@seedgrid/fe-components 2026.9.4 → 2026.9.5
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.
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SgInputDate.d.ts","sourceRoot":"","sources":["../../src/inputs/SgInputDate.tsx"],"names":[],"mappings":"AAGA,OAAO,EAAe,KAAK,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAKnE,MAAM,MAAM,gBAAgB,GAAG,IAAI,CAAC,gBAAgB,EAAE,MAAM,CAAC,GAAG;IAC9D,mDAAmD;IACnD,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB,qEAAqE;IACrE,MAAM,CAAC,EAAE,MAAM,IAAI,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB,CAAC;
|
|
1
|
+
{"version":3,"file":"SgInputDate.d.ts","sourceRoot":"","sources":["../../src/inputs/SgInputDate.tsx"],"names":[],"mappings":"AAGA,OAAO,EAAe,KAAK,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAKnE,MAAM,MAAM,gBAAgB,GAAG,IAAI,CAAC,gBAAgB,EAAE,MAAM,CAAC,GAAG;IAC9D,mDAAmD;IACnD,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB,qEAAqE;IACrE,MAAM,CAAC,EAAE,MAAM,IAAI,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB,CAAC;AAoCF,wBAAgB,WAAW,CAAC,KAAK,EAAE,gBAAgB,2CA0JlD"}
|
|
@@ -29,6 +29,18 @@ function parseDateValue(value) {
|
|
|
29
29
|
return null;
|
|
30
30
|
return date;
|
|
31
31
|
}
|
|
32
|
+
/**
|
|
33
|
+
* Teto do widget quando o consumidor nao informa `maxDate`.
|
|
34
|
+
*
|
|
35
|
+
* O <input type="date"> aceita ano de ate 6 digitos (o calendario do HTML vai ate
|
|
36
|
+
* 275760), entao sem `max` o campo aceita "202699" no lugar de "2026". Com um `max`
|
|
37
|
+
* de ano de 4 digitos o navegador contem o segmento em 4.
|
|
38
|
+
*
|
|
39
|
+
* Vale so' para o atributo HTML: a validacao continua usando os limites que o
|
|
40
|
+
* consumidor pediu, para nenhuma mensagem de erro citar um 31/12/9999 que ninguem
|
|
41
|
+
* escolheu.
|
|
42
|
+
*/
|
|
43
|
+
const WIDGET_MAX_DATE = "9999-12-31";
|
|
32
44
|
export function SgInputDate(props) {
|
|
33
45
|
const i18n = useComponentsI18n();
|
|
34
46
|
const isDark = useDarkFlag();
|
|
@@ -86,7 +98,7 @@ export function SgInputDate(props) {
|
|
|
86
98
|
...inputProps,
|
|
87
99
|
placeholder: showStaticLabel ? " " : (inputProps?.placeholder ?? rest.hintText ?? labelText),
|
|
88
100
|
min: minDateValue,
|
|
89
|
-
max: maxDateValue,
|
|
101
|
+
max: maxDateValue ?? WIDGET_MAX_DATE,
|
|
90
102
|
readOnly: inputProps?.readOnly,
|
|
91
103
|
onChange: (event) => {
|
|
92
104
|
setHasInteracted(true);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SgPeriodSelector.d.ts","sourceRoot":"","sources":["../../src/inputs/SgPeriodSelector.tsx"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"SgPeriodSelector.d.ts","sourceRoot":"","sources":["../../src/inputs/SgPeriodSelector.tsx"],"names":[],"mappings":"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"}
|
|
@@ -296,37 +296,51 @@ export function buildPeriodOptions(config, locale = "pt-BR") {
|
|
|
296
296
|
/* ------------------------------------------------------------------ */
|
|
297
297
|
/* Componente */
|
|
298
298
|
/* ------------------------------------------------------------------ */
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
299
|
+
/**
|
|
300
|
+
* Converte o valor cru do <input type="date"> (ISO yyyy-MM-dd) em Date local.
|
|
301
|
+
*
|
|
302
|
+
* O input nativo emite um change a cada digito do ano, entao "2026" chega aqui
|
|
303
|
+
* antes como "0002", "0020" e "0202". Esses anos incompletos sao recusados, e o
|
|
304
|
+
* ano completo passa por setFullYear para escapar da regra legada do JS que
|
|
305
|
+
* mapeia ano 0..99 para 1900+ano (new Date(2, 8, 19) => 1902-09-19).
|
|
306
|
+
*/
|
|
307
307
|
function parseIsoDate(value) {
|
|
308
|
-
|
|
308
|
+
const match = /^(\d{4})-(\d{2})-(\d{2})$/.exec(value);
|
|
309
|
+
if (!match)
|
|
309
310
|
return null;
|
|
310
|
-
const
|
|
311
|
-
|
|
311
|
+
const year = Number(match[1]);
|
|
312
|
+
const month = Number(match[2]);
|
|
313
|
+
const day = Number(match[3]);
|
|
314
|
+
if (year < 1000 || month < 1 || month > 12 || day < 1 || day > 31)
|
|
312
315
|
return null;
|
|
313
|
-
|
|
316
|
+
const date = new Date(year, month - 1, day);
|
|
317
|
+
date.setFullYear(year);
|
|
318
|
+
return Number.isNaN(date.getTime()) ? null : date;
|
|
314
319
|
}
|
|
315
320
|
function SgPeriodSelectorBase(props) {
|
|
316
321
|
const { id = "sg-period-selector", label, value, onChange, permitPast = true, permitCurrent = true, permitFuture = true, permitAll = true, allowCustomPeriod = true, locale = "pt-BR", disabled, required, minDate, maxDate, referenceDate, className, error } = props;
|
|
317
322
|
const isControlled = value !== undefined;
|
|
318
323
|
const [internalPreset, setInternalPreset] = React.useState(value ?? null);
|
|
319
324
|
const selectedPreset = isControlled ? value ?? null : internalPreset;
|
|
320
|
-
|
|
321
|
-
|
|
325
|
+
// Guardamos a string crua do input (ISO ou parcial), nunca um Date reformatado:
|
|
326
|
+
// devolver ao input um texto diferente do digitado reinicia o segmento em foco
|
|
327
|
+
// e impede o usuario de terminar de digitar o ano.
|
|
328
|
+
const [customStart, setCustomStart] = React.useState("");
|
|
329
|
+
const [customEnd, setCustomEnd] = React.useState("");
|
|
322
330
|
const options = React.useMemo(() => buildPeriodOptions({ permitAll, allowCustomPeriod, permitCurrent, permitFuture, permitPast }, locale), [permitAll, allowCustomPeriod, permitCurrent, permitFuture, permitPast, locale]);
|
|
323
331
|
const resolveOptions = React.useMemo(() => ({ minDate, maxDate, locale }), [minDate, maxDate, locale]);
|
|
324
|
-
const emitCustom = React.useCallback((
|
|
332
|
+
const emitCustom = React.useCallback((startIso, endIso) => {
|
|
333
|
+
// Enquanto a data estiver incompleta o parse devolve null: melhor emitir
|
|
334
|
+
// "sem limite" do que uma data de ano 0002 no meio da digitacao.
|
|
335
|
+
const startDate = parseIsoDate(startIso);
|
|
336
|
+
const endDate = parseIsoDate(endIso);
|
|
337
|
+
startDate?.setHours(0, 0, 0, 0);
|
|
338
|
+
endDate?.setHours(23, 59, 59, 999);
|
|
325
339
|
onChange?.({
|
|
326
340
|
preset: PeriodPreset.CUSTOM,
|
|
327
341
|
label: periodPresetLabel(PeriodPreset.CUSTOM, locale),
|
|
328
|
-
startDate
|
|
329
|
-
endDate
|
|
342
|
+
startDate,
|
|
343
|
+
endDate
|
|
330
344
|
});
|
|
331
345
|
}, [locale, onChange]);
|
|
332
346
|
const handleValueChange = React.useCallback((raw) => {
|
|
@@ -346,14 +360,12 @@ function SgPeriodSelectorBase(props) {
|
|
|
346
360
|
onChange?.(resolvePeriod(preset, referenceDate ?? new Date(), resolveOptions));
|
|
347
361
|
}, [customEnd, customStart, emitCustom, isControlled, onChange, referenceDate, resolveOptions]);
|
|
348
362
|
const showCustomRange = allowCustomPeriod && selectedPreset === PeriodPreset.CUSTOM;
|
|
349
|
-
return (_jsxs("div", { className: cn("w-full max-w-[18rem]", className), children: [_jsx(SgCombobox, { id: id, label: label, source: options, value: selectedPreset ?? null, grouped: true, openOnFocus: true, enabled: disabled ? false : undefined, required: required, error: error, renderGroupHeader: (group) => group ? (_jsx("div", { className: "mt-2 border-b border-border pb-1.5 text-center text-[11px] font-bold uppercase tracking-wider text-muted-foreground", children: group })) : null, onValueChange: handleValueChange }), showCustomRange ? (_jsxs("div", { className: "mt-2 grid grid-cols-1 gap-2", children: [_jsx(SgInputDate, { id: `${id}-custom-start`, inputProps: { value:
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
setCustomEnd(parsed);
|
|
356
|
-
emitCustom(customStart, parsed);
|
|
363
|
+
return (_jsxs("div", { className: cn("w-full max-w-[18rem]", className), children: [_jsx(SgCombobox, { id: id, label: label, source: options, value: selectedPreset ?? null, grouped: true, openOnFocus: true, enabled: disabled ? false : undefined, required: required, error: error, renderGroupHeader: (group) => group ? (_jsx("div", { className: "mt-2 border-b border-border pb-1.5 text-center text-[11px] font-bold uppercase tracking-wider text-muted-foreground", children: group })) : null, onValueChange: handleValueChange }), showCustomRange ? (_jsxs("div", { className: "mt-2 grid grid-cols-1 gap-2", children: [_jsx(SgInputDate, { id: `${id}-custom-start`, inputProps: { value: customStart }, minDate: minDate, maxDate: maxDate, enabled: disabled ? false : undefined, onChange: (next) => {
|
|
364
|
+
setCustomStart(next);
|
|
365
|
+
emitCustom(next, customEnd);
|
|
366
|
+
} }), _jsx(SgInputDate, { id: `${id}-custom-end`, inputProps: { value: customEnd }, minDate: minDate, maxDate: maxDate, enabled: disabled ? false : undefined, onChange: (next) => {
|
|
367
|
+
setCustomEnd(next);
|
|
368
|
+
emitCustom(customStart, next);
|
|
357
369
|
} })] })) : null] }));
|
|
358
370
|
}
|
|
359
371
|
export function SgPeriodSelector(props) {
|