pixelize-design-library 2.4.2-beta.39 → 2.4.2-beta.40

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/COMPONENT-GOTCHAS.md +127 -8
  2. package/dist/Components/Apexcharts/ApexBarChart/ApexBarChart.d.ts +1 -0
  3. package/dist/Components/Apexcharts/ApexBarChart/ApexBarChart.js +1 -0
  4. package/dist/Components/Apexcharts/ApexLineChart/ApexLineChart.d.ts +1 -0
  5. package/dist/Components/Apexcharts/ApexLineChart/ApexLineChart.js +1 -0
  6. package/dist/Components/Apexcharts/ApexPieChart/ApexPieChart.d.ts +1 -0
  7. package/dist/Components/Apexcharts/ApexPieChart/ApexPieChart.js +1 -0
  8. package/dist/Components/Apexcharts/ApexPolarCharts/ApexPolarCharts.d.ts +1 -0
  9. package/dist/Components/Apexcharts/ApexPolarCharts/ApexPolarCharts.js +1 -0
  10. package/dist/Components/KanbanBoard/KanbanBoardProps.d.ts +27 -3
  11. package/dist/Components/OrganizationDetails/OrganizationDetails.d.ts +1 -0
  12. package/dist/Components/OrganizationDetails/OrganizationDetails.js +1 -0
  13. package/dist/Components/OrganizationDetails/OrganizationDetailsProps.d.ts +8 -4
  14. package/dist/Components/RolesPermission/RolesPermission.d.ts +1 -0
  15. package/dist/Components/RolesPermission/RolesPermission.js +1 -0
  16. package/dist/Components/RolesPermission/RolesPermissionProps.d.ts +6 -1
  17. package/dist/Components/ScrollbarBox/ScrollbarBox.d.ts +7 -0
  18. package/dist/Components/ScrollbarBox/ScrollbarBox.js +1 -0
  19. package/dist/Components/SearchSelect/SearchSelectProps.d.ts +18 -0
  20. package/dist/Components/SideBar/SideBarProps.d.ts +29 -24
  21. package/dist/Components/StageProgress/StageProgressProps.d.ts +33 -0
  22. package/dist/Components/Table/Table.d.ts +1 -0
  23. package/dist/Components/Table/Table.js +1 -0
  24. package/dist/Components/Table/TableProps.d.ts +27 -0
  25. package/dist/Components/UserDetails/UserDetails.d.ts +1 -0
  26. package/dist/Components/UserDetails/UserDetails.js +1 -0
  27. package/dist/Components/UserDetails/UserDetailsProps.d.ts +13 -0
  28. package/dist/esm/Components/Apexcharts/ApexBarChart/ApexBarChart.js +1 -0
  29. package/dist/esm/Components/Apexcharts/ApexLineChart/ApexLineChart.js +1 -0
  30. package/dist/esm/Components/Apexcharts/ApexPieChart/ApexPieChart.js +1 -0
  31. package/dist/esm/Components/Apexcharts/ApexPolarCharts/ApexPolarCharts.js +1 -0
  32. package/dist/esm/Components/OrganizationDetails/OrganizationDetails.js +1 -0
  33. package/dist/esm/Components/RolesPermission/RolesPermission.js +1 -0
  34. package/dist/esm/Components/ScrollbarBox/ScrollbarBox.js +1 -0
  35. package/dist/esm/Components/Table/Table.js +1 -0
  36. package/dist/esm/Components/UserDetails/UserDetails.js +1 -0
  37. package/package.json +1 -1
@@ -443,15 +443,17 @@ styleable) `Divider` re-exported from the `Primitives` barrel. `Trail/TrailWorks
443
443
  **Apply:** for a divider in a consuming app, use the `Divider` from `Primitives`, not this library's
444
444
  own. For a real data grid, use `Table` — nothing under `Trail/` is meant for reuse.
445
445
 
446
- ### `KanbanActions` is not wired into `KanbanBoard`, and is not exported
446
+ ### `KanbanActions` is exported but still not wired into `KanbanBoard`
447
447
 
448
448
  `KanbanBoard`'s header select/edit/create bar is driven by its own `kanbanSelect`/`kanbanEdit`/
449
- `kanbanCreate` props, via a different internal component. `KanbanActions` is a separate,
450
- unconnected, unexported component whose only references are its own file and test — its
451
- `options`-driven buttons always render with no gating, unlike the real header actions.
449
+ `kanbanCreate` props, via a different internal component. `KanbanActions` is a separate, standalone
450
+ component (exported from the package root as of 2.4.2-beta.39) that a consumer must render and wire
451
+ up itself — its `options`-driven buttons always render with no permission gating, unlike
452
+ `KanbanBoard`'s own header actions, which respect `permissions.isEditable`/`isCreatable`.
452
453
 
453
- **Apply:** use `KanbanBoard`'s own `kanbanSelect`/`kanbanEdit`/`kanbanCreate` props for board header
454
- actions — never reach for `KanbanActions`.
454
+ **Apply:** use `KanbanBoard`'s own `kanbanSelect`/`kanbanEdit`/`kanbanCreate` props for the board's
455
+ built-in header actions. Reach for `KanbanActions` only when building a custom toolbar outside
456
+ `KanbanBoard`, and gate it yourself — it has no permissions awareness of its own.
455
457
 
456
458
  ### `KanbanBoard`'s `permissions.isEditable: false` disables card drag but not column-reorder drag
457
459
 
@@ -962,7 +964,124 @@ Remount via `key={fileUrl}` when swapping the file in place instead of just chan
962
964
 
963
965
  Both props stop having any effect the moment a tracker switches to the stepper variant. Separately,
964
966
  if `value` matches no `stage.id` (e.g. `stages` was filtered/re-derived and went stale), every stage
965
- silently renders as `"upcoming"` — no stage is ever active or completed, with no error.
967
+ silently renders as `"upcoming"` — no stage is ever active or completed, with no error. The match is
968
+ also a strict `===`: a numeric `stage.id` compared against a string `value` (or vice versa) never
969
+ matches either, even when the "same" stage is clearly intended.
966
970
 
967
971
  **Apply:** don't rely on either prop once on the stepper variant. Re-validate `value` against the
968
- current `stages` list whenever it's filtered.
972
+ current `stages` list whenever it's filtered, and keep `id`/`value` the same primitive type at every
973
+ call site.
974
+
975
+ ### `Table`'s `isVisiblity`, `tableSettings`, `handleExportChange`/`exportOptions`/`exportLabel`, and `onColumnFilter` are dead props
976
+
977
+ None of these do anything in the current implementation, despite being typed on `TableProps` (and
978
+ some documented on the demo page):
979
+
980
+ - `isVisiblity` — `Table`'s own destructure never lists it, so a consumer's value is dropped. It's
981
+ hardcoded `true` into both `Pagination` call sites regardless, and `Pagination` doesn't read it
982
+ either. It is a misspelling of `isVisibility`, but do not rename it (breaking change) — and do not
983
+ expect it to do anything if you do.
984
+ - `tableSettings` (`{filters, filterSelected, onFilterSelection}`) — `Table` passes it to
985
+ `TableSettings`, but `TableSettings`'s function signature never destructures it.
986
+ - `handleExportChange` / `exportOptions` / `exportLabel` — `Table` renders no export UI at all; none
987
+ of the three are read anywhere, despite `src/Pages/table.tsx` documenting them as if live.
988
+ - `onColumnFilter` — commented out of `Table`'s own destructure (`// onColumnFilter`).
989
+
990
+ **Apply:** don't reach for any of these expecting an effect. Column visibility is driven by
991
+ `isTableSettings` (shows the Settings gear) + `preferences` (server persistence) + the Manage
992
+ Columns tab — not by `isVisiblity`/`tableSettings`.
993
+
994
+ ### `Table`'s `preferences` prop is silent-by-default, not required
995
+
996
+ Omitting `preferences` (or leaving `preferences.url` empty, the default) does not throw or disable
997
+ the table — the persistence hooks both early-return when the base URL is falsy. The table works
998
+ fully in memory; it just never persists column order/visibility, density, or grouping across
999
+ reloads. When you do wire a `url`, `token` is sent as a **raw** `Authorization` header value — do
1000
+ not prefix it with `"Bearer "` yourself expecting the hook to strip it.
1001
+
1002
+ **Apply:** treat `preferences` as opt-in persistence, not a required config block. If settings
1003
+ aren't surviving a refresh, check `preferences.url` is actually set before assuming a bug.
1004
+
1005
+ ### `SearchSelect`'s `height` prop only resizes the `insideSelect` segment, not the field
1006
+
1007
+ Despite the name, `height` is read only to size the nested `insideSelect` trigger. The main
1008
+ control's height always comes from `size`'s token set — passing `height` with no `insideSelect`
1009
+ configured has no visible effect at all.
1010
+
1011
+ **Apply:** to change the main field's height, change `size`; `height` only matters when
1012
+ `insideSelect` is also passed.
1013
+
1014
+ ### `SearchSelect`'s `pagination.limit` also drives a "has more" guess, not just page size
1015
+
1016
+ `hasMore` is computed as `options.length % pagination.limit === 0` — there is no real end-of-data
1017
+ signal from the consumer. A total result count that happens to be an exact multiple of `limit`
1018
+ looks indistinguishable from "more pages exist," firing one extra, empty `onScroll` call.
1019
+
1020
+ **Apply:** if exact pagination boundaries matter, pad or report a real "no more results" state some
1021
+ other way; don't rely on `hasMore` being accurate at a page boundary.
1022
+
1023
+ ### `RolesPermission`'s `RoleData.permission`/`designation`/`makeSuperAdmin`/`automation`/`trackLocation`/`show_records` are dead weight in this component
1024
+
1025
+ None of these fields are read by `RolesPermission` — the roles list only renders
1026
+ `roleName`/`createdBy`/`created_at`/`roles_id`. They exist solely to be round-tripped unchanged
1027
+ through `onViewRole`/`onEditRole` so the consumer can prefill its own edit form. Setting them has no
1028
+ visible effect inside this component.
1029
+
1030
+ **Apply:** treat these fields as pass-through-only storage — populate them for your own edit form,
1031
+ not to change anything `RolesPermission` itself renders.
1032
+
1033
+ ### `OrganizationDetails`' `OrganizationItem.uiInvite` is never read
1034
+
1035
+ Active vs. invited organizations are decided purely by which array (`activeOrganizations` vs
1036
+ `invitedOrganizations`) an item is placed in — `uiInvite` is carried on the type but
1037
+ `OrganizationDetails` never inspects it.
1038
+
1039
+ **Apply:** don't rely on `uiInvite` to control which section an item renders in — move the item
1040
+ between the two arrays instead.
1041
+
1042
+ ### `OrganizationDetails`' `onSetDefault`/`onAcceptInvite`/`onDeclineInvite` are fire-and-forget despite their `Promise<void>` signature
1043
+
1044
+ Unlike `onCreateOrganization`/`onEditOrganization`/`onDeleteOrganization` (all awaited), these three
1045
+ are called without `await` — the `switchingOrgIds`/`respondingOrgIds` spinner arrays are entirely
1046
+ consumer-managed state, not driven by this component resolving the promise.
1047
+
1048
+ **Apply:** don't assume symmetry with the awaited callbacks in the same props interface; manage your
1049
+ own loading state for these three around the promise you return.
1050
+
1051
+ ### `OrganizationDetails`' `CreateOrgFormValues.default`/`defaultOrg` are dead fields
1052
+
1053
+ The built-in `CreateOrgModal`'s internal state and submit handler never set or forward them, and the
1054
+ public `onCreateOrganization` callback's parameter type doesn't declare them at all — populating
1055
+ them in a custom create form has no effect on the built-in flow.
1056
+
1057
+ **Apply:** don't rely on these two fields to pre-mark a newly created org as default.
1058
+
1059
+ ### `SideBar`'s `selectedSubMenu` prop is accepted but never read
1060
+
1061
+ `SidebarProps.selectedSubMenu` is threaded through `SideBar` → `MenuItems` → `MenuItemBox`, but the
1062
+ component's destructure never includes it — passing it has no effect of any kind.
1063
+
1064
+ **Apply:** don't pass `selectedSubMenu` expecting it to highlight a submenu row.
1065
+
1066
+ ### `SideBar`'s `locked` menu-item flag doesn't lock anything
1067
+
1068
+ `MenuProps.locked` only swaps the trailing badge/chevron for a lock icon. The click handler checks
1069
+ only `disabled` — a `locked: true, disabled: false` item still fully navigates/expands.
1070
+
1071
+ **Apply:** set `disabled: true` alongside `locked: true` to actually prevent interaction.
1072
+
1073
+ ### `KanbanBoard`'s `kanbanSelect` ignores `permissions`, unlike `kanbanEdit`/`kanbanCreate`
1074
+
1075
+ `kanbanEdit`/`kanbanCreate` are only forwarded when `permissions.isEditable`/`isCreatable` allow it;
1076
+ `kanbanSelect` is passed through unconditionally regardless of `permissions`. `onOpen` similarly has
1077
+ no permission gate at all, asymmetric with the gated `onDelete`.
1078
+
1079
+ **Apply:** gate `kanbanSelect.isSelect` (and any `onOpen` affordance) yourself if they should also be
1080
+ permission-locked.
1081
+
1082
+ ### `KanbanBoard`'s `permissions.isViewable: false` hides everything, including header actions
1083
+
1084
+ Not just the columns — the select/edit/create header bar disappears too, since the whole component
1085
+ returns `null` before rendering anything.
1086
+
1087
+ **Apply:** there's no prop for hiding only the board body while keeping header actions visible.
@@ -1,2 +1,3 @@
1
1
  import { ApexBarChartProps } from "./ApexBarChartProps";
