anima-ds-nucleus 1.0.0
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/LICENSE.md +20 -0
- package/README.md +109 -0
- package/dist/anima-ds.cjs.js +1332 -0
- package/dist/anima-ds.esm.js +88297 -0
- package/dist/vite.svg +1 -0
- package/package.json +76 -0
- package/src/assets/charly.png +0 -0
- package/src/components/Atoms/Alert/Alert.jsx +52 -0
- package/src/components/Atoms/Alert/Alert.stories.jsx +62 -0
- package/src/components/Atoms/Avatar/Avatar.jsx +60 -0
- package/src/components/Atoms/Avatar/Avatar.stories.jsx +61 -0
- package/src/components/Atoms/Badge/Badge.jsx +34 -0
- package/src/components/Atoms/Badge/Badge.stories.jsx +55 -0
- package/src/components/Atoms/Button/Button.jsx +281 -0
- package/src/components/Atoms/Button/Button.stories.jsx +365 -0
- package/src/components/Atoms/Divider/Divider.jsx +49 -0
- package/src/components/Atoms/Divider/Divider.stories.jsx +62 -0
- package/src/components/Atoms/Icon/Icon.jsx +361 -0
- package/src/components/Atoms/Icon/Icon.stories.jsx +115 -0
- package/src/components/Atoms/Label/Label.jsx +22 -0
- package/src/components/Atoms/Progress/Progress.jsx +49 -0
- package/src/components/Atoms/Progress/Progress.stories.jsx +88 -0
- package/src/components/Atoms/Radios/Radios.jsx +39 -0
- package/src/components/Atoms/Radios/Radios.stories.jsx +119 -0
- package/src/components/Atoms/Shadow/Shadow.stories.jsx +25 -0
- package/src/components/Atoms/Skeleton/Skeleton.jsx +50 -0
- package/src/components/Atoms/Skeleton/Skeleton.stories.jsx +55 -0
- package/src/components/Atoms/Spacing/Spacing.jsx +56 -0
- package/src/components/Atoms/Spacing/Spacing.stories.jsx +78 -0
- package/src/components/Atoms/Spinner/Spinner.jsx +47 -0
- package/src/components/Atoms/Spinner/Spinner.stories.jsx +56 -0
- package/src/components/Atoms/Toast/Toast.jsx +74 -0
- package/src/components/Atoms/Toast/Toast.stories.jsx +101 -0
- package/src/components/Atoms/Tooltip/Tooltip.jsx +49 -0
- package/src/components/Atoms/Tooltip/Tooltip.stories.jsx +58 -0
- package/src/components/Atoms/Typography/Typography.jsx +52 -0
- package/src/components/Atoms/Typography/Typography.stories.jsx +267 -0
- package/src/components/DataDisplay/AreaChart/AreaChart.jsx +95 -0
- package/src/components/DataDisplay/AreaChart/AreaChart.stories.jsx +51 -0
- package/src/components/DataDisplay/BarChart/BarChart.jsx +90 -0
- package/src/components/DataDisplay/BarChart/BarChart.stories.jsx +60 -0
- package/src/components/DataDisplay/Card/Card.jsx +31 -0
- package/src/components/DataDisplay/Card/Card.stories.jsx +50 -0
- package/src/components/DataDisplay/ColumnChart/ColumnChart.jsx +92 -0
- package/src/components/DataDisplay/ColumnChart/ColumnChart.stories.jsx +65 -0
- package/src/components/DataDisplay/DBGrid/DBGrid.jsx +138 -0
- package/src/components/DataDisplay/DBGrid/DBGrid.stories.jsx +126 -0
- package/src/components/DataDisplay/DonutChart/DonutChart.jsx +83 -0
- package/src/components/DataDisplay/DonutChart/DonutChart.stories.jsx +48 -0
- package/src/components/DataDisplay/EmptyState/EmptyState.jsx +30 -0
- package/src/components/DataDisplay/EmptyState/EmptyState.stories.jsx +42 -0
- package/src/components/DataDisplay/LineChart/LineChart.jsx +86 -0
- package/src/components/DataDisplay/LineChart/LineChart.stories.jsx +67 -0
- package/src/components/DataDisplay/List/List.jsx +30 -0
- package/src/components/DataDisplay/List/List.stories.jsx +59 -0
- package/src/components/DataDisplay/PieChart/PieChart.jsx +64 -0
- package/src/components/DataDisplay/PieChart/PieChart.stories.jsx +47 -0
- package/src/components/DataDisplay/StatCard/StatCard.jsx +55 -0
- package/src/components/DataDisplay/StatCard/StatCard.stories.jsx +59 -0
- package/src/components/DataDisplay/TagList/TagList.jsx +37 -0
- package/src/components/DataDisplay/TagList/TagList.stories.jsx +48 -0
- package/src/components/DataDisplay/Timeline/Timeline.jsx +41 -0
- package/src/components/DataDisplay/Timeline/Timeline.stories.jsx +64 -0
- package/src/components/Inputs/Checkbox/Checkbox.jsx +27 -0
- package/src/components/Inputs/Checkbox/Checkbox.stories.jsx +51 -0
- package/src/components/Inputs/DatePicker/DatePicker.jsx +55 -0
- package/src/components/Inputs/DatePicker/DatePicker.stories.jsx +52 -0
- package/src/components/Inputs/FileUpload/FileUpload.jsx +108 -0
- package/src/components/Inputs/FileUpload/FileUpload.stories.jsx +52 -0
- package/src/components/Inputs/Input/Input.jsx +50 -0
- package/src/components/Inputs/Input/Input.stories.jsx +63 -0
- package/src/components/Inputs/RadioButton/RadioButton.jsx +31 -0
- package/src/components/Inputs/RadioButton/RadioButton.stories.jsx +59 -0
- package/src/components/Inputs/Select/Select.jsx +59 -0
- package/src/components/Inputs/Select/Select.stories.jsx +66 -0
- package/src/components/Inputs/Switch/Switch.jsx +44 -0
- package/src/components/Inputs/Switch/Switch.stories.jsx +51 -0
- package/src/components/Inputs/Textarea/Textarea.jsx +51 -0
- package/src/components/Inputs/Textarea/Textarea.stories.jsx +65 -0
- package/src/components/Layout/Accordion/Accordion.jsx +58 -0
- package/src/components/Layout/Accordion/Accordion.stories.jsx +55 -0
- package/src/components/Layout/Breadcrumbs/Breadcrumbs.jsx +49 -0
- package/src/components/Layout/Breadcrumbs/Breadcrumbs.stories.jsx +44 -0
- package/src/components/Layout/Breakpoint/Breakpoint.jsx +35 -0
- package/src/components/Layout/Breakpoint/Breakpoint.stories.jsx +348 -0
- package/src/components/Layout/Drawer/Drawer.jsx +75 -0
- package/src/components/Layout/Drawer/Drawer.stories.jsx +77 -0
- package/src/components/Layout/Dropdown/Dropdown.jsx +83 -0
- package/src/components/Layout/Dropdown/Dropdown.stories.jsx +53 -0
- package/src/components/Layout/Grid/Grid.jsx +39 -0
- package/src/components/Layout/Grid/Grid.stories.jsx +546 -0
- package/src/components/Layout/Header/Header.jsx +50 -0
- package/src/components/Layout/Header/Header.stories.jsx +36 -0
- package/src/components/Layout/Layout/Layout.jsx +14 -0
- package/src/components/Layout/Layout/Layout.stories.jsx +34 -0
- package/src/components/Layout/Modal/Modal.jsx +78 -0
- package/src/components/Layout/Modal/Modal.stories.jsx +98 -0
- package/src/components/Layout/Pagination/Pagination.jsx +109 -0
- package/src/components/Layout/Pagination/Pagination.stories.jsx +62 -0
- package/src/components/Layout/Sidebar/Sidebar.jsx +57 -0
- package/src/components/Layout/Sidebar/Sidebar.stories.jsx +51 -0
- package/src/components/Layout/Stepper/Stepper.jsx +132 -0
- package/src/components/Layout/Stepper/Stepper.stories.jsx +78 -0
- package/src/components/Layout/Tabs/Tabs.jsx +63 -0
- package/src/components/Layout/Tabs/Tabs.stories.jsx +62 -0
- package/src/components/Views/ChangePasswordForm/ChangePasswordForm.jsx +125 -0
- package/src/components/Views/ChangePasswordForm/ChangePasswordForm.stories.jsx +55 -0
- package/src/components/Views/Chat/Chat.jsx +134 -0
- package/src/components/Views/Chat/Chat.stories.jsx +143 -0
- package/src/components/Views/LoginForm/LoginForm.jsx +98 -0
- package/src/components/Views/LoginForm/LoginForm.stories.jsx +55 -0
- package/src/i18n/config.js +209 -0
- package/src/index.js +60 -0
- package/src/main.jsx +510 -0
- package/src/providers/I18nProvider.jsx +13 -0
- package/src/style.css +721 -0
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import { useState } from 'react';
|
|
2
|
+
import { Select } from './Select';
|
|
3
|
+
import { I18nProvider } from '../../../providers/I18nProvider';
|
|
4
|
+
|
|
5
|
+
const options = [
|
|
6
|
+
{ value: 'option1', label: 'Option 1' },
|
|
7
|
+
{ value: 'option2', label: 'Option 2' },
|
|
8
|
+
{ value: 'option3', label: 'Option 3' },
|
|
9
|
+
{ value: 'option4', label: 'Option 4' },
|
|
10
|
+
];
|
|
11
|
+
|
|
12
|
+
export default {
|
|
13
|
+
title: 'Inputs/Select',
|
|
14
|
+
component: Select,
|
|
15
|
+
tags: ['autodocs'],
|
|
16
|
+
decorators: [
|
|
17
|
+
(Story) => (
|
|
18
|
+
<I18nProvider>
|
|
19
|
+
<Story />
|
|
20
|
+
</I18nProvider>
|
|
21
|
+
),
|
|
22
|
+
],
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
export const Default = {
|
|
26
|
+
render: () => {
|
|
27
|
+
const [value, setValue] = useState('');
|
|
28
|
+
return (
|
|
29
|
+
<Select
|
|
30
|
+
label="Select an option"
|
|
31
|
+
options={options}
|
|
32
|
+
value={value}
|
|
33
|
+
placeholder="Choose..."
|
|
34
|
+
onChange={(e) => setValue(e.target.value)}
|
|
35
|
+
/>
|
|
36
|
+
);
|
|
37
|
+
},
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
export const WithError = {
|
|
41
|
+
args: {
|
|
42
|
+
label: 'Select',
|
|
43
|
+
options: options,
|
|
44
|
+
placeholder: 'Choose an option',
|
|
45
|
+
error: 'Please select an option',
|
|
46
|
+
},
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
export const Disabled = {
|
|
50
|
+
args: {
|
|
51
|
+
label: 'Disabled Select',
|
|
52
|
+
options: options,
|
|
53
|
+
value: 'option1',
|
|
54
|
+
disabled: true,
|
|
55
|
+
},
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
export const Required = {
|
|
59
|
+
args: {
|
|
60
|
+
label: 'Required Select',
|
|
61
|
+
options: options,
|
|
62
|
+
placeholder: 'Choose an option',
|
|
63
|
+
required: true,
|
|
64
|
+
},
|
|
65
|
+
};
|
|
66
|
+
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
export const Switch = ({
|
|
2
|
+
label,
|
|
3
|
+
checked = false,
|
|
4
|
+
disabled = false,
|
|
5
|
+
onChange,
|
|
6
|
+
className = '',
|
|
7
|
+
...props
|
|
8
|
+
}) => {
|
|
9
|
+
return (
|
|
10
|
+
<label className={`flex items-center ${disabled ? 'cursor-not-allowed opacity-50' : 'cursor-pointer'} ${className}`}>
|
|
11
|
+
<div className="relative">
|
|
12
|
+
<input
|
|
13
|
+
type="checkbox"
|
|
14
|
+
checked={checked}
|
|
15
|
+
disabled={disabled}
|
|
16
|
+
onChange={onChange}
|
|
17
|
+
className="sr-only"
|
|
18
|
+
{...props}
|
|
19
|
+
/>
|
|
20
|
+
<div
|
|
21
|
+
className={`
|
|
22
|
+
w-11 h-6 rounded-full transition-colors
|
|
23
|
+
${checked ? 'bg-blue-600' : 'bg-gray-300'}
|
|
24
|
+
${disabled ? 'opacity-50' : ''}
|
|
25
|
+
`}
|
|
26
|
+
>
|
|
27
|
+
<div
|
|
28
|
+
className={`
|
|
29
|
+
absolute top-0.5 left-0.5 w-5 h-5 bg-white rounded-full
|
|
30
|
+
transition-transform duration-200 ease-in-out
|
|
31
|
+
${checked ? 'transform translate-x-5' : ''}
|
|
32
|
+
`}
|
|
33
|
+
/>
|
|
34
|
+
</div>
|
|
35
|
+
</div>
|
|
36
|
+
{label && (
|
|
37
|
+
<span className="ml-3 text-sm text-gray-700">{label}</span>
|
|
38
|
+
)}
|
|
39
|
+
</label>
|
|
40
|
+
);
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
export default Switch;
|
|
44
|
+
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { useState } from 'react';
|
|
2
|
+
import { Switch } from './Switch';
|
|
3
|
+
|
|
4
|
+
export default {
|
|
5
|
+
title: 'Inputs/Switch',
|
|
6
|
+
component: Switch,
|
|
7
|
+
tags: ['autodocs'],
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
export const Default = {
|
|
11
|
+
render: () => {
|
|
12
|
+
const [checked, setChecked] = useState(false);
|
|
13
|
+
return (
|
|
14
|
+
<Switch
|
|
15
|
+
label="Activar notificaciones"
|
|
16
|
+
checked={checked}
|
|
17
|
+
onChange={(e) => setChecked(e.target.checked)}
|
|
18
|
+
/>
|
|
19
|
+
);
|
|
20
|
+
},
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
export const Checked = {
|
|
24
|
+
args: {
|
|
25
|
+
label: 'Switch activado',
|
|
26
|
+
checked: true,
|
|
27
|
+
},
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
export const Disabled = {
|
|
31
|
+
args: {
|
|
32
|
+
label: 'Switch deshabilitado',
|
|
33
|
+
checked: false,
|
|
34
|
+
disabled: true,
|
|
35
|
+
},
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
export const DisabledChecked = {
|
|
39
|
+
args: {
|
|
40
|
+
label: 'Switch deshabilitado y activado',
|
|
41
|
+
checked: true,
|
|
42
|
+
disabled: true,
|
|
43
|
+
},
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
export const WithoutLabel = {
|
|
47
|
+
args: {
|
|
48
|
+
checked: false,
|
|
49
|
+
},
|
|
50
|
+
};
|
|
51
|
+
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { useTranslation } from 'react-i18next';
|
|
2
|
+
|
|
3
|
+
export const Textarea = ({
|
|
4
|
+
label,
|
|
5
|
+
placeholder,
|
|
6
|
+
error,
|
|
7
|
+
helperText,
|
|
8
|
+
disabled = false,
|
|
9
|
+
required = false,
|
|
10
|
+
rows = 4,
|
|
11
|
+
className = '',
|
|
12
|
+
...props
|
|
13
|
+
}) => {
|
|
14
|
+
const { t } = useTranslation();
|
|
15
|
+
|
|
16
|
+
const textareaClasses = `
|
|
17
|
+
w-full px-3 py-2 border rounded-lg
|
|
18
|
+
focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent
|
|
19
|
+
disabled:bg-gray-100 disabled:cursor-not-allowed
|
|
20
|
+
resize-y
|
|
21
|
+
${error ? 'border-red-500' : 'border-gray-300'}
|
|
22
|
+
${className}
|
|
23
|
+
`;
|
|
24
|
+
|
|
25
|
+
return (
|
|
26
|
+
<div className="w-full">
|
|
27
|
+
{label && (
|
|
28
|
+
<label className="block text-sm font-medium text-gray-700 mb-1">
|
|
29
|
+
{label}
|
|
30
|
+
{required && <span className="text-red-500 ml-1">*</span>}
|
|
31
|
+
</label>
|
|
32
|
+
)}
|
|
33
|
+
<textarea
|
|
34
|
+
rows={rows}
|
|
35
|
+
placeholder={placeholder || t('placeholder.search')}
|
|
36
|
+
disabled={disabled}
|
|
37
|
+
className={textareaClasses}
|
|
38
|
+
{...props}
|
|
39
|
+
/>
|
|
40
|
+
{error && (
|
|
41
|
+
<p className="mt-1 text-sm text-red-600">{error}</p>
|
|
42
|
+
)}
|
|
43
|
+
{helperText && !error && (
|
|
44
|
+
<p className="mt-1 text-sm text-gray-500">{helperText}</p>
|
|
45
|
+
)}
|
|
46
|
+
</div>
|
|
47
|
+
);
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
export default Textarea;
|
|
51
|
+
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { Textarea } from './Textarea';
|
|
2
|
+
import { I18nProvider } from '../../../providers/I18nProvider';
|
|
3
|
+
|
|
4
|
+
export default {
|
|
5
|
+
title: 'Inputs/Textarea',
|
|
6
|
+
component: Textarea,
|
|
7
|
+
tags: ['autodocs'],
|
|
8
|
+
decorators: [
|
|
9
|
+
(Story) => (
|
|
10
|
+
<I18nProvider>
|
|
11
|
+
<Story />
|
|
12
|
+
</I18nProvider>
|
|
13
|
+
),
|
|
14
|
+
],
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
export const Default = {
|
|
18
|
+
args: {
|
|
19
|
+
label: 'Descripción',
|
|
20
|
+
placeholder: 'Escribe tu mensaje aquí...',
|
|
21
|
+
rows: 4,
|
|
22
|
+
},
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
export const WithError = {
|
|
26
|
+
args: {
|
|
27
|
+
label: 'Comentario',
|
|
28
|
+
placeholder: 'Escribe tu comentario',
|
|
29
|
+
error: 'Este campo es requerido',
|
|
30
|
+
},
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
export const WithHelperText = {
|
|
34
|
+
args: {
|
|
35
|
+
label: 'Mensaje',
|
|
36
|
+
placeholder: 'Escribe tu mensaje',
|
|
37
|
+
helperText: 'Máximo 500 caracteres',
|
|
38
|
+
},
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
export const Disabled = {
|
|
42
|
+
args: {
|
|
43
|
+
label: 'Texto deshabilitado',
|
|
44
|
+
placeholder: 'Este campo está deshabilitado',
|
|
45
|
+
disabled: true,
|
|
46
|
+
defaultValue: 'Texto prellenado',
|
|
47
|
+
},
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
export const Required = {
|
|
51
|
+
args: {
|
|
52
|
+
label: 'Campo requerido',
|
|
53
|
+
placeholder: 'Este campo es obligatorio',
|
|
54
|
+
required: true,
|
|
55
|
+
},
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
export const Large = {
|
|
59
|
+
args: {
|
|
60
|
+
label: 'Mensaje largo',
|
|
61
|
+
placeholder: 'Escribe un mensaje largo',
|
|
62
|
+
rows: 8,
|
|
63
|
+
},
|
|
64
|
+
};
|
|
65
|
+
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { useState } from 'react';
|
|
2
|
+
import { Icon } from '../../Atoms/Icon/Icon';
|
|
3
|
+
|
|
4
|
+
export const Accordion = ({
|
|
5
|
+
items = [],
|
|
6
|
+
allowMultiple = false,
|
|
7
|
+
defaultOpen = [],
|
|
8
|
+
className = '',
|
|
9
|
+
...props
|
|
10
|
+
}) => {
|
|
11
|
+
const [openItems, setOpenItems] = useState(defaultOpen);
|
|
12
|
+
|
|
13
|
+
const toggleItem = (index) => {
|
|
14
|
+
if (allowMultiple) {
|
|
15
|
+
setOpenItems((prev) =>
|
|
16
|
+
prev.includes(index)
|
|
17
|
+
? prev.filter((i) => i !== index)
|
|
18
|
+
: [...prev, index]
|
|
19
|
+
);
|
|
20
|
+
} else {
|
|
21
|
+
setOpenItems((prev) => (prev.includes(index) ? [] : [index]));
|
|
22
|
+
}
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
if (items.length === 0) return null;
|
|
26
|
+
|
|
27
|
+
return (
|
|
28
|
+
<div className={`space-y-2 ${className}`} {...props}>
|
|
29
|
+
{items.map((item, index) => {
|
|
30
|
+
const isOpen = openItems.includes(index);
|
|
31
|
+
return (
|
|
32
|
+
<div key={index} className="border border-gray-200 rounded-lg overflow-hidden">
|
|
33
|
+
<button
|
|
34
|
+
onClick={() => toggleItem(index)}
|
|
35
|
+
className="w-full px-4 py-3 flex items-center justify-between bg-white hover:bg-gray-50 transition-colors"
|
|
36
|
+
>
|
|
37
|
+
<span className="font-medium text-gray-900">{item.title}</span>
|
|
38
|
+
<Icon
|
|
39
|
+
name="ChevronDownIcon"
|
|
40
|
+
className={`h-5 w-5 text-gray-500 transition-transform ${
|
|
41
|
+
isOpen ? 'transform rotate-180' : ''
|
|
42
|
+
}`}
|
|
43
|
+
/>
|
|
44
|
+
</button>
|
|
45
|
+
{isOpen && (
|
|
46
|
+
<div className="px-4 py-3 bg-gray-50 border-t border-gray-200">
|
|
47
|
+
{item.content}
|
|
48
|
+
</div>
|
|
49
|
+
)}
|
|
50
|
+
</div>
|
|
51
|
+
);
|
|
52
|
+
})}
|
|
53
|
+
</div>
|
|
54
|
+
);
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
export default Accordion;
|
|
58
|
+
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { Accordion } from './Accordion';
|
|
2
|
+
|
|
3
|
+
const accordionItems = [
|
|
4
|
+
{
|
|
5
|
+
title: '¿Qué es este servicio?',
|
|
6
|
+
content: (
|
|
7
|
+
<p className="text-gray-600">
|
|
8
|
+
Este es un servicio que permite gestionar y organizar información de manera eficiente.
|
|
9
|
+
</p>
|
|
10
|
+
),
|
|
11
|
+
},
|
|
12
|
+
{
|
|
13
|
+
title: '¿Cómo puedo empezar?',
|
|
14
|
+
content: (
|
|
15
|
+
<p className="text-gray-600">
|
|
16
|
+
Puedes empezar creando una cuenta y siguiendo el proceso de registro.
|
|
17
|
+
</p>
|
|
18
|
+
),
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
title: '¿Hay algún costo?',
|
|
22
|
+
content: (
|
|
23
|
+
<p className="text-gray-600">
|
|
24
|
+
El servicio tiene un plan gratuito y planes premium disponibles.
|
|
25
|
+
</p>
|
|
26
|
+
),
|
|
27
|
+
},
|
|
28
|
+
];
|
|
29
|
+
|
|
30
|
+
export default {
|
|
31
|
+
title: 'Layout/Accordion',
|
|
32
|
+
component: Accordion,
|
|
33
|
+
tags: ['autodocs'],
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
export const Default = {
|
|
37
|
+
args: {
|
|
38
|
+
items: accordionItems,
|
|
39
|
+
},
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
export const AllowMultiple = {
|
|
43
|
+
args: {
|
|
44
|
+
items: accordionItems,
|
|
45
|
+
allowMultiple: true,
|
|
46
|
+
},
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
export const DefaultOpen = {
|
|
50
|
+
args: {
|
|
51
|
+
items: accordionItems,
|
|
52
|
+
defaultOpen: [0],
|
|
53
|
+
},
|
|
54
|
+
};
|
|
55
|
+
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { Icon } from '../../Atoms/Icon/Icon';
|
|
2
|
+
|
|
3
|
+
export const Breadcrumbs = ({
|
|
4
|
+
items = [],
|
|
5
|
+
separator = '/',
|
|
6
|
+
className = '',
|
|
7
|
+
...props
|
|
8
|
+
}) => {
|
|
9
|
+
if (items.length === 0) return null;
|
|
10
|
+
|
|
11
|
+
return (
|
|
12
|
+
<nav className={className} aria-label="Breadcrumb" {...props}>
|
|
13
|
+
<ol className="flex items-center space-x-2">
|
|
14
|
+
{items.map((item, index) => {
|
|
15
|
+
const isLast = index === items.length - 1;
|
|
16
|
+
return (
|
|
17
|
+
<li key={index} className="flex items-center">
|
|
18
|
+
{index > 0 && (
|
|
19
|
+
<span className="mx-2 text-gray-400">
|
|
20
|
+
{separator === 'icon' ? (
|
|
21
|
+
<Icon name="ChevronRightIcon" className="h-4 w-4" />
|
|
22
|
+
) : (
|
|
23
|
+
separator
|
|
24
|
+
)}
|
|
25
|
+
</span>
|
|
26
|
+
)}
|
|
27
|
+
{isLast ? (
|
|
28
|
+
<span className="text-gray-500 font-medium" aria-current="page">
|
|
29
|
+
{item.label}
|
|
30
|
+
</span>
|
|
31
|
+
) : (
|
|
32
|
+
<a
|
|
33
|
+
href={item.href || '#'}
|
|
34
|
+
className="text-gray-500 hover:text-gray-700"
|
|
35
|
+
onClick={item.onClick}
|
|
36
|
+
>
|
|
37
|
+
{item.label}
|
|
38
|
+
</a>
|
|
39
|
+
)}
|
|
40
|
+
</li>
|
|
41
|
+
);
|
|
42
|
+
})}
|
|
43
|
+
</ol>
|
|
44
|
+
</nav>
|
|
45
|
+
);
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
export default Breadcrumbs;
|
|
49
|
+
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { Breadcrumbs } from './Breadcrumbs';
|
|
2
|
+
|
|
3
|
+
const breadcrumbItems = [
|
|
4
|
+
{ label: 'Inicio', href: '#' },
|
|
5
|
+
{ label: 'Productos', href: '#' },
|
|
6
|
+
{ label: 'Electrónica', href: '#' },
|
|
7
|
+
{ label: 'Smartphones' },
|
|
8
|
+
];
|
|
9
|
+
|
|
10
|
+
export default {
|
|
11
|
+
title: 'Layout/Breadcrumbs',
|
|
12
|
+
component: Breadcrumbs,
|
|
13
|
+
tags: ['autodocs'],
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
export const Default = {
|
|
17
|
+
args: {
|
|
18
|
+
items: breadcrumbItems,
|
|
19
|
+
},
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
export const WithIconSeparator = {
|
|
23
|
+
args: {
|
|
24
|
+
items: breadcrumbItems,
|
|
25
|
+
separator: 'icon',
|
|
26
|
+
},
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
export const CustomSeparator = {
|
|
30
|
+
args: {
|
|
31
|
+
items: breadcrumbItems,
|
|
32
|
+
separator: '>',
|
|
33
|
+
},
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
export const Simple = {
|
|
37
|
+
args: {
|
|
38
|
+
items: [
|
|
39
|
+
{ label: 'Inicio', href: '#' },
|
|
40
|
+
{ label: 'Página actual' },
|
|
41
|
+
],
|
|
42
|
+
},
|
|
43
|
+
};
|
|
44
|
+
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
export const Breakpoint = ({ children, min, max, className = '', ...props }) => {
|
|
2
|
+
if (!min && !max) {
|
|
3
|
+
return null;
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
const breakpointMap = {
|
|
7
|
+
'breakpoint-sm': { min: 'var(--breakpoint-sm)', max: 'var(--breakpoint-sm-max)' },
|
|
8
|
+
'breakpoint-md': { min: 'var(--breakpoint-md)', max: 'var(--breakpoint-md-max)' },
|
|
9
|
+
'breakpoint-base': { min: 'var(--breakpoint-base)', max: 'var(--breakpoint-base-max)' },
|
|
10
|
+
'breakpoint-lg': { min: 'var(--breakpoint-lg)', max: 'none' },
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
const breakpoint = breakpointMap[min] || breakpointMap[max];
|
|
14
|
+
if (!breakpoint) {
|
|
15
|
+
return null;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
const style = {
|
|
19
|
+
'--breakpoint-min': breakpoint.min,
|
|
20
|
+
'--breakpoint-max': breakpoint.max === 'none' ? '9999px' : breakpoint.max,
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
return (
|
|
24
|
+
<div
|
|
25
|
+
className={`breakpoint-container ${className}`.trim()}
|
|
26
|
+
style={style}
|
|
27
|
+
{...props}
|
|
28
|
+
>
|
|
29
|
+
{children}
|
|
30
|
+
</div>
|
|
31
|
+
);
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
export default Breakpoint;
|
|
35
|
+
|