@commercelayer/app-elements 7.12.0 → 7.14.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (84) hide show
  1. package/dist/{CodeEditorComponent-lf915EGg.js → CodeEditorComponent-txM4ls17.js} +2 -2
  2. package/dist/{InputDateComponent-DD_fCyi_.js → InputDateComponent-C4QUlrmn.js} +2 -2
  3. package/dist/{RuleEngineComponent-CVD0pObW.js → RuleEngineComponent-dEe0FTBs.js} +266 -261
  4. package/dist/{en-CcBUYKzR.js → en-B-7ylwWx.js} +30 -1
  5. package/dist/{fetchCoreResourcesSuggestions-BS4pPkGo.js → fetchCoreResourcesSuggestions-DZuapPGj.js} +1 -1
  6. package/dist/helpers/numbers.d.ts +25 -0
  7. package/dist/helpers/numbers.test.d.ts +1 -0
  8. package/dist/hooks/useConfirmDialog.test.d.ts +1 -0
  9. package/dist/hooks/useOverlay.d.ts +9 -1
  10. package/dist/{it-y1Q1-MMT.js → it-BXPKgQsm.js} +30 -1
  11. package/dist/locales/en.d.ts +29 -0
  12. package/dist/{main-DIL89neT.js → main-Op1RV9MX.js} +23801 -19311
  13. package/dist/main.d.ts +9 -3
  14. package/dist/main.js +176 -165
  15. package/dist/mocks/data/core_schemas.d.ts +2 -0
  16. package/dist/mocks/data/event_stores.d.ts +2 -0
  17. package/dist/mocks/data/event_stores.test.d.ts +1 -0
  18. package/dist/{parseISO-CeYGLBle.js → parseISO-C1OS0R6q.js} +1 -1
  19. package/dist/providers/TokenProvider/MockTokenProvider.d.ts +1 -1
  20. package/dist/providers/TokenProvider/TokenProvider.d.ts +1 -1
  21. package/dist/style.css +1 -1
  22. package/dist/tailwind.global.css +8 -4
  23. package/dist/ui/atoms/AvatarLetter/AvatarLetter.d.ts +6 -1
  24. package/dist/ui/atoms/ButtonFilter.d.ts +17 -1
  25. package/dist/ui/atoms/Container.d.ts +10 -0
  26. package/dist/ui/atoms/PageHeading/PageHeading.d.ts +22 -4
  27. package/dist/ui/atoms/RadialProgress.d.ts +2 -2
  28. package/dist/ui/atoms/Section.d.ts +35 -0
  29. package/dist/ui/atoms/Spacer.d.ts +29 -4
  30. package/dist/ui/atoms/Stack.d.ts +48 -2
  31. package/dist/ui/atoms/Table/Table.d.ts +8 -0
  32. package/dist/ui/atoms/Tabs.d.ts +8 -0
  33. package/dist/ui/atoms/VisibilityTrigger.d.ts +19 -0
  34. package/dist/ui/atoms/VisibilityTrigger.test.d.ts +1 -0
  35. package/dist/ui/composite/Address.d.ts +9 -0
  36. package/dist/ui/composite/HomePageLayout.d.ts +3 -2
  37. package/dist/ui/composite/ListDetailsItem.d.ts +14 -1
  38. package/dist/ui/composite/PageLayout.d.ts +71 -1
  39. package/dist/ui/composite/PageLoading.d.ts +35 -0
  40. package/dist/ui/composite/PageLoading.test.d.ts +1 -0
  41. package/dist/ui/composite/PageSkeleton.d.ts +6 -0
  42. package/dist/ui/composite/Routes/LoadingPage.test.d.ts +1 -0
  43. package/dist/ui/forms/InputSelect/InputSelect.d.ts +8 -0
  44. package/dist/ui/internals/Overlay.test.d.ts +1 -0
  45. package/dist/ui/internals/bodyScrollLock.d.ts +2 -0
  46. package/dist/ui/internals/overlayContext.d.ts +36 -0
  47. package/dist/ui/resources/ResourceAddress/ResourceAddress.d.ts +12 -2
  48. package/dist/ui/resources/ResourceDetails/ResourceDetails.d.ts +9 -0
  49. package/dist/ui/resources/ResourceDetails/ResourceDetails.test.d.ts +1 -0
  50. package/dist/ui/resources/ResourceDetailsModal/ResourceAttributes.d.ts +11 -0
  51. package/dist/ui/resources/ResourceDetailsModal/ResourceDetailsContent.d.ts +43 -0
  52. package/dist/ui/resources/ResourceDetailsModal/ResourceDetailsContent.test.d.ts +1 -0
  53. package/dist/ui/resources/ResourceDetailsModal/ResourceEvents.d.ts +15 -0
  54. package/dist/ui/resources/ResourceDetailsModal/index.d.ts +2 -0
  55. package/dist/ui/resources/ResourceDetailsModal/resourceFields.d.ts +19 -0
  56. package/dist/ui/resources/ResourceDetailsModal/resourceFields.test.d.ts +1 -0
  57. package/dist/ui/resources/ResourceDetailsModal/useInfiniteScrollCursor.d.ts +39 -0
  58. package/dist/ui/resources/ResourceDetailsModal/useResourceDetailsModal.d.ts +23 -0
  59. package/dist/ui/resources/ResourceMetadata/ResourceMetadata.d.ts +9 -0
  60. package/dist/ui/resources/ResourceTags.d.ts +21 -1
  61. package/dist/ui/resources/ResourceTags.test.d.ts +1 -0
  62. package/dist/ui/resources/useResourceFilters/FieldOptionsSelect.d.ts +20 -0
  63. package/dist/ui/resources/useResourceFilters/FiltersBar.d.ts +64 -0
  64. package/dist/ui/resources/useResourceFilters/FiltersDrawer.d.ts +35 -0
  65. package/dist/ui/resources/useResourceFilters/FiltersSearchBar.d.ts +2 -2
  66. package/dist/ui/resources/useResourceFilters/activeFilters.d.ts +111 -0
  67. package/dist/ui/resources/useResourceFilters/activeFilters.test.d.ts +1 -0
  68. package/dist/ui/resources/useResourceFilters/types.d.ts +50 -0
  69. package/dist/ui/resources/useResourceFilters/useResourceFilters.d.ts +48 -0
  70. package/dist/ui/resources/useResourceFilters/utils.d.ts +10 -0
  71. package/dist/ui/resources/useResourceList/adaptMetricsOrderToCore.d.ts +5 -0
  72. package/dist/ui/resources/useResourceList/index.d.ts +1 -0
  73. package/dist/ui/resources/useResourceList/listFetcher.d.ts +7 -1
  74. package/dist/ui/resources/useResourceList/resourceListSignals.d.ts +46 -0
  75. package/dist/ui/resources/useResourceList/resourceListSignals.integration.test.d.ts +1 -0
  76. package/dist/ui/resources/useResourceList/resourceListSignals.test.d.ts +1 -0
  77. package/dist/ui/resources/useResourceList/useResourceList.d.ts +3 -1
  78. package/dist/ui/resources/useResourceTable/index.d.ts +2 -0
  79. package/dist/ui/resources/useResourceTable/types.d.ts +252 -0
  80. package/dist/ui/resources/useResourceTable/useResourceTable.d.ts +11 -0
  81. package/dist/ui/resources/useResourceTable/useResourceTable.test.d.ts +1 -0
  82. package/package.json +5 -3
  83. package/dist/ui/resources/useResourceList/VisibilityTrigger.d.ts +0 -8
  84. /package/dist/{ui/resources/useResourceList/VisibilityTrigger.test.d.ts → dictionaries/orders.test.d.ts} +0 -0
