React Tabulator - How to display table horizontally - reactjs

I'm using react-tabulator for a component: http://tabulator.info/docs/4.0/frameworks
I have put the component on the page in my app but am struggling to do anything with the styling. Right now, the component just displays everything vertically and looks really bad:
I want to display this horizontally in something that looks like a normal tabular format. I would also like to change column width. I've found limited documentation examples. Someone did ask a similar question and in this StackOverflow thread: How to style react-tabulator table? but I've not been able to edit the styles.css stylesheet to do anything useful.
Here is my component code:
import React from 'react'
import { ReactTabulator } from 'react-tabulator'
import 'react-tabulator/lib/styles.css';
const TabularData = (props) => {
const dataArray = []
//gets just first streelights record
for (const [i, v] of props.streetlights.features.entries()) {
if (i < 1) {
dataArray.push(v.properties); // properties of each item is what contains the info about each streetlight
}
}
let columns = [
{title:"WORKLOCATI", field:"WORKLOCATI"},
{title:"WORKREQUES", field:"WORKREQUES"},
{title:"WORK_EFFEC", field:"WORK_EFFEC"},
{title:"WORK_REQUE", field:"WORK_REQUE"},
]
return (
<ReactTabulator
columns={columns}
layout={"fitData"}
data={dataArray}
/>
)
}
export default TabularData

The css in react-tabulator/lib/styles.css is just the most base-level css.
Try importing one of the pre-built themes:
import "react-tabulator/css/bootstrap/tabulator_bootstrap.min.css";
There are a whole bunch of them in the css folder, and you can use them as a basis for creating your own.
Minimum working example here.

To get the right styling you will also have to import tabulator.min.css in your module, which is the theme, according to here.
Your imports should look like this:
import { ReactTabulator } from 'react-tabulator'
import 'react-tabulator/lib/styles.css';
import 'react-tabulator/lib/css/tabulator.min.css'; // theme
Without it, it looks like the image you posted:
With it, it looks like this:
In the folder node_modules/react-tabulator/css you can find more themes.

Related

import { styled } from '#mui/material/styles'; displayName not showing

Using Mui styled function to style both jsx elements and MUI components. The displayName is not showing when I debug the element in Chrome or any browser for that matter.
Anyone know how to fix this.
I'm using Vite for my setup.
const MyComponent = styled('div')`
display: flex;
`;
As you can see from the below screenshot its not showing MyComponent display name instead its showing css-1vht943
You can see class only inside the Element tab. When you click on one of the lines which contains the class name.
You can find all the CSS related to that class under the styles tab including display name for your case. Please check the image below
If you want to have a name I think you can use styled('div', { name: 'MyTheme'}), then you will see something like <div class="css-t7mscw-MyTheme-root"></div>. Don't know if this is what you want, but here it is vaguely mentioned in the doc.

react-three/fiber creating 3D text