2
+ /** Bar chart wrapper around react-apexcharts (horizontal/stacked/distributed via props), themed via chartColorsFromTheme + chartBase. */
2
3
  export default function ApexBarChart({ data, labels, title, titlePosition, height, width, barColor, xAxisStyle, yAxisStyle, titleStyle, horizontal, distributed, seriesName, series, stacked, showLegend, legendPosition, }: ApexBarChartProps): import("react/jsx-runtime").JSX.Element;
@@ -10,6 +10,7 @@ const react_apexcharts_1 = __importDefault(require("react-apexcharts"));
10
10
  const react_2 = require("@chakra-ui/react");
11
11
  const chartColorsFromTheme_1 = require("../../../Theme/tokens/builders/chartColorsFromTheme");
12
12
  const chartBase_1 = require("../chartBase");
13
+ /** Bar chart wrapper around react-apexcharts (horizontal/stacked/distributed via props), themed via chartColorsFromTheme + chartBase. */
13
14
  function ApexBarChart({ data, labels, title, titlePosition, height = 400, width = 500, barColor, xAxisStyle, yAxisStyle, titleStyle, horizontal = false, distributed = false, seriesName = "Data", series, stacked = false, showLegend, legendPosition = "bottom", }) {
14
15
  const theme = (0, react_2.useTheme)();
15
16
  const palette = theme.colors;
@@ -1,3 +1,4 @@
1
1
  import { ApexLineChartProps } from "./ApexLineChartProps";
2
+ /** Line chart wrapper around react-apexcharts, themed via chartColorsFromTheme + chartBase. */
2
3
  declare const ApexLineChart: ({ data, labels, title, height, width, lineColors, titlePosition, titleStyle, compact, toolbarBreakpointPct, titleClampLines, showTitleEllipsis, showSeries, series: seriesNames, variant, }: ApexLineChartProps) => import("react/jsx-runtime").JSX.Element;
3
4
  export default ApexLineChart;
@@ -10,6 +10,7 @@ const react_2 = require("@chakra-ui/react");
10
10
  const ToolTip_1 = __importDefault(require("../../ToolTip/ToolTip"));
11
11
  const chartColorsFromTheme_1 = require("../../../Theme/tokens/builders/chartColorsFromTheme");
12
12
  const chartBase_1 = require("../chartBase");
13
+ /** Line chart wrapper around react-apexcharts, themed via chartColorsFromTheme + chartBase. */
13
14
  const ApexLineChart = ({ data, labels, title, height, width, lineColors, titlePosition = "center", titleStyle, compact = false, toolbarBreakpointPct = 0.6, titleClampLines, showTitleEllipsis = true, showSeries = true, series: seriesNames, variant = "basic", }) => {
14
15
  const theme = (0, react_2.useTheme)();
15
16
  const palette = theme.colors;
@@ -1,3 +1,4 @@
1
1
  import { ApexPieChartProps } from "./ApexPieChartProps";
2
+ /** Pie/donut chart wrapper around react-apexcharts, themed via chartColorsFromTheme + chartBase. */
2
3
  declare const ApexPieChart: ({ data, labels, title, height, width, donutColors, chartColor, titlePosition, titleStyle, legendPosition, legendStyle, variant, showDataLabels, minLabelPercent, surfaceColor, donutSize, totalLabel, labelPlacement, }: ApexPieChartProps) => import("react/jsx-runtime").JSX.Element;
3
4
  export default ApexPieChart;
@@ -17,6 +17,7 @@ const getValidLegendPosition = (position) => {
17
17
  console.warn(`Invalid legend position: ${position}. Defaulting to 'bottom'.`);
18
18
  return "bottom";
19
19
  };
20
+ /** Pie/donut chart wrapper around react-apexcharts, themed via chartColorsFromTheme + chartBase. */
20
21
  const ApexPieChart = ({ data, labels, title, height = 400, width = 500, donutColors, chartColor, titlePosition = "center", titleStyle, legendPosition = "bottom", legendStyle, variant = "pie", showDataLabels = true, minLabelPercent = 8, surfaceColor, donutSize = "68%", totalLabel = "Total", labelPlacement = "auto", }) => {
21
22
  var _a;
22
23
  const { colors: palette } = (0, useCustomTheme_1.useCustomTheme)();
@@ -1,3 +1,4 @@
1
1
  import { ApexPolarChartProps } from "./ApexPolarChartsProps";
2
+ /** Polar-area chart wrapper around react-apexcharts, themed via chartColorsFromTheme + chartBase. */
2
3
  declare const ApexPolarChart: ({ data, labels, title, height, width, chartColors, titlePosition, titleStyle, legendStyle, variant, }: ApexPolarChartProps) => import("react/jsx-runtime").JSX.Element;
3
4
  export default ApexPolarChart;
@@ -9,6 +9,7 @@ const react_apexcharts_1 = __importDefault(require("react-apexcharts"));
9
9
  const react_2 = require("@chakra-ui/react");
10
10
  const chartColorsFromTheme_1 = require("../../../Theme/tokens/builders/chartColorsFromTheme");
11
11
  const chartBase_1 = require("../chartBase");
12
+ /** Polar-area chart wrapper around react-apexcharts, themed via chartColorsFromTheme + chartBase. */
12
13
  const ApexPolarChart = ({ data, labels, title, height = 400, width = 500, chartColors, titlePosition = "center", titleStyle, legendStyle, variant = "basic", }) => {
13
14
  const theme = (0, react_2.useTheme)();
14
15
  const palette = theme.colors;
@@ -2,11 +2,17 @@ import type { ReactNode } from "react";
2
2
  import { OptionProp } from "../Select/SelectProps";
3
3
  /** Extra string keys render as label:value rows on the card; number values (also allowed here) are silently never shown. */
4
4
  export type Account = {
5
+ /** Used as the React key and the dnd draggableId — must be unique and stable across renders. */
5
6
  id: string;
7
+ /** Fully replaces AccountCard for this card — onDelete/onOpen/isDeletable and expand/collapse never apply when set. */
6
8
  customNode?: () => ReactNode;
9
+ /** Excluded from the generic row list; shown as separate description text, only when expanded. */
7
10
  details?: string;
11
+ /** No special rendering — just another label:value row like any extra string key. */
8
12
  name?: string;
13
+ /** Same generic row treatment as `name` — not validated or used for an avatar. */
9
14
  email?: string;
15
+ /** Same generic row treatment as `name`/`email` — plain string, not a number. */
10
16
  rating?: string;
11
17
  [key: string]: string | number | null | undefined | (() => ReactNode);
12
18
  };
@@ -14,11 +20,10 @@ export type Account = {
14
20
  export type ColumnType = {
15
21
  id: string;
16
22
  title: string;
23
+ /** Falls back to `colors.primary[500]` when omitted — used for the accent dot/border. */
17
24
  color: string;
18
25
  items: Account[];
19
- /**
20
- * Column-level slot (e.g. totals). Shown below the title when expanded, and in the collapsed narrow rail (rotated).
21
- */
26
+ /** Column-level slot (e.g. totals); shown below the title expanded, and rotated in the collapsed rail. */
22
27
  customNode?: () => ReactNode;
23
28
  };
24
29
  /** Fired after a column rail is collapsed or expanded via the board UI. */
@@ -31,16 +36,21 @@ export type ColumnCollapseChangePayload = {
31
36
  };
32
37
  /** Props for KanbanBoard — keyed columns (`data`) of draggable `Account` cards. */
33
38
  export type KanbanBoardProps = {
39
+ /** Base columns; `customColumns` below is merged on top, not into, this. */
34
40
  data: Record<string, ColumnType>;
35
41
  /** Merged on top of `data` — a matching column id in both silently overwrites the `data` entry, not merges its fields. */
36
42
  customColumns?: Record<string, ColumnType>;
37
43
  /** `isVisible` renders an inline dashed column when others exist, or a centered empty-state overlay when there are none. */
38
44
  customizeColumn?: {
39
45
  isVisible?: boolean;
46
+ /** Defaults to "Add column". */
40
47
  buttonText?: string;
48
+ /** Fires from both the inline dashed column and the empty-board overlay variant. */
41
49
  onAddColumn?: () => void;
42
50
  };
51
+ /** Never fires for a `customNode` card — it owns its own delete UI, and is not gated by `permissions.isDeletable`. */
43
52
  onDelete?: (account: Account) => void;
53
+ /** Same `customNode` exemption as `onDelete`; unlike delete, `onOpen` has no permission gate at all. */
44
54
  onOpen?: (account: Account) => void;
45
55
  /** Receives the deleted column's item ids, not the column's own id — the column identity itself is not passed. */
46
56
  onColumnDelete?: (colId: (string | number)[]) => void;
@@ -53,13 +63,17 @@ export type KanbanBoardProps = {
53
63
  fromIndex: number;
54
64
  toIndex: number;
55
65
  }) => void;
66
+ /** Also true (skeletons show) whenever `preferences.baseurl` is set and its own fetch is still loading. */
56
67
  isLoading?: boolean;
57
68
  kanbanSelect?: {
69
+ /** Gates the whole select — unlike `kanbanEdit`/`kanbanCreate`, never checked against `permissions`. */
58
70
  isSelect?: boolean;
59
71
  options?: OptionProp[];
60
72
  onSelectChange?: (option?: OptionProp) => void;
61
73
  selectPlaceholderText?: string;
74
+ /** Defaults to `"12.5rem"` when omitted. */
62
75
  width?: string;
76
+ /** Controlled value passed straight to the underlying Select. */
63
77
  value?: string;
64
78
  };
65
79
  /** Button shows only when this `isEditable` AND `permissions.isEditable` (default true) both allow it. */
@@ -74,18 +88,27 @@ export type KanbanBoardProps = {
74
88
  onCreate?: () => void;
75
89
  label?: string;
76
90
  };
91
+ /** true renders cards via a virtualized react-window list; otherwise all cards mount directly. */
77
92
  virtualization?: boolean;
78
93
  permissions?: {
94
+ /** Also gates the `kanbanEdit` button and card drag; column-reorder drag ignores this. */
79
95
  isEditable?: boolean;
96
+ /** Also gates the `kanbanCreate` button. */
80
97
  isCreatable?: boolean;
98
+ /** Also hides the column-delete trash icon on column-header hover, not just per-card delete. */
81
99
  isDeletable?: boolean;
100
+ /** false returns null for the whole board — nothing renders, not even header actions. */
82
101
  isViewable?: boolean;
83
102
  };
84
103
  noItems?: {
104
+ /** Also requires the column to have zero items — evaluated per column, not board-wide. */
85
105
  isVisible?: boolean;
106
+ /** Defaults to "No items in this column". */
86
107
  text?: string;
108
+ /** Defaults to "Add Item"; hidden entirely when `isEmptyTextOnly` is true. */
87
109
  buttonText?: string;
88
110
  onClick?: (column: ColumnType) => void;
111
+ /** When true, the button never renders — only the text line shows. */
89
112
  isEmptyTextOnly?: boolean;
90
113
  };
91
114
  /** When true, columns can collapse to a narrow horizontal rail (full height). */
@@ -100,6 +123,7 @@ export type KanbanBoardProps = {
100
123
  onColumnReorder?: (columns: Record<string, ColumnType>) => void;
101
124
  /** Same shape as Table's `preferences`; collapse state loads/saves to `json.collapsedColumns` only when `baseurl` is set. */
102
125
  preferences?: {
126
+ /** Must be non-empty to activate preferences loading/saving at all. */
103
127
  baseurl: string;
104
128
  token: string;
105
129
  key?: string;
@@ -1,4 +1,5 @@
1
1
  import React from "react";
2
2
  import { OrganizationDetailsProps } from "./OrganizationDetailsProps";
3
+ /** Admin panel for the org list — rename/delete/create/invites/default; not a session switcher. */
3
4
  declare const OrganizationDetails: React.FC<OrganizationDetailsProps>;
4
5
  export default OrganizationDetails;
@@ -53,6 +53,7 @@ const DEFAULT_LABELS = {
53
53
  copyright: "Pixelize Corp. All rights reserved.",
54
54
  termsOfService: "Terms of Service",
55
55
  };
56
+ /** Admin panel for the org list — rename/delete/create/invites/default; not a session switcher. */
56
57
  const OrganizationDetails = ({ activeOrganizations, invitedOrganizations, isLoading = false, switchingOrgIds = [], respondingOrgIds = [], editingOrgIds = [], isCreating = false, userName, userAvatarUrl, onSetDefault, onAcceptInvite, onDeclineInvite, onDeleteOrganization, onDeleteRequest, onCreateOrganization, onEditOrganization, onBack, footerSlot, labels: labelOverrides, }) => {
57
58
  const { colors } = (0, useCustomTheme_1.useCustomTheme)();
58
59
  const labels = (0, react_1.useMemo)(() => ({ ...DEFAULT_LABELS, ...labelOverrides }), [labelOverrides]);
@@ -6,16 +6,16 @@ export type OrganizationItem = {
6
6
  company_url?: string;
7
7
  /** 1 when this org is the user's default org. */
8
8
  default: number;
9
- /** 1 = active/accepted, 0 = pending invite. */
9
+ /** Not read by OrganizationDetails — active vs. invited comes from which array the item is placed in. */
10
10
  uiInvite: number;
11
- /** 1 always blocks delete, even if canDelete is explicitly true — not overridable like canRename/canDelete are. */
11
+ /** Distinct from `default` above — only gates delete-protection, not the Default badge/set-default flow. */
12
12
  defaultOrg: number;
13
13
  roleName?: string;
14
14
  /** True when the current user owns this org; the app computes ownership. */
15
15
  isOwner?: boolean;
16
- /** Overrides the role-name check for the rename control. */
16
+ /** Overrides the role-name check for rename; omitted, defaults to roleName === "Super Admin". */
17
17
  canRename?: boolean;
18
- /** Overrides the role-name check for delete — defaultOrg === 1 still blocks it regardless. */
18
+ /** Same default-if-omitted as canRename; defaultOrg === 1 still blocks delete regardless. */
19
19
  canDelete?: boolean;
20
20
  /**
21
21
  * Why delete is unavailable for this organization, shown on the disabled
@@ -28,6 +28,7 @@ export type CreateOrgFormValues = {
28
28
  company_name: string;
29
29
  company_address: string;
30
30
  phone?: string;
31
+ /** Never populated by the built-in CreateOrgModal — dead unless your own submit handler sets it. */
31
32
  default?: number;
32
33
  defaultOrg?: number;
33
34
  };
@@ -89,7 +90,9 @@ export interface OrganizationDetailsProps {
89
90
  editingOrgIds?: number[];
90
91
  userName?: string;
91
92
  userAvatarUrl?: string;
93
+ /** Not awaited internally despite the Promise signature — drive switchingOrgIds yourself. */
92
94
  onSetDefault?: (orgId: number) => void | Promise<void>;
95
+ /** Same as onSetDefault — not awaited internally; respondingOrgIds is entirely consumer-managed. */
93
96
  onAcceptInvite?: (orgId: number) => void | Promise<void>;
94
97
  onDeclineInvite?: (orgId: number) => void | Promise<void>;
95
98
  /**
@@ -107,6 +110,7 @@ export interface OrganizationDetailsProps {
107
110
  onCreateOrganization?: (values: CreateOrganizationValues) => void | Promise<void>;
108
111
  /** Called when the user confirms a new name for an organization */
109
112
  onEditOrganization?: (orgId: number, newName: string) => void | Promise<void>;
113
+ /** Back icon renders only when this is provided, not merely disabled when omitted. */
110
114
  onBack?: () => void;
111
115
  footerSlot?: ReactNode;
112
116
  labels?: OrganizationDetailsLabels;
@@ -1,4 +1,5 @@
1
1
  import React from "react";
2
2
  import { RolesPermissionProps } from "./RolesPermissionProps";
3
+ /** Role list + role/permission-matrix form in one component (switch via `view`). */
3
4
  declare const RolesPermission: React.FC<RolesPermissionProps>;
4
5
  export default RolesPermission;
@@ -56,6 +56,7 @@ const DEFAULT_KEYS = [
56
56
  "import",
57
57
  "export",
58
58
  ];
59
+ /** Role list + role/permission-matrix form in one component (switch via `view`). */
59
60
  const RolesPermission = ({ view, mode = "create", roles, isRolesLoading = false, permissions, permissionKeys = DEFAULT_KEYS, roleName, roleNameError, isSuperAdmin, isTrackLocation, isShowRecords, isEditing = false, isSaving = false, onNewRole, onViewRole, onEditRole, onDeleteRole, onBack, onRoleNameChange, onToggleSuperAdmin, onToggleTrackLocation, onToggleShowRecords, onPermissionChange, onSave, onCancelForm, footerSlot, checkIcon, labels: labelOverrides, padding = "16px", }) => {
60
61
  const { colors } = (0, useCustomTheme_1.useCustomTheme)();
61
62
  const labels = (0, react_1.useMemo)(() => ({ ...DEFAULT_LABELS, ...labelOverrides }), [labelOverrides]);
@@ -21,6 +21,7 @@ export type RoleData = {
21
21
  permission: Permission[];
22
22
  /** Coerced via Number() before reaching onDeleteRole — a non-numeric id silently becomes NaN with no error. */
23
23
  roles_id: string;
24
+ /** designation/makeSuperAdmin/automation/trackLocation/show_records: never read by this component — pass-through only, for the consumer to prefill its own form state on edit/view. */
24
25
  designation: string;
25
26
  makeSuperAdmin?: boolean;
26
27
  automation?: boolean;
@@ -83,9 +84,10 @@ export interface RolesPermissionProps {
83
84
  permissions: Permission[];
84
85
  /** Columns rendered in the matrix. Defaults to all non-automation keys. */
85
86
  permissionKeys?: PermissionKey[];
86
- /** Form field values (controlled). */
87
+ /** Form field values — fully controlled, no internal state; edits are invisible without the matching handler below. */
87
88
  roleName: string;
88
89
  roleNameError?: string;
90
+ /** Toggling this does not itself grant matrix permissions — it's cosmetic until the consumer applies that logic. */
89
91
  isSuperAdmin: boolean;
90
92
  isTrackLocation: boolean;
91
93
  isShowRecords: boolean;
@@ -99,14 +101,17 @@ export interface RolesPermissionProps {
99
101
  onEditRole?: (role: RoleData) => void;
100
102
  /** Called synchronously right before the modal closes — no await, no loading state; errors must be surfaced outside this flow. */
101
103
  onDeleteRole?: (roleId: number) => void;
104
+ /** Back icon renders only when this is provided, not merely disabled when omitted. */
102
105
  onBack?: () => void;
103
106
  /** Form actions. */
104
107
  onRoleNameChange?: (value: string) => void;
105
108
  onToggleSuperAdmin?: (checked: boolean) => void;
106
109
  onToggleTrackLocation?: (checked: boolean) => void;
107
110
  onToggleShowRecords?: (checked: boolean) => void;
111
+ /** Fires with key "automation" (not "read") for a module named "automation" — see Permission.module. */
108
112
  onPermissionChange?: (module: string, key: PermissionKey) => void;
109
113
  onSave?: () => void;
114
+ /** Header back icon renders only when set; the footer Cancel button always renders and no-ops without it. */
110
115
  onCancelForm?: () => void;
111
116
  /** App-specific sections rendered under the roles list (e.g. ModuleDelete, SignInActivity). */
112
117
  footerSlot?: ReactNode;
@@ -2,12 +2,19 @@ import React, { ReactNode } from "react";
2
2
  import { ScrollbarVariant } from "../../Theme/tokens/builders/scrollbar";
3
3
  export interface ScrollbarBoxProps {
4
4
  children: ReactNode;
5
+ /** Fixed box height; omit to let content size the box instead of scrolling it. */
5
6
  height?: string;
7
+ /** Caps growth and enables scrolling; without it the box grows unbounded. */
6
8
  maxHeight?: string;
9
+ /** No default (unlike overflowY) — falls through to the browser's normal overflow. */
7
10
  overflowX?: string;
11
+ /** Defaults to "auto" — scrolls only once content exceeds height/maxHeight. */
8
12
  overflowY?: string;
13
+ /** Picks the scrollbar chrome from scrollbarStyles; see scrollbar.ts for what each looks like. */
9
14
  variant?: ScrollbarVariant;
15
+ /** Forwarded to the underlying Box so a consumer can read/scroll the container from outside. */
10
16
  scrollContainerRef?: React.Ref<HTMLDivElement> | null;
11
17
  }
18
+ /** Scrollable Box with themed scrollbar chrome (scrollbarStyles) applied via variant. */
12
19
  declare const ScrollbarBox: React.FC<ScrollbarBoxProps>;
13
20
  export default ScrollbarBox;
@@ -4,6 +4,7 @@ const jsx_runtime_1 = require("react/jsx-runtime");
4
4
  const react_1 = require("@chakra-ui/react");
5
5
  const useCustomTheme_1 = require("../../Theme/useCustomTheme");
6
6
  const scrollbar_1 = require("../../Theme/tokens/builders/scrollbar");
7
+ /** Scrollable Box with themed scrollbar chrome (scrollbarStyles) applied via variant. */
7
8
  const ScrollbarBox = ({ children, height, maxHeight, overflowX, overflowY = "auto", variant = "default", scrollContainerRef, }) => {
8
9
  const { colors } = (0, useCustomTheme_1.useCustomTheme)();
9
10
  return ((0, jsx_runtime_1.jsx)(react_1.Box, { ref: scrollContainerRef, height: height, maxHeight: maxHeight, position: "relative", sx: { overflowX, overflowY, ...(0, scrollbar_1.scrollbarStyles)(colors, variant) }, children: children }));
@@ -2,58 +2,76 @@
2
2
  export type SearchSelectProps = {
3
3
  id?: string;
4
4
  label?: string;
5
+ /** Filtered against option.label only — a custom `view` node's visible text isn't searchable. */
5
6
  options: Options[];
7
+ /** Required for selections to stick — the component is fully controlled, no internal selected state. */
6
8
  onSelect?: (options: Options | Options[] | undefined) => void;
9
+ /** Fires 1s after typing stops; local filtering against `options` already runs synchronously regardless. */
7
10
  onSearch?: (value: string) => void;
8
11
  isOptionLoading?: boolean;
12
+ /** Overrides rightIcon — replaces it with a spinner in the trailing slot whenever true. */
9
13
  isLoading?: boolean;
10
14
  loadingText?: string;
11
15
  placeholder?: string;
12
16
  value?: Options[] | Options;
17
+ /** Only seeds the initial input text at mount — later prop changes don't resync the input. */
13
18
  searchQuery?: string;
14
19
  isMultiple?: boolean;
20
+ /** Visual-only — shows the required asterisk on the label; doesn't block selection or submission. */
15
21
  isRequired?: boolean;
16
22
  error?: boolean;
23
+ /** Only rendered when `error` is true — setting this alone shows nothing. */
17
24
  errorMessage?: string;
25
+ /** Hidden whenever `error` is true — mutually exclusive with errorMessage. */
18
26
  helperText?: string;
19
27
  width?: string | number;
28
+ /** Only sets the insideSelect segment's height, not the main field's — that's driven by `size`. */
20
29
  height?: string | number;
21
30
  size?: "xs" | "sm" | "md" | "lg";
22
31
  chip?: {
23
32
  /** 0 is falsy and falls back to "no limit" (shows every chip) — pass 1+ to actually cap the count. */
24
33
  maxChips?: number;
25
34
  maxText?: number;
35
+ /** Also gates the chip's remove (X) icon — omit it and chips can't be removed via the chip itself. */
26
36
  onClick?: (options: Options | Options[]) => void;
27
37
  };
28
38
  information?: {
29
39
  isInformation?: boolean;
30
40
  informationMessage?: string;
31
41
  };
42
+ /** Wins over `information.isInformation` when both are set; both this and informationMessage must be truthy to show the icon. */
32
43
  isInformation?: boolean;
33
44
  informationMessage?: string;
34
45
  rightIcon?: {
46
+ /** Must be a rendered element (`<Icon />`); anything else fails isValidElement and falls back to the toggle chevron. */
35
47
  icon?: React.ReactNode;
36
48
  onClick?: () => void;
37
49
  };
38
50
  addNew?: {
51
+ /** Must be explicitly true — icon/text/onClick alone render nothing. */
39
52
  enabled: boolean;
40
53
  icon?: React.ReactNode;
41
54
  text?: string;
42
55
  onClick?: () => void;
43
56
  };
44
57
  isRemoveAllIcon?: boolean;
58
+ /** Ignored entirely unless `isMultiple` is also true. */
45
59
  isSelectAll?: boolean;
46
60
  pagination?: {
47
61
  /** startIndex is 1-based (current options.length + 1), not a 0-based offset. */
48
62
  onScroll?: (startIndex: number, limit: number, query: string) => void;
63
+ /** Also used to guess whether more pages exist (options.length % limit === 0) — an exact-multiple total triggers one extra scroll fetch. */
49
64
  limit?: number;
65
+ /** Set this synchronously while a page request is in flight, or fast scrolling can re-fire onScroll for the same page. */
50
66
  scrollLoading?: boolean;
51
67
  };
52
68
  /** Not implemented — the option list always renders unvirtualized; use `pagination` to page in large datasets instead. */
53
69
  virtualization?: boolean;
54
70
  insideSelect?: {
55
71
  onSelect?: (options: Options) => void;
72
+ /** In isMultiple mode, its `id` is stamped onto every newly selected main option as `insideSelectId`. */
56
73
  value?: Options;
74
+ /** The nested picker's own option list — distinct from the top-level `options`, singular name despite being an array. */
57
75
  option?: Options[];
58
76
  width?: string;
59
77
  /** Shown when no value is selected. Defaults to "Select". */
@@ -16,48 +16,35 @@ export type SidebarProps = {
16
16
  handleSecondaryNavClick?: (menu: MenuProps) => void;
17
17
  toggle: boolean;
18
18
  changeToggle: () => void;
19
+ /** Falls back to a rendered brand mark (DefaultLogo) tinted by primary color when omitted. */
19
20
  logo?: string;
20
21
  companyName: string;
21
22
  companySubtitle?: string;
23
+ /** Footer identity block is omitted entirely (not just simplified) when this is not provided. */
22
24
  user?: SidebarUser;
25
+ /** true hides the Add New row completely, rather than disabling it. */
23
26
  isDisableAddNew?: boolean;
24
27
  onAddNewClick?: () => void;
28
+ /** Threaded down to MenuItemBox but never read there — currently has no effect. */
25
29
  selectedSubMenu?: string | null;
26
30
  selectedSecondaryItem?: string | number | null;
31
+ /** Shows skeleton rows instead of MenuItems; header and footer render normally. */
27
32
  isLoading?: boolean;
33
+ /** Defaults to 15 when isLoading is true; ignored otherwise. */
28
34
  loadingLines?: number;
29
35
  /** Not a direct render switch — on change it calls `changeToggle()` once; nothing collapses unless that updates `toggle`. */
30
36
  open?: boolean;
37
+ /** Legacy "Switch app" grid — AppSwitcher supersedes it; avoid wiring both into one shell. */
31
38
  otherApps?: OtherAppsProps['otherApps'];
32
- /**
33
- * Below the `lg` breakpoint the sidebar renders as a slide-in overlay above
34
- * the content (it does not occupy layout space). `mobileOpen` controls that
35
- * overlay's visibility; it has no effect at `lg` and up, where the sidebar is
36
- * always inline. Wire it to the NavigationBar hamburger (`onSideBarToggole`).
37
- */
39
+ /** Controls the overlay's visibility below `lg`; no effect once inline at `lg`+. Wire to NavigationBar's `onSideBarToggole`. */
38
40
  mobileOpen?: boolean;
39
41
  /** Called when the overlay is dismissed (backdrop click, Esc, close button, or swipe). */
40
42
  onMobileClose?: () => void;
41
- /**
42
- * Forces the "mobile navbar" presentation at ANY width: the sidebar leaves the
43
- * inline layout and behaves as the slide-in overlay (hamburger + full-screen
44
- * content), exactly like below `lg` — but on big screens too. This is a layout
45
- * switch, not a close: toggling it never hides the navigation, it only changes
46
- * how it is presented. When `false` the breakpoint alone decides (inline at
47
- * `lg`+, overlay below `lg`).
48
- */
43
+ /** Forces overlay presentation at any width — a layout switch, not a close; never hides navigation. */
49
44
  mobileNav?: boolean;
50
- /**
51
- * Handler for the footer Hide/Show control that flips `mobileNav`. Render the
52
- * control only when provided. Wire it so entering mobile-nav also opens the
53
- * overlay (keeps the sidebar visible) and leaving it returns to the docked
54
- * sidebar — see the playground for the canonical wiring.
55
- */
45
+ /** Backs the footer Hide/Show control; render it only when this is provided. */
56
46
  onToggleMobileNav?: () => void;
57
- /**
58
- * Overlay peek: the sidebar shows without pinning, and closes itself when the pointer
59
- * leaves the panel. Wire to `NavigationBar`'s `onSideBarPeek`.
60
- */
47
+ /** Shows the sidebar without pinning — closes on pointer-leave. Wire to NavigationBar's `onSideBarPeek`. */
61
48
  peekOpen?: boolean;
62
49
  onPeekEnd?: () => void;
63
50
  };
@@ -66,18 +53,26 @@ export type MenuProps = {
66
53
  id: string | number;
67
54
  title: string;
68
55
  icon?: ElementType;
56
+ /** Ignored when subMenu is non-empty — the row becomes a toggle button instead of a link. */
69
57
  url: string;
70
58
  disabled?: boolean;
59
+ /** Shows a lock icon only — does not block the click handler; pair with `disabled` to prevent it. */
71
60
  locked?: boolean;
61
+ /** Runtime also accepts a bare number/string (legacy shorthand) though the type only declares the object shape. */
72
62
  badge?: {
63
+ /** Also triggers the small red dot on the icon when the rail is collapsed. */
73
64
  count?: number;
65
+ /** Chakra colorScheme name; defaults to "teal". */
74
66
  color?: string;
67
+ /** Chakra borderRadius value; defaults to "full". */
75
68
  radius?: string | number;
69
+ /** Chakra Badge variant; defaults to "subtle". */
76
70
  variant?: string;
77
71
  };
78
72
  subMenu?: MenuProps[];
79
73
  /** Non-empty on the active menu auto-collapses the main rail and renders a SecondaryBar, regardless of the `toggle` prop. */
80
74
  secondaryItems?: MenuProps[];
75
+ /** First item with a new value renders a section label plus divider; items must be pre-sorted by group. */
81
76
  group?: string;
82
77
  };
83
78
  /** Props for the internal MenuItems renderer — a narrowed slice of SidebarProps. */
@@ -92,24 +87,34 @@ export type RenderMenuType = {
92
87
  /** Secondary flyout panel props; `defaultCollapsed` only seeds initial state, then the panel self-manages it. */
93
88
  export type SecondaryBarProps = {
94
89
  items?: MenuProps[];
90
+ /** Defaults to true (collapsed) when omitted. */
95
91
  defaultCollapsed?: boolean;
92
+ /** Defaults to "3.5rem". */
96
93
  collapsedWidth?: string | number;
94
+ /** Defaults to "10rem". */
97
95
  expandedWidth?: string | number;
98
96
  headerFontSize?: string;
99
97
  itemFontSize?: string;
98
+ /** Matched by string equality against either the item's id or title, whichever matches. */
100
99
  selected?: string | number | null;
101
100
  onItemClick?: (item: MenuProps) => void;
101
+ /** Also used as the collapsed-state tooltip label. */
102
102
  title?: string;
103
+ /** Shown only in the expanded header — hidden entirely while collapsed. */
103
104
  icon?: ElementType;
104
105
  };
105
106
  /** "Switch app" footer grid; becomes hover popovers when the sidebar is collapsed. */
106
107
  export type OtherAppsProps = {
107
108
  toggle: boolean;
108
109
  otherApps: {
110
+ /** Used as the React list key — must be unique among otherApps entries. */
109
111
  name: string;
112
+ /** Fills the fallback dot (no icon) and its glow — ignored when `icon` is provided. */
110
113
  color: string;
114
+ /** Shown only in the collapsed-state hover flyout, never in the expanded grid cell. */
111
115
  description?: string;
112
116
  onClick: () => void;
117
+ /** A pre-rendered ReactNode, unlike MenuProps.icon (a component reference). */
113
118
  icon?: React.ReactNode;
114
119
  }[];
115
120
  };
@@ -9,7 +9,9 @@ export type StageState = "completed" | "active" | "upcoming";
9
9
  export type StageVariant = "chevron" | "bar" | "pills" | "stepper";
10
10
  /** One entry in StageProgressProps.stages — the ordered pipeline this tracker renders. */
11
11
  export interface Stage {
12
+ /** Compared to `value` via strict `===`; a numeric id vs a string `value` never matches. */
12
13
  id: string | number;
14
+ /** Truncates with an ellipsis (or a tooltip) under chevron/bar/pills; wraps to 2 lines under stepper. */
13
15
  label: string;
14
16
  /** Disable selecting this stage individually. */
15
17
  disabled?: boolean;
@@ -24,7 +26,9 @@ export interface StageProgressProps {
24
26
  value?: string | number;
25
27
  /** Skipped when isReadOnly, or when that specific stage's own `disabled` is true. */
26
28
  onChange?: (id: string | number, stage: Stage, index: number) => void;
29
+ /** Default "md"; also sets the loading skeleton's row height. */
27
30
  size?: StageSize;
31
+ /** Default "primary"; resolved per stage via resolveStagePalette, not applied directly. */
28
32
  colorScheme?: StageColorScheme;
29
33
  /** Render stages before the active one in a distinct "done" style. Default true. */
30
34
  markCompleted?: boolean;
@@ -43,50 +47,79 @@ export interface StageProgressProps {
43
47
  }
44
48
  /** Props for one chevron/bar/pills stage; variant="stepper" renders StepperStage/StepperStageProps instead. */
45
49
  export interface StageItemProps {
50
+ /** Ellipsis-truncates in the fixed-width box; see tooltipThreshold for when a tooltip also appears. */
46
51
  label: string;
52
+ /** 0-based position; with total, picks the chevron's first/last point shape. */
47
53
  index: number;
54
+ /** Stage count; with index, drives first/last chevron-point and bar-corner rounding. */
48
55
  total: number;
49
56
  state: StageState;
50
57
  /** "chevron" | "bar" | "pills" (stepper has its own renderer). */
51
58
  variant?: Exclude<StageVariant, "stepper">;
59
+ /** Default "md"; keys this stage's own pixel/spacing lookup table. */
52
60
  size?: StageSize;
61
+ /** Default "primary"; passed straight into resolveStagePalette for this stage. */
53
62
  colorScheme?: StageColorScheme;
63
+ /** Called with no args — StageProgress wraps id/stage/index into this closure itself. */
54
64
  onClick?: () => void;
65
+ /** Disables all interactivity without dimming opacity (unlike disabled). */
55
66
  isReadOnly?: boolean;
67
+ /** Disables just this stage and dims it to 0.55 opacity. */
56
68
  disabled?: boolean;
69
+ /** Adds a check icon before the label only when this stage is completed. */
57
70
  showCheck?: boolean;
71
+ /** Falls back to this size's own fixed minW when unset, not to content width. */
58
72
  minWidth?: string;
73
+ /** Only scrolls when this item's own state is "active" — a no-op otherwise. */
59
74
  scrollIntoViewWhenActive?: boolean;
75
+ /** Character count (not pixels) above which the label swaps to a hover tooltip. */
60
76
  tooltipThreshold?: number;
61
77
  }
62
78
  /** Props for one stepper-variant node; leftDone/rightDone fill the connector line per side. */
63
79
  export interface StepperStageProps {
80
+ /** Wraps up to 2 lines (noOfLines=2) instead of truncating; ignores tooltipThreshold entirely. */
64
81
  label: string;
65
82
  /** 1-based step number shown inside the circle. */
66
83
  number: number;
67
84
  state: StageState;
85
+ /** Default "md"; keys this node's own circle/font/minWidth lookup table. */
68
86
  size?: StageSize;
87
+ /** Default "primary"; passed straight into resolveStagePalette for this node. */
69
88
  colorScheme?: StageColorScheme;
89
+ /** Called with no args — StageProgress's own onChange(id, stage, index) is wrapped upstream. */
70
90
  onClick?: () => void;
91
+ /** Disables interactivity without dimming opacity (unlike disabled). */
71
92
  isReadOnly?: boolean;
93
+ /** Disables this node and dims it to 0.55 opacity. */
72
94
  disabled?: boolean;
95
+ /** Defaults true here (unlike StageItem's false); StageProgress always overrides it explicitly. */
73
96
  showCheck?: boolean;
97
+ /** Hides (not shortens) the left connector line entirely, regardless of leftDone. */
74
98
  isFirst: boolean;
99
+ /** Hides (not shortens) the right connector line entirely, regardless of rightDone. */
75
100
  isLast: boolean;
76
101
  /** Connector entering this node is part of a completed segment. */
77
102
  leftDone: boolean;
78
103
  /** Connector leaving this node is part of a completed segment. */
79
104
  rightDone: boolean;
105
+ /** Only scrolls when this node's own state is "active" — a no-op otherwise. */
80
106
  scrollIntoViewWhenActive?: boolean;
81
107
  }
82
108
  /** Color set for one scheme's states, returned by resolveStagePalette (soft/strong/muted + text). */
83
109
  export interface StagePalette {
110
+ /** Background for "completed" stages, and the active stepper circle's outer glow ring. */
84
111
  soft: string;
112
+ /** Text/icon color for "completed" stages, contrast-walked against soft, not a fixed rung. */
85
113
  softText: string;
114
+ /** Background for "active" stages, and the hover fill for completed/upcoming stages. */
86
115
  strong: string;
116
+ /** Text/icon color on strong; picked between white/black per scheme to clear AA. */
87
117
  onStrong: string;
118
+ /** Hover-only background for an already-"active" stage; other states hover to strong instead. */
88
119
  hover: string;
120
+ /** Background for "upcoming" stages; also the unfilled stepper circle's border and idle connector line. */
89
121
  muted: string;
122
+ /** Text color for "upcoming" stages, chevron/bar/pills and stepper alike. */
90
123
  mutedText: string;
91
124
  }
92
125
  /** Resolve a chevron palette for a given color scheme from the theme. */
@@ -1,2 +1,3 @@
1
1
  import { TableProps } from "./TableProps";
2
+ /** Data table: virtualized-height rows, pagination, filters, selection, and an optional Monday-style grouped board. */
2
3
  export default function Table({ data, columns, onSelection, isLoading, isCheckbox, headerBgColor, freezedBgColor, freezedTextColor, tableBorderColor, noBorders, isPagination, onRowClick, selections, isActionFreeze, preferences, paginationMode, infiniteScroll, hasMore, isLoadingMore, groupLoadMore, loadMoreText, loadMorePosition, loadMoreChunkSize, noOfRowsPerPage, totalRecords, onPagination, isTableSettings, headerActions, onGlobalSearch, onNoOfRowsPerPageChange, paginationSelectOptions, tableMaxHeight, minVisibleRows, maxVisibleRows, autoFitViewport, tableSettings, filterSidebar, loadingSkeletonRows, defaultVisibleColumns, density, variant, stripe, groupColors, onAddItem, emptyState, onRefresh, }: TableProps): import("react/jsx-runtime").JSX.Element;
@@ -32,6 +32,7 @@ const Button_1 = __importDefault(require("../Button/Button"));
32
32
  const ToolTip_1 = __importDefault(require("../ToolTip/ToolTip"));
33
33
  const lucide_react_1 = require("lucide-react");
34
34
  const MotionBox = (0, framer_motion_1.motion)(react_2.Box);
35
+ /** Data table: virtualized-height rows, pagination, filters, selection, and an optional Monday-style grouped board. */
35
36
  function Table({ data, columns, onSelection, isLoading, isCheckbox = false, headerBgColor, freezedBgColor, freezedTextColor, tableBorderColor, noBorders = false, isPagination = true, onRowClick, selections, isActionFreeze = true, preferences = {
36
37
  url: "",
37
38
  token: "",
@@ -18,17 +18,25 @@ export type TableEmptyState = {
18
18
  export type TableProps = {
19
19
  data: DataObject[];
20
20
  columns: TableHeaderProps[];
21
+ /** Hex override per group value; wins over the auto-assigned palette color. Only visible while grouped (Settings > Group). */
21
22
  groupColors?: Record<string | number, string>;
23
+ /** Renders a "+ add item" control in each group's footer row; no-op in flat (ungrouped) mode. */
22
24
  onAddItem?: (groupValue: string | number) => void;
25
+ /** Seeds the initial row height only — Table Settings > Density (or saved preferences.density) takes over after the first change. */
23
26
  density?: TableDensity;
24
27
  /** Visual preset. Defaults to `classic` — the table exactly as it shipped. */
25
28
  variant?: TableVariant;
29
+ /** Accepted and forwarded to TableBody but never read there — no visual effect (see COMPONENT-GOTCHAS.md). */
26
30
  stripe?: boolean;
27
31
  emptyState?: TableEmptyState | ReactNode;
32
+ /** Dead prop — Table renders no export UI and never reads this; declared for a feature that was never wired up. */
28
33
  handleExportChange?: (value: string) => void | undefined;
34
+ /** Dead prop — same unwired export feature as handleExportChange/exportLabel. */
29
35
  exportOptions?: ExportOption[];
36
+ /** Dead prop — same unwired export feature as handleExportChange/exportOptions. */
30
37
  exportLabel?: string;
31
38
  isLoading?: boolean;
39
+ /** sic — misspelling of isVisibility, kept for backward compat. Dead: Table never destructures it, so it has no effect. */
32
40
  isVisiblity?: boolean;
33
41
  isCheckbox?: boolean;
34
42
  headerBgColor?: string;
@@ -41,7 +49,9 @@ export type TableProps = {
41
49
  selections?: (string | number)[];
42
50
  /** Fires per cell, gated on the column: a column with `node` swallows its clicks. */
43
51
  onRowClick?: (row: DataObject, header: Record<string | number, string | number>) => void;
52
+ /** Sticky-positions the trailing action/link column during horizontal scroll. Defaults true. */
44
53
  isActionFreeze?: boolean;
54
+ /** "server" skips client-side slicing entirely — the parent must supply totalRecords and drive paging via onPagination. */
45
55
  paginationMode?: "client" | "server";
46
56
  infiniteScroll?: boolean;
47
57
  hasMore?: boolean;
@@ -54,24 +64,34 @@ export type TableProps = {
54
64
  loadMoreChunkSize?: number;
55
65
  noOfRowsPerPage?: number;
56
66
  totalRecords?: number;
67
+ /** record is the page's last row on "next"/"last", its first row on "prev"/"first" — a cursor for server paging. */
57
68
  onPagination?: (page: number, noOfRecords: number, record: DataObject | undefined, direction: "next" | "prev" | "first" | "last") => void;
58
69
  onNoOfRowsPerPageChange?: (noOfRows: number) => void;
59
70
  paginationSelectOptions?: (number | string)[];
71
+ /** Explicit pixel height; overrides autoFitViewport and minVisibleRows/maxVisibleRows outright when set. */
60
72
  tableMaxHeight?: number;
73
+ /** Floors the auto-computed row count used for sizing only — doesn't add rows or affect pagination. */
61
74
  minVisibleRows?: number;
75
+ /** Caps the auto-computed row count used for sizing (paired with minVisibleRows); ignored once tableMaxHeight is set. */
62
76
  maxVisibleRows?: number;
77
+ /** Further clamps computed height to remaining viewport space below the table, recalculated on resize; ignored once tableMaxHeight is set. */
63
78
  autoFitViewport?: boolean;
79
+ /** Hides columns past this index on first render only — a saved preferences.columns list (or a Settings save) wins on every later render. */
64
80
  defaultVisibleColumns?: number;
65
81
  loadingSkeletonRows?: number;
66
82
  headerActions?: HeaderActionsProps;
67
83
  onGlobalSearch?: (searchVal: string) => void;
84
+ /** Dead prop — Table.tsx has it commented out of its own destructure; never called. */
68
85
  onColumnFilter?: (filters: FilterValues) => void;
86
+ /** Gates the Settings gear (Density / Manage Columns / Group) — the real switch for column-visibility UI, unlike tableSettings or isVisiblity. */
69
87
  isTableSettings?: boolean;
88
+ /** Dead prop — TableSettings receives it but never destructures it; these fields currently do nothing. */
70
89
  tableSettings?: {
71
90
  filters?: string[];
72
91
  filterSelected?: string[];
73
92
  onFilterSelection?: (filters: string[]) => void;
74
93
  };
94
+ /** filterMode defaults to "sidebar"; Clear All in "modal" mode doesn't re-apply filters (see COMPONENT-GOTCHAS.md). */
75
95
  filterSidebar?: Partial<FilterSidebarProps> & {
76
96
  isFilterSidebar?: boolean;
77
97
  handleSidebarFilterClick?: (filters: FilterValues) => void;
@@ -79,12 +99,19 @@ export type TableProps = {
79
99
  isApplyLoading?: boolean;
80
100
  filterMode?: "sidebar" | "modal";
81
101
  };
102
+ /** Server-persists columns/density/grouping as one JSON blob (GET on mount, POST on every Settings save). Omitting url (the default) makes it a silent no-op, not an error — the table just doesn't persist. */
82
103
  preferences?: {
104
+ /** Base REST endpoint for both GET and POST; empty string (the default) disables persistence entirely. */
83
105
  url: string;
106
+ /** Sent as a raw Authorization header value — not "Bearer "-prefixed. */
84
107
  token: string;
108
+ /** Distinguishes multiple saved blobs at the same url/page/name (e.g. per-view settings). */
85
109
  key?: string;
110
+ /** Sent alongside key/page as a query param — a server-side identifier, not rendered anywhere. */
86
111
  name?: string;
112
+ /** Identifies which page/screen owns this table's preferences; sent as a query param. */
87
113
  page?: string;
114
+ /** Scopes the preference blob per organization; sent on both GET and POST. */
88
115
  orgId?: string;
89
116
  };
90
117
  onRefresh?: () => void;
@@ -1,4 +1,5 @@
1
1
  import React from "react";
2
2
  import { UserDetailsProps } from "./UserDetailsProps";
3
+ /** Two-pane user directory + detail panel with bundled Add/Change-Role/Deactivate modals. */
3
4
  declare const UserDetails: React.FC<UserDetailsProps>;
4
5
  export default UserDetails;
@@ -85,6 +85,7 @@ const DEFAULT_LABELS = {
85
85
  deactivateConfirmQuestion: "Are you sure you want to deactivate this user?",
86
86
  deactivateConfirmDescription: "will no longer have access to the organization. You can reactivate them later if needed.",
87
87
  };
88
+ /** Two-pane user directory + detail panel with bundled Add/Change-Role/Deactivate modals. */
88
89
  const UserDetails = ({ users, selectedUser, selectedUserId, roleOptions = [], canManageUsers = false, isUsersLoading = false, isInviteLoading = false, isDeactivateLoading = false, isAddUserLoading = false, isChangeRoleLoading = false, onSelectUser, onRefresh, onBack, onAddUserSubmit, onChangeRoleSubmit, onReinvite, onDeactivate, onAddRoleClick, addUserUpgradeNotice, labels: labelOverrides, minHeight = "90vh", }) => {
89
90
  const { colors } = (0, useCustomTheme_1.useCustomTheme)();
90
91
  const labels = (0, react_1.useMemo)(() => ({ ...DEFAULT_LABELS, ...labelOverrides }), [labelOverrides]);
@@ -10,6 +10,7 @@ export type UserListItem = {
10
10
  firstName: string;
11
11
  lastName: string;
12
12
  email: string;
13
+ /** Display-only — UserDetails never reads this in the list row itself, only in SelectedUserDetail once selected. */
13
14
  role: string;
14
15
  profile?: string;
15
16
  isActive: boolean;
@@ -29,11 +30,15 @@ export type SelectedUserDetail = {
29
30
  /** When null, Change Role and Resend Invitation silently no-op on click (no disabled state) — unlike Deactivate, which greys out. */
30
31
  userId?: number;
31
32
  name: string;
33
+ /** Feeds ChangeRoleModal's currentRole — must case-insensitively match a roleOptions[].label or the modal opens with nothing pre-selected. */
32
34
  role: string;
35
+ /** Shown only inside ChangeRoleModal's header — the Personal Information panel does not render this field, only `details`. */
33
36
  email: string;
34
37
  profilePhoto?: string;
35
38
  isActive: boolean;
39
+ /** Renders the "Pending Invitation" badge only — does not affect which action buttons show. */
36
40
  isPending?: boolean;
41
+ /** Hides Resend Invitation and Deactivate (both gated on !isCurrent) and shows a "You" badge on the avatar. */
37
42
  isCurrent?: boolean;
38
43
  /** True hides the entire action bar (reinvite/change-role/deactivate), not just the deactivate button. */
39
44
  isSuperAdmin?: boolean;
@@ -106,6 +111,7 @@ export interface UserDetailsProps {
106
111
  canManageUsers?: boolean;
107
112
  /** Loading flags driven by the host app's async calls. */
108
113
  isUsersLoading?: boolean;
114
+ /** Spins only the Resend Invitation button, not the list or either modal. */
109
115
  isInviteLoading?: boolean;
110
116
  /** Unlike isAddUserLoading/isChangeRoleLoading, the confirm modal closes immediately on click — this flag can't keep it open to show a spinner. */
111
117
  isDeactivateLoading?: boolean;
@@ -113,12 +119,15 @@ export interface UserDetailsProps {
113
119
  isChangeRoleLoading?: boolean;
114
120
  /** Selection + refresh. */
115
121
  onSelectUser?: (user: UserListItem) => void;
122
+ /** Omitting this hides the refresh button entirely, not just disables it. */
116
123
  onRefresh?: () => void;
117
124
  /** Back navigation handler for the list panel header. */
118
125
  onBack?: () => void;
119
126
  /** Modal submit / action callbacks. */
120
127
  onAddUserSubmit?: (values: AddUserFormValues) => void | Promise<void>;
128
+ /** Awaited before the modal closes — unlike onDeactivate, which fires and closes immediately. */
121
129
  onChangeRoleSubmit?: (payload: ChangeRoleSubmitPayload) => void | Promise<void>;
130
+ /** Never called when selectedUser.userId is null — the button stays enabled but silently no-ops. */
122
131
  onReinvite?: (userId: number) => void;
123
132
  /** Not awaited — the confirm modal closes right after this fires, so a slow or failing deactivation gets no in-modal feedback. */
124
133
  onDeactivate?: (userId: number) => void;
@@ -140,12 +149,14 @@ export interface AddUserModalProps {
140
149
  onSubmit?: (values: AddUserFormValues) => void | Promise<void>;
141
150
  onAddRoleClick?: () => void;
142
151
  upgradeNotice?: ReactNode;
152
+ /** A strict subset of UserDetailsLabels — the merged defaults from UserDetails always satisfy it. */
143
153
  labels: Required<Pick<UserDetailsLabels, "addNewUser" | "firstName" | "lastName" | "email" | "role" | "firstNamePlaceholder" | "lastNamePlaceholder" | "emailPlaceholder" | "addNewRole" | "cancel" | "save" | "firstNameRequired" | "lastNameRequired" | "emailRequired" | "emailInvalid" | "roleRequired">>;
144
154
  }
145
155
  /** Reassigns one user's role only — Save stays disabled until a genuinely different role is picked (see currentRole below). */
146
156
  export interface ChangeRoleModalProps {
147
157
  isOpen: boolean;
148
158
  onClose: () => void;
159
+ /** Submit silently no-ops when null — Save disables only for isUnchanged/no-selection, not for this. */
149
160
  userId: number | null;
150
161
  email?: string;
151
162
  /** Matched to roleOptions by case-insensitive label text; no match silently pre-selects nothing and leaves Save disabled. */
@@ -161,7 +172,9 @@ export interface DeactivateConfirmModalProps {
161
172
  isOpen: boolean;
162
173
  onClose: () => void;
163
174
  userName?: string;
175
+ /** Effectively unusable — the modal always closes before an async confirm could flip this. */
164
176
  isLoading?: boolean;
177
+ /** Synchronous by type — the modal closes in the same tick this fires, so it can't be awaited. */
165
178
  onConfirm: () => void;
166
179
  labels: Required<Pick<UserDetailsLabels, "confirmDeactivation" | "deactivateConfirmQuestion" | "deactivateConfirmDescription" | "cancel" | "deactivateUser">>;
167
180
  }
@@ -4,6 +4,7 @@ import ReactApexChart from "react-apexcharts";
4
4
  import { useTheme } from "@chakra-ui/react";
5
5
  import { chartAxisLabelColor, getDefaultSeriesColors, mergeChartTitleStyle, } from "../../../Theme/tokens/builders/chartColorsFromTheme.js";
6
6
  import { baseAxisLabels, baseChart, baseGrid, baseLegend, baseTooltip } from "../chartBase.js";
7
+ /** Bar chart wrapper around react-apexcharts (horizontal/stacked/distributed via props), themed via chartColorsFromTheme + chartBase. */
7
8
  export default function ApexBarChart({ data, labels, title, titlePosition, height = 400, width = 500, barColor, xAxisStyle, yAxisStyle, titleStyle, horizontal = false, distributed = false, seriesName = "Data", series, stacked = false, showLegend, legendPosition = "bottom", }) {
8
9
  const theme = useTheme();
9
10
  const palette = theme.colors;
@@ -5,6 +5,7 @@ import { useTheme } from "@chakra-ui/react";
5
5
  import ToolTip from "../../ToolTip/ToolTip.js";
6
6
  import { getDefaultSeriesColors, mergeChartTitleStyle, } from "../../../Theme/tokens/builders/chartColorsFromTheme.js";
7
7
  import { baseAxisLabels, baseChart, baseGrid, baseTooltip } from "../chartBase.js";
8
+ /** Line chart wrapper around react-apexcharts, themed via chartColorsFromTheme + chartBase. */
8
9
  const ApexLineChart = ({ data, labels, title, height, width, lineColors, titlePosition = "center", titleStyle, compact = false, toolbarBreakpointPct = 0.6, titleClampLines, showTitleEllipsis = true, showSeries = true, series: seriesNames, variant = "basic", }) => {
9
10
  const theme = useTheme();
10
11
  const palette = theme.colors;
@@ -12,6 +12,7 @@ const getValidLegendPosition = (position) => {
12
12
  console.warn(`Invalid legend position: ${position}. Defaulting to 'bottom'.`);
13
13
  return "bottom";
14
14
  };
15
+ /** Pie/donut chart wrapper around react-apexcharts, themed via chartColorsFromTheme + chartBase. */
15
16
  const ApexPieChart = ({ data, labels, title, height = 400, width = 500, donutColors, chartColor, titlePosition = "center", titleStyle, legendPosition = "bottom", legendStyle, variant = "pie", showDataLabels = true, minLabelPercent = 8, surfaceColor, donutSize = "68%", totalLabel = "Total", labelPlacement = "auto", }) => {
16
17
  var _a;
17
18
  const { colors: palette } = useCustomTheme();
@@ -4,6 +4,7 @@ import ReactApexChart from "react-apexcharts";
4
4
  import { useTheme } from "@chakra-ui/react";
5
5
  import { chartInk, chartMode, getDefaultSeriesColors, mergeChartTitleStyle, } from "../../../Theme/tokens/builders/chartColorsFromTheme.js";
6
6
  import { baseChart, baseLegend, baseTooltip } from "../chartBase.js";
7
+ /** Polar-area chart wrapper around react-apexcharts, themed via chartColorsFromTheme + chartBase. */
7
8
  const ApexPolarChart = ({ data, labels, title, height = 400, width = 500, chartColors, titlePosition = "center", titleStyle, legendStyle, variant = "basic", }) => {
8
9
  const theme = useTheme();
9
10
  const palette = theme.colors;
@@ -48,6 +48,7 @@ const DEFAULT_LABELS = {
48
48
  copyright: "Pixelize Corp. All rights reserved.",
49
49
  termsOfService: "Terms of Service",
50
50
  };
51
+ /** Admin panel for the org list — rename/delete/create/invites/default; not a session switcher. */
51
52
  const OrganizationDetails = ({ activeOrganizations, invitedOrganizations, isLoading = false, switchingOrgIds = [], respondingOrgIds = [], editingOrgIds = [], isCreating = false, userName, userAvatarUrl, onSetDefault, onAcceptInvite, onDeclineInvite, onDeleteOrganization, onDeleteRequest, onCreateOrganization, onEditOrganization, onBack, footerSlot, labels: labelOverrides, }) => {
52
53
  const { colors } = useCustomTheme();
53
54
  const labels = useMemo(() => ({ ...DEFAULT_LABELS, ...labelOverrides }), [labelOverrides]);
@@ -51,6 +51,7 @@ const DEFAULT_KEYS = [
51
51
  "import",
52
52
  "export",
53
53
  ];
54
+ /** Role list + role/permission-matrix form in one component (switch via `view`). */
54
55
  const RolesPermission = ({ view, mode = "create", roles, isRolesLoading = false, permissions, permissionKeys = DEFAULT_KEYS, roleName, roleNameError, isSuperAdmin, isTrackLocation, isShowRecords, isEditing = false, isSaving = false, onNewRole, onViewRole, onEditRole, onDeleteRole, onBack, onRoleNameChange, onToggleSuperAdmin, onToggleTrackLocation, onToggleShowRecords, onPermissionChange, onSave, onCancelForm, footerSlot, checkIcon, labels: labelOverrides, padding = "16px", }) => {
55
56
  const { colors } = useCustomTheme();
56
57
  const labels = useMemo(() => ({ ...DEFAULT_LABELS, ...labelOverrides }), [labelOverrides]);
@@ -2,6 +2,7 @@ import { jsx as _jsx } from "react/jsx-runtime";
2
2
  import { Box } from "@chakra-ui/react";
3
3
  import { useCustomTheme } from "../../Theme/useCustomTheme.js";
4
4
  import { scrollbarStyles, } from "../../Theme/tokens/builders/scrollbar.js";
5
+ /** Scrollable Box with themed scrollbar chrome (scrollbarStyles) applied via variant. */
5
6
  const ScrollbarBox = ({ children, height, maxHeight, overflowX, overflowY = "auto", variant = "default", scrollContainerRef, }) => {
6
7
  const { colors } = useCustomTheme();
7
8
  return (_jsx(Box, { ref: scrollContainerRef, height: height, maxHeight: maxHeight, position: "relative", sx: { overflowX, overflowY, ...scrollbarStyles(colors, variant) }, children: children }));
@@ -26,6 +26,7 @@ import Button from "../Button/Button.js";
26
26
  import ToolTip from "../ToolTip/ToolTip.js";
27
27
  import { Filter, EllipsisVertical, X, RefreshCw } from "lucide-react";
28
28
  const MotionBox = motion(Box);
29
+ /** Data table: virtualized-height rows, pagination, filters, selection, and an optional Monday-style grouped board. */
29
30
  export default function Table({ data, columns, onSelection, isLoading, isCheckbox = false, headerBgColor, freezedBgColor, freezedTextColor, tableBorderColor, noBorders = false, isPagination = true, onRowClick, selections, isActionFreeze = true, preferences = {
30
31
  url: "",
31
32
  token: "",
@@ -47,6 +47,7 @@ const DEFAULT_LABELS = {
47
47
  deactivateConfirmQuestion: "Are you sure you want to deactivate this user?",
48
48
  deactivateConfirmDescription: "will no longer have access to the organization. You can reactivate them later if needed.",
49
49
  };
50
+ /** Two-pane user directory + detail panel with bundled Add/Change-Role/Deactivate modals. */
50
51
  const UserDetails = ({ users, selectedUser, selectedUserId, roleOptions = [], canManageUsers = false, isUsersLoading = false, isInviteLoading = false, isDeactivateLoading = false, isAddUserLoading = false, isChangeRoleLoading = false, onSelectUser, onRefresh, onBack, onAddUserSubmit, onChangeRoleSubmit, onReinvite, onDeactivate, onAddRoleClick, addUserUpgradeNotice, labels: labelOverrides, minHeight = "90vh", }) => {
51
52
  const { colors } = useCustomTheme();
52
53
  const labels = useMemo(() => ({ ...DEFAULT_LABELS, ...labelOverrides }), [labelOverrides]);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pixelize-design-library",
3
- "version": "2.4.2-beta.39",
3
+ "version": "2.4.2-beta.40",
4
4
  "description": "React component library for Pixelize apps: themeable Chakra-based components, design tokens and light/dark brand theming.",
5
5
  "keywords": [
6
6
  "react",