@loj-lang/rdsl-runtime 0.5.0 → 0.6.1

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 (125) hide show
  1. package/dist/components/Badge.d.ts +2 -1
  2. package/dist/components/Badge.d.ts.map +1 -1
  3. package/dist/components/Badge.js +2 -2
  4. package/dist/components/ConfirmDialog.d.ts +6 -1
  5. package/dist/components/ConfirmDialog.d.ts.map +1 -1
  6. package/dist/components/ConfirmDialog.js +35 -6
  7. package/dist/components/DataTable.d.ts +35 -2
  8. package/dist/components/DataTable.d.ts.map +1 -1
  9. package/dist/components/DataTable.js +64 -38
  10. package/dist/components/DropdownButton.d.ts +11 -0
  11. package/dist/components/DropdownButton.d.ts.map +1 -0
  12. package/dist/components/DropdownButton.js +9 -0
  13. package/dist/components/ErrorBoundary.d.ts +18 -0
  14. package/dist/components/ErrorBoundary.d.ts.map +1 -0
  15. package/dist/components/ErrorBoundary.js +19 -0
  16. package/dist/components/ErrorState.d.ts +6 -0
  17. package/dist/components/ErrorState.d.ts.map +1 -0
  18. package/dist/components/ErrorState.js +25 -0
  19. package/dist/components/FilterBar.d.ts +2 -0
  20. package/dist/components/FilterBar.d.ts.map +1 -1
  21. package/dist/components/FilterBar.js +3 -2
  22. package/dist/components/FormField.d.ts +7 -2
  23. package/dist/components/FormField.d.ts.map +1 -1
  24. package/dist/components/FormField.js +16 -5
  25. package/dist/components/GroupedDataTable.d.ts.map +1 -1
  26. package/dist/components/GroupedDataTable.js +40 -59
  27. package/dist/components/Pagination.js +1 -1
  28. package/dist/components/PivotDataTable.d.ts.map +1 -1
  29. package/dist/components/PivotDataTable.js +42 -65
  30. package/dist/components/Tag.d.ts +2 -1
  31. package/dist/components/Tag.d.ts.map +1 -1
  32. package/dist/components/Tag.js +2 -2
  33. package/dist/components/WorkflowSummary.js +6 -6
  34. package/dist/components/readFormatting.d.ts +2 -0
  35. package/dist/components/readFormatting.d.ts.map +1 -0
  36. package/dist/components/readFormatting.js +1 -0
  37. package/dist/derivations.d.ts +3 -0
  38. package/dist/derivations.d.ts.map +1 -0
  39. package/dist/derivations.js +1 -0
  40. package/dist/hooks/browserStorage.d.ts +3 -0
  41. package/dist/hooks/browserStorage.d.ts.map +1 -0
  42. package/dist/hooks/browserStorage.js +1 -0
  43. package/dist/hooks/deleteConfirmation.d.ts +20 -0
  44. package/dist/hooks/deleteConfirmation.d.ts.map +1 -0
  45. package/dist/hooks/deleteConfirmation.js +21 -0
  46. package/dist/hooks/exportDownload.d.ts +16 -0
  47. package/dist/hooks/exportDownload.d.ts.map +1 -0
  48. package/dist/hooks/exportDownload.js +55 -0
  49. package/dist/hooks/formDerivations.d.ts +7 -0
  50. package/dist/hooks/formDerivations.d.ts.map +1 -0
  51. package/dist/hooks/formDerivations.js +23 -0
  52. package/dist/hooks/formSeeds.d.ts +12 -0
  53. package/dist/hooks/formSeeds.d.ts.map +1 -0
  54. package/dist/hooks/formSeeds.js +26 -0
  55. package/dist/hooks/navigation.d.ts +37 -0
  56. package/dist/hooks/navigation.d.ts.map +1 -1
  57. package/dist/hooks/navigation.js +107 -70
  58. package/dist/hooks/readModelStore.d.ts +29 -0
  59. package/dist/hooks/readModelStore.d.ts.map +1 -0
  60. package/dist/hooks/readModelStore.js +135 -0
  61. package/dist/hooks/recordScopedWorkflow.d.ts +13 -0
  62. package/dist/hooks/recordScopedWorkflow.d.ts.map +1 -0
  63. package/dist/hooks/recordScopedWorkflow.js +40 -0
  64. package/dist/hooks/resourceClient.d.ts +39 -0
  65. package/dist/hooks/resourceClient.d.ts.map +1 -1
  66. package/dist/hooks/resourceClient.js +205 -71
  67. package/dist/hooks/resourceErrors.d.ts +13 -0
  68. package/dist/hooks/resourceErrors.d.ts.map +1 -0
  69. package/dist/hooks/resourceErrors.js +140 -0
  70. package/dist/hooks/resourceRowActions.d.ts +17 -0
  71. package/dist/hooks/resourceRowActions.d.ts.map +1 -0
  72. package/dist/hooks/resourceRowActions.js +48 -0
  73. package/dist/hooks/resourceStore.d.ts +2 -24
  74. package/dist/hooks/resourceStore.d.ts.map +1 -1
  75. package/dist/hooks/resourceStore.js +1 -164
  76. package/dist/hooks/resourceTarget.d.ts +1 -1
  77. package/dist/hooks/resourceTarget.d.ts.map +1 -1
  78. package/dist/hooks/resourceTarget.js +1 -22
  79. package/dist/hooks/serverListStore.d.ts +3 -0
  80. package/dist/hooks/serverListStore.d.ts.map +1 -0
  81. package/dist/hooks/serverListStore.js +1 -0
  82. package/dist/hooks/sessionCaches.d.ts +6 -0
  83. package/dist/hooks/sessionCaches.d.ts.map +1 -0
  84. package/dist/hooks/sessionCaches.js +14 -0
  85. package/dist/hooks/transitionedSetter.d.ts +2 -0
  86. package/dist/hooks/transitionedSetter.d.ts.map +1 -0
  87. package/dist/hooks/transitionedSetter.js +9 -0
  88. package/dist/hooks/useAuth.d.ts +18 -0
  89. package/dist/hooks/useAuth.d.ts.map +1 -1
  90. package/dist/hooks/useAuth.js +30 -0
  91. package/dist/hooks/useCollectionView.d.ts +2 -8
  92. package/dist/hooks/useCollectionView.d.ts.map +1 -1
  93. package/dist/hooks/useCollectionView.js +8 -36
  94. package/dist/hooks/useDocumentMetadata.d.ts.map +1 -1
  95. package/dist/hooks/useDocumentMetadata.js +57 -0
  96. package/dist/hooks/useGroupedCollectionView.d.ts +2 -7
  97. package/dist/hooks/useGroupedCollectionView.d.ts.map +1 -1
  98. package/dist/hooks/useGroupedCollectionView.js +8 -52
  99. package/dist/hooks/useI18n.d.ts +21 -0
  100. package/dist/hooks/useI18n.d.ts.map +1 -0
  101. package/dist/hooks/useI18n.js +86 -0
  102. package/dist/hooks/useReadModel.d.ts +15 -0
  103. package/dist/hooks/useReadModel.d.ts.map +1 -1
  104. package/dist/hooks/useReadModel.js +127 -40
  105. package/dist/hooks/useResource.d.ts +7 -0
  106. package/dist/hooks/useResource.d.ts.map +1 -1
  107. package/dist/hooks/useResource.js +159 -3
  108. package/dist/hooks/useStoredState.d.ts +15 -0
  109. package/dist/hooks/useStoredState.d.ts.map +1 -0
  110. package/dist/hooks/useStoredState.js +28 -0
  111. package/dist/hooks/useToast.d.ts.map +1 -1
  112. package/dist/hooks/useToast.js +1 -1
  113. package/dist/hooks/workflowTransition.d.ts +21 -0
  114. package/dist/hooks/workflowTransition.d.ts.map +1 -0
  115. package/dist/hooks/workflowTransition.js +54 -0
  116. package/dist/index.d.ts +35 -9
  117. package/dist/index.d.ts.map +1 -1
  118. package/dist/index.js +21 -5
  119. package/dist/policies/can.d.ts +2 -14
  120. package/dist/policies/can.d.ts.map +1 -1
  121. package/dist/policies/can.js +1 -160
  122. package/dist/workflow.d.ts +3 -0
  123. package/dist/workflow.d.ts.map +1 -0
  124. package/dist/workflow.js +1 -0
  125. package/package.json +142 -26
