@object-ui/core 17.2.0 → 17.5.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 (79) hide show
  1. package/CHANGELOG.md +1436 -0
  2. package/README.md +31 -12
  3. package/dist/actions/ActionEngine.d.ts +53 -31
  4. package/dist/actions/ActionEngine.js +87 -66
  5. package/dist/actions/ActionRunner.d.ts +215 -24
  6. package/dist/actions/ActionRunner.js +334 -17
  7. package/dist/actions/actionErrorDetail.d.ts +26 -0
  8. package/dist/actions/actionErrorDetail.js +37 -0
  9. package/dist/actions/actionKeys.d.ts +96 -20
  10. package/dist/actions/actionKeys.js +168 -18
  11. package/dist/actions/actionResponse.d.ts +42 -0
  12. package/dist/actions/actionResponse.js +104 -0
  13. package/dist/actions/index.d.ts +3 -0
  14. package/dist/actions/index.js +3 -0
  15. package/dist/actions/serverActionHandler.d.ts +143 -0
  16. package/dist/actions/serverActionHandler.js +137 -0
  17. package/dist/data-scope/ViewDataProvider.d.ts +37 -12
  18. package/dist/data-scope/ViewDataProvider.js +83 -5
  19. package/dist/data-scope/element-data-source.d.ts +113 -0
  20. package/dist/data-scope/element-data-source.js +216 -0
  21. package/dist/data-scope/index.d.ts +2 -1
  22. package/dist/data-scope/index.js +1 -0
  23. package/dist/evaluator/ExpressionEvaluator.js +4 -2
  24. package/dist/evaluator/declaredPredicate.d.ts +119 -0
  25. package/dist/evaluator/declaredPredicate.js +152 -0
  26. package/dist/evaluator/fieldRules.d.ts +42 -2
  27. package/dist/evaluator/fieldRules.js +101 -11
  28. package/dist/evaluator/index.d.ts +2 -0
  29. package/dist/evaluator/index.js +2 -0
  30. package/dist/evaluator/listConditional.d.ts +18 -3
  31. package/dist/evaluator/listConditional.js +0 -0
  32. package/dist/evaluator/optionRules.js +5 -1
  33. package/dist/evaluator/predicateInput.d.ts +132 -0
  34. package/dist/evaluator/predicateInput.js +129 -0
  35. package/dist/index.d.ts +7 -1
  36. package/dist/index.js +26 -1
  37. package/dist/protocols/DndProtocol.d.ts +42 -1
  38. package/dist/protocols/KeyboardProtocol.d.ts +31 -1
  39. package/dist/protocols/SharingProtocol.d.ts +11 -1
  40. package/dist/protocols/index.d.ts +0 -1
  41. package/dist/protocols/index.js +8 -1
  42. package/dist/registry/Registry.d.ts +24 -0
  43. package/dist/theme/ThemeEngine.d.ts +0 -8
  44. package/dist/theme/ThemeEngine.js +22 -103
  45. package/dist/theme/index.d.ts +1 -1
  46. package/dist/theme/index.js +7 -1
  47. package/dist/types/index.d.ts +42 -8
  48. package/dist/utils/chart-series.d.ts +258 -5
  49. package/dist/utils/chart-series.js +423 -20
  50. package/dist/utils/compare-to.d.ts +40 -13
  51. package/dist/utils/compare-to.js +4 -32
  52. package/dist/utils/dashboard-filters.d.ts +54 -8
  53. package/dist/utils/dashboard-filters.js +261 -12
  54. package/dist/utils/dataset-format.d.ts +79 -15
  55. package/dist/utils/dataset-format.js +130 -9
  56. package/dist/utils/dataset-pivot.d.ts +78 -0
  57. package/dist/utils/dataset-pivot.js +78 -0
  58. package/dist/utils/dom-props.d.ts +137 -0
  59. package/dist/utils/dom-props.js +153 -0
  60. package/dist/utils/filter-converter.d.ts +39 -11
  61. package/dist/utils/filter-converter.js +87 -7
  62. package/dist/utils/normalize-list-view.d.ts +26 -6
  63. package/dist/utils/normalize-list-view.js +30 -8
  64. package/dist/utils/number-display.d.ts +151 -0
  65. package/dist/utils/number-display.js +71 -0
  66. package/dist/utils/predicate-fields.d.ts +96 -0
  67. package/dist/utils/predicate-fields.js +163 -0
  68. package/dist/utils/predicate-record.d.ts +32 -0
  69. package/dist/utils/predicate-record.js +120 -0
  70. package/dist/utils/record-title.js +0 -0
  71. package/dist/utils/resolve-view-id.d.ts +31 -0
  72. package/dist/utils/resolve-view-id.js +45 -0
  73. package/dist/utils/sort-query.d.ts +55 -0
  74. package/dist/utils/sort-query.js +35 -0
  75. package/package.json +5 -5
  76. package/dist/protocols/NotificationProtocol.d.ts +0 -71
  77. package/dist/protocols/NotificationProtocol.js +0 -89
  78. package/dist/utils/merge-views-into-objects.d.ts +0 -19
  79. package/dist/utils/merge-views-into-objects.js +0 -39
