@tecsinapse/cortex-react 1.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +11 -0
- package/package.json +33 -0
- package/src/components/Badge.tsx +45 -0
- package/src/components/Button.tsx +19 -0
- package/src/components/Card.tsx +18 -0
- package/src/components/Hint.tsx +31 -0
- package/src/components/Input.tsx +110 -0
- package/src/components/Modal.tsx +24 -0
- package/src/components/SearchInput.tsx +86 -0
- package/src/components/Select.tsx +170 -0
- package/src/components/Snackbar.tsx +26 -0
- package/src/components/Tag.tsx +19 -0
- package/src/components/TextArea.tsx +121 -0
- package/src/components/Toggle.tsx +25 -0
- package/src/components/index.ts +11 -0
- package/src/docs/badge-anchor.stories.tsx +42 -0
- package/src/docs/badge.stories.tsx +31 -0
- package/src/docs/button.stories.tsx +37 -0
- package/src/docs/card.stories.tsx +29 -0
- package/src/docs/hint.stories.tsx +32 -0
- package/src/docs/input-custom.stories.tsx +45 -0
- package/src/docs/input.stories.tsx +40 -0
- package/src/docs/modal.stories.tsx +48 -0
- package/src/docs/select-grouped.stories.tsx +79 -0
- package/src/docs/select.stories.tsx +70 -0
- package/src/docs/snackbar.stories.tsx +31 -0
- package/src/docs/tag.stories.tsx +37 -0
- package/src/docs/text-area.stories.tsx +50 -0
- package/src/docs/toggle.stories.tsx +18 -0
- package/src/docs/utils.ts +8 -0
- package/src/hooks/index.ts +1 -0
- package/src/hooks/useDebouncedState.ts +24 -0
- package/src/index.ts +1 -0
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import {
|
|
3
|
+
input,
|
|
4
|
+
InputBaseVariants,
|
|
5
|
+
inputBox,
|
|
6
|
+
labelStyle,
|
|
7
|
+
} from '@tecsinapse/cortex-core';
|
|
8
|
+
import { clsx } from 'clsx';
|
|
9
|
+
|
|
10
|
+
const getValidChildren = (children: React.ReactNode) => {
|
|
11
|
+
return React.Children.toArray(children).filter(el =>
|
|
12
|
+
React.isValidElement(el)
|
|
13
|
+
) as React.ReactElement[];
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
interface TextAreaPropsBase {
|
|
17
|
+
variants?: InputBaseVariants;
|
|
18
|
+
label?: string;
|
|
19
|
+
rows?: number;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
interface TextAreaProps
|
|
23
|
+
extends React.TextareaHTMLAttributes<HTMLTextAreaElement>,
|
|
24
|
+
TextAreaPropsBase {}
|
|
25
|
+
|
|
26
|
+
const Box = React.forwardRef<HTMLTextAreaElement, TextAreaProps>(
|
|
27
|
+
(
|
|
28
|
+
{ id, name, variants, label, placeholder, rows, className, ...rest },
|
|
29
|
+
ref
|
|
30
|
+
) => {
|
|
31
|
+
return (
|
|
32
|
+
<div className="flex w-full flex-col">
|
|
33
|
+
<textarea
|
|
34
|
+
ref={ref}
|
|
35
|
+
id={id ?? name}
|
|
36
|
+
name={name}
|
|
37
|
+
placeholder={placeholder ?? ' '}
|
|
38
|
+
className={clsx(
|
|
39
|
+
inputBox(placeholder, label, className),
|
|
40
|
+
'resize-none mt-mili'
|
|
41
|
+
)}
|
|
42
|
+
rows={rows}
|
|
43
|
+
{...rest}
|
|
44
|
+
/>
|
|
45
|
+
<label
|
|
46
|
+
htmlFor={id ?? name}
|
|
47
|
+
className={labelStyle({
|
|
48
|
+
intent: variants?.intent,
|
|
49
|
+
placeholder,
|
|
50
|
+
})}
|
|
51
|
+
>
|
|
52
|
+
{label}
|
|
53
|
+
</label>
|
|
54
|
+
</div>
|
|
55
|
+
);
|
|
56
|
+
}
|
|
57
|
+
);
|
|
58
|
+
|
|
59
|
+
type DivBaseProps = React.HTMLAttributes<HTMLDivElement>;
|
|
60
|
+
type TextAreaFaceProps = DivBaseProps & Pick<TextAreaPropsBase, 'variants'>;
|
|
61
|
+
|
|
62
|
+
const Face = React.forwardRef<HTMLDivElement, TextAreaFaceProps>(
|
|
63
|
+
({ children, variants, className, ...rest }, ref) => {
|
|
64
|
+
const clones = getValidChildren(children).map(el => {
|
|
65
|
+
return React.cloneElement(el, { ...el.props, variants });
|
|
66
|
+
});
|
|
67
|
+
return (
|
|
68
|
+
<div
|
|
69
|
+
ref={ref}
|
|
70
|
+
className={clsx(input(variants), className)}
|
|
71
|
+
id="textarea-face"
|
|
72
|
+
{...rest}
|
|
73
|
+
>
|
|
74
|
+
{clones}
|
|
75
|
+
</div>
|
|
76
|
+
);
|
|
77
|
+
}
|
|
78
|
+
);
|
|
79
|
+
|
|
80
|
+
const Root = React.forwardRef<HTMLTextAreaElement, TextAreaProps>(
|
|
81
|
+
({ variants, className, ...rest }, ref) => {
|
|
82
|
+
return (
|
|
83
|
+
<Face variants={variants} className={className}>
|
|
84
|
+
<Box ref={ref} {...rest} />
|
|
85
|
+
</Face>
|
|
86
|
+
);
|
|
87
|
+
}
|
|
88
|
+
);
|
|
89
|
+
|
|
90
|
+
type TextAreaElementsProps = DivBaseProps & {
|
|
91
|
+
children: React.ReactNode;
|
|
92
|
+
className?: string;
|
|
93
|
+
};
|
|
94
|
+
|
|
95
|
+
const Left = React.forwardRef<HTMLDivElement, TextAreaElementsProps>(
|
|
96
|
+
({ children, className, ...rest }, ref) => {
|
|
97
|
+
return (
|
|
98
|
+
<div className={clsx(className, 'mr-2.5')} {...rest} ref={ref}>
|
|
99
|
+
{children}
|
|
100
|
+
</div>
|
|
101
|
+
);
|
|
102
|
+
}
|
|
103
|
+
);
|
|
104
|
+
|
|
105
|
+
const Right = React.forwardRef<HTMLDivElement, TextAreaElementsProps>(
|
|
106
|
+
({ children, className, ...rest }, ref) => {
|
|
107
|
+
return (
|
|
108
|
+
<div className={clsx(className, 'ml-2.5')} {...rest} ref={ref}>
|
|
109
|
+
{children}
|
|
110
|
+
</div>
|
|
111
|
+
);
|
|
112
|
+
}
|
|
113
|
+
);
|
|
114
|
+
|
|
115
|
+
export const TextArea = {
|
|
116
|
+
Root,
|
|
117
|
+
Face,
|
|
118
|
+
Box,
|
|
119
|
+
Left,
|
|
120
|
+
Right,
|
|
121
|
+
};
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import React, { forwardRef, InputHTMLAttributes } from 'react';
|
|
2
|
+
import {
|
|
3
|
+
styleInputElement,
|
|
4
|
+
styleLabelElement,
|
|
5
|
+
toggle,
|
|
6
|
+
} from '@tecsinapse/cortex-core';
|
|
7
|
+
|
|
8
|
+
export const Toggle = forwardRef<
|
|
9
|
+
HTMLInputElement,
|
|
10
|
+
InputHTMLAttributes<HTMLInputElement>
|
|
11
|
+
>((props, ref) => {
|
|
12
|
+
return (
|
|
13
|
+
<div className={'flex flex-row items-center gap-x-centi'}>
|
|
14
|
+
<label className={styleLabelElement()}>
|
|
15
|
+
<input
|
|
16
|
+
type="checkbox"
|
|
17
|
+
className={styleInputElement()}
|
|
18
|
+
ref={ref}
|
|
19
|
+
{...props}
|
|
20
|
+
/>
|
|
21
|
+
<div className={toggle()} />
|
|
22
|
+
</label>
|
|
23
|
+
</div>
|
|
24
|
+
);
|
|
25
|
+
});
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export * from './Badge';
|
|
2
|
+
export * from './Button';
|
|
3
|
+
export * from './Card';
|
|
4
|
+
export * from './Hint';
|
|
5
|
+
export * from './Input';
|
|
6
|
+
export * from './Modal';
|
|
7
|
+
export { default as Select } from './Select';
|
|
8
|
+
export * from './Snackbar';
|
|
9
|
+
export * from './Tag';
|
|
10
|
+
export * from './Toggle';
|
|
11
|
+
export * from './TextArea';
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { StoryFn } from '@storybook/react';
|
|
3
|
+
import { BadgeAnchor, Button } from '../index';
|
|
4
|
+
import { defaultIntents } from './utils';
|
|
5
|
+
|
|
6
|
+
export default {
|
|
7
|
+
title: 'Cortex-React/Badge/Anchor',
|
|
8
|
+
component: <div />,
|
|
9
|
+
args: {
|
|
10
|
+
value: 1,
|
|
11
|
+
intent: 'primary',
|
|
12
|
+
},
|
|
13
|
+
argTypes: {
|
|
14
|
+
intent: {
|
|
15
|
+
options: defaultIntents,
|
|
16
|
+
control: { type: 'select' },
|
|
17
|
+
},
|
|
18
|
+
value: {
|
|
19
|
+
control: { type: 'number' },
|
|
20
|
+
min: 1,
|
|
21
|
+
max: 9,
|
|
22
|
+
},
|
|
23
|
+
},
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
const Template: StoryFn = args => {
|
|
27
|
+
return (
|
|
28
|
+
<BadgeAnchor
|
|
29
|
+
variants={{ intent: args.intent, isAnchor: true }}
|
|
30
|
+
value={args.value}
|
|
31
|
+
>
|
|
32
|
+
<Button variants={{ variant: 'outline' }}>
|
|
33
|
+
<p>Button</p>
|
|
34
|
+
</Button>
|
|
35
|
+
</BadgeAnchor>
|
|
36
|
+
);
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
export const Base = {
|
|
40
|
+
render: Template,
|
|
41
|
+
args: {},
|
|
42
|
+
};
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { StoryFn } from '@storybook/react';
|
|
3
|
+
import { Badge } from '../index';
|
|
4
|
+
import { defaultIntents } from './utils';
|
|
5
|
+
|
|
6
|
+
export default {
|
|
7
|
+
title: 'Cortex-React/Badge',
|
|
8
|
+
component: <div />,
|
|
9
|
+
args: {
|
|
10
|
+
value: '1',
|
|
11
|
+
intent: 'primary',
|
|
12
|
+
},
|
|
13
|
+
argTypes: {
|
|
14
|
+
intent: {
|
|
15
|
+
options: defaultIntents,
|
|
16
|
+
control: { type: 'select' },
|
|
17
|
+
},
|
|
18
|
+
value: {
|
|
19
|
+
control: { type: 'text' },
|
|
20
|
+
},
|
|
21
|
+
},
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
const Template: StoryFn = args => {
|
|
25
|
+
return <Badge variants={{ intent: args.intent }} value={args.value ?? '2'} />;
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
export const Base = {
|
|
29
|
+
render: Template,
|
|
30
|
+
args: {},
|
|
31
|
+
};
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { StoryFn } from '@storybook/react';
|
|
3
|
+
import { Button } from '../index';
|
|
4
|
+
|
|
5
|
+
export default {
|
|
6
|
+
title: 'Cortex-React/Button',
|
|
7
|
+
component: <div />,
|
|
8
|
+
argTypes: {
|
|
9
|
+
intent: {
|
|
10
|
+
options: ['primary', 'secondary', 'success', 'info', 'warning', 'error'],
|
|
11
|
+
control: { type: 'select' },
|
|
12
|
+
},
|
|
13
|
+
variant: {
|
|
14
|
+
options: ['outline', 'text', 'filled'],
|
|
15
|
+
control: { type: 'select' },
|
|
16
|
+
},
|
|
17
|
+
size: {
|
|
18
|
+
options: ['small', 'default', 'circle', 'square'],
|
|
19
|
+
control: { type: 'select' },
|
|
20
|
+
},
|
|
21
|
+
},
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
const Template: StoryFn = args => {
|
|
25
|
+
return (
|
|
26
|
+
<Button
|
|
27
|
+
variants={{ intent: args.intent, variant: args.variant, size: args.size }}
|
|
28
|
+
>
|
|
29
|
+
<p>Button</p>
|
|
30
|
+
</Button>
|
|
31
|
+
);
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
export const Base = {
|
|
35
|
+
render: Template,
|
|
36
|
+
args: {},
|
|
37
|
+
};
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { StoryFn } from '@storybook/react';
|
|
3
|
+
import { Button, Card } from '../index';
|
|
4
|
+
import { IoMdArrowForward } from 'react-icons/io';
|
|
5
|
+
export default {
|
|
6
|
+
title: 'Cortex-React/Card',
|
|
7
|
+
component: <div />,
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
const Template: StoryFn = () => {
|
|
11
|
+
return (
|
|
12
|
+
<Card>
|
|
13
|
+
<div className={'w-[300px]'}>
|
|
14
|
+
<p className={'text-h5 font-bold'}>Exemple card</p>
|
|
15
|
+
<div className={'flex flex-row items-center gap-x-deca mt-deca'}>
|
|
16
|
+
<Button variants={{ variant: 'outline', size: 'small' }}>
|
|
17
|
+
<IoMdArrowForward />
|
|
18
|
+
</Button>
|
|
19
|
+
<p className={''}>Exemple description card</p>
|
|
20
|
+
</div>
|
|
21
|
+
</div>
|
|
22
|
+
</Card>
|
|
23
|
+
);
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
export const Base = {
|
|
27
|
+
render: Template,
|
|
28
|
+
args: {},
|
|
29
|
+
};
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { StoryFn } from '@storybook/react';
|
|
3
|
+
import { Hint } from '../index';
|
|
4
|
+
|
|
5
|
+
export default {
|
|
6
|
+
title: 'Cortex-React/Hint',
|
|
7
|
+
component: <div />,
|
|
8
|
+
args: {
|
|
9
|
+
intent: 'default',
|
|
10
|
+
description: 'Hint description',
|
|
11
|
+
},
|
|
12
|
+
argTypes: {
|
|
13
|
+
intent: {
|
|
14
|
+
options: ['default', 'success', 'warning', 'error'],
|
|
15
|
+
control: { type: 'select' },
|
|
16
|
+
},
|
|
17
|
+
description: {
|
|
18
|
+
control: { type: 'text' },
|
|
19
|
+
},
|
|
20
|
+
},
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
const Template: StoryFn = args => {
|
|
24
|
+
return (
|
|
25
|
+
<Hint variants={{ intent: args.intent }} description={args.description} />
|
|
26
|
+
);
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
export const Base = {
|
|
30
|
+
render: Template,
|
|
31
|
+
args: {},
|
|
32
|
+
};
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { StoryFn } from '@storybook/react';
|
|
3
|
+
import { Input } from '../components';
|
|
4
|
+
import { IoPerson } from 'react-icons/io5';
|
|
5
|
+
import { IoEye } from 'react-icons/io5';
|
|
6
|
+
export default {
|
|
7
|
+
title: 'Cortex-React/Input/Custom',
|
|
8
|
+
component: <div />,
|
|
9
|
+
args: {
|
|
10
|
+
label: 'Label',
|
|
11
|
+
placeholder: 'Placeholder',
|
|
12
|
+
intent: 'default',
|
|
13
|
+
},
|
|
14
|
+
argTypes: {
|
|
15
|
+
intent: {
|
|
16
|
+
options: ['default', 'success', 'warning', 'error'],
|
|
17
|
+
control: { type: 'select' },
|
|
18
|
+
},
|
|
19
|
+
label: {
|
|
20
|
+
control: { type: 'text' },
|
|
21
|
+
},
|
|
22
|
+
placeholder: {
|
|
23
|
+
control: { type: 'text' },
|
|
24
|
+
},
|
|
25
|
+
},
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
const Template: StoryFn = args => {
|
|
29
|
+
return (
|
|
30
|
+
<Input.Face variants={{ intent: args.intent }}>
|
|
31
|
+
<Input.Left>
|
|
32
|
+
<IoPerson size={16} />
|
|
33
|
+
</Input.Left>
|
|
34
|
+
<Input.Box label={args.label} placeholder={args.placeholder}></Input.Box>
|
|
35
|
+
<Input.Right>
|
|
36
|
+
<IoEye />
|
|
37
|
+
</Input.Right>
|
|
38
|
+
</Input.Face>
|
|
39
|
+
);
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
export const Base = {
|
|
43
|
+
render: Template,
|
|
44
|
+
args: {},
|
|
45
|
+
};
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { StoryFn } from '@storybook/react';
|
|
3
|
+
import { Input } from '../components';
|
|
4
|
+
|
|
5
|
+
export default {
|
|
6
|
+
title: 'Cortex-React/Input',
|
|
7
|
+
component: <div />,
|
|
8
|
+
args: {
|
|
9
|
+
label: 'Label',
|
|
10
|
+
placeholder: 'Placeholder',
|
|
11
|
+
intent: 'default',
|
|
12
|
+
},
|
|
13
|
+
argTypes: {
|
|
14
|
+
intent: {
|
|
15
|
+
options: ['default', 'success', 'warning', 'error'],
|
|
16
|
+
control: { type: 'select' },
|
|
17
|
+
},
|
|
18
|
+
label: {
|
|
19
|
+
control: { type: 'text' },
|
|
20
|
+
},
|
|
21
|
+
placeholder: {
|
|
22
|
+
control: { type: 'text' },
|
|
23
|
+
},
|
|
24
|
+
},
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
const Template: StoryFn = args => {
|
|
28
|
+
return (
|
|
29
|
+
<Input.Root
|
|
30
|
+
variants={{ intent: args.intent }}
|
|
31
|
+
label={args.label}
|
|
32
|
+
placeholder={args.placeholder}
|
|
33
|
+
/>
|
|
34
|
+
);
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
export const Base = {
|
|
38
|
+
render: Template,
|
|
39
|
+
args: {},
|
|
40
|
+
};
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import React, { useState } from 'react';
|
|
2
|
+
import { StoryFn } from '@storybook/react';
|
|
3
|
+
import { Button, Modal } from '../index';
|
|
4
|
+
import { MdClose } from 'react-icons/md';
|
|
5
|
+
export default {
|
|
6
|
+
title: 'Cortex-React/Modal',
|
|
7
|
+
component: <div />,
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
const Template: StoryFn = () => {
|
|
11
|
+
const [showModal, setShowModal] = useState(false);
|
|
12
|
+
return (
|
|
13
|
+
<>
|
|
14
|
+
<Button onClick={() => setShowModal(true)}>
|
|
15
|
+
<p>Show modal</p>
|
|
16
|
+
</Button>
|
|
17
|
+
<Modal open={showModal} onClose={() => setShowModal(false)}>
|
|
18
|
+
<div className={'w-[600px] h-[80%]'}>
|
|
19
|
+
<div className={'justify-between flex flex-row'}>
|
|
20
|
+
<p className={'font-black text-h3'}>What is Lorem Ipsum?</p>
|
|
21
|
+
<MdClose
|
|
22
|
+
className={
|
|
23
|
+
'text-primary-medium text-deca cursor-pointer hover:text-primary-dark'
|
|
24
|
+
}
|
|
25
|
+
onClick={() => setShowModal(false)}
|
|
26
|
+
/>
|
|
27
|
+
</div>
|
|
28
|
+
<p className={'mt-giga'}>
|
|
29
|
+
Lorem Ipsum is simply dummy text of the printing and typesetting
|
|
30
|
+
industry. Lorem Ipsum has been the industry's standard dummy text
|
|
31
|
+
ever since the 1500s, when an unknown printer took a galley of type
|
|
32
|
+
and scrambled it to make a type specimen book. It has survived not
|
|
33
|
+
only five centuries, but also the leap into electronic typesetting,
|
|
34
|
+
remaining essentially unchanged. It was popularised in the 1960s
|
|
35
|
+
with the release of Letraset sheets containing Lorem Ipsum passages,
|
|
36
|
+
and more recently with desktop publishing software like Aldus
|
|
37
|
+
PageMaker including versions of Lorem Ipsum.
|
|
38
|
+
</p>
|
|
39
|
+
</div>
|
|
40
|
+
</Modal>
|
|
41
|
+
</>
|
|
42
|
+
);
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
export const Base = {
|
|
46
|
+
render: Template,
|
|
47
|
+
args: {},
|
|
48
|
+
};
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import React, { useState } from 'react';
|
|
2
|
+
import { StoryFn } from '@storybook/react';
|
|
3
|
+
import { Select } from '../index';
|
|
4
|
+
|
|
5
|
+
export default {
|
|
6
|
+
title: 'Cortex-React/Select/Grouped',
|
|
7
|
+
component: <div />,
|
|
8
|
+
argTypes: {
|
|
9
|
+
variant: {
|
|
10
|
+
options: ['default', 'error'],
|
|
11
|
+
control: { type: 'select' },
|
|
12
|
+
},
|
|
13
|
+
label: {
|
|
14
|
+
control: { type: 'text' },
|
|
15
|
+
},
|
|
16
|
+
placeholderSearchInput: {
|
|
17
|
+
control: { type: 'text' },
|
|
18
|
+
},
|
|
19
|
+
},
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
const Template: StoryFn = args => {
|
|
23
|
+
const [value, setValue] = useState<{ key: string; label: string }>();
|
|
24
|
+
|
|
25
|
+
const estadosECidades = new Map();
|
|
26
|
+
|
|
27
|
+
estadosECidades.set('São Paulo', [
|
|
28
|
+
{ key: 'SP1', label: 'São Paulo' },
|
|
29
|
+
{ key: 'SP2', label: 'Campinas' },
|
|
30
|
+
{ key: 'SP3', label: 'Santos' },
|
|
31
|
+
]);
|
|
32
|
+
estadosECidades.set('Rio de Janeiro', [
|
|
33
|
+
{ key: 'RJ1', label: 'Rio de Janeiro' },
|
|
34
|
+
{ key: 'RJ2', label: 'Niterói' },
|
|
35
|
+
{ key: 'RJ3', label: 'Petrópolis' },
|
|
36
|
+
]);
|
|
37
|
+
estadosECidades.set('Minas Gerais', [
|
|
38
|
+
{ key: 'MG1', label: 'Belo Horizonte' },
|
|
39
|
+
{ key: 'MG2', label: 'Uberlândia' },
|
|
40
|
+
{ key: 'MG3', label: 'Ouro Preto' },
|
|
41
|
+
]);
|
|
42
|
+
estadosECidades.set('Bahia', [
|
|
43
|
+
{ key: 'BA1', label: 'Salvador' },
|
|
44
|
+
{ key: 'BA2', label: 'Feira de Santana' },
|
|
45
|
+
{ key: 'BA3', label: 'Ilhéus' },
|
|
46
|
+
]);
|
|
47
|
+
estadosECidades.set('Paraná', [
|
|
48
|
+
{ key: 'PR1', label: 'Curitiba' },
|
|
49
|
+
{ key: 'PR2', label: 'Londrina' },
|
|
50
|
+
{ key: 'PR3', label: 'Maringá' },
|
|
51
|
+
]);
|
|
52
|
+
|
|
53
|
+
return (
|
|
54
|
+
<div className={'w-[350px]'}>
|
|
55
|
+
<Select
|
|
56
|
+
variant={args.variant}
|
|
57
|
+
label={args.label}
|
|
58
|
+
// onSearch={handleSearch}
|
|
59
|
+
placeholderSearchInput={args.placeholderSearchInput}
|
|
60
|
+
labelExtractor={op => op.label}
|
|
61
|
+
keyExtractor={op => op.key}
|
|
62
|
+
onSelect={setValue}
|
|
63
|
+
value={value}
|
|
64
|
+
grouped={true}
|
|
65
|
+
groupedLabelExtractor={labelGroup => labelGroup}
|
|
66
|
+
options={estadosECidades}
|
|
67
|
+
/>
|
|
68
|
+
</div>
|
|
69
|
+
);
|
|
70
|
+
};
|
|
71
|
+
|
|
72
|
+
export const Base = {
|
|
73
|
+
render: Template,
|
|
74
|
+
args: {
|
|
75
|
+
variant: 'default',
|
|
76
|
+
label: 'Label',
|
|
77
|
+
placeholderSearchInput: 'Placeholder Search',
|
|
78
|
+
},
|
|
79
|
+
};
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import React, { useState } from 'react';
|
|
2
|
+
import { StoryFn } from '@storybook/react';
|
|
3
|
+
import { Select } from '../index';
|
|
4
|
+
|
|
5
|
+
export default {
|
|
6
|
+
title: 'Cortex-React/Select',
|
|
7
|
+
component: <div />,
|
|
8
|
+
argTypes: {
|
|
9
|
+
variant: {
|
|
10
|
+
options: ['default', 'error'],
|
|
11
|
+
control: { type: 'select' },
|
|
12
|
+
},
|
|
13
|
+
label: {
|
|
14
|
+
control: { type: 'text' },
|
|
15
|
+
},
|
|
16
|
+
placeholderSearchInput: {
|
|
17
|
+
control: { type: 'text' },
|
|
18
|
+
},
|
|
19
|
+
},
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
const _options = [
|
|
23
|
+
{ key: '1', label: 'São paulo' },
|
|
24
|
+
{ key: '2', label: 'Rio de Janeiro' },
|
|
25
|
+
{ key: '3', label: 'Campo Grande' },
|
|
26
|
+
{ key: '4', label: 'Goiania' },
|
|
27
|
+
{ key: '5', label: 'Uberlândia' },
|
|
28
|
+
{ key: '6', label: 'Salvador' },
|
|
29
|
+
{ key: '7', label: 'São Luis' },
|
|
30
|
+
{ key: '7', label: 'Manaus' },
|
|
31
|
+
{ key: '8', label: 'Rio Branco' },
|
|
32
|
+
];
|
|
33
|
+
|
|
34
|
+
type Option = { key: string; label: string };
|
|
35
|
+
const Template: StoryFn = args => {
|
|
36
|
+
const [value, setValue] = useState<{ key: string; label: string }>();
|
|
37
|
+
const [options, setOptions] = useState<Option[]>(_options);
|
|
38
|
+
|
|
39
|
+
const handleSearch = React.useCallback((searchArg: string) => {
|
|
40
|
+
setOptions(
|
|
41
|
+
(options as Option[]).filter(item =>
|
|
42
|
+
new RegExp(searchArg, 'ig').test(item.label)
|
|
43
|
+
)
|
|
44
|
+
);
|
|
45
|
+
}, []);
|
|
46
|
+
return (
|
|
47
|
+
<div className={'w-[350px]'}>
|
|
48
|
+
<Select
|
|
49
|
+
variant={args.variant}
|
|
50
|
+
keyExtractor={op => op.key}
|
|
51
|
+
label={args.label}
|
|
52
|
+
onSearch={handleSearch}
|
|
53
|
+
placeholderSearchInput={args.placeholderSearchInput}
|
|
54
|
+
labelExtractor={op => op.label}
|
|
55
|
+
onSelect={setValue}
|
|
56
|
+
value={value}
|
|
57
|
+
options={options}
|
|
58
|
+
/>
|
|
59
|
+
</div>
|
|
60
|
+
);
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
export const Base = {
|
|
64
|
+
render: Template,
|
|
65
|
+
args: {
|
|
66
|
+
variant: 'default',
|
|
67
|
+
label: 'Label',
|
|
68
|
+
placeholderSearchInput: 'Placeholder Search',
|
|
69
|
+
},
|
|
70
|
+
};
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { StoryFn } from '@storybook/react';
|
|
3
|
+
import { Snackbar } from '../index';
|
|
4
|
+
import { defaultIntents } from './utils';
|
|
5
|
+
|
|
6
|
+
export default {
|
|
7
|
+
title: 'Cortex-React/Snackbar',
|
|
8
|
+
component: <div />,
|
|
9
|
+
args: {
|
|
10
|
+
intent: 'primary',
|
|
11
|
+
},
|
|
12
|
+
argTypes: {
|
|
13
|
+
intent: {
|
|
14
|
+
options: defaultIntents,
|
|
15
|
+
control: { type: 'select' },
|
|
16
|
+
},
|
|
17
|
+
},
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
const Template: StoryFn = args => {
|
|
21
|
+
return (
|
|
22
|
+
<Snackbar show={true} variants={{ intent: args.intent }}>
|
|
23
|
+
<p>Description snackbar</p>
|
|
24
|
+
</Snackbar>
|
|
25
|
+
);
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
export const Base = {
|
|
29
|
+
render: Template,
|
|
30
|
+
args: {},
|
|
31
|
+
};
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { StoryFn } from '@storybook/react';
|
|
3
|
+
import { Tag } from '../index';
|
|
4
|
+
|
|
5
|
+
export default {
|
|
6
|
+
title: 'Cortex-React/Tag',
|
|
7
|
+
component: <div />,
|
|
8
|
+
args: {
|
|
9
|
+
intent: 'primary',
|
|
10
|
+
},
|
|
11
|
+
argTypes: {
|
|
12
|
+
intent: {
|
|
13
|
+
options: ['success', 'primary', 'secondary', 'info', 'white'],
|
|
14
|
+
control: { type: 'select' },
|
|
15
|
+
},
|
|
16
|
+
},
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
const Template: StoryFn = args => {
|
|
20
|
+
return (
|
|
21
|
+
<div className={'flex flex-col justify-center items-center'}>
|
|
22
|
+
<Tag variants={{ intent: args.intent }} label={'Intent color'} />
|
|
23
|
+
<div className={'flex flex-row gap-x-deca mt-giga'}>
|
|
24
|
+
<Tag variants={{ intent: 'primary' }} label={'Tag label'} />
|
|
25
|
+
<Tag variants={{ intent: 'success' }} label={'Tag label'} />
|
|
26
|
+
<Tag variants={{ intent: 'info' }} label={'Tag label'} />
|
|
27
|
+
<Tag variants={{ intent: 'secondary' }} label={'Tag label'} />
|
|
28
|
+
<Tag variants={{ intent: 'white' }} label={'Tag label'} />
|
|
29
|
+
</div>
|
|
30
|
+
</div>
|
|
31
|
+
);
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
export const Base = {
|
|
35
|
+
render: Template,
|
|
36
|
+
args: {},
|
|
37
|
+
};
|