@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
@@ -1,9 +1,55 @@
1
1
  import { JSX, ReactNode } from 'react';
2
+ export type StackSize = "regular" | "small";
2
3
  export interface StackProps {
3
4
  children: ReactNode;
5
+ /**
6
+ * How dense the row is.
7
+ *
8
+ * `regular` keeps the page-level rhythm. `small` tightens the padding and, from
9
+ * `@xl` up — where the cells sit side by side — sends the trailing cell to the
10
+ * right edge; stacked, every cell still reads from the left. `StackCell` takes its
11
+ * type sizes from this as well.
12
+ *
13
+ * ⚠️ Give a `small` row **two cells**. The pair is what the alignment is built
14
+ * for: one cell reading from the left edge, one from the right. A third cell
15
+ * lands in the middle with nothing to align to, so more facts go in further
16
+ * `Stack`s below — consecutive ones merge their borders and read as one block.
17
+ * A lone cell is fine as the remainder of an odd count; it stays left-aligned.
18
+ *
19
+ * @example
20
+ * ```jsx
21
+ * <Stack size='small'>
22
+ * <StackCell label='Frequency'>Monthly</StackCell>
23
+ * <StackCell label='Last run'>Mar 15, 2024</StackCell>
24
+ * </Stack>
25
+ * <Stack size='small'>
26
+ * <StackCell label='Source order'>#1234</StackCell>
27
+ * <StackCell label='Customer'>customer@commercelayer.io</StackCell>
28
+ * </Stack>
29
+ * ```
30
+ */
31
+ size?: StackSize;
4
32
  }
5
- declare function Stack({ children, ...props }: StackProps): JSX.Element;
33
+ declare function Stack({ children, size, ...props }: StackProps): JSX.Element;
6
34
  declare namespace Stack {
7
35
  var displayName: string;
8
36
  }
9
- export { Stack };
37
+ export interface StackCellProps {
38
+ /** Muted caption, above the value. */
39
+ label: string;
40
+ /** The value. When empty it renders as a dash, so the row keeps its grid. */
41
+ children?: ReactNode;
42
+ /** Overrides the size inherited from the surrounding `Stack`. */
43
+ size?: StackSize;
44
+ }
45
+ /**
46
+ * One cell of a `Stack`: a muted label with its value underneath.
47
+ *
48
+ * The type sizes and the gap follow the `Stack`'s `size`, so a `small` row is small
49
+ * throughout without every call site restating it.
50
+ */
51
+ declare function StackCell({ label, children, size }: StackCellProps): JSX.Element;
52
+ declare namespace StackCell {
53
+ var displayName: string;
54
+ }
55
+ export { Stack, StackCell };
@@ -1,5 +1,13 @@
1
1
  import { default as React } from 'react';