@@ -15,7 +15,37 @@
15
15
  * @module protocols/KeyboardProtocol
16
16
  * @packageDocumentation
17
17
  */
18
- import type { KeyboardNavigationConfig, KeyboardShortcut, FocusTrapConfig } from '@object-ui/types';
18
+ /** A single keyboard shortcut binding. */
19
+ export interface KeyboardShortcut {
20
+ key: string;
21
+ action: string;
22
+ description?: string;
23
+ scope: 'global' | 'form' | 'modal' | 'view' | 'list';
24
+ }
25
+ /** Focus trap declaration for a modal-like region. */
26
+ export interface FocusTrapConfig {
27
+ enabled: boolean;
28
+ initialFocus?: string;
29
+ returnFocus: boolean;
30
+ escapeDeactivates: boolean;
31
+ }
32
+ /** Focus management declaration. */
33
+ export interface FocusManagement {
34
+ tabOrder: 'manual' | 'auto';
35
+ skipLinks: boolean;
36
+ focusVisible: boolean;
37
+ focusTrap?: FocusTrapConfig;
38
+ arrowNavigation: boolean;
39
+ }
40
+ /** Top-level keyboard navigation configuration. */
41
+ export interface KeyboardNavigationConfig {
42
+ shortcuts?: KeyboardShortcut[];
43
+ focusManagement?: FocusManagement;
44
+ rovingTabindex: boolean;
45
+ ariaLabel?: string;
46
+ ariaDescribedBy?: string;
47
+ role?: string;
48
+ }
19
49
  /** Fully resolved keyboard navigation configuration. */
