@webiny/admin-ui 6.5.0-beta.4 → 6.5.0-beta.6

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 (37) hide show
  1. package/DataTable/DataTable.d.ts +16 -6
  2. package/DataTable/DataTable.js +14 -6
  3. package/DataTable/DataTable.js.map +1 -1
  4. package/DataTable/components/ColumnsVisibility.d.ts +5 -4
  5. package/DataTable/components/ColumnsVisibility.js +6 -3
  6. package/DataTable/components/ColumnsVisibility.js.map +1 -1
  7. package/DatePicker/primitives/DateTimePicker.js +8 -7
  8. package/DatePicker/primitives/DateTimePicker.js.map +1 -1
  9. package/FilePicker/FilePicker.stories.d.ts +6 -0
  10. package/FilePicker/FilePicker.stories.js +24 -1
  11. package/FilePicker/FilePicker.stories.js.map +1 -1
  12. package/FilePicker/primitives/components/previews/ItemActions.js.map +1 -1
  13. package/FilePicker/primitives/components/previews/ItemDescription.js +1 -1
  14. package/FilePicker/primitives/components/previews/ItemDescription.js.map +1 -1
  15. package/FilePicker/primitives/components/previews/RichItemPreview/FileType.d.ts +4 -0
  16. package/FilePicker/primitives/components/previews/RichItemPreview/FileType.js.map +1 -1
  17. package/FilePicker/primitives/components/previews/RichItemPreview/Placeholder.d.ts +3 -0
  18. package/FilePicker/primitives/components/previews/RichItemPreview/Placeholder.js.map +1 -1
  19. package/FilePicker/primitives/components/previews/RichItemPreview/RichItemPreview.js.map +1 -1
  20. package/FilePicker/primitives/components/previews/RichItemPreview/Thumbnail.d.ts +4 -0
  21. package/FilePicker/primitives/components/previews/RichItemPreview/Thumbnail.js.map +1 -1
  22. package/FilePicker/primitives/components/previews/RichItemPreview/ThumbnailActions.d.ts +5 -0
  23. package/FilePicker/primitives/components/previews/RichItemPreview/ThumbnailActions.js.map +1 -1
  24. package/FilePicker/primitives/components/previews/TruncatedFileName.d.ts +4 -0
  25. package/FilePicker/primitives/components/previews/TruncatedFileName.js.map +1 -1
  26. package/FilePicker/primitives/components/previews/fileName.d.ts +8 -0
  27. package/FilePicker/primitives/components/previews/fileName.js.map +1 -1
  28. package/IconPicker/domains/IconPickerIcon.js +1 -1
  29. package/IconPicker/domains/IconPickerIcon.js.map +1 -1
  30. package/ImageEditor/types.js +1 -1
  31. package/ImageEditor/types.js.map +1 -1
  32. package/MultiAutoComplete/primitives/presenters/MultiAutoCompletePresenter.test.js +1 -1
  33. package/MultiAutoComplete/primitives/presenters/MultiAutoCompletePresenter.test.js.map +1 -1
  34. package/MultiAutoComplete/primitives/useMultiAutoComplete.js +3 -2
  35. package/MultiAutoComplete/primitives/useMultiAutoComplete.js.map +1 -1
  36. package/Toast/useToast.stories.js.map +1 -1
  37. package/package.json +24 -24
@@ -1,5 +1,15 @@
1
1
  import React from "react";