2
2
  export interface TableProps {
3
+ /**
4
+ * Column definitions (`<col>` elements), rendered before the header.
5
+ *
6
+ * This is where column widths belong when the table lays out with
7
+ * `table-layout: fixed`: widths declared on the header row are lost as soon as
8
+ * the header is hidden, while a `colgroup` holds regardless.
9
+ */
10
+ colgroup?: React.ReactNode;
3
11
  thead?: React.ReactNode;
4
12
  className?: string;
5
13
  variant?: "boxed";
@@ -38,6 +38,14 @@ export interface TabProps {
38
38
  * This is the tab name used to render the Tab Navigation on top
39
39
  */
40
40
  name: string;
41
+ /**
42
+ * Draws a vertical rule before this tab in the navigation, to set the tabs that
43
+ * follow apart from the ones before — e.g. to separate the states an order moves
44
+ * through from the shelves it can be put on (carts, archive).
45
+ *
46
+ * Ignored on the first rendered tab, where there is nothing to separate.
47
+ */
48
+ separatorBefore?: boolean;
41
49
  /**
42
50
  * Tab Panel content
43
51
  */
@@ -0,0 +1,19 @@
1
+ import { default as React, JSX } from 'react';
2
+ export interface VisibilityTriggerProps extends React.HTMLAttributes<HTMLDivElement> {
3
+ /**
4
+ * Grows or shrinks the area that counts as visible, e.g. `"200px"` to start
5
+ * loading before the element actually reaches the viewport.
6
+ */
7
+ rootMargin?: string;
8
+ /** Invoked whenever the element enters or leaves the viewport. */
9
+ callback: (entry: IntersectionObserverEntry) => void;
10
+ /** When `false` the element still renders, but is not observed. */
11
+ enabled: boolean;
12
+ }
13
+ /**
14
+ * Renders an empty element and reports when it scrolls into view, so callers
15
+ * can load the next page of a long list as the user approaches the end of it.
16
+ *
17
+ * Place it after the last item you have rendered.
18
+ */
19
+ export declare function VisibilityTrigger({ rootMargin, enabled, callback, className, ...rest }: VisibilityTriggerProps): JSX.Element;
@@ -0,0 +1 @@
1
+ export {};
@@ -23,6 +23,14 @@ export interface AddressProps {
23
23
  * The implemented method get triggered every time the edit button is clicked.
24
24
  */
25
25
  onEdit?: () => void;
26
+ /**
27
+ * When set, the address can be deleted.
28
+ *
29
+ * With both actions the two move into a `…` menu, as everywhere else a row
30
+ * carries more than one action; with only `onEdit` the pencil stays, since a
31
+ * menu holding a single item is a click for nothing.
32
+ */
33
+ onDelete?: () => void;
26
34
  }
27
35
  /**
28
36
  * Renders an all-in-one visualization to deal with a given address
@@ -48,6 +56,7 @@ export declare const Address: import('../atoms/SkeletonTemplate').SkeletonTempla
48
56
  */
49
57
  | undefined;
50
58
  onEdit?: (() => void) | undefined;
59
+ onDelete?: (() => void) | undefined;
51
60
  delayMs?: number | undefined;
52
61
  isLoading?: boolean | undefined;
53
62
  }>;
@@ -1,7 +1,8 @@
1
1
  import { JSX, ReactNode } from 'react';
2
2
  import { PageHeadingProps } from '../atoms/PageHeading';
3
3
  import { PageHeadingToolbarProps } from '../atoms/PageHeading/PageHeadingToolbar';
4
- export interface HomePageLayoutProps extends Pick<PageHeadingProps, "title"> {
4
+ import { PageLayoutProps } from './PageLayout';
5
+ export interface HomePageLayoutProps extends Pick<PageHeadingProps, "title">, Pick<PageLayoutProps, "fullWidth"> {
5
6
  /**
6
7
  * Page content
7
8
  */
@@ -15,7 +16,7 @@ export interface HomePageLayoutProps extends Pick<PageHeadingProps, "title"> {
15
16
  * This component renders a standard `PageLayout` but holds some logic
16
17
  * to define some default behavior for the home page, such as the navigation button label and action.
17
18
  */
18
- export declare function HomePageLayout({ title, children, toolbar, }: HomePageLayoutProps): JSX.Element;
19
+ export declare function HomePageLayout({ title, children, toolbar, fullWidth, }: HomePageLayoutProps): JSX.Element;
19
20
  export declare namespace HomePageLayout {
20
21
  var displayName: string;
21
22
  }
@@ -26,8 +26,21 @@ export interface ListDetailsItemProps {
26
26
  * Specify `none` to remove side gutter
27
27
  */
28
28
  gutter?: "none";
29
+ /**
30
+ * Where the row is rendered, which sets how it uses the width it has.
31
+ *
32
+ * - `"default"` — stacked on a phone, label and value side by side from `md` up.
33
+ * - `"sidebar"` — the narrow column: from `lg` up (where `PageLayout` splits into
34
+ * two columns) the row stays stacked and drops its divider, since 380px is not
35
+ * enough for two columns and the gaps read better than lines. Below that it is a
36
+ * full-width row like any other, so it renders as `"default"`.
37
+ *
38
+ * Inferred from where the row sits — `PageLayout`'s sidebar slot reports
39
+ * `"sidebar"` — so pass it only to force the other rendering.
40
+ */
41
+ surface?: "default" | "sidebar";
29
42
  }
30
- export declare function ListDetailsItem({ label, children, isLoading, border, gutter, childrenAlign, ...rest }: ListDetailsItemProps): JSX.Element;
43
+ export declare function ListDetailsItem({ label, children, isLoading, border, gutter, childrenAlign, surface, ...rest }: ListDetailsItemProps): JSX.Element;
31
44
  export declare namespace ListDetailsItem {
32
45
  var displayName: string;
33
46
  }
@@ -2,14 +2,76 @@ import { ReactNode } from 'react';
2
2
  import { ContainerProps } from '../atoms/Container';
3
3
  import { PageHeadingProps } from '../atoms/PageHeading';
4
4
  import { OverlayProps } from '../internals/Overlay';
5
- export type PageLayoutProps = Pick<PageHeadingProps, "title" | "description" | "navigationButton" | "toolbar" | "gap"> & Pick<ContainerProps, "minHeight"> & {
5
+ export type PageLayoutProps = Pick<PageHeadingProps, "title" | "description" | "navigationButton" | "toolbar" | "gap"> & Pick<ContainerProps, "minHeight" | "fullWidth"> & {
6
6
  /**
7
7
  * Page content
8
8
  */
9
9
  children: ReactNode;
10
+ /**
11
+ * Page-level notices, rendered full width between the heading and the content.
12
+ *
13
+ * For what is true of the resource as a whole — "generated via API", "pending
14
+ * because it has no usable payment method", a failed purchase — rather than of
15
+ * one section. Read before anything else, and spanning the sidebar too, since
16
+ * they are about the page and not about its main column.
17
+ *
18
+ * Pass the `Alert`s themselves: the spacing around them belongs here, so the
19
+ * gap stays the same whether a page shows one, two or none.
20
+ *
21
+ * @example
22
+ * ```jsx
23
+ * <PageLayout
24
+ * title='Promotion'
25
+ * alert={viaApi && <Alert status='info'>Generated via API.</Alert>}
26
+ * >
27
+ * ```
28
+ */
29
+ alert?: ReactNode;
30
+ /**
31
+ * Secondary content, rendered in a column beside `children` on large screens
32
+ * and stacked below it on smaller ones.
33
+ *
34
+ * Meant for details pages, where the supporting information of a resource
35
+ * (customer, addresses, tags, metadata, …) sits next to its main content.
36
+ * Pass one `Section` per block: the column's card is drawn here, so the slot
37
+ * takes the blocks themselves and no wrapper of its own.
38
+ *
39
+ * Best paired with `fullWidth`, since the default content width leaves too
40
+ * little room for two columns.
41
+ *
42
+ * Pair it with `gap="only-top"` and open `children` with a `Spacer top="14"`:
43
+ * the card is aligned to that spacer, and the heading's default bottom gap
44
+ * would otherwise be added on top of it.
45
+ *
46
+ * @example
47
+ * ```jsx
48
+ * <PageLayout
49
+ * title='Order #1234'
50
+ * fullWidth
51
+ * gap='only-top'
52
+ * sidebar={
53
+ * <>
54
+ * <Section title='Customer'>...</Section>
55
+ * <Spacer top='10'>
56
+ * <Section title='Addresses'>...</Section>
57
+ * </Spacer>
58
+ * </>
59
+ * }
60
+ * >
61
+ * <Spacer top='14'>
62
+ * <OrderSummary />
63
+ * </Spacer>
64
+ * </PageLayout>
65
+ * ```
66
+ */
67
+ sidebar?: ReactNode;
10
68
  /**
11
69
  * When mode is `test`, it will render a `TEST DATA` Badge to inform user api is working in test mode.
12
70
  * Only if app is standalone mode.
71
+ *
72
+ * Defaults to the mode of the current token, so a page gets the badge without
73
+ * having to pass anything: forgetting it is invisible in the dashboard, where
74
+ * the badge is suppressed anyway, and only shows up standalone.
13
75
  */
14
76
  mode?: "test" | "live";
15
77
  /**
@@ -37,9 +99,13 @@ export declare const PageLayout: import('../atoms/SkeletonTemplate').SkeletonTem
37
99
  label: string;
38
100
  onClick: () => void;
39
101
  icon?: "x" | "arrowLeft";
102
+ variant?: "inline" | "button";
40
103
  } | undefined;
41
104
  minHeight?: boolean | undefined;
105
+ fullWidth?: boolean | undefined;
42
106
  children: ReactNode;
107
+ alert?: ReactNode;
108
+ sidebar?: ReactNode;
43
109
  mode?: "test" | "live"
44
110
  /**
45
111
  * Optional prop to enable scroll to top behavior on location change
@@ -58,9 +124,13 @@ export declare const PageLayout: import('../atoms/SkeletonTemplate').SkeletonTem
58
124
  label: string;
59
125
  onClick: () => void;
60
126
  icon?: "x" | "arrowLeft";
127
+ variant?: "inline" | "button";
61
128
  } | undefined;
62
129
  minHeight?: boolean | undefined;
130
+ fullWidth?: boolean | undefined;
63
131
  children: ReactNode;
132
+ alert?: ReactNode;
133
+ sidebar?: ReactNode;
64
134
  mode?: "test" | "live"
65
135
  /**
66
136
  * Optional prop to enable scroll to top behavior on location change
@@ -0,0 +1,35 @@
1
+ export interface PageLoadingProps {
2
+ /**
3
+ * Milliseconds to wait before the spinner appears. A page that resolves faster
4
+ * than this shows no indicator at all, instead of a flash.
5
+ * @default 400
6
+ */
7
+ delayMs?: number;
8
+ /**
9
+ * Match the page being waited for, so its content does not shift sideways once
10
+ * it arrives.
11
+ * @default false
12
+ */
13
+ fullWidth?: boolean;
14
+ /**
15
+ * Renders the test/live banner of the page being waited for, when it is known.
16
+ */
17
+ mode?: "test" | "live";
18
+ }
19
+ /**
20
+ * Placeholder for a page that has not loaded yet.
21
+ *
22
+ * It draws only what is true before the page is known: the frame and the band the
23
+ * title will occupy, so nothing jumps when the real page arrives, plus a spinner.
24
+ * Deliberately no fake rows, cards or search bars —
25
+ * a placeholder that mimics content has to be kept in step with every screen it
26
+ * stands in for, and silently starts lying the moment one of them changes.
27
+ *
28
+ * For loading *within* a page, where the shape is known, use `SkeletonTemplate`
29
+ * around the real components instead: it renders the actual markup, so it cannot
30
+ * drift.
31
+ */
32
+ export declare function PageLoading({ delayMs, fullWidth, mode, }: PageLoadingProps): React.JSX.Element;
33
+ export declare namespace PageLoading {
34
+ var displayName: string;
35
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -7,6 +7,12 @@ import { JSX } from 'react';
7
7
  * - list of items.
8
8
  *
9
9
  * <span type='info'>You can use this component to display generic loading UI when you can't rely on single SkeletonTemplate blocks.</span>
10
+ *
11
+ * @deprecated Use `PageLoading` instead. The elements drawn here have to be kept in
12
+ * step with every page this stands in for, and they no longer match: apps render
13
+ * tables, not a search bar over a list of items. `PageLoading` draws only the frame
14
+ * and a spinner, so it cannot drift. For loading *within* a page, where the shape is
15
+ * known, wrap the real components in `SkeletonTemplate`.
10
16
  **/
11
17
  declare function PageSkeleton(): JSX.Element;
12
18
  declare namespace PageSkeleton {
@@ -0,0 +1 @@
1
+ export {};
@@ -110,6 +110,14 @@ export interface InputSelectProps extends InputWrapperBaseProps {
110
110
  * **This option is only available when `loadAsyncValues` is provided.**
111
111
  */
112
112
  asTextSearch?: boolean;
113
+ /**
114
+ * Hide the chevron on the right of the control.
115
+ *
116
+ * For a field that is a text entry first and a picker second — an email you may be
117
+ * typing for the first time — where the chevron promises a list of choices the
118
+ * value does not have to come from. The menu still opens on focus and on typing.
119
+ */
120
+ hideDropdownIndicator?: boolean;
113
121
  /**
114
122
  * Whether the menu should use a portal, and where it should attach to.
115
123
  */
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,2 @@
1
+ export declare function lockBodyScroll(): void;
2
+ export declare function unlockBodyScroll(): void;
@@ -0,0 +1,36 @@
1
+ /**
2
+ * Where content is being rendered, so that it can adapt without every page passing
3
+ * a prop down.
4
+ *
5
+ * - `"page"` — the main column of a page, the widest surface.
6
+ * - `"drawer"` — inside a drawer, 680px from `md` up.
7
+ * - `"sidebar"` — `PageLayout`'s sidebar slot, a 380px column from `lg` up.
8
+ *
9
+ * Below the width at which each surface takes its own shape, all three are just
10
+ * full-width rows, so anything that adapts should differ only in `md:`/`lg:`-
11
+ * prefixed classes and read the same on a phone.
12
+ */
13
+ export type Surface = "page" | "drawer" | "sidebar";
14
+ /**
15
+ * Its own module rather than living in `Overlay` or `PageLayout`, so components that
16
+ * adapt to a surface (`PageHeading`, `ResourceDetails`) do not have to import the
17
+ * components that render them.
18
+ */
19
+ export declare const OverlayContext: import('react').Context<{
20
+ surface: Surface;
21
+ }>;
22
+ /** Where the calling component is being rendered. */
23
+ export declare function useSurface(): Surface;
24
+ /**
25
+ * `true` when the calling component sits inside a drawer, `false` on a page, in the
26
+ * sidebar or in a full-screen overlay.
27
+ */
28
+ export declare function useIsInDrawer(): boolean;
29
+ /**
30
+ * The two renderings a block of resource details has: the narrow sidebar column, or
31
+ * everything else. A page and a drawer differ in width but not in how these blocks
32
+ * lay out, so they share one.
33
+ */
34
+ export type SurfaceVariant = "default" | "sidebar";
35
+ /** The rendering the calling component should use, from where it sits. */
36
+ export declare function useSurfaceVariant(): SurfaceVariant;
@@ -11,6 +11,13 @@ export type ResourceAddressProps = Pick<AddressProps, "showBillingInfo" | "showN
11
11
  * requested resource before to render editable related functionalities.
12
12
  */
13
13
  editable?: boolean;
14
+ /**
15
+ * When set, the address can be deleted: the edit pencil becomes a `…` menu
16
+ * holding both actions. The handler is called on click — the confirmation and
17
+ * the delete itself belong to the caller, which knows what the address is
18
+ * attached to.
19
+ */
20
+ onDelete?: () => void;
14
21
  /**
15
22
  * Optional setting to define if given `Address` `billing_info` data is required.
16
23
  * @default false
@@ -35,10 +42,13 @@ export declare const ResourceAddress: import('../../atoms/SkeletonTemplate').Ske
35
42
  address?: (AddressType | null) | undefined;
36
43
  editable?: boolean
37
44
  /**
38
- * Optional setting to define if given `Address` `billing_info` data is required.
39
- * @default false
45
+ * When set, the address can be deleted: the edit pencil becomes a `…` menu
46
+ * holding both actions. The handler is called on click — the confirmation and
47
+ * the delete itself belong to the caller, which knows what the address is
48
+ * attached to.
40
49
  */
41
50
  | undefined;
51
+ onDelete?: (() => void) | undefined;
42
52
  requiresBillingInfo?: boolean
43
53
  /**
44
54
  * Get triggered as soon as the new address is created.
@@ -1,5 +1,13 @@
1
1
  import { Resource } from '@commercelayer/sdk';
2
2
  export interface ResourceDetailsProps {
3
+ /**
4
+ * How the block renders, overriding what it infers from where it sits.
5
+ *
6
+ * Inferred by default — `PageLayout`'s sidebar slot reports `"sidebar"`, while a
7
+ * page and a drawer both report the wider `"default"`. Pass it only to force a
8
+ * rendering the surrounding surface would not choose.
9
+ */
10
+ variant?: "default" | "sidebar";
3
11
  resource: Resource;
4
12
  onUpdated: () => Promise<void>;
5
13
  }
@@ -7,6 +15,7 @@ export interface ResourceDetailsProps {
7
15
  * This component provides a listed visualization of details attributes of a given resource.
8
16
  */
9
17
  export declare const ResourceDetails: import('../../atoms/SkeletonTemplate').SkeletonTemplateComponent<{
18
+ variant?: "default" | "sidebar" | undefined;
10
19
  resource: Resource;
11
20
  onUpdated: () => Promise<void>;
12
21
  delayMs?: number | undefined;
@@ -0,0 +1,11 @@
1
+ import { Resource } from '@commercelayer/sdk';
2
+ /**
3
+ * Lists a resource's plain attributes. Relationships are filtered out: they
4
+ * are rendered by whoever owns that concern, so they don't leak into this list
5
+ * as raw JSON.
6
+ */
7
+ export declare const ResourceAttributes: import('../../atoms/SkeletonTemplate').SkeletonTemplateComponent<{
8
+ resource: Resource;
9
+ delayMs?: number | undefined;
10
+ isLoading?: boolean | undefined;
11
+ }>;
@@ -0,0 +1,43 @@
1
+ import { Resource } from '@commercelayer/sdk';
2
+ import { FC, ReactNode } from 'react';
3
+ export interface ResourceDetailsTab {
4
+ /** Tab label. */
5
+ name: string;
6
+ /** Receives the resource, so the tab can render data already loaded by the caller. */
7
+ content: (resource: Resource) => ReactNode;
8
+ }
9
+ export interface ResourceDetailsContentProps {
10
+ /**
11
+ * The resource to display, already loaded by the caller.
12
+ *
13
+ * Nothing is fetched here: the caller decides what to sideload, which keeps
14
+ * `include`/`fields` policy out of this component and avoids re-requesting a
15
+ * resource that is often already in hand.
16
+ */
17
+ resource: Resource;
18
+ /** Renders skeletons while the caller is still loading the resource. */
19
+ isLoading?: boolean;
20
+ /** Extra tabs, rendered between Attributes and Events. */
21
+ tabs?: ResourceDetailsTab[];
22
+ /**
23
+ * Fixed height for each tab panel, e.g. `"70vh"`. Set it when the surrounding
24
+ * container must not resize as tabs change (a modal, typically). Leave it
25
+ * unset on a page, so content flows naturally instead of gaining a nested
26
+ * scrollbar.
27
+ */
28
+ panelHeight?: string;
29
+ /**
30
+ * Id for the tab list, used to build the ids that link each tab to its panel.
31
+ * Defaults to a generated one, so several instances can coexist on the same
32
+ * page without colliding.
33
+ */
34
+ id?: string;
35
+ }
36
+ /**
37
+ * Tabbed view of a single resource: its attributes, any tabs the caller adds,
38
+ * and its event stream.
39
+ *
40
+ * Usable on its own inside a page, or wrapped in a modal via
41
+ * `useResourceDetailsModal`.
42
+ */
43
+ export declare const ResourceDetailsContent: FC<ResourceDetailsContentProps>;
@@ -0,0 +1,15 @@
1
+ import { ResourceTypeLock } from '@commercelayer/sdk';
2
+ import { FC } from 'react';
3
+ /**
4
+ * Timeline of a resource's event stores, newest first, grouped by day and
5
+ * paginated as the user scrolls.
6
+ *
7
+ * Event stores are part of the Event Stream Hub, so organizations without it
8
+ * see an upsell instead. Enterprise-ness is read from the token provider
9
+ * extras. When it is absent (an app running outside the dashboard, where
10
+ * nothing populates it) the upsell is shown rather than the timeline.
11
+ */
12
+ export declare const ResourceEvents: FC<{
13
+ resourceId: string;
14
+ resourceType: ResourceTypeLock;
15
+ }>;
@@ -0,0 +1,2 @@
1
+ export { ResourceDetailsContent, type ResourceDetailsContentProps, type ResourceDetailsTab, } from './ResourceDetailsContent';
2
+ export { type UseResourceDetailsModalProps, type UseResourceDetailsModalReturn, useResourceDetailsModal, } from './useResourceDetailsModal';
@@ -0,0 +1,19 @@
1
+ import { Resource } from '@commercelayer/sdk';
2
+ /**
3
+ * An empty array is treated as a relationship: an emptied has-many
4
+ * (`payment_refunds: []`) is far more common than a top-level array-valued
5
+ * attribute, and there is no way to tell them apart from the payload alone.
6
+ */
7
+ export declare function isRelationshipValue(value: unknown): boolean;
8
+ export interface ResourceFields {
9
+ /** Plain attribute keys, alphabetically sorted. */
10
+ attributes: string[];
11
+ /** Relationship keys, alphabetically sorted. */
12
+ relationships: string[];
13
+ }
14
+ /**
15
+ * Splits a resource's keys into plain attributes and relationships, so each can
16
+ * be rendered separately. `id` and `type` are excluded: they identify the
17
+ * resource itself and are shown on their own.
18
+ */
19
+ export declare function splitResourceFields(resource: Resource): ResourceFields;
@@ -0,0 +1,39 @@
1
+ import { ListResponse, Resource } from '@commercelayer/sdk';
2
+ import { Arguments, BareFetcher } from 'swr';
3
+ import { SWRInfiniteConfiguration } from 'swr/infinite';
4
+ import { useCoreSdkProvider } from '../../../providers/CoreSdkProvider';
5
+ /** The `@commercelayer/sdk` client, as provided by `CoreSdkProvider`. */
6
+ type SdkClient = ReturnType<typeof useCoreSdkProvider>["sdkClient"];
7
+ export interface CursorPage<Data extends ListResponse<Resource>> {
8
+ /**
9
+ * A serializable value that uniquely identifies this page request. It's used
10
+ * as the SWR cache key, so it must include everything that makes the request
11
+ * unique (resource type, parent id, cursor, ...).
12
+ */
13
+ key: Arguments;
14
+ /** Performs the actual cursor-paginated request and resolves the page data. */
15
+ fetch: () => Promise<Data>;
16
+ }
17
+ export type GetCursorPage<Data extends ListResponse<Resource>> = (params: {
18
+ sdkClient: SdkClient;
19
+ index: number;
20
+ previousPageData: Data | null;
21
+ }) => CursorPage<Data> | null;
22
+ /**
23
+ * Returns the `next` cursor from a cursor-paginated response, ready to be used
24
+ * as the `pageAfter` query param. Returns `undefined` for offset-paginated
25
+ * responses, missing data or when there are no more pages.
26
+ */
27
+ export declare const getNextCursor: (page: ListResponse<Resource> | null | undefined) => string | undefined;
28
+ export declare const useInfiniteScrollCursor: <Data extends ListResponse<Resource>, Error = unknown>(getCursorPage: GetCursorPage<Data>, config?: SWRInfiniteConfiguration<Data, Error, BareFetcher<Data>>) => {
29
+ data: (Data extends readonly (infer InnerArr)[] ? InnerArr : Data)[];
30
+ error: Error | undefined;
31
+ isLoading: boolean;
32
+ isValidating: boolean;
33
+ mutate: import('swr/infinite').SWRInfiniteKeyedMutator<Data[]>;
34
+ currentPage: number;
35
+ isLoadingMore: boolean;
36
+ fetchNextPage: (() => void) | undefined;
37
+ VisibilityTrigger: () => import("react/jsx-runtime").JSX.Element;
38
+ };
39
+ export {};
@@ -0,0 +1,23 @@
1
+ import { ReactNode } from 'react';
2
+ import { ResourceDetailsContentProps } from './ResourceDetailsContent';
3
+ export interface UseResourceDetailsModalProps extends Omit<ResourceDetailsContentProps, "panelHeight"> {
4
+ /** Modal heading. Defaults to a generic "Resource details". */
5
+ title?: string;
6
+ }
7
+ export interface UseResourceDetailsModalReturn {
8
+ /** Render this wherever the modal should mount. */
9
+ modal: ReactNode;
10
+ open: () => void;
11
+ close: () => void;
12
+ }
13
+ /**
14
+ * Shows a resource's details in a modal: its attributes, any caller-supplied
15
+ * tabs, and its event stream.
16
+ *
17
+ * The modal is returned as an *element*, not a component. A component created
18
+ * inside this hook would get a fresh identity on every render of the caller,
19
+ * so React would unmount and remount the whole subtree whenever the caller
20
+ * re-rendered (an SWR revalidation on window focus, say), discarding the
21
+ * active tab and repainting the contents.
22
+ */
23
+ export declare function useResourceDetailsModal({ title, ...contentProps }: UseResourceDetailsModalProps): UseResourceDetailsModalReturn;
@@ -3,6 +3,14 @@ import { EditMetadataOverlayProps } from '../../../hooks/useEditMetadataOverlay'
3
3
  interface MetadataOverlay extends Omit<EditMetadataOverlayProps, "resourceId" | "resourceType"> {
4
4
  }
5
5
  export interface ResourceMetadataProps {
6
+ /**
7
+ * How the block renders, overriding what it infers from where it sits.
8
+ *
9
+ * Inferred by default — `PageLayout`'s sidebar slot reports `"sidebar"`, while a
10
+ * page and a drawer both report the wider `"default"`. Pass it only to force a
11
+ * rendering the surrounding surface would not choose.
12
+ */
13
+ variant?: "default" | "sidebar";
6
14
  resourceType: ListableResourceType;
7
15
  resourceId: string;
8
16
  /**
@@ -18,6 +26,7 @@ export declare const isUpdatableType: (value: any) => value is UpdatableType;
18
26
  * More in detail the `metadata` attribute is a JSON object, customizable for several purposes, and this component will allow to show and manage its keys with a simple (string kind) values.
19
27
  */
20
28
  export declare const ResourceMetadata: import('../../atoms/SkeletonTemplate').SkeletonTemplateComponent<{
29
+ variant?: "default" | "sidebar" | undefined;
21
30
  resourceType: ListableResourceType;
22
31
  resourceId: string;
23
32
  overlay?: MetadataOverlay | undefined;