@@ -0,0 +1,252 @@
1
+ import { ListableResourceType, ResourceSortFields } from '@commercelayer/sdk';
2
+ import { FC, ReactNode } from 'react';
3
+ import { SectionProps } from '../../atoms/Section';
4
+ import { Resource } from '../useResourceList/listFetcher';
5
+ import { UseResourceListConfig } from '../useResourceList/useResourceList';
6
+ /**
7
+ * A single column definition for a `ResourceTable`.
8
+ *
9
+ * This is app-elements' own column type: TanStack Table is an implementation
10
+ * detail and its `ColumnDef` is intentionally not exposed here (see
11
+ * `docs/adr/0001-encapsulate-tanstack-table.md`).
12
+ */
13
+ export interface ResourceTableColumn<TResource extends ListableResourceType> {
14
+ /**
15
+ * Header content. A plain string or any node (icon, tooltip, …).
16
+ */
17
+ header: ReactNode;
18
+ /**
19
+ * Cell renderer for this column. Receives the fetched resource for the row
20
+ * and returns whatever should be displayed in the cell.
21
+ */
22
+ cell: (props: {
23
+ resource: Resource<TResource>;
24
+ }) => ReactNode;
25
+ /**
26
+ * Stable, unique column id.
27
+ * When omitted it falls back to `sortBy`, then to a positional `col-<index>`.
28
+ * Provide one explicitly when two columns would otherwise collide.
29
+ */
30
+ id?: string;
31
+ /**
32
+ * Horizontal alignment applied to both the header and the cells.
33
+ * @default 'left'
34
+ */
35
+ align?: "left" | "right" | "center";
36
+ /**
37
+ * What the column holds. Sets its width — as a share of the table, so it stays
38
+ * liquid — plus alignment and truncation, from one scale shared by every app
39
+ * (see `columnKindClassName`). Leave it off for the column that should absorb
40
+ * the leftover space: the name, email or SKU the row is about.
41
+ *
42
+ * Prefer this over `width`: it is what keeps a status column the same size in
43
+ * every app, and it makes the loading and loaded tables identical, since the
44
+ * widths no longer depend on the cell content.
45
+ */
46
+ kind?: ResourceTableColumnKind;
47
+ /**
48
+ * Escape hatch for a width `kind` cannot express, as a CSS class applied to
49
+ * the column header (e.g. `"w-1/2"`). Overrides the `kind` width.
50
+ *
51
+ * Note the table lays out with `table-layout: fixed`, so a class means what it
52
+ * says: a column narrower than its content clips rather than growing.
53
+ */
54
+ width?: string;
55
+ /**
56
+ * When this column starts being shown, overriding the default.
57
+ *
58
+ * By default a table shows only its first column on mobile — a phone has room
59
+ * for what the row is about and little else — and everything else from `md` up.
60
+ * Set this to widen or narrow that:
61
+ *
62
+ * - `"lg"` / `"xl"` — appear later than the default (a low-value column)
63
+ * - `"never"` — always visible, mobile included. For the one column that is the
64
+ * point of the table: a stock item's quantity, a price, a gift card balance.
65
+ *
66
+ * These are app-elements' own breakpoints (see `styles/global.css`, which resets
67
+ * Tailwind's defaults): `md` 768px, `lg` 992px, `xl` 1280px. There is
68
+ * deliberately no `sm`.
69
+ *
70
+ * The column's data is still fetched either way; only its rendering is
71
+ * suppressed, via CSS, so nothing shifts on resize.
72
+ */
73
+ hideBelow?: "md" | "lg" | "xl" | "never";
74
+ /**
75
+ * When set, the column becomes sortable and this value is the attribute it
76
+ * sorts by (e.g. `"created_at"`).
77
+ *
78
+ * Only attributes the API can actually sort by are accepted: the type is the
79
+ * resource's own sortable set, taken from the SDK (see `SortableAttribute`).
80
+ * Attributes reached through a relationship (`sku.code`, a market's name) are
81
+ * not sortable, so those columns stay static.
82
+ *
83
+ * On a `metricsQuery` table the value is a Metrics attribute instead
84
+ * (`"order.placed_at"`) — see `MetricsAttribute`.
85
+ *
86
+ * Sorting is server-side: the attribute goes into the SDK `sort` query param and
87
+ * the list refetches. Rows are never reordered client-side.
88
+ *
89
+ * Declaring it does not make the header interactive — table headers are inert.
90
+ * It marks the column as sortable and names the attribute, which is what a sort
91
+ * control outside the table reads to build its options.
92
+ */
93
+ sortBy?: SortableAttribute<TResource> | MetricsAttribute;
94
+ }
95
+ /**
96
+ * The kinds of column a resource table has, each with a width, an alignment and
97
+ * a truncation rule. Deliberately a short list: the point is that a status column
98
+ * is the same width in every app, which only holds if apps pick from a scale
99
+ * rather than sizing columns one by one.
100
+ *
101
+ * `text` is for the secondary strings a row carries — a market, a stock location,
102
+ * a customer, an origin. Without it they would split the leftover space evenly
103
+ * with the column the row is actually about, which is rarely what you want.
104
+ */
105
+ export type ResourceTableColumnKind = "text" | "code" | "status" | "datetime" | "amount" | "count" | "actions";
106
+ /**
107
+ * The attributes the API can sort a given resource by, straight from the SDK's
108
+ * `ResourceSortFields`. Every resource adds the shared `id`, `reference`,
109
+ * `reference_origin`, `created_at` and `updated_at` to its own set.
110
+ *
111
+ * This is the single source of truth for whether a column can be sortable: the
112
+ * API rejects anything else, and computed values (a status derived from several
113
+ * timestamps, a relationship's name) are not in it by definition.
114
+ */
115
+ export type SortableAttribute<TResource extends ListableResourceType> = Extract<keyof ResourceSortFields[TResource], string>;
116
+ /**
117
+ * A Metrics API sort attribute, always namespaced by its entity
118
+ * (`"order.placed_at"`). Metrics has its own attribute names, outside the SDK's
119
+ * resource types, so these can only be checked by shape — the dot is what tells
120
+ * them apart from a Core attribute.
121
+ */
122
+ export type MetricsAttribute = `${string}.${string}`;
123
+ /**
124
+ * SDK sort expression, e.g. `"created_at"` (asc) or `"-created_at"` (desc).
125
+ * `undefined` means no explicit table sort is applied.
126
+ */
127
+ export type ResourceTableSort<TResource extends ListableResourceType = ListableResourceType> = SortableAttribute<TResource> | `-${SortableAttribute<TResource>}` | MetricsAttribute | `-${MetricsAttribute}` | undefined;
128
+ export type UseResourceTableConfig<TResource extends ListableResourceType> = Omit<UseResourceListConfig<TResource>, "metricsQuery" | "query"> & {
129
+ /** The columns to render, in display order. */
130
+ columns: Array<ResourceTableColumn<TResource>>;
131
+ /**
132
+ * SDK query object, excluding `pageNumber` (handled internally) and
133
+ * `sort` (owned by the table's sorting state — set the initial sort with
134
+ * `sort` instead).
135
+ */
136
+ query?: Omit<NonNullable<UseResourceListConfig<TResource>["query"]>, "sort">;
137
+ /**
138
+ * When set, data is fetched from the Metrics API instead of the Core API.
139
+ *
140
+ * Sorting still works: a column's `sortBy` is sent as the metrics
141
+ * `search.sort_by` (so use metrics attribute names, e.g. `"order.placed_at"`)
142
+ * together with the matching `search.sort` direction — omit `search.sort_by`
143
+ * here and let the table own it.
144
+ */
145
+ metricsQuery?: {
146
+ search: {
147
+ limit?: number;
148
+ fields?: string[];
149
+ };
150
+ /**
151
+ * Metrics filters. When the table is rendered through
152
+ * `useResourceFilters`' `FilteredTable`, this is injected from the active
153
+ * filters and must not be set here.
154
+ */
155
+ filter?: Record<string, unknown>;
156
+ };
157
+ /**
158
+ * Optional row-level click handler. When provided the whole row becomes
159
+ * interactive (hover affordance + click). Use it to navigate with your
160
+ * app's router.
161
+ *
162
+ * The click event is passed as second argument, so it can be forwarded to
163
+ * helpers that need it (e.g. `navigateTo(...).onClick`).
164
+ */
165
+ onRowClick?: (resource: Resource<TResource>, event: React.MouseEvent<HTMLElement>) => void;
166
+ /**
167
+ * Return an href to make each row a real link (rendered as a stretched
168
+ * anchor over the row). This enables native link behavior — cmd/ctrl/middle
169
+ * click opens the row in a new tab, and the URL shows on hover.
170
+ *
171
+ * Combine with `onRowClick` for client-side navigation: a plain click calls
172
+ * `onRowClick` (and suppresses the default navigation), while modified
173
+ * clicks fall through to the browser. Return `undefined` to leave a row
174
+ * non-navigable.
175
+ *
176
+ * Note: avoid interactive elements in the first column when using this — the
177
+ * stretched anchor sits over the row (in-cell controls would need their own
178
+ * `relative`/`z-10` to stay clickable).
179
+ */
180
+ getRowHref?: (resource: Resource<TResource>) => string | undefined;
181
+ /**
182
+ * Controlled sort value (SDK sort expression, e.g. `"-created_at"`).
183
+ * Pass together with `onSortChange` to own the sort state (e.g. persist it
184
+ * in the URL). When omitted the table manages sort internally.
185
+ */
186
+ sort?: ResourceTableSort<TResource>;
187
+ /**
188
+ * Called when the sort changes. Provide together with `sort` for controlled
189
+ * mode; the callback receives the new SDK sort expression (or `undefined` when
190
+ * sorting is cleared).
191
+ */
192
+ onSortChange?: (sort: ResourceTableSort<TResource>) => void;
193
+ /**
194
+ * Initial sort used only when the table manages sort internally
195
+ * (uncontrolled). Ignored when `sort`/`onSortChange` are provided.
196
+ */
197
+ defaultSort?: ResourceTableSort<TResource>;
198
+ };
199
+ /** Props of the `ResourceTable` component returned by the hook. */
200
+ export interface ResourceTableProps {
201
+ /** Title. Can be a node or a function receiving the record count. */
202
+ title?: ((recordCount: number | undefined) => ReactNode) | ReactNode;
203
+ /** Action button rendered next to the title. */
204
+ actionButton?: SectionProps["actionButton"];
205
+ /**
206
+ * Rendered when the table has no rows.
207
+ * When omitted, a default message based on the resource name is shown.
208
+ */
209
+ emptyState?: ReactNode;
210
+ /** Force the title size. Defaults to `normal`. */
211
+ titleSize?: SectionProps["titleSize"];
212
+ /** `boxed` wraps the table in a bordered card. */
213
+ variant?: "boxed";
214
+ /**
215
+ * How the table behaves when its content is wider than the container.
216
+ * - `"fit"` (default): the table fills the container width; columns share the
217
+ * available space (and wrap/shrink). Pair with `hideBelow` on columns to
218
+ * drop low-value columns on small screens.
219
+ * - `"scroll"`: the table keeps its natural (unwrapped) width and scrolls
220
+ * horizontally inside its own container; the title/action button stay fixed.
221
+ * @default 'fit'
222
+ */
223
+ layout?: "fit" | "scroll";
224
+ }
225
+ export interface UseResourceTableReturn<TResource extends ListableResourceType> {
226
+ /** The component that renders the data table. */
227
+ ResourceTable: FC<ResourceTableProps>;
228
+ /** Prev/next pagination controls. Renders `null` unless in `pagination` mode with more than one page. */
229
+ Pagination: FC;
230
+ /** The rows currently displayed (current page, or accumulated in infinite mode). */
231
+ list?: Array<Resource<TResource>>;
232
+ /** SDK pagination metadata. */
233
+ meta?: import('../useResourceList/listFetcher').FetcherResponse<Resource<TResource>>["meta"];
234
+ isLoading: boolean;
235
+ isFirstLoading: boolean;
236
+ error?: string;
237
+ /** Removes a row from the UI only (call after a successful delete API call). */
238
+ removeItem: (resourceId: string) => void;
239
+ /** Clears fetched data and refetches from the first page. */
240
+ refresh: () => void;
241
+ hasMorePages?: boolean;
242
+ /** The active sort (SDK sort expression), whether controlled or internal. */
243
+ sort: ResourceTableSort<TResource>;
244
+ /**
245
+ * Sets the sort, for a control outside the table to drive — a field + direction
246
+ * picker, say. Table headers are inert (see `sortBy`).
247
+ *
248
+ * In controlled mode (`sort` + `onSortChange`) this calls `onSortChange` rather
249
+ * than holding state of its own.
250
+ */
251
+ setSort: (sort: ResourceTableSort<TResource>) => void;
252
+ }
@@ -0,0 +1,11 @@
1
+ import { ListableResourceType } from '@commercelayer/sdk';
2
+ import { UseResourceTableConfig, UseResourceTableReturn } from './types';
3
+ /**
4
+ * `useResourceTable` fetches a CommerceLayer resource type and renders it as a
5
+ * data table driven by a column model, backed by TanStack Table v9.
6
+ *
7
+ * It reuses `useResourceList`'s fetch/pagination layer verbatim and only
8
+ * replaces item rendering with a TanStack-driven table. Sorting, filtering,
9
+ * search and pagination are all resolved server-side.
10
+ */
11
+ export declare function useResourceTable<TResource extends ListableResourceType>(config: UseResourceTableConfig<TResource>): UseResourceTableReturn<TResource>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@commercelayer/app-elements",
3
- "version": "7.12.0",
3
+ "version": "7.14.0",
4
4
  "type": "module",
