@soyfri/shared-library 2.0.0-beta.2 → 2.0.0-beta.4
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/.dockerignore +8 -0
- package/.github/workflows/publish.yml +107 -0
- package/.prettierrc +3 -0
- package/.storybook/main.ts +19 -0
- package/.storybook/preview.ts +14 -0
- package/.storybook/vitest.setup.ts +9 -0
- package/Dockerfile +37 -0
- package/build.js +102 -0
- package/chromatic.config.json +5 -0
- package/cleanDirectories.js +40 -0
- package/dist/README.md +243 -0
- package/dist/components/Icon/Icon.js +1 -1
- package/dist/components/Table/Table.js +1 -1
- package/dist/index.cjs +24 -0
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +7 -1
- package/dist/mui.d.ts +1 -0
- package/dist/package.json +197 -0
- package/package.json +4 -32
- package/rollup.config.cjs +87 -0
- package/src/components/ActionMenu/ActionMenu.stories.tsx +230 -0
- package/src/components/ActionMenu/ActionMenu.tsx +174 -0
- package/src/components/ActionMenu/index.ts +2 -0
- package/src/components/AppBar/AppBar.stories.tsx +272 -0
- package/src/components/AppBar/AppBar.sx.ts +32 -0
- package/src/components/AppBar/AppBar.tsx +123 -0
- package/src/components/AppBar/AppBarBrand.tsx +120 -0
- package/src/components/AppBar/AppBarContext.ts +25 -0
- package/src/components/AppBar/AppBarMenuToggle.tsx +90 -0
- package/src/components/AppBar/AppBarUserMenu.tsx +217 -0
- package/src/components/AppBar/index.ts +25 -0
- package/src/components/Autocomplete/Autocomplete.definitions.ts +477 -0
- package/src/components/Autocomplete/Autocomplete.helpers.ts +60 -0
- package/src/components/Autocomplete/Autocomplete.stories.tsx +748 -0
- package/src/components/Autocomplete/Autocomplete.sx.ts +30 -0
- package/src/components/Autocomplete/Autocomplete.tsx +361 -0
- package/src/components/Autocomplete/Autocomplete.types.ts +13 -0
- package/src/components/Autocomplete/_parts/AutocompleteChips.tsx +55 -0
- package/src/components/Autocomplete/_parts/AutocompleteLoader.tsx +17 -0
- package/src/components/Autocomplete/_parts/AutocompleteOption.tsx +31 -0
- package/src/components/Autocomplete/index.ts +12 -0
- package/src/components/Avatar/Avatar.definitions.ts +162 -0
- package/src/components/Avatar/Avatar.stories.tsx +258 -0
- package/src/components/Avatar/Avatar.tsx +206 -0
- package/src/components/Avatar/index.ts +1 -0
- package/src/components/Button/Button.definition.ts +97 -0
- package/src/components/Button/Button.stories.tsx +285 -0
- package/src/components/Button/Button.tsx +67 -0
- package/src/components/Button/index.ts +1 -0
- package/src/components/Card/Card.definition.ts +5 -0
- package/src/components/Card/Card.stories.tsx +221 -0
- package/src/components/Card/Card.sx.ts +104 -0
- package/src/components/Card/Card.tsx +200 -0
- package/src/components/Card/index.ts +9 -0
- package/src/components/Chip/Chip.definitions.ts +167 -0
- package/src/components/Chip/Chip.stories.tsx +265 -0
- package/src/components/Chip/Chip.tsx +61 -0
- package/src/components/Chip/index.ts +1 -0
- package/src/components/Column/Column.tsx +29 -0
- package/src/components/Column/index.ts +1 -0
- package/src/components/DatePicker/DatePicker.definitions.ts +228 -0
- package/src/components/DatePicker/DatePicker.helpers.ts +24 -0
- package/src/components/DatePicker/DatePicker.stories.tsx +309 -0
- package/src/components/DatePicker/DatePicker.sx.ts +33 -0
- package/src/components/DatePicker/DatePicker.tsx +189 -0
- package/src/components/DatePicker/DatePicker.types.ts +10 -0
- package/src/components/DatePicker/index.ts +9 -0
- package/src/components/DateRangePicker/DateRangePicker.definitions.ts +191 -0
- package/src/components/DateRangePicker/DateRangePicker.stories.tsx +252 -0
- package/src/components/DateRangePicker/DateRangePicker.tsx +56 -0
- package/src/components/DateRangePicker/index.ts +1 -0
- package/src/components/DateTimePicker/DateTimePicker.definitions.ts +256 -0
- package/src/components/DateTimePicker/DateTimePicker.helpers.ts +38 -0
- package/src/components/DateTimePicker/DateTimePicker.stories.tsx +418 -0
- package/src/components/DateTimePicker/DateTimePicker.sx.ts +30 -0
- package/src/components/DateTimePicker/DateTimePicker.tsx +225 -0
- package/src/components/DateTimePicker/DateTimePicker.types.ts +10 -0
- package/src/components/DateTimePicker/index.ts +9 -0
- package/src/components/Drawer/Drawer.stories.tsx +270 -0
- package/src/components/Drawer/Drawer.sx.ts +106 -0
- package/src/components/Drawer/Drawer.tsx +214 -0
- package/src/components/Drawer/DrawerContext.ts +26 -0
- package/src/components/Drawer/DrawerItem.tsx +110 -0
- package/src/components/Drawer/index.ts +10 -0
- package/src/components/Flyout/Flyout.stories.tsx +282 -0
- package/src/components/Flyout/Flyout.tsx +122 -0
- package/src/components/Flyout/index.ts +1 -0
- package/src/components/Gallery/Gallery.definition.tsx +37 -0
- package/src/components/Gallery/Gallery.stories.tsx +82 -0
- package/src/components/Gallery/Gallery.tsx +118 -0
- package/src/components/Gallery/GalleryLightbox.tsx +170 -0
- package/src/components/Gallery/GalleryMain.tsx +84 -0
- package/src/components/Gallery/GalleryThumbnails.tsx +106 -0
- package/src/components/Gallery/index.ts +1 -0
- package/src/components/Icon/Icon.stories.tsx +121 -0
- package/src/components/Icon/Icon.tsx +175 -0
- package/src/components/Icon/index.ts +2 -0
- package/src/components/Input/Input.definitions.ts +324 -0
- package/src/components/Input/Input.helpers.ts +49 -0
- package/src/components/Input/Input.stories.tsx +499 -0
- package/src/components/Input/Input.sx.ts +42 -0
- package/src/components/Input/Input.tsx +141 -0
- package/src/components/Input/Input.types.ts +10 -0
- package/src/components/Input/index.ts +9 -0
- package/src/components/InputGroup/InputGroup.definitions.ts +158 -0
- package/src/components/InputGroup/InputGroup.stories.tsx +267 -0
- package/src/components/InputGroup/InputGroup.tsx +179 -0
- package/src/components/InputGroup/index.ts +1 -0
- package/src/components/MenuButton/MenuButton.stories.tsx +197 -0
- package/src/components/MenuButton/MenuButton.tsx +100 -0
- package/src/components/MenuButton/index.ts +1 -0
- package/src/components/Modal/Modal.stories.tsx +721 -0
- package/src/components/Modal/Modal.tsx +355 -0
- package/src/components/Modal/ModalBody.tsx +16 -0
- package/src/components/Modal/ModalFooter.tsx +71 -0
- package/src/components/Modal/ModalHeader.tsx +18 -0
- package/src/components/Modal/index.ts +6 -0
- package/src/components/PageLoader/PageLoader.stories.tsx +217 -0
- package/src/components/PageLoader/PageLoader.tsx +96 -0
- package/src/components/PageLoader/index.ts +2 -0
- package/src/components/ScrollTopButton/ScrollTopButton.stories.tsx +158 -0
- package/src/components/ScrollTopButton/ScrollTopButton.tsx +135 -0
- package/src/components/ScrollTopButton/index.ts +8 -0
- package/src/components/ScrollTopButton/scrollToTop.ts +37 -0
- package/src/components/Select/Select.definitions.ts +602 -0
- package/src/components/Select/Select.helpers.ts +71 -0
- package/src/components/Select/Select.stories.tsx +687 -0
- package/src/components/Select/Select.sx.ts +14 -0
- package/src/components/Select/Select.tsx +429 -0
- package/src/components/Select/Select.types.ts +15 -0
- package/src/components/Select/_parts/SelectMenuItem.tsx +40 -0
- package/src/components/Select/_parts/SelectSearchHeader.tsx +51 -0
- package/src/components/Select/_parts/SelectValue.tsx +96 -0
- package/src/components/Select/index.ts +14 -0
- package/src/components/Stat/Stat.stories.tsx +85 -0
- package/src/components/Stat/Stat.tsx +117 -0
- package/src/components/Stat/index.ts +2 -0
- package/src/components/StatusMessage/StatusMessage.stories.tsx +130 -0
- package/src/components/StatusMessage/StatusMessage.tsx +162 -0
- package/src/components/StatusMessage/index.ts +2 -0
- package/src/components/Stepper/Step.tsx +21 -0
- package/src/components/Stepper/Stepper.definition.ts +75 -0
- package/src/components/Stepper/Stepper.stories.tsx +122 -0
- package/src/components/Stepper/Stepper.tsx +75 -0
- package/src/components/Stepper/index.ts +2 -0
- package/src/components/Table/EmptyTable.png +0 -0
- package/src/components/Table/Table.definition.ts +580 -0
- package/src/components/Table/Table.stories.tsx +853 -0
- package/src/components/Table/Table.tsx +495 -0
- package/src/components/Table/data.ts +134 -0
- package/src/components/Table/exportsUtils.ts +195 -0
- package/src/components/Table/index.ts +3 -0
- package/src/components/Table/types.ts +34 -0
- package/src/components/Tabs/Tab.definition.ts +53 -0
- package/src/components/Tabs/Tab.tsx +19 -0
- package/src/components/Tabs/Tabs.stories.tsx +118 -0
- package/src/components/Tabs/Tabs.tsx +99 -0
- package/src/components/Tabs/_tabUtils.tsx +4 -0
- package/src/components/Tabs/index.ts +2 -0
- package/src/components/Timeline/Timeline.definition.ts +43 -0
- package/src/components/Timeline/Timeline.stories.tsx +108 -0
- package/src/components/Timeline/Timeline.tsx +49 -0
- package/src/components/Timeline/TimelineItem.tsx +31 -0
- package/src/components/Timeline/index.ts +2 -0
- package/src/components/Tooltip/Tooltip.stories.tsx +129 -0
- package/src/components/Tooltip/Tooltip.tsx +58 -0
- package/src/components/Tooltip/index.ts +1 -0
- package/src/components/_shared/formField.sx.ts +118 -0
- package/src/components/_shared/resolvePreset.ts +35 -0
- package/src/hooks/ClipBoard/ClipBoard.stories.tsx +168 -0
- package/src/hooks/ClipBoard/ClipBoard.tsx +131 -0
- package/src/hooks/ClipBoard/ClipboardUnifiedDemo.tsx +111 -0
- package/src/hooks/ClipBoard/index.ts +1 -0
- package/src/hooks/Wizard/Wizard.stories.tsx +301 -0
- package/src/hooks/Wizard/WizardContext.tsx +166 -0
- package/src/hooks/Wizard/index.ts +6 -0
- package/src/hooks/Wizard/useWizard.ts +13 -0
- package/src/index.ts +17 -0
- package/src/mui.ts +54 -0
- package/src/styles.css +3 -0
- package/src/theme/componentStyles.ts +47 -0
- package/src/theme/tokens.ts +43 -0
- package/tailwind.config.js +10 -0
- package/tsconfig.json +48 -0
- package/tsup.config.js +41 -0
- package/vite.config.js +132 -0
- package/vitest.config.ts +35 -0
|
@@ -0,0 +1,418 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from '@storybook/react';
|
|
2
|
+
import React, { useState, useMemo } from 'react';
|
|
3
|
+
import {
|
|
4
|
+
Box,
|
|
5
|
+
Typography,
|
|
6
|
+
} from '@mui/material';
|
|
7
|
+
|
|
8
|
+
// Importaciones de @mui/x-date-pickers y dayjs
|
|
9
|
+
import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs';
|
|
10
|
+
import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider';
|
|
11
|
+
import { DateTimePicker as MuiDateTimePicker } from '@mui/x-date-pickers/DateTimePicker';
|
|
12
|
+
import { DateValidationError } from '@mui/x-date-pickers/models';
|
|
13
|
+
import dayjs, { Dayjs } from 'dayjs';
|
|
14
|
+
import { renderMultiSectionDigitalClockTimeView } from '@mui/x-date-pickers/timeViewRenderers';
|
|
15
|
+
|
|
16
|
+
// Importar las definiciones de las historias
|
|
17
|
+
import {
|
|
18
|
+
BasicDateTimePickerDefinition,
|
|
19
|
+
DateTimePickerWithMinMaxDefinition,
|
|
20
|
+
DateTimePickerDisabledDefinition,
|
|
21
|
+
DateTimePickerReadOnlyDefinition,
|
|
22
|
+
DateTimePickerWithInitialNullDefinition,
|
|
23
|
+
DateTimePickerSmallSizeDefinition,
|
|
24
|
+
DateTimePickerWithCustomButtonTextDefinition,
|
|
25
|
+
DateTimePickerWithButtonsDefinition,
|
|
26
|
+
DateTimePickerWithCustomInputFormatDefinition,
|
|
27
|
+
DateTimePickerEmptyWithMaskDefinition,
|
|
28
|
+
} from './DateTimePicker.definitions'; // Asegúrate de que esta ruta sea correcta
|
|
29
|
+
import { DateTimePicker } from './DateTimePicker';
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
const meta: Meta<typeof DateTimePicker> = {
|
|
33
|
+
title: 'Components/DateTimePicker',
|
|
34
|
+
component: DateTimePicker,
|
|
35
|
+
tags: ['autodocs'],
|
|
36
|
+
parameters: {
|
|
37
|
+
layout: 'centered',
|
|
38
|
+
docs: {
|
|
39
|
+
description: {
|
|
40
|
+
component: 'Un componente `DateTimePicker` personalizado de Material UI que permite seleccionar tanto la fecha como la hora.',
|
|
41
|
+
},
|
|
42
|
+
},
|
|
43
|
+
},
|
|
44
|
+
argTypes: {
|
|
45
|
+
label: { control: 'text', description: 'Etiqueta para el selector de fecha y hora.' },
|
|
46
|
+
selectedDateTime: { control: 'object', description: 'La fecha y hora actualmente seleccionada.', type: { name: 'object', required: false, value: {} } },
|
|
47
|
+
onDateTimeChange: { action: 'dateTimeChanged', description: 'Callback que se dispara cuando la fecha y hora cambian.' },
|
|
48
|
+
minDateTime: { control: 'object', description: 'La fecha y hora mínima permitida.' },
|
|
49
|
+
maxDateTime: { control: 'object', description: 'La fecha y hora máxima permitida.' },
|
|
50
|
+
disabled: { control: 'boolean', description: 'Si es verdadero, el selector estará deshabilitado.' },
|
|
51
|
+
readOnly: { control: 'boolean', description: 'Si es verdadero, el selector estará en modo de solo lectura.' },
|
|
52
|
+
inputFormat: { control: 'text', description: 'Formato de la fecha y hora en el campo de entrada (ej. "DD/MM/YYYY HH:mm").' }, // Nuevo argType
|
|
53
|
+
slotProps: { control: 'object', description: 'Propiedades pasadas a los slots internos del DateTimePicker (e.g., `textField`, `actionBar`).' },
|
|
54
|
+
clearButtonText: { control: 'text', description: 'Texto personalizado para el botón "Limpiar".', if: { arg: 'slotProps.actionBar.actions', eq: 'clear' } },
|
|
55
|
+
cancelButtonText: { control: 'text', description: 'Texto personalizado para el botón "Cancelar".', if: { arg: 'slotProps.actionBar.actions', eq: 'cancel' } },
|
|
56
|
+
acceptButtonText: { control: 'text', description: 'Texto personalizado para el botón "Aceptar".', if: { arg: 'slotProps.actionBar.actions', eq: 'accept' } },
|
|
57
|
+
},
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
export default meta;
|
|
61
|
+
type Story = StoryObj<typeof DateTimePicker>;
|
|
62
|
+
|
|
63
|
+
// =============================================================================
|
|
64
|
+
// Historias
|
|
65
|
+
// =============================================================================
|
|
66
|
+
|
|
67
|
+
export const BasicDateTimePicker: Story = {
|
|
68
|
+
render: () => {
|
|
69
|
+
const [selectedDateTime, setSelectedDateTime] = useState<Dayjs | null>(dayjs());
|
|
70
|
+
return (
|
|
71
|
+
<Box sx={{ width: 300 }}>
|
|
72
|
+
<DateTimePicker
|
|
73
|
+
label="Seleccionar Fecha y Hora"
|
|
74
|
+
selectedDateTime={selectedDateTime}
|
|
75
|
+
onDateTimeChange={setSelectedDateTime}
|
|
76
|
+
/>
|
|
77
|
+
<Typography sx={{ mt: 2 }}>
|
|
78
|
+
Seleccionado: {selectedDateTime ? selectedDateTime.format('YYYY-MM-DD HH:mm') : 'Ninguna'}
|
|
79
|
+
</Typography>
|
|
80
|
+
</Box>
|
|
81
|
+
);
|
|
82
|
+
},
|
|
83
|
+
parameters: {
|
|
84
|
+
docs: {
|
|
85
|
+
description: {
|
|
86
|
+
story: "Un `DateTimePicker` básico con selección de fecha y hora actual."
|
|
87
|
+
},
|
|
88
|
+
source: { code: BasicDateTimePickerDefinition.trim() }
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
};
|
|
92
|
+
|
|
93
|
+
export const DateTimePickerWithMinMax: Story = {
|
|
94
|
+
render: () => {
|
|
95
|
+
const [selectedDateTime, setSelectedDateTime] = useState<Dayjs | null>(dayjs('2023-06-15T10:00'));
|
|
96
|
+
const minDateTime = dayjs('2023-06-01T09:00');
|
|
97
|
+
const maxDateTime = dayjs('2023-06-30T17:00');
|
|
98
|
+
return (
|
|
99
|
+
<Box sx={{ width: 300 }}>
|
|
100
|
+
<DateTimePicker
|
|
101
|
+
label="Fecha y Hora en Junio (Rango)"
|
|
102
|
+
selectedDateTime={selectedDateTime}
|
|
103
|
+
onDateTimeChange={setSelectedDateTime}
|
|
104
|
+
minDateTime={minDateTime}
|
|
105
|
+
maxDateTime={maxDateTime}
|
|
106
|
+
/>
|
|
107
|
+
<Typography sx={{ mt: 2 }}>
|
|
108
|
+
Seleccionado: {selectedDateTime ? selectedDateTime.format('YYYY-MM-DD HH:mm') : 'Ninguna'}
|
|
109
|
+
</Typography>
|
|
110
|
+
<Typography variant="caption" color="text.secondary">
|
|
111
|
+
(Rango: ${minDateTime.format('YYYY-MM-DD HH:mm')} a ${maxDateTime.format('YYYY-MM-DD HH:mm')})
|
|
112
|
+
</Typography>
|
|
113
|
+
</Box>
|
|
114
|
+
);
|
|
115
|
+
},
|
|
116
|
+
parameters: {
|
|
117
|
+
docs: {
|
|
118
|
+
description: {
|
|
119
|
+
story: "Muestra un `DateTimePicker` con límites de fecha y hora mínimos y máximos."
|
|
120
|
+
},
|
|
121
|
+
source: { code: DateTimePickerWithMinMaxDefinition.trim() }
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
};
|
|
125
|
+
|
|
126
|
+
export const DateTimePickerDisabled: Story = {
|
|
127
|
+
render: () => {
|
|
128
|
+
const [selectedDateTime, setSelectedDateTime] = useState<Dayjs | null>(dayjs());
|
|
129
|
+
return (
|
|
130
|
+
<Box sx={{ width: 300 }}>
|
|
131
|
+
<DateTimePicker
|
|
132
|
+
label="Fecha y Hora (Deshabilitado)"
|
|
133
|
+
selectedDateTime={selectedDateTime}
|
|
134
|
+
onDateTimeChange={setSelectedDateTime}
|
|
135
|
+
disabled
|
|
136
|
+
/>
|
|
137
|
+
<Typography sx={{ mt: 2 }}>
|
|
138
|
+
Seleccionado: {selectedDateTime ? selectedDateTime.format('YYYY-MM-DD HH:mm') : 'Ninguna'}
|
|
139
|
+
</Typography>
|
|
140
|
+
</Box>
|
|
141
|
+
);
|
|
142
|
+
},
|
|
143
|
+
parameters: {
|
|
144
|
+
docs: {
|
|
145
|
+
description: {
|
|
146
|
+
story: "Demuestra un `DateTimePicker` en estado deshabilitado."
|
|
147
|
+
},
|
|
148
|
+
source: { code: DateTimePickerDisabledDefinition.trim() }
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
};
|
|
152
|
+
|
|
153
|
+
export const DateTimePickerReadOnly: Story = {
|
|
154
|
+
render: () => {
|
|
155
|
+
const [selectedDateTime, setSelectedDateTime] = useState<Dayjs | null>(dayjs('2024-07-24T14:30'));
|
|
156
|
+
return (
|
|
157
|
+
<Box sx={{ width: 300 }}>
|
|
158
|
+
<DateTimePicker
|
|
159
|
+
label="Fecha y Hora (Solo Lectura)"
|
|
160
|
+
selectedDateTime={selectedDateTime}
|
|
161
|
+
onDateTimeChange={() => {}} // No permite cambios
|
|
162
|
+
readOnly
|
|
163
|
+
/>
|
|
164
|
+
<Typography sx={{ mt: 2 }}>
|
|
165
|
+
Seleccionado: {selectedDateTime ? selectedDateTime.format('YYYY-MM-DD HH:mm') : 'Ninguna'}
|
|
166
|
+
</Typography>
|
|
167
|
+
</Box>
|
|
168
|
+
);
|
|
169
|
+
},
|
|
170
|
+
parameters: {
|
|
171
|
+
docs: {
|
|
172
|
+
description: {
|
|
173
|
+
story: "Muestra el `DateTimePicker` en modo de solo lectura."
|
|
174
|
+
},
|
|
175
|
+
source: { code: DateTimePickerReadOnlyDefinition.trim() }
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
};
|
|
179
|
+
|
|
180
|
+
export const DateTimePickerWithInitialNull: Story = {
|
|
181
|
+
render: () => {
|
|
182
|
+
const [selectedDateTime, setSelectedDateTime] = useState<Dayjs | null>(null);
|
|
183
|
+
return (
|
|
184
|
+
<Box sx={{ width: 300 }}>
|
|
185
|
+
<DateTimePicker
|
|
186
|
+
label="Fecha y Hora (Sin Selección Inicial)"
|
|
187
|
+
selectedDateTime={selectedDateTime}
|
|
188
|
+
onDateTimeChange={setSelectedDateTime}
|
|
189
|
+
/>
|
|
190
|
+
<Typography sx={{ mt: 2 }}>
|
|
191
|
+
Seleccionado: {selectedDateTime ? selectedDateTime.format('YYYY-MM-DD HH:mm') : 'Ninguna'}
|
|
192
|
+
</Typography>
|
|
193
|
+
</Box>
|
|
194
|
+
);
|
|
195
|
+
},
|
|
196
|
+
parameters: {
|
|
197
|
+
docs: {
|
|
198
|
+
description: {
|
|
199
|
+
story: "Muestra un `DateTimePicker` sin fecha y hora seleccionadas inicialmente."
|
|
200
|
+
},
|
|
201
|
+
source: { code: DateTimePickerWithInitialNullDefinition.trim() }
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
};
|
|
205
|
+
|
|
206
|
+
export const DateTimePickerEmptyWithMask: Story = {
|
|
207
|
+
render: () => {
|
|
208
|
+
const [selectedDateTime, setSelectedDateTime] = useState<Dayjs | null>(null);
|
|
209
|
+
return (
|
|
210
|
+
<Box sx={{ width: 300 }}>
|
|
211
|
+
<DateTimePicker
|
|
212
|
+
label="Fecha y Hora"
|
|
213
|
+
selectedDateTime={selectedDateTime}
|
|
214
|
+
onDateTimeChange={setSelectedDateTime}
|
|
215
|
+
inputFormat="DD/MM/YY HH:mm"
|
|
216
|
+
/>
|
|
217
|
+
<Typography sx={{ mt: 2 }} variant="caption" color="text.secondary">
|
|
218
|
+
Al estar vacío, el campo muestra la máscara del formato (DD/MM/AA HH:MM).
|
|
219
|
+
</Typography>
|
|
220
|
+
</Box>
|
|
221
|
+
);
|
|
222
|
+
},
|
|
223
|
+
parameters: {
|
|
224
|
+
docs: {
|
|
225
|
+
description: {
|
|
226
|
+
story:
|
|
227
|
+
"DateTimePicker vacío. Al no haber valor seleccionado, cada sección del campo muestra su placeholder según el `inputFormat` (por ejemplo `DD/MM/AA HH:MM`), funcionando como máscara visual."
|
|
228
|
+
},
|
|
229
|
+
source: { code: DateTimePickerEmptyWithMaskDefinition.trim() }
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
};
|
|
233
|
+
|
|
234
|
+
export const DateTimePickerSmallSize: Story = {
|
|
235
|
+
render: () => {
|
|
236
|
+
const [selectedDateTime, setSelectedDateTime] = useState<Dayjs | null>(dayjs());
|
|
237
|
+
return (
|
|
238
|
+
<Box sx={{ width: 250 }}>
|
|
239
|
+
<DateTimePicker
|
|
240
|
+
label="Fecha y Hora (Pequeño)"
|
|
241
|
+
selectedDateTime={selectedDateTime}
|
|
242
|
+
onDateTimeChange={setSelectedDateTime}
|
|
243
|
+
slotProps={{ textField: { size: 'small' } }}
|
|
244
|
+
/>
|
|
245
|
+
<Typography sx={{ mt: 2 }}>
|
|
246
|
+
Seleccionado: {selectedDateTime ? selectedDateTime.format('YYYY-MM-DD HH:mm') : 'Ninguna'}
|
|
247
|
+
</Typography>
|
|
248
|
+
</Box>
|
|
249
|
+
);
|
|
250
|
+
},
|
|
251
|
+
parameters: {
|
|
252
|
+
docs: {
|
|
253
|
+
description: {
|
|
254
|
+
story: "Demuestra cómo aplicar un tamaño más pequeño al `DateTimePicker`."
|
|
255
|
+
},
|
|
256
|
+
source: { code: DateTimePickerSmallSizeDefinition.trim() }
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
};
|
|
260
|
+
|
|
261
|
+
export const DateTimePickerWithButtons: Story = {
|
|
262
|
+
render: () => {
|
|
263
|
+
const [selectedDateTime, setSelectedDateTime] = useState<Dayjs | null>(dayjs());
|
|
264
|
+
return (
|
|
265
|
+
<Box sx={{ width: 300 }}>
|
|
266
|
+
<DateTimePicker
|
|
267
|
+
label="Fecha y Hora (Con Botones por Defecto)"
|
|
268
|
+
selectedDateTime={selectedDateTime}
|
|
269
|
+
onDateTimeChange={setSelectedDateTime}
|
|
270
|
+
slotProps={{
|
|
271
|
+
actionBar: {
|
|
272
|
+
actions: ['clear', 'cancel', 'accept'],
|
|
273
|
+
},
|
|
274
|
+
}}
|
|
275
|
+
/>
|
|
276
|
+
<Typography sx={{ mt: 2 }}>
|
|
277
|
+
Seleccionado: {selectedDateTime ? selectedDateTime.format('YYYY-MM-DD HH:mm') : 'Ninguna'}
|
|
278
|
+
</Typography>
|
|
279
|
+
</Box>
|
|
280
|
+
);
|
|
281
|
+
},
|
|
282
|
+
parameters: {
|
|
283
|
+
docs: {
|
|
284
|
+
description: {
|
|
285
|
+
story: "Muestra el `DateTimePicker` con botones de acción ('Limpiar', 'Cancelar', 'Aceptar') en el pie del selector."
|
|
286
|
+
},
|
|
287
|
+
source: { code: DateTimePickerWithButtonsDefinition.trim() }
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
};
|
|
291
|
+
|
|
292
|
+
export const DateTimePickerWithCustomButtonText: Story = {
|
|
293
|
+
render: () => {
|
|
294
|
+
const [selectedDateTime, setSelectedDateTime] = useState<Dayjs | null>(dayjs());
|
|
295
|
+
return (
|
|
296
|
+
<Box sx={{ width: 300 }}>
|
|
297
|
+
<DateTimePicker
|
|
298
|
+
label="Fecha y Hora (Botones Personalizados)"
|
|
299
|
+
selectedDateTime={selectedDateTime}
|
|
300
|
+
onDateTimeChange={setSelectedDateTime}
|
|
301
|
+
clearButtonText="Limpiar Todo"
|
|
302
|
+
cancelButtonText="Descartar"
|
|
303
|
+
acceptButtonText="Confirmar Selección"
|
|
304
|
+
slotProps={{
|
|
305
|
+
actionBar: {
|
|
306
|
+
actions: ['clear', 'cancel', 'accept'],
|
|
307
|
+
},
|
|
308
|
+
}}
|
|
309
|
+
/>
|
|
310
|
+
<Typography sx={{ mt: 2 }}>
|
|
311
|
+
Seleccionado: {selectedDateTime ? selectedDateTime.format('YYYY-MM-DD HH:mm') : 'Ninguna'}
|
|
312
|
+
</Typography>
|
|
313
|
+
</Box>
|
|
314
|
+
);
|
|
315
|
+
},
|
|
316
|
+
parameters: {
|
|
317
|
+
docs: {
|
|
318
|
+
description: {
|
|
319
|
+
story: "Demuestra cómo personalizar el texto de los botones de acción ('Limpiar', 'Cancelar', 'Aceptar') en el `DateTimePicker`."
|
|
320
|
+
},
|
|
321
|
+
source: { code: DateTimePickerWithCustomButtonTextDefinition.trim() }
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
};
|
|
325
|
+
|
|
326
|
+
export const DateTimePickerWithCustomInputFormat: Story = {
|
|
327
|
+
render: () => {
|
|
328
|
+
const [selectedDateTime, setSelectedDateTime] = useState<Dayjs | null>(dayjs());
|
|
329
|
+
return (
|
|
330
|
+
<Box sx={{ width: 300 }}>
|
|
331
|
+
<DateTimePicker
|
|
332
|
+
label="Fecha y Hora (Formato dd/MM/YYYY HH:mm)"
|
|
333
|
+
selectedDateTime={selectedDateTime}
|
|
334
|
+
onDateTimeChange={setSelectedDateTime}
|
|
335
|
+
inputFormat="DD/MM/YYYY HH:mm" // Custom date format
|
|
336
|
+
/>
|
|
337
|
+
<Typography sx={{ mt: 2 }}>
|
|
338
|
+
Seleccionado: {selectedDateTime ? selectedDateTime.format('YYYY-MM-DD HH:mm') : 'Ninguna'}
|
|
339
|
+
</Typography>
|
|
340
|
+
</Box>
|
|
341
|
+
);
|
|
342
|
+
},
|
|
343
|
+
parameters: {
|
|
344
|
+
docs: {
|
|
345
|
+
description: {
|
|
346
|
+
story: "Muestra el `DateTimePicker` con un formato de fecha y hora personalizado en el campo de entrada, por ejemplo `DD/MM/YYYY HH:mm`."
|
|
347
|
+
},
|
|
348
|
+
source: { code: DateTimePickerWithCustomInputFormatDefinition.trim() }
|
|
349
|
+
}
|
|
350
|
+
}
|
|
351
|
+
};
|
|
352
|
+
|
|
353
|
+
export const DateTimePickerWithAllMinutes: Story = {
|
|
354
|
+
render: () => {
|
|
355
|
+
const [selectedDateTime, setSelectedDateTime] = useState<Dayjs | null>(dayjs('2023-06-15T10:00'));
|
|
356
|
+
|
|
357
|
+
return (
|
|
358
|
+
<Box sx={{ width: 300 }}>
|
|
359
|
+
<DateTimePicker
|
|
360
|
+
label="Fecha y Hora en Junio (Rango)"
|
|
361
|
+
selectedDateTime={selectedDateTime}
|
|
362
|
+
onDateTimeChange={setSelectedDateTime}
|
|
363
|
+
viewRenderers={{
|
|
364
|
+
hours: renderMultiSectionDigitalClockTimeView,
|
|
365
|
+
minutes: renderMultiSectionDigitalClockTimeView,
|
|
366
|
+
}}
|
|
367
|
+
minutesStep={1}
|
|
368
|
+
timeSteps={{ minutes: 1 }} // <-- clave en varias versiones
|
|
369
|
+
/>
|
|
370
|
+
<Typography sx={{ mt: 2 }}>
|
|
371
|
+
Seleccionado: {selectedDateTime ? selectedDateTime.format('YYYY-MM-DD HH:mm') : 'Ninguna'}
|
|
372
|
+
</Typography>
|
|
373
|
+
</Box>
|
|
374
|
+
);
|
|
375
|
+
},
|
|
376
|
+
parameters: {
|
|
377
|
+
docs: {
|
|
378
|
+
description: {
|
|
379
|
+
story: "Muestra un `DateTimePicker` con todos los minutos habiles."
|
|
380
|
+
},
|
|
381
|
+
source: { code: DateTimePickerWithMinMaxDefinition.trim() }
|
|
382
|
+
}
|
|
383
|
+
}
|
|
384
|
+
};
|
|
385
|
+
|
|
386
|
+
export const DateTimePicker24h: Story = {
|
|
387
|
+
render: () => {
|
|
388
|
+
const [selectedDateTime, setSelectedDateTime] = useState<Dayjs | null>(dayjs('2023-06-15T10:00'));
|
|
389
|
+
|
|
390
|
+
return (
|
|
391
|
+
<Box sx={{ width: 300 }}>
|
|
392
|
+
<DateTimePicker
|
|
393
|
+
label="Fecha y Hora en Junio (Rango)"
|
|
394
|
+
selectedDateTime={selectedDateTime}
|
|
395
|
+
onDateTimeChange={setSelectedDateTime}
|
|
396
|
+
viewRenderers={{
|
|
397
|
+
hours: renderMultiSectionDigitalClockTimeView,
|
|
398
|
+
minutes: renderMultiSectionDigitalClockTimeView,
|
|
399
|
+
}}
|
|
400
|
+
minutesStep={1}
|
|
401
|
+
timeSteps={{ minutes: 1 }} // <-- clave en varias versiones
|
|
402
|
+
ampm={true}
|
|
403
|
+
/>
|
|
404
|
+
<Typography sx={{ mt: 2 }}>
|
|
405
|
+
Seleccionado: {selectedDateTime ? selectedDateTime.format('YYYY-MM-DD HH:mm') : 'Ninguna'}
|
|
406
|
+
</Typography>
|
|
407
|
+
</Box>
|
|
408
|
+
);
|
|
409
|
+
},
|
|
410
|
+
parameters: {
|
|
411
|
+
docs: {
|
|
412
|
+
description: {
|
|
413
|
+
story: "Muestra un `DateTimePicker` con formato de 24 horas."
|
|
414
|
+
},
|
|
415
|
+
source: { code: DateTimePickerWithMinMaxDefinition.trim() }
|
|
416
|
+
}
|
|
417
|
+
}
|
|
418
|
+
};
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import type { SxProps, Theme } from '@mui/material';
|
|
2
|
+
|
|
3
|
+
import { buildFormFieldSx } from '../_shared/formField.sx';
|
|
4
|
+
import { FIELD_INPUT_PADDING_Y } from '../../theme/tokens';
|
|
5
|
+
import type { LabelPosition } from './DateTimePicker';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Builder de sx para el DateTimePicker. Mismo patrón que DatePicker.
|
|
9
|
+
* Usa `includePickersApi: true` para soportar la API nueva de MUI X v8.
|
|
10
|
+
*/
|
|
11
|
+
export const buildDateTimePickerSx = (
|
|
12
|
+
borderRadius: number | string,
|
|
13
|
+
labelPosition: LabelPosition,
|
|
14
|
+
): SxProps<Theme> =>
|
|
15
|
+
buildFormFieldSx({
|
|
16
|
+
borderRadius,
|
|
17
|
+
labelPosition,
|
|
18
|
+
includePickersApi: true,
|
|
19
|
+
extraOutsideSx: {
|
|
20
|
+
'& .MuiInputBase-input': {
|
|
21
|
+
paddingTop: FIELD_INPUT_PADDING_Y,
|
|
22
|
+
paddingBottom: FIELD_INPUT_PADDING_Y,
|
|
23
|
+
},
|
|
24
|
+
|
|
25
|
+
'& .MuiPickersInputBase-sectionsContainer': {
|
|
26
|
+
paddingTop: FIELD_INPUT_PADDING_Y,
|
|
27
|
+
paddingBottom: FIELD_INPUT_PADDING_Y,
|
|
28
|
+
},
|
|
29
|
+
},
|
|
30
|
+
});
|
|
@@ -0,0 +1,225 @@
|
|
|
1
|
+
import React, { useMemo } from 'react';
|
|
2
|
+
import type { SxProps, Theme } from '@mui/material';
|
|
3
|
+
import { useTheme } from '@mui/material/styles';
|
|
4
|
+
import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs';
|
|
5
|
+
import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider';
|
|
6
|
+
import {
|
|
7
|
+
DateTimePicker as MuiDateTimePicker,
|
|
8
|
+
type DateTimePickerProps as MuiDateTimePickerProps,
|
|
9
|
+
} from '@mui/x-date-pickers/DateTimePicker';
|
|
10
|
+
import { DateValidationError } from '@mui/x-date-pickers/models';
|
|
11
|
+
import { Dayjs } from 'dayjs';
|
|
12
|
+
import { Controller, type Control, type RegisterOptions } from 'react-hook-form';
|
|
13
|
+
|
|
14
|
+
import { buildDateTimePickerSx } from './DateTimePicker.sx';
|
|
15
|
+
import {
|
|
16
|
+
buildLocaleText,
|
|
17
|
+
getDateTimeValidationMessage,
|
|
18
|
+
} from './DateTimePicker.helpers';
|
|
19
|
+
import { resolvePreset } from '../_shared/resolvePreset';
|
|
20
|
+
|
|
21
|
+
// ── Tipos de dominio ─────────────────────────────────────────────────────
|
|
22
|
+
export type LabelPosition = 'outside' | 'floating';
|
|
23
|
+
export type DateTimePickerSize = 'small' | 'medium';
|
|
24
|
+
|
|
25
|
+
// ── Props base ───────────────────────────────────────────────────────────
|
|
26
|
+
export interface BaseDateTimePickerProps
|
|
27
|
+
extends Omit<MuiDateTimePickerProps, 'value' | 'onChange' | 'slotProps' | 'format'> {
|
|
28
|
+
label?: string;
|
|
29
|
+
minDateTime?: Dayjs;
|
|
30
|
+
maxDateTime?: Dayjs;
|
|
31
|
+
disabled?: boolean;
|
|
32
|
+
readOnly?: boolean;
|
|
33
|
+
/** Formato de la fecha/hora. Default: 'DD/MM/YYYY HH:mm'. */
|
|
34
|
+
inputFormat?: string;
|
|
35
|
+
/** Border radius del input. Default: 10. */
|
|
36
|
+
borderRadius?: number | string;
|
|
37
|
+
/** "outside" (default) o "floating". */
|
|
38
|
+
labelPosition?: LabelPosition;
|
|
39
|
+
/** Tamaño del TextField. Default: 'small'. */
|
|
40
|
+
size?: DateTimePickerSize;
|
|
41
|
+
helperText?: string;
|
|
42
|
+
error?: boolean;
|
|
43
|
+
sx?: SxProps<Theme>;
|
|
44
|
+
className?: string;
|
|
45
|
+
/**
|
|
46
|
+
* Nombre del preset de estilo registrado en `theme.styles.DateTimePicker`.
|
|
47
|
+
* - `"default"` (o ausente) = estilo built-in del paquete.
|
|
48
|
+
* - Cualquier otro string = mergea el preset encima del estilo built-in.
|
|
49
|
+
*/
|
|
50
|
+
preset?: string;
|
|
51
|
+
/** Locale del adaptador dayjs. */
|
|
52
|
+
adapterLocale?: string;
|
|
53
|
+
/** Textos de los botones del popover. */
|
|
54
|
+
clearButtonText?: string;
|
|
55
|
+
cancelButtonText?: string;
|
|
56
|
+
acceptButtonText?: string;
|
|
57
|
+
minutesStep?: number;
|
|
58
|
+
minTime?: Dayjs;
|
|
59
|
+
customClass?: string;
|
|
60
|
+
viewRenderers?: any;
|
|
61
|
+
timeSteps?: any;
|
|
62
|
+
/** Si es true usa formato 12h, false = 24h. Default: false. */
|
|
63
|
+
ampm?: boolean;
|
|
64
|
+
textFieldProps?: Record<string, any>;
|
|
65
|
+
/** Passthrough completo a slotProps del MuiDateTimePicker. */
|
|
66
|
+
slotProps?: MuiDateTimePickerProps['slotProps'];
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
// ── Variantes discriminadas (RHF vs controlado) ──────────────────────────
|
|
70
|
+
export interface RHFDateTimePickerProps extends BaseDateTimePickerProps {
|
|
71
|
+
name: string;
|
|
72
|
+
control: Control<any>;
|
|
73
|
+
validation?: RegisterOptions;
|
|
74
|
+
selectedDateTime?: never;
|
|
75
|
+
onDateTimeChange?: never;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
export interface ControlledDateTimePickerProps extends BaseDateTimePickerProps {
|
|
79
|
+
name?: string;
|
|
80
|
+
control?: never;
|
|
81
|
+
validation?: never;
|
|
82
|
+
selectedDateTime: Dayjs | null;
|
|
83
|
+
onDateTimeChange: (dateTime: Dayjs | null) => void;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
// ── API pública final ────────────────────────────────────────────────────
|
|
87
|
+
export type DateTimePickerProps =
|
|
88
|
+
| RHFDateTimePickerProps
|
|
89
|
+
| ControlledDateTimePickerProps;
|
|
90
|
+
|
|
91
|
+
export const DateTimePicker: React.FC<DateTimePickerProps> = (props) => {
|
|
92
|
+
const {
|
|
93
|
+
label,
|
|
94
|
+
minDateTime,
|
|
95
|
+
maxDateTime,
|
|
96
|
+
disabled,
|
|
97
|
+
readOnly,
|
|
98
|
+
inputFormat,
|
|
99
|
+
borderRadius = 10,
|
|
100
|
+
labelPosition = 'outside',
|
|
101
|
+
size = 'small',
|
|
102
|
+
helperText,
|
|
103
|
+
error: errorProp,
|
|
104
|
+
sx,
|
|
105
|
+
className,
|
|
106
|
+
preset,
|
|
107
|
+
adapterLocale,
|
|
108
|
+
clearButtonText,
|
|
109
|
+
cancelButtonText,
|
|
110
|
+
acceptButtonText,
|
|
111
|
+
minutesStep,
|
|
112
|
+
minTime,
|
|
113
|
+
customClass,
|
|
114
|
+
viewRenderers,
|
|
115
|
+
timeSteps,
|
|
116
|
+
ampm = false,
|
|
117
|
+
textFieldProps,
|
|
118
|
+
slotProps: slotPropsProp,
|
|
119
|
+
...rest
|
|
120
|
+
} = props as ControlledDateTimePickerProps & {
|
|
121
|
+
control?: Control<any>;
|
|
122
|
+
validation?: RegisterOptions;
|
|
123
|
+
};
|
|
124
|
+
|
|
125
|
+
const [validationError, setValidationError] = React.useState<DateValidationError | null>(null);
|
|
126
|
+
|
|
127
|
+
const validationErrorMessage = useMemo(
|
|
128
|
+
() => getDateTimeValidationMessage(validationError),
|
|
129
|
+
[validationError],
|
|
130
|
+
);
|
|
131
|
+
|
|
132
|
+
const customLocaleText = useMemo(
|
|
133
|
+
() => buildLocaleText(clearButtonText, cancelButtonText, acceptButtonText),
|
|
134
|
+
[clearButtonText, cancelButtonText, acceptButtonText],
|
|
135
|
+
);
|
|
136
|
+
|
|
137
|
+
const theme = useTheme();
|
|
138
|
+
const presetSx = resolvePreset('DateTimePicker', preset, theme);
|
|
139
|
+
|
|
140
|
+
const mergedSx = [
|
|
141
|
+
buildDateTimePickerSx(borderRadius, labelPosition),
|
|
142
|
+
...(presetSx ? [presetSx] : []),
|
|
143
|
+
...(Array.isArray(sx) ? sx : [sx]),
|
|
144
|
+
];
|
|
145
|
+
|
|
146
|
+
const renderPicker = (
|
|
147
|
+
value: Dayjs | null,
|
|
148
|
+
onChange: (date: Dayjs | null) => void,
|
|
149
|
+
onBlur?: () => void,
|
|
150
|
+
inputRef?: React.Ref<any>,
|
|
151
|
+
rhfError?: boolean,
|
|
152
|
+
rhfHelperText?: string,
|
|
153
|
+
) => {
|
|
154
|
+
const finalError = rhfError || !!validationErrorMessage || !!errorProp;
|
|
155
|
+
const finalHelperText = rhfHelperText || validationErrorMessage || helperText;
|
|
156
|
+
|
|
157
|
+
return (
|
|
158
|
+
<LocalizationProvider
|
|
159
|
+
dateAdapter={AdapterDayjs}
|
|
160
|
+
{...(adapterLocale ? { adapterLocale } : {})}
|
|
161
|
+
>
|
|
162
|
+
<MuiDateTimePicker
|
|
163
|
+
className={customClass || className}
|
|
164
|
+
label={label}
|
|
165
|
+
value={value}
|
|
166
|
+
onChange={onChange}
|
|
167
|
+
onError={setValidationError}
|
|
168
|
+
minDateTime={minDateTime}
|
|
169
|
+
maxDateTime={maxDateTime}
|
|
170
|
+
minutesStep={minutesStep}
|
|
171
|
+
disabled={disabled}
|
|
172
|
+
readOnly={readOnly}
|
|
173
|
+
minTime={minTime}
|
|
174
|
+
format={inputFormat ?? 'DD/MM/YYYY HH:mm'}
|
|
175
|
+
viewRenderers={viewRenderers}
|
|
176
|
+
timeSteps={timeSteps}
|
|
177
|
+
ampm={ampm}
|
|
178
|
+
sx={mergedSx}
|
|
179
|
+
slotProps={{
|
|
180
|
+
...slotPropsProp,
|
|
181
|
+
textField: {
|
|
182
|
+
fullWidth: true,
|
|
183
|
+
size,
|
|
184
|
+
variant: 'outlined',
|
|
185
|
+
onBlur,
|
|
186
|
+
inputRef,
|
|
187
|
+
error: !!finalError,
|
|
188
|
+
helperText: finalHelperText,
|
|
189
|
+
...(slotPropsProp?.textField as Record<string, any> | undefined),
|
|
190
|
+
...textFieldProps,
|
|
191
|
+
} as any,
|
|
192
|
+
}}
|
|
193
|
+
localeText={customLocaleText}
|
|
194
|
+
{...(rest as any)}
|
|
195
|
+
/>
|
|
196
|
+
</LocalizationProvider>
|
|
197
|
+
);
|
|
198
|
+
};
|
|
199
|
+
|
|
200
|
+
if ('control' in props && props.control) {
|
|
201
|
+
const { name, control, validation } = props as RHFDateTimePickerProps;
|
|
202
|
+
return (
|
|
203
|
+
<Controller
|
|
204
|
+
name={name}
|
|
205
|
+
control={control}
|
|
206
|
+
rules={validation}
|
|
207
|
+
render={({ field, fieldState: { error: fieldError } }) =>
|
|
208
|
+
renderPicker(
|
|
209
|
+
field.value ?? null,
|
|
210
|
+
field.onChange,
|
|
211
|
+
field.onBlur,
|
|
212
|
+
field.ref,
|
|
213
|
+
!!fieldError,
|
|
214
|
+
fieldError?.message,
|
|
215
|
+
)
|
|
216
|
+
}
|
|
217
|
+
/>
|
|
218
|
+
);
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
const { selectedDateTime, onDateTimeChange } = props as ControlledDateTimePickerProps;
|
|
222
|
+
return renderPicker(selectedDateTime, onDateTimeChange);
|
|
223
|
+
};
|
|
224
|
+
|
|
225
|
+
export default DateTimePicker;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
// Re-export barrel para compatibilidad con imports antiguos.
|
|
2
|
+
// Los tipos ahora viven dentro de DateTimePicker.tsx.
|
|
3
|
+
export type {
|
|
4
|
+
LabelPosition,
|
|
5
|
+
DateTimePickerSize,
|
|
6
|
+
BaseDateTimePickerProps,
|
|
7
|
+
RHFDateTimePickerProps,
|
|
8
|
+
ControlledDateTimePickerProps,
|
|
9
|
+
DateTimePickerProps,
|
|
10
|
+
} from './DateTimePicker';
|