I'm trying to create 3d text using Threejs + react-three/fiber .
I loaded the font using font loader like this :
const font = new FontLoader().parse('/Microsoft Tai Le_Regular.json');
After that I tried to use component inside the mesh , for some reason it didn't work, any other type of Geometry would work .
<mesh>
<textGeometry /> // this can't even be compiled ( maybe it has to do with typescript
</mesh>
With that problem , I tried to create the textGeometry on js instead of jsx So I did this :
const textOptions = {
font: font,
size: props.size,
height: props.height,
curveSegments: 12,
bevelEnabled: true,
bevelThickness: 10,
bevelSize: 8,
bevelOffset: 0,
bevelSegments: 5
};
const textGeo = new TextGeometry(props.text, textOptions);
and Passed 'textGeo' to mesh geometry prop
<mesh
geometry={textGeo}
>
still didn't work and gave this error :
can't access property "yMax", data.boundingBox is undefined
Thanks for your help,
So I'll preface this by saying that I'm still a student so I can't explain exactly why all these steps need to be done but here's what worked for me. It seems that your issue is with the path that you are using to parse. The file name itself seems inaccurate but even if the file path is valid, it still will not work, it must be imported. Make sure that your json file is inside of your src folder and import the json file using the relative path.
import myFont from '../relative_path'
Make sure to import extend from r3f
import { extend } from '#react-three/fiber'
Next, textGeometry does not come standard with r3f, so it needs to be imported like so
import { TextGeometry } from 'three/examples/jsm/geometries/TextGeometry'
Then extend TextGeometry
extend({ TextGeometry })
This should work to get the textgeometry to compile. Take a look below for the full snippet.
import { extend } from '#react-three/fiber'
import { FontLoader } from 'three/examples/jsm/loaders/FontLoader'
import { TextGeometry } from 'three/examples/jsm/geometries/TextGeometry'
import myFont from '../relative_path'
extend({ TextGeometry })
export default function Text() {
const font = new FontLoader().parse(myFont);
return(
<mesh position={[0,10,0]}>
<textGeometry args={['test', {font, size:5, height: 1}]}/>
<meshLambertMaterial attach='material' color={'gold'}/>
</mesh>
)
}
Obviously you can change the args and material to fit your needs.

Dynamically changing Less variables in React Gatsby app with Ant Design at runtime

