@object-ui/components 11.4.0 → 13.1.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.
- package/CHANGELOG.md +149 -0
- package/dist/hooks/related-count-store.d.ts +8 -0
- package/dist/index.css +12 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +2208 -2104
- package/dist/index.umd.cjs +3 -3
- package/dist/renderers/complex/data-table.d.ts +33 -4
- package/package.json +39 -39
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,154 @@
|
|
|
1
1
|
# @object-ui/components
|
|
2
2
|
|
|
3
|
+
## 13.1.0
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- @object-ui/types@13.1.0
|
|
8
|
+
- @object-ui/core@13.1.0
|
|
9
|
+
- @object-ui/i18n@13.1.0
|
|
10
|
+
- @object-ui/react@13.1.0
|
|
11
|
+
- @object-ui/react-runtime@13.1.0
|
|
12
|
+
- @object-ui/sdui-parser@13.1.0
|
|
13
|
+
|
|
14
|
+
## 13.0.0
|
|
15
|
+
|
|
16
|
+
### Patch Changes
|
|
17
|
+
|
|
18
|
+
- ac04b76: Data-table row menu: honor each custom row action's `visible` (and `disabled`) predicate.
|
|
19
|
+
|
|
20
|
+
The data-table's inline row overflow menu — used by a record detail page's related list — rendered every custom row action unconditionally, ignoring the action's `visible` CEL. ObjectGrid's row menu already evaluates `visible` per row (`RowActionMenuItem`), so the two row-menu paths disagreed: on an organization's Members tab, `sys_member`'s `transfer_ownership` action (`visible: "record.role != 'owner' && …"`) showed on the owner's own row.
|
|
21
|
+
|
|
22
|
+
Each custom action now renders through a hook-safe `DataTableRowActionItem` that mirrors `RowActionMenuItem`, evaluating `visible`/`disabled` with `useCondition`/`toPredicateInput` against the same per-row context (`{ ...row, record: row }`); `features`/`user` resolve from the ambient `ExpressionProvider` scope, so gating matches the grid. Rendering-layer only — the action definitions are unchanged.
|
|
23
|
+
|
|
24
|
+
- 619097e: Adopt `@objectstack/spec` 13 (ADR-0090 Permission Model v2) across the workspace.
|
|
25
|
+
|
|
26
|
+
Every workspace package now depends on `@objectstack/spec` ^13.0.0 — the v2 major that renames role → position (D3), removes the profile concept (D2), makes OWD default to `private` when unset (D1), and drops the legacy `read`/`read_write`/`full` sharing aliases (D4). UI fallout fixed in the same sweep:
|
|
27
|
+
|
|
28
|
+
- **clientValidation**: the `role` draft-schema loader is now `position` → `PositionSchema` (fixes the `RoleSchema does not exist` build break, #2365); the dead `profile` loader is removed (D2).
|
|
29
|
+
- **Studio previews**: `RolePreview` → `PositionPreview` (flat — positions carry no hierarchy; the old parent-chain breadcrumb and "assign to a Profile" copy are gone). Legacy `role`/`profile` preview keys stay registered for pre-v2 backends.
|
|
30
|
+
- **OWD control** (`ObjectSettingsPanel`): removed the now-dead alias normalization (spec 13 rejects the aliases at authoring time) and the amber "fully public" warning — an unset sharing model now defaults to Private (D1), and the copy says so in both locales.
|
|
31
|
+
- **Fallback schemas / anchors / samples**: `position` replaces the hierarchical `role` fallback schema; `isProfile` dropped from the permission create-anchor and previews samples; permission-set viewer no longer renders a profile badge; console System hub counts `sys_position` instead of the removed `sys_role`.
|
|
32
|
+
- **Studio i18n**: type labels `Role/角色` → `Position/岗位`, `profile` label removed, Access-pillar heading and sharing copy rewritten to the v2 vocabulary.
|
|
33
|
+
- `@object-ui/types` now exports `SubmitBehavior` (was defined but missing from the public surface, breaking `@object-ui/plugin-form`'s re-export under a clean build).
|
|
34
|
+
- **External OWD dial (D11)**: the object Settings sharing card gains an `externalSharingModel` select (portal/partner baseline) with an inline wider-than-internal warning mirroring the publish-time lint.
|
|
35
|
+
- **Permission matrix OWD badges**: every object row now shows its record-level baseline (`OWD Public read`, `Ext Private`, or `OWD Private (default)` for the D1 fail-closed unset case) so grant edits carry their record-reach context.
|
|
36
|
+
|
|
37
|
+
The flow designer's approval assignee `role` kind is intentionally unchanged — spec 13 keeps it as the sole D3 exception (better-auth `sys_member.role` org-membership tier).
|
|
38
|
+
|
|
39
|
+
- Updated dependencies [9e38270]
|
|
40
|
+
- Updated dependencies [619097e]
|
|
41
|
+
- @object-ui/i18n@13.0.0
|
|
42
|
+
- @object-ui/types@13.0.0
|
|
43
|
+
- @object-ui/react@13.0.0
|
|
44
|
+
- @object-ui/core@13.0.0
|
|
45
|
+
- @object-ui/react-runtime@13.0.0
|
|
46
|
+
- @object-ui/sdui-parser@13.0.0
|
|
47
|
+
|
|
48
|
+
## 12.1.0
|
|
49
|
+
|
|
50
|
+
### Minor Changes
|
|
51
|
+
|
|
52
|
+
- c31874d: Record-header actions honour `Action.order`, so approval decisions no longer get buried in the `⋯` overflow menu (objectui#2339 / framework#2670).
|
|
53
|
+
|
|
54
|
+
The `action:bar` renderer now stable-sorts its actions by an explicit **`order`** field (lower = higher / more prominent, default `0`) before the inline/overflow split. The sort is stable and treats unset `order` as `0`, so action groups where nobody sets `order` keep their exact registration order — existing toolbars are unaffected. `order` is added to `ActionSchema` in `@object-ui/types`, mirroring `Action.order` in `@objectstack/spec`.
|
|
55
|
+
|
|
56
|
+
`RecordDetailView` now assigns the injected **Approve / Reject** decision buttons a strongly-negative `order` (and gives Approve the highlighted `primary` variant), so on a pending-approval record the approver's decision takes the primary-button slot and app `record_header` actions follow it — instead of the app having to hide its own actions to surface the decision.
|
|
57
|
+
|
|
58
|
+
### Patch Changes
|
|
59
|
+
|
|
60
|
+
- 6cbccf3: Localize form validation messages, toast client-side validation failures, and make native date/time picker icons legible in dark mode.
|
|
61
|
+
|
|
62
|
+
Record-form validation messages (required, min/max length, min/max value, pattern, email, URL) were hard-coded English even when the field label was localized — e.g. a Chinese "计划开始日期" field showed "计划开始日期 is required". `buildValidationRules` baked English strings, so the form renderer's `t(...)` fallback never applied. It now emits `required: true` and, for the other rules, a `messageKey` + `undefined` message (a field-authored `*_message` still wins and passes through verbatim); the form renderer fills the blanks via i18n (`validation.*` keys already exist in every locale), so messages track the label's language.
|
|
63
|
+
|
|
64
|
+
When client-side validation blocks a submit, the offending field's inline error can sit below the fold in a long modal/drawer form — the user clicks 创建 and sees nothing happen. The form renderer now also fires a `toast.error` naming the fields (`validation.formInvalid`, added to all 10 locales), mirroring the existing server-error toast so the feedback is visible regardless of scroll position.
|
|
65
|
+
|
|
66
|
+
Separately, native controls now declare `color-scheme` (`light` on `:root`, `dark` on `.dark`), so the webkit calendar-picker-indicator and other built-in glyphs render light-on-dark instead of vanishing against the dark input background.
|
|
67
|
+
|
|
68
|
+
- Updated dependencies [6cbccf3]
|
|
69
|
+
- Updated dependencies [e1840bf]
|
|
70
|
+
- Updated dependencies [c31874d]
|
|
71
|
+
- @object-ui/i18n@12.1.0
|
|
72
|
+
- @object-ui/types@12.1.0
|
|
73
|
+
- @object-ui/react@12.1.0
|
|
74
|
+
- @object-ui/core@12.1.0
|
|
75
|
+
- @object-ui/react-runtime@12.1.0
|
|
76
|
+
- @object-ui/sdui-parser@12.1.0
|
|
77
|
+
|
|
78
|
+
## 12.0.0
|
|
79
|
+
|
|
80
|
+
### Minor Changes
|
|
81
|
+
|
|
82
|
+
- 226fde9: Cascading & role-gated `select` options (#2284).
|
|
83
|
+
|
|
84
|
+
`select` options now accept a per-option `visibleWhen` CEL predicate — the option
|
|
85
|
+
is offered only when it evaluates TRUE against the live record **plus
|
|
86
|
+
`current_user`** (same engine/env as a field-level `visibleWhen`). Combined with a
|
|
87
|
+
field-level `dependsOn`, this drives dependent selects (country → province → city)
|
|
88
|
+
and role/context gating with no bespoke matrix — the same primitives dependent
|
|
89
|
+
lookups (#2215) already use.
|
|
90
|
+
|
|
91
|
+
- `@object-ui/core` exposes `resolveVisibleOptions` / `isOptionGroupGated` /
|
|
92
|
+
`resolveDependsOnFields` / `isValueStillOffered` (evaluator), reusing the
|
|
93
|
+
canonical `evalFieldPredicate`.
|
|
94
|
+
- The form renderer narrows a dependent select's option list, gates the control
|
|
95
|
+
with a "Select {parent} first" hint while a `dependsOn` field is empty, and
|
|
96
|
+
clears a now-invalid value when the parent changes.
|
|
97
|
+
- The standalone `SelectField` widget applies the same resolution via
|
|
98
|
+
`dependentValues` + the global predicate scope.
|
|
99
|
+
|
|
100
|
+
Client-side hiding is UX, not authorization: gate authorization-sensitive option
|
|
101
|
+
values on the server too. Aligns with `@objectstack/spec` `SelectOption.visibleWhen`.
|
|
102
|
+
|
|
103
|
+
- e4de456: Fix form section grouping inconsistencies found in a UX review of grouped forms:
|
|
104
|
+
|
|
105
|
+
- **Unified section visual language.** `FormSection`'s Card-wrapped path (used by Modal/Split/Tabbed/Wizard forms) previously rendered as a nearly-invisible white-on-white card (same `bg-card` as the page background, distinguished only by a barely-visible shadow) with a duplicated, inconsistent header (different title size, and a collapse chevron positioned differently) versus the flat `SectionDivider` path used by simple/drawer forms. Both now share the same header treatment (`text-sm font-semibold`, inline-left chevron, bottom border), and the Card path gets a soft `bg-muted/40` tint so grouped sections are visually distinguishable without relying on shadow alone.
|
|
106
|
+
- **`readonly` no longer renders as `disabled`.** A field marked `readonly` (statically or via `readonlyWhen`) was being folded into the `disabled` prop before reaching field widgets, so widgets with a dedicated readonly display (e.g. `EmailField`'s mailto link, `TextField`'s plain-text view) never received it — every readonly field just looked permanently disabled. `readonly` is now forwarded as its own prop; generic `input`/`textarea` fields get a distinct readonly style (`bg-muted/40`, no `cursor-not-allowed`) instead of the disabled look.
|
|
107
|
+
- **Section `className`/`gridClassName` now flow through JSON schemas.** `ObjectFormSection` and the per-form-variant section configs (`ModalFormSectionConfig`, `SplitFormSectionConfig`, `FormSectionConfig`, `DrawerFormSectionConfig`) accept `className` (and `gridClassName` where applicable), wired through `ObjectForm`'s form-type dispatch into `FormSection`/`SectionDivider` — closing a gap where section wrappers couldn't be customized from schema despite `FormSection` itself already supporting it.
|
|
108
|
+
|
|
109
|
+
### Patch Changes
|
|
110
|
+
|
|
111
|
+
- Updated dependencies [226fde9]
|
|
112
|
+
- Updated dependencies [e4de456]
|
|
113
|
+
- @object-ui/types@12.0.0
|
|
114
|
+
- @object-ui/core@12.0.0
|
|
115
|
+
- @object-ui/react@12.0.0
|
|
116
|
+
- @object-ui/i18n@12.0.0
|
|
117
|
+
- @object-ui/react-runtime@12.0.0
|
|
118
|
+
- @object-ui/sdui-parser@12.0.0
|
|
119
|
+
|
|
120
|
+
## 11.5.0
|
|
121
|
+
|
|
122
|
+
### Minor Changes
|
|
123
|
+
|
|
124
|
+
- 6fffd3d: Client-side data-invalidation bus — refresh data, don't rebuild UI (objectui#2269 P1).
|
|
125
|
+
|
|
126
|
+
- `@object-ui/react` gains the bus: `notifyDataChanged({objectName, recordId?})`, `useDataInvalidation(objectName, recordId?)` (reader nonce), `subscribeDataChanges`, and `useMutationInvalidationBridge(dataSource)` which fans every dataSource write (`MutationEvent`) onto the bus. The bus also dispatches the legacy `objectui:related-changed` window event, so pre-bus listeners keep working.
|
|
127
|
+
- The `key={refreshKey}` remount of `RecordDetailView` (AppContent) and the `key={actionRefreshKey}` remount of `DetailView` (RecordDetailView) are GONE: record data now refetches in place via the bus — scroll, collapsed sections, tabs and in-progress inline edits survive every save/action/undo. All nine action-success bumps became precisely-scoped `notifyDataChanged` calls; undo/redo use the operation's own `objectName`/`recordId`.
|
|
128
|
+
- `RelatedCountStore` is wired to the bus (tab count badges refetch after any change to their object) and its `useSyncExternalStore` snapshot is now a monotonic version — previously it returned the same `Map` reference, so `emit()` never re-rendered subscribers and invalidations left badges stale; `useRelatedCountVersion()` is exported and drives the probe effect's re-fetch.
|
|
129
|
+
- app-shell also gains the reserved URL-param registry (`urlParams.ts` — `form`/`formObject`/`formLink`/`tab`/`recordId`/`palette`/`shortcuts` constants replace scattered string literals) and AGENTS.md Commandment #8 (UI-state classification: state that must survive a data refresh may never live only in an uncontrolled component).
|
|
130
|
+
|
|
131
|
+
- 9255686: Record detail tabs are URL-addressable (`?tab=`) and survive subtree remounts (objectui#2257, ADR-0054 C3).
|
|
132
|
+
|
|
133
|
+
- `buildDefaultTabs` emits STABLE semantic tab values (`details` / `related:<child>` / `related` / `activity` / `history`) instead of leaving the renderer to synthesize index-derived ones.
|
|
134
|
+
- `PageTabsRenderer` honors `item.value`, a host-provided `schema.defaultTab` (validated against actual tabs) and `schema.onTabChange`; index fallback kept for authored schemas without values.
|
|
135
|
+
- app-shell `RecordDetailView` restores the active tab from `?tab=` and writes it back with `replace` (tab switches never stack history), via the pure `withPageTabsUrlSync` page-tree injector (never mutates authored/memoized page schemas). Legacy `DetailView.autoTabs` wired to the same contract (`defaultTab`/`onTabChange`).
|
|
136
|
+
- Fixes the tab strip resetting to Details after save-refresh remounts (`refreshKey`-style) and dev-StrictMode URL churn; enables `?tab=` deep links; invalid values fall back to Details.
|
|
137
|
+
|
|
138
|
+
### Patch Changes
|
|
139
|
+
|
|
140
|
+
- Updated dependencies [544d8eb]
|
|
141
|
+
- Updated dependencies [6fffd3d]
|
|
142
|
+
- Updated dependencies [9255686]
|
|
143
|
+
- Updated dependencies [fae75e2]
|
|
144
|
+
- Updated dependencies [1072701]
|
|
145
|
+
- @object-ui/i18n@11.5.0
|
|
146
|
+
- @object-ui/react@11.5.0
|
|
147
|
+
- @object-ui/types@11.5.0
|
|
148
|
+
- @object-ui/core@11.5.0
|
|
149
|
+
- @object-ui/react-runtime@11.5.0
|
|
150
|
+
- @object-ui/sdui-parser@11.5.0
|
|
151
|
+
|
|
3
152
|
## 11.4.0
|
|
4
153
|
|
|
5
154
|
### Patch Changes
|
|
@@ -56,6 +56,14 @@ declare function invalidateAll(): void;
|
|
|
56
56
|
* probe is in flight or before the first request.
|
|
57
57
|
*/
|
|
58
58
|
export declare function useRelatedCount(objectName: string | undefined, relField: string | undefined, parentId: string | undefined): number | undefined;
|
|
59
|
+
/**
|
|
60
|
+
* Subscribe to the store's monotonic version. Put it in an effect dependency
|
|
61
|
+
* array to RE-RUN count probes after an invalidation (#2269) — invalidate
|
|
62
|
+
* deletes the cached numbers, and this version bump is what makes the probe
|
|
63
|
+
* effect fetch them again (fetchCount returns cached values without emitting,
|
|
64
|
+
* so the loop settles once every probed key is warm again).
|
|
65
|
+
*/
|
|
66
|
+
export declare function useRelatedCountVersion(): number;
|
|
59
67
|
/**
|
|
60
68
|
* Imperative store API for non-React callers (mutation handlers, tests).
|
|
61
69
|
* Prefer `useRelatedCount` in components.
|
package/dist/index.css
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! tailwindcss v4.3.
|
|
1
|
+
/*! tailwindcss v4.3.2 | MIT License | https://tailwindcss.com */
|
|
2
2
|
@layer properties;
|
|
3
3
|
@layer theme, base, components, utilities;
|
|
4
4
|
@layer theme {
|
|
@@ -1255,6 +1255,9 @@
|
|
|
1255
1255
|
.cursor-grab {
|
|
1256
1256
|
cursor: grab;
|
|
1257
1257
|
}
|
|
1258
|
+
.cursor-not-allowed {
|
|
1259
|
+
cursor: not-allowed;
|
|
1260
|
+
}
|
|
1258
1261
|
.cursor-pointer {
|
|
1259
1262
|
cursor: pointer;
|
|
1260
1263
|
}
|
|
@@ -3675,6 +3678,12 @@
|
|
|
3675
3678
|
border-color: var(--color-ring);
|
|
3676
3679
|
}
|
|
3677
3680
|
}
|
|
3681
|
+
.focus-visible\:ring-0 {
|
|
3682
|
+
&:focus-visible {
|
|
3683
|
+
--tw-ring-shadow: var(--tw-ring-inset,) 0 0 0 calc(0px + var(--tw-ring-offset-width)) var(--tw-ring-color, currentcolor);
|
|
3684
|
+
box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow);
|
|
3685
|
+
}
|
|
3686
|
+
}
|
|
3678
3687
|
.focus-visible\:ring-1 {
|
|
3679
3688
|
&:focus-visible {
|
|
3680
3689
|
--tw-ring-shadow: var(--tw-ring-inset,) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color, currentcolor);
|
|
@@ -6262,6 +6271,7 @@
|
|
|
6262
6271
|
}
|
|
6263
6272
|
}
|
|
6264
6273
|
:root {
|
|
6274
|
+
color-scheme: light;
|
|
6265
6275
|
--background: 0 0% 100%;
|
|
6266
6276
|
--foreground: 222.2 84% 4.9%;
|
|
6267
6277
|
--card: 0 0% 100%;
|
|
@@ -6320,6 +6330,7 @@
|
|
|
6320
6330
|
font-family: 'Inter', ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
|
|
6321
6331
|
}
|
|
6322
6332
|
.dark {
|
|
6333
|
+
color-scheme: dark;
|
|
6323
6334
|
--background: 222.2 84% 4.9%;
|
|
6324
6335
|
--foreground: 210 40% 98%;
|
|
6325
6336
|
--card: 222.2 84% 4.9%;
|
package/dist/index.d.ts
CHANGED
|
@@ -13,7 +13,7 @@ export { useResizeObserver } from './hooks/use-resize-observer';
|
|
|
13
13
|
export type { ElementSize } from './hooks/use-resize-observer';
|
|
14
14
|
export { useExportJob } from './hooks/use-export-job';
|
|
15
15
|
export type { UseExportJobOptions, UseExportJobReturn } from './hooks/use-export-job';
|
|
16
|
-
export { useRelatedCount, RelatedCountStore } from './hooks/related-count-store';
|
|
16
|
+
export { useRelatedCount, useRelatedCountVersion, RelatedCountStore } from './hooks/related-count-store';
|
|
17
17
|
export type { ControlType, ConfigField, ConfigSection, ConfigPanelSchema, } from './types/config-panel';
|
|
18
18
|
export declare function initializeComponents(): boolean;
|
|
19
19
|
export * from './debug';
|