Integrate "react-intl" langage locale with switcher in storybook - reactjs

I am trying to include langage locale support from my React components in Storybook using "react-intl", I added the following global types in "preview.js" as list of Languages supported to appear in the Storybook toolbar:
export const globalTypes = {
locale: {
title: 'Locale',
description: 'Internationalization locale',
toolbar: {
icon: 'globe',
items: [
{ value: 'en', right: 'πŸ‡ΊπŸ‡Έ', title: 'English' },
{ value: 'de', right: 'πŸ‡©πŸ‡ͺ', title: 'Deutsch' },
],
dynamicTitle: true,
},
},
};
When I switch the langages it does not work always the default langage is showed, I need to know the code that can be used to implement the langage switcher and make it work with the code implemented within our React application in IdwIntlProvider.. I have to implement the functionality without using the react-intl Addon.

Related

Storybook does not infer controls for Kendo-UI (React) Components

I'm in the process of creating an internal component library using Storybook and Kendo React and I'm having to explicitly define argTypes for controls for every prop in order to get them to give me anything but a string input (with the sole exception of booleans).
Here's a sample of one of my stories:
import React from "react";
import { ComponentStory, ComponentMeta } from "#storybook/react";
import { TestAvatar } from "../../components/Avatar/TestAvatar";
export default {
title: "Atomic Components/Test Avatar",
component: TestAvatar,
} as ComponentMeta<typeof TestAvatar>;
const Template: ComponentStory<typeof TestAvatar> = ({ ...args }: any) => (
<TestAvatar {...args} />
);
export const Standard = Template.bind({});
Standard.args = {
border: false,
themeColor: "base",
fillMode: "solid",
rounded: "medium",
size: "medium",
type: undefined,
};
Standard.argTypes = {
themeColor: {
options: ["base", "primary", "secondary", "tertiary", "success", "error"],
control: { type: "select" },
},
rounded: {
options: ["small", "medium", "large", "full", null],
control: { type: "select" },
},
size: {
options: ["small", "medium", "large"],
control: { type: "select" },
},
fillMode: {
options: ["solid", "outline"],
control: { type: "radio" },
},
type: {
options: ["image", "text", "icon"],
control: { type: "select" },
},
};
I have all the standard addons, although I haven't created any typescript options in main.js - I've tried, using info I got from this question but they don't seem to make any difference.
I've tried a few things, using Story and Meta from Storybook instead of the newer ComponentStory and ComponentMeta, I've tried extending the AvatarProps interface and I have also tried using the Kendo AvatarProps interface directly, but I can't find a way around it.
I suspect it's to do with how the Kendo library is typed.
I want to have to avoid creating controls for every single component I'm creating - does anyone have any ideas on how I can circumvent that amount of unnecessary work?

Using chart js options with react-chartjs-2 and typescript