@@ -1,6 +1,7 @@
1
1
  export interface BadgeProps {
2
2
  value: string;
3
3
  colors: Record<string, string>;
4
+ displayValue?: string;
4
5
  }
5
- export declare function Badge({ value, colors }: BadgeProps): JSX.Element;
6
+ export declare function Badge({ value, colors, displayValue }: BadgeProps): JSX.Element;
6
7
  //# sourceMappingURL=Badge.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"Badge.d.ts","sourceRoot":"","sources":["../../src/components/Badge.tsx"],"names":[],"mappings":"AAEA,MAAM,WAAW,UAAU;IACzB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAChC;AAED,wBAAgB,KAAK,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE,UAAU,eAOlD"}
1
+ {"version":3,"file":"Badge.d.ts","sourceRoot":"","sources":["../../src/components/Badge.tsx"],"names":[],"mappings":"AAEA,MAAM,WAAW,UAAU;IACzB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC/B,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,wBAAgB,KAAK,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,YAAY,EAAE,EAAE,UAAU,eAOhE"}
@@ -1,5 +1,5 @@
1
1
  import React from 'react';
2
- export function Badge({ value, colors }) {
2
+ export function Badge({ value, colors, displayValue }) {
3
3
  const color = colors[value] ?? 'gray';
4
- return (React.createElement("span", { className: "rdsl-badge", style: { border: `1px solid ${color}`, color, padding: '0.125rem 0.5rem', borderRadius: '0.375rem' } }, value));
4
+ return (React.createElement("span", { className: "rdsl-badge", style: { border: `1px solid ${color}`, color, padding: '0.125rem 0.5rem', borderRadius: '0.375rem' } }, displayValue ?? value));
5
5
  }
@@ -3,6 +3,11 @@ export interface ConfirmDialogProps {
3
3
  message: string;
4
4
  onConfirm: () => void | Promise<void>;
5
5
  onCancel: () => void;
6
+ intent?: 'default' | 'delete' | 'archive';
7
+ confirmLabel?: string;
6
8
  }
7
- export declare function ConfirmDialog({ open, message, onConfirm, onCancel }: ConfirmDialogProps): JSX.Element | null;
9
+ export declare function resolveConfirmDialogIntent(props: Pick<ConfirmDialogProps, 'intent'>): 'default' | 'delete' | 'archive';
10
+ export declare function resolveConfirmDialogConfirmLabel(props: Pick<ConfirmDialogProps, 'intent' | 'confirmLabel'>): string;
11
+ export declare function resolveConfirmDialogConfirmClassName(props: Pick<ConfirmDialogProps, 'intent'>): string | undefined;
12
+ export declare function ConfirmDialog({ open, message, onConfirm, onCancel, intent, confirmLabel }: ConfirmDialogProps): JSX.Element | null;
8
13
  //# sourceMappingURL=ConfirmDialog.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"ConfirmDialog.d.ts","sourceRoot":"","sources":["../../src/components/ConfirmDialog.tsx"],"names":[],"mappings":"AAEA,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,OAAO,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACtC,QAAQ,EAAE,MAAM,IAAI,CAAC;CACtB;AAED,wBAAgB,aAAa,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,EAAE,kBAAkB,sBAkBvF"}
1
+ {"version":3,"file":"ConfirmDialog.d.ts","sourceRoot":"","sources":["../../src/components/ConfirmDialog.tsx"],"names":[],"mappings":"AAOA,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,OAAO,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACtC,QAAQ,EAAE,MAAM,IAAI,CAAC;IACrB,MAAM,CAAC,EAAE,SAAS,GAAG,QAAQ,GAAG,SAAS,CAAC;IAC1C,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,wBAAgB,0BAA0B,CACxC,KAAK,EAAE,IAAI,CAAC,kBAAkB,EAAE,QAAQ,CAAC,GACxC,SAAS,GAAG,QAAQ,GAAG,SAAS,CAElC;AAED,wBAAgB,gCAAgC,CAC9C,KAAK,EAAE,IAAI,CAAC,kBAAkB,EAAE,QAAQ,GAAG,cAAc,CAAC,GACzD,MAAM,CAER;AAED,wBAAgB,oCAAoC,CAClD,KAAK,EAAE,IAAI,CAAC,kBAAkB,EAAE,QAAQ,CAAC,GACxC,MAAM,GAAG,SAAS,CAEpB;AAED,wBAAgB,aAAa,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,EAAE,YAAY,EAAE,EAAE,kBAAkB,sBAqC7G"}
@@ -1,11 +1,40 @@
1
1
  import React from 'react';
2
- export function ConfirmDialog({ open, message, onConfirm, onCancel }) {
2
+ import { resolveConfirmClassName, resolveConfirmIntent, resolveConfirmLabel, } from '../../../runtime-core/dist/tableUi.js';
3
+ export function resolveConfirmDialogIntent(props) {
4
+ return resolveConfirmIntent(props);
5
+ }
6
+ export function resolveConfirmDialogConfirmLabel(props) {
7
+ return resolveConfirmLabel(props);
8
+ }
9
+ export function resolveConfirmDialogConfirmClassName(props) {
10
+ return resolveConfirmClassName(props);
11
+ }
12
+ export function ConfirmDialog({ open, message, onConfirm, onCancel, intent, confirmLabel }) {
13
+ const [confirmInFlight, setConfirmInFlight] = React.useState(false);
14
+ React.useEffect(() => {
15
+ if (!open) {
16
+ setConfirmInFlight(false);
17
+ }
18
+ }, [open]);
19
+ const handleConfirm = React.useCallback(() => {
20
+ if (confirmInFlight) {
21
+ return;
22
+ }
23
+ setConfirmInFlight(true);
24
+ void Promise.resolve(onConfirm())
25
+ .catch(() => undefined)
26
+ .finally(() => {
27
+ setConfirmInFlight(false);
28
+ });
29
+ }, [confirmInFlight, onConfirm]);
3
30
  if (!open)
4
31
  return null;
5
- return (React.createElement("div", { className: "rdsl-dialog-backdrop", role: "presentation" },
6
- React.createElement("div", { className: "rdsl-dialog", role: "dialog", "aria-modal": "true", "aria-label": "Confirmation dialog" },
32
+ const resolvedIntent = resolveConfirmDialogIntent({ intent });
33
+ const resolvedConfirmLabel = resolveConfirmDialogConfirmLabel({ intent, confirmLabel });
34
+ return (React.createElement("div", { role: "presentation" },
35
+ React.createElement("div", { role: "dialog", "aria-modal": "true", "aria-label": "Confirmation dialog" },
7
36
  React.createElement("p", null, message),
8
- React.createElement("div", { className: "rdsl-dialog-actions" },
9
- React.createElement("button", { type: "button", className: "rdsl-btn rdsl-btn-secondary", onClick: onCancel }, "Cancel"),
10
- React.createElement("button", { type: "button", className: "rdsl-btn rdsl-btn-danger", onClick: () => void onConfirm() }, "Confirm")))));
37
+ React.createElement("div", null,
38
+ React.createElement("button", { type: "button", "data-intent": "default", onClick: onCancel, disabled: confirmInFlight }, "Cancel"),
39
+ React.createElement("button", { type: "button", "data-intent": resolvedIntent, onClick: handleConfirm, disabled: confirmInFlight }, resolvedConfirmLabel)))));
11
40
  }
@@ -2,7 +2,9 @@ export interface DataTableColumn<T> {
2
2
  key: string;
3
3
  label: string;
4
4
  sortable?: boolean;
5
- format?: 'date';
5
+ format?: 'date' | 'number' | 'decimal';
6
+ enumKeyPrefix?: string;
7
+ enumLabels?: Record<string, string>;
6
8
  render?: (value: unknown, record: T) => React.ReactNode;
7
9
  }
8
10
  export interface DataTableAction<T> {
@@ -10,6 +12,7 @@ export interface DataTableAction<T> {
10
12
  href?: (row: T) => string;
11
13
  onClick?: (row: T) => void | Promise<void>;
12
14
  variant?: 'default' | 'danger';
15
+ intent?: 'default' | 'delete' | 'archive';
13
16
  }
14
17
  export interface SortState {
15
18
  field: string;
@@ -26,9 +29,39 @@ export interface DataTableProps<T extends {
26
29
  actions?: readonly DataTableAction<T>[];
27
30
  selectedRowId?: string | null;
28
31
  onSelectRow?: (row: T) => void;
32
+ selectedRowIds?: string[];
33
+ onToggleRowSelection?: (row: T, checked: boolean) => void;
34
+ onToggleAllRowsSelection?: (checked: boolean) => void;
29
35
  selectionName?: string;
30
36
  }
37
+ export declare function resolveDataTableActionIntent<T extends {
38
+ id: string;
39
+ }>(action: DataTableAction<T>): 'default' | 'delete' | 'archive';
40
+ export declare function resolveDataTableActionClassName<T extends {
41
+ id: string;
42
+ }>(action: DataTableAction<T>): string | undefined;
43
+ export declare function buildDeleteTableAction<T extends {
44
+ id: string;
45
+ }>(options: {
46
+ label: string;
47
+ onClick: (row: T) => void | Promise<void>;
48
+ softDelete: boolean;
49
+ }): DataTableAction<T>;
50
+ export declare function buildResourceTableActions<T extends {
51
+ id: string;
52
+ }>(resourceName: string, options?: {
53
+ includeView?: boolean;
54
+ includeEdit?: boolean;
55
+ includeWorkflow?: boolean;
56
+ returnTo?: string | null;
57
+ deleteAction?: {
58
+ label: string;
59
+ onClick: (row: T) => void | Promise<void>;
60
+ softDelete: boolean;
61
+ };
62
+ }): DataTableAction<T>[];
63
+ export declare function formatDataTableValue(value: unknown, format?: 'date' | 'number' | 'decimal', enumKeyPrefix?: string, enumLabels?: Record<string, string>): React.ReactNode;
31
64
  export declare function DataTable<T extends {
32
65
  id: string;
33
- }>({ columns, data, loading, sort, onSortChange, actions, selectedRowId, onSelectRow, selectionName, }: DataTableProps<T>): JSX.Element;
66
+ }>({ columns, data, loading, sort, onSortChange, actions, selectedRowId, onSelectRow, selectedRowIds, onToggleRowSelection, onToggleAllRowsSelection, selectionName, }: DataTableProps<T>): JSX.Element;
34
67
  //# sourceMappingURL=DataTable.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"DataTable.d.ts","sourceRoot":"","sources":["../../src/components/DataTable.tsx"],"names":[],"mappings":"AAEA,MAAM,WAAW,eAAe,CAAC,CAAC;IAChC,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC,KAAK,KAAK,CAAC,SAAS,CAAC;CACzD;AAED,MAAM,WAAW,eAAe,CAAC,CAAC;IAChC,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,CAAC,GAAG,EAAE,CAAC,KAAK,MAAM,CAAC;IAC1B,OAAO,CAAC,EAAE,CAAC,GAAG,EAAE,CAAC,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC3C,OAAO,CAAC,EAAE,SAAS,GAAG,QAAQ,CAAC;CAChC;AAED,MAAM,WAAW,SAAS;IACxB,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,KAAK,GAAG,MAAM,CAAC;CAC3B;AAED,MAAM,WAAW,cAAc,CAAC,CAAC,SAAS;IAAE,EAAE,EAAE,MAAM,CAAA;CAAE;IACtD,OAAO,EAAE,SAAS,eAAe,CAAC,CAAC,CAAC,EAAE,CAAC;IACvC,IAAI,EAAE,CAAC,EAAE,CAAC;IACV,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,IAAI,CAAC,EAAE,SAAS,GAAG,IAAI,CAAC;IACxB,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,SAAS,GAAG,IAAI,KAAK,IAAI,CAAC;IAChD,OAAO,CAAC,EAAE,SAAS,eAAe,CAAC,CAAC,CAAC,EAAE,CAAC;IACxC,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,WAAW,CAAC,EAAE,CAAC,GAAG,EAAE,CAAC,KAAK,IAAI,CAAC;IAC/B,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAmBD,wBAAgB,SAAS,CAAC,CAAC,SAAS;IAAE,EAAE,EAAE,MAAM,CAAA;CAAE,EAAE,EAClD,OAAO,EACP,IAAI,EACJ,OAAe,EACf,IAAW,EACX,YAAY,EACZ,OAAY,EACZ,aAAoB,EACpB,WAAW,EACX,aAAsC,GACvC,EAAE,cAAc,CAAC,CAAC,CAAC,eAmGnB"}
1
+ {"version":3,"file":"DataTable.d.ts","sourceRoot":"","sources":["../../src/components/DataTable.tsx"],"names":[],"mappings":"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"}
@@ -1,58 +1,84 @@
1
1
  import React from 'react';
2
- function formatValue(value, format) {
3
- if (value === null || value === undefined || value === '')
4
- return '';
5
- if (format !== 'date')
6
- return String(value);
7
- const date = new Date(String(value));
8
- return Number.isNaN(date.getTime()) ? String(value) : date.toLocaleString();
2
+ import { nextTableSortState, resolveTableActionClassName, resolveTableActionIntent, } from '../../../runtime-core/dist/tableUi.js';
3
+ import { buildAppHrefWithSearchEntries, prefixAppBasePath } from '../hooks/navigation.js';
4
+ import { formatReadValue } from './readFormatting.js';
5
+ export function resolveDataTableActionIntent(action) {
6
+ return resolveTableActionIntent(action);
9
7
  }
10
- function nextSortState(current, field) {
11
- if (!current || current.field !== field) {
12
- return { field, direction: 'asc' };
8
+ export function resolveDataTableActionClassName(action) {
9
+ return resolveTableActionClassName(action);
10
+ }
11
+ export function buildDeleteTableAction(options) {
12
+ return {
13
+ label: options.label,
14
+ onClick: options.onClick,
15
+ variant: options.softDelete ? 'default' : 'danger',
16
+ intent: options.softDelete ? 'archive' : 'delete',
17
+ };
18
+ }
19
+ export function buildResourceTableActions(resourceName, options = {}) {
20
+ const actions = [];
21
+ const buildHref = (rowId, suffix = '') => {
22
+ const path = `/${resourceName}/${rowId}${suffix}`;
23
+ return options.returnTo
24
+ ? buildAppHrefWithSearchEntries(path, [['returnTo', options.returnTo]])
25
+ : prefixAppBasePath(path);
26
+ };
27
+ if (options.includeView) {
28
+ actions.push({ label: 'View', href: (row) => buildHref(String(row.id)) });
29
+ }
30
+ if (options.includeEdit) {
31
+ actions.push({ label: 'Edit', href: (row) => buildHref(String(row.id), '/edit') });
32
+ }
33
+ if (options.includeWorkflow) {
34
+ actions.push({ label: 'Workflow', href: (row) => buildHref(String(row.id), '/workflow') });
13
35
  }
14
- if (current.direction === 'asc') {
15
- return { field, direction: 'desc' };
36
+ if (options.deleteAction) {
37
+ actions.push(buildDeleteTableAction(options.deleteAction));
16
38
  }
17
- return null;
39
+ return actions;
18
40
  }
19
- export function DataTable({ columns, data, loading = false, sort = null, onSortChange, actions = [], selectedRowId = null, onSelectRow, selectionName = 'rdsl-table-selection', }) {
20
- const hasSelection = Boolean(onSelectRow);
21
- return (React.createElement("div", { className: "rdsl-data-table" },
41
+ export function formatDataTableValue(value, format, enumKeyPrefix, enumLabels) {
42
+ return formatReadValue(value, format, enumKeyPrefix, enumLabels);
43
+ }
44
+ export function DataTable({ columns, data, loading = false, sort = null, onSortChange, actions = [], selectedRowId = null, onSelectRow, selectedRowIds = [], onToggleRowSelection, onToggleAllRowsSelection, selectionName = 'rdsl-table-selection', }) {
45
+ const hasSingleSelection = Boolean(onSelectRow);
46
+ const hasMultiSelection = Boolean(onToggleRowSelection);
47
+ const hasSelection = hasSingleSelection || hasMultiSelection;
48
+ const selectedIdSet = React.useMemo(() => new Set(selectedRowIds.map((id) => String(id))), [selectedRowIds]);
49
+ const allRowsSelected = hasMultiSelection && data.length > 0 && data.every((record) => selectedIdSet.has(String(record.id)));
50
+ return (React.createElement("div", null,
22
51
  React.createElement("table", null,
23
52
  React.createElement("thead", null,
24
53
  React.createElement("tr", null,
25
- hasSelection ? React.createElement("th", null, "Select") : null,
54
+ hasSelection ? (React.createElement("th", null, hasMultiSelection ? (React.createElement("input", { type: "checkbox", "aria-label": "Select all rows", checked: allRowsSelected, onChange: (event) => onToggleAllRowsSelection?.(event.currentTarget.checked) })) : ('Select'))) : null,
26
55
  columns.map((column) => {
27
56
  const sortable = Boolean(column.sortable && onSortChange);
28
57
  const activeSort = sort?.field === column.key ? sort.direction : null;
29
- return (React.createElement("th", { key: column.key }, sortable ? (React.createElement("button", { type: "button", className: "rdsl-table-sort", onClick: () => onSortChange?.(nextSortState(sort, column.key)) },
58
+ return (React.createElement("th", { key: column.key }, sortable ? (React.createElement("button", { type: "button", onClick: () => onSortChange?.(nextTableSortState(sort, column.key)) },
30
59
  column.label,
31
60
  activeSort ? ` ${activeSort === 'asc' ? '↑' : '↓'}` : '')) : (column.label)));
32
61
  }),
33
62
  actions.length > 0 ? React.createElement("th", null, "Actions") : null)),
34
63
  React.createElement("tbody", null,
35
- loading ? (React.createElement("tr", null,
64
+ loading && data.length === 0 ? (React.createElement("tr", null,
36
65
  React.createElement("td", { colSpan: columns.length + (actions.length > 0 ? 1 : 0) + (hasSelection ? 1 : 0) }, "Loading..."))) : null,
66
+ loading && data.length > 0 ? (React.createElement("tr", null,
67
+ React.createElement("td", { colSpan: columns.length + (actions.length > 0 ? 1 : 0) + (hasSelection ? 1 : 0) }, "Refreshing..."))) : null,
37
68
  !loading && data.length === 0 ? (React.createElement("tr", null,
38
69
  React.createElement("td", { colSpan: columns.length + (actions.length > 0 ? 1 : 0) + (hasSelection ? 1 : 0) }, "No records"))) : null,
39
- !loading
40
- ? data.map((record) => (React.createElement("tr", { key: record.id },
41
- hasSelection ? (React.createElement("td", null,
42
- React.createElement("input", { type: "radio", name: selectionName, checked: selectedRowId === String(record.id), onChange: () => onSelectRow?.(record) }))) : null,
43
- columns.map((column) => {
44
- const value = record[column.key];
45
- return (React.createElement("td", { key: column.key }, column.render ? column.render(value, record) : formatValue(value, column.format)));
46
- }),
47
- actions.length > 0 ? (React.createElement("td", null,
48
- React.createElement("div", { className: "rdsl-table-actions" }, actions.map((action) => {
49
- const className = action.variant === 'danger'
50
- ? 'rdsl-btn rdsl-btn-danger'
51
- : 'rdsl-btn rdsl-btn-secondary';
52
- if (action.href) {
53
- return (React.createElement("a", { key: action.label, className: className, href: action.href(record) }, action.label));
54
- }
55
- return (React.createElement("button", { key: action.label, type: "button", className: className, onClick: () => action.onClick?.(record) }, action.label));
56
- })))) : null)))
57
- : null))));
70
+ data.map((record) => (React.createElement("tr", { key: record.id },
71
+ hasSelection ? (React.createElement("td", null, hasMultiSelection ? (React.createElement("input", { type: "checkbox", checked: selectedIdSet.has(String(record.id)), onChange: (event) => onToggleRowSelection?.(record, event.currentTarget.checked) })) : (React.createElement("input", { type: "radio", name: selectionName, checked: selectedRowId === String(record.id), onChange: () => onSelectRow?.(record) })))) : null,
72
+ columns.map((column) => {
73
+ const value = record[column.key];
74
+ return (React.createElement("td", { key: column.key }, column.render ? column.render(value, record) : formatDataTableValue(value, column.format, column.enumKeyPrefix, column.enumLabels)));
75
+ }),
76
+ actions.length > 0 ? (React.createElement("td", null,
77
+ React.createElement("div", null, actions.map((action) => {
78
+ const intent = resolveDataTableActionIntent(action);
79
+ if (action.href) {
80
+ return (React.createElement("a", { key: action.label, "data-intent": intent, href: action.href(record) }, action.label));
81
+ }
82
+ return (React.createElement("button", { key: action.label, type: "button", "data-intent": intent, onClick: () => action.onClick?.(record) }, action.label));
83
+ })))) : null)))))));
58
84
  }
@@ -0,0 +1,11 @@
1
+ export interface DropdownButtonProps {
2
+ label: React.ReactNode;
3
+ children?: React.ReactNode;
4
+ }
5
+ export interface MenuItemProps {
6
+ children?: React.ReactNode;
7
+ onClick?: () => void | Promise<void>;
8
+ }
9
+ export declare function DropdownButton({ label, children }: DropdownButtonProps): JSX.Element;
10
+ export declare function MenuItem({ children, onClick }: MenuItemProps): JSX.Element;
11
+ //# sourceMappingURL=DropdownButton.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DropdownButton.d.ts","sourceRoot":"","sources":["../../src/components/DropdownButton.tsx"],"names":[],"mappings":"AAEA,MAAM,WAAW,mBAAmB;IAClC,KAAK,EAAE,KAAK,CAAC,SAAS,CAAC;IACvB,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;CAC5B;AAED,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC3B,OAAO,CAAC,EAAE,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACtC;AAED,wBAAgB,cAAc,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAE,EAAE,mBAAmB,eAStE;AAED,wBAAgB,QAAQ,CAAC,EAAE,QAAQ,EAAE,OAAO,EAAE,EAAE,aAAa,eAM5D"}
@@ -0,0 +1,9 @@
1
+ import React from 'react';
2
+ export function DropdownButton({ label, children }) {
3
+ return (React.createElement("details", null,
4
+ React.createElement("summary", { "data-intent": "default" }, label),
5
+ React.createElement("div", { role: "menu" }, children)));
6
+ }
7
+ export function MenuItem({ children, onClick }) {
8
+ return (React.createElement("button", { type: "button", "data-intent": "default", role: "menuitem", onClick: () => void onClick?.() }, children));
9
+ }
@@ -0,0 +1,18 @@
1
+ import * as React from 'react';
2
+ export interface ErrorBoundaryProps {
3
+ children?: any;
4
+ message?: string;
5
+ }
6
+ interface ErrorBoundaryState {
7
+ readonly hasError: boolean;
8
+ readonly error?: Error;
9
+ }
10
+ export declare class ErrorBoundary extends React.Component<ErrorBoundaryProps, ErrorBoundaryState> {
11
+ props: ErrorBoundaryProps;
12
+ state: ErrorBoundaryState;
13
+ constructor(props: ErrorBoundaryProps);
14
+ static getDerivedStateFromError(error: Error): ErrorBoundaryState;
15
+ render(): any;
16
+ }
17
+ export {};
18
+ //# sourceMappingURL=ErrorBoundary.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ErrorBoundary.d.ts","sourceRoot":"","sources":["../../src/components/ErrorBoundary.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAG/B,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,EAAE,GAAG,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,UAAU,kBAAkB;IAC1B,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC;IAC3B,QAAQ,CAAC,KAAK,CAAC,EAAE,KAAK,CAAC;CACxB;AAED,qBAAa,aAAc,SAAQ,KAAK,CAAC,SAAS,CAAC,kBAAkB,EAAE,kBAAkB,CAAC;IACxF,KAAK,EAAE,kBAAkB,CAAC;IAC1B,KAAK,EAAE,kBAAkB,CAAuB;gBAEpC,KAAK,EAAE,kBAAkB;IAKrC,MAAM,CAAC,wBAAwB,CAAC,KAAK,EAAE,KAAK,GAAG,kBAAkB;IAIjE,MAAM;CAMP"}
@@ -0,0 +1,19 @@
1
+ import * as React from 'react';
2
+ import { ErrorState } from './ErrorState.js';
3
+ export class ErrorBoundary extends React.Component {
4
+ props;
5
+ state = { hasError: false };
6
+ constructor(props) {
7
+ super(props);
8
+ this.props = props;
9
+ }
10
+ static getDerivedStateFromError(error) {
11
+ return { hasError: true, error };
12
+ }
13
+ render() {
14
+ if (this.state.hasError) {
15
+ return React.createElement(ErrorState, { error: this.state.error, message: this.props.message ?? 'Something went wrong' });
16
+ }
17
+ return this.props.children;
18
+ }
19
+ }
@@ -0,0 +1,6 @@
1
+ export interface ErrorStateProps {
2
+ error?: unknown;
3
+ message?: string;
4
+ }
5
+ export declare function ErrorState({ error, message }: ErrorStateProps): JSX.Element;
6
+ //# sourceMappingURL=ErrorState.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ErrorState.d.ts","sourceRoot":"","sources":["../../src/components/ErrorState.tsx"],"names":[],"mappings":"AAGA,MAAM,WAAW,eAAe;IAC9B,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAoBD,wBAAgB,UAAU,CAAC,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE,eAAe,eAK7D"}
@@ -0,0 +1,25 @@
1
+ import React from 'react';
2
+ import { ResourceClientError } from '../hooks/resourceClient.js';
3
+ function resolveFallbackMessage(error) {
4
+ if (error instanceof ResourceClientError) {
5
+ if (error.offline) {
6
+ return 'You appear to be offline. Check your connection and try again.';
7
+ }
8
+ if (error.status === 429 && typeof error.retryAfterSeconds === 'number') {
9
+ return `Too many requests. Try again in ${error.retryAfterSeconds} seconds.`;
10
+ }
11
+ if (error.message.trim() !== '') {
12
+ return error.message;
13
+ }
14
+ }
15
+ if (error instanceof Error && error.message.trim() !== '') {
16
+ return error.message;
17
+ }
18
+ return 'Something went wrong. Please try again.';
19
+ }
20
+ export function ErrorState({ error, message }) {
21
+ const resolvedMessage = typeof message === 'string' && message.trim() !== ''
22
+ ? message
23
+ : resolveFallbackMessage(error);
24
+ return React.createElement("div", null, resolvedMessage);
25
+ }
@@ -3,6 +3,8 @@ export interface FilterField {
3
3
  label: string;
4
4
  type: 'text' | 'select';
5
5
  options?: readonly string[];
6
+ optionKeyPrefix?: string;
7
+ optionLabels?: Record<string, string>;
6
8
  }
7
9
  export interface FilterBarProps {
8
10
  fields: readonly FilterField[];
@@ -1 +1 @@
1
- {"version":3,"file":"FilterBar.d.ts","sourceRoot":"","sources":["../../src/components/FilterBar.tsx"],"names":[],"mappings":"AAEA,MAAM,WAAW,WAAW;IAC1B,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,GAAG,QAAQ,CAAC;IACxB,OAAO,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CAC7B;AAED,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,SAAS,WAAW,EAAE,CAAC;IAC/B,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC/B,QAAQ,EAAE,CAAC,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,KAAK,IAAI,CAAC;CACxD;AAED,wBAAgB,SAAS,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,EAAE,cAAc,eAoErE"}
1
+ {"version":3,"file":"FilterBar.d.ts","sourceRoot":"","sources":["../../src/components/FilterBar.tsx"],"names":[],"mappings":"AAGA,MAAM,WAAW,WAAW;IAC1B,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,GAAG,QAAQ,CAAC;IACxB,OAAO,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAC5B,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACvC;AAED,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,SAAS,WAAW,EAAE,CAAC;IAC/B,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC/B,QAAQ,EAAE,CAAC,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,KAAK,IAAI,CAAC;CACxD;AAED,wBAAgB,SAAS,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,EAAE,cAAc,eAoErE"}
@@ -1,4 +1,5 @@
1
1
  import React from 'react';
2
+ import { resolveEnumValueText } from '../hooks/useI18n.js';
2
3
  export function FilterBar({ fields, values, onChange }) {
3
4
  const [draftValues, setDraftValues] = React.useState(values);
4
5
  const composingFieldKeyRef = React.useRef(null);
@@ -20,11 +21,11 @@ export function FilterBar({ fields, values, onChange }) {
20
21
  [fieldKey]: value,
21
22
  }));
22
23
  }, []);
23
- return (React.createElement("div", { className: "rdsl-filter-bar" }, fields.map((field) => (React.createElement("label", { key: field.key, className: "rdsl-filter-field" },
24
+ return (React.createElement("div", null, fields.map((field) => (React.createElement("label", { key: field.key },
24
25
  React.createElement("span", null, field.label),
25
26
  field.type === 'select' ? (React.createElement("select", { value: values[field.key] ?? '', onChange: (event) => commitChange(field.key, String(event?.target?.value ?? '')) },
26
27
  React.createElement("option", { value: "" }, "All"),
27
- (field.options ?? []).map((option) => (React.createElement("option", { key: option, value: option }, option))))) : (React.createElement("input", { type: "text", value: draftValues[field.key] ?? values[field.key] ?? '', onCompositionStart: () => {
28
+ (field.options ?? []).map((option) => (React.createElement("option", { key: option, value: option }, resolveEnumValueText(option, field.optionKeyPrefix, field.optionLabels)))))) : (React.createElement("input", { type: "text", value: draftValues[field.key] ?? values[field.key] ?? '', onCompositionStart: () => {
28
29
  composingFieldKeyRef.current = field.key;
29
30
  }, onCompositionEnd: (event) => {
30
31
  const nextValue = String(event?.target?.value ?? '');
@@ -3,6 +3,7 @@ export interface FieldSchema {
3
3
  pattern?: RegExp;
4
4
  minLength?: number;
5
5
  unique?: true;
6
+ displayAs?: 'number' | 'decimal';
6
7
  }
7
8
  export interface SelectOption {
8
9
  value: string;
@@ -11,12 +12,16 @@ export interface SelectOption {
11
12
  export interface FormFieldProps {
12
13
  label: string;
13
14
  name: string;
14
- type: 'text' | 'number' | 'checkbox' | 'datetime' | 'select';
15
+ type: 'text' | 'number' | 'checkbox' | 'date' | 'datetime' | 'select';
15
16
  value: unknown;
16
17
  onChange: (value: unknown) => void;
17
18
  schema?: FieldSchema;
18
19
  options?: readonly (string | SelectOption)[];
20
+ optionKeyPrefix?: string;
21
+ optionLabels?: Record<string, string>;
19
22
  disabled?: boolean;
23
+ error?: string | null;
20
24
  }
21
- export declare function FormField({ label, name, type, value, onChange, schema, options, disabled, }: FormFieldProps): JSX.Element;
25
+ export declare function resolveFieldTextInputMode(schema?: FieldSchema): 'numeric' | 'decimal' | undefined;
26
+ export declare function FormField({ label, name, type, value, onChange, schema, options, optionKeyPrefix, optionLabels, disabled, error, }: FormFieldProps): JSX.Element;
22
27
  //# sourceMappingURL=FormField.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"FormField.d.ts","sourceRoot":"","sources":["../../src/components/FormField.tsx"],"names":[],"mappings":"AAEA,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,EAAE,IAAI,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,IAAI,CAAC;CACf;AAED,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,GAAG,QAAQ,GAAG,UAAU,GAAG,UAAU,GAAG,QAAQ,CAAC;IAC7D,KAAK,EAAE,OAAO,CAAC;IACf,QAAQ,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,CAAC;IACnC,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,OAAO,CAAC,EAAE,SAAS,CAAC,MAAM,GAAG,YAAY,CAAC,EAAE,CAAC;IAC7C,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAsBD,wBAAgB,SAAS,CAAC,EACxB,KAAK,EACL,IAAI,EACJ,IAAI,EACJ,KAAK,EACL,QAAQ,EACR,MAAM,EACN,OAAO,EACP,QAAgB,GACjB,EAAE,cAAc,eA2EhB"}
1
+ {"version":3,"file":"FormField.d.ts","sourceRoot":"","sources":["../../src/components/FormField.tsx"],"names":[],"mappings":"AAGA,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,EAAE,IAAI,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,IAAI,CAAC;IACd,SAAS,CAAC,EAAE,QAAQ,GAAG,SAAS,CAAC;CAClC;AAED,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,GAAG,QAAQ,GAAG,UAAU,GAAG,MAAM,GAAG,UAAU,GAAG,QAAQ,CAAC;IACtE,KAAK,EAAE,OAAO,CAAC;IACf,QAAQ,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,CAAC;IACnC,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,OAAO,CAAC,EAAE,SAAS,CAAC,MAAM,GAAG,YAAY,CAAC,EAAE,CAAC;IAC7C,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACtC,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACvB;AAsBD,wBAAgB,yBAAyB,CAAC,MAAM,CAAC,EAAE,WAAW,GAAG,SAAS,GAAG,SAAS,GAAG,SAAS,CAQjG;AAED,wBAAgB,SAAS,CAAC,EACxB,KAAK,EACL,IAAI,EACJ,IAAI,EACJ,KAAK,EACL,QAAQ,EACR,MAAM,EACN,OAAO,EACP,eAAe,EACf,YAAY,EACZ,QAAgB,EAChB,KAAY,GACb,EAAE,cAAc,eA6EhB"}
@@ -1,4 +1,5 @@
1
1
  import React from 'react';
2
+ import { resolveEnumValueText } from '../hooks/useI18n.js';
2
3
  function coerceValue(type, event) {
3
4
  const target = event?.target;
4
5
  if (type === 'checkbox')
@@ -23,7 +24,16 @@ function describeSchema(schema) {
23
24
  hints.push('Must be unique');
24
25
  return hints.length > 0 ? hints.join(' • ') : null;
25
26
  }
26
- export function FormField({ label, name, type, value, onChange, schema, options, disabled = false, }) {
27
+ export function resolveFieldTextInputMode(schema) {
28
+ if (schema?.displayAs === 'number') {
29
+ return 'numeric';
30
+ }
31
+ if (schema?.displayAs === 'decimal') {
32
+ return 'decimal';
33
+ }
34
+ return undefined;
35
+ }
36
+ export function FormField({ label, name, type, value, onChange, schema, options, optionKeyPrefix, optionLabels, disabled = false, error = null, }) {
27
37
  const hint = describeSchema(schema);
28
38
  const isTextLikeInput = type === 'text';
29
39
  const externalValue = String(value ?? '');
@@ -35,16 +45,16 @@ export function FormField({ label, name, type, value, onChange, schema, options,
35
45
  }
36
46
  setDraftValue(externalValue);
37
47
  }, [externalValue, isTextLikeInput]);
38
- return (React.createElement("label", { className: "rdsl-form-field" },
48
+ return (React.createElement("label", null,
39
49
  React.createElement("span", null, label),
40
50
  type === 'select' ? (React.createElement("select", { name: name, value: String(value ?? ''), disabled: disabled, onChange: (event) => onChange(event?.target?.value ?? '') },
41
51
  React.createElement("option", { value: "" }, "Select..."),
42
52
  (options ?? []).map((option) => {
43
53
  const normalized = typeof option === 'string'
44
- ? { value: option, label: option }
54
+ ? { value: option, label: resolveEnumValueText(option, optionKeyPrefix, optionLabels) }
45
55
  : option;
46
56
  return (React.createElement("option", { key: normalized.value, value: normalized.value }, normalized.label));
47
- }))) : type === 'checkbox' ? (React.createElement("input", { name: name, type: "checkbox", checked: Boolean(value), disabled: disabled, onChange: (event) => onChange(coerceValue(type, event)) })) : (React.createElement("input", { name: name, type: type === 'datetime' ? 'datetime-local' : type, value: isTextLikeInput ? draftValue : type === 'number' ? String(value ?? '') : String(value ?? ''), disabled: disabled, onCompositionStart: isTextLikeInput ? (() => {
57
+ }))) : type === 'checkbox' ? (React.createElement("input", { name: name, type: "checkbox", checked: Boolean(value), disabled: disabled, onChange: (event) => onChange(coerceValue(type, event)) })) : (React.createElement("input", { name: name, type: type === 'datetime' ? 'datetime-local' : type, value: isTextLikeInput ? draftValue : type === 'number' ? String(value ?? '') : String(value ?? ''), inputMode: isTextLikeInput ? resolveFieldTextInputMode(schema) : undefined, disabled: disabled, onCompositionStart: isTextLikeInput ? (() => {
48
58
  isComposingRef.current = true;
49
59
  }) : undefined, onCompositionEnd: isTextLikeInput ? ((event) => {
50
60
  const nextValue = String(event?.target?.value ?? '');
@@ -62,5 +72,6 @@ export function FormField({ label, name, type, value, onChange, schema, options,
62
72
  onChange(nextValue);
63
73
  }
64
74
  } })),
65
- hint ? React.createElement("small", { className: "rdsl-form-hint" }, hint) : null));
75
+ hint ? React.createElement("small", null, hint) : null,
76
+ error ? React.createElement("small", null, error) : null));
66
77
  }
@@ -1 +1 @@
1
- {"version":3,"file":"GroupedDataTable.d.ts","sourceRoot":"","sources":["../../src/components/GroupedDataTable.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAE,eAAe,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAElF,MAAM,WAAW,qBAAqB,CAAC,CAAC,SAAS;IAAE,EAAE,EAAE,MAAM,CAAA;CAAE;IAC7D,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAChC,IAAI,EAAE,CAAC,EAAE,CAAC;CACX;AAED,MAAM,WAAW,qBAAqB,CAAC,CAAC,SAAS;IAAE,EAAE,EAAE,MAAM,CAAA;CAAE;IAC7D,OAAO,EAAE,SAAS,eAAe,CAAC,CAAC,CAAC,EAAE,CAAC;IACvC,OAAO,EAAE,SAAS,MAAM,EAAE,CAAC;IAC3B,MAAM,EAAE,KAAK,CAAC,qBAAqB,CAAC,CAAC,CAAC,CAAC,CAAC;IACxC,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,IAAI,CAAC,EAAE,SAAS,GAAG,IAAI,CAAC;IACxB,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,SAAS,GAAG,IAAI,KAAK,IAAI,CAAC;IAChD,OAAO,CAAC,EAAE,SAAS,eAAe,CAAC,CAAC,CAAC,EAAE,CAAC;IACxC,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,WAAW,CAAC,EAAE,CAAC,GAAG,EAAE,CAAC,KAAK,IAAI,CAAC;IAC/B,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAmBD,wBAAgB,gBAAgB,CAAC,CAAC,SAAS;IAAE,EAAE,EAAE,MAAM,CAAA;CAAE,EAAE,EACzD,OAAO,EACP,OAAO,EACP,MAAM,EACN,OAAe,EACf,IAAW,EACX,YAAY,EACZ,OAAY,EACZ,aAAoB,EACpB,WAAW,EACX,aAA8C,GAC/C,EAAE,qBAAqB,CAAC,CAAC,CAAC,eA+G1B"}
1
+ {"version":3,"file":"GroupedDataTable.d.ts","sourceRoot":"","sources":["../../src/components/GroupedDataTable.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,eAAe,EAAE,eAAe,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAElF,MAAM,WAAW,qBAAqB,CAAC,CAAC,SAAS;IAAE,EAAE,EAAE,MAAM,CAAA;CAAE;IAC7D,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAChC,IAAI,EAAE,CAAC,EAAE,CAAC;CACX;AAED,MAAM,WAAW,qBAAqB,CAAC,CAAC,SAAS;IAAE,EAAE,EAAE,MAAM,CAAA;CAAE;IAC7D,OAAO,EAAE,SAAS,eAAe,CAAC,CAAC,CAAC,EAAE,CAAC;IACvC,OAAO,EAAE,SAAS,MAAM,EAAE,CAAC;IAC3B,MAAM,EAAE,KAAK,CAAC,qBAAqB,CAAC,CAAC,CAAC,CAAC,CAAC;IACxC,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,IAAI,CAAC,EAAE,SAAS,GAAG,IAAI,CAAC;IACxB,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,SAAS,GAAG,IAAI,KAAK,IAAI,CAAC;IAChD,OAAO,CAAC,EAAE,SAAS,eAAe,CAAC,CAAC,CAAC,EAAE,CAAC;IACxC,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,WAAW,CAAC,EAAE,CAAC,GAAG,EAAE,CAAC,KAAK,IAAI,CAAC;IAC/B,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,wBAAgB,gBAAgB,CAAC,CAAC,SAAS;IAAE,EAAE,EAAE,MAAM,CAAA;CAAE,EAAE,EACzD,OAAO,EACP,OAAO,EACP,MAAM,EACN,OAAe,EACf,IAAW,EACX,YAAY,EACZ,OAAY,EACZ,aAAoB,EACpB,WAAW,EACX,aAA8C,GAC/C,EAAE,qBAAqB,CAAC,CAAC,CAAC,eA0G1B"}