@aspprev/versi-ds 0.4.3 → 0.4.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/README.md CHANGED
@@ -90,6 +90,9 @@ import {
90
90
 
91
91
  - `OtpCodeInput` suporta `onComplete`, colagem de código, máscara, erro e controle por `value`/`values`.
92
92
  - `QRCode` suporta `description`, `ariaLabel`, `loading`, `error`, `size` e nível de correção.
93
+ - `PageHeading` e `PageTabsHeader` mantêm o bloco do título flexível em tablet/desktop, truncam títulos longos com reticências e preservam o texto completo no atributo `title` quando o título é texto simples. O retorno (`back`) e as ações continuam disponíveis.
94
+ - `Input` e `InputStandalone` aceitam `formatter={(value) => string}` para máscaras definidas pelo consumidor, sem props de domínio; as máscaras nomeadas existentes permanecem compatíveis.
95
+ - `validateFiles` retorna `code`, nome, extensão, tamanho e limite da rejeição e aceita mensagens por código; `FileViewer` também aceita `Promise<FileViewerSource>` como source.
93
96
  - Upload e `FileViewer` são controlados pelo consumidor; transporte, autenticação, persistência e download não fazem parte do pacote.
94
97
  - `DatePicker` aceita `selectionMode="year"` e mantém `selectionMode="day"` como padrão.
95
98
  - `DomainStatusBadge` aceita `statusMap` para vocabulário específico do produto.
@@ -225,3 +228,10 @@ Ao criar ou alterar um componente:
225
228
  6. execute `npm run prepack` antes de gerar o pacote.
226
229
 
227
230
  Detalhes de contratos, governança e segurança ficam na pasta `docs/`. A documentação de uso visual deve permanecer principalmente no Storybook.
231
+ ### Contratos adicionados no lote seguinte
232
+
233
+ - `Input` e `InputStandalone` preservam a posição do cursor ao aplicar um `formatter` genérico; máscaras de domínio continuam sendo definidas pelo consumidor.
234
+ - `InputSlider` usa `suffix` como prop canônica e mantém `sufix` apenas como alias de migração. `Avatar` aceita `xl` além dos tamanhos existentes.
235
+ - `validateFiles` também rejeita arquivos vazios ou inválidos, com mensagens customizáveis; `FileViewer` aceita um slot `actions`.
236
+ - `TimeSeriesChart` e `InteractiveDonutChart` expõem estados genéricos de carregamento, erro e ausência de dados.
237
+ - `BoletoBarCode` aceita `width`, `height`, `quietZone` e estado de erro; o payload de boleto continua sendo responsabilidade do consumidor.
package/dist/charts.d.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  import * as React from 'react';
2
+ import { ReactNode } from 'react';
2
3
  import { Props as Props$1 } from 'react-apexcharts';
3
4
 
4
5
  type Props = Props$1;
@@ -8,6 +9,10 @@ type InteractiveDonutOptions = NonNullable<Props["options"]>;
8
9
  type InteractiveDonutProps = Omit<Props, "options" | "series" | "type"> & {
9
10
  options?: InteractiveDonutOptions;
10
11
  series: number[];
12
+ loading?: boolean;
13
+ loadingMessage?: ReactNode;
14
+ error?: ReactNode;
15
+ emptyMessage?: ReactNode;
11
16
  colors?: string[];
12
17
  mutedColors?: string[];
13
18
  valueFormatter?: (value: number) => string;
@@ -17,18 +22,22 @@ type InteractiveDonutProps = Omit<Props, "options" | "series" | "type"> & {
17
22
  responsiveHeight?: boolean;
18
23
  highContrastOverride?: boolean;
19
24
  };
20
- declare function InteractiveDonutChart({ options, series, colors, mutedColors, valueFormatter, ariaLabel, className, chartClassName, responsiveHeight, highContrastOverride, ...rest }: InteractiveDonutProps): React.JSX.Element;
25
+ declare function InteractiveDonutChart({ options, series, loading, loadingMessage, error, emptyMessage, colors, mutedColors, valueFormatter, ariaLabel, className, chartClassName, responsiveHeight, highContrastOverride, ...rest }: InteractiveDonutProps): React.JSX.Element;
21
26
 
22
27
  type TimeSeriesChartOptions = NonNullable<Props["options"]>;
23
28
  type TimeSeriesChartProps = Omit<Props, "options"> & {
24
29
  options: TimeSeriesChartOptions;
25
30
  ariaLabel: string;
31
+ loading?: boolean;
32
+ loadingMessage?: ReactNode;
33
+ error?: ReactNode;
34
+ emptyMessage?: ReactNode;
26
35
  className?: string;
27
36
  chartClassName?: string;
28
37
  responsiveHeight?: boolean;
29
38
  highContrastOverride?: boolean;
30
39
  };
31
- declare function TimeSeriesChart({ options, ariaLabel, className, chartClassName, responsiveHeight, highContrastOverride, ...chartProps }: TimeSeriesChartProps): React.JSX.Element;
40
+ declare function TimeSeriesChart({ options, ariaLabel, loading, loadingMessage, error, emptyMessage, className, chartClassName, responsiveHeight, highContrastOverride, ...chartProps }: TimeSeriesChartProps): React.JSX.Element;
32
41
 
33
42
  type TimeRangeSelectorProps<T extends string | number> = {
34
43
  options: readonly T[];
package/dist/charts.js CHANGED
@@ -12,7 +12,7 @@ import {
12
12
  normalizeTimeSeriesTooltipColor,
13
13
  resolveInteractiveDonutColors,
14
14
  resolveRelativeDonutSelection
15
- } from "./chunk-5MRS4PDD.js";
15
+ } from "./chunk-HKCVDOGK.js";
16
16
  export {
17
17
  InteractiveDonutChart,
18
18
  LazyApexChart,
@@ -88,6 +88,23 @@ var FieldFrame_default = FieldFrame;
88
88
 
89
89
  // src/components/input/Input.tsx
90
90
  import { Fragment, jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
91
+ function getFormattedCaretPosition(rawValue, formattedValue, selectionStart, formatter, sanitize) {
92
+ if (selectionStart === null) return null;
93
+ if (selectionStart >= rawValue.length) return formattedValue.length;
94
+ const formattedSuffix = sanitize(formatter(rawValue.slice(selectionStart)));
95
+ return Math.max(
96
+ 0,
97
+ Math.min(formattedValue.length, formattedValue.length - formattedSuffix.length)
98
+ );
99
+ }
100
+ function restoreCaretPosition(inputRef, position) {
101
+ if (position === null || typeof window === "undefined") return;
102
+ window.requestAnimationFrame(() => {
103
+ const input = inputRef.current;
104
+ if (!input || document.activeElement !== input) return;
105
+ input.setSelectionRange(position, position);
106
+ });
107
+ }
91
108
  var BaseInput = React.forwardRef((props, ref) => /* @__PURE__ */ jsx2(
92
109
  "input",
93
110
  {
@@ -150,6 +167,7 @@ var Input = ({
150
167
  prefix,
151
168
  suffix,
152
169
  mask,
170
+ formatter,
153
171
  disabled,
154
172
  error,
155
173
  disallowSpaces,
@@ -248,6 +266,44 @@ var Input = ({
248
266
  };
249
267
  const renderMaskedInput = (inputType) => {
250
268
  const autoCompleteValue = rest.autoComplete;
269
+ if (formatter) {
270
+ const currentValue = String(safeValue(field.value));
271
+ return /* @__PURE__ */ jsx2(
272
+ "input",
273
+ {
274
+ ...rest,
275
+ ...accessibilityProps,
276
+ name,
277
+ ref: inputRef,
278
+ type: inputType === "date" ? "text" : inputType,
279
+ value: currentValue,
280
+ onChange: (event) => {
281
+ const rawValue = event.target.value;
282
+ const formattedValue = sanitizeValue(formatter(rawValue));
283
+ const caretPosition = getFormattedCaretPosition(
284
+ rawValue,
285
+ formattedValue,
286
+ event.target.selectionStart,
287
+ formatter,
288
+ sanitizeValue
289
+ );
290
+ helpers.setValue(formattedValue);
291
+ restoreCaretPosition(inputRef, caretPosition);
292
+ rest.onChange?.({
293
+ ...event,
294
+ target: { ...event.target, value: formattedValue },
295
+ currentTarget: { ...event.currentTarget, value: formattedValue }
296
+ });
297
+ },
298
+ onBlur: field.onBlur,
299
+ onPaste: handlePasteFormik,
300
+ placeholder,
301
+ className: classNames2(FIELD_INPUT_CLASS, className),
302
+ autoComplete: autoCompleteValue,
303
+ disabled
304
+ }
305
+ );
306
+ }
251
307
  if (mask === "currency") {
252
308
  const rawCurrencyValue = typeof field.value === "string" || typeof field.value === "number" ? field.value : "";
253
309
  return /* @__PURE__ */ jsx2(
@@ -531,6 +587,7 @@ var InputStandalone = (props) => {
531
587
  prefix,
532
588
  suffix,
533
589
  mask,
590
+ formatter,
534
591
  disabled,
535
592
  error,
536
593
  errorText,
@@ -615,6 +672,41 @@ var InputStandalone = (props) => {
615
672
  };
616
673
  const renderMaskedInput = (inputType) => {
617
674
  const autoCompleteValue = rest.autoComplete;
675
+ if (formatter) {
676
+ const currentValue = String(safeValue(rest.value));
677
+ return /* @__PURE__ */ jsx2(
678
+ "input",
679
+ {
680
+ ...rest,
681
+ ...accessibilityProps,
682
+ ref: inputRef,
683
+ type: inputType === "date" ? "text" : inputType,
684
+ value: currentValue,
685
+ onChange: (event) => {
686
+ const rawValue = event.target.value;
687
+ const formattedValue = sanitizeValue(formatter(rawValue));
688
+ const caretPosition = getFormattedCaretPosition(
689
+ rawValue,
690
+ formattedValue,
691
+ event.target.selectionStart,
692
+ formatter,
693
+ sanitizeValue
694
+ );
695
+ restoreCaretPosition(inputRef, caretPosition);
696
+ rest.onChange?.({
697
+ ...event,
698
+ target: { ...event.target, value: formattedValue },
699
+ currentTarget: { ...event.currentTarget, value: formattedValue }
700
+ });
701
+ },
702
+ onPaste: handlePasteStandalone,
703
+ placeholder: rest.placeholder,
704
+ className: classNames2(FIELD_INPUT_CLASS, className),
705
+ autoComplete: autoCompleteValue,
706
+ disabled
707
+ }
708
+ );
709
+ }
618
710
  if (mask === "currency") {
619
711
  const rawCurrencyValue = typeof rest.value === "string" || typeof rest.value === "number" ? rest.value : "";
620
712
  return /* @__PURE__ */ jsx2(
@@ -3653,4 +3745,4 @@ export {
3653
3745
  RadioCardGroup,
3654
3746
  OtpCodeInput_default
3655
3747
  };
3656
- //# sourceMappingURL=chunk-MC4MSOCM.js.map
3748
+ //# sourceMappingURL=chunk-CLXCB6LY.js.map