@object-ui/components 17.6.0 → 18.0.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 +9618 -0
- package/README.md +27 -3
- package/dist/custom/RecordTitleChip.d.ts +4 -3
- package/dist/custom/button-group.d.ts +1 -1
- package/dist/custom/combobox.d.ts +2 -4
- package/dist/custom/dialog-viewport-gutter.d.ts +37 -0
- package/dist/custom/empty-state-link.d.ts +63 -0
- package/dist/custom/empty.d.ts +16 -4
- package/dist/custom/field.d.ts +1 -1
- package/dist/custom/filter-builder.d.ts +225 -77
- package/dist/custom/grouping-editor.d.ts +4 -0
- package/dist/custom/horizontal-overflow.d.ts +18 -0
- package/dist/custom/index.d.ts +4 -1
- package/dist/custom/item.d.ts +1 -1
- package/dist/custom/kbd.d.ts +1 -1
- package/dist/custom/mobile-dialog-content.d.ts +22 -1
- package/dist/custom/navigation-overlay.d.ts +105 -0
- package/dist/custom/refresh-indicator.d.ts +8 -2
- package/dist/custom/sort-builder.d.ts +8 -0
- package/dist/custom/use-horizontal-overflow.d.ts +36 -0
- package/dist/custom/view-states.d.ts +74 -1
- package/dist/hooks/related-count-store.d.ts +81 -28
- package/dist/index.css +345 -361
- package/dist/index.d.ts +11 -3
- package/dist/index.js +8480 -6628
- package/dist/index.umd.cjs +11 -15
- package/dist/lib/close-label.d.ts +1 -2
- package/dist/lib/date-fns-locale.d.ts +41 -0
- package/dist/lib/inline-markdown.d.ts +64 -0
- package/dist/lib/lazy-icon.d.ts +32 -1
- package/dist/lib/lucide-record-icon-names.d.ts +30 -0
- package/dist/lib/utils.d.ts +113 -0
- package/dist/renderers/action/action-bar.d.ts +8 -36
- package/dist/renderers/action/action-button.d.ts +15 -4
- package/dist/renderers/action/action-group.d.ts +5 -4
- package/dist/renderers/action/action-icon.d.ts +12 -2
- package/dist/renderers/action/action-menu.d.ts +5 -2
- package/dist/renderers/action/auto-trigger.d.ts +19 -4
- package/dist/renderers/action/disabled-reason.d.ts +49 -0
- package/dist/renderers/action/resolve-icon.d.ts +27 -2
- package/dist/renderers/action/static-params.d.ts +71 -0
- package/dist/renderers/action/visibility-gate.d.ts +11 -3
- package/dist/renderers/basic/data-list.d.ts +2 -1
- package/dist/renderers/basic/elements.d.ts +2 -0
- package/dist/renderers/basic/html-elements.d.ts +7 -3
- package/dist/renderers/basic/readProps.d.ts +60 -0
- package/dist/renderers/basic/record-picker.d.ts +3 -2
- package/dist/renderers/complex/data-table.d.ts +31 -14
- package/dist/renderers/complex/dataTableBindDiagnostic.d.ts +187 -0
- package/dist/renderers/layout/box.d.ts +8 -0
- package/dist/renderers/layout/containers.d.ts +28 -23
- package/dist/renderers/layout/page-block-grid.d.ts +29 -0
- package/dist/renderers/layout/page-block-span.d.ts +50 -0
- package/dist/renderers/layout/page-description-context.d.ts +14 -0
- package/dist/renderers/layout/page-print.d.ts +14 -0
- package/dist/renderers/layout/page-region-posture.d.ts +82 -0
- package/dist/renderers/layout/react-page.d.ts +4 -0
- package/dist/renderers/navigation/sidebar.d.ts +31 -0
- package/dist/ui/badge.d.ts +1 -1
- package/dist/ui/button.d.ts +1 -1
- package/dist/ui/calendar.d.ts +2 -1
- package/dist/ui/command.d.ts +7 -7
- package/dist/ui/index.d.ts +0 -1
- package/dist/ui/input-otp.d.ts +2 -2
- package/dist/ui/sheet.d.ts +1 -1
- package/dist/ui/sidebar.d.ts +2 -1
- package/package.json +14 -15
- package/dist/SchemaRenderer.d.ts +0 -4
- package/dist/custom/export-progress-dialog.d.ts +0 -43
- package/dist/hooks/use-export-job.d.ts +0 -34
- package/dist/ui/chart.d.ts +0 -56
- package/dist/ui/toast.d.ts +0 -22
package/README.md
CHANGED
|
@@ -86,15 +86,16 @@ tree-shake that import away.
|
|
|
86
86
|
```tsx
|
|
87
87
|
import { SchemaRenderer } from '@object-ui/react'
|
|
88
88
|
import { initializeComponents } from '@object-ui/components'
|
|
89
|
+
import type { DeclaredNode } from '@object-ui/types'
|
|
89
90
|
|
|
90
91
|
initializeComponents()
|
|
91
92
|
|
|
92
|
-
const schema = {
|
|
93
|
+
const schema: DeclaredNode = {
|
|
93
94
|
type: 'card',
|
|
94
95
|
title: 'Welcome',
|
|
95
|
-
|
|
96
|
+
children: {
|
|
96
97
|
type: 'text',
|
|
97
|
-
|
|
98
|
+
content: 'Hello from Object UI!'
|
|
98
99
|
}
|
|
99
100
|
}
|
|
100
101
|
|
|
@@ -139,6 +140,28 @@ function MyComponent() {
|
|
|
139
140
|
- `tabs` - Tab navigation
|
|
140
141
|
- `accordion` - Collapsible sections
|
|
141
142
|
|
|
143
|
+
#### Page region posture — `usePageRegionPosture()`
|
|
144
|
+
|
|
145
|
+
The page renderer measures each region of a page against the page body, using
|
|
146
|
+
`ResizeObserver` on the region, not the viewport, and tells the region's blocks
|
|
147
|
+
how much room they have:
|
|
148
|
+
|
|
149
|
+
```ts
|
|
150
|
+
import { usePageRegionPosture, type PageRegionPosture } from '@object-ui/components';
|
|
151
|
+
|
|
152
|
+
const posture: PageRegionPosture | null = usePageRegionPosture(); // 'compact' | 'full' | null
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
- `'compact'`: the region is narrower than `(page − 24) / 2`, that is, half
|
|
156
|
+
the page less the 24 px gap between regions side by side. A half-and-half
|
|
157
|
+
cell therefore stays `'full'`.
|
|
158
|
+
- `'full'`: the region is half the page or wider.
|
|
159
|
+
- `null`: outside a page region, or before the width is known (server render,
|
|
160
|
+
no `ResizeObserver`). Read `null` as `'full'`.
|
|
161
|
+
|
|
162
|
+
The posture is measured, never authored, and no schema key sets it. The
|
|
163
|
+
`list-view` block in `@object-ui/plugin-list` reads it to draw a compact list.
|
|
164
|
+
|
|
142
165
|
### Data Display
|
|
143
166
|
- `table` - Data table
|
|
144
167
|
- `list` - List view
|
|
@@ -175,6 +198,7 @@ them draw the notification's `severity` icon unless it declares an `icon`
|
|
|
175
198
|
override naming a real Lucide icon. See the
|
|
176
199
|
[notifications guide](https://objectui.org/docs/guide/notifications).
|
|
177
200
|
|
|
201
|
+
<!-- doc-snippet: fragment — router-layout excerpt: `Outlet` is react-router's, supplied by the host application -->
|
|
178
202
|
```tsx
|
|
179
203
|
import { NotificationBanners, NotificationAlerts } from '@object-ui/components';
|
|
180
204
|
|
|
@@ -8,13 +8,14 @@ export interface RecordTitleChipProps {
|
|
|
8
8
|
objectLabel?: string;
|
|
9
9
|
/** Record identifier shown next to the object label with a copy button. */
|
|
10
10
|
resourceId?: string;
|
|
11
|
-
/** Hide the favourite star (default: shown). */
|
|
12
|
-
showStar?: boolean;
|
|
13
11
|
/** Hide the copy-id button (default: shown when `resourceId` is given). */
|
|
14
12
|
showCopyId?: boolean;
|
|
15
13
|
/** Controlled favourite state. When omitted, the chip manages its own. */
|
|
16
14
|
isFavorite?: boolean;
|
|
17
|
-
/**
|
|
15
|
+
/**
|
|
16
|
+
* Called when the favourite star is toggled. The star draws exactly when
|
|
17
|
+
* this is given: a star with nothing to call would store nothing.
|
|
18
|
+
*/
|
|
18
19
|
onToggleFavorite?: (next: boolean) => void;
|
|
19
20
|
/** Extra classes for the outer flex column. */
|
|
20
21
|
className?: string;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { VariantProps } from 'class-variance-authority';
|
|
2
2
|
import { Separator } from '../ui/separator.js';
|
|
3
3
|
declare const buttonGroupVariants: (props?: ({
|
|
4
|
-
orientation?: "
|
|
4
|
+
orientation?: "vertical" | "horizontal" | null | undefined;
|
|
5
5
|
} & import('class-variance-authority/types').ClassProp) | undefined) => string;
|
|
6
6
|
declare function ButtonGroup({ className, orientation, ...props }: React.ComponentProps<"div"> & VariantProps<typeof buttonGroupVariants>): import("react").JSX.Element;
|
|
7
7
|
declare function ButtonGroupText({ className, asChild, ...props }: React.ComponentProps<"div"> & {
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { ComboboxOption } from '@object-ui/types/form';
|
|
1
2
|
/**
|
|
2
3
|
* ObjectUI
|
|
3
4
|
* Copyright (c) 2024-present ObjectStack Inc.
|
|
@@ -6,10 +7,7 @@
|
|
|
6
7
|
* LICENSE file in the root directory of this source tree.
|
|
7
8
|
*/
|
|
8
9
|
import * as React from "react";
|
|
9
|
-
export
|
|
10
|
-
value: string;
|
|
11
|
-
label: string;
|
|
12
|
-
}
|
|
10
|
+
export type { ComboboxOption } from '@object-ui/types/form';
|
|
13
11
|
/**
|
|
14
12
|
* Beyond its own named props, the combobox accepts standard button attributes
|
|
15
13
|
* (`id`, `aria-*`, `data-*`, handlers, …) and forwards them to the trigger —
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ObjectUI
|
|
3
|
+
* Copyright (c) 2024-present ObjectStack Inc.
|
|
4
|
+
*
|
|
5
|
+
* This source code is licensed under the MIT license found in the
|
|
6
|
+
* LICENSE file in the root directory of this source tree.
|
|
7
|
+
*/
|
|
8
|
+
/**
|
|
9
|
+
* The ONE viewport gutter every wide centred dialog reads from `sm` up
|
|
10
|
+
* (objectui#12593, promoted to a shared export by objectui#12603).
|
|
11
|
+
*
|
|
12
|
+
* The `DialogContent` primitive draws `w-full max-w-lg`. A consumer that raises
|
|
13
|
+
* the cap with `sm:max-w-2xl` or wider makes the dialog exactly as wide as any
|
|
14
|
+
* window narrower than that cap, at x = 0, edge to edge. With this class the
|
|
15
|
+
* dialog is the smaller of its max width and the window less 2rem, and the
|
|
16
|
+
* primitive's `left-[50%]` plus `translate-x-[-50%]` centres it with an equal
|
|
17
|
+
* 1rem either side. Above the max width plus 2rem the dialog is exactly as wide
|
|
18
|
+
* as before.
|
|
19
|
+
*
|
|
20
|
+
* `100%`, not `100vw`: the dialog is `fixed`, so `100%` is its containing
|
|
21
|
+
* block, the viewport less any classic scrollbar, the same box `left-[50%]`
|
|
22
|
+
* centres in. `100vw` counts the scrollbar, so each gutter would lose half of
|
|
23
|
+
* the scrollbar's width.
|
|
24
|
+
*
|
|
25
|
+
* `sm:` only: below `sm` a dialog is the phone sheet, which this leaves alone.
|
|
26
|
+
* A dialog that keeps its own viewport-relative cap (`sm:max-w-[95vw]
|
|
27
|
+
* sm:w-full`, the `full` size) does not read it.
|
|
28
|
+
*
|
|
29
|
+
* The class string is literal here so Tailwind's source scan emits it; an app
|
|
30
|
+
* that `@source`-scans this package gets the rule. A site writes its wide cap
|
|
31
|
+
* and this constant together (`` `sm:max-w-5xl ${DIALOG_VIEWPORT_GUTTER}` ``,
|
|
32
|
+
* or the constant as an unconditional `cn()` argument), never a gutter literal
|
|
33
|
+
* of its own. The census
|
|
34
|
+
* `packages/components/src/__tests__/dialogViewportGutterCensus-12603.test.ts`
|
|
35
|
+
* enumerates every wide `DialogContent` and fails one that does not.
|
|
36
|
+
*/
|
|
37
|
+
export declare const DIALOG_VIEWPORT_GUTTER = "sm:w-[calc(100%-2rem)]";
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { EmptyState } from '@objectstack/spec/ui';
|
|
2
|
+
/**
|
|
3
|
+
* ObjectUI
|
|
4
|
+
* Copyright (c) 2024-present ObjectStack Inc.
|
|
5
|
+
*
|
|
6
|
+
* This source code is licensed under the MIT license found in the
|
|
7
|
+
* LICENSE file in the root directory of this source tree.
|
|
8
|
+
*/
|
|
9
|
+
/**
|
|
10
|
+
* The one link an empty state names (objectui#12270).
|
|
11
|
+
*
|
|
12
|
+
* `@objectstack/spec`'s `EmptyStateSchema` declares an optional `link`,
|
|
13
|
+
* `{ label, url }`: the one next step an empty list names, such as the how-to
|
|
14
|
+
* page that explains what belongs here. The shape is taken by reference, so the
|
|
15
|
+
* link reaches every empty state that shape reaches, and each of them draws it
|
|
16
|
+
* through this component, ⛔ never a copy of its own:
|
|
17
|
+
*
|
|
18
|
+
* - a list view's `emptyState`, drawn by `@object-ui/plugin-list`'s `ListView`;
|
|
19
|
+
* - a list page's own `interfaceConfig.emptyState`, which that page hands the
|
|
20
|
+
* same `ListView`;
|
|
21
|
+
* - the `object-grid` block's `emptyState`, drawn by `@object-ui/plugin-grid`'s
|
|
22
|
+
* `ObjectGrid`.
|
|
23
|
+
*
|
|
24
|
+
* ## The click is the action runner's
|
|
25
|
+
*
|
|
26
|
+
* The link is followed as a `type: 'url'` action through the ActionRunner, so
|
|
27
|
+
* what a click may open is the runner's `classifyNavigationTarget` answer, the
|
|
28
|
+
* one answer every navigator in the app asks (ruling A+ on objectui#12191).
|
|
29
|
+
* ⛔ No scheme test lives here. An in-app path goes through the host's router,
|
|
30
|
+
* in place. An `http(s)://` address opens as the runner opens any external
|
|
31
|
+
* target. `mailto:` opens the mail client in place. Any other value is refused
|
|
32
|
+
* by the runner at the click, which reports its refusal (an error toast under
|
|
33
|
+
* the console's provider) and navigates nowhere. The spec judges the url at
|
|
34
|
+
* parse, except a template that opens with `${…}`, which it says is judged when
|
|
35
|
+
* it is clicked, after interpolation: the runner's click is that judgement, so
|
|
36
|
+
* nothing is judged here at render.
|
|
37
|
+
*
|
|
38
|
+
* Following a link is not feedback-worthy, so it raises no success toast, as
|
|
39
|
+
* the html tier's anchor and the dashboard's header link raise none.
|
|
40
|
+
*
|
|
41
|
+
* ## Without an ActionProvider
|
|
42
|
+
*
|
|
43
|
+
* `useAction()` then hands over a local runner with no navigation or toast
|
|
44
|
+
* handler. That runner hands an admitted in-app path back as `redirect`
|
|
45
|
+
* instead of navigating, and reports a refusal to nobody, so this component
|
|
46
|
+
* follows the redirect with a page navigation and logs the refusal.
|
|
47
|
+
*/
|
|
48
|
+
import * as React from 'react';
|
|
49
|
+
/** The spec's empty-state link, `{ label, url }` (`EmptyStateSchema.link`). */
|
|
50
|
+
export type EmptyStateLinkSpec = NonNullable<EmptyState['link']>;
|
|
51
|
+
export interface EmptyStateLinkProps {
|
|
52
|
+
/** The authored `emptyState.link`. Absent, nothing is drawn. */
|
|
53
|
+
link?: EmptyStateLinkSpec;
|
|
54
|
+
/**
|
|
55
|
+
* The locale the `label` is resolved against when it is an inline locale
|
|
56
|
+
* map: the one the caller resolves the empty state's `title` and `message`
|
|
57
|
+
* against. A label that resolves to no text draws nothing.
|
|
58
|
+
*/
|
|
59
|
+
displayLocale: string;
|
|
60
|
+
className?: string;
|
|
61
|
+
'data-testid'?: string;
|
|
62
|
+
}
|
|
63
|
+
export declare function EmptyStateLink({ link, displayLocale, className, 'data-testid': testId, }: EmptyStateLinkProps): React.JSX.Element | null;
|
package/dist/custom/empty.d.ts
CHANGED
|
@@ -6,15 +6,27 @@ declare const emptyMediaVariants: (props?: ({
|
|
|
6
6
|
} & import('class-variance-authority/types').ClassProp) | undefined) => string;
|
|
7
7
|
declare function EmptyMedia({ className, variant, ...props }: React.ComponentProps<"div"> & VariantProps<typeof emptyMediaVariants>): import("react").JSX.Element;
|
|
8
8
|
declare function EmptyTitle({ className, ...props }: React.ComponentProps<"div">): import("react").JSX.Element;
|
|
9
|
-
declare function EmptyDescription({ className, ...props }: React.ComponentProps<"
|
|
9
|
+
declare function EmptyDescription({ className, ...props }: React.ComponentProps<"div">): import("react").JSX.Element;
|
|
10
10
|
declare function EmptyContent({ className, ...props }: React.ComponentProps<"div">): import("react").JSX.Element;
|
|
11
11
|
/**
|
|
12
12
|
* EmptyValue — universal inline placeholder for missing cell/field values.
|
|
13
13
|
*
|
|
14
14
|
* Use this anywhere a renderer would otherwise show "-" or "—" for a null,
|
|
15
|
-
* undefined or empty value. It renders a muted, non-interactive
|
|
16
|
-
*
|
|
17
|
-
*
|
|
15
|
+
* undefined or empty value. It renders a muted, non-interactive EM-dash (the
|
|
16
|
+
* `glyph` default below is U+2014, and every call site depends on that width)
|
|
17
|
+
* that does not inherit link/button colors from surrounding ancestors, so a
|
|
18
|
+
* missing value never looks clickable. This sentence said "en-dash" until
|
|
19
|
+
* objectui#8506: the word was wrong, never the code — do not "fix" the glyph
|
|
20
|
+
* to match a stale docblock.
|
|
21
|
+
*
|
|
22
|
+
* ⚠️ A caller that passes a `title` through `...props` must also pass
|
|
23
|
+
* `pointer-events-auto` in `className`. `pointer-events-none` below stops this
|
|
24
|
+
* span being a hit target, so a `title` on it never renders a tooltip — the
|
|
25
|
+
* hover falls through to whichever ancestor has one. The attribute stays in the
|
|
26
|
+
* DOM either way, which is exactly why nothing catches it: a test that reads
|
|
27
|
+
* `getAttribute('title')` is green over a tooltip that can never appear
|
|
28
|
+
* (objectui#8506, where `DetailSection` kept such a `title` and two landed pins
|
|
29
|
+
* navigate by it).
|
|
18
30
|
*/
|
|
19
31
|
declare function EmptyValue({ className, glyph, ...props }: React.ComponentProps<"span"> & {
|
|
20
32
|
glyph?: string;
|
package/dist/custom/field.d.ts
CHANGED
|
@@ -25,7 +25,7 @@ export interface FieldProps extends React.HTMLAttributes<HTMLDivElement>, Varian
|
|
|
25
25
|
* A labelled form-control wrapper: label, slotted control, description, error.
|
|
26
26
|
*
|
|
27
27
|
* Named `FieldContainer`, not `Field` (objectstack#4115): `@objectstack/spec/data`
|
|
28
|
-
* exports `Field` — an object FIELD's metadata (type,
|
|
28
|
+
* exports `Field` — an object FIELD's metadata (type, reference, options,
|
|
29
29
|
* permissions, …) and its builder namespace — which has nothing to do with this
|
|
30
30
|
* `<div>`. Two unrelated things under one name is the defect that issue exists
|
|
31
31
|
* to remove; `@object-ui/app-shell` already renamed the same kind of collision
|