20
50
  export interface ResolvedKeyboardConfig {
21
51
  shortcuts: KeyboardShortcut[];
@@ -15,7 +15,17 @@
15
15
  * @module protocols/SharingProtocol
16
16
  * @packageDocumentation
17
17
  */
18
- import type { SharingConfig, EmbedConfig } from '@object-ui/types';
18
+ import type { SharingConfig } from '@object-ui/types';
19
+ /** An iframe embed declaration. */
20
+ export interface EmbedConfig {
21
+ enabled: boolean;
22
+ allowedOrigins?: string[];
23
+ width?: string;
24
+ height?: string;
25
+ showHeader?: boolean;
26
+ showNavigation?: boolean;
27
+ responsive?: boolean;
28
+ }
19
29
  /** Fully resolved sharing configuration. */
20
30
  export interface ResolvedSharingConfig {
21
31
  enabled: boolean;
@@ -7,6 +7,5 @@
7
7
  */
8
8
  export * from './DndProtocol.js';
9
9
  export * from './KeyboardProtocol.js';
10
- export * from './NotificationProtocol.js';
11
10
  export * from './ResponsiveProtocol.js';
12
11
  export * from './SharingProtocol.js';
@@ -7,6 +7,13 @@
7
7
  */
8
8
  export * from './DndProtocol.js';
9
9
  export * from './KeyboardProtocol.js';
10
- export * from './NotificationProtocol.js';
10
+ // `NotificationProtocol` removed in the 17.0.0-rc.2 uptake: it bridged
11
+ // `@objectstack/spec/ui`'s `Notification` / `NotificationConfig`, which
12
+ // objectstack#4610 deleted with no successor. The bridge had zero consumers in
13
+ // this repo — the live notification config resolution is
14
+ // `resolveNotificationConfig` in `@object-ui/react`'s `NotificationContext`,
15
+ // which declares its own `NotificationSystemConfig` and is what every surface
16
+ // reads. Re-typing the bridge would have meant re-declaring a vocabulary the
17
+ // spec had just retired (AGENTS.md #0.1).
11
18
  export * from './ResponsiveProtocol.js';
12
19
  export * from './SharingProtocol.js';
@@ -43,6 +43,30 @@ export type ComponentMeta = {
43
43
  * registry.register('form', FormView, { namespace: 'view', skipFallback: true });
44
44
  */
45
45
  skipFallback?: boolean;
46
+ /**
47
+ * How a HOST must associate its own visible label with what this component
48
+ * renders (objectui#3961). Read by the form renderer; absent ⇒ `'control'`.
49
+ *
50
+ * - `'control'` — the component's outermost rendered element is a LABELABLE
51
+ * HTML element (`input` / `textarea` / `select` / `button` / …), so the host
52
+ * associates its label the plain way: `<label for>` → the id the host handed
53
+ * down. This is the default and covers every single-control widget.
54
+ * - `'group'` — it is NOT labelable: either a real composite (several inputs
55
+ * under one container, e.g. `address`) or a single control that is not a
56
+ * labelable element (a `div[role="button"]` dropzone, e.g. `file`). A
57
+ * `<label for>` pointing at such an element is inert in HTML — it activates
58
+ * nothing and contributes no accessible name (`HTMLLabelElement.control` is
59
+ * `null`) — so the host must instead give its label an `id` and hand the
60
+ * component `aria-labelledby`, which associates by IDREF and works on any
61
+ * element.
62
+ *
63
+ * This is a DECLARATION, not a guess: the host cannot infer it from the DOM a
64
+ * widget happens to render, and a widget that fails to declare it falls back
65
+ * to the `'control'` path where the dangling/inert `for` is caught by the
66
+ * label-association tests (objectui#3952) instead of silently producing an
67
+ * unlabelled group.
68
+ */
69
+ labelling?: 'control' | 'group';
46
70
  inputs?: ComponentInput[];
47
71
  defaultProps?: Record<string, any>;
48
72
  defaultChildren?: SchemaNode[];
@@ -43,14 +43,6 @@ export declare function generateBorderRadiusVars(borderRadius: NonNullable<Theme
43
43
  * Generate CSS custom properties from a Theme's shadow config.
44
44
  */
45
45
  export declare function generateShadowVars(shadows: NonNullable<Theme['shadows']>): Record<string, string>;
46
- /**
47
- * Generate CSS custom properties from a Theme's animation config.
48
- */
49
- export declare function generateAnimationVars(animation: NonNullable<Theme['animation']>): Record<string, string>;
50
- /**
51
- * Generate CSS custom properties from a Theme's z-index config.
52
- */
53
- export declare function generateZIndexVars(zIndex: NonNullable<Theme['zIndex']>): Record<string, string>;
54
46
  /**
55
47
  * Generate ALL CSS custom properties from a complete Theme.
56
48
  * This is the main entry point for theme → CSS conversion.
@@ -116,41 +116,33 @@ export function generateColorVars(colors) {
116
116
  /**
117
117
  * Generate CSS custom properties from a Theme's typography config.
118
118
  */
119
+ // ----------------------------------------------------------------------------
120
+ // RETIRED THEME BLOCKS — @objectstack/spec 17.0.0-rc.3 (objectstack#5021 option
121
+ // 2, PR objectstack#5289), objectui#3361.
122
+ //
123
+ // `theme.animation`, `theme.zIndex` and five typography groups
124
+ // (`fontSize` / `fontWeight` / `lineHeight` / `letterSpacing`, plus
125
+ // `fontFamily.heading` / `fontFamily.mono`) became TOMBSTONES: the schema now
126
+ // rejects them by name and their prescription points at `theme.customVars`, the
127
+ // declared — and since #5021 the only — door for a custom property. A
128
+ // `--z-modal` or a `--duration-fast` is authored there now, emitted verbatim as
129
+ // `--<key>: <value>`.
130
+ //
131
+ // The emission code below them was therefore structurally dead: no author can
132
+ // produce the input that would reach it. It is removed rather than left behind
133
+ // a cast, because the tombstoned keys type as `never` and any cast that made
134
+ // them compile would fossilize a shape the contract has withdrawn (AGENTS.md
135
+ // #0.1). LIVE emission — `colors`, `borderRadius`, `shadows`,
136
+ // `typography.fontFamily.base` (→ `--font-sans`) and `customVars` — is
137
+ // untouched, byte for byte.
138
+ // ----------------------------------------------------------------------------
119
139
  export function generateTypographyVars(typography) {
120
140
  const vars = {};
141
+ // `fontFamily.base` is the only surviving typography input — see the RETIRED
142
+ // THEME BLOCKS note above for where the other five groups went.
121
143
  if (typography.fontFamily?.base) {
122
144
  vars['--font-sans'] = typography.fontFamily.base;
123
145
  }
124
- if (typography.fontFamily?.heading) {
125
- vars['--font-heading'] = typography.fontFamily.heading;
126
- }
127
- if (typography.fontFamily?.mono) {
128
- vars['--font-mono'] = typography.fontFamily.mono;
129
- }
130
- if (typography.fontSize) {
131
- for (const [key, value] of Object.entries(typography.fontSize)) {
132
- if (value)
133
- vars[`--font-size-${key}`] = value;
134
- }
135
- }
136
- if (typography.fontWeight) {
137
- for (const [key, value] of Object.entries(typography.fontWeight)) {
138
- if (value != null)
139
- vars[`--font-weight-${key}`] = String(value);
140
- }
141
- }
142
- if (typography.lineHeight) {
143
- for (const [key, value] of Object.entries(typography.lineHeight)) {
144
- if (value)
145
- vars[`--line-height-${key}`] = value;
146
- }
147
- }
148
- if (typography.letterSpacing) {
149
- for (const [key, value] of Object.entries(typography.letterSpacing)) {
150
- if (value)
151
- vars[`--letter-spacing-${key}`] = value;
152
- }
153
- }
154
146
  return vars;
155
147
  }
156
148
  /**
@@ -197,36 +189,6 @@ export function generateShadowVars(shadows) {
197
189
  }
198
190
  return vars;
199
191
  }
200
- /**
201
- * Generate CSS custom properties from a Theme's animation config.
202
- */
203
- export function generateAnimationVars(animation) {
204
- const vars = {};
205
- if (animation.duration) {
206
- for (const [key, value] of Object.entries(animation.duration)) {
207
- if (value)
208
- vars[`--duration-${key}`] = value;
209
- }
210
- }
211
- if (animation.timing) {
212
- for (const [key, value] of Object.entries(animation.timing)) {
213
- if (value)
214
- vars[`--timing-${key}`] = value;
215
- }
216
- }
217
- return vars;
218
- }
219
- /**
220
- * Generate CSS custom properties from a Theme's z-index config.
221
- */
222
- export function generateZIndexVars(zIndex) {
223
- const vars = {};
224
- for (const [key, value] of Object.entries(zIndex)) {
225
- if (value != null)
226
- vars[`--z-${key}`] = String(value);
227
- }
228
- return vars;
229
- }
230
192
  /**
231
193
  * Generate ALL CSS custom properties from a complete Theme.
232
194
  * This is the main entry point for theme → CSS conversion.
@@ -247,14 +209,6 @@ export function generateThemeVars(theme) {
247
209
  if (theme.shadows) {
248
210
  Object.assign(vars, generateShadowVars(theme.shadows));
249
211
  }
250
- // Animation
251
- if (theme.animation) {
252
- Object.assign(vars, generateAnimationVars(theme.animation));
253
- }
254
- // Z-Index
255
- if (theme.zIndex) {
256
- Object.assign(vars, generateZIndexVars(theme.zIndex));
257
- }
258
212
  // Custom CSS variables (passthrough)
259
213
  if (theme.customVars) {
260
214
  for (const [key, value] of Object.entries(theme.customVars)) {
@@ -290,22 +244,6 @@ export function mergeThemes(parent, child) {
290
244
  ...parent.typography?.fontFamily,
291
245
  ...child.typography?.fontFamily,
292
246
  },
293
- fontSize: {
294
- ...parent.typography?.fontSize,
295
- ...child.typography?.fontSize,
296
- },
297
- fontWeight: {
298
- ...parent.typography?.fontWeight,
299
- ...child.typography?.fontWeight,
300
- },
301
- lineHeight: {
302
- ...parent.typography?.lineHeight,
303
- ...child.typography?.lineHeight,
304
- },
305
- letterSpacing: {
306
- ...parent.typography?.letterSpacing,
307
- ...child.typography?.letterSpacing,
308
- },
309
247
  }
310
248
  : undefined,
311
249
  // Deep-merge border radius
@@ -316,25 +254,6 @@ export function mergeThemes(parent, child) {
316
254
  shadows: child.shadows || parent.shadows
317
255
  ? { ...parent.shadows, ...child.shadows }
318
256
  : undefined,
319
- // Deep-merge animation
320
- animation: child.animation || parent.animation
321
- ? {
322
- ...parent.animation,
323
- ...child.animation,
324
- duration: {
325
- ...parent.animation?.duration,
326
- ...child.animation?.duration,
327
- },
328
- timing: {
329
- ...parent.animation?.timing,
330
- ...child.animation?.timing,
331
- },
332
- }
333
- : undefined,
334
- // Deep-merge zIndex
335
- zIndex: child.zIndex || parent.zIndex
336
- ? { ...parent.zIndex, ...child.zIndex }
337
- : undefined,
338
257
  // Deep-merge customVars
339
258
  customVars: child.customVars || parent.customVars
340
259
  ? { ...parent.customVars, ...child.customVars }
@@ -5,4 +5,4 @@
5
5
  * This source code is licensed under the MIT license found in the
6
6
  * LICENSE file in the root directory of this source tree.
7
7
  */
8
- export { hexToHSL, toCSSColor, generateColorVars, generateTypographyVars, generateBorderRadiusVars, generateShadowVars, generateAnimationVars, generateZIndexVars, generateThemeVars, mergeThemes, resolveThemeInheritance, resolveMode, contrastRatio, meetsContrastLevel, } from './ThemeEngine';
8
+ export { hexToHSL, toCSSColor, generateColorVars, generateTypographyVars, generateBorderRadiusVars, generateShadowVars, generateThemeVars, mergeThemes, resolveThemeInheritance, resolveMode, contrastRatio, meetsContrastLevel, } from './ThemeEngine';
@@ -5,4 +5,10 @@
5
5
  * This source code is licensed under the MIT license found in the
6
6
  * LICENSE file in the root directory of this source tree.
7
7
  */
8
- export { hexToHSL, toCSSColor, generateColorVars, generateTypographyVars, generateBorderRadiusVars, generateShadowVars, generateAnimationVars, generateZIndexVars, generateThemeVars, mergeThemes, resolveThemeInheritance, resolveMode, contrastRatio, meetsContrastLevel, } from './ThemeEngine';
8
+ export { hexToHSL, toCSSColor, generateColorVars, generateTypographyVars, generateBorderRadiusVars, generateShadowVars,
9
+ // `generateAnimationVars` / `generateZIndexVars` removed with the
10
+ // `theme.animation` / `theme.zIndex` tombstones in @objectstack/spec
11
+ // 17.0.0-rc.3 (objectstack#5021) — see ThemeEngine's RETIRED THEME BLOCKS
12
+ // note. `theme.customVars` is the declared door for a `--duration-*` or
13
+ // `--z-*` now.
14
+ generateThemeVars, mergeThemes, resolveThemeInheritance, resolveMode, contrastRatio, meetsContrastLevel, } from './ThemeEngine';
@@ -5,14 +5,48 @@
5
5
  * This source code is licensed under the MIT license found in the
6
6
  * LICENSE file in the root directory of this source tree.
7
7
  */
8
- export interface SchemaNode {
9
- type: string;
10
- id?: string;
11
- className?: string;
12
- data?: any;
13
- body?: SchemaNode | SchemaNode[];
14
- [key: string]: any;
15
- }
8
+ /**
9
+ * One `SchemaNode` (objectui#4580).
10
+ *
11
+ * This package used to hand-declare `interface SchemaNode { type: string; …
12
+ * [key: string]: any }` here, while `@object-ui/types` exported
13
+ * `type SchemaNode = BaseSchema | string | number | boolean | null | undefined`
14
+ * — two different types under one name, from two packages the same consumers
15
+ * import together. Which declaration a call site got depended on which package
16
+ * it happened to import from, and #4548's option-A canary measured **19 of 35**
17
+ * errors as exactly that collision:
18
+ *
19
+ * ```
20
+ * Type 'import(".../packages/types/dist/base").SchemaNode' is not assignable to
21
+ * type 'import(".../packages/core/dist/types/index").SchemaNode'
22
+ * ```
23
+ *
24
+ * PR #4578 sidestepped it — `SchemaRenderer` states its own component-level
25
+ * union rather than picking a side — and left the reconciliation to this card.
26
+ *
27
+ * **`@object-ui/types`' union wins**, per #4580's ruling 1: it is the spec of
28
+ * record (its own doc comment names `'Plain string'` a valid node), and it is
29
+ * the side the measured collisions resolve toward. The declaration is RE-EXPORTED
30
+ * rather than restated, so there is exactly one declaration left to disagree
31
+ * with — a structural copy would reproduce the defect the moment either side
32
+ * moved. This package already depends on `@object-ui/types`, so the edge exists
33
+ * and adds no cycle, and core's own entry surface is unchanged (`dist/index.d.ts`
34
+ * is byte-identical across the change — measured, both rounds).
35
+ *
36
+ * The collision is only observable from a package that resolves BOTH through
37
+ * `node_modules`; the pin therefore lives in `@object-ui/react`
38
+ * (`src/__tests__/SchemaNode.reconciliation.test.ts`), not here.
39
+ */
40
+ export type { SchemaNode } from '@object-ui/types';
41
+ import type { SchemaNode } from '@object-ui/types';
42
+ /**
43
+ * ⛔ Deliberately NOT reconciled with `@object-ui/types`' `ComponentRendererProps`
44
+ * (objectui#4594). The two declarations differ — types' is generic
45
+ * (`< TSchema extends BaseSchema = BaseSchema >`), this one is not — but that
46
+ * card measured **zero consumers** of this declaration, so reconciling it here
47
+ * would be an unmeasured change riding a card that was scoped to `SchemaNode`.
48
+ * It stays dual-declared until #4594 is dispatched on its own evidence.
49
+ */
16
50
  export interface ComponentRendererProps {
17
51
  schema: SchemaNode;
18
52
  [key: string]: any;