periplo-ui 4.4.2 → 4.6.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.
Files changed (34) hide show
  1. package/dist/components/Checkbox/Checkbox.d.ts +4 -4
  2. package/dist/components/Checkbox/Checkbox.js +3 -1
  3. package/dist/components/Checkbox/Checkbox.js.map +1 -1
  4. package/dist/components/DataTable/DataTable.d.ts +1 -1
  5. package/dist/components/DataTable/DataTable.js +49 -18
  6. package/dist/components/DataTable/DataTable.js.map +1 -1
  7. package/dist/components/DataTable/components/DataTableBody.d.ts +12 -3
  8. package/dist/components/DataTable/components/DataTableBody.js +43 -8
  9. package/dist/components/DataTable/components/DataTableBody.js.map +1 -1
  10. package/dist/components/DataTable/components/DataTableGroupRow.d.ts +10 -0
  11. package/dist/components/DataTable/components/DataTableGroupRow.js +25 -0
  12. package/dist/components/DataTable/components/DataTableGroupRow.js.map +1 -0
  13. package/dist/components/DataTable/components/DataTableGroupRowSelector.d.ts +9 -0
  14. package/dist/components/DataTable/components/DataTableGroupRowSelector.js +32 -0
  15. package/dist/components/DataTable/components/DataTableGroupRowSelector.js.map +1 -0
  16. package/dist/components/DataTable/components/DataTableSelectHeader.js +16 -10
  17. package/dist/components/DataTable/components/DataTableSelectHeader.js.map +1 -1
  18. package/dist/components/DataTable/hooks/useGroupExpansion.d.ts +19 -0
  19. package/dist/components/DataTable/hooks/useGroupExpansion.js +34 -0
  20. package/dist/components/DataTable/hooks/useGroupExpansion.js.map +1 -0
  21. package/dist/components/DataTable/types.d.ts +27 -6
  22. package/dist/components/DataTable/utils.d.ts +6 -0
  23. package/dist/components/DataTable/utils.js +15 -0
  24. package/dist/components/DataTable/utils.js.map +1 -0
  25. package/dist/components/InputDate/InputDate.d.ts +9 -11
  26. package/dist/components/InputDate/InputDate.js +91 -113
  27. package/dist/components/InputDate/InputDate.js.map +1 -1
  28. package/package.json +6 -3
  29. package/dist/components/InputDate/MaskedInput.d.ts +0 -18
  30. package/dist/components/InputDate/MaskedInput.js +0 -227
  31. package/dist/components/InputDate/MaskedInput.js.map +0 -1
  32. package/dist/components/InputDate/manualDateFormat.d.ts +0 -11
  33. package/dist/components/InputDate/manualDateFormat.js +0 -60
  34. package/dist/components/InputDate/manualDateFormat.js.map +0 -1