2
- import type { ColumnSort, OnChangeFn, Row, SortingState, VisibilityState } from "@tanstack/react-table";
2
+ import type { ColumnSort, ColumnVisibilityState, OnChangeFn, Row, RowData, SortingState } from "@tanstack/react-table";
3
+ declare const features: {
4
+ columnResizingFeature: import("@tanstack/table-core").TableFeature;
5
+ columnSizingFeature: import("@tanstack/table-core").TableFeature;
6
+ columnVisibilityFeature: import("@tanstack/table-core").TableFeature;
7
+ rowSelectionFeature: import("@tanstack/table-core").TableFeature;
8
+ rowSortingFeature: import("@tanstack/table-core").TableFeature;
9
+ sortedRowModel: (table: import("@tanstack/table-core").Table<any, any>) => () => import("@tanstack/table-core").RowModel<any, any>;
10
+ coreRowModel: (table: import("@tanstack/table-core").Table<any, any>) => () => import("@tanstack/table-core").RowModel<any, any>;
11
+ };
12
+ type Features = typeof features;
3
13
  interface DataTableColumn<T> {
4
14
  header?: string | number | React.JSX.Element;
5
15
  cell?: (row: T) => string | number | React.JSX.Element | null;
@@ -18,13 +28,13 @@ type DataTableDefaultData = {
18
28
  id: string;
19
29
  $selectable?: boolean;
20
30
  };
21
- type DataTableRow<T> = Row<DataTableDefaultData & T>;
31
+ type DataTableRow<T extends RowData> = Row<Features, DataTableDefaultData & T>;
22
32
  type DataTableSorting = SortingState;
23
33
  type DataTableColumnSort = ColumnSort;
24
34
  type OnDataTableSortingChange = OnChangeFn<DataTableSorting>;
25
- type DataTableColumnVisibility = VisibilityState;
35
+ type DataTableColumnVisibility = ColumnVisibilityState;
26
36
  type OnDataTableColumnVisibilityChange = OnChangeFn<DataTableColumnVisibility>;
27
- interface DataTableProps<TEntry> {
37
+ interface DataTableProps<TEntry extends RowData> {
28
38
  /**
29
39
  * Show or hide borders.
30
40
  */
@@ -52,7 +62,7 @@ interface DataTableProps<TEntry> {
52
62
  /**
53
63
  * Callback that is called to determine if the row is selectable.
54
64
  */
55
- isRowSelectable?: (row: Row<TEntry>) => boolean;
65
+ isRowSelectable?: (row: Row<Features, TEntry>) => boolean;
56
66
  /**
57
67
  * Render the skeleton state while data are loading.
58
68
  */
@@ -106,4 +116,4 @@ declare const DataTable: typeof DecoratableDataTable & {
106
116
  displayName: string;
107
117
  }>) => (props: unknown) => React.JSX.Element;
108
118
  };
109
- export { DataTable, type DataTableProps, type DataTableColumn, type DataTableColumns, type DataTableDefaultData, type DataTableRow, type DataTableSorting, type DataTableColumnSort, type OnDataTableSortingChange, type DataTableColumnVisibility, type OnDataTableColumnVisibilityChange };
119
+ export { DataTable, type Features, type DataTableProps, type DataTableColumn, type DataTableColumns, type DataTableDefaultData, type DataTableRow, type DataTableSorting, type DataTableColumnSort, type OnDataTableSortingChange, type DataTableColumnVisibility, type OnDataTableColumnVisibilityChange };
@@ -1,10 +1,19 @@
1
1
  import react, { memo, useCallback, useEffect, useMemo, useRef, useState } from "react";
2
- import { flexRender, getCoreRowModel, getSortedRowModel, useReactTable } from "@tanstack/react-table";
2
+ import { columnResizingFeature, columnSizingFeature, columnVisibilityFeature, createCoreRowModel, createSortedRowModel, flexRender, rowSelectionFeature, rowSortingFeature, tableFeatures, useTable } from "@tanstack/react-table";
3
3
  import { CheckboxPrimitive } from "../Checkbox/index.js";
4
4
  import { Skeleton } from "../Skeleton/index.js";
5
5
  import { Table } from "../Table/index.js";
6
6
  import { ColumnSorter, ColumnsVisibility } from "./components/index.js";
7
7
  import { cn, makeDecoratable } from "../utils.js";
8
+ const features = tableFeatures({
9
+ columnResizingFeature: columnResizingFeature,
10
+ columnSizingFeature: columnSizingFeature,
11
+ columnVisibilityFeature: columnVisibilityFeature,
12
+ rowSelectionFeature: rowSelectionFeature,
13
+ rowSortingFeature: rowSortingFeature,
14
+ sortedRowModel: createSortedRowModel(),
15
+ coreRowModel: createCoreRowModel()
16
+ });
8
17
  const defineColumns = (columns, options)=>{
9
18
  const { canSelectAllRows, onSelectRow, onToggleRow, loading } = options;
10
19
  return useMemo(()=>{
@@ -20,7 +29,7 @@ const defineColumns = (columns, options)=>{
20
29
  header: ()=>header,
21
30
  cell: (props)=>{
22
31
  if (cell && "function" == typeof cell) return cell(props.row.original);
23
- return props.getValue() ? String(props.getValue()) : null;
32
+ else return props.getValue() ? String(props.getValue()) : null;
24
33
  },
25
34
  enableSorting,
26
35
  meta: {
@@ -141,7 +150,7 @@ const DecoratableDataTable = ({ bordered, canSelectAllRows = true, columnVisibil
141
150
  ...Object.keys(newSelection).filter((x)=>!(x in rowSelection))
142
151
  ];
143
152
  if (1 === toggledRows.length && "function" == typeof onToggleRow) return void onToggleRow(data[parseInt(toggledRows[0])]);
144
- if ("function" == typeof onSelectRow) {
153
+ else if ("function" == typeof onSelectRow) {
145
154
  const selection = Object.keys(newSelection).map((key)=>data[parseInt(key)]);
146
155
  onSelectRow(selection);
147
156
  }
@@ -158,7 +167,8 @@ const DecoratableDataTable = ({ bordered, canSelectAllRows = true, columnVisibil
158
167
  onToggleRow,
159
168
  loading
160
169
  });
161
- const table = useReactTable({
170
+ const table = useTable({
171
+ features: features,
162
172
  columnResizeMode: "onChange",
163
173
  columns,
164
174
  data,
@@ -167,8 +177,6 @@ const DecoratableDataTable = ({ bordered, canSelectAllRows = true, columnVisibil
167
177
  enableRowSelection: isRowSelectable,
168
178
  enableSorting: !!onSortingChange,
169
179
  enableSortingRemoval: false,
170
- getCoreRowModel: getCoreRowModel(),
171
- getSortedRowModel: getSortedRowModel(),
172
180
  manualSorting: true,
173
181
  onColumnVisibilityChange,
174
182
  onRowSelectionChange,
@@ -1 +1 @@
1
- {"version":3,"file":"DataTable/DataTable.js","sources":["../../src/DataTable/DataTable.tsx"],"sourcesContent":["import React, { memo, useCallback, useEffect, useMemo, useRef, useState } from \"react\";\nimport type {\n Cell,\n Column,\n ColumnDef,\n ColumnSort,\n OnChangeFn,\n Row,\n RowSelectionState,\n SortingState,\n VisibilityState\n} from \"@tanstack/react-table\";\nimport {\n flexRender,\n getCoreRowModel,\n getSortedRowModel,\n useReactTable\n} from \"@tanstack/react-table\";\nimport { CheckboxPrimitive } from \"~/Checkbox/index.js\";\nimport { Skeleton } from \"~/Skeleton/index.js\";\nimport { Table } from \"~/Table/index.js\";\nimport { ColumnSorter, ColumnsVisibility } from \"./components/index.js\";\nimport { cn, makeDecoratable } from \"~/utils.js\";\n\ninterface DataTableColumn<T> {\n /*\n * Column header component.\n */\n header?: string | number | React.JSX.Element;\n /*\n * Cell renderer, receives the full row and returns the value to render inside the cell.\n */\n cell?: (row: T) => string | number | React.JSX.Element | null;\n /*\n * Column size.\n */\n size?: number;\n /*\n * Should truncate?\n */\n truncate?: boolean;\n /*\n * Column class names.\n */\n className?: string;\n /*\n * Enable column sorting.\n */\n enableSorting?: boolean;\n /*\n * Enable column resizing.\n */\n enableResizing?: boolean;\n /*\n * Enable column visibility toggling.\n */\n enableHiding?: boolean;\n /*\n * Accessor key for the column data path.\n */\n accessorKey?: string;\n}\n\ntype DataTableColumns<T> = {\n [P in keyof T]?: DataTableColumn<T>;\n};\n\ntype DataTableDefaultData = {\n id: string;\n /*\n * Define if a specific row can be selected.\n */\n $selectable?: boolean;\n};\n\ntype DataTableRow<T> = Row<DataTableDefaultData & T>;\n\ntype DataTableSorting = SortingState;\n\ntype DataTableColumnSort = ColumnSort;\n\ntype OnDataTableSortingChange = OnChangeFn<DataTableSorting>;\n\ntype DataTableColumnVisibility = VisibilityState;\n\ntype OnDataTableColumnVisibilityChange = OnChangeFn<DataTableColumnVisibility>;\n\ninterface DataTableProps<TEntry> {\n /**\n * Show or hide borders.\n */\n bordered?: boolean;\n /**\n * Controls whether \"select all\" action is allowed.\n */\n canSelectAllRows?: boolean;\n /**\n * Columns definition.\n */\n columns: DataTableColumns<TEntry>;\n /**\n * The column visibility state.\n */\n columnVisibility?: DataTableColumnVisibility;\n /**\n * Callback that receives current column visibility state.\n */\n onColumnVisibilityChange?: OnDataTableColumnVisibilityChange;\n /**\n * Data to display into DataTable body.\n */\n data: TEntry[];\n /**\n * Callback that is called to determine if the row is selectable.\n */\n isRowSelectable?: (row: Row<TEntry>) => boolean;\n /**\n * Render the skeleton state while data are loading.\n */\n loading?: boolean;\n /**\n * Callback that receives the selected rows.\n */\n onSelectRow?: (rows: TEntry[]) => void;\n /**\n * Callback that receives the toggled row.\n */\n onToggleRow?: (row: TEntry) => void;\n /**\n * Callback that receives current sorting state.\n */\n onSortingChange?: OnDataTableSortingChange;\n /**\n * Selected rows.\n */\n selectedRows?: TEntry[];\n /**\n * Sorting state.\n */\n sorting?: DataTableSorting;\n /**\n * Initial sorting state.\n */\n initialSorting?: DataTableSorting;\n /**\n * Enable sticky header.\n */\n stickyHeader?: boolean;\n}\n\ninterface DefineColumnsOptions<TEntry> {\n canSelectAllRows: boolean;\n onSelectRow?: DataTableProps<TEntry>[\"onSelectRow\"];\n onToggleRow: DataTableProps<TEntry>[\"onToggleRow\"];\n loading: DataTableProps<TEntry>[\"loading\"];\n}\n\nconst defineColumns = <T,>(\n columns: DataTableProps<T>[\"columns\"],\n options: DefineColumnsOptions<T>\n): ColumnDef<T>[] => {\n const { canSelectAllRows, onSelectRow, onToggleRow, loading } = options;\n\n return useMemo(() => {\n const columnsList = Object.keys(columns).map(key => ({\n id: key,\n ...columns[key as keyof typeof columns]\n }));\n\n const defaults: ColumnDef<T>[] = columnsList.map(column => {\n const {\n accessorKey,\n cell,\n className,\n enableHiding = true,\n enableResizing = true,\n enableSorting = false,\n header,\n truncate = true,\n id,\n size = 100\n } = column;\n\n return {\n id,\n accessorKey: accessorKey || id,\n header: () => header,\n cell: props => {\n if (cell && typeof cell === \"function\") {\n return cell(props.row.original);\n } else {\n // Automatically convert any cell value to a string for rendering,\n // ensuring the table displays values correctly. This aligns with React's\n // rendering, which expects JSX, strings or null.\n // https://github.com/TanStack/table/issues/1042\n return props.getValue() ? String(props.getValue()) : null;\n }\n },\n enableSorting,\n meta: {\n className,\n truncate\n },\n enableResizing,\n size,\n enableHiding\n };\n });\n\n let columnsDefs = defaults;\n const firstColumn = defaults[0];\n const isSelectable = onToggleRow || onSelectRow;\n\n if (isSelectable && firstColumn) {\n columnsDefs = [\n {\n ...firstColumn,\n accessorKey: firstColumn.id as string,\n header: props => {\n if (!props) {\n return null;\n }\n\n return (\n <div className={\"flex items-center gap-xl\"}>\n <CheckboxPrimitive\n indeterminate={props.table.getIsSomeRowsSelected()}\n checked={props.table.getIsAllRowsSelected()}\n onChange={props.table.toggleAllPageRowsSelected}\n aria-label=\"Select all\"\n disabled={!canSelectAllRows}\n onClick={e => e.stopPropagation()}\n />\n {firstColumn.header\n ? React.createElement(firstColumn.header, props)\n : null}\n </div>\n );\n },\n cell: props => {\n if (!props) {\n return null;\n }\n return (\n <div className={\"flex items-center gap-xl\"}>\n <CheckboxPrimitive\n checked={props.row.getIsSelected()}\n onChange={value => props.row.toggleSelected(!!value)}\n disabled={!props.row.getCanSelect()}\n aria-label=\"Select row\"\n className={cn(!props.row.getCanSelect() ? \"invisible\" : \"\")}\n />\n {firstColumn.cell\n ? React.createElement(firstColumn.cell, props)\n : null}\n </div>\n );\n }\n },\n ...defaults.slice(1)\n ];\n }\n\n return columnsDefs.map(column => {\n if (loading) {\n return {\n ...column,\n cell: () => <Skeleton type={\"text\"} size={\"md\"} />\n };\n }\n\n return column;\n });\n }, [columns, onSelectRow, onToggleRow, loading]);\n};\n\nconst typedMemo: <T>(component: T) => T = memo;\n\ninterface TableCellProps<T> {\n cell: Cell<T, unknown>;\n getColumnWidth: (column: Column<T>) => number;\n}\n\nconst TableCell = <T,>({ cell, getColumnWidth }: TableCellProps<T>) => {\n const width = getColumnWidth(cell.column);\n\n return (\n <Table.Cell {...cell.column.columnDef.meta} style={{ width, maxWidth: width }}>\n {flexRender(cell.column.columnDef.cell, cell.getContext())}\n </Table.Cell>\n );\n};\n\nconst MemoTableCell = typedMemo(TableCell);\n\ninterface TableRowProps<T> {\n selected: boolean;\n cells: Cell<T, unknown>[];\n getColumnWidth: (column: Column<T>) => number;\n}\n\nconst TableRow = <T,>({ selected, cells, getColumnWidth }: TableRowProps<T>) => {\n return (\n <Table.Row selected={selected}>\n {cells.map(cell => (\n <MemoTableCell<T> key={cell.id} cell={cell} getColumnWidth={getColumnWidth} />\n ))}\n </Table.Row>\n );\n};\n\nconst MemoTableRow = typedMemo(TableRow);\n\n/**\n * Empty array must be defined outside the React component so it does not force rerendering of the DataTable\n */\nconst emptyArray = Array(10).fill({});\n\nconst DecoratableDataTable = <T extends Record<string, any> & DataTableDefaultData>({\n bordered,\n canSelectAllRows = true,\n columnVisibility,\n columns: initialColumns,\n data: initialData,\n initialSorting,\n isRowSelectable,\n loading,\n onColumnVisibilityChange,\n onSelectRow,\n onSortingChange,\n onToggleRow,\n selectedRows = [],\n sorting,\n stickyHeader\n}: DataTableProps<T>) => {\n const tableRef = useRef<HTMLDivElement>(null);\n const [tableWidth, setTableWidth] = useState(1);\n\n const data = loading ? emptyArray : initialData;\n\n useEffect(() => {\n const updateElementWidth = () => {\n if (tableRef.current) {\n const width = tableRef.current.clientWidth;\n setTableWidth(width);\n }\n };\n\n updateElementWidth();\n\n window.addEventListener(\"resize\", updateElementWidth);\n\n return () => {\n window.removeEventListener(\"resize\", updateElementWidth);\n };\n }, [tableRef.current]);\n\n const rowSelection = useMemo(() => {\n return selectedRows.reduce<RowSelectionState>((acc, item) => {\n const recordIndex = data.findIndex(rec => rec.id === item.id);\n return { ...acc, [recordIndex]: true };\n }, {});\n }, [selectedRows, data]);\n\n const onRowSelectionChange: OnChangeFn<RowSelectionState> = updater => {\n const newSelection = typeof updater === \"function\" ? updater(rowSelection) : updater;\n\n /**\n * `@tanstack/react-table` isn't telling us what row was selected or deselected. It simply gives us\n * the new selection state (an object with row indexes that are currently selected).\n *\n * To figure out what row was toggled, we need to calculate the difference between the old selection\n * and the new selection. What we're doing here is:\n * - find all items that were present in the previous selection, but are no longer present in the new selection\n * - find all items that are present in the new selection, but were not present in the previous selection\n */\n const toggledRows = [\n ...Object.keys(rowSelection).filter(x => !(x in newSelection)),\n ...Object.keys(newSelection).filter(x => !(x in rowSelection))\n ];\n\n // If the difference is only 1 item, and `onToggleRow` is available, execute that.\n if (toggledRows.length === 1 && typeof onToggleRow === \"function\") {\n onToggleRow(data[parseInt(toggledRows[0])]);\n return;\n } else if (typeof onSelectRow === \"function\") {\n const selection = Object.keys(newSelection).map(key => data[parseInt(key)]);\n onSelectRow(selection);\n }\n };\n\n const tableSorting = useMemo(() => {\n if (!Array.isArray(sorting) || !sorting.length) {\n return initialSorting;\n }\n return sorting;\n }, [sorting]);\n\n const columns = defineColumns(initialColumns, {\n canSelectAllRows,\n onSelectRow,\n onToggleRow,\n loading\n });\n\n const table = useReactTable<T>({\n columnResizeMode: \"onChange\",\n columns,\n data,\n enableColumnResizing: true,\n enableHiding: !!onColumnVisibilityChange,\n enableRowSelection: isRowSelectable,\n enableSorting: !!onSortingChange,\n enableSortingRemoval: false,\n getCoreRowModel: getCoreRowModel(),\n getSortedRowModel: getSortedRowModel(),\n manualSorting: true,\n onColumnVisibilityChange,\n onRowSelectionChange,\n onSortingChange,\n state: {\n columnVisibility,\n rowSelection,\n sorting: tableSorting\n }\n });\n\n const getColumnWidth = useCallback(\n (column: Column<T>): number => {\n // Non-resizable columns (e.g. row-selection, actions) keep their fixed size.\n if (!column.getCanResize()) {\n return column.getSize();\n }\n\n /**\n * Resizable columns share the space left after the fixed columns, proportionally to\n * their own size. This makes the table always fill the full container width — even when\n * columns are hidden — so trailing content (e.g. the columns-visibility cog) stays\n * flush right instead of drifting left as columns are removed.\n */\n const visibleColumns = table.getVisibleLeafColumns();\n const fixedTotal = visibleColumns\n .filter(col => !col.getCanResize())\n .reduce((total, col) => total + col.getSize(), 0);\n const resizableTotal = visibleColumns\n .filter(col => col.getCanResize())\n .reduce((total, col) => total + col.getSize(), 0);\n\n if (resizableTotal === 0) {\n return column.getSize();\n }\n\n const available = Math.max(tableWidth - fixedTotal, 0);\n\n return Math.ceil((column.getSize() * available) / resizableTotal);\n },\n [table, tableWidth]\n );\n\n /**\n * Had to memoize the rows to avoid browser freeze.\n */\n const tableRows = useMemo(() => {\n return table.getRowModel().rows;\n }, [table, data, columns]);\n\n return (\n <div ref={tableRef}>\n <Table bordered={bordered} sticky={stickyHeader}>\n <Table.Header sticky={stickyHeader}>\n {table.getHeaderGroups().map(headerGroup => (\n <Table.Row key={headerGroup.id}>\n {headerGroup.headers.map((header, index) => {\n const isLastCell = index === headerGroup.headers.length - 1;\n const width = getColumnWidth(header.column);\n\n return (\n <Table.Head\n key={header.id}\n {...header.column.columnDef.meta}\n colSpan={header.colSpan}\n style={{ width, maxWidth: width }}\n >\n {header.isPlaceholder ? null : (\n <ColumnSorter\n onClick={header.column.getToggleSortingHandler()}\n sortable={header.column.getCanSort()}\n >\n <div\n className={cn({\n \"w-full overflow-hidden whitespace-nowrap\": true,\n truncate: !isLastCell\n })}\n >\n {flexRender(\n header.column.columnDef.header,\n header.getContext()\n )}\n </div>\n <Table.Direction\n direction={header.column.getIsSorted() || null}\n />\n {isLastCell && (\n <div className={\"h-md\"}>\n <ColumnsVisibility\n columns={table.getAllColumns()}\n />\n </div>\n )}\n </ColumnSorter>\n )}\n {header.column.getCanResize() && (\n <Table.Resizer\n onMouseDown={header.getResizeHandler()}\n onTouchStart={header.getResizeHandler()}\n isResizing={header.column.getIsResizing()}\n />\n )}\n </Table.Head>\n );\n })}\n </Table.Row>\n ))}\n </Table.Header>\n <Table.Body>\n {tableRows.map(row => {\n const id = row.original.id || row.id;\n return (\n <MemoTableRow<T>\n key={id}\n cells={row.getVisibleCells()}\n selected={row.getIsSelected()}\n getColumnWidth={getColumnWidth}\n />\n );\n })}\n </Table.Body>\n </Table>\n </div>\n );\n};\n\nconst DataTable = makeDecoratable(\"DataTable\", DecoratableDataTable);\n\nexport {\n DataTable,\n type DataTableProps,\n type DataTableColumn,\n type DataTableColumns,\n type DataTableDefaultData,\n type DataTableRow,\n type DataTableSorting,\n type DataTableColumnSort,\n type OnDataTableSortingChange,\n type DataTableColumnVisibility,\n type OnDataTableColumnVisibilityChange\n};\n"],"names":["defineColumns","columns","options","canSelectAllRows","onSelectRow","onToggleRow","loading","useMemo","columnsList","Object","key","defaults","column","accessorKey","cell","className","enableHiding","enableResizing","enableSorting","header","truncate","id","size","props","String","columnsDefs","firstColumn","isSelectable","CheckboxPrimitive","e","React","value","cn","Skeleton","typedMemo","memo","TableCell","getColumnWidth","width","Table","flexRender","MemoTableCell","TableRow","selected","cells","MemoTableRow","emptyArray","Array","DecoratableDataTable","bordered","columnVisibility","initialColumns","initialData","initialSorting","isRowSelectable","onColumnVisibilityChange","onSortingChange","selectedRows","sorting","stickyHeader","tableRef","useRef","tableWidth","setTableWidth","useState","data","useEffect","updateElementWidth","window","rowSelection","acc","item","recordIndex","rec","onRowSelectionChange","updater","newSelection","toggledRows","x","parseInt","selection","tableSorting","table","useReactTable","getCoreRowModel","getSortedRowModel","useCallback","visibleColumns","fixedTotal","col","total","resizableTotal","available","Math","tableRows","headerGroup","index","isLastCell","ColumnSorter","ColumnsVisibility","row","DataTable","makeDecoratable"],"mappings":"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"}
1
+ {"version":3,"file":"DataTable/DataTable.js","sources":["../../src/DataTable/DataTable.tsx"],"sourcesContent":["import React, { memo, useCallback, useEffect, useMemo, useRef, useState } from \"react\";\nimport type {\n Cell,\n Column,\n ColumnDef,\n ColumnSort,\n ColumnVisibilityState,\n OnChangeFn,\n Row,\n RowData,\n RowSelectionState,\n SortingState\n} from \"@tanstack/react-table\";\nimport {\n columnResizingFeature,\n columnSizingFeature,\n columnVisibilityFeature,\n createCoreRowModel,\n createSortedRowModel,\n flexRender,\n rowSelectionFeature,\n rowSortingFeature,\n tableFeatures,\n useTable\n} from \"@tanstack/react-table\";\nimport { CheckboxPrimitive } from \"~/Checkbox/index.js\";\nimport { Skeleton } from \"~/Skeleton/index.js\";\nimport { Table } from \"~/Table/index.js\";\nimport { ColumnSorter, ColumnsVisibility } from \"./components/index.js\";\nimport { cn, makeDecoratable } from \"~/utils.js\";\n\nconst features = tableFeatures({\n columnResizingFeature,\n columnSizingFeature,\n columnVisibilityFeature,\n rowSelectionFeature,\n rowSortingFeature,\n sortedRowModel: createSortedRowModel(),\n coreRowModel: createCoreRowModel()\n});\n\ntype Features = typeof features;\n\ninterface DataTableColumn<T> {\n /*\n * Column header component.\n */\n header?: string | number | React.JSX.Element;\n /*\n * Cell renderer, receives the full row and returns the value to render inside the cell.\n */\n cell?: (row: T) => string | number | React.JSX.Element | null;\n /*\n * Column size.\n */\n size?: number;\n /*\n * Should truncate?\n */\n truncate?: boolean;\n /*\n * Column class names.\n */\n className?: string;\n /*\n * Enable column sorting.\n */\n enableSorting?: boolean;\n /*\n * Enable column resizing.\n */\n enableResizing?: boolean;\n /*\n * Enable column visibility toggling.\n */\n enableHiding?: boolean;\n /*\n * Accessor key for the column data path.\n */\n accessorKey?: string;\n}\n\ntype DataTableColumns<T> = {\n [P in keyof T]?: DataTableColumn<T>;\n};\n\ntype DataTableDefaultData = {\n id: string;\n /*\n * Define if a specific row can be selected.\n */\n $selectable?: boolean;\n};\n\ntype DataTableRow<T extends RowData> = Row<Features, DataTableDefaultData & T>;\n\ntype DataTableSorting = SortingState;\n\ntype DataTableColumnSort = ColumnSort;\n\ntype OnDataTableSortingChange = OnChangeFn<DataTableSorting>;\n\ntype DataTableColumnVisibility = ColumnVisibilityState;\n\ntype OnDataTableColumnVisibilityChange = OnChangeFn<DataTableColumnVisibility>;\n\ninterface DataTableProps<TEntry extends RowData> {\n /**\n * Show or hide borders.\n */\n bordered?: boolean;\n /**\n * Controls whether \"select all\" action is allowed.\n */\n canSelectAllRows?: boolean;\n /**\n * Columns definition.\n */\n columns: DataTableColumns<TEntry>;\n /**\n * The column visibility state.\n */\n columnVisibility?: DataTableColumnVisibility;\n /**\n * Callback that receives current column visibility state.\n */\n onColumnVisibilityChange?: OnDataTableColumnVisibilityChange;\n /**\n * Data to display into DataTable body.\n */\n data: TEntry[];\n /**\n * Callback that is called to determine if the row is selectable.\n */\n isRowSelectable?: (row: Row<Features, TEntry>) => boolean;\n /**\n * Render the skeleton state while data are loading.\n */\n loading?: boolean;\n /**\n * Callback that receives the selected rows.\n */\n onSelectRow?: (rows: TEntry[]) => void;\n /**\n * Callback that receives the toggled row.\n */\n onToggleRow?: (row: TEntry) => void;\n /**\n * Callback that receives current sorting state.\n */\n onSortingChange?: OnDataTableSortingChange;\n /**\n * Selected rows.\n */\n selectedRows?: TEntry[];\n /**\n * Sorting state.\n */\n sorting?: DataTableSorting;\n /**\n * Initial sorting state.\n */\n initialSorting?: DataTableSorting;\n /**\n * Enable sticky header.\n */\n stickyHeader?: boolean;\n}\n\ninterface DefineColumnsOptions<TEntry extends RowData> {\n canSelectAllRows: boolean;\n onSelectRow?: DataTableProps<TEntry>[\"onSelectRow\"];\n onToggleRow: DataTableProps<TEntry>[\"onToggleRow\"];\n loading: DataTableProps<TEntry>[\"loading\"];\n}\n\nconst defineColumns = <T extends RowData>(\n columns: DataTableProps<T>[\"columns\"],\n options: DefineColumnsOptions<T>\n): ColumnDef<Features, T>[] => {\n const { canSelectAllRows, onSelectRow, onToggleRow, loading } = options;\n\n return useMemo(() => {\n const columnsList = Object.keys(columns).map(key => ({\n id: key,\n ...columns[key as keyof typeof columns]\n }));\n\n const defaults: ColumnDef<Features, T>[] = columnsList.map(column => {\n const {\n accessorKey,\n cell,\n className,\n enableHiding = true,\n enableResizing = true,\n enableSorting = false,\n header,\n truncate = true,\n id,\n size = 100\n } = column;\n\n return {\n id,\n accessorKey: accessorKey || id,\n header: () => header,\n cell: props => {\n if (cell && typeof cell === \"function\") {\n return cell(props.row.original);\n } else {\n // Automatically convert any cell value to a string for rendering,\n // ensuring the table displays values correctly. This aligns with React's\n // rendering, which expects JSX, strings or null.\n // https://github.com/TanStack/table/issues/1042\n return props.getValue() ? String(props.getValue()) : null;\n }\n },\n enableSorting,\n meta: {\n className,\n truncate\n },\n enableResizing,\n size,\n enableHiding\n };\n });\n\n let columnsDefs = defaults;\n const firstColumn = defaults[0];\n const isSelectable = onToggleRow || onSelectRow;\n\n if (isSelectable && firstColumn) {\n columnsDefs = [\n {\n ...firstColumn,\n accessorKey: firstColumn.id as string,\n header: props => {\n if (!props) {\n return null;\n }\n\n return (\n <div className={\"flex items-center gap-xl\"}>\n <CheckboxPrimitive\n indeterminate={props.table.getIsSomeRowsSelected()}\n checked={props.table.getIsAllRowsSelected()}\n onChange={props.table.toggleAllPageRowsSelected}\n aria-label=\"Select all\"\n disabled={!canSelectAllRows}\n onClick={e => e.stopPropagation()}\n />\n {firstColumn.header\n ? React.createElement(firstColumn.header, props)\n : null}\n </div>\n );\n },\n cell: props => {\n if (!props) {\n return null;\n }\n return (\n <div className={\"flex items-center gap-xl\"}>\n <CheckboxPrimitive\n checked={props.row.getIsSelected()}\n onChange={value => props.row.toggleSelected(!!value)}\n disabled={!props.row.getCanSelect()}\n aria-label=\"Select row\"\n className={cn(!props.row.getCanSelect() ? \"invisible\" : \"\")}\n />\n {firstColumn.cell\n ? React.createElement(firstColumn.cell, props)\n : null}\n </div>\n );\n }\n },\n ...defaults.slice(1)\n ];\n }\n\n return columnsDefs.map(column => {\n if (loading) {\n return {\n ...column,\n cell: () => <Skeleton type={\"text\"} size={\"md\"} />\n };\n }\n\n return column;\n });\n }, [columns, onSelectRow, onToggleRow, loading]);\n};\n\nconst typedMemo: <T>(component: T) => T = memo;\n\ninterface TableCellProps<T extends RowData> {\n cell: Cell<Features, T, unknown>;\n getColumnWidth: (column: Column<Features, T>) => number;\n}\n\nconst TableCell = <T extends RowData>({ cell, getColumnWidth }: TableCellProps<T>) => {\n const width = getColumnWidth(cell.column);\n\n return (\n <Table.Cell {...cell.column.columnDef.meta} style={{ width, maxWidth: width }}>\n {flexRender(cell.column.columnDef.cell, cell.getContext())}\n </Table.Cell>\n );\n};\n\nconst MemoTableCell = typedMemo(TableCell);\n\ninterface TableRowProps<T extends RowData> {\n selected: boolean;\n cells: Cell<Features, T, unknown>[];\n getColumnWidth: (column: Column<Features, T>) => number;\n}\n\nconst TableRow = <T extends RowData>({ selected, cells, getColumnWidth }: TableRowProps<T>) => {\n return (\n <Table.Row selected={selected}>\n {cells.map(cell => (\n <MemoTableCell<T> key={cell.id} cell={cell} getColumnWidth={getColumnWidth} />\n ))}\n </Table.Row>\n );\n};\n\nconst MemoTableRow = typedMemo(TableRow);\n\n/**\n * Empty array must be defined outside the React component so it does not force rerendering of the DataTable\n */\nconst emptyArray = Array(10).fill({});\n\nconst DecoratableDataTable = <T extends Record<string, any> & DataTableDefaultData>({\n bordered,\n canSelectAllRows = true,\n columnVisibility,\n columns: initialColumns,\n data: initialData,\n initialSorting,\n isRowSelectable,\n loading,\n onColumnVisibilityChange,\n onSelectRow,\n onSortingChange,\n onToggleRow,\n selectedRows = [],\n sorting,\n stickyHeader\n}: DataTableProps<T>) => {\n const tableRef = useRef<HTMLDivElement>(null);\n const [tableWidth, setTableWidth] = useState(1);\n\n const data = loading ? emptyArray : initialData;\n\n useEffect(() => {\n const updateElementWidth = () => {\n if (tableRef.current) {\n const width = tableRef.current.clientWidth;\n setTableWidth(width);\n }\n };\n\n updateElementWidth();\n\n window.addEventListener(\"resize\", updateElementWidth);\n\n return () => {\n window.removeEventListener(\"resize\", updateElementWidth);\n };\n }, [tableRef.current]);\n\n const rowSelection = useMemo(() => {\n return selectedRows.reduce<RowSelectionState>((acc, item) => {\n const recordIndex = data.findIndex(rec => rec.id === item.id);\n return { ...acc, [recordIndex]: true };\n }, {});\n }, [selectedRows, data]);\n\n const onRowSelectionChange: OnChangeFn<RowSelectionState> = updater => {\n const newSelection = typeof updater === \"function\" ? updater(rowSelection) : updater;\n\n /**\n * `@tanstack/react-table` isn't telling us what row was selected or deselected. It simply gives us\n * the new selection state (an object with row indexes that are currently selected).\n *\n * To figure out what row was toggled, we need to calculate the difference between the old selection\n * and the new selection. What we're doing here is:\n * - find all items that were present in the previous selection, but are no longer present in the new selection\n * - find all items that are present in the new selection, but were not present in the previous selection\n */\n const toggledRows = [\n ...Object.keys(rowSelection).filter(x => !(x in newSelection)),\n ...Object.keys(newSelection).filter(x => !(x in rowSelection))\n ];\n\n // If the difference is only 1 item, and `onToggleRow` is available, execute that.\n if (toggledRows.length === 1 && typeof onToggleRow === \"function\") {\n onToggleRow(data[parseInt(toggledRows[0])]);\n return;\n } else if (typeof onSelectRow === \"function\") {\n const selection = Object.keys(newSelection).map(key => data[parseInt(key)]);\n onSelectRow(selection);\n }\n };\n\n const tableSorting = useMemo(() => {\n if (!Array.isArray(sorting) || !sorting.length) {\n return initialSorting;\n }\n return sorting;\n }, [sorting]);\n\n const columns = defineColumns(initialColumns, {\n canSelectAllRows,\n onSelectRow,\n onToggleRow,\n loading\n });\n\n const table = useTable<typeof features, T>({\n features,\n columnResizeMode: \"onChange\",\n columns,\n data,\n enableColumnResizing: true,\n enableHiding: !!onColumnVisibilityChange,\n enableRowSelection: isRowSelectable,\n enableSorting: !!onSortingChange,\n enableSortingRemoval: false,\n manualSorting: true,\n onColumnVisibilityChange,\n onRowSelectionChange,\n onSortingChange,\n state: {\n columnVisibility,\n rowSelection,\n sorting: tableSorting\n }\n });\n\n const getColumnWidth = useCallback(\n (column: Column<Features, T>): number => {\n // Non-resizable columns (e.g. row-selection, actions) keep their fixed size.\n if (!column.getCanResize()) {\n return column.getSize();\n }\n\n /**\n * Resizable columns share the space left after the fixed columns, proportionally to\n * their own size. This makes the table always fill the full container width — even when\n * columns are hidden — so trailing content (e.g. the columns-visibility cog) stays\n * flush right instead of drifting left as columns are removed.\n */\n const visibleColumns = table.getVisibleLeafColumns();\n const fixedTotal = visibleColumns\n .filter(col => !col.getCanResize())\n .reduce((total, col) => total + col.getSize(), 0);\n const resizableTotal = visibleColumns\n .filter(col => col.getCanResize())\n .reduce((total, col) => total + col.getSize(), 0);\n\n if (resizableTotal === 0) {\n return column.getSize();\n }\n\n const available = Math.max(tableWidth - fixedTotal, 0);\n\n return Math.ceil((column.getSize() * available) / resizableTotal);\n },\n [table, tableWidth]\n );\n\n /**\n * Had to memoize the rows to avoid browser freeze.\n */\n const tableRows = useMemo(() => {\n return table.getRowModel().rows;\n }, [table, data, columns]);\n\n return (\n <div ref={tableRef}>\n <Table bordered={bordered} sticky={stickyHeader}>\n <Table.Header sticky={stickyHeader}>\n {table.getHeaderGroups().map(headerGroup => (\n <Table.Row key={headerGroup.id}>\n {headerGroup.headers.map((header, index) => {\n const isLastCell = index === headerGroup.headers.length - 1;\n const width = getColumnWidth(header.column);\n\n return (\n <Table.Head\n key={header.id}\n {...header.column.columnDef.meta}\n colSpan={header.colSpan}\n style={{ width, maxWidth: width }}\n >\n {header.isPlaceholder ? null : (\n <ColumnSorter\n onClick={header.column.getToggleSortingHandler()}\n sortable={header.column.getCanSort()}\n >\n <div\n className={cn({\n \"w-full overflow-hidden whitespace-nowrap\": true,\n truncate: !isLastCell\n })}\n >\n {flexRender(\n header.column.columnDef.header,\n header.getContext()\n )}\n </div>\n <Table.Direction\n direction={header.column.getIsSorted() || null}\n />\n {isLastCell && (\n <div className={\"h-md\"}>\n <ColumnsVisibility\n columns={table.getAllColumns()}\n />\n </div>\n )}\n </ColumnSorter>\n )}\n {header.column.getCanResize() && (\n <Table.Resizer\n onMouseDown={header.getResizeHandler()}\n onTouchStart={header.getResizeHandler()}\n isResizing={header.column.getIsResizing()}\n />\n )}\n </Table.Head>\n );\n })}\n </Table.Row>\n ))}\n </Table.Header>\n <Table.Body>\n {tableRows.map(row => {\n const id = row.original.id || row.id;\n return (\n <MemoTableRow<T>\n key={id}\n cells={row.getVisibleCells()}\n selected={row.getIsSelected()}\n getColumnWidth={getColumnWidth}\n />\n );\n })}\n </Table.Body>\n </Table>\n </div>\n );\n};\n\nconst DataTable = makeDecoratable(\"DataTable\", DecoratableDataTable);\n\nexport {\n DataTable,\n type Features,\n type DataTableProps,\n type DataTableColumn,\n type DataTableColumns,\n type DataTableDefaultData,\n type DataTableRow,\n type DataTableSorting,\n type DataTableColumnSort,\n type OnDataTableSortingChange,\n type DataTableColumnVisibility,\n type OnDataTableColumnVisibilityChange\n};\n"],"names":["features","tableFeatures","columnResizingFeature","columnSizingFeature","columnVisibilityFeature","rowSelectionFeature","rowSortingFeature","createSortedRowModel","createCoreRowModel","defineColumns","columns","options","canSelectAllRows","onSelectRow","onToggleRow","loading","useMemo","columnsList","Object","key","defaults","column","accessorKey","cell","className","enableHiding","enableResizing","enableSorting","header","truncate","id","size","props","String","columnsDefs","firstColumn","isSelectable","CheckboxPrimitive","e","React","value","cn","Skeleton","typedMemo","memo","TableCell","getColumnWidth","width","Table","flexRender","MemoTableCell","TableRow","selected","cells","MemoTableRow","emptyArray","Array","DecoratableDataTable","bordered","columnVisibility","initialColumns","initialData","initialSorting","isRowSelectable","onColumnVisibilityChange","onSortingChange","selectedRows","sorting","stickyHeader","tableRef","useRef","tableWidth","setTableWidth","useState","data","useEffect","updateElementWidth","window","rowSelection","acc","item","recordIndex","rec","onRowSelectionChange","updater","newSelection","toggledRows","x","parseInt","selection","tableSorting","table","useTable","useCallback","visibleColumns","fixedTotal","col","total","resizableTotal","available","Math","tableRows","headerGroup","index","isLastCell","ColumnSorter","ColumnsVisibility","row","DataTable","makeDecoratable"],"mappings":"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"}
@@ -1,7 +1,8 @@
1
1
  import React from "react";
2
- import type { Column } from "@tanstack/react-table";
3
- interface ColumnsVisibilityProps<T> {
4
- columns: Column<T>[];
2
+ import type { Column, RowData } from "@tanstack/react-table";
3
+ import type { Features } from "../DataTable.js";
4
+ interface ColumnsVisibilityProps<T extends RowData> {
5
+ columns: Column<Features, T>[];
5
6
  }
6
- export declare const ColumnsVisibility: <T>(props: ColumnsVisibilityProps<T>) => React.JSX.Element | null;
7
+ export declare const ColumnsVisibility: <T extends RowData>(props: ColumnsVisibilityProps<T>) => React.JSX.Element | null;
7
8
  export {};
@@ -7,14 +7,17 @@ const ColumnsVisibility = (props)=>{
7
7
  const getHeaderName = useCallback((column)=>{
8
8
  const { header } = column.columnDef;
9
9
  if ("string" == typeof header) return header;
10
- if ("function" == typeof header) return header();
10
+ if ("function" == typeof header) {
11
+ const flatHeader = column.table.getFlatHeaders().find((h)=>h.column.id === column.id);
12
+ if (flatHeader) return header(flatHeader.getContext());
13
+ }
11
14
  return column.id;
12
15
  }, []);
13
16
  const options = useMemo(()=>props.columns.filter((column)=>column.getCanHide()).map((column)=>({
14
17
  id: column.id,
15
18
  header: getHeaderName(column),
16
- onChange: column.toggleVisibility,
17
- getValue: column.getIsVisible
19
+ onChange: (value)=>column.toggleVisibility(value),
20
+ getValue: ()=>column.getIsVisible()
18
21
  })), [
19
22
  props.columns
20
23
  ]);
@@ -1 +1 @@
1
- {"version":3,"file":"DataTable/components/ColumnsVisibility.js","sources":["../../../src/DataTable/components/ColumnsVisibility.tsx"],"sourcesContent":["import React, { useCallback, useMemo } from \"react\";\nimport { ReactComponent as SettingsIcon } from \"@webiny/icons/settings.svg\";\nimport type { Column } from \"@tanstack/react-table\";\nimport { IconButton } from \"~/Button/index.js\";\nimport { Checkbox } from \"~/Checkbox/index.js\";\nimport { DropdownMenu } from \"~/DropdownMenu/index.js\";\n\ninterface ColumnsVisibilityProps<T> {\n columns: Column<T>[];\n}\n\ninterface Option {\n id: string;\n header: string;\n onChange: (value?: boolean | undefined) => void;\n getValue: () => boolean;\n}\n\nexport const ColumnsVisibility = <T,>(props: ColumnsVisibilityProps<T>) => {\n /**\n * `@tanstack/react-table` does not have a simple method to return the header component.\n * The only possible way is to use `flexRenderer`, but this is not working with the current implementation\n * since we don't have access to the header context.\n */\n const getHeaderName = useCallback((column: Column<T>) => {\n const { header } = column.columnDef;\n\n if (typeof header === \"string\") {\n return header;\n }\n\n if (typeof header === \"function\") {\n // @ts-expect-error\n return header();\n }\n\n return column.id;\n }, []);\n\n const options: Option[] = useMemo(() => {\n return props.columns\n .filter(column => column.getCanHide())\n .map(column => {\n return {\n id: column.id,\n header: getHeaderName(column),\n onChange: column.toggleVisibility,\n getValue: column.getIsVisible\n };\n });\n }, [props.columns]);\n\n if (options.length === 0) {\n return null;\n }\n\n return (\n <DropdownMenu\n trigger={<IconButton icon={<SettingsIcon />} variant={\"ghost\"} size={\"xs\"} />}\n >\n <DropdownMenu.Label text={\"Display columns\"} />\n {options.map(option => {\n return (\n <DropdownMenu.Item\n key={option.id}\n preventClose\n text={\n <Checkbox\n label={option.header}\n onChange={option.onChange}\n checked={option.getValue()}\n />\n }\n />\n );\n })}\n </DropdownMenu>\n );\n};\n"],"names":["ColumnsVisibility","props","getHeaderName","useCallback","column","header","options","useMemo","DropdownMenu","IconButton","SettingsIcon","option","Checkbox"],"mappings":";;;;;AAkBO,MAAMA,oBAAoB,CAAKC;IAMlC,MAAMC,gBAAgBC,YAAY,CAACC;QAC/B,MAAM,EAAEC,MAAM,EAAE,GAAGD,OAAO,SAAS;QAEnC,IAAI,AAAkB,YAAlB,OAAOC,QACP,OAAOA;QAGX,IAAI,AAAkB,cAAlB,OAAOA,QAEP,OAAOA;QAGX,OAAOD,OAAO,EAAE;IACpB,GAAG,EAAE;IAEL,MAAME,UAAoBC,QAAQ,IACvBN,MAAM,OAAO,CACf,MAAM,CAACG,CAAAA,SAAUA,OAAO,UAAU,IAClC,GAAG,CAACA,CAAAA,SACM;gBACH,IAAIA,OAAO,EAAE;gBACb,QAAQF,cAAcE;gBACtB,UAAUA,OAAO,gBAAgB;gBACjC,UAAUA,OAAO,YAAY;YACjC,KAET;QAACH,MAAM,OAAO;KAAC;IAElB,IAAIK,AAAmB,MAAnBA,QAAQ,MAAM,EACd,OAAO;IAGX,OAAO,WAAP,GACI,oBAACE,cAAYA;QACT,uBAAS,oBAACC,YAAUA;YAAC,oBAAM,oBAACC,gBAAYA;YAAK,SAAS;YAAS,MAAM;;qBAErE,oBAACF,aAAa,KAAK;QAAC,MAAM;QACzBF,QAAQ,GAAG,CAACK,CAAAA,SACF,WAAP,GACI,oBAACH,aAAa,IAAI;YACd,KAAKG,OAAO,EAAE;YACd;YACA,oBACI,oBAACC,UAAQA;gBACL,OAAOD,OAAO,MAAM;gBACpB,UAAUA,OAAO,QAAQ;gBACzB,SAASA,OAAO,QAAQ;;;AAQxD"}
1
+ {"version":3,"file":"DataTable/components/ColumnsVisibility.js","sources":["../../../src/DataTable/components/ColumnsVisibility.tsx"],"sourcesContent":["import React, { useCallback, useMemo } from \"react\";\nimport { ReactComponent as SettingsIcon } from \"@webiny/icons/settings.svg\";\nimport type { Column, RowData } from \"@tanstack/react-table\";\nimport { IconButton } from \"~/Button/index.js\";\nimport { Checkbox } from \"~/Checkbox/index.js\";\nimport { DropdownMenu } from \"~/DropdownMenu/index.js\";\nimport type { Features } from \"../DataTable.js\";\n\ninterface ColumnsVisibilityProps<T extends RowData> {\n columns: Column<Features, T>[];\n}\n\ninterface Option {\n id: string;\n header: string;\n onChange: (value?: boolean | undefined) => void;\n getValue: () => boolean;\n}\n\nexport const ColumnsVisibility = <T extends RowData>(props: ColumnsVisibilityProps<T>) => {\n /**\n * `@tanstack/react-table` does not have a simple method to return the header component.\n * The only possible way is to use `flexRenderer`, but this is not working with the current implementation\n * since we don't have access to the header context.\n */\n const getHeaderName = useCallback((column: Column<Features, T>) => {\n const { header } = column.columnDef;\n\n if (typeof header === \"string\") {\n return header;\n }\n\n if (typeof header === \"function\") {\n const flatHeader = column.table.getFlatHeaders().find(h => h.column.id === column.id);\n\n if (flatHeader) {\n return header(flatHeader.getContext());\n }\n }\n\n return column.id;\n }, []);\n\n const options: Option[] = useMemo(() => {\n return props.columns\n .filter(column => column.getCanHide())\n .map(column => {\n return {\n id: column.id,\n header: getHeaderName(column),\n /**\n * `@tanstack/react-table` v9 puts these on the column prototype, so they\n * read their column off `this`. They must stay attached to the column.\n */\n onChange: value => column.toggleVisibility(value),\n getValue: () => column.getIsVisible()\n };\n });\n }, [props.columns]);\n\n if (options.length === 0) {\n return null;\n }\n\n return (\n <DropdownMenu\n trigger={<IconButton icon={<SettingsIcon />} variant={\"ghost\"} size={\"xs\"} />}\n >\n <DropdownMenu.Label text={\"Display columns\"} />\n {options.map(option => {\n return (\n <DropdownMenu.Item\n key={option.id}\n preventClose\n text={\n <Checkbox\n label={option.header}\n onChange={option.onChange}\n checked={option.getValue()}\n />\n }\n />\n );\n })}\n </DropdownMenu>\n );\n};\n"],"names":["ColumnsVisibility","props","getHeaderName","useCallback","column","header","flatHeader","h","options","useMemo","value","DropdownMenu","IconButton","SettingsIcon","option","Checkbox"],"mappings":";;;;;AAmBO,MAAMA,oBAAoB,CAAoBC;IAMjD,MAAMC,gBAAgBC,YAAY,CAACC;QAC/B,MAAM,EAAEC,MAAM,EAAE,GAAGD,OAAO,SAAS;QAEnC,IAAI,AAAkB,YAAlB,OAAOC,QACP,OAAOA;QAGX,IAAI,AAAkB,cAAlB,OAAOA,QAAuB;YAC9B,MAAMC,aAAaF,OAAO,KAAK,CAAC,cAAc,GAAG,IAAI,CAACG,CAAAA,IAAKA,EAAE,MAAM,CAAC,EAAE,KAAKH,OAAO,EAAE;YAEpF,IAAIE,YACA,OAAOD,OAAOC,WAAW,UAAU;QAE3C;QAEA,OAAOF,OAAO,EAAE;IACpB,GAAG,EAAE;IAEL,MAAMI,UAAoBC,QAAQ,IACvBR,MAAM,OAAO,CACf,MAAM,CAACG,CAAAA,SAAUA,OAAO,UAAU,IAClC,GAAG,CAACA,CAAAA,SACM;gBACH,IAAIA,OAAO,EAAE;gBACb,QAAQF,cAAcE;gBAKtB,UAAUM,CAAAA,QAASN,OAAO,gBAAgB,CAACM;gBAC3C,UAAU,IAAMN,OAAO,YAAY;YACvC,KAET;QAACH,MAAM,OAAO;KAAC;IAElB,IAAIO,AAAmB,MAAnBA,QAAQ,MAAM,EACd,OAAO;IAGX,OAAO,WAAP,GACI,oBAACG,cAAYA;QACT,uBAAS,oBAACC,YAAUA;YAAC,oBAAM,oBAACC,gBAAYA;YAAK,SAAS;YAAS,MAAM;;qBAErE,oBAACF,aAAa,KAAK;QAAC,MAAM;QACzBH,QAAQ,GAAG,CAACM,CAAAA,SACF,WAAP,GACI,oBAACH,aAAa,IAAI;YACd,KAAKG,OAAO,EAAE;YACd;YACA,oBACI,oBAACC,UAAQA;gBACL,OAAOD,OAAO,MAAM;gBACpB,UAAUA,OAAO,QAAQ;gBACzB,SAASA,OAAO,QAAQ;;;AAQxD"}
@@ -1,11 +1,10 @@
1
1
  import react, { useState } from "react";
2
- import { format } from "date-fns";
3
2
  import { UTC_TIMEZONES } from "@webiny/utils";
4
3
  import { Calendar } from "../../Calendar/index.js";
5
4
  import { PopoverPrimitive } from "../../Popover/index.js";
6
5
  import { SelectPrimitive } from "../../Select/index.js";
7
- import { extractTimezone, formatDateForDisplay, formatTimeValue, getLocalTimezone, parseTimeValue } from "../utils/dateHelpers.js";
8
- import { naiveDateToUtcIso, parseToDate, utcToTimezoneDate } from "../utils/timezoneHelpers.js";
6
+ import { extractTimezone, formatDateForDisplay, formatTimeValue, getLocalTimezone, parseTimeValue, toIsoWithTz } from "../utils/dateHelpers.js";
7
+ import { parseToDate, utcToTimezoneDate } from "../utils/timezoneHelpers.js";
9
8
  import { DatePickerTrigger } from "./components/DatePickerTrigger.js";
10
9
  import { TimePicker } from "./components/TimePicker.js";
11
10
  const timezoneOptions = UTC_TIMEZONES.map((tz)=>({
@@ -15,18 +14,19 @@ const timezoneOptions = UTC_TIMEZONES.map((tz)=>({
15
14
  const DateTimePicker = ({ value, onChange, placeholder, disabled, size, variant, invalid, weekStartsOn, onOpenChange, className, withTimezone, displayFormat, minDate, maxDate })=>{
16
15
  const [open, setOpen] = useState(false);
17
16
  const existingTz = withTimezone && value ? extractTimezone(value) : void 0;
18
- const [timezone, setTimezone] = useState(existingTz || getLocalTimezone());
17
+ const [selectedTimezone, setSelectedTimezone] = useState(getLocalTimezone());
18
+ const timezone = existingTz || selectedTimezone;
19
19
  const handleOpenChange = (isOpen)=>{
20
20
  setOpen(isOpen);
21
21
  if (onOpenChange) onOpenChange(isOpen);
22
22
  };
23
23
  const currentDate = parseToDate(value);
24
24
  const displayDate = withTimezone && currentDate ? utcToTimezoneDate(currentDate, timezone) : currentDate;
25
- const displayValue = withTimezone ? displayDate ? formatDateForDisplay(format(displayDate, "yyyy-MM-dd'T'HH:mm:ss") + timezone, "dateTimeTz", displayFormat) : void 0 : formatDateForDisplay(value, "dateTimeLocal", displayFormat);
25
+ const displayValue = withTimezone ? displayDate ? formatDateForDisplay(toIsoWithTz(displayDate, timezone), "dateTimeTz", displayFormat) : void 0 : formatDateForDisplay(value, "dateTimeLocal", displayFormat);
26
26
  const timeValue = displayDate ? formatTimeValue(displayDate) : "";
27
27
  const emitChange = (date, tz)=>{
28
28
  if (!onChange) return;
29
- withTimezone ? onChange(naiveDateToUtcIso(date, tz || timezone)) : onChange(format(date, "yyyy-MM-dd'T'HH:mm:ss") + ".000Z");
29
+ withTimezone ? onChange(toIsoWithTz(date, tz || timezone)) : onChange(date.toISOString());
30
30
  };
31
31
  const handleDateSelect = (date)=>{
32
32
  if (!date) return;
@@ -42,7 +42,8 @@ const DateTimePicker = ({ value, onChange, placeholder, disabled, size, variant,
42
42
  emitChange(base);
43
43
  };
44
44
  const handleTimezoneChange = (tz)=>{
45
- setTimezone(tz);
45
+ setSelectedTimezone(tz);
46
+ if (displayDate) emitChange(displayDate, tz);
46
47
  };
47
48
  return /*#__PURE__*/ react.createElement("div", {
48
49
  className: className
@@ -1 +1 @@
1
- {"version":3,"file":"DatePicker/primitives/DateTimePicker.js","sources":["../../../src/DatePicker/primitives/DateTimePicker.tsx"],"sourcesContent":["import React, { useState } from \"react\";\nimport { format } from \"date-fns\";\nimport { UTC_TIMEZONES } from \"@webiny/utils\";\nimport { Calendar } from \"~/Calendar/index.js\";\nimport { PopoverPrimitive } from \"~/Popover/index.js\";\nimport { SelectPrimitive } from \"~/Select/index.js\";\nimport type { DateTimeLocalPickerProps, DateTimeTzPickerProps } from \"../utils/types.js\";\nimport {\n extractTimezone,\n formatDateForDisplay,\n formatTimeValue,\n getLocalTimezone,\n parseTimeValue\n} from \"../utils/dateHelpers.js\";\nimport { naiveDateToUtcIso, parseToDate, utcToTimezoneDate } from \"../utils/timezoneHelpers.js\";\nimport { DatePickerTrigger } from \"./components/DatePickerTrigger.js\";\nimport { TimePicker } from \"./components/TimePicker.js\";\n\ntype DateTimePickerInternalProps = (DateTimeLocalPickerProps | DateTimeTzPickerProps) & {\n withTimezone: boolean;\n};\n\nconst timezoneOptions = UTC_TIMEZONES.map(tz => ({ value: tz.value, label: tz.label }));\n\nconst DateTimePicker = ({\n value,\n onChange,\n placeholder,\n disabled,\n size,\n variant,\n invalid,\n weekStartsOn,\n onOpenChange,\n className,\n withTimezone,\n displayFormat,\n minDate,\n maxDate\n}: DateTimePickerInternalProps) => {\n const [open, setOpen] = useState(false);\n\n const existingTz = withTimezone && value ? extractTimezone(value) : undefined;\n const [timezone, setTimezone] = useState(existingTz || getLocalTimezone());\n\n const handleOpenChange = (isOpen: boolean) => {\n setOpen(isOpen);\n if (onOpenChange) {\n onOpenChange(isOpen);\n }\n };\n\n const currentDate = parseToDate(value);\n\n const displayDate =\n withTimezone && currentDate ? utcToTimezoneDate(currentDate, timezone) : currentDate;\n\n const displayValue = withTimezone\n ? displayDate\n ? formatDateForDisplay(\n format(displayDate, \"yyyy-MM-dd'T'HH:mm:ss\") + timezone,\n \"dateTimeTz\",\n displayFormat\n )\n : undefined\n : formatDateForDisplay(value, \"dateTimeLocal\", displayFormat);\n\n const timeValue = displayDate ? formatTimeValue(displayDate) : \"\";\n\n const emitChange = (date: Date, tz?: string) => {\n if (!onChange) {\n return;\n }\n if (withTimezone) {\n onChange(naiveDateToUtcIso(date, tz || timezone));\n } else {\n onChange(format(date, \"yyyy-MM-dd'T'HH:mm:ss\") + \".000Z\");\n }\n };\n\n const handleDateSelect = (date: Date | undefined) => {\n if (!date) {\n return;\n }\n if (displayDate) {\n date.setHours(displayDate.getHours(), displayDate.getMinutes());\n }\n emitChange(date);\n };\n\n const handleTimeChange = (time: string | undefined) => {\n if (!time) {\n return;\n }\n const parsed = parseTimeValue(time);\n if (!parsed) {\n return;\n }\n const base = displayDate ? new Date(displayDate) : new Date();\n base.setHours(parsed.hours, parsed.minutes, 0, 0);\n emitChange(base);\n };\n\n const handleTimezoneChange = (tz: string) => {\n setTimezone(tz);\n };\n\n return (\n <div className={className}>\n <PopoverPrimitive open={open} onOpenChange={handleOpenChange}>\n <DatePickerTrigger\n displayValue={displayValue}\n placeholder={placeholder ?? \"Pick date & time\"}\n disabled={disabled}\n size={size}\n variant={variant}\n invalid={invalid}\n />\n <PopoverPrimitive.Content align=\"start\">\n <div className=\"flex flex-col gap-sm\">\n <Calendar\n mode=\"single\"\n selected={displayDate}\n onSelect={handleDateSelect}\n weekStartsOn={weekStartsOn}\n disabled={[\n ...(minDate ? [{ before: minDate }] : []),\n ...(maxDate ? [{ after: maxDate }] : [])\n ]}\n />\n <div className=\"flex gap-sm px-md pb-md\">\n <div className=\"flex-1\">\n <TimePicker\n value={timeValue}\n onChange={handleTimeChange}\n disabled={disabled}\n size=\"md\"\n />\n </div>\n {withTimezone && (\n <div className=\"flex-1\">\n <SelectPrimitive\n value={timezone}\n onChange={handleTimezoneChange}\n options={timezoneOptions}\n disabled={disabled}\n size=\"md\"\n />\n </div>\n )}\n </div>\n </div>\n </PopoverPrimitive.Content>\n </PopoverPrimitive>\n </div>\n );\n};\n\nexport { DateTimePicker };\n"],"names":["timezoneOptions","UTC_TIMEZONES","tz","DateTimePicker","value","onChange","placeholder","disabled","size","variant","invalid","weekStartsOn","onOpenChange","className","withTimezone","displayFormat","minDate","maxDate","open","setOpen","useState","existingTz","extractTimezone","undefined","timezone","setTimezone","getLocalTimezone","handleOpenChange","isOpen","currentDate","parseToDate","displayDate","utcToTimezoneDate","displayValue","formatDateForDisplay","format","timeValue","formatTimeValue","emitChange","date","naiveDateToUtcIso","handleDateSelect","handleTimeChange","time","parsed","parseTimeValue","base","Date","handleTimezoneChange","PopoverPrimitive","DatePickerTrigger","Calendar","TimePicker","SelectPrimitive"],"mappings":";;;;;;;;;;AAsBA,MAAMA,kBAAkBC,cAAc,GAAG,CAACC,CAAAA,KAAO;QAAE,OAAOA,GAAG,KAAK;QAAE,OAAOA,GAAG,KAAK;IAAC;AAEpF,MAAMC,iBAAiB,CAAC,EACpBC,KAAK,EACLC,QAAQ,EACRC,WAAW,EACXC,QAAQ,EACRC,IAAI,EACJC,OAAO,EACPC,OAAO,EACPC,YAAY,EACZC,YAAY,EACZC,SAAS,EACTC,YAAY,EACZC,aAAa,EACbC,OAAO,EACPC,OAAO,EACmB;IAC1B,MAAM,CAACC,MAAMC,QAAQ,GAAGC,SAAS;IAEjC,MAAMC,aAAaP,gBAAgBV,QAAQkB,gBAAgBlB,SAASmB;IACpE,MAAM,CAACC,UAAUC,YAAY,GAAGL,SAASC,cAAcK;IAEvD,MAAMC,mBAAmB,CAACC;QACtBT,QAAQS;QACR,IAAIhB,cACAA,aAAagB;IAErB;IAEA,MAAMC,cAAcC,YAAY1B;IAEhC,MAAM2B,cACFjB,gBAAgBe,cAAcG,kBAAkBH,aAAaL,YAAYK;IAE7E,MAAMI,eAAenB,eACfiB,cACIG,qBACIC,OAAOJ,aAAa,2BAA2BP,UAC/C,cACAT,iBAEJQ,SACJW,qBAAqB9B,OAAO,iBAAiBW;IAEnD,MAAMqB,YAAYL,cAAcM,gBAAgBN,eAAe;IAE/D,MAAMO,aAAa,CAACC,MAAYrC;QAC5B,IAAI,CAACG,UACD;QAEAS,eACAT,SAASmC,kBAAkBD,MAAMrC,MAAMsB,aAEvCnB,SAAS8B,OAAOI,MAAM,2BAA2B;IAEzD;IAEA,MAAME,mBAAmB,CAACF;QACtB,IAAI,CAACA,MACD;QAEJ,IAAIR,aACAQ,KAAK,QAAQ,CAACR,YAAY,QAAQ,IAAIA,YAAY,UAAU;QAEhEO,WAAWC;IACf;IAEA,MAAMG,mBAAmB,CAACC;QACtB,IAAI,CAACA,MACD;QAEJ,MAAMC,SAASC,eAAeF;QAC9B,IAAI,CAACC,QACD;QAEJ,MAAME,OAAOf,cAAc,IAAIgB,KAAKhB,eAAe,IAAIgB;QACvDD,KAAK,QAAQ,CAACF,OAAO,KAAK,EAAEA,OAAO,OAAO,EAAE,GAAG;QAC/CN,WAAWQ;IACf;IAEA,MAAME,uBAAuB,CAAC9C;QAC1BuB,YAAYvB;IAChB;IAEA,OAAO,WAAP,GACI,oBAAC;QAAI,WAAWW;qBACZ,oBAACoC,kBAAgBA;QAAC,MAAM/B;QAAM,cAAcS;qBACxC,oBAACuB,mBAAiBA;QACd,cAAcjB;QACd,aAAa3B,eAAe;QAC5B,UAAUC;QACV,MAAMC;QACN,SAASC;QACT,SAASC;sBAEb,oBAACuC,iBAAiB,OAAO;QAAC,OAAM;qBAC5B,oBAAC;QAAI,WAAU;qBACX,oBAACE,UAAQA;QACL,MAAK;QACL,UAAUpB;QACV,UAAUU;QACV,cAAc9B;QACd,UAAU;eACFK,UAAU;gBAAC;oBAAE,QAAQA;gBAAQ;aAAE,GAAG,EAAE;eACpCC,UAAU;gBAAC;oBAAE,OAAOA;gBAAQ;aAAE,GAAG,EAAE;SAC1C;sBAEL,oBAAC;QAAI,WAAU;qBACX,oBAAC;QAAI,WAAU;qBACX,oBAACmC,YAAUA;QACP,OAAOhB;QACP,UAAUM;QACV,UAAUnC;QACV,MAAK;SAGZO,gBAAgB,WAAhBA,GACG,oBAAC;QAAI,WAAU;qBACX,oBAACuC,iBAAeA;QACZ,OAAO7B;QACP,UAAUwB;QACV,SAAShD;QACT,UAAUO;QACV,MAAK;;AAU7C"}
1
+ {"version":3,"file":"DatePicker/primitives/DateTimePicker.js","sources":["../../../src/DatePicker/primitives/DateTimePicker.tsx"],"sourcesContent":["import React, { useState } from \"react\";\nimport { UTC_TIMEZONES } from \"@webiny/utils\";\nimport { Calendar } from \"~/Calendar/index.js\";\nimport { PopoverPrimitive } from \"~/Popover/index.js\";\nimport { SelectPrimitive } from \"~/Select/index.js\";\nimport type { DateTimeLocalPickerProps, DateTimeTzPickerProps } from \"../utils/types.js\";\nimport {\n extractTimezone,\n formatDateForDisplay,\n formatTimeValue,\n getLocalTimezone,\n parseTimeValue,\n toIsoWithTz\n} from \"../utils/dateHelpers.js\";\nimport { parseToDate, utcToTimezoneDate } from \"../utils/timezoneHelpers.js\";\nimport { DatePickerTrigger } from \"./components/DatePickerTrigger.js\";\nimport { TimePicker } from \"./components/TimePicker.js\";\n\ntype DateTimePickerInternalProps = (DateTimeLocalPickerProps | DateTimeTzPickerProps) & {\n withTimezone: boolean;\n};\n\nconst timezoneOptions = UTC_TIMEZONES.map(tz => ({ value: tz.value, label: tz.label }));\n\nconst DateTimePicker = ({\n value,\n onChange,\n placeholder,\n disabled,\n size,\n variant,\n invalid,\n weekStartsOn,\n onOpenChange,\n className,\n withTimezone,\n displayFormat,\n minDate,\n maxDate\n}: DateTimePickerInternalProps) => {\n const [open, setOpen] = useState(false);\n\n const existingTz = withTimezone && value ? extractTimezone(value) : undefined;\n const [selectedTimezone, setSelectedTimezone] = useState(getLocalTimezone());\n // The value carries its own offset; the selected one applies only until a value exists.\n const timezone = existingTz || selectedTimezone;\n\n const handleOpenChange = (isOpen: boolean) => {\n setOpen(isOpen);\n if (onOpenChange) {\n onOpenChange(isOpen);\n }\n };\n\n const currentDate = parseToDate(value);\n\n const displayDate =\n withTimezone && currentDate ? utcToTimezoneDate(currentDate, timezone) : currentDate;\n\n const displayValue = withTimezone\n ? displayDate\n ? formatDateForDisplay(toIsoWithTz(displayDate, timezone), \"dateTimeTz\", displayFormat)\n : undefined\n : formatDateForDisplay(value, \"dateTimeLocal\", displayFormat);\n\n const timeValue = displayDate ? formatTimeValue(displayDate) : \"\";\n\n const emitChange = (date: Date, tz?: string) => {\n if (!onChange) {\n return;\n }\n if (withTimezone) {\n // Wall time of `date` is the time in the selected timezone: \"2026-05-01T14:30:00+02:00\".\n onChange(toIsoWithTz(date, tz || timezone));\n } else {\n // Absolute instant: \"2026-05-01T12:30:00.000Z\".\n onChange(date.toISOString());\n }\n };\n\n const handleDateSelect = (date: Date | undefined) => {\n if (!date) {\n return;\n }\n if (displayDate) {\n date.setHours(displayDate.getHours(), displayDate.getMinutes());\n }\n emitChange(date);\n };\n\n const handleTimeChange = (time: string | undefined) => {\n if (!time) {\n return;\n }\n const parsed = parseTimeValue(time);\n if (!parsed) {\n return;\n }\n const base = displayDate ? new Date(displayDate) : new Date();\n base.setHours(parsed.hours, parsed.minutes, 0, 0);\n emitChange(base);\n };\n\n const handleTimezoneChange = (tz: string) => {\n setSelectedTimezone(tz);\n // Keep the picked wall time, re-label it with the new offset.\n if (displayDate) {\n emitChange(displayDate, tz);\n }\n };\n\n return (\n <div className={className}>\n <PopoverPrimitive open={open} onOpenChange={handleOpenChange}>\n <DatePickerTrigger\n displayValue={displayValue}\n placeholder={placeholder ?? \"Pick date & time\"}\n disabled={disabled}\n size={size}\n variant={variant}\n invalid={invalid}\n />\n <PopoverPrimitive.Content align=\"start\">\n <div className=\"flex flex-col gap-sm\">\n <Calendar\n mode=\"single\"\n selected={displayDate}\n onSelect={handleDateSelect}\n weekStartsOn={weekStartsOn}\n disabled={[\n ...(minDate ? [{ before: minDate }] : []),\n ...(maxDate ? [{ after: maxDate }] : [])\n ]}\n />\n <div className=\"flex gap-sm px-md pb-md\">\n <div className=\"flex-1\">\n <TimePicker\n value={timeValue}\n onChange={handleTimeChange}\n disabled={disabled}\n size=\"md\"\n />\n </div>\n {withTimezone && (\n <div className=\"flex-1\">\n <SelectPrimitive\n value={timezone}\n onChange={handleTimezoneChange}\n options={timezoneOptions}\n disabled={disabled}\n size=\"md\"\n />\n </div>\n )}\n </div>\n </div>\n </PopoverPrimitive.Content>\n </PopoverPrimitive>\n </div>\n );\n};\n\nexport { DateTimePicker };\n"],"names":["timezoneOptions","UTC_TIMEZONES","tz","DateTimePicker","value","onChange","placeholder","disabled","size","variant","invalid","weekStartsOn","onOpenChange","className","withTimezone","displayFormat","minDate","maxDate","open","setOpen","useState","existingTz","extractTimezone","undefined","selectedTimezone","setSelectedTimezone","getLocalTimezone","timezone","handleOpenChange","isOpen","currentDate","parseToDate","displayDate","utcToTimezoneDate","displayValue","formatDateForDisplay","toIsoWithTz","timeValue","formatTimeValue","emitChange","date","handleDateSelect","handleTimeChange","time","parsed","parseTimeValue","base","Date","handleTimezoneChange","PopoverPrimitive","DatePickerTrigger","Calendar","TimePicker","SelectPrimitive"],"mappings":";;;;;;;;;AAsBA,MAAMA,kBAAkBC,cAAc,GAAG,CAACC,CAAAA,KAAO;QAAE,OAAOA,GAAG,KAAK;QAAE,OAAOA,GAAG,KAAK;IAAC;AAEpF,MAAMC,iBAAiB,CAAC,EACpBC,KAAK,EACLC,QAAQ,EACRC,WAAW,EACXC,QAAQ,EACRC,IAAI,EACJC,OAAO,EACPC,OAAO,EACPC,YAAY,EACZC,YAAY,EACZC,SAAS,EACTC,YAAY,EACZC,aAAa,EACbC,OAAO,EACPC,OAAO,EACmB;IAC1B,MAAM,CAACC,MAAMC,QAAQ,GAAGC,SAAS;IAEjC,MAAMC,aAAaP,gBAAgBV,QAAQkB,gBAAgBlB,SAASmB;IACpE,MAAM,CAACC,kBAAkBC,oBAAoB,GAAGL,SAASM;IAEzD,MAAMC,WAAWN,cAAcG;IAE/B,MAAMI,mBAAmB,CAACC;QACtBV,QAAQU;QACR,IAAIjB,cACAA,aAAaiB;IAErB;IAEA,MAAMC,cAAcC,YAAY3B;IAEhC,MAAM4B,cACFlB,gBAAgBgB,cAAcG,kBAAkBH,aAAaH,YAAYG;IAE7E,MAAMI,eAAepB,eACfkB,cACIG,qBAAqBC,YAAYJ,aAAaL,WAAW,cAAcZ,iBACvEQ,SACJY,qBAAqB/B,OAAO,iBAAiBW;IAEnD,MAAMsB,YAAYL,cAAcM,gBAAgBN,eAAe;IAE/D,MAAMO,aAAa,CAACC,MAAYtC;QAC5B,IAAI,CAACG,UACD;QAEAS,eAEAT,SAAS+B,YAAYI,MAAMtC,MAAMyB,aAGjCtB,SAASmC,KAAK,WAAW;IAEjC;IAEA,MAAMC,mBAAmB,CAACD;QACtB,IAAI,CAACA,MACD;QAEJ,IAAIR,aACAQ,KAAK,QAAQ,CAACR,YAAY,QAAQ,IAAIA,YAAY,UAAU;QAEhEO,WAAWC;IACf;IAEA,MAAME,mBAAmB,CAACC;QACtB,IAAI,CAACA,MACD;QAEJ,MAAMC,SAASC,eAAeF;QAC9B,IAAI,CAACC,QACD;QAEJ,MAAME,OAAOd,cAAc,IAAIe,KAAKf,eAAe,IAAIe;QACvDD,KAAK,QAAQ,CAACF,OAAO,KAAK,EAAEA,OAAO,OAAO,EAAE,GAAG;QAC/CL,WAAWO;IACf;IAEA,MAAME,uBAAuB,CAAC9C;QAC1BuB,oBAAoBvB;QAEpB,IAAI8B,aACAO,WAAWP,aAAa9B;IAEhC;IAEA,OAAO,WAAP,GACI,oBAAC;QAAI,WAAWW;qBACZ,oBAACoC,kBAAgBA;QAAC,MAAM/B;QAAM,cAAcU;qBACxC,oBAACsB,mBAAiBA;QACd,cAAchB;QACd,aAAa5B,eAAe;QAC5B,UAAUC;QACV,MAAMC;QACN,SAASC;QACT,SAASC;sBAEb,oBAACuC,iBAAiB,OAAO;QAAC,OAAM;qBAC5B,oBAAC;QAAI,WAAU;qBACX,oBAACE,UAAQA;QACL,MAAK;QACL,UAAUnB;QACV,UAAUS;QACV,cAAc9B;QACd,UAAU;eACFK,UAAU;gBAAC;oBAAE,QAAQA;gBAAQ;aAAE,GAAG,EAAE;eACpCC,UAAU;gBAAC;oBAAE,OAAOA;gBAAQ;aAAE,GAAG,EAAE;SAC1C;sBAEL,oBAAC;QAAI,WAAU;qBACX,oBAAC;QAAI,WAAU;qBACX,oBAACmC,YAAUA;QACP,OAAOf;QACP,UAAUK;QACV,UAAUnC;QACV,MAAK;SAGZO,gBAAgB,WAAhBA,GACG,oBAAC;QAAI,WAAU;qBACX,oBAACuC,iBAAeA;QACZ,OAAO1B;QACP,UAAUqB;QACV,SAAShD;QACT,UAAUO;QACV,MAAK;;AAU7C"}
@@ -22,4 +22,10 @@ export declare const CompactWithErrors: Story;
22
22
  export declare const CompactDisabled: Story;
23
23
  export declare const CompactWithValidateFunction: Story;
24
24
  export declare const CompactFullExample: Story;
25
+ /**
26
+ * Reproduces the Website Builder style sidebar at its 206px value column: the preview stacks,
27
+ * the file name truncates in the middle so the extension and version suffix survive, and the
28
+ * actions spell themselves out instead of costing a fixed block of the row.
29
+ */
30
+ export declare const CompactWithLongFileNameInNarrowContainer: Story;
25
31
  export declare const Documentation: Story;
@@ -210,6 +210,29 @@ const CompactFullExample = {
210
210
  }
211
211
  }
212
212
  };
213
+ const CompactWithLongFileNameInNarrowContainer = {
214
+ args: {
215
+ ...Compact.args
216
+ },
217
+ render: (args)=>{
218
+ const [selectedFile, setSelectedFile] = useState({
219
+ name: "tide-cc-statuses-2026-08-21-final-v2.png",
220
+ mimeType: "image/png",
221
+ size: 674161,
222
+ url: "https://picsum.photos/1200/800"
223
+ });
224
+ return /*#__PURE__*/ react.createElement("div", {
225
+ style: {
226
+ width: 206
227
+ }
228
+ }, /*#__PURE__*/ react.createElement(FilePicker, {
229
+ ...args,
230
+ value: selectedFile,
231
+ onSelectItem: ()=>setSelectedFile(getFile()),
232
+ onRemoveItem: ()=>setSelectedFile(null)
233
+ }));
234
+ }
235
+ };
213
236
  const Documentation = {
214
237
  render: (args)=>{
215
238
  const [selectedFile, setSelectedFile] = useState(args.value);
@@ -324,6 +347,6 @@ const Documentation = {
324
347
  }
325
348
  };
326
349
  export default FilePicker_stories;
327
- export { AreaDisabled, AreaFullExample, AreaType, AreaWithDescription, AreaWithErrors, AreaWithLabel, AreaWithLabelRequired, AreaWithNotes, AreaWithValidateFunction, Compact, CompactDisabled, CompactFullExample, CompactWithDescription, CompactWithErrors, CompactWithLabel, CompactWithLabelRequired, CompactWithNotes, CompactWithValidateFunction, Default, Documentation };
350
+ export { AreaDisabled, AreaFullExample, AreaType, AreaWithDescription, AreaWithErrors, AreaWithLabel, AreaWithLabelRequired, AreaWithNotes, AreaWithValidateFunction, Compact, CompactDisabled, CompactFullExample, CompactWithDescription, CompactWithErrors, CompactWithLabel, CompactWithLabelRequired, CompactWithLongFileNameInNarrowContainer, CompactWithNotes, CompactWithValidateFunction, Default, Documentation };
328
351
 
329
352
  //# sourceMappingURL=FilePicker.stories.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"FilePicker/FilePicker.stories.js","sources":["../../src/FilePicker/FilePicker.stories.tsx"],"sourcesContent":["import React, { useState, useEffect } from \"react\";\nimport type { Meta, StoryObj } from \"@storybook/react\";\nimport { type FileItemDto, FilePicker } from \"~/FilePicker/index.js\";\n\nconst getRandomNumber = (min: number, max: number): number =>\n Math.floor(Math.random() * (max - min + 1)) + min;\n\nconst getFile = (): FileItemDto => {\n const width = getRandomNumber(500, 2000); // Random width between 500 and 2000\n const height = getRandomNumber(500, 2000); // Random height between 500 and 2000\n const fileSize = getRandomNumber(500000, 5000000); // Random file size between 500KB and 5MB\n\n return {\n name: \"selected-file.jpg\",\n mimeType: \"image/jpeg\",\n size: fileSize,\n url: `https://picsum.photos/${width}/${height}`\n };\n};\n\nconst meta: Meta<typeof FilePicker> = {\n title: \"Components/Form/FilePicker\",\n component: FilePicker,\n argTypes: {\n onSelectItem: { action: \"onSelectItem\" },\n onEditItem: { action: \"onEditItem\" },\n onRemoveItem: { action: \"onRemoveItem\" },\n disabled: {\n control: \"boolean\",\n defaultValue: false\n }\n },\n parameters: {\n layout: \"padded\"\n },\n render: args => {\n const [selectedFile, setSelectedFile] = useState(args.value);\n return (\n <FilePicker\n {...args}\n value={selectedFile}\n onSelectItem={() => setSelectedFile(getFile())}\n onRemoveItem={() => setSelectedFile(null)}\n onEditItem={() => alert(`Editing File`)}\n />\n );\n }\n};\n\nexport default meta;\ntype Story = StoryObj<typeof FilePicker>;\n\nexport const Default: Story = {};\n\nexport const AreaType: Story = {\n args: {\n ...Default.args,\n type: \"area\"\n }\n};\n\nexport const AreaWithLabel: Story = {\n args: {\n ...AreaType.args,\n label: \"Any field label\"\n }\n};\n\nexport const AreaWithLabelRequired: Story = {\n args: {\n ...AreaType.args,\n label: \"Any field label\",\n required: true\n }\n};\n\nexport const AreaWithDescription: Story = {\n args: {\n ...AreaType.args,\n description: \"Provide the required information for processing your request.\"\n }\n};\n\nexport const AreaWithNotes: Story = {\n args: {\n ...AreaType.args,\n note: \"Note: Ensure your selection or input is accurate before proceeding.\"\n }\n};\n\nexport const AreaWithErrors: Story = {\n args: {\n ...AreaType.args,\n validation: {\n isValid: false,\n message: \"This field is required.\"\n }\n }\n};\n\nexport const AreaDisabled: Story = {\n args: {\n ...AreaType.args,\n label: \"Any field label\",\n disabled: true\n }\n};\n\nexport const AreaWithValidateFunction: Story = {\n args: {\n ...AreaType.args\n },\n render: args => {\n const [validation, setValidation] = useState<any>({ isValid: true, message: undefined });\n\n const validate = async () => {\n setValidation({ isValid: false, message: \"Any custom error message.\" });\n };\n\n return <FilePicker {...args} validate={validate} validation={validation} />;\n }\n};\n\nexport const AreaFullExample: Story = {\n args: {\n ...AreaType.args,\n label: \"Any field label\",\n required: true,\n description: \"Provide the required information for processing your request.\",\n note: \"Note: Ensure your selection or input is accurate before proceeding.\",\n validation: {\n isValid: false,\n message: \"This field is required.\"\n }\n }\n};\n\nexport const Compact: Story = {\n args: {\n ...Default.args,\n type: \"compact\"\n }\n};\n\nexport const CompactWithLabel: Story = {\n args: {\n ...Compact.args,\n label: \"Any field label\"\n }\n};\n\nexport const CompactWithLabelRequired: Story = {\n args: {\n ...Compact.args,\n label: \"Any field label\",\n required: true\n }\n};\n\nexport const CompactWithDescription: Story = {\n args: {\n ...Compact.args,\n description: \"Provide the required information for processing your request.\"\n }\n};\n\nexport const CompactWithNotes: Story = {\n args: {\n ...Compact.args,\n note: \"Note: Ensure your selection or input is accurate before proceeding.\"\n }\n};\n\nexport const CompactWithErrors: Story = {\n args: {\n ...Compact.args,\n validation: {\n isValid: false,\n message: \"This field is required.\"\n }\n }\n};\n\nexport const CompactDisabled: Story = {\n args: {\n ...Compact.args,\n label: \"Any field label\",\n disabled: true\n }\n};\n\nexport const CompactWithValidateFunction: Story = {\n args: {\n ...Compact.args\n },\n render: args => {\n const [validation, setValidation] = useState<any>({ isValid: true, message: undefined });\n\n const validate = async () => {\n setValidation({ isValid: false, message: \"Any custom error message.\" });\n };\n\n return <FilePicker {...args} validate={validate} validation={validation} />;\n }\n};\n\nexport const CompactFullExample: Story = {\n args: {\n ...Compact.args,\n label: \"Any field label\",\n required: true,\n description: \"Provide the required information for processing your request.\",\n note: \"Note: Ensure your selection or input is accurate before proceeding.\",\n validation: {\n isValid: false,\n message: \"This field is required.\"\n }\n }\n};\n\nexport const Documentation: Story = {\n render: args => {\n const [selectedFile, setSelectedFile] = useState(args.value);\n const [validation, setValidation] = useState({ isValid: true, message: \"\" });\n\n // Update value when args.value changes\n useEffect(() => {\n setSelectedFile(args.value);\n }, [args.value]);\n\n const handleSelect = () => {\n setSelectedFile(getFile());\n setValidation({ isValid: true, message: \"\" });\n };\n\n const handleEdit = (file: any) => {\n if (file) {\n console.log(\"Editing file:\", file);\n alert(`Editing File: ${file.name}`);\n }\n };\n\n const handleRemove = () => {\n setSelectedFile(null);\n\n if (args.required) {\n setValidation({ isValid: false, message: \"Please select a file\" });\n }\n };\n\n // Validate on required change or value change\n useEffect(() => {\n if (args.required && !selectedFile) {\n setValidation({ isValid: false, message: \"Please select a file\" });\n } else {\n setValidation({ isValid: true, message: \"\" });\n }\n }, [args.required, selectedFile]);\n\n return (\n <FilePicker\n {...args}\n value={selectedFile}\n onSelectItem={handleSelect}\n onRemoveItem={handleRemove}\n onEditItem={handleEdit}\n validation={validation}\n />\n );\n },\n args: {\n label: \"Upload Image\",\n required: true,\n disabled: false,\n description: \"Select a file to upload (JPG, PNG, PDF)\",\n note: \"Note: Maximum file size is 5MB\",\n type: \"area\",\n value: null,\n validation: undefined,\n onSelectItem: undefined,\n onEditItem: undefined,\n onRemoveItem: undefined\n },\n argTypes: {\n label: {\n description: \"Label text for the file picker\",\n control: \"text\"\n },\n required: {\n description: \"Makes the field required when set to true\",\n control: \"boolean\"\n },\n disabled: {\n description: \"Disables the file picker when set to true\",\n control: \"boolean\"\n },\n description: {\n description: \"Additional description text below the field\",\n control: \"text\"\n },\n note: {\n description: \"Additional note text below the field\",\n control: \"text\"\n },\n type: {\n description: \"The visual style of the file picker\",\n control: \"radio\",\n options: [\"area\", \"compact\"]\n },\n value: {\n description: \"The currently selected file\",\n control: \"object\"\n },\n validation: {\n description:\n \"Object containing validation state and message. Please refer to the example code for details on usage.\"\n },\n onSelectItem: {\n description: \"Function called when a file is selected\"\n },\n onEditItem: {\n description: \"Function called when a file is edited\"\n },\n onRemoveItem: {\n description: \"Function called when a file is removed\"\n }\n }\n};\n"],"names":["getRandomNumber","min","max","Math","getFile","width","height","fileSize","meta","FilePicker","args","selectedFile","setSelectedFile","useState","alert","Default","AreaType","AreaWithLabel","AreaWithLabelRequired","AreaWithDescription","AreaWithNotes","AreaWithErrors","AreaDisabled","AreaWithValidateFunction","validation","setValidation","undefined","validate","AreaFullExample","Compact","CompactWithLabel","CompactWithLabelRequired","CompactWithDescription","CompactWithNotes","CompactWithErrors","CompactDisabled","CompactWithValidateFunction","CompactFullExample","Documentation","useEffect","handleSelect","handleEdit","file","console","handleRemove"],"mappings":"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"}
1
+ {"version":3,"file":"FilePicker/FilePicker.stories.js","sources":["../../src/FilePicker/FilePicker.stories.tsx"],"sourcesContent":["import React, { useState, useEffect } from \"react\";\nimport type { Meta, StoryObj } from \"@storybook/react\";\nimport { type FileItemDto, FilePicker } from \"~/FilePicker/index.js\";\n\nconst getRandomNumber = (min: number, max: number): number =>\n Math.floor(Math.random() * (max - min + 1)) + min;\n\nconst getFile = (): FileItemDto => {\n const width = getRandomNumber(500, 2000); // Random width between 500 and 2000\n const height = getRandomNumber(500, 2000); // Random height between 500 and 2000\n const fileSize = getRandomNumber(500000, 5000000); // Random file size between 500KB and 5MB\n\n return {\n name: \"selected-file.jpg\",\n mimeType: \"image/jpeg\",\n size: fileSize,\n url: `https://picsum.photos/${width}/${height}`\n };\n};\n\nconst meta: Meta<typeof FilePicker> = {\n title: \"Components/Form/FilePicker\",\n component: FilePicker,\n argTypes: {\n onSelectItem: { action: \"onSelectItem\" },\n onEditItem: { action: \"onEditItem\" },\n onRemoveItem: { action: \"onRemoveItem\" },\n disabled: {\n control: \"boolean\",\n defaultValue: false\n }\n },\n parameters: {\n layout: \"padded\"\n },\n render: args => {\n const [selectedFile, setSelectedFile] = useState(args.value);\n return (\n <FilePicker\n {...args}\n value={selectedFile}\n onSelectItem={() => setSelectedFile(getFile())}\n onRemoveItem={() => setSelectedFile(null)}\n onEditItem={() => alert(`Editing File`)}\n />\n );\n }\n};\n\nexport default meta;\ntype Story = StoryObj<typeof FilePicker>;\n\nexport const Default: Story = {};\n\nexport const AreaType: Story = {\n args: {\n ...Default.args,\n type: \"area\"\n }\n};\n\nexport const AreaWithLabel: Story = {\n args: {\n ...AreaType.args,\n label: \"Any field label\"\n }\n};\n\nexport const AreaWithLabelRequired: Story = {\n args: {\n ...AreaType.args,\n label: \"Any field label\",\n required: true\n }\n};\n\nexport const AreaWithDescription: Story = {\n args: {\n ...AreaType.args,\n description: \"Provide the required information for processing your request.\"\n }\n};\n\nexport const AreaWithNotes: Story = {\n args: {\n ...AreaType.args,\n note: \"Note: Ensure your selection or input is accurate before proceeding.\"\n }\n};\n\nexport const AreaWithErrors: Story = {\n args: {\n ...AreaType.args,\n validation: {\n isValid: false,\n message: \"This field is required.\"\n }\n }\n};\n\nexport const AreaDisabled: Story = {\n args: {\n ...AreaType.args,\n label: \"Any field label\",\n disabled: true\n }\n};\n\nexport const AreaWithValidateFunction: Story = {\n args: {\n ...AreaType.args\n },\n render: args => {\n const [validation, setValidation] = useState<any>({ isValid: true, message: undefined });\n\n const validate = async () => {\n setValidation({ isValid: false, message: \"Any custom error message.\" });\n };\n\n return <FilePicker {...args} validate={validate} validation={validation} />;\n }\n};\n\nexport const AreaFullExample: Story = {\n args: {\n ...AreaType.args,\n label: \"Any field label\",\n required: true,\n description: \"Provide the required information for processing your request.\",\n note: \"Note: Ensure your selection or input is accurate before proceeding.\",\n validation: {\n isValid: false,\n message: \"This field is required.\"\n }\n }\n};\n\nexport const Compact: Story = {\n args: {\n ...Default.args,\n type: \"compact\"\n }\n};\n\nexport const CompactWithLabel: Story = {\n args: {\n ...Compact.args,\n label: \"Any field label\"\n }\n};\n\nexport const CompactWithLabelRequired: Story = {\n args: {\n ...Compact.args,\n label: \"Any field label\",\n required: true\n }\n};\n\nexport const CompactWithDescription: Story = {\n args: {\n ...Compact.args,\n description: \"Provide the required information for processing your request.\"\n }\n};\n\nexport const CompactWithNotes: Story = {\n args: {\n ...Compact.args,\n note: \"Note: Ensure your selection or input is accurate before proceeding.\"\n }\n};\n\nexport const CompactWithErrors: Story = {\n args: {\n ...Compact.args,\n validation: {\n isValid: false,\n message: \"This field is required.\"\n }\n }\n};\n\nexport const CompactDisabled: Story = {\n args: {\n ...Compact.args,\n label: \"Any field label\",\n disabled: true\n }\n};\n\nexport const CompactWithValidateFunction: Story = {\n args: {\n ...Compact.args\n },\n render: args => {\n const [validation, setValidation] = useState<any>({ isValid: true, message: undefined });\n\n const validate = async () => {\n setValidation({ isValid: false, message: \"Any custom error message.\" });\n };\n\n return <FilePicker {...args} validate={validate} validation={validation} />;\n }\n};\n\nexport const CompactFullExample: Story = {\n args: {\n ...Compact.args,\n label: \"Any field label\",\n required: true,\n description: \"Provide the required information for processing your request.\",\n note: \"Note: Ensure your selection or input is accurate before proceeding.\",\n validation: {\n isValid: false,\n message: \"This field is required.\"\n }\n }\n};\n\n/**\n * Reproduces the Website Builder style sidebar at its 206px value column: the preview stacks,\n * the file name truncates in the middle so the extension and version suffix survive, and the\n * actions spell themselves out instead of costing a fixed block of the row.\n */\nexport const CompactWithLongFileNameInNarrowContainer: Story = {\n args: {\n ...Compact.args\n },\n render: args => {\n const [selectedFile, setSelectedFile] = useState<FileItemDto | null>({\n name: \"tide-cc-statuses-2026-08-21-final-v2.png\",\n mimeType: \"image/png\",\n size: 674161,\n url: \"https://picsum.photos/1200/800\"\n });\n\n return (\n <div style={{ width: 206 }}>\n <FilePicker\n {...args}\n value={selectedFile}\n onSelectItem={() => setSelectedFile(getFile())}\n onRemoveItem={() => setSelectedFile(null)}\n />\n </div>\n );\n }\n};\n\nexport const Documentation: Story = {\n render: args => {\n const [selectedFile, setSelectedFile] = useState(args.value);\n const [validation, setValidation] = useState({ isValid: true, message: \"\" });\n\n // Update value when args.value changes\n useEffect(() => {\n setSelectedFile(args.value);\n }, [args.value]);\n\n const handleSelect = () => {\n setSelectedFile(getFile());\n setValidation({ isValid: true, message: \"\" });\n };\n\n const handleEdit = (file: any) => {\n if (file) {\n console.log(\"Editing file:\", file);\n alert(`Editing File: ${file.name}`);\n }\n };\n\n const handleRemove = () => {\n setSelectedFile(null);\n\n if (args.required) {\n setValidation({ isValid: false, message: \"Please select a file\" });\n }\n };\n\n // Validate on required change or value change\n useEffect(() => {\n if (args.required && !selectedFile) {\n setValidation({ isValid: false, message: \"Please select a file\" });\n } else {\n setValidation({ isValid: true, message: \"\" });\n }\n }, [args.required, selectedFile]);\n\n return (\n <FilePicker\n {...args}\n value={selectedFile}\n onSelectItem={handleSelect}\n onRemoveItem={handleRemove}\n onEditItem={handleEdit}\n validation={validation}\n />\n );\n },\n args: {\n label: \"Upload Image\",\n required: true,\n disabled: false,\n description: \"Select a file to upload (JPG, PNG, PDF)\",\n note: \"Note: Maximum file size is 5MB\",\n type: \"area\",\n value: null,\n validation: undefined,\n onSelectItem: undefined,\n onEditItem: undefined,\n onRemoveItem: undefined\n },\n argTypes: {\n label: {\n description: \"Label text for the file picker\",\n control: \"text\"\n },\n required: {\n description: \"Makes the field required when set to true\",\n control: \"boolean\"\n },\n disabled: {\n description: \"Disables the file picker when set to true\",\n control: \"boolean\"\n },\n description: {\n description: \"Additional description text below the field\",\n control: \"text\"\n },\n note: {\n description: \"Additional note text below the field\",\n control: \"text\"\n },\n type: {\n description: \"The visual style of the file picker\",\n control: \"radio\",\n options: [\"area\", \"compact\"]\n },\n value: {\n description: \"The currently selected file\",\n control: \"object\"\n },\n validation: {\n description:\n \"Object containing validation state and message. Please refer to the example code for details on usage.\"\n },\n onSelectItem: {\n description: \"Function called when a file is selected\"\n },\n onEditItem: {\n description: \"Function called when a file is edited\"\n },\n onRemoveItem: {\n description: \"Function called when a file is removed\"\n }\n }\n};\n"],"names":["getRandomNumber","min","max","Math","getFile","width","height","fileSize","meta","FilePicker","args","selectedFile","setSelectedFile","useState","alert","Default","AreaType","AreaWithLabel","AreaWithLabelRequired","AreaWithDescription","AreaWithNotes","AreaWithErrors","AreaDisabled","AreaWithValidateFunction","validation","setValidation","undefined","validate","AreaFullExample","Compact","CompactWithLabel","CompactWithLabelRequired","CompactWithDescription","CompactWithNotes","CompactWithErrors","CompactDisabled","CompactWithValidateFunction","CompactFullExample","CompactWithLongFileNameInNarrowContainer","Documentation","useEffect","handleSelect","handleEdit","file","console","handleRemove"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"FilePicker/primitives/components/previews/ItemActions.js","sources":["../../../../../src/FilePicker/primitives/components/previews/ItemActions.tsx"],"sourcesContent":["import React from \"react\";\nimport { ReactComponent as ReplaceIcon } from \"@webiny/icons/file_upload.svg\";\nimport { ReactComponent as EditIcon } from \"@webiny/icons/edit.svg\";\nimport { ReactComponent as TrashIcon } from \"@webiny/icons/delete.svg\";\nimport { IconButton } from \"~/Button/index.js\";\nimport { Icon } from \"~/Icon/index.js\";\nimport { cn } from \"~/utils.js\";\n\ninterface ItemActionsProps extends React.HTMLAttributes<HTMLDivElement> {\n onRemoveItem?: () => void;\n onEditItem?: () => void;\n onReplaceItem?: () => void;\n disabled?: boolean;\n small?: boolean;\n}\n\nconst ItemActions = ({\n disabled,\n onRemoveItem,\n onEditItem,\n onReplaceItem,\n small,\n className,\n ...props\n}: ItemActionsProps) => {\n const iconSize = small ? \"default\" : \"lg\";\n const buttonSize = small ? \"xs\" : \"sm\";\n\n return (\n <div {...props} className={cn(\"flex justify-center items-center gap-xs\", className)}>\n {onReplaceItem && (\n <IconButton\n icon={\n <Icon\n icon={<ReplaceIcon />}\n label={\"Replace\"}\n size={\"md\"}\n color={\"neutral-light\"}\n />\n }\n variant={\"ghost\"}\n size={buttonSize}\n iconSize={iconSize}\n onClick={onReplaceItem}\n disabled={disabled}\n />\n )}\n\n {onEditItem && (\n <IconButton\n icon={\n <Icon\n icon={<EditIcon />}\n label={\"Edit\"}\n size={\"md\"}\n color={\"neutral-light\"}\n />\n }\n variant={\"ghost\"}\n size={buttonSize}\n iconSize={iconSize}\n onClick={onEditItem}\n disabled={disabled}\n />\n )}\n\n {onRemoveItem && (\n <IconButton\n icon={\n <Icon\n icon={<TrashIcon />}\n label={\"Remove\"}\n size={\"md\"}\n color={\"neutral-light\"}\n />\n }\n variant={\"ghost\"}\n size={buttonSize}\n iconSize={iconSize}\n onClick={onRemoveItem}\n disabled={disabled}\n />\n )}\n </div>\n );\n};\n\nexport { ItemActions, type ItemActionsProps };\n"],"names":["ItemActions","disabled","onRemoveItem","onEditItem","onReplaceItem","small","className","props","iconSize","buttonSize","cn","IconButton","Icon","ReplaceIcon","EditIcon","TrashIcon"],"mappings":";;;;;;;AAgBA,MAAMA,cAAc,CAAC,EACjBC,QAAQ,EACRC,YAAY,EACZC,UAAU,EACVC,aAAa,EACbC,KAAK,EACLC,SAAS,EACT,GAAGC,OACY;IACf,MAAMC,WAAWH,QAAQ,YAAY;IACrC,MAAMI,aAAaJ,QAAQ,OAAO;IAElC,OAAO,WAAP,GACI,oBAAC;QAAK,GAAGE,KAAK;QAAE,WAAWG,GAAG,2CAA2CJ;OACpEF,iBAAiB,WAAjBA,GACG,oBAACO,YAAUA;QACP,oBACI,oBAACC,MAAIA;YACD,oBAAM,oBAACC,gBAAWA;YAClB,OAAO;YACP,MAAM;YACN,OAAO;;QAGf,SAAS;QACT,MAAMJ;QACN,UAAUD;QACV,SAASJ;QACT,UAAUH;QAIjBE,cAAc,WAAdA,GACG,oBAACQ,YAAUA;QACP,oBACI,oBAACC,MAAIA;YACD,oBAAM,oBAACE,yBAAQA;YACf,OAAO;YACP,MAAM;YACN,OAAO;;QAGf,SAAS;QACT,MAAML;QACN,UAAUD;QACV,SAASL;QACT,UAAUF;QAIjBC,gBAAgB,WAAhBA,GACG,oBAACS,YAAUA;QACP,oBACI,oBAACC,MAAIA;YACD,oBAAM,oBAACG,2BAASA;YAChB,OAAO;YACP,MAAM;YACN,OAAO;;QAGf,SAAS;QACT,MAAMN;QACN,UAAUD;QACV,SAASN;QACT,UAAUD;;AAK9B"}
1
+ {"version":3,"file":"FilePicker/primitives/components/previews/ItemActions.js","sources":["../../../../../src/FilePicker/primitives/components/previews/ItemActions.tsx"],"sourcesContent":["import React from \"react\";\nimport { ReactComponent as ReplaceIcon } from \"@webiny/icons/file_upload.svg\";\nimport { ReactComponent as EditIcon } from \"@webiny/icons/edit.svg\";\nimport { ReactComponent as TrashIcon } from \"@webiny/icons/delete.svg\";\nimport { IconButton } from \"~/Button/index.js\";\nimport { Icon } from \"~/Icon/index.js\";\nimport { cn } from \"~/utils.js\";\n\ninterface ItemActionsProps extends React.HTMLAttributes<HTMLDivElement> {\n onRemoveItem?: () => void;\n onEditItem?: () => void;\n onReplaceItem?: () => void;\n disabled?: boolean;\n small?: boolean;\n}\n\nconst ItemActions = ({\n disabled,\n onRemoveItem,\n onEditItem,\n onReplaceItem,\n small,\n className,\n ...props\n}: ItemActionsProps) => {\n const iconSize = small ? \"default\" : \"lg\";\n const buttonSize = small ? \"xs\" : \"sm\";\n\n return (\n <div {...props} className={cn(\"flex justify-center items-center gap-xs\", className)}>\n {/* Replace is the action a populated picker mainly exists for, and it was only ever\n shown in the `small` layout - elsewhere it hid behind clicking the thumbnail. */}\n {onReplaceItem && (\n <IconButton\n icon={\n <Icon\n icon={<ReplaceIcon />}\n label={\"Replace\"}\n size={\"md\"}\n color={\"neutral-light\"}\n />\n }\n variant={\"ghost\"}\n size={buttonSize}\n iconSize={iconSize}\n onClick={onReplaceItem}\n disabled={disabled}\n />\n )}\n\n {onEditItem && (\n <IconButton\n icon={\n <Icon\n icon={<EditIcon />}\n label={\"Edit\"}\n size={\"md\"}\n color={\"neutral-light\"}\n />\n }\n variant={\"ghost\"}\n size={buttonSize}\n iconSize={iconSize}\n onClick={onEditItem}\n disabled={disabled}\n />\n )}\n\n {onRemoveItem && (\n <IconButton\n icon={\n <Icon\n icon={<TrashIcon />}\n label={\"Remove\"}\n size={\"md\"}\n color={\"neutral-light\"}\n />\n }\n variant={\"ghost\"}\n size={buttonSize}\n iconSize={iconSize}\n onClick={onRemoveItem}\n disabled={disabled}\n />\n )}\n </div>\n );\n};\n\nexport { ItemActions, type ItemActionsProps };\n"],"names":["ItemActions","disabled","onRemoveItem","onEditItem","onReplaceItem","small","className","props","iconSize","buttonSize","cn","IconButton","Icon","ReplaceIcon","EditIcon","TrashIcon"],"mappings":";;;;;;;AAgBA,MAAMA,cAAc,CAAC,EACjBC,QAAQ,EACRC,YAAY,EACZC,UAAU,EACVC,aAAa,EACbC,KAAK,EACLC,SAAS,EACT,GAAGC,OACY;IACf,MAAMC,WAAWH,QAAQ,YAAY;IACrC,MAAMI,aAAaJ,QAAQ,OAAO;IAElC,OAAO,WAAP,GACI,oBAAC;QAAK,GAAGE,KAAK;QAAE,WAAWG,GAAG,2CAA2CJ;OAGpEF,iBAAiB,WAAjBA,GACG,oBAACO,YAAUA;QACP,oBACI,oBAACC,MAAIA;YACD,oBAAM,oBAACC,gBAAWA;YAClB,OAAO;YACP,MAAM;YACN,OAAO;;QAGf,SAAS;QACT,MAAMJ;QACN,UAAUD;QACV,SAASJ;QACT,UAAUH;QAIjBE,cAAc,WAAdA,GACG,oBAACQ,YAAUA;QACP,oBACI,oBAACC,MAAIA;YACD,oBAAM,oBAACE,yBAAQA;YACf,OAAO;YACP,MAAM;YACN,OAAO;;QAGf,SAAS;QACT,MAAML;QACN,UAAUD;QACV,SAASL;QACT,UAAUF;QAIjBC,gBAAgB,WAAhBA,GACG,oBAACS,YAAUA;QACP,oBACI,oBAACC,MAAIA;YACD,oBAAM,oBAACG,2BAASA;YAChB,OAAO;YACP,MAAM;YACN,OAAO;;QAGf,SAAS;QACT,MAAMN;QACN,UAAUD;QACV,SAASN;QACT,UAAUD;;AAK9B"}
@@ -7,7 +7,7 @@ const ItemDescription = ({ className, disabled, item, small, ...props })=>{
7
7
  unitSeparator: " "
8
8
  });
9
9
  return /*#__PURE__*/ react.createElement("div", {
10
- className: cn("flex flex-col gap-xxs overflow-hidden flex-1 min-w-0", className),
10
+ className: cn("flex flex-col gap-xxs overflow-hidden min-w-0", className),
11
11
  ...props
12
12
  }, /*#__PURE__*/ react.createElement(Text, {
13
13
  size: "sm",
@@ -1 +1 @@
1
- {"version":3,"file":"FilePicker/primitives/components/previews/ItemDescription.js","sources":["../../../../../src/FilePicker/primitives/components/previews/ItemDescription.tsx"],"sourcesContent":["import React from \"react\";\nimport bytes from \"bytes\";\nimport { Text } from \"~/Text/index.js\";\nimport { cn } from \"~/utils.js\";\nimport type { FileItemFormatted } from \"~/FilePicker/index.js\";\n\ninterface ItemDescriptionProps extends Omit<React.HTMLAttributes<HTMLDivElement>, \"children\"> {\n item: FileItemFormatted;\n disabled?: boolean;\n small?: boolean;\n}\n\nconst ItemDescription = ({ className, disabled, item, small, ...props }: ItemDescriptionProps) => {\n const formattedSize = item.size && bytes.format(item.size, { unitSeparator: \" \" });\n\n return (\n <div\n className={cn(\"flex flex-col gap-xxs overflow-hidden flex-1 min-w-0\", className)}\n {...props}\n >\n <Text\n size=\"sm\"\n as=\"div\"\n className={cn(\n \"truncate overflow-hidden whitespace-nowrap w-full\",\n disabled ? \"text-neutral-disabled\" : \"text-neutral-primary\"\n )}\n >\n {item.name}\n </Text>\n {!small && (formattedSize || item.mimeType) && (\n <Text\n size=\"sm\"\n className={cn(\n \"truncate overflow-hidden whitespace-nowrap w-full\",\n disabled ? \"text-neutral-disabled\" : \"text-neutral-muted\"\n )}\n >\n {[formattedSize, item.mimeType].filter(Boolean).join(\" - \")}\n </Text>\n )}\n </div>\n );\n};\n\nexport { ItemDescription, type ItemDescriptionProps };\n"],"names":["ItemDescription","className","disabled","item","small","props","formattedSize","bytes","cn","Text","Boolean"],"mappings":";;;;AAYA,MAAMA,kBAAkB,CAAC,EAAEC,SAAS,EAAEC,QAAQ,EAAEC,IAAI,EAAEC,KAAK,EAAE,GAAGC,OAA6B;IACzF,MAAMC,gBAAgBH,KAAK,IAAI,IAAII,MAAM,MAAM,CAACJ,KAAK,IAAI,EAAE;QAAE,eAAe;IAAI;IAEhF,OAAO,WAAP,GACI,oBAAC;QACG,WAAWK,GAAG,wDAAwDP;QACrE,GAAGI,KAAK;qBAET,oBAACI,MAAIA;QACD,MAAK;QACL,IAAG;QACH,WAAWD,GACP,qDACAN,WAAW,0BAA0B;OAGxCC,KAAK,IAAI,GAEb,CAACC,SAAUE,CAAAA,iBAAiBH,KAAK,QAAO,mBACrC,oBAACM,MAAIA;QACD,MAAK;QACL,WAAWD,GACP,qDACAN,WAAW,0BAA0B;OAGxC;QAACI;QAAeH,KAAK,QAAQ;KAAC,CAAC,MAAM,CAACO,SAAS,IAAI,CAAC;AAKzE"}
1
+ {"version":3,"file":"FilePicker/primitives/components/previews/ItemDescription.js","sources":["../../../../../src/FilePicker/primitives/components/previews/ItemDescription.tsx"],"sourcesContent":["import React from \"react\";\nimport bytes from \"bytes\";\nimport { Text } from \"~/Text/index.js\";\nimport { cn } from \"~/utils.js\";\nimport type { FileItemFormatted } from \"~/FilePicker/index.js\";\n\ninterface ItemDescriptionProps extends Omit<React.HTMLAttributes<HTMLDivElement>, \"children\"> {\n item: FileItemFormatted;\n disabled?: boolean;\n small?: boolean;\n}\n\nconst ItemDescription = ({ className, disabled, item, small, ...props }: ItemDescriptionProps) => {\n const formattedSize = item.size && bytes.format(item.size, { unitSeparator: \" \" });\n\n return (\n <div className={cn(\"flex flex-col gap-xxs overflow-hidden min-w-0\", className)} {...props}>\n <Text\n size=\"sm\"\n as=\"div\"\n className={cn(\n \"truncate overflow-hidden whitespace-nowrap w-full\",\n disabled ? \"text-neutral-disabled\" : \"text-neutral-primary\"\n )}\n >\n {item.name}\n </Text>\n {!small && (formattedSize || item.mimeType) && (\n <Text\n size=\"sm\"\n className={cn(\n \"truncate overflow-hidden whitespace-nowrap w-full\",\n disabled ? \"text-neutral-disabled\" : \"text-neutral-muted\"\n )}\n >\n {[formattedSize, item.mimeType].filter(Boolean).join(\" - \")}\n </Text>\n )}\n </div>\n );\n};\n\nexport { ItemDescription, type ItemDescriptionProps };\n"],"names":["ItemDescription","className","disabled","item","small","props","formattedSize","bytes","cn","Text","Boolean"],"mappings":";;;;AAYA,MAAMA,kBAAkB,CAAC,EAAEC,SAAS,EAAEC,QAAQ,EAAEC,IAAI,EAAEC,KAAK,EAAE,GAAGC,OAA6B;IACzF,MAAMC,gBAAgBH,KAAK,IAAI,IAAII,MAAM,MAAM,CAACJ,KAAK,IAAI,EAAE;QAAE,eAAe;IAAI;IAEhF,OAAO,WAAP,GACI,oBAAC;QAAI,WAAWK,GAAG,iDAAiDP;QAAa,GAAGI,KAAK;qBACrF,oBAACI,MAAIA;QACD,MAAK;QACL,IAAG;QACH,WAAWD,GACP,qDACAN,WAAW,0BAA0B;OAGxCC,KAAK,IAAI,GAEb,CAACC,SAAUE,CAAAA,iBAAiBH,KAAK,QAAO,mBACrC,oBAACM,MAAIA;QACD,MAAK;QACL,WAAWD,GACP,qDACAN,WAAW,0BAA0B;OAGxC;QAACI;QAAeH,KAAK,QAAQ;KAAC,CAAC,MAAM,CAACO,SAAS,IAAI,CAAC;AAKzE"}
@@ -1,5 +1,9 @@
1
1
  import React from "react";
2
2
  import type { FileItemFormatted } from "../../../../../FilePicker/index.js";
3
3
  type FileTypeProps = Pick<FileItemFormatted, "mimeType" | "name">;
4
+ /**
5
+ * The stand-in for a file that cannot be shown as a picture: an icon of its format, falling back
6
+ * to a generic one for anything unrecognised.
7
+ */
4
8
  declare const FileType: ({ mimeType, name }: FileTypeProps) => React.JSX.Element;
5
9
  export { FileType, type FileTypeProps };