I am trying to use a plugin with a react-chartjs doughnut chart. In order to use the plugin (https://www.npmjs.com/package/#scottalan/chartjs-plugin-doughnutlabel), I have to pass options to the component. But when I try to pass options, I get a type error
Type '{ doughnutlabel: { labels: { text: string; font: { size: string; family: string; style: string; weight: string; }; color: string; }[]; }; }' is not assignable to type '_DeepPartialObject<PluginOptionsByType<keyof ChartTypeRegistry>>'.
Object literal may only specify known properties, and 'doughnutlabel' does not exist in type '_DeepPartialObject<PluginOptionsByType<keyof ChartTypeRegistry>>'.
My best guess is that ChartOptions is the wrong type to assign my options to because I get the same error event without trying to use the plugin with const options: ChartOptions = {}. My full code is below, any help is appreciated.
import React, { useEffect, ReactNode, Component } from "react"
import { Chart, ChartOptions, registerables } from 'chart.js'
import { Doughnut } from 'react-chartjs-2';
Chart.register(...registerables);
const MyDoughnut = (props: ComponentProps) => {
const renderChart = (percents: number[]) => {
const data = {
datasets: [{
label: 'Progress',
data: percents,
backgroundColor: [
'rgb(255, 99, 132)',
'transparent',
],
hoverOffset: 4,
cutout: "75%",
radius: "100%"
}]
}
const options: ChartOptions = {
responsive: true,
legend: {
display: false,
position: 'top',
},
title: {
display: true,
fontSize: 20,
text: 'My Title'
},
plugins: {
doughnutlabel: {
labels: [
{
text: "Foo",
font: {
size: '60',
family: 'Arial, Helvetica, sans-serif',
style: 'italic',
weight: 'bold'
},
color: '#bc2c1a'
}
]
}
}
}
return <Doughnut options={options} data={data}></Doughnut>
}
const render = (): ReactNode => {
// const percents = props.args["percents"]
const percents = [76, 24];
return (
<span>
{renderChart(percents)}
</span>
)
}
return <div>{render()}</div>
};
I am using react-chartjs-2 version 4.0.0 and react version 17.0.2.
It turns out the typing error can be solved by using any instead of ChartOptions.
const options: any = {
...
}
As LeeLenalee pointed out, there is also an issue using this specific plugin with V3 of Chart.js, but using any worked with another similar plugin.
types are exported from chart.js
import type { ChartData, ChartOptions } from 'chart.js';
interface DoughnutProps {
options: ChartOptions<'doughnut'>;
data: ChartData<'doughnut'>;
}
I looked at the source of the plugin and it seems like even if you solve the typing issue it wont work. The reason for this is that you are using V3 of Chart.js while the plugin was written for V2 and never updated. It is self registering and it does this in the wrong way, it defines its default options in the wrong place (both namespaces dont exist anymore).
So if you really want to use this plugin I suggest you take a look at the source and modify it so it works with V3 or downgrade to chart.js v2 where there is no build in typing or find another plugin.

difference between knobs and controls in Storybook?

I am new to the storybook. When I go through the documentation and videos about the storybook I read about knobs Addon. Knobs addon and control looks similar. What is the difference between those two things?
Controls were introduced with Storybook version 6. They replace knobs for most of the use cases. However, there may be some edge cases were you still want to use knobs for dynamic values. For example, see this Github discussion on this topic: https://github.com/storybookjs/storybook/issues/11984
controls addon is a companion to the docs addon so it interfaces with the ArgsTable which by itself is designed to automatically extract your components' propTypes & defaultProps (although I found this not to work)
So, with Knobs you define each prop (which you wish to be dynamic) yourself, manually, and this requires some more manual sync when your component changes and also more work, and also Knobs variables definitions might be scattered all across your story's file, where controls are all defined in one place, though the same "order" can also be done with Knobs, it does not enforces it (for good reasons).
If you want to have an interactive propTypes documentation for your components, then I suggest using controls with addon-docs, and I've been using knobs for years, but that's it, it's time to upgrade.
If, for some reason, your component's propTypes where not auto-detected (in the story) then you can define then (with controls) like so:
import Alert from './';
export default {
title: 'General/Alert',
component: Alert,
parameters: {
controls: { expanded: true }, // Show full documentation for each property
},
argTypes: {
type: {
description: 'Alert.Types',
defaultValue: Alert.Types.WARNING,
table: {
type: {
summary: 'string',
},
defaultValue: {
summary: Alert.Types.WARNING,
},
},
options: Alert.Types,
control: {
type: 'select', // for selecting between the array of options above
},
},
title: {
defaultValue: '',
table: {
type: {
summary: 'string',
},
},
description: 'An optional title',
control: {
type: 'text',
},
},
onClose: {
table: {
type: {
summary: 'func',
},
},
description: 'Γ— button click callback',
control: { type: null },
},
children: {
description: 'The message body (mandatory)',
type : {
required: true,
},
table: {
type: {
summary: 'node',
},
},
control: { type: null },
},
},
}
//...export your story...
Notes:
How to migrate dynamic knobs to controls?

React Quill - How do I show the differences between two text versions?

I'm currently designing a website with React where the user will work with a text editor. The text editor will already have text in it. The user will make some changes to the text and submit it. I would like to add a button that will show the user the differences between the original text and his new text, like Git but down to individual characters.
I'm currently trying to use Quill for that. I've found a lovely solution to my problem, but it's written in plain JavaScript. I've tried translating it to React by setting the Quill objects in the state:
const [quill_old, set_quill_old] = React.useState(new Quill('#old', {
modules: {
toolbar: [
[{ header: [1, 2, false] }],
['bold', 'italic', 'underline'],
['image', 'code-block']
]
},
placeholder: 'Compose an epic...',
theme: 'snow' // or 'bubble'
}))
const [quill_new, set_quill_new] = React.useState(new Quill('#new', {
modules: {
toolbar: [
[{ header: [1, 2, false] }],
['bold', 'italic', 'underline'],
['image', 'code-block']
]
},
placeholder: 'Compose an epic...',
theme: 'snow' // or 'bubble'
}))
const [quill_diff, set_quill_diff] = React.useState(new Quill('#diff', {
modules: {
toolbar: [
[{ header: [1, 2, false] }],
['bold', 'italic', 'underline'],
['image', 'code-block']
]
},
placeholder: 'Compose an epic...',
theme: 'snow' // or 'bubble'
}))
but when initializing the code it gets stuck on the "findDiff" function, on this line:
var oldContent = quill_old.getContents();
and returns an error:
TypeError: Cannot read property 'length' of undefined
Where "undefined" is "quill_old".
When trying to run the page without the function, the page shows properly, but I get multiple errors in the console like this:
quill Invalid Quill container #old
Does somebody know how to properly implement this solution in React? Or has a suggestion on some other library I can use?
Thank you for your time

How to add custom components into Ant Design stepper?

I'm new to AntD and having a little trouble with the stepper component - specifically, how to add a custom component into each of the steps.
For example,
const steps = [
{
title: 'First',
content: 'First-content',
},
{
title: 'Second',
content: 'Second-content',
},
{
title: 'Last',
content: 'Last-content',
},
];
For simplicity, if I were to use the Autocomplete component would it be just:
{
title: 'First',
content: '<Autocomplete />',
},
No luck so far. Any advice is appreciated.
There is no content in Steps.Step.
You may be trying to render a custom component in Steps, then you need to provide ReactNode and not a string type:
<Steps>
<Steps.Step> title="Finished" description={<AutoComplete/>} />
</Steps>
Its all mentioned in the docs, I believe what you need is the basics of React.
Maybe you found this official example Switch Step, there is a steps variable like this:
const steps = [
{
title: 'First',
content: 'First-content',
},
{
title: 'Second',
content: 'Second-content',
},
{
title: 'Last',
content: 'Last-content',
},
];
This is a user-defined variable, NOT pre-defined by antd, you can use whatever property even data structure you want. You can assign the ReactNode to content property like:
const steps = [
{
title: 'First',
content: <Autocomplete />,
},
// ...
]
And render the content based on current step state:
<div className="steps-content">{steps[current].content}</div>
There is NO content prop for the Steps.Step component. This is another way different from the accepted answer.

Resources