@@ -0,0 +1,34 @@
1
+ import * as React from 'react';
2
+
3
+ function useGroupExpansion({
4
+ grouping,
5
+ data,
6
+ getRowId
7
+ }) {
8
+ const [internalExpanded, setInternalExpanded] = React.useState(grouping?.defaultOpen ? true : {});
9
+ const expandedState = grouping?.open ?? internalExpanded;
10
+ const setExpandedState = grouping?.onOpenChange ?? setInternalExpanded;
11
+ const isGroupOpen = React.useCallback(
12
+ (groupId) => expandedState === true || typeof expandedState === "object" && expandedState[groupId] === true,
13
+ [expandedState]
14
+ );
15
+ const groupIds = React.useMemo(
16
+ () => grouping ? data.filter((item) => (grouping.getSubRows(item)?.length ?? 0) > 0).map(getRowId) : [],
17
+ [grouping, data, getRowId]
18
+ );
19
+ const toggleGroup = React.useCallback(
20
+ (groupId) => {
21
+ const updater = (prev) => {
22
+ const current = prev === true ? Object.fromEntries(groupIds.map((id) => [id, true])) : { ...prev };
23
+ current[groupId] = !current[groupId];
24
+ return current;
25
+ };
26
+ setExpandedState(updater);
27
+ },
28
+ [setExpandedState, groupIds]
29
+ );
30
+ return { isGroupOpen, toggleGroup };
31
+ }
32
+
33
+ export { useGroupExpansion };
34
+ //# sourceMappingURL=useGroupExpansion.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useGroupExpansion.js","sources":["../../../../src/components/DataTable/hooks/useGroupExpansion.ts"],"sourcesContent":["import { ExpandedState, Updater } from '@tanstack/react-table'\nimport * as React from 'react'\n\nimport { GroupingConfig, RowIdentifierFn } from '../types'\n\ntype UseGroupExpansionParams<TData> = {\n grouping?: GroupingConfig<TData>\n data: Array<TData>\n getRowId: RowIdentifierFn<TData>\n}\n\ntype UseGroupExpansionResult = {\n /** Whether the group identified by `groupId` is currently expanded. */\n isGroupOpen: (groupId: string) => boolean\n /** Toggles the expanded state of the group identified by `groupId`. */\n toggleGroup: (groupId: string) => void\n}\n\n/**\n * Encapsulates the expanded-state bookkeeping for grouped tables: tracks which\n * groups are open (supporting both controlled and uncontrolled modes) and\n * exposes helpers to query and toggle individual groups.\n */\nexport function useGroupExpansion<TData>({\n grouping,\n data,\n getRowId,\n}: UseGroupExpansionParams<TData>): UseGroupExpansionResult {\n const [internalExpanded, setInternalExpanded] = React.useState<ExpandedState>(grouping?.defaultOpen ? true : {})\n\n const expandedState = grouping?.open ?? internalExpanded\n const setExpandedState = grouping?.onOpenChange ?? setInternalExpanded\n\n const isGroupOpen = React.useCallback(\n (groupId: string) =>\n expandedState === true || (typeof expandedState === 'object' && expandedState[groupId] === true),\n [expandedState],\n )\n\n const groupIds = React.useMemo(\n () => (grouping ? data.filter((item) => (grouping.getSubRows(item)?.length ?? 0) > 0).map(getRowId) : []),\n [grouping, data, getRowId],\n )\n\n const toggleGroup = React.useCallback(\n (groupId: string) => {\n const updater = (prev: ExpandedState): ExpandedState => {\n const current = prev === true ? Object.fromEntries(groupIds.map((id) => [id, true])) : { ...prev }\n current[groupId] = !current[groupId]\n return current\n }\n ;(setExpandedState as (u: Updater<ExpandedState>) => void)(updater)\n },\n [setExpandedState, groupIds],\n )\n\n return { isGroupOpen, toggleGroup }\n}\n"],"names":[],"mappings":";;AAuBO,SAAS,iBAAA,CAAyB;AAAA,EACvC,QAAA;AAAA,EACA,IAAA;AAAA,EACA;AACF,CAAA,EAA4D;AAC1D,EAAA,MAAM,CAAC,gBAAA,EAAkB,mBAAmB,CAAA,GAAI,KAAA,CAAM,SAAwB,QAAA,EAAU,WAAA,GAAc,IAAA,GAAO,EAAE,CAAA;AAE/G,EAAA,MAAM,aAAA,GAAgB,UAAU,IAAA,IAAQ,gBAAA;AACxC,EAAA,MAAM,gBAAA,GAAmB,UAAU,YAAA,IAAgB,mBAAA;AAEnD,EAAA,MAAM,cAAc,KAAA,CAAM,WAAA;AAAA,IACxB,CAAC,YACC,aAAA,KAAkB,IAAA,IAAS,OAAO,aAAA,KAAkB,QAAA,IAAY,aAAA,CAAc,OAAO,CAAA,KAAM,IAAA;AAAA,IAC7F,CAAC,aAAa;AAAA,GAChB;AAEA,EAAA,MAAM,WAAW,KAAA,CAAM,OAAA;AAAA,IACrB,MAAO,QAAA,GAAW,IAAA,CAAK,MAAA,CAAO,CAAC,UAAU,QAAA,CAAS,UAAA,CAAW,IAAI,CAAA,EAAG,UAAU,CAAA,IAAK,CAAC,EAAE,GAAA,CAAI,QAAQ,IAAI,EAAC;AAAA,IACvG,CAAC,QAAA,EAAU,IAAA,EAAM,QAAQ;AAAA,GAC3B;AAEA,EAAA,MAAM,cAAc,KAAA,CAAM,WAAA;AAAA,IACxB,CAAC,OAAA,KAAoB;AACnB,MAAA,MAAM,OAAA,GAAU,CAAC,IAAA,KAAuC;AACtD,QAAA,MAAM,UAAU,IAAA,KAAS,IAAA,GAAO,MAAA,CAAO,WAAA,CAAY,SAAS,GAAA,CAAI,CAAC,EAAA,KAAO,CAAC,IAAI,IAAI,CAAC,CAAC,CAAA,GAAI,EAAE,GAAG,IAAA,EAAK;AACjG,QAAA,OAAA,CAAQ,OAAO,CAAA,GAAI,CAAC,OAAA,CAAQ,OAAO,CAAA;AACnC,QAAA,OAAO,OAAA;AAAA,MACT,CAAA;AACC,MAAC,iBAAyD,OAAO,CAAA;AAAA,IACpE,CAAA;AAAA,IACA,CAAC,kBAAkB,QAAQ;AAAA,GAC7B;AAEA,EAAA,OAAO,EAAE,aAAa,WAAA,EAAY;AACpC;;;;"}
@@ -1,4 +1,4 @@
1
- import { ColumnDef, OnChangeFn, VisibilityState } from '@tanstack/react-table';
1
+ import { ColumnDef, ExpandedState, OnChangeFn, Row, VisibilityState } from '@tanstack/react-table';
2
2
  import { ReactNode } from 'react';