5
5
  "license": "MIT",
6
6
  "files": [
@@ -38,6 +38,7 @@
38
38
  "@commercelayer/sdk": "8.0.0-beta.11",
39
39
  "@date-fns/tz": "^1.5.0",
40
40
  "@monaco-editor/react": "~4.7.0",
41
+ "@tanstack/react-table": "^9.0.0",
41
42
  "@types/lodash-es": "^4.17.12",
42
43
  "@types/react": "19.2.13",
43
44
  "@types/react-datepicker": "^7.0.0",
@@ -60,6 +61,7 @@
60
61
  "react-select": "^5.10.2",
61
62
  "react-toastify": "^11.1.0",
62
63
  "react-tooltip": "^5.30.1",
64
+ "stable-hash": "^0.0.6",
63
65
  "swr": "^2.4.2",
64
66
  "ts-invariant": "^0.10.3",
65
67
  "type-fest": "^5.7.0",
@@ -100,8 +102,8 @@
100
102
  "wouter": "^3.x"
101
103
  },
102
104
  "scripts": {
103
- "build": "tsc && vite build && pnpm build:css-vendor && pnpm build:tailwind-cfg",
104
- "build:tailwind-cfg": "cp ./src/styles/global.css ./dist/tailwind.global.css",
105
+ "build": "tsc && vite build && pnpm build:css-vendor",
106
+ "build:watch": "pnpm dlx concurrently@10 --kill-others --names vendor,lib --prefix-colors cyan,magenta \"pnpm build:css-vendor --watch\" \"APP_ELEMENTS_WATCH=true vite build --watch\"",
105
107
  "build:css-vendor": "pnpm dlx @tailwindcss/cli -i ./src/styles/vendor.css -o ./dist/vendor.css --minify",
106
108
  "check": "pnpm biome check",
107
109
  "check:fix": "pnpm biome check --write",
@@ -1,8 +0,0 @@
1
- import { default as React, JSX } from 'react';
2
- interface VisibilityTriggerProps extends React.HTMLAttributes<HTMLDivElement> {
3
- rootMargin?: string;
4
- callback: (entry: IntersectionObserverEntry) => void;
5
- enabled: boolean;
6
- }
7
- export declare function VisibilityTrigger({ rootMargin, enabled, callback, ...rest }: VisibilityTriggerProps): JSX.Element;
8
- export {};