We are building a White Label platform using React, GatsbyJs and Ant Design. We are stuck with Gatsby and Ant Design because we are migrating from an existing system and changing any of those would bring huge impact. Also, we must have a single deploy. Having a build for each White Label is not an option.
So, we need to be able to change style (mainly color) at runtime.
The problem is: Ant Design uses less variables to define it's themes and we're not able to change them at runtime, not even with less's modifyVars.
The thing is we MUST change less variables, and not global CSS or use other means
Ant Design derivates the main variables many times to get adjacent properties. So, for instance, if we define #primary-color as red, when we add a Button to the screen, Ant Design also defines it's border color, hover color, and many other details with different shades of red.
This means that, if we were to use other styling tool, we would need to generate those color derivations and replace every little property for every component. This would be chaos.
Scenario
We are using gatsby-plugin-antd and gatsby-plugin-less to load less and change vars at build time. Our gatsby-config.js looks like this:
module.exports = {
siteMetadata: {
siteUrl: 'https://www.yourdomain.tld',
title: 'yourtitle'
},
plugins: [
'gatsby-plugin-root-import',
'gatsby-plugin-typescript',
{
resolve: 'gatsby-plugin-antd',
options: {
style: true
}
},
{
resolve: 'gatsby-plugin-less',
options: {
lessOptions: {
javascriptEnabled: true,
modifyVars: {
'primary-color': '#FFFFFF',
'link-color': '#000000',
'success-color': '#FFFFFF',
'warning-color': '#000000'
}
}
}
}
]
};
We import styling in our gatsby-browser.js file:
import './src/styles/index';
Our styles/index has:
import 'tachyons';
import './global.css';
import './antd.less';
antd.less:
#import '~antd/dist/antd.less';
And global.css has some general CSS for the project.
It's working fine with the defined variables at build time.
What we attempted so far...
We have tried out this plugin:
https://github.com/mzohaibqc/antd-theme-webpack-plugin
Which supposedly does exactly what we need. But there's no example using Gatsby.
We then tried to add the plugin using the gatsby-node.js as mentioned here:
https://www.gatsbyjs.com/docs/how-to/custom-configuration/add-custom-webpack-config/
First, we tried using index.html as the indexFileName for the pluggin. It just doesn't work.
Then, following the plugin docs, we tried using indexFileName as false and importing the following scripts using Helmet at our pages/index.tsx:
<script> window.less = { async: false, env: 'production' };
</script> <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/less.js/2.7.2/less.min.js"></script> ```
Also didn't work. If we define indexFileName as false, we get memory over the heap.
If we keep indexFileName as 'index.html' and just add the scripts, we are able to call window.less.modifyVars and it returns successfully (we are logging the Promise's then and error) but it doesn't affect antd's variables.
We then tried doing something similar, but instead of loading less externally, we installed it as a node_module and imported it to the file and used it directly in a similar fashion. Got the same result: modifyVars runs and returns successfully but doesn't affect antd.
Then, we tried something a bit different: we removed gatsby plugins and tried importing less from antd directly, as suggested here:
https://ant.design/docs/react/customize-theme
So we imported it like this:
#import '~antd/lib/style/themes/default.less';
#import '~antd/dist/antd.less';
#import 'your-theme-file.less';
Also, no good. It's different from the previous scenario, because style gets updated after you save your code. No need to stop Gatsby, as the first solutions. But, modifyVars still has no affect on antd components.
Then, to isolate the issue, we tried to style a basic HTML component - a button - to check if the issue was with gatsby or antd. And... still no success. less.modifyVars didn't work to change a basic button style on runtime.
So, we think it's probably something between Gatsby and Less. We checked gatsby-plugin-antd and gatsby-plugin-less to see if we could find something, but found nothing useful.
We assume that the "less instance" or "less context" used by gatsby's less-loader during build time is not the same we are calling modifyVars on. So it doesn't affect the original vars.
Totally stuck. Please, help!
EDIT - SOLUTION
Ant Design team has just released - TODAY - a new alpha version that includes dynamic theming, using CSS Variables.
https://ant.design/docs/react/customize-theme-variable
It works fine, so far. Closing the issue.
EDIT 2
There's a more detailed solution on the accepted answer.
Ant Design team has just released - TODAY - a new alpha version that includes dynamic theming, using CSS Variables.
https://ant.design/docs/react/customize-theme-variable
It works fine, so far.
EDIT - Detailed solution
I removed gatsby-plugin-antd and gatsby-plugin-less from the project. Also removed the import of antd less file.
Instead, in my styles/index.tsx (which is imported in gatsby-browser.js), I'm importing the variables.min.css file:
import 'antd/dist/antd.variable.min.css';
Then, whenever I want to change Ant Design variables, I just use:
import { ConfigProvider } from 'antd';
...
ConfigProvider.config({
theme: {
primaryColor: '#[DESIRED_COLOR_HEX]'
}
});
Provider
Since this has to be done every time the site is loaded, I'm creating a ThemeProvider that wraps every page and defines the theme. It fetches theme data from the backend and sets Ant Design theme variables.
Example code:
import { Spin } from 'antd';
import React, { useEffect, useState } from 'react';
import { ConfigProvider } from 'antd';
import { Theme } from './theme.interface';
interface Props {
children: React.ReactNode;
}
export const ThemeProvider = ({ children }: Props): JSX.Element => {
const [themeVars, setThemeVars] = useState<Theme>(null);
useEffect(() => {
async function fetchMyAPI() {
const result = await getThemeFromBackend(); // Make API call with Axios
if (result) setThemeVars(result);
}
fetchMyAPI();
}, []);
useEffect(() => {
if (themeVars) {
ConfigProvider.config({
theme: {
primaryColor: `#${themeVars.primaryColor}`
}
});
}
}, [themeVars]);
return <div>{!themeVars ? <Spin size="large" /> : <>{children}</>}</div>;
};
And it can be used like this:
...
<ThemeProvider>
<h1>My page header</h1>
<p>Page content...</p>
</ThemeProvider>
...
Note: You can save theme data on local storage for performance improvement, so you don't have to call your backend everytime your site reloads. Maybe you'll just have to refresh it from time to time.

how do I interpolate a Link component in Next-i18next / React i18next that changes position in the text

Currently I'm using Next.js with Next-i18next for I18N, but I understand that the React/i18next implementation is basically the same.
The problem I'm having is that I need to interpolate a next Link component inside some translation text, but depending on the language (English vs German), the order of the text and the link would change.
For instance the text I'm struggling with is: 'Accept data policy' vs 'Datenschutzerklärung akzeptieren'
As of the moment I have a quick fix by creating two values in the translation JSON files for the text and the link and then swapping the position based on the current language. Obviously this is not a sustainable solution. I have tried to utilise the 'Trans' component but this is showing some unexpected behaviour where the translation only kicks in after the page is refreshed, otherwise you see the text inside the Trans component.
example:
function LinkText({ href, children}) {
return <Link to={href || ''}>{children}</Link>;
}
return (
<Trans i18nKey="sentence">
text before link
<LinkText href="/data-policy">{t("dataPolicy")}</LinkText>
text after link
</Trans>
);
and the JSON in question:
{
"sentence": "agree to our <1><0/></1>",
"dataPolicy": "data policy"
}
Here's a link to CodeSandbox I made to replicate the problem with in React: link
(P.S The implementation of i18next doesn't seem to effectively swap out the languages in Codesandbox at the moment, but I included it as the code is there for a MWE)
Thanks in advance for your help, this has been driving me insane.
You had few missing parts,
Your i18next config was lack of a way to fetch the locale files, I've added i18next-http-backend.
You should use Trans component to inject the link to the sentence.
Your locale json should look like this:
{
"sentence": "Accept <0>data policy</0>"
}
// TranslatedLink.js
import React from 'react';
import { useTranslation, Trans } from 'react-i18next';
import { Link } from 'react-router-dom';
function LinkText({ href, children }) {
return <Link to={href || ''}>{children}</Link>;
}
export default function TranslatedLink() {
const { t } = useTranslation(['common']);
return (
<div style={{ padding: 50 }}>
<Trans i18nKey="sentence" t={t} components={[<LinkText href="/data-policy" />]} />
</div>
);
}
A working example: https://codesandbox.io/s/react-i18n-interpolation-issue-forked-ck8l4

How to get Material UI Icon SVG path? React Icon Picker

I have a react application using Material UI's Icons. The main objective is to have an Icon Picker, where a user can select a MUI Icon and that selected icon's SVG path is saved within the state.
This svg path will then be saved out to an API where it can be displayed in various places. etc.
I've searched through documentation on MUI's site regarding icons, but it's all about implementation, which I can do just fine. I've looked for an npm package, without much luck.
I did come across this package (https://github.com/DMDc0de/material-ui-icon-picker), which is essentially what I'd like the picker to be - but it outputs the icon's name for an icon component <i />. Not what I want. I need the source of the SVG path.
Any direction towards this would be super helpful.
Go to the icon site: https://material.io/tools/icons/
Click on an icon
Click on "Selected icon" button (bottom left)
Click on the "SVG" button to download the SVG version
Alternatively, go to the GitHub repo and download the SVGs there.
One way of doing that programmatically is to load the component and to render it in a string. Then to extract the path from the string.
To do so, we can use the renderToString or renderToMarkupString method of ReactDomServer.
Than we can extract the path from the generated string. We can either parse the svg XML with the DOMParser or with a regexp.
Here's an example in TypeScript:
import EditIcon from '#material-ui/icons/Edit';
import ReactDOMServer from 'react-dom/server';
export function getEditIconPath(): string {
const iconString = ReactDOMServer.renderToString(<EditIcon />);
const parser = new DOMParser();
const svgDoc = parser.parseFromString(iconString, 'image/svg+xml');
const iconPath = svgDoc.querySelector('path')?.getAttribute('d') as string;
return iconPath;
}
Another way to achieve that would be to use the React Test Renderer, thus we can get directly a json including the different properties (including the path). However, it looks like this method is around 10 times slower than the previous method.
Here's an example with the second method:
import EditIcon from '#material-ui/icons/Edit';
import TestRenderer from 'react-test-renderer'; // ES6
export function getEditIconPath(): string {
const iconComponent = TestRenderer.create(<EditIcon />);
const iconJson = iconComponent.toJSON();
const path = iconJson.children[0].props.d;
return path;
}

Resources