3
3
  export type User = {
4
4
  id: string;
@@ -107,7 +107,19 @@ export type BackendPaginationProps = {
107
107
  /** Callback when page changes */
108
108
  readonly onPageChange: (page: number) => void;
109
109
  } & BasePaginationProps;
110
- export type DataTableProps<TData> = {
110
+ export type GroupingConfig<TData> = {
111
+ /** Returns the children for a row. Return `undefined`/empty for leaf rows (no group). */
112
+ readonly getSubRows: (row: TData) => Array<TData> | undefined;
113
+ /** Whether all groups are expanded on first render (default: `false`, all collapsed). */
114
+ readonly defaultOpen?: boolean;
115
+ /** Controlled expanded state. When provided, you must manage it via `onOpenChange`. */
116
+ readonly open?: ExpandedState;
117
+ /** Callback when the expanded state changes (controlled mode). */
118
+ readonly onOpenChange?: OnChangeFn<ExpandedState>;
119
+ /** Renders the content of a group row (label, count, etc.). Defaults to an item count. */
120
+ readonly renderGroupRow?: (row: Row<TData>) => ReactNode;
121
+ };
122
+ type DataTableBaseProps<TData> = {
111
123
  /** Array of column definitions that describe the table structure */
112
124
  readonly columns: Array<ColumnDef<TData>>;
113
125
  /** Array of data items to be displayed in the table */
@@ -116,8 +128,6 @@ export type DataTableProps<TData> = {
116
128
  readonly columnVisibility?: ColumnVisibilityConfig;
117
129
  /** Whether the table is in a loading state */
118
130
  readonly isLoading?: boolean;
119
- /** Pagination configuration. If not provided, pagination is disabled */
120
- readonly pagination?: BasePaginationProps | BackendPaginationProps;
121
131
  /** Primary filters that appear directly above the table */
122
132
  readonly primaryFilters?: ReactNode;
123
133
  /** Secondary filters that appear in the filters dropdown */
@@ -154,13 +164,23 @@ export type DataTableProps<TData> = {
154
164
  readonly className?: string;
155
165
  /** Optional className for the table */
156
166
  readonly tableClassName?: string;
157
- } & (HasId<TData> extends true ? {
167
+ };
168
+ type IdProps<TData> = HasId<TData> extends true ? {
158
169
  /** Function to get unique identifier from a row. Not needed when data has 'id' property */
159
170
  readonly getRowId?: RowIdentifierFn<TData>;
160
171
  } : {
161
172
  /** Function to get unique identifier from a row. Required when data doesn't have 'id' property */
162
173
  readonly getRowId: RowIdentifierFn<TData>;
163
- });
174
+ };
175
+ type PaginatedVariant = {
176
+ readonly pagination?: BasePaginationProps | BackendPaginationProps;
177
+ readonly grouping?: never;
178
+ };
179
+ type GroupedVariant<TData> = {
180
+ readonly grouping: GroupingConfig<TData>;
181
+ readonly pagination?: never;
182
+ };
183
+ export type DataTableProps<TData> = DataTableBaseProps<TData> & IdProps<TData> & (PaginatedVariant | GroupedVariant<TData>);
164
184
  /**
165
185
  * Type helper to check if a type has an 'id' property
166
186
  */
@@ -171,3 +191,4 @@ export type HasId<T> = T extends {
171
191
  * Function to get a unique identifier from a row
172
192
  */
173
193
  export type RowIdentifierFn<T> = (row: T) => string;
194
+ export {};
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Recursively flattens a sub-row tree into its leaf items, discarding group
3
+ * nodes. Used so selection (counts, select-all, ids) operates over the actual
4
+ * selectable leaf rows rather than the group containers.
5
+ */
6
+ export declare function flattenLeaves<TData>(data: Array<TData>, getSubRows: (row: TData) => Array<TData> | undefined): Array<TData>;
@@ -0,0 +1,15 @@
1
+ function flattenLeaves(data, getSubRows) {
2
+ const leaves = [];
3
+ for (const item of data) {
4
+ const children = getSubRows(item);
5
+ if (children && children.length > 0) {
6
+ leaves.push(...flattenLeaves(children, getSubRows));
7
+ } else {
8
+ leaves.push(item);
9
+ }
10
+ }
11
+ return leaves;
12
+ }
13
+
14
+ export { flattenLeaves };
15
+ //# sourceMappingURL=utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.js","sources":["../../../src/components/DataTable/utils.ts"],"sourcesContent":["/**\n * Recursively flattens a sub-row tree into its leaf items, discarding group\n * nodes. Used so selection (counts, select-all, ids) operates over the actual\n * selectable leaf rows rather than the group containers.\n */\nexport function flattenLeaves<TData>(\n data: Array<TData>,\n getSubRows: (row: TData) => Array<TData> | undefined,\n): Array<TData> {\n const leaves: Array<TData> = []\n for (const item of data) {\n const children = getSubRows(item)\n if (children && children.length > 0) {\n leaves.push(...flattenLeaves(children, getSubRows))\n } else {\n leaves.push(item)\n }\n }\n return leaves\n}\n"],"names":[],"mappings":"AAKO,SAAS,aAAA,CACd,MACA,UAAA,EACc;AACd,EAAA,MAAM,SAAuB,EAAC;AAC9B,EAAA,KAAA,MAAW,QAAQ,IAAA,EAAM;AACvB,IAAA,MAAM,QAAA,GAAW,WAAW,IAAI,CAAA;AAChC,IAAA,IAAI,QAAA,IAAY,QAAA,CAAS,MAAA,GAAS,CAAA,EAAG;AACnC,MAAA,MAAA,CAAO,IAAA,CAAK,GAAG,aAAA,CAAc,QAAA,EAAU,UAAU,CAAC,CAAA;AAAA,IACpD,CAAA,MAAO;AACL,MAAA,MAAA,CAAO,KAAK,IAAI,CAAA;AAAA,IAClB;AAAA,EACF;AACA,EAAA,OAAO,MAAA;AACT;;;;"}
@@ -1,27 +1,25 @@
1
- import { DateInputFormat } from './manualDateFormat';
1
+ import { DateField, DateValue } from 'react-aria-components';
2
2
  import * as React from 'react';
3
3
  export type InputDateProps = {
4
4
  className?: string;
5
- endContent?: React.ReactElement;
6
5
  disabled?: boolean;
7
6
  error?: boolean | string;
8
7
  errorMessage?: string;
9
8
  inputClassName?: string;
10
- inputFormat?: DateInputFormat;
9
+ locale?: string;
11
10
  onClear?: boolean | (() => void);
12
- value?: string;
13
- onChange?: (event: React.ChangeEvent<HTMLInputElement>) => void;
14
- } & Omit<React.InputHTMLAttributes<HTMLInputElement>, 'value' | 'onChange' | 'type'>;
11
+ value?: DateValue | null;
12
+ onChange?: (date: DateValue | null) => void;
13
+ } & Omit<React.ComponentPropsWithoutRef<typeof DateField<DateValue>>, 'value' | 'onChange'>;
15
14
  declare const InputDate: React.ForwardRefExoticComponent<{
16
15
  className?: string;
17
- endContent?: React.ReactElement;
18
16
  disabled?: boolean;
19
17
  error?: boolean | string;
20
18
  errorMessage?: string;
21
19
  inputClassName?: string;
22
- inputFormat?: DateInputFormat;
20
+ locale?: string;
23
21
  onClear?: boolean | (() => void);
24
- value?: string;
25
- onChange?: (event: React.ChangeEvent<HTMLInputElement>) => void;
26
- } & Omit<React.InputHTMLAttributes<HTMLInputElement>, "onChange" | "value" | "type"> & React.RefAttributes<HTMLInputElement>>;
22
+ value?: DateValue | null;
23
+ onChange?: (date: DateValue | null) => void;
24
+ } & Omit<Omit<import('react-aria-components').DateFieldProps<DateValue> & React.RefAttributes<HTMLDivElement>, "ref">, "onChange" | "value"> & React.RefAttributes<HTMLDivElement>>;
27
25
  export { InputDate };
@@ -2,25 +2,14 @@ import { jsxs, jsx } from 'react/jsx-runtime';
2
2
  import { CalendarBlank } from '@phosphor-icons/react/dist/ssr/CalendarBlank';
3
3
  import { WarningCircle } from '@phosphor-icons/react/dist/ssr/WarningCircle';
4
4
  import { X } from '@phosphor-icons/react/dist/ssr/X';
5
+ import { I18nProvider } from 'react-aria';
5
6
  import * as React from 'react';
6
- import { MaskedInput } from './MaskedInput.js';
7
+ import { DateField, Group, DateInput, DateSegment } from 'react-aria-components';
7
8
  import { cn } from '../../lib/utils.js';
8
9
 
9
- const emit = (onChange, value) => {
10
- onChange?.({ target: { value } });
11
- };
12
- const toInternalValue = (external, format) => {
13
- const isoMatch = /^(\d{4})-(\d{2})-(\d{2})$/.exec(external.trim());
14
- if (!isoMatch) return external;
15
- const [, year, month, day] = isoMatch;
16
- if (format === "DD/MM/YYYY") return `${day}/${month}/${year}`;
17
- if (format === "MM/DD/YYYY") return `${month}/${day}/${year}`;
18
- return `${year}/${month}/${day}`;
19
- };
20
10
  const InputDate = React.forwardRef(
21
11
  ({
22
12
  className,
23
- endContent,
24
13
  disabled,
25
14
  error,
26
15
  errorMessage,
@@ -28,129 +17,118 @@ const InputDate = React.forwardRef(
28
17
  onChange: controlledOnChange,
29
18
  inputClassName,
30
19
  onClear = true,
31
- inputFormat = "DD/MM/YYYY",
32
- "aria-invalid": ariaInvalid,
20
+ locale,
33
21
  ...props
34
22
  }, ref) => {
35
- const [internalValue, setInternalValue] = React.useState(() => toInternalValue(controlledValue ?? "", inputFormat));
23
+ const [dateValue, setDateValue] = React.useState(() => controlledValue ?? null);
36
24
  const [isHovered, setIsHovered] = React.useState(false);
25
+ const internalChange = React.useRef(false);
37
26
  React.useEffect(() => {
38
- if (!controlledValue) {
39
- setInternalValue("");
27
+ if (internalChange.current) {
28
+ internalChange.current = false;
40
29
  return;
41
30
  }
42
- if (/^\d{4}-\d{2}-\d{2}$/.test(controlledValue.trim())) {
43
- setInternalValue(toInternalValue(controlledValue, inputFormat));
44
- }
45
- }, [controlledValue, inputFormat]);
46
- const handleMaskedChange = (newValue) => {
47
- setInternalValue(newValue);
48
- if (!controlledOnChange) return;
49
- if (!newValue.trim()) {
50
- emit(controlledOnChange, "");
51
- return;
52
- }
53
- const formatConfigs = {
54
- "DD/MM/YYYY": { regex: /^(\d{2})\/(\d{2})\/(\d{4})$/, d: 1, m: 2, y: 3 },
55
- "MM/DD/YYYY": { regex: /^(\d{2})\/(\d{2})\/(\d{4})$/, d: 2, m: 1, y: 3 },
56
- "YYYY/MM/DD": { regex: /^(\d{4})\/(\d{2})\/(\d{2})$/, d: 3, m: 2, y: 1 }
57
- };
58
- const config = formatConfigs[inputFormat];
59
- const match = config.regex.exec(newValue);
60
- if (match) {
61
- const year = match[config.y];
62
- const month = match[config.m];
63
- const day = match[config.d];
64
- emit(controlledOnChange, `${year}-${month}-${day}`);
65
- }
31
+ setDateValue(controlledValue ?? null);
32
+ }, [controlledValue]);
33
+ const handleRacChange = (date) => {
34
+ internalChange.current = true;
35
+ setDateValue(date);
36
+ controlledOnChange?.(date);
66
37
  };
67
38
  const handleClear = () => {
68
- setInternalValue("");
69
- emit(controlledOnChange, "");
39
+ internalChange.current = true;
40
+ setDateValue(null);
41
+ controlledOnChange?.(null);
70
42
  if (typeof onClear === "function") onClear();
71
43
  };
72
- const hasValue = Boolean(internalValue && internalValue.trim() !== "");
44
+ const hasValue = dateValue !== null;
73
45
  const showClearIcon = Boolean(onClear && hasValue && isHovered && !disabled);
74
46
  const resolvedErrorMessage = typeof error === "string" ? error : errorMessage;
75
47
  const hasError = Boolean(error ?? resolvedErrorMessage);
76
- const renderCalendarIcon = () => /* @__PURE__ */ jsx(CalendarBlank, { size: 20 });
77
- const renderErrorIcon = () => {
78
- if (!hasError) return null;
79
- return /* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsx(
80
- WarningCircle,
81
- {
82
- "data-testid": "exclaim-icon",
83
- className: cn(
84
- "text-error-500 transition-opacity duration-150",
85
- showClearIcon ? "opacity-0" : "opacity-100"
86
- ),
87
- size: 18
88
- }
89
- ) });
90
- };
91
- const renderClearIcon = () => {
92
- if (disabled || !onClear) return null;
93
- return /* @__PURE__ */ jsx(
94
- "div",
48
+ const inner = /* @__PURE__ */ jsxs("div", { className: "flex w-full flex-col gap-1", children: [
49
+ /* @__PURE__ */ jsx("div", { className: "flex w-full items-center", children: /* @__PURE__ */ jsx(
50
+ DateField,
95
51
  {
96
- className: cn(
97
- "absolute right-3 z-10 flex h-full w-10 items-center justify-end rounded-r-lg",
98
- endContent || error ? "bg-transparent" : "bg-gradient-to-l from-white from-60% via-white/80 via-80% to-transparent transition-opacity duration-150",
99
- showClearIcon ? "opacity-100" : "opacity-0"
100
- ),
101
- children: /* @__PURE__ */ jsx(
102
- X,
52
+ ref,
53
+ value: dateValue,
54
+ onChange: handleRacChange,
55
+ isDisabled: disabled,
56
+ isInvalid: hasError,
57
+ granularity: "day",
58
+ className: "w-full",
59
+ ...props,
60
+ children: /* @__PURE__ */ jsxs(
61
+ Group,
103
62
  {
104
- "data-testid": "clear-button",
63
+ "data-testid": "input-date-mask-control",
105
64
  className: cn(
106
- "h-4 w-4 shrink-0 cursor-pointer transition-opacity duration-150",
107
- showClearIcon ? "opacity-100 hover:opacity-70" : "opacity-0"
65
+ "relative flex h-12 w-full items-center rounded-lg border border-neutral-200 bg-white px-3 transition-colors focus-within:border-neutral-950",
66
+ disabled && "bg-neutral-50",
67
+ hasError && "border-error-400 focus-within:border-error-700",
68
+ className
108
69
  ),
109
- onClick: handleClear
70
+ onMouseEnter: () => setIsHovered(true),
71
+ onMouseLeave: () => setIsHovered(false),
72
+ children: [
73
+ /* @__PURE__ */ jsx(CalendarBlank, { size: 20 }),
74
+ /* @__PURE__ */ jsx(DateInput, { className: cn("flex flex-1 items-center justify-center px-2", inputClassName), children: (segment) => /* @__PURE__ */ jsx(
75
+ DateSegment,
76
+ {
77
+ segment,
78
+ className: cn(
79
+ segment.type === "literal" ? "select-none text-neutral-400" : cn(
80
+ "min-w-[1ch] rounded-sm bg-transparent px-0.5 py-px text-center outline-0 transition-colors",
81
+ "caret-neutral-900",
82
+ "placeholder:text-neutral-300",
83
+ "data-focused:bg-neutral-100 data-focused:text-neutral-900",
84
+ "data-disabled:cursor-not-allowed data-disabled:opacity-50"
85
+ )
86
+ )
87
+ }
88
+ ) }),
89
+ hasError && /* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsx(
90
+ WarningCircle,
91
+ {
92
+ "data-testid": "exclaim-icon",
93
+ className: cn(
94
+ "text-error-500 transition-opacity duration-150",
95
+ showClearIcon ? "opacity-0" : "opacity-100"
96
+ ),
97
+ size: 18
98
+ }
99
+ ) }),
100
+ onClear && !disabled && /* @__PURE__ */ jsx(
101
+ "div",
102
+ {
103
+ className: cn(
104
+ "absolute right-3 z-10 flex h-full w-10 items-center justify-end rounded-r-lg",
105
+ hasError ? "bg-transparent" : "bg-linear-to-l from-white from-60% via-white/80 via-80% to-transparent transition-opacity duration-150",
106
+ showClearIcon ? "opacity-100" : "opacity-0"
107
+ ),
108
+ children: /* @__PURE__ */ jsx(
109
+ X,
110
+ {
111
+ "data-testid": "clear-button",
112
+ className: cn(
113
+ "h-4 w-4 shrink-0 cursor-pointer transition-opacity duration-150",
114
+ showClearIcon ? "opacity-100 hover:opacity-70" : "opacity-0"
115
+ ),
116
+ onClick: (e) => {
117
+ e.stopPropagation();
118
+ handleClear();
119
+ }
120
+ }
121
+ )
122
+ }
123
+ )
124
+ ]
110
125
  }
111
126
  )
112
127
  }
113
- );
114
- };
115
- return /* @__PURE__ */ jsxs("div", { className: "flex w-full flex-col gap-1", children: [
116
- /* @__PURE__ */ jsx("div", { className: "flex w-full items-center", children: /* @__PURE__ */ jsxs(
117
- "label",
118
- {
119
- "data-testid": "input-date-mask-control",
120
- className: cn(
121
- "relative flex h-12 w-full items-center rounded-lg border border-neutral-200 bg-white px-3 transition-colors focus-within:border-neutral-950",
122
- disabled && "bg-neutral-50",
123
- hasError && "border-error-400 focus-within:border-error-700",
124
- className
125
- ),
126
- onMouseEnter: () => setIsHovered(true),
127
- onMouseLeave: () => setIsHovered(false),
128
- children: [
129
- renderCalendarIcon(),
130
- /* @__PURE__ */ jsx(
131
- MaskedInput,
132
- {
133
- ref,
134
- inputFormat,
135
- placeholder: inputFormat,
136
- "aria-invalid": ariaInvalid ?? hasError,
137
- disabled,
138
- value: internalValue,
139
- onChange: handleMaskedChange,
140
- className: cn(
141
- "w-full bg-transparent px-2 outline-0 transition-colors placeholder:text-neutral-300 disabled:cursor-not-allowed disabled:opacity-50",
142
- inputClassName
143
- ),
144
- ...props
145
- }
146
- ),
147
- renderErrorIcon(),
148
- renderClearIcon()
149
- ]
150
- }
151
128
  ) }),
152
129
  resolvedErrorMessage && /* @__PURE__ */ jsx("span", { className: "text-error-500 text-sm", children: resolvedErrorMessage })
153
130
  ] });
131
+ return locale ? /* @__PURE__ */ jsx(I18nProvider, { locale, children: inner }) : inner;
154
132
  }
155
133
  );
156
134
  InputDate.displayName = "InputDate";
@@ -1 +1 @@
1
- {"version":3,"file":"InputDate.js","sources":["../../../src/components/InputDate/InputDate.tsx"],"sourcesContent":["import { CalendarBlank } from '@phosphor-icons/react/dist/ssr/CalendarBlank'\nimport { WarningCircle } from '@phosphor-icons/react/dist/ssr/WarningCircle'\nimport { X } from '@phosphor-icons/react/dist/ssr/X'\nimport * as React from 'react'\n\nimport { type DateInputFormat } from './manualDateFormat'\nimport { MaskedInput } from './MaskedInput'\n\nimport { cn } from '@/lib/utils'\n\nexport type InputDateProps = {\n className?: string\n endContent?: React.ReactElement\n disabled?: boolean\n error?: boolean | string\n errorMessage?: string\n inputClassName?: string\n inputFormat?: DateInputFormat\n onClear?: boolean | (() => void)\n value?: string\n onChange?: (event: React.ChangeEvent<HTMLInputElement>) => void\n} & Omit<React.InputHTMLAttributes<HTMLInputElement>, 'value' | 'onChange' | 'type'>\n\nconst emit = (onChange: ((e: React.ChangeEvent<HTMLInputElement>) => void) | undefined, value: string) => {\n onChange?.({ target: { value } } as React.ChangeEvent<HTMLInputElement>)\n}\n\nconst toInternalValue = (external: string, format: DateInputFormat): string => {\n const isoMatch = /^(\\d{4})-(\\d{2})-(\\d{2})$/.exec(external.trim())\n if (!isoMatch) return external\n\n const [, year, month, day] = isoMatch\n if (format === 'DD/MM/YYYY') return `${day}/${month}/${year}`\n if (format === 'MM/DD/YYYY') return `${month}/${day}/${year}`\n return `${year}/${month}/${day}`\n}\n\nconst InputDate = React.forwardRef<HTMLInputElement, InputDateProps>(\n (\n {\n className,\n endContent,\n disabled,\n error,\n errorMessage,\n value: controlledValue,\n onChange: controlledOnChange,\n inputClassName,\n onClear = true,\n inputFormat = 'DD/MM/YYYY',\n 'aria-invalid': ariaInvalid,\n ...props\n },\n ref,\n ) => {\n const [internalValue, setInternalValue] = React.useState(() => toInternalValue(controlledValue ?? '', inputFormat))\n const [isHovered, setIsHovered] = React.useState(false)\n\n React.useEffect(() => {\n if (!controlledValue) {\n setInternalValue('')\n return\n }\n if (/^\\d{4}-\\d{2}-\\d{2}$/.test(controlledValue.trim())) {\n setInternalValue(toInternalValue(controlledValue, inputFormat))\n }\n }, [controlledValue, inputFormat])\n\n const handleMaskedChange = (newValue: string) => {\n setInternalValue(newValue)\n\n if (!controlledOnChange) return\n\n if (!newValue.trim()) {\n emit(controlledOnChange, '')\n return\n }\n\n const formatConfigs: Record<DateInputFormat, { regex: RegExp; d: number; m: number; y: number }> = {\n 'DD/MM/YYYY': { regex: /^(\\d{2})\\/(\\d{2})\\/(\\d{4})$/, d: 1, m: 2, y: 3 },\n 'MM/DD/YYYY': { regex: /^(\\d{2})\\/(\\d{2})\\/(\\d{4})$/, d: 2, m: 1, y: 3 },\n 'YYYY/MM/DD': { regex: /^(\\d{4})\\/(\\d{2})\\/(\\d{2})$/, d: 3, m: 2, y: 1 },\n }\n\n const config = formatConfigs[inputFormat]\n const match = config.regex.exec(newValue)\n\n if (match) {\n const year = match[config.y]\n const month = match[config.m]\n const day = match[config.d]\n\n emit(controlledOnChange, `${year}-${month}-${day}`)\n }\n }\n\n const handleClear = () => {\n setInternalValue('')\n emit(controlledOnChange, '')\n if (typeof onClear === 'function') onClear()\n }\n\n const hasValue = Boolean(internalValue && internalValue.trim() !== '')\n const showClearIcon = Boolean(onClear && hasValue && isHovered && !disabled)\n const resolvedErrorMessage = typeof error === 'string' ? error : errorMessage\n const hasError = Boolean(error ?? resolvedErrorMessage)\n\n const renderCalendarIcon = () => <CalendarBlank size={20} />\n\n const renderErrorIcon = () => {\n if (!hasError) return null\n return (\n <div>\n <WarningCircle\n data-testid=\"exclaim-icon\"\n className={cn(\n 'text-error-500 transition-opacity duration-150',\n showClearIcon ? 'opacity-0' : 'opacity-100',\n )}\n size={18}\n />\n </div>\n )\n }\n\n const renderClearIcon = () => {\n if (disabled || !onClear) return null\n return (\n <div\n className={cn(\n 'absolute right-3 z-10 flex h-full w-10 items-center justify-end rounded-r-lg',\n endContent || error\n ? 'bg-transparent'\n : 'bg-gradient-to-l from-white from-60% via-white/80 via-80% to-transparent transition-opacity duration-150',\n showClearIcon ? 'opacity-100' : 'opacity-0',\n )}\n >\n <X\n data-testid=\"clear-button\"\n className={cn(\n 'h-4 w-4 shrink-0 cursor-pointer transition-opacity duration-150',\n showClearIcon ? 'opacity-100 hover:opacity-70' : 'opacity-0',\n )}\n onClick={handleClear}\n />\n </div>\n )\n }\n\n return (\n <div className=\"flex w-full flex-col gap-1\">\n <div className=\"flex w-full items-center\">\n <label\n data-testid=\"input-date-mask-control\"\n className={cn(\n 'relative flex h-12 w-full items-center rounded-lg border border-neutral-200 bg-white px-3 transition-colors focus-within:border-neutral-950',\n disabled && 'bg-neutral-50',\n hasError && 'border-error-400 focus-within:border-error-700',\n className,\n )}\n onMouseEnter={() => setIsHovered(true)}\n onMouseLeave={() => setIsHovered(false)}\n >\n {renderCalendarIcon()}\n <MaskedInput\n ref={ref}\n inputFormat={inputFormat}\n placeholder={inputFormat}\n aria-invalid={ariaInvalid ?? hasError}\n disabled={disabled}\n value={internalValue}\n onChange={handleMaskedChange}\n className={cn(\n 'w-full bg-transparent px-2 outline-0 transition-colors placeholder:text-neutral-300 disabled:cursor-not-allowed disabled:opacity-50',\n inputClassName,\n )}\n {...props}\n />\n {renderErrorIcon()}\n {renderClearIcon()}\n </label>\n </div>\n {resolvedErrorMessage && <span className=\"text-error-500 text-sm\">{resolvedErrorMessage}</span>}\n </div>\n )\n },\n)\n\nInputDate.displayName = 'InputDate'\n\nexport { InputDate }\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"InputDate.js","sources":["../../../src/components/InputDate/InputDate.tsx"],"sourcesContent":["import { CalendarBlank } from '@phosphor-icons/react/dist/ssr/CalendarBlank'\nimport { WarningCircle } from '@phosphor-icons/react/dist/ssr/WarningCircle'\nimport { X } from '@phosphor-icons/react/dist/ssr/X'\nimport { I18nProvider } from 'react-aria'\nimport * as React from 'react'\nimport {\n DateField,\n DateInput,\n DateSegment,\n Group,\n type DateValue,\n} from 'react-aria-components'\nimport { cn } from '@/lib/utils'\n\nexport type InputDateProps = {\n className?: string\n disabled?: boolean\n error?: boolean | string\n errorMessage?: string\n inputClassName?: string\n locale?: string\n onClear?: boolean | (() => void)\n value?: DateValue | null\n onChange?: (date: DateValue | null) => void\n} & Omit<React.ComponentPropsWithoutRef<typeof DateField<DateValue>>, 'value' | 'onChange'>\n\nconst InputDate = React.forwardRef<HTMLDivElement, InputDateProps>(\n (\n {\n className,\n disabled,\n error,\n errorMessage,\n value: controlledValue,\n onChange: controlledOnChange,\n inputClassName,\n onClear = true,\n locale,\n ...props\n },\n ref,\n ) => {\n const [dateValue, setDateValue] = React.useState<DateValue | null>(() => controlledValue ?? null)\n const [isHovered, setIsHovered] = React.useState(false)\n const internalChange = React.useRef(false)\n\n React.useEffect(() => {\n if (internalChange.current) {\n internalChange.current = false\n return\n }\n setDateValue(controlledValue ?? null)\n }, [controlledValue])\n\n const handleRacChange = (date: DateValue | null) => {\n internalChange.current = true\n setDateValue(date)\n controlledOnChange?.(date)\n }\n\n const handleClear = () => {\n internalChange.current = true\n setDateValue(null)\n controlledOnChange?.(null)\n if (typeof onClear === 'function') onClear()\n }\n\n const hasValue = dateValue !== null\n const showClearIcon = Boolean(onClear && hasValue && isHovered && !disabled)\n const resolvedErrorMessage = typeof error === 'string' ? error : errorMessage\n const hasError = Boolean(error ?? resolvedErrorMessage)\n\n const inner = (\n <div className=\"flex w-full flex-col gap-1\">\n <div className=\"flex w-full items-center\">\n <DateField\n ref={ref}\n value={dateValue}\n onChange={handleRacChange}\n isDisabled={disabled}\n isInvalid={hasError}\n granularity=\"day\"\n className=\"w-full\"\n {...props}\n >\n <Group\n data-testid=\"input-date-mask-control\"\n className={cn(\n 'relative flex h-12 w-full items-center rounded-lg border border-neutral-200 bg-white px-3 transition-colors focus-within:border-neutral-950',\n disabled && 'bg-neutral-50',\n hasError && 'border-error-400 focus-within:border-error-700',\n className,\n )}\n onMouseEnter={() => setIsHovered(true)}\n onMouseLeave={() => setIsHovered(false)}\n >\n <CalendarBlank size={20} />\n <DateInput className={cn('flex flex-1 items-center justify-center px-2', inputClassName)}>\n {(segment) => (\n <DateSegment\n segment={segment}\n className={cn(\n segment.type === 'literal'\n ? 'select-none text-neutral-400'\n : cn(\n 'min-w-[1ch] rounded-sm bg-transparent px-0.5 py-px text-center outline-0 transition-colors',\n 'caret-neutral-900',\n 'placeholder:text-neutral-300',\n 'data-focused:bg-neutral-100 data-focused:text-neutral-900',\n 'data-disabled:cursor-not-allowed data-disabled:opacity-50',\n ),\n )}\n />\n )}\n </DateInput>\n {hasError && (\n <div>\n <WarningCircle\n data-testid=\"exclaim-icon\"\n className={cn(\n 'text-error-500 transition-opacity duration-150',\n showClearIcon ? 'opacity-0' : 'opacity-100',\n )}\n size={18}\n />\n </div>\n )}\n {onClear && !disabled && (\n <div\n className={cn(\n 'absolute right-3 z-10 flex h-full w-10 items-center justify-end rounded-r-lg',\n hasError\n ? 'bg-transparent'\n : 'bg-linear-to-l from-white from-60% via-white/80 via-80% to-transparent transition-opacity duration-150',\n showClearIcon ? 'opacity-100' : 'opacity-0',\n )}\n >\n <X\n data-testid=\"clear-button\"\n className={cn(\n 'h-4 w-4 shrink-0 cursor-pointer transition-opacity duration-150',\n showClearIcon ? 'opacity-100 hover:opacity-70' : 'opacity-0',\n )}\n onClick={(e) => {\n e.stopPropagation()\n handleClear()\n }}\n />\n </div>\n )}\n </Group>\n </DateField>\n </div>\n {resolvedErrorMessage && <span className=\"text-error-500 text-sm\">{resolvedErrorMessage}</span>}\n </div>\n )\n\n return locale ? <I18nProvider locale={locale}>{inner}</I18nProvider> : inner\n },\n)\n\nInputDate.displayName = 'InputDate'\n\nexport { InputDate }\n"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "periplo-ui",
3
3
  "description": "IATI UI library",
4
4
  "private": false,
5
- "version": "4.4.2",
5
+ "version": "4.6.0",
6
6
  "type": "module",
7
7
  "main": "dist/index.js",
8
8
  "types": "dist/index.d.ts",
@@ -335,6 +335,7 @@
335
335
  "dist"
336
336
  ],
337
337
  "dependencies": {
338
+ "@internationalized/date": "^3.12.2",
338
339
  "@radix-ui/react-accordion": "^1.2.11",
339
340
  "@radix-ui/react-avatar": "^1.1.10",
340
341
  "@radix-ui/react-checkbox": "^1.3.2",
@@ -352,14 +353,16 @@
352
353
  "@radix-ui/react-toggle": "^1.1.9",
353
354
  "@radix-ui/react-toggle-group": "^1.1.10",
354
355
  "@radix-ui/react-tooltip": "^1.2.7",
356
+ "@tanstack/react-virtual": "^3.13.18",
355
357
  "class-variance-authority": "0.7.1",
356
358
  "clsx": "2.1.1",
357
359
  "cmdk": "^1.1.1",
358
360
  "date-fns": "^4.1.0",
359
361
  "embla-carousel-react": "^8.6.0",
362
+ "react-aria": "^3.50.0",
363
+ "react-aria-components": "^1.19.0",
360
364
  "react-day-picker": "^9.7.0",
361
365
  "sonner": "^2.0.5",
362
- "tailwind-merge": "3.3.1",
363
- "@tanstack/react-virtual": "^3.13.18"
366
+ "tailwind-merge": "3.3.1"
364
367
  }
365
368
  }
@@ -1,18 +0,0 @@
1
- import { default as React } from 'react';
2
- export type DateInputFormat = 'DD/MM/YYYY' | 'MM/DD/YYYY' | 'YYYY/MM/DD';
3
- type Props = {
4
- value: string;
5
- onChange: (value: string) => void;
6
- onBlur?: React.FocusEventHandler<HTMLInputElement>;
7
- onFocus?: React.FocusEventHandler<HTMLInputElement>;
8
- onKeyDown?: React.KeyboardEventHandler<HTMLInputElement>;
9
- placeholder?: string;
10
- disabled?: boolean;
11
- id?: string;
12
- name?: string;
13
- className?: string;
14
- 'aria-invalid'?: React.InputHTMLAttributes<HTMLInputElement>['aria-invalid'];
15
- inputFormat?: DateInputFormat;
16
- };
17
- export declare const MaskedInput: React.ForwardRefExoticComponent<Props & React.RefAttributes<HTMLInputElement>>;
18
- export {};