@globalpayments-private/gpds-pattern-web-react 0.0.0-stage → 0.1.1-pr.52.gae8887e

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 (40) hide show
  1. package/dist/components.d.ts +12 -0
  2. package/dist/components.js +13 -0
  3. package/dist/composition/admin.d.ts +60 -0
  4. package/dist/composition/admin.js +29 -0
  5. package/dist/composition/children.d.ts +3 -0
  6. package/dist/composition/children.js +7 -0
  7. package/dist/composition/custom-routes.d.ts +88 -0
  8. package/dist/composition/custom-routes.js +76 -0
  9. package/dist/composition/index.d.ts +55 -0
  10. package/dist/composition/index.js +48 -0
  11. package/dist/composition/list.d.ts +220 -0
  12. package/dist/composition/list.js +90 -0
  13. package/dist/composition/record.d.ts +137 -0
  14. package/dist/composition/record.js +257 -0
  15. package/dist/composition/reference-many.d.ts +86 -0
  16. package/dist/composition/reference-many.js +60 -0
  17. package/dist/composition/reference.d.ts +13 -0
  18. package/dist/composition/reference.js +17 -0
  19. package/dist/composition/resource.d.ts +36 -0
  20. package/dist/composition/resource.js +52 -0
  21. package/dist/composition/simple-form.d.ts +96 -0
  22. package/dist/composition/simple-form.js +82 -0
  23. package/dist/gp-admin.d.ts +9 -0
  24. package/dist/gp-admin.js +20 -0
  25. package/dist/gp-pattern-list.d.ts +11 -0
  26. package/dist/gp-pattern-list.js +22 -0
  27. package/dist/gp-pattern-record.d.ts +12 -0
  28. package/dist/gp-pattern-record.js +23 -0
  29. package/dist/gp-pattern-reference-input.d.ts +8 -0
  30. package/dist/gp-pattern-reference-input.js +19 -0
  31. package/dist/gp-pattern-wizard.d.ts +11 -0
  32. package/dist/gp-pattern-wizard.js +22 -0
  33. package/dist/gp-resource.d.ts +5 -0
  34. package/dist/gp-resource.js +17 -0
  35. package/dist/uds-pattern-login-card.d.ts +13 -0
  36. package/dist/uds-pattern-login-card.js +22 -0
  37. package/dist/uds-pattern-login-page.d.ts +5 -0
  38. package/dist/uds-pattern-login-page.js +17 -0
  39. package/package.json +54 -4
  40. package/README.md +0 -3
