@worknice/whiteboard 0.69.0 → 0.70.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -15,6 +15,7 @@ type Option = {
15
15
  } | {
16
16
  href: string;
17
17
  external?: boolean;
18
+ download?: string | boolean;
18
19
  type: "link";
19
20
  });
20
21
  type Props = {
@@ -153,7 +153,13 @@ const MenuButton = ({ autoFocus = false, ariaLabel, disabled = false, id, size =
153
153
  optionsRef.current[index] = node;
154
154
  }
155
155
  }),
156
- children: option.external ? /*#__PURE__*/ (0, __WEBPACK_EXTERNAL_MODULE_react_jsx_runtime_225474f2__.jsx)("a", {
156
+ children: void 0 !== option.download ? /*#__PURE__*/ (0, __WEBPACK_EXTERNAL_MODULE_react_jsx_runtime_225474f2__.jsx)("a", {
157
+ href: option.href,
158
+ download: option.download,
159
+ "aria-disabled": option.disabled,
160
+ className: __WEBPACK_EXTERNAL_MODULE__MenuButton_module_js_872b1a55__["default"].listItemLink,
161
+ children: optionContent
162
+ }) : option.external ? /*#__PURE__*/ (0, __WEBPACK_EXTERNAL_MODULE_react_jsx_runtime_225474f2__.jsx)("a", {
157
163
  href: option.href,
158
164
  "aria-disabled": option.disabled,
159
165
  target: "_blank",
@@ -0,0 +1,5 @@
1
+ declare const _default: {
2
+ ({ size, tone, animate }: import("../types").IconProps): import("react/jsx-runtime").JSX.Element;
3
+ displayName: string;
4
+ };
5
+ export default _default;
@@ -0,0 +1,14 @@
1
+ import * as __WEBPACK_EXTERNAL_MODULE_react_jsx_runtime_225474f2__ from "react/jsx-runtime";
2
+ import * as __WEBPACK_EXTERNAL_MODULE__createIcon_js_4dc54f83__ from "../createIcon.js";
3
+ const FileImportSvg = (props)=>/*#__PURE__*/ (0, __WEBPACK_EXTERNAL_MODULE_react_jsx_runtime_225474f2__.jsx)("svg", {
4
+ xmlns: "http://www.w3.org/2000/svg",
5
+ viewBox: "0 0 640 640",
6
+ "aria-hidden": "true",
7
+ fill: "currentColor",
8
+ ...props,
9
+ children: /*#__PURE__*/ (0, __WEBPACK_EXTERNAL_MODULE_react_jsx_runtime_225474f2__.jsx)("path", {
10
+ d: "M192 112L304 112L304 200C304 239.8 336.2 272 376 272L464 272L464 512C464 520.8 456.8 528 448 528L192 528C183.2 528 176 520.8 176 512L176 464L128 464L128 512C128 547.3 156.7 576 192 576L448 576C483.3 576 512 547.3 512 512L512 250.5C512 233.5 505.3 217.2 493.3 205.2L370.7 82.7C358.7 70.7 342.5 64 325.5 64L192 64C156.7 64 128 92.7 128 128L128 320L176 320L176 128C176 119.2 183.2 112 192 112zM352 131.9L444.1 224L376 224C362.7 224 352 213.3 352 200L352 131.9zM64 392C64 405.3 74.7 416 88 416L310.1 416L279.1 447C269.7 456.4 269.7 471.6 279.1 480.9C288.5 490.2 303.7 490.3 313 480.9L385 408.9C394.4 399.5 394.4 384.3 385 375L313 303C303.6 293.6 288.4 293.6 279.1 303C269.8 312.4 269.7 327.6 279.1 336.9L310.1 367.9L88 367.9C74.7 367.9 64 378.6 64 391.9z"
11
+ })
12
+ });
13
+ const FileImport_rslib_entry_ = (0, __WEBPACK_EXTERNAL_MODULE__createIcon_js_4dc54f83__.createIcon)(FileImportSvg);
14
+ export { FileImport_rslib_entry_ as default };
@@ -45,6 +45,7 @@ export { default as Events } from "./Events";
45
45
  export { default as External } from "./External";
46
46
  export { default as FileCirclePlus } from "./FileCirclePlus";
47
47
  export { default as FileExport } from "./FileExport";
48
+ export { default as FileImport } from "./FileImport";
48
49
  export { default as Filter } from "./Filter";
49
50
  export { default as FilterList } from "./FilterList";
50
51
  export { default as FitView } from "./FitView";
@@ -45,6 +45,7 @@ import * as __WEBPACK_EXTERNAL_MODULE__Events_js_f62d9e1f__ from "./Events.js";
45
45
  import * as __WEBPACK_EXTERNAL_MODULE__External_js_f57b3137__ from "./External.js";
46
46
  import * as __WEBPACK_EXTERNAL_MODULE__FileCirclePlus_js_8a998d41__ from "./FileCirclePlus.js";
47
47
  import * as __WEBPACK_EXTERNAL_MODULE__FileExport_js_b58980f9__ from "./FileExport.js";
48
+ import * as __WEBPACK_EXTERNAL_MODULE__FileImport_js_364e619c__ from "./FileImport.js";
48
49
  import * as __WEBPACK_EXTERNAL_MODULE__Filter_js_962e7a68__ from "./Filter.js";
49
50
  import * as __WEBPACK_EXTERNAL_MODULE__FilterList_js_14d71870__ from "./FilterList.js";
50
51
  import * as __WEBPACK_EXTERNAL_MODULE__FitView_js_91c9e961__ from "./FitView.js";
@@ -158,6 +159,7 @@ var __webpack_exports__Events = __WEBPACK_EXTERNAL_MODULE__Events_js_f62d9e1f__[
158
159
  var __webpack_exports__External = __WEBPACK_EXTERNAL_MODULE__External_js_f57b3137__["default"];
159
160
  var __webpack_exports__FileCirclePlus = __WEBPACK_EXTERNAL_MODULE__FileCirclePlus_js_8a998d41__["default"];
160
161
  var __webpack_exports__FileExport = __WEBPACK_EXTERNAL_MODULE__FileExport_js_b58980f9__["default"];
162
+ var __webpack_exports__FileImport = __WEBPACK_EXTERNAL_MODULE__FileImport_js_364e619c__["default"];
161
163
  var __webpack_exports__Filter = __WEBPACK_EXTERNAL_MODULE__Filter_js_962e7a68__["default"];
162
164
  var __webpack_exports__FilterList = __WEBPACK_EXTERNAL_MODULE__FilterList_js_14d71870__["default"];
163
165
  var __webpack_exports__FitView = __WEBPACK_EXTERNAL_MODULE__FitView_js_91c9e961__["default"];
@@ -224,4 +226,4 @@ var __webpack_exports__UserPlus = __WEBPACK_EXTERNAL_MODULE__UserPlus_js_796202e
224
226
  var __webpack_exports__Visible = __WEBPACK_EXTERNAL_MODULE__Visible_js_aa1c6acc__["default"];
225
227
  var __webpack_exports__Warning = __WEBPACK_EXTERNAL_MODULE__Warning_js_d0de15e9__["default"];
226
228
  var __webpack_exports__Workflows = __WEBPACK_EXTERNAL_MODULE__Workflows_js_35639a49__["default"];
227
- export { __webpack_exports__Approval as Approval, __webpack_exports__Apps as Apps, __webpack_exports__Archive as Archive, __webpack_exports__ArrowLeft as ArrowLeft, __webpack_exports__ArrowRight as ArrowRight, __webpack_exports__ArrowTurnLeftUp as ArrowTurnLeftUp, __webpack_exports__ArrowsCompress as ArrowsCompress, __webpack_exports__ArrowsExpand as ArrowsExpand, __webpack_exports__ArrowsUpDown as ArrowsUpDown, __webpack_exports__Assign as Assign, __webpack_exports__AssignmentCertificate as AssignmentCertificate, __webpack_exports__AssignmentDocument as AssignmentDocument, __webpack_exports__AssignmentForm as AssignmentForm, __webpack_exports__AssignmentQuestionnaire as AssignmentQuestionnaire, __webpack_exports__BankAccount as BankAccount, __webpack_exports__Bolt as Bolt, __webpack_exports__BookOpenLines as BookOpenLines, __webpack_exports__Bug as Bug, __webpack_exports__Calendar as Calendar, __webpack_exports__CalendarPlus as CalendarPlus, __webpack_exports__Cancel as Cancel, __webpack_exports__CaratDown as CaratDown, __webpack_exports__CaratLeft as CaratLeft, __webpack_exports__CaratRight as CaratRight, __webpack_exports__CaratUp as CaratUp, __webpack_exports__CheckMark as CheckMark, __webpack_exports__ChevronDown as ChevronDown, __webpack_exports__ChevronLeft as ChevronLeft, __webpack_exports__ChevronRight as ChevronRight, __webpack_exports__ChevronUp as ChevronUp, __webpack_exports__Clock as Clock, __webpack_exports__Close as Close, __webpack_exports__Columns as Columns, __webpack_exports__Comment as Comment, __webpack_exports__Copy as Copy, __webpack_exports__Dash as Dash, __webpack_exports__Delete as Delete, __webpack_exports__Directory as Directory, __webpack_exports__DocumentProcessingFailed as DocumentProcessingFailed, __webpack_exports__Download as Download, __webpack_exports__Edit as Edit, __webpack_exports__Email as Email, __webpack_exports__EmergencyContact as EmergencyContact, __webpack_exports__Events as Events, __webpack_exports__External as External, __webpack_exports__FileCirclePlus as FileCirclePlus, __webpack_exports__FileExport as FileExport, __webpack_exports__Filter as Filter, __webpack_exports__FilterList as FilterList, __webpack_exports__FitView as FitView, __webpack_exports__Globe as Globe, __webpack_exports__GripLines as GripLines, __webpack_exports__Help as Help, __webpack_exports__Hidden as Hidden, __webpack_exports__History as History, __webpack_exports__Inbox as Inbox, __webpack_exports__Info as Info, __webpack_exports__Insights as Insights, __webpack_exports__Job as Job, __webpack_exports__Leave as Leave, __webpack_exports__Lightbulb as Lightbulb, __webpack_exports__Loading as Loading, __webpack_exports__LocationCheck as LocationCheck, __webpack_exports__Logout as Logout, __webpack_exports__Messages as Messages, __webpack_exports__Microsoft as Microsoft, __webpack_exports__Minus as Minus, __webpack_exports__Newspaper as Newspaper, __webpack_exports__Overflow as Overflow, __webpack_exports__Paperwork as Paperwork, __webpack_exports__PaperworkAssigned as PaperworkAssigned, __webpack_exports__PaperworkDraft as PaperworkDraft, __webpack_exports__PaperworkExpired as PaperworkExpired, __webpack_exports__PaperworkExpiringSoon as PaperworkExpiringSoon, __webpack_exports__PaperworkMissing as PaperworkMissing, __webpack_exports__PaperworkProcessed as PaperworkProcessed, __webpack_exports__PaperworkSubmitted as PaperworkSubmitted, __webpack_exports__People as People, __webpack_exports__Phone as Phone, __webpack_exports__Plus as Plus, __webpack_exports__Positions as Positions, __webpack_exports__Profile as Profile, __webpack_exports__ProfileFemale as ProfileFemale, __webpack_exports__ProfileMale as ProfileMale, __webpack_exports__QuestionMark as QuestionMark, __webpack_exports__Remuneration as Remuneration, __webpack_exports__Reschedule as Reschedule, __webpack_exports__Restore as Restore, __webpack_exports__Review as Review, __webpack_exports__Schedule as Schedule, __webpack_exports__Search as Search, __webpack_exports__Settings as Settings, __webpack_exports__Shield as Shield, __webpack_exports__Sidebar as Sidebar, __webpack_exports__Sliders as Sliders, __webpack_exports__SortAsc as SortAsc, __webpack_exports__SortDefault as SortDefault, __webpack_exports__SortDes as SortDes, __webpack_exports__StepsComplete as StepsComplete, __webpack_exports__StepsCurrent as StepsCurrent, __webpack_exports__StepsIncomplete as StepsIncomplete, __webpack_exports__Submit as Submit, __webpack_exports__Success as Success, __webpack_exports__SuperFund as SuperFund, __webpack_exports__Sync as Sync, __webpack_exports__Table as Table, __webpack_exports__Task as Task, __webpack_exports__Tax as Tax, __webpack_exports__Tenure as Tenure, __webpack_exports__UserPlus as UserPlus, __webpack_exports__Visible as Visible, __webpack_exports__Warning as Warning, __webpack_exports__Workflows as Workflows };
229
+ export { __webpack_exports__Approval as Approval, __webpack_exports__Apps as Apps, __webpack_exports__Archive as Archive, __webpack_exports__ArrowLeft as ArrowLeft, __webpack_exports__ArrowRight as ArrowRight, __webpack_exports__ArrowTurnLeftUp as ArrowTurnLeftUp, __webpack_exports__ArrowsCompress as ArrowsCompress, __webpack_exports__ArrowsExpand as ArrowsExpand, __webpack_exports__ArrowsUpDown as ArrowsUpDown, __webpack_exports__Assign as Assign, __webpack_exports__AssignmentCertificate as AssignmentCertificate, __webpack_exports__AssignmentDocument as AssignmentDocument, __webpack_exports__AssignmentForm as AssignmentForm, __webpack_exports__AssignmentQuestionnaire as AssignmentQuestionnaire, __webpack_exports__BankAccount as BankAccount, __webpack_exports__Bolt as Bolt, __webpack_exports__BookOpenLines as BookOpenLines, __webpack_exports__Bug as Bug, __webpack_exports__Calendar as Calendar, __webpack_exports__CalendarPlus as CalendarPlus, __webpack_exports__Cancel as Cancel, __webpack_exports__CaratDown as CaratDown, __webpack_exports__CaratLeft as CaratLeft, __webpack_exports__CaratRight as CaratRight, __webpack_exports__CaratUp as CaratUp, __webpack_exports__CheckMark as CheckMark, __webpack_exports__ChevronDown as ChevronDown, __webpack_exports__ChevronLeft as ChevronLeft, __webpack_exports__ChevronRight as ChevronRight, __webpack_exports__ChevronUp as ChevronUp, __webpack_exports__Clock as Clock, __webpack_exports__Close as Close, __webpack_exports__Columns as Columns, __webpack_exports__Comment as Comment, __webpack_exports__Copy as Copy, __webpack_exports__Dash as Dash, __webpack_exports__Delete as Delete, __webpack_exports__Directory as Directory, __webpack_exports__DocumentProcessingFailed as DocumentProcessingFailed, __webpack_exports__Download as Download, __webpack_exports__Edit as Edit, __webpack_exports__Email as Email, __webpack_exports__EmergencyContact as EmergencyContact, __webpack_exports__Events as Events, __webpack_exports__External as External, __webpack_exports__FileCirclePlus as FileCirclePlus, __webpack_exports__FileExport as FileExport, __webpack_exports__FileImport as FileImport, __webpack_exports__Filter as Filter, __webpack_exports__FilterList as FilterList, __webpack_exports__FitView as FitView, __webpack_exports__Globe as Globe, __webpack_exports__GripLines as GripLines, __webpack_exports__Help as Help, __webpack_exports__Hidden as Hidden, __webpack_exports__History as History, __webpack_exports__Inbox as Inbox, __webpack_exports__Info as Info, __webpack_exports__Insights as Insights, __webpack_exports__Job as Job, __webpack_exports__Leave as Leave, __webpack_exports__Lightbulb as Lightbulb, __webpack_exports__Loading as Loading, __webpack_exports__LocationCheck as LocationCheck, __webpack_exports__Logout as Logout, __webpack_exports__Messages as Messages, __webpack_exports__Microsoft as Microsoft, __webpack_exports__Minus as Minus, __webpack_exports__Newspaper as Newspaper, __webpack_exports__Overflow as Overflow, __webpack_exports__Paperwork as Paperwork, __webpack_exports__PaperworkAssigned as PaperworkAssigned, __webpack_exports__PaperworkDraft as PaperworkDraft, __webpack_exports__PaperworkExpired as PaperworkExpired, __webpack_exports__PaperworkExpiringSoon as PaperworkExpiringSoon, __webpack_exports__PaperworkMissing as PaperworkMissing, __webpack_exports__PaperworkProcessed as PaperworkProcessed, __webpack_exports__PaperworkSubmitted as PaperworkSubmitted, __webpack_exports__People as People, __webpack_exports__Phone as Phone, __webpack_exports__Plus as Plus, __webpack_exports__Positions as Positions, __webpack_exports__Profile as Profile, __webpack_exports__ProfileFemale as ProfileFemale, __webpack_exports__ProfileMale as ProfileMale, __webpack_exports__QuestionMark as QuestionMark, __webpack_exports__Remuneration as Remuneration, __webpack_exports__Reschedule as Reschedule, __webpack_exports__Restore as Restore, __webpack_exports__Review as Review, __webpack_exports__Schedule as Schedule, __webpack_exports__Search as Search, __webpack_exports__Settings as Settings, __webpack_exports__Shield as Shield, __webpack_exports__Sidebar as Sidebar, __webpack_exports__Sliders as Sliders, __webpack_exports__SortAsc as SortAsc, __webpack_exports__SortDefault as SortDefault, __webpack_exports__SortDes as SortDes, __webpack_exports__StepsComplete as StepsComplete, __webpack_exports__StepsCurrent as StepsCurrent, __webpack_exports__StepsIncomplete as StepsIncomplete, __webpack_exports__Submit as Submit, __webpack_exports__Success as Success, __webpack_exports__SuperFund as SuperFund, __webpack_exports__Sync as Sync, __webpack_exports__Table as Table, __webpack_exports__Task as Task, __webpack_exports__Tax as Tax, __webpack_exports__Tenure as Tenure, __webpack_exports__UserPlus as UserPlus, __webpack_exports__Visible as Visible, __webpack_exports__Warning as Warning, __webpack_exports__Workflows as Workflows };
@@ -0,0 +1,2 @@
1
+ import FileImport_rslib_entry_namespaceObject from "../../static/svg/FileImport.svg";
2
+ export { FileImport_rslib_entry_namespaceObject as default };
@@ -110,14 +110,18 @@ type CommonProps<Type> = {
110
110
  * Set with `pathName` if you want column filters and visibility saved between visits.
111
111
  * @default (omitted) persistence disabled.
112
112
  */
113
+ storageId?: string;
114
+ /**
115
+ * @deprecated Use `storageId`. Kept for backwards compatibility with `Table`.
116
+ */
113
117
  id?: string;
114
118
  /**
115
- * Scope for saved list settings; use together with `id` so persistence is enabled.
119
+ * Scope for saved list settings; use together with `storageId` so persistence is enabled.
116
120
  * @default (omitted) persistence disabled.
117
121
  */
118
122
  pathName?: string;
119
123
  /**
120
- * Schema for validating stored list state when using `id` and `pathName`.
124
+ * Schema for validating stored list state when using `storageId` and `pathName`.
121
125
  * @default (omitted) stored JSON is not parsed with Zod before use.
122
126
  */
123
127
  localStorageSchema?: ZodTypeAny;
@@ -43,7 +43,8 @@ function mergeInlineSinglePersistedColumnFilters(tableColumnFilters, inlineColum
43
43
  }
44
44
  ];
45
45
  }
46
- const RichListInner = ({ data, getRowId, leadingSlot, mainSlot, contentSlots = EMPTY_RICH_LIST_CONTENT_SLOTS, contentAlignment = "space-evenly", trailingSlot, href, onClick, rowActions, bulkActions = EMPTY_RICH_LIST_BULK_ACTIONS, secondaryBulkActions = EMPTY_RICH_LIST_BULK_ACTIONS, rowHeight = "medium", csvFilename, fillContainerHeight = false, compactBreakpoint: compactBreakpointProp, emptyState = "No results", id, pathName, localStorageSchema, header, onFiltersChange })=>{
46
+ const RichListInner = ({ data, getRowId, leadingSlot, mainSlot, contentSlots = EMPTY_RICH_LIST_CONTENT_SLOTS, contentAlignment = "space-evenly", trailingSlot, href, onClick, rowActions, bulkActions = EMPTY_RICH_LIST_BULK_ACTIONS, secondaryBulkActions = EMPTY_RICH_LIST_BULK_ACTIONS, rowHeight = "medium", csvFilename, fillContainerHeight = false, compactBreakpoint: compactBreakpointProp, emptyState = "No results", storageId, id, pathName, localStorageSchema, header, onFiltersChange })=>{
47
+ const resolvedStorageId = storageId ?? id;
47
48
  const [searchTerm, setSearchTerm] = (0, __WEBPACK_EXTERNAL_MODULE_react__.useState)("");
48
49
  const [inlineSingleSelectChoice, setInlineSingleSelectChoice] = (0, __WEBPACK_EXTERNAL_MODULE_react__.useState)(void 0);
49
50
  const [isFilterModalOpen, setIsFilterModalOpen] = (0, __WEBPACK_EXTERNAL_MODULE_react__.useState)(false);
@@ -154,6 +155,9 @@ const RichListInner = ({ data, getRowId, leadingSlot, mainSlot, contentSlots = E
154
155
  const sortableEntryIds = (0, __WEBPACK_EXTERNAL_MODULE_react__.useMemo)(()=>new Set(sortableEntries.map((entry)=>entry.id)), [
155
156
  sortableEntries
156
157
  ]);
158
+ const groupableEntryIds = (0, __WEBPACK_EXTERNAL_MODULE_react__.useMemo)(()=>new Set(groupableEntries.map((entry)=>entry.id)), [
159
+ groupableEntries
160
+ ]);
157
161
  const columnDefs = (0, __WEBPACK_EXTERNAL_MODULE_react__.useMemo)(()=>{
158
162
  const columnHelper = (0, __WEBPACK_EXTERNAL_MODULE__tanstack_react_table_777e1b4b__.createColumnHelper)();
159
163
  const tableFilteringForEntry = (entryId)=>!(void 0 !== inlineSingleSelectExcludedFromTableColumnId && entryId === inlineSingleSelectExcludedFromTableColumnId);
@@ -222,9 +226,9 @@ const RichListInner = ({ data, getRowId, leadingSlot, mainSlot, contentSlots = E
222
226
  }), [
223
227
  entriesWithFilter
224
228
  ]);
225
- const storageKey = (0, __WEBPACK_EXTERNAL_MODULE_react__.useMemo)(()=>pathName && id ? `${pathName}#${id}_richList` : null, [
229
+ const storageKey = (0, __WEBPACK_EXTERNAL_MODULE_react__.useMemo)(()=>pathName && resolvedStorageId ? `${pathName}#${resolvedStorageId}_richList` : null, [
226
230
  pathName,
227
- id
231
+ resolvedStorageId
228
232
  ]);
229
233
  const localStorageData = "undefined" != typeof window && storageKey ? window.localStorage.getItem(storageKey) : null;
230
234
  const parsedLocalStorage = (0, __WEBPACK_EXTERNAL_MODULE_react__.useMemo)(()=>{
@@ -245,6 +249,10 @@ const RichListInner = ({ data, getRowId, leadingSlot, mainSlot, contentSlots = E
245
249
  parsedLocalStorage.sorting,
246
250
  sortableEntryIds
247
251
  ]);
252
+ const initialGrouping = (0, __WEBPACK_EXTERNAL_MODULE_react__.useMemo)(()=>(parsedLocalStorage.grouping ?? []).filter((id)=>groupableEntryIds.has(id)), [
253
+ groupableEntryIds,
254
+ parsedLocalStorage.grouping
255
+ ]);
248
256
  const mergedInitialPersistedColumnFilters = (0, __WEBPACK_EXTERNAL_MODULE_react__.useMemo)(()=>parsedLocalStorage.columnFilters ?? columnFiltersInitialState, [
249
257
  parsedLocalStorage.columnFilters,
250
258
  columnFiltersInitialState
@@ -333,7 +341,7 @@ const RichListInner = ({ data, getRowId, leadingSlot, mainSlot, contentSlots = E
333
341
  columnVisibility: initialColumnVisibility,
334
342
  expanded: true,
335
343
  globalFilter: "",
336
- grouping: parsedLocalStorage.grouping ?? [],
344
+ grouping: initialGrouping,
337
345
  sorting: initialSorting
338
346
  },
339
347
  defaultColumn: {
@@ -359,6 +367,38 @@ const RichListInner = ({ data, getRowId, leadingSlot, mainSlot, contentSlots = E
359
367
  permanentlyHiddenColumnIds,
360
368
  table
361
369
  ]);
370
+ const hasRestoredLayoutFromStorageRef = (0, __WEBPACK_EXTERNAL_MODULE_react__.useRef)(false);
371
+ (0, __WEBPACK_EXTERNAL_MODULE_react__.useLayoutEffect)(()=>{
372
+ if (hasRestoredLayoutFromStorageRef.current || !storageKey || !localStorageSchema) return;
373
+ hasRestoredLayoutFromStorageRef.current = true;
374
+ const raw = window.localStorage.getItem(storageKey);
375
+ if (!raw) return;
376
+ try {
377
+ const parsed = JSON.parse(raw);
378
+ localStorageSchema.parse(parsed);
379
+ const sorting = (parsed.sorting ?? []).filter((sort)=>sortableEntryIds.has(sort.id));
380
+ if (sorting.length > 0) table.setSorting(sorting);
381
+ const grouping = (parsed.grouping ?? []).filter((id)=>groupableEntryIds.has(id));
382
+ if (grouping.length > 0) table.setGrouping(grouping);
383
+ if (parsed.columnVisibility) table.setColumnVisibility((prev)=>{
384
+ const next = {
385
+ ...prev,
386
+ ...parsed.columnVisibility
387
+ };
388
+ for (const id of permanentlyHiddenColumnIds)next[id] = false;
389
+ return next;
390
+ });
391
+ } catch (error) {
392
+ console.error("Error restoring RichList layout from localStorage:", error);
393
+ }
394
+ }, [
395
+ groupableEntryIds,
396
+ localStorageSchema,
397
+ permanentlyHiddenColumnIds,
398
+ sortableEntryIds,
399
+ storageKey,
400
+ table
401
+ ]);
362
402
  const tableState = table.getState();
363
403
  const persistedSorting = (0, __WEBPACK_EXTERNAL_MODULE_react__.useMemo)(()=>tableState.sorting.filter((sort)=>sortableEntryIds.has(sort.id)), [
364
404
  sortableEntryIds,
@@ -376,7 +416,8 @@ const RichListInner = ({ data, getRowId, leadingSlot, mainSlot, contentSlots = E
376
416
  ]);
377
417
  const showSearchReset = activeFilterCount > 0 || "" !== tableState.globalFilter;
378
418
  (0, __WEBPACK_EXTERNAL_MODULE_react__.useEffect)(()=>{
379
- if (storageKey) window.localStorage.setItem(storageKey, JSON.stringify({
419
+ if (!storageKey) return;
420
+ window.localStorage.setItem(storageKey, JSON.stringify({
380
421
  columnFilters: mergeInlineSinglePersistedColumnFilters(tableState.columnFilters, inlineSingleSelectExcludedFromTableColumnId, inlineSingleSelectOptionIdResolved),
381
422
  columnVisibility: tableState.columnVisibility,
382
423
  sorting: persistedSorting,
@@ -731,10 +772,17 @@ const RichListInner = ({ data, getRowId, leadingSlot, mainSlot, contentSlots = E
731
772
  };
732
773
  const RICH_LIST_DEFER_ROW_THRESHOLD = 1000;
733
774
  const RichList = (props)=>{
734
- const shouldDefer = props.data.length > RICH_LIST_DEFER_ROW_THRESHOLD;
735
- const [ready, setReady] = (0, __WEBPACK_EXTERNAL_MODULE_react__.useState)(!shouldDefer);
775
+ const resolvedStorageId = props.storageId ?? props.id;
776
+ const persistenceEnabled = Boolean(resolvedStorageId);
777
+ const persistencePathReady = !persistenceEnabled || Boolean(props.pathName);
778
+ const shouldDefer = props.data.length > RICH_LIST_DEFER_ROW_THRESHOLD || persistenceEnabled;
779
+ const [ready, setReady] = (0, __WEBPACK_EXTERNAL_MODULE_react__.useState)(!shouldDefer && persistencePathReady);
736
780
  (0, __WEBPACK_EXTERNAL_MODULE_react__.useEffect)(()=>{
737
- if (ready) return;
781
+ if (ready || !persistencePathReady) return;
782
+ if (!shouldDefer) {
783
+ setReady(true);
784
+ return;
785
+ }
738
786
  let innerHandle = 0;
739
787
  const outerHandle = requestAnimationFrame(()=>{
740
788
  innerHandle = requestAnimationFrame(()=>setReady(true));
@@ -744,7 +792,9 @@ const RichList = (props)=>{
744
792
  cancelAnimationFrame(innerHandle);
745
793
  };
746
794
  }, [
747
- ready
795
+ persistencePathReady,
796
+ ready,
797
+ shouldDefer
748
798
  ]);
749
799
  return ready ? /*#__PURE__*/ (0, __WEBPACK_EXTERNAL_MODULE_react_jsx_runtime_225474f2__.jsx)(RichListInner, {
750
800
  ...props
@@ -258,7 +258,8 @@ const RichListRow = ({ row, table, groupEntry, enableRowSelection, anyRowCanBeSe
258
258
  icon: action.icon,
259
259
  tooltip: action.label,
260
260
  href: action.href(rowOriginal),
261
- external: action.external
261
+ external: action.external,
262
+ download: action.download?.(rowOriginal)
262
263
  }, action.id);
263
264
  if ("onClick" === action.type) return /*#__PURE__*/ (0, __WEBPACK_EXTERNAL_MODULE_react_jsx_runtime_225474f2__.jsx)(__WEBPACK_EXTERNAL_MODULE__controls_Button_js_2f50b64a__["default"], {
264
265
  id: action.id,
@@ -48,12 +48,20 @@ const RichListSkeleton = ({ leadingSlot, mainSlot, contentSlots, trailingSlot, r
48
48
  hasToolbar ? /*#__PURE__*/ (0, __WEBPACK_EXTERNAL_MODULE_react_jsx_runtime_225474f2__.jsxs)("div", {
49
49
  className: __WEBPACK_EXTERNAL_MODULE__RichListSkeleton_module_js_905f84d0__["default"].toolbar,
50
50
  children: [
51
- /*#__PURE__*/ (0, __WEBPACK_EXTERNAL_MODULE_react_jsx_runtime_225474f2__.jsx)(__WEBPACK_EXTERNAL_MODULE__SkeletonBlock_js_ce81034c__["default"], {
52
- className: __WEBPACK_EXTERNAL_MODULE__RichListSkeleton_module_js_905f84d0__["default"].line,
53
- style: {
54
- height: 32,
55
- width: 240
56
- }
51
+ /*#__PURE__*/ (0, __WEBPACK_EXTERNAL_MODULE_react_jsx_runtime_225474f2__.jsxs)("div", {
52
+ className: __WEBPACK_EXTERNAL_MODULE__RichListSkeleton_module_js_905f84d0__["default"].searchbar,
53
+ children: [
54
+ enableRowSelection ? /*#__PURE__*/ (0, __WEBPACK_EXTERNAL_MODULE_react_jsx_runtime_225474f2__.jsx)(__WEBPACK_EXTERNAL_MODULE__SkeletonBlock_js_ce81034c__["default"], {
55
+ className: __WEBPACK_EXTERNAL_MODULE__RichListSkeleton_module_js_905f84d0__["default"].checkbox
56
+ }) : null,
57
+ /*#__PURE__*/ (0, __WEBPACK_EXTERNAL_MODULE_react_jsx_runtime_225474f2__.jsx)(__WEBPACK_EXTERNAL_MODULE__SkeletonBlock_js_ce81034c__["default"], {
58
+ className: __WEBPACK_EXTERNAL_MODULE__RichListSkeleton_module_js_905f84d0__["default"].line,
59
+ style: {
60
+ height: 20,
61
+ width: 240
62
+ }
63
+ })
64
+ ]
57
65
  }),
58
66
  /*#__PURE__*/ (0, __WEBPACK_EXTERNAL_MODULE_react_jsx_runtime_225474f2__.jsx)("span", {
59
67
  className: __WEBPACK_EXTERNAL_MODULE__RichListSkeleton_module_js_905f84d0__["default"].grow
@@ -61,14 +69,14 @@ const RichListSkeleton = ({ leadingSlot, mainSlot, contentSlots, trailingSlot, r
61
69
  /*#__PURE__*/ (0, __WEBPACK_EXTERNAL_MODULE_react_jsx_runtime_225474f2__.jsx)(__WEBPACK_EXTERNAL_MODULE__SkeletonBlock_js_ce81034c__["default"], {
62
70
  className: __WEBPACK_EXTERNAL_MODULE__RichListSkeleton_module_js_905f84d0__["default"].line,
63
71
  style: {
64
- height: 32,
72
+ height: 20,
65
73
  width: 84
66
74
  }
67
75
  }),
68
76
  /*#__PURE__*/ (0, __WEBPACK_EXTERNAL_MODULE_react_jsx_runtime_225474f2__.jsx)(__WEBPACK_EXTERNAL_MODULE__SkeletonBlock_js_ce81034c__["default"], {
69
77
  className: __WEBPACK_EXTERNAL_MODULE__RichListSkeleton_module_js_905f84d0__["default"].line,
70
78
  style: {
71
- height: 32,
79
+ height: 20,
72
80
  width: 84
73
81
  }
74
82
  })
@@ -7,6 +7,7 @@ const RichListSkeleton_module_rslib_entry_ = {
7
7
  grow: "grow-djYGNT",
8
8
  checkbox: "checkbox-TgI6UA",
9
9
  circle: "circle-Wh22l0",
10
- line: "line-SMRPlk"
10
+ line: "line-SMRPlk",
11
+ searchbar: "searchbar-SAzIf9"
11
12
  };
12
13
  export { RichListSkeleton_module_rslib_entry_ as default };
@@ -20,8 +20,7 @@
20
20
  box-sizing: border-box;
21
21
  align-items: center;
22
22
  gap: var(--size-n2);
23
- min-height: var(--row-height);
24
- padding: var(--size-n2) var(--richlist-padding-inline, var(--size-n1));
23
+ padding: 17px var(--richlist-padding-inline, var(--size-n1));
25
24
  display: flex;
26
25
  }
27
26
 
@@ -51,11 +50,17 @@
51
50
 
52
51
  .circle-Wh22l0 {
53
52
  border-radius: 50%;
54
- width: 32px;
55
- height: 32px;
53
+ width: 48px;
54
+ height: 48px;
56
55
  }
57
56
 
58
57
  .line-SMRPlk {
59
58
  height: 16px;
60
59
  }
61
60
 
61
+ .searchbar-SAzIf9 {
62
+ align-items: center;
63
+ gap: var(--size-00);
64
+ display: flex;
65
+ }
66
+
@@ -62,6 +62,10 @@ export declare const RICH_LIST_INLINE_PAD_PRESET_PX: {
62
62
  };
63
63
  export declare const richListInlinePaddingPx: (rowHeight: RichListRowHeightValue) => number;
64
64
  export declare const SELECT_COLUMN_ID = "_richListSelect";
65
+ /** Default TanStack column id for `mainSlot.primary` when `RichListTextField.id` is omitted. */
66
+ export declare const RICH_LIST_DEFAULT_PRIMARY_FIELD_ID = "_richList_primary";
67
+ /** Default TanStack column id for `mainSlot.secondary` when `RichListTextField.id` is omitted. */
68
+ export declare const RICH_LIST_DEFAULT_SECONDARY_FIELD_ID = "_richList_secondary";
65
69
  export declare const normalizeTextField: <Type>(field: RichListTextField<Type>, position: "primary" | "secondary") => NormalizedTextField<Type>;
66
70
  /**
67
71
  * Accepts the wider `RichListContentSlot` shape so leading/trailing `RichListSlot`
@@ -36,9 +36,11 @@ const richListInlinePaddingPx = (rowHeight)=>{
36
36
  return RICH_LIST_INLINE_PAD_PRESET_PX.large;
37
37
  };
38
38
  const SELECT_COLUMN_ID = "_richListSelect";
39
+ const RICH_LIST_DEFAULT_PRIMARY_FIELD_ID = "_richList_primary";
40
+ const RICH_LIST_DEFAULT_SECONDARY_FIELD_ID = "_richList_secondary";
39
41
  const normalizeTextField = (field, position)=>{
40
42
  if ("function" == typeof field) return {
41
- id: `_richList_${position}`,
43
+ id: "primary" === position ? RICH_LIST_DEFAULT_PRIMARY_FIELD_ID : RICH_LIST_DEFAULT_SECONDARY_FIELD_ID,
42
44
  position,
43
45
  render: field,
44
46
  globalFiltering: false,
@@ -47,7 +49,7 @@ const normalizeTextField = (field, position)=>{
47
49
  layoutVisibility: "always"
48
50
  };
49
51
  return {
50
- id: `_richList_${position}`,
52
+ id: field.id ?? ("primary" === position ? RICH_LIST_DEFAULT_PRIMARY_FIELD_ID : RICH_LIST_DEFAULT_SECONDARY_FIELD_ID),
51
53
  position,
52
54
  label: field.label,
53
55
  value: field.value,
@@ -141,7 +143,8 @@ const richListRowActionToMenuOption = (action, row)=>{
141
143
  icon: action.icon,
142
144
  type: "link",
143
145
  href: action.href(row),
144
- external: action.external
146
+ external: action.external,
147
+ download: action.download?.(row)
145
148
  };
146
149
  if ("onClick" === action.type) return {
147
150
  id: action.id,
@@ -158,4 +161,4 @@ const richListRowActionToMenuOption = (action, row)=>{
158
161
  render: action.render
159
162
  };
160
163
  };
161
- export { RICH_LIST_CONTENT_COMPACT_MAX_PX, RICH_LIST_INLINE_PAD_PRESET_PX, ROW_HEIGHT_PRESETS, SELECT_COLUMN_ID, formatSlotSize, handleDownloadCsv, isColumnWithVisibilityState, isRichListRowHeightByBreakpoint, isToggleableContentColumn, isVisibleAtBreakpoint, normalizeSlot, normalizeTextField, resolveRichListRowHeightValue, richListInlinePaddingPx, richListRowActionToMenuOption, richListRowHeightToPx };
164
+ export { RICH_LIST_CONTENT_COMPACT_MAX_PX, RICH_LIST_DEFAULT_PRIMARY_FIELD_ID, RICH_LIST_DEFAULT_SECONDARY_FIELD_ID, RICH_LIST_INLINE_PAD_PRESET_PX, ROW_HEIGHT_PRESETS, SELECT_COLUMN_ID, formatSlotSize, handleDownloadCsv, isColumnWithVisibilityState, isRichListRowHeightByBreakpoint, isToggleableContentColumn, isVisibleAtBreakpoint, normalizeSlot, normalizeTextField, resolveRichListRowHeightValue, richListInlinePaddingPx, richListRowActionToMenuOption, richListRowHeightToPx };
@@ -48,6 +48,11 @@ export type RichListColumnWidthMode = "shrinkable" | "fixed";
48
48
  * (function form forces `globalFiltering: false` and `csvExport: false`).
49
49
  */
50
50
  export type RichListTextField<Type> = ((row: Type) => ReactNode) | {
51
+ /**
52
+ * Unique id for this field in sort, group, filter, and localStorage persistence.
53
+ * @default `_richList_primary` or `_richList_secondary` (see `normalizeTextField`)
54
+ */
55
+ id?: string;
51
56
  /**
52
57
  * Long text is truncated with an ellipsis when space is tight.
53
58
  * Use `prefixOnWide` / `suffixOnWide` for small extras beside the main line at
@@ -388,6 +393,8 @@ export type RichListRowAction<Type> = {
388
393
  href: (row: Type) => string;
389
394
  /** When `true`, opens in a new tab with `rel="noopener noreferrer"`. */
390
395
  external?: boolean;
396
+ /** Suggested filename for a download link. */
397
+ download?: (row: Type) => string | boolean;
391
398
  } | {
392
399
  type: "onClick";
393
400
  onClick: (row: Type) => void;
@@ -0,0 +1 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 640"><!--!Font Awesome Pro 7.3.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2026 Fonticons, Inc.--><path d="M192 112L304 112L304 200C304 239.8 336.2 272 376 272L464 272L464 512C464 520.8 456.8 528 448 528L192 528C183.2 528 176 520.8 176 512L176 464L128 464L128 512C128 547.3 156.7 576 192 576L448 576C483.3 576 512 547.3 512 512L512 250.5C512 233.5 505.3 217.2 493.3 205.2L370.7 82.7C358.7 70.7 342.5 64 325.5 64L192 64C156.7 64 128 92.7 128 128L128 320L176 320L176 128C176 119.2 183.2 112 192 112zM352 131.9L444.1 224L376 224C362.7 224 352 213.3 352 200L352 131.9zM64 392C64 405.3 74.7 416 88 416L310.1 416L279.1 447C269.7 456.4 269.7 471.6 279.1 480.9C288.5 490.2 303.7 490.3 313 480.9L385 408.9C394.4 399.5 394.4 384.3 385 375L313 303C303.6 293.6 288.4 293.6 279.1 303C269.8 312.4 269.7 327.6 279.1 336.9L310.1 367.9L88 367.9C74.7 367.9 64 378.6 64 391.9z"/></svg>
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@worknice/whiteboard",
3
3
  "description": "",
4
- "version": "0.69.0",
4
+ "version": "0.70.0",
5
5
  "license": "MIT",
6
6
  "private": false,
7
7
  "files": [
@@ -39,7 +39,7 @@
39
39
  "react-markdown": "^10.1.0",
40
40
  "utf8": "^3.0.0",
41
41
  "zod": "^4.1.13",
42
- "@worknice/utils": "^0.52.0"
42
+ "@worknice/utils": "^0.53.0"
43
43
  },
44
44
  "devDependencies": {
45
45
  "@anolilab/semantic-release-pnpm": "^3.2.2",