@@ -0,0 +1,12 @@
1
+ /**
2
+ * This file was automatically generated by the Stencil React Output Target.
3
+ * Changes to this file may cause incorrect behavior and will be lost if the code is regenerated.
4
+ */
5
+ export { GpAdmin } from './gp-admin.js';
6
+ export { GpPatternList } from './gp-pattern-list.js';
7
+ export { GpPatternRecord } from './gp-pattern-record.js';
8
+ export { GpPatternReferenceInput } from './gp-pattern-reference-input.js';
9
+ export { GpPatternWizard } from './gp-pattern-wizard.js';
10
+ export { GpResource } from './gp-resource.js';
11
+ export { UdsPatternLoginCard } from './uds-pattern-login-card.js';
12
+ export { UdsPatternLoginPage } from './uds-pattern-login-page.js';
@@ -0,0 +1,13 @@
1
+ /**
2
+ * This file was automatically generated by the Stencil React Output Target.
3
+ * Changes to this file may cause incorrect behavior and will be lost if the code is regenerated.
4
+ */
5
+ /* eslint-disable */
6
+ export { GpAdmin } from './gp-admin.js';
7
+ export { GpPatternList } from './gp-pattern-list.js';
8
+ export { GpPatternRecord } from './gp-pattern-record.js';
9
+ export { GpPatternReferenceInput } from './gp-pattern-reference-input.js';
10
+ export { GpPatternWizard } from './gp-pattern-wizard.js';
11
+ export { GpResource } from './gp-resource.js';
12
+ export { UdsPatternLoginCard } from './uds-pattern-login-card.js';
13
+ export { UdsPatternLoginPage } from './uds-pattern-login-page.js';
@@ -0,0 +1,60 @@
1
+ import { type ReactElement, type ReactNode } from 'react';
2
+ import type { UdsAdminLabels, UdsAuthProvider, UdsDataProvider, UdsNotificationProvider, UdsQueryProvider, UdsRouterProvider } from '@globalpayments-private/gpds-pattern-web';
3
+ import { type UdsPageBuilder } from './custom-routes';
4
+ /**
5
+ * `Admin`: the root of the composition layer, a thin rename of what
6
+ * `gp-admin` already was (ADR 0012 already treats `<gp-admin><gp-resource/>
7
+ * </gp-admin>` as a composition, not as config). `Admin` exists only because
8
+ * real react-admin's root is called `<Admin>`
9
+ * (https://marmelab.com/react-admin/Tutorial.html) — see
10
+ * `docs/specs/north-star-composition.md` §9.
11
+ *
12
+ * `children` are forwarded untouched: a `<Resource>` passed here renders as a
13
+ * real `<gp-resource>` child element, which is how `gp-admin` discovers its
14
+ * resources today (`admin.config.resources` is the alternative path, not a
15
+ * replacement — see `UdsAdminConfig.resources`'s own doc).
16
+ *
17
+ * `<CustomRoutes>` is the one child `Admin` also *reads*, because a custom
18
+ * page is half configuration (`config.pages`) and half slotted content
19
+ * (`<section slot="page-…">`). Both halves are produced here so the consumer
20
+ * only ever writes react-admin's tree — see `custom-routes.tsx` for why that
21
+ * is the one marker pair that renders.
22
+ *
23
+ * Written with `createElement` rather than JSX: this package's shared Jest
24
+ * config compiles every `.tsx` with Stencil's own `h`-pragma transform (the
25
+ * rest of `src/` needs exactly that), so JSX syntax here would silently
26
+ * target the wrong runtime under test. `createElement` is what JSX compiles
27
+ * to either way.
28
+ */
29
+ export interface AdminProps {
30
+ data?: UdsDataProvider;
31
+ auth?: UdsAuthProvider;
32
+ /**
33
+ * The query cache, mirroring react-admin's `queryClient`
34
+ * (https://marmelab.com/react-admin/Admin.html#queryclient).
35
+ */
36
+ query?: UdsQueryProvider;
37
+ /**
38
+ * The router, mirroring react-admin's `basename`/router configuration. A
39
+ * demo served from GitHub Pages needs `createHistoryRouter({ hash: true })`
40
+ * here, so this is not an advanced seam — it is the first thing a deployed
41
+ * app sets.
42
+ */
43
+ router?: UdsRouterProvider;
44
+ /** Notifications, mirroring react-admin's `notification` slot. */
45
+ notifications?: UdsNotificationProvider;
46
+ /** Copy overrides, the narrow part of react-admin's `i18nProvider`. */
47
+ labels?: Partial<UdsAdminLabels>;
48
+ /**
49
+ * The landing screen, mirroring react-admin's `dashboard`
50
+ * (https://marmelab.com/react-admin/Admin.html#dashboard).
51
+ *
52
+ * Takes a React node or a `() => Node` builder, for the same reason
53
+ * `<Route element>` does: this library's framework-neutral pages return
54
+ * plain DOM and are mirrored unchanged into the vanilla, Vue and Angular
55
+ * variants of the same demo (ADR 0017, ADR 0030).
56
+ */
57
+ dashboard?: ReactNode | UdsPageBuilder;
58
+ children?: ReactElement | ReactElement[];
59
+ }
60
+ export declare function Admin({ data, auth, query, router, notifications, labels, dashboard, children, }: AdminProps): ReactElement;
@@ -0,0 +1,29 @@
1
+ import { createElement } from 'react';
2
+ // Relative, not the `./react` package subpath: that subpath has no `require`
3
+ // condition (ESM-only, matching the rest of the generated bindings), which
4
+ // would break loading this file under Jest's CommonJS test runner.
5
+ import { GpAdmin } from '@globalpayments-private/gpds-pattern-web-react';
6
+ import { mountBuilder, pageSectionsFrom, pagesFrom, routesFromChildren, } from './custom-routes';
7
+ export function Admin({ data, auth, query, router, notifications, labels, dashboard, children, }) {
8
+ const routes = routesFromChildren(children);
9
+ const config = {
10
+ data,
11
+ auth,
12
+ query,
13
+ router,
14
+ notifications,
15
+ labels,
16
+ pages: pagesFrom(routes),
17
+ };
18
+ return createElement(GpAdmin, { config, hasDashboard: dashboard !== undefined }, children, ...pageSectionsFrom(routes), ...dashboardSection(dashboard));
19
+ }
20
+ /** The `<div slot="dashboard">` the shell renders its landing screen into, when there is one. */
21
+ function dashboardSection(dashboard) {
22
+ if (dashboard === undefined) {
23
+ return [];
24
+ }
25
+ const isBuilder = typeof dashboard === 'function';
26
+ return [
27
+ createElement('div', { key: 'dashboard', slot: 'dashboard', ...(isBuilder ? { ref: mountBuilder(dashboard) } : {}) }, isBuilder ? undefined : dashboard),
28
+ ];
29
+ }
@@ -0,0 +1,3 @@
1
+ import type { ReactNode } from 'react';
2
+ /** `React.Children.toArray`, without taking a hard dependency on the `React` default export. */
3
+ export declare function reactChildrenToArray(children: ReactNode): ReactNode[];
@@ -0,0 +1,7 @@
1
+ /** `React.Children.toArray`, without taking a hard dependency on the `React` default export. */
2
+ export function reactChildrenToArray(children) {
3
+ if (children === undefined || children === null || children === false) {
4
+ return [];
5
+ }
6
+ return Array.isArray(children) ? children.flat(Infinity) : [children];
7
+ }
@@ -0,0 +1,88 @@
1
+ import { type ReactElement, type ReactNode } from 'react';
2
+ import type { UdsAdminPageDefinition } from '@globalpayments-private/gpds-pattern-web';
3
+ /**
4
+ * `CustomRoutes` and `Route`: the composition spelling of
5
+ * `UdsAdminConfig.pages`, mirroring real react-admin's
6
+ * https://marmelab.com/react-admin/CustomRoutes.html:
7
+ *
8
+ * ```tsx
9
+ * <Admin data={data}>
10
+ * <Resource name="merchants">…</Resource>
11
+ * <CustomRoutes>
12
+ * <Route path="/reports/settlement" name="settlement" label="Settlement" element={buildSettlementReport} />
13
+ * </CustomRoutes>
14
+ * </Admin>
15
+ * ```
16
+ *
17
+ * ## Why these are the one pair of markers that really render
18
+ *
19
+ * Every other marker in this layer is read and discarded, because what it
20
+ * describes is *configuration* that ends up on a `config` prop. A custom page
21
+ * is not only configuration: `gp-admin` matches `pages[].path` and then
22
+ * renders whatever is in the matching **named slot** — `{ name: 'settlement' }`
23
+ * pairs with `<section slot="page-settlement">`. The definition and the
24
+ * content are two halves of one thing, and only one half is a plain object.
25
+ *
26
+ * So `Admin` does both: it reads `<CustomRoutes>` into `config.pages`, and it
27
+ * renders each `<Route>`'s `element` into the `<section slot="page-…">` the
28
+ * shell will look for. The consumer writes react-admin's tree and never sees
29
+ * the slot convention, which is the point.
30
+ *
31
+ * ## Why `element` accepts a DOM builder as well as a React node
32
+ *
33
+ * React-admin's `element` is necessarily a React element — react-admin is a
34
+ * React framework. This library is not: its demos' custom pages are
35
+ * framework-neutral builders that return plain DOM and reach the shell
36
+ * through `requestContext` (ADR 0017), and they are mirrored unchanged into
37
+ * the vanilla, Vue and Angular variants of the same demo. Accepting only a
38
+ * React node would mean every custom page had to be rewritten as a React tree
39
+ * purely to satisfy the shape of a tag — which would end the single mirrored
40
+ * source those demos are built on, to buy nothing.
41
+ *
42
+ * So `element` takes either: a React node, rendered as the slot's children;
43
+ * or a `() => Node` builder, mounted into the slot through a ref on first
44
+ * attach. See ADR 0030.
45
+ */
46
+ /** A builder that returns a plain DOM node — what this library's framework-neutral pages are. */
47
+ export type UdsPageBuilder = () => Node;
48
+ export interface RouteProps extends Omit<UdsAdminPageDefinition, 'name'> {
49
+ /**
50
+ * The page's stable key, used for the slot name (`page-<name>`).
51
+ *
52
+ * Defaults to a slug of `path`, so the common case needs only `path` and
53
+ * `element`, as in react-admin.
54
+ */
55
+ name?: string;
56
+ /** The page's content: a React node, or a builder returning a DOM node. */
57
+ element: ReactNode | UdsPageBuilder;
58
+ }
59
+ /** Marker component for one custom page. Never rendered directly — see the module doc. */
60
+ export declare function Route(_props: RouteProps): null;
61
+ export interface CustomRoutesProps {
62
+ /** `<Route>` children. */
63
+ children?: ReactNode;
64
+ }
65
+ /** Marker component for the custom-page set. Never rendered directly — see the module doc. */
66
+ export declare function CustomRoutes(_props: CustomRoutesProps): null;
67
+ /** One `<Route>`, resolved into the definition and the content the shell needs separately. */
68
+ interface ResolvedRoute {
69
+ definition: UdsAdminPageDefinition;
70
+ element: ReactNode | UdsPageBuilder;
71
+ }
72
+ /** Reads every `<CustomRoutes>` child of an `<Admin>` into its `<Route>`s, in order. */
73
+ export declare function routesFromChildren(children: ReactNode): ResolvedRoute[];
74
+ /** The `pages` member a resolved route set stands for, or `undefined` when there are none. */
75
+ export declare function pagesFrom(routes: ResolvedRoute[]): UdsAdminPageDefinition[] | undefined;
76
+ /**
77
+ * The `<section slot="page-…">` elements `gp-admin` renders custom pages into.
78
+ *
79
+ * A React-node `element` becomes the section's children. A builder is mounted
80
+ * through a ref: the section is created empty and the builder's node appended
81
+ * once, on attach. The ref deliberately rebuilds nothing on re-render — these
82
+ * pages own their own DOM and their own updates (ADR 0017), and re-running a
83
+ * builder under them would throw away the state they are holding.
84
+ */
85
+ export declare function pageSectionsFrom(routes: ResolvedRoute[]): ReactElement[];
86
+ /** A ref callback that appends the builder's node once, the first time the host attaches. */
87
+ export declare function mountBuilder(build: UdsPageBuilder): (host: Element | null) => void;
88
+ export {};
@@ -0,0 +1,76 @@
1
+ import { createElement } from 'react';
2
+ import { reactChildrenToArray } from './children';
3
+ /** Marker component for one custom page. Never rendered directly — see the module doc. */
4
+ export function Route(_props) {
5
+ return null;
6
+ }
7
+ /** Marker component for the custom-page set. Never rendered directly — see the module doc. */
8
+ export function CustomRoutes(_props) {
9
+ return null;
10
+ }
11
+ /** Reads every `<CustomRoutes>` child of an `<Admin>` into its `<Route>`s, in order. */
12
+ export function routesFromChildren(children) {
13
+ const resolved = [];
14
+ reactChildrenToArray(children).forEach((child) => {
15
+ if (!isElementOfType(child, CustomRoutes)) {
16
+ return;
17
+ }
18
+ reactChildrenToArray(child.props.children).forEach((route) => {
19
+ if (!isElementOfType(route, Route)) {
20
+ return;
21
+ }
22
+ const { name, element, ...page } = route.props;
23
+ resolved.push({ definition: { ...page, name: name ?? slug(page.path) }, element });
24
+ });
25
+ });
26
+ return resolved;
27
+ }
28
+ /** The `pages` member a resolved route set stands for, or `undefined` when there are none. */
29
+ export function pagesFrom(routes) {
30
+ return routes.length ? routes.map((route) => route.definition) : undefined;
31
+ }
32
+ /**
33
+ * The `<section slot="page-…">` elements `gp-admin` renders custom pages into.
34
+ *
35
+ * A React-node `element` becomes the section's children. A builder is mounted
36
+ * through a ref: the section is created empty and the builder's node appended
37
+ * once, on attach. The ref deliberately rebuilds nothing on re-render — these
38
+ * pages own their own DOM and their own updates (ADR 0017), and re-running a
39
+ * builder under them would throw away the state they are holding.
40
+ */
41
+ export function pageSectionsFrom(routes) {
42
+ return routes.map(({ definition, element }) => createElement('section', {
43
+ key: definition.name,
44
+ slot: `page-${definition.name}`,
45
+ ...(isBuilder(element) ? { ref: mountBuilder(element) } : {}),
46
+ }, isBuilder(element) ? undefined : element));
47
+ }
48
+ /** A ref callback that appends the builder's node once, the first time the host attaches. */
49
+ export function mountBuilder(build) {
50
+ return (host) => {
51
+ if (host && !host.firstChild) {
52
+ host.appendChild(build());
53
+ }
54
+ };
55
+ }
56
+ /**
57
+ * A function `element` is a builder, not a React node.
58
+ *
59
+ * React elements are objects and strings are strings, so a function is never
60
+ * a valid `ReactNode` — there is no ambiguity to resolve here, which is why
61
+ * the two forms can share one prop without a discriminator.
62
+ */
63
+ function isBuilder(element) {
64
+ return typeof element === 'function';
65
+ }
66
+ /** `'/reports/settlement'` → `'reports-settlement'`. */
67
+ function slug(path) {
68
+ return path
69
+ .toLowerCase()
70
+ .replace(/[^a-z0-9]+/g, '-')
71
+ .replace(/^-+|-+$/g, '');
72
+ }
73
+ /** A React element whose `type` is exactly this marker function. */
74
+ function isElementOfType(node, type) {
75
+ return typeof node === 'object' && node !== null && 'type' in node && node.type === type;
76
+ }
@@ -0,0 +1,55 @@
1
+ /**
2
+ * The composition layer: a thin, additive JSX authoring surface over the
3
+ * existing config-as-data public API (ADR 0028). None of this is a new
4
+ * runtime — `Admin`/`Resource` are renamed pass-throughs to `gp-admin`/
5
+ * `gp-resource` (ADR 0012), and the rest are read once into the same
6
+ * `UdsAdminResource` shape a hand-written `config` object already produces.
7
+ *
8
+ * ## What mirrors react-admin, and what does not
9
+ *
10
+ * **Mirrors react-admin one-to-one** (https://marmelab.com/react-admin/Tutorial.html):
11
+ * `Admin`, `Resource`, `List`, `DataTable`, `DataTable.Col`, `Show`, `Edit`,
12
+ * `Create`, `SimpleForm` and its inputs, `TabbedShowLayout` /
13
+ * `TabbedShowLayout.Tab`, `ReferenceManyField`, `CustomRoutes` / `Route`.
14
+ *
15
+ * **Deliberate extensions beyond react-admin** (ADR 0030): `Board` and
16
+ * `CardGrid`. React-admin ships no kanban-board and no card-grid list view
17
+ * anywhere in its core — Marmelab's own Kanban is built from scratch in a
18
+ * tutorial and their Atomic CRM demo hand-rolls its deal pipeline. These
19
+ * exist because this library's pattern layer already ships both as
20
+ * `kind: 'board' | 'grid'` layouts (ADR 0016). They follow react-admin's
21
+ * grammar even so: they are *view children of `<List>`*, siblings of
22
+ * `<DataTable>`, never replacements for `<List>` itself.
23
+ *
24
+ * **Deliberately absent**: `Filter` — react-admin has no such tag, only a
25
+ * `filters` array *prop*, which `List.filters` mirrors directly. And no
26
+ * `Money`/`Status` tags, which react-admin likewise does not ship.
27
+ *
28
+ * **The two places this surface used to be narrower than react-admin are
29
+ * closed** (ADR 0031). `Show`/`Edit`/`Create` may carry genuinely different
30
+ * field sets — they are merged into the shell's one `fields` array and gated
31
+ * per mode via `UdsRecordField.modes` — and `ReferenceManyField` works both
32
+ * inside a view, reading the record's id from context as react-admin does,
33
+ * and as a child of `Resource` with an explicit `id`, which keeps working.
34
+ *
35
+ * What remains loud is only what one shell rendering one tab strip genuinely
36
+ * cannot express: wrappers that use different layouts, order the same fields
37
+ * differently, or name, order or label tabs differently. Those are rejected
38
+ * at read time with an error naming the limitation, never approximated — see
39
+ * `record.tsx`, `reference-many.tsx`, ADR 0030, ADR 0031 and
40
+ * `docs/specs/north-star-composition.md` §12 and §14.
41
+ */
42
+ export { Admin } from './admin';
43
+ export type { AdminProps } from './admin';
44
+ export { Resource } from './resource';
45
+ export type { ResourceProps } from './resource';
46
+ export { List, DataTable, Board, CardGrid } from './list';
47
+ export type { ListProps, ListViewActionProps, DataTableProps, DataTableColProps, BoardProps, CardGridProps, } from './list';
48
+ export { Show, Edit, Create, TabbedShowLayout } from './record';
49
+ export type { ShowProps, EditProps, CreateProps, TabbedShowLayoutProps, TabbedShowLayoutTabProps, } from './record';
50
+ export { ReferenceManyField } from './reference-many';
51
+ export type { ReferenceManyFieldProps } from './reference-many';
52
+ export { CustomRoutes, Route } from './custom-routes';
53
+ export type { CustomRoutesProps, RouteProps, UdsPageBuilder } from './custom-routes';
54
+ export { SimpleForm, TextInput, NumberInput, BooleanInput, DateInput, SelectInput, ReferenceInput, } from './simple-form';
55
+ export type { SimpleFormProps, TextInputProps, NumberInputProps, BooleanInputProps, DateInputProps, SelectInputProps, ReferenceInputProps, } from './simple-form';
@@ -0,0 +1,48 @@
1
+ /**
2
+ * The composition layer: a thin, additive JSX authoring surface over the
3
+ * existing config-as-data public API (ADR 0028). None of this is a new
4
+ * runtime — `Admin`/`Resource` are renamed pass-throughs to `gp-admin`/
5
+ * `gp-resource` (ADR 0012), and the rest are read once into the same
6
+ * `UdsAdminResource` shape a hand-written `config` object already produces.
7
+ *
8
+ * ## What mirrors react-admin, and what does not
9
+ *
10
+ * **Mirrors react-admin one-to-one** (https://marmelab.com/react-admin/Tutorial.html):
11
+ * `Admin`, `Resource`, `List`, `DataTable`, `DataTable.Col`, `Show`, `Edit`,
12
+ * `Create`, `SimpleForm` and its inputs, `TabbedShowLayout` /
13
+ * `TabbedShowLayout.Tab`, `ReferenceManyField`, `CustomRoutes` / `Route`.
14
+ *
15
+ * **Deliberate extensions beyond react-admin** (ADR 0030): `Board` and
16
+ * `CardGrid`. React-admin ships no kanban-board and no card-grid list view
17
+ * anywhere in its core — Marmelab's own Kanban is built from scratch in a
18
+ * tutorial and their Atomic CRM demo hand-rolls its deal pipeline. These
19
+ * exist because this library's pattern layer already ships both as
20
+ * `kind: 'board' | 'grid'` layouts (ADR 0016). They follow react-admin's
21
+ * grammar even so: they are *view children of `<List>`*, siblings of
22
+ * `<DataTable>`, never replacements for `<List>` itself.
23
+ *
24
+ * **Deliberately absent**: `Filter` — react-admin has no such tag, only a
25
+ * `filters` array *prop*, which `List.filters` mirrors directly. And no
26
+ * `Money`/`Status` tags, which react-admin likewise does not ship.
27
+ *
28
+ * **The two places this surface used to be narrower than react-admin are
29
+ * closed** (ADR 0031). `Show`/`Edit`/`Create` may carry genuinely different
30
+ * field sets — they are merged into the shell's one `fields` array and gated
31
+ * per mode via `UdsRecordField.modes` — and `ReferenceManyField` works both
32
+ * inside a view, reading the record's id from context as react-admin does,
33
+ * and as a child of `Resource` with an explicit `id`, which keeps working.
34
+ *
35
+ * What remains loud is only what one shell rendering one tab strip genuinely
36
+ * cannot express: wrappers that use different layouts, order the same fields
37
+ * differently, or name, order or label tabs differently. Those are rejected
38
+ * at read time with an error naming the limitation, never approximated — see
39
+ * `record.tsx`, `reference-many.tsx`, ADR 0030, ADR 0031 and
40
+ * `docs/specs/north-star-composition.md` §12 and §14.
41
+ */
42
+ export { Admin } from './admin';
43
+ export { Resource } from './resource';
44
+ export { List, DataTable, Board, CardGrid } from './list';
45
+ export { Show, Edit, Create, TabbedShowLayout } from './record';
46
+ export { ReferenceManyField } from './reference-many';
47
+ export { CustomRoutes, Route } from './custom-routes';
48
+ export { SimpleForm, TextInput, NumberInput, BooleanInput, DateInput, SelectInput, ReferenceInput, } from './simple-form';
@@ -0,0 +1,220 @@
1
+ import type { ReactNode } from 'react';
2
+ import type { UdsAdminListConfig, UdsListAction, UdsListColumn, UdsListFilterField, UdsListLane, UdsListMedia } from '@globalpayments-private/gpds-pattern-web';
3
+ /**
4
+ * `List`, `DataTable` and `DataTable.Col`: non-rendering marker components
5
+ * read by `Resource` (`resource.tsx`) to build a `UdsAdminListConfig` before
6
+ * anything reaches `gp-resource`/`gp-pattern-list`.
7
+ *
8
+ * ## Why these never render
9
+ *
10
+ * Every `@slot` this library ships holds markup rendered verbatim; none holds
11
+ * a schema read back out and discarded. `List`/`DataTable`/`DataTable.Col`
12
+ * are the one necessary exception ADR 0009 already accepts for
13
+ * `<Column>`/`<Filter>`-shaped authoring, so they stay here rather than
14
+ * becoming real elements: each one is called with its props and children at
15
+ * read time (`listConfigFromChildren`, below), and the resulting
16
+ * `UdsAdminListConfig` is handed to `<GpResource config>` — the same public
17
+ * prop a hand-written consumer uses (ADR 0012's equivalence rule). None of
18
+ * these functions is ever invoked by React; they only need a stable function
19
+ * identity so the reader below can recognise which element is which.
20
+ *
21
+ * ## Why the set mirrors what react-admin ships — and where it deliberately does not
22
+ *
23
+ * Per explicit direction, this composition layer duplicates real
24
+ * react-admin's shipped API (https://marmelab.com/react-admin/Tutorial.html)
25
+ * one-to-one rather than approximating it: `DataTable` is named after
26
+ * react-admin's actual table view component, and `DataTable.Col` after
27
+ * `DataTable.Col` — see `docs/specs/north-star-composition.md` §10 for the
28
+ * full reasoning. `Filter` is dropped entirely: react-admin has no such tag,
29
+ * only a `filters` array *prop* of input elements, which `List.filters`
30
+ * mirrors directly (`UdsListFilterField` is already the plain-object shape
31
+ * that prop wants, so there is nothing to translate).
32
+ *
33
+ * `Board` and `CardGrid` are the two **deliberate extensions beyond
34
+ * react-admin** (ADR 0030). React-admin ships no kanban-board and no
35
+ * card-grid list view anywhere in its core, under any name or shape:
36
+ * Marmelab's own Kanban is built from scratch in a tutorial
37
+ * (https://marmelab.com/blog/2023/07/28/create-a-kanban-board-in-react-admin.html)
38
+ * and their Atomic CRM demo hand-rolls its deal pipeline. They exist here
39
+ * because this library's pattern layer already ships both presentations as
40
+ * `kind: 'board' | 'grid'` layouts (ADR 0016) and the authoring surface was
41
+ * the only thing that could not reach them.
42
+ *
43
+ * They are shaped to react-admin's *grammar* even though the components are
44
+ * ours: in react-admin **the `<List>` element never swaps — only its view
45
+ * child does** (`<DataTable>`, `<SimpleList>`, `<SingleFieldList>`). So these
46
+ * are siblings of `DataTable` *inside* `<List>`, never replacements for
47
+ * `<List>` itself. A `<Board>` that replaced `<List>` would discard the
48
+ * querying, URL state, sorting, filtering, pagination and capability gating
49
+ * that `<List>` is, which is the whole claim of ADR 0016.
50
+ *
51
+ * All three view children read the same `<DataTable.Col>` children, because
52
+ * columns are the configuration for *every* layout — moving a list between
53
+ * presentations is one tag and never a rewrite of its columns.
54
+ *
55
+ * ## Where the actions live, and why the two differ
56
+ *
57
+ * `bulkActions` sits on the **view child, not on `<List>`**, because that is
58
+ * where real react-admin puts it: `bulkActionButtons` is a documented prop of
59
+ * `<DataTable>` (https://marmelab.com/react-admin/DataTable.html#props), not
60
+ * of `<List>`. Row *selection* is a property of the thing that renders rows,
61
+ * so the toolbar acting on a selection belongs beside it. Our config object
62
+ * happens to keep `bulkActions` under `list`, and that was not allowed to
63
+ * decide the JSX: the projection translates, exactly as `perPage` is a
64
+ * `<List>` prop that lands outside `list` (see `listConfigFromChildren`).
65
+ *
66
+ * `rowActions` sits there too, and that one **is a deviation**, stated rather
67
+ * than hidden. React-admin has no `rowActions` prop; it spells a row action
68
+ * as an ordinary button inside a column — `<DataTable.Col><EditButton /></…>`.
69
+ * That shape cannot be mirrored here for two independent reasons:
70
+ *
71
+ * 1. **Ours are effects, not elements.** `UdsListAction` is a description of
72
+ * a write (`{ kind: 'update', values }`), executed by the pattern through
73
+ * the staged, capability-gated, undoable path of ADR 0010 — and *not
74
+ * rendered at all* when the adapter cannot service it (ADR 0002 §2). A
75
+ * React element child is an instruction to render something regardless;
76
+ * accepting one would mean either ignoring what it renders or losing the
77
+ * gating, and both are worse than a different spelling.
78
+ * 2. **Two of the three layouts have no columns to put it in.** `board` and
79
+ * `grid` render row actions in the card footer. A column-shaped spelling
80
+ * would be correct for `table` and meaningless for the other two, which
81
+ * breaks the one-tag-swap rule the view children exist to keep.
82
+ *
83
+ * So both are plain array props, for the same reason `filters` is one: the
84
+ * underlying member is already the plain-object shape the prop wants, and
85
+ * inventing a `<RowAction>` tag would add a vocabulary without adding a
86
+ * capability. See ADR 0032.
87
+ */
88
+ /** A pure-data column: everything `DataTable.Col` accepts except the raw React element wrapper. */
89
+ export interface DataTableColProps {
90
+ field: string;
91
+ label: string;
92
+ sortable?: boolean;
93
+ align?: UdsListColumn['align'];
94
+ width?: string;
95
+ /** `{ resource: 'merchants' }` shorthand — defaults `field` to `'name'`. */
96
+ reference?: string | UdsListColumn['reference'];
97
+ /**
98
+ * A column factory, called as `(field, label) => UdsListColumn` — the exact
99
+ * signature `moneyColumn`/`statusColumn` already export. Mirrors
100
+ * `<DataTable.Col source="email"><EmailField source="email" /></DataTable.Col>`:
101
+ * the child does the real work, the wrapper only carries `field`/`label`.
102
+ */
103
+ children?: (field: string, label: string) => UdsListColumn;
104
+ }
105
+ /** Marker component for one table column. Never rendered — see the module doc. */
106
+ export declare function DataTableCol(_props: DataTableColProps): null;
107
+ /**
108
+ * The two action props every view child accepts.
109
+ *
110
+ * Factored out rather than repeated three times because `rowActions` renders
111
+ * in a trailing column for `table` and in the card footer for `board` and
112
+ * `grid` — one configuration, three presentations, which is the same rule
113
+ * columns already follow. See the module doc for why these sit on the view
114
+ * child and not on `<List>`.
115
+ */
116
+ export interface ListViewActionProps {
117
+ /**
118
+ * Actions offered on each record, forwarded to `UdsListConfig.rowActions`.
119
+ *
120
+ * **A deviation from react-admin**, deliberately — see the module doc. An
121
+ * action the adapter cannot service is absent rather than disabled, and
122
+ * `available` — an extension with no react-admin counterpart, like `Board`
123
+ * and `CardGrid` (ADR 0030) — hides one for records it does not apply to.
124
+ */
125
+ rowActions?: UdsListAction[];
126
+ /**
127
+ * Actions offered on the current selection, forwarded to
128
+ * `UdsListConfig.bulkActions`. Mirrors the placement of react-admin's
129
+ * `bulkActionButtons`, which is likewise a prop of the table view and not
130
+ * of `<List>`.
131
+ */
132
+ bulkActions?: UdsListAction[];
133
+ }
134
+ export interface DataTableProps extends ListViewActionProps {
135
+ children?: ReactNode;
136
+ }
137
+ /** Marker component for the table view. Never rendered. */
138
+ export declare function DataTable(_props: DataTableProps): null;
139
+ export declare namespace DataTable {
140
+ var Col: typeof DataTableCol;
141
+ }
142
+ /**
143
+ * **An extension beyond react-admin** (see the module doc): cards distributed
144
+ * into lanes by the value of one field — a pipeline rather than a ledger.
145
+ *
146
+ * The stacks are **lanes**, never "columns". `UdsListBoardLayout` spends a
147
+ * long comment on why the word is spent only once: this library ships a
148
+ * *column chooser*, and a user who opens a menu labelled "Columns" on a
149
+ * kanban and is shown field names has been misled by our vocabulary. The JSX
150
+ * honours the same rule — `groupBy` names the lane-forming field, exactly as
151
+ * the underlying layout member does, so the projection is one-to-one and
152
+ * there is no second vocabulary to keep in step.
153
+ */
154
+ export interface BoardProps extends ListViewActionProps {
155
+ /** The field whose value forms the lanes. Mirrors `UdsListBoardLayout.groupBy`. */
156
+ groupBy: string;
157
+ /** The lanes to render, in order. Omit to derive them from the data. */
158
+ lanes?: UdsListLane[];
159
+ /** The column whose value heads each card, by `field`. Defaults to the first. */
160
+ title?: string;
161
+ /** Which columns fill the card body, by `field`. Defaults to every other one. */
162
+ fields?: string[];
163
+ /** The narrowest a lane may become, as a CSS length. */
164
+ minLaneWidth?: string;
165
+ /** `<DataTable.Col>` children — the same columns a table would read. */
166
+ children?: ReactNode;
167
+ }
168
+ /** Marker component for the board view. Never rendered — see the module doc. */
169
+ export declare function Board(_props: BoardProps): null;
170
+ /**
171
+ * **An extension beyond react-admin** (see the module doc): rows as a
172
+ * responsive grid of cards — a catalogue rather than a ledger.
173
+ *
174
+ * Named `CardGrid` rather than `Grid` because a bare `Grid` reads as a
175
+ * generic layout primitive (it is one, in every component library this sits
176
+ * beside) rather than as a list *view*, and this is only ever the latter.
177
+ */
178
+ export interface CardGridProps extends ListViewActionProps {
179
+ /** The column whose value heads each card, by `field`. Defaults to the first. */
180
+ title?: string;
181
+ /** An image to lead each card with. Omit for text-only cards. */
182
+ media?: UdsListMedia;
183
+ /** Which columns fill the card body, by `field`. Defaults to every other one. */
184
+ fields?: string[];
185
+ /** The narrowest a card may become before the grid drops a column, as a CSS length. */
186
+ minColumnWidth?: string;
187
+ /** `<DataTable.Col>` children — the same columns a table would read. */
188
+ children?: ReactNode;
189
+ }
190
+ /** Marker component for the card-grid view. Never rendered — see the module doc. */
191
+ export declare function CardGrid(_props: CardGridProps): null;
192
+ export interface ListProps {
193
+ perPage?: number;
194
+ /**
195
+ * Passed straight through to `UdsAdminListConfig.filters` — a plain prop,
196
+ * not a child element, matching react-admin's own `<List filters={[...]}>`
197
+ * (see the module doc).
198
+ */
199
+ filters?: UdsListFilterField[];
200
+ /** The view child: `<DataTable>`, `<Board>` or `<CardGrid>`. */
201
+ children?: ReactNode;
202
+ }
203
+ /** Marker component for the list workflow. Never rendered — see the module doc. */
204
+ export declare function List(_props: ListProps): null;
205
+ /**
206
+ * Reads a `<List>` element's props and view child into a `UdsAdminListConfig`
207
+ * — the exact shape `GpResource`'s `config.list` takes (ADR 0022).
208
+ *
209
+ * `perPage` is a scalar, forwarded as `UdsAdminResource.perPage` rather than
210
+ * as a member of this config (see `admin-config.ts`'s `perPage` doc) — the
211
+ * caller (`resource.tsx`) is responsible for placing it there; this function
212
+ * only returns what belongs under `list`.
213
+ *
214
+ * The view child decides the `layout` and nothing else: all three read the
215
+ * same `<DataTable.Col>` children into the same `columns`, which is what
216
+ * makes swapping one for another a one-tag change (ADR 0016). A `<List>` with
217
+ * no recognised view child keeps the table default rather than rendering
218
+ * nothing, matching the behaviour before the board and grid views existed.
219
+ */
220
+ export declare function listConfigFromChildren(listChildren: ReactNode): UdsAdminListConfig;