@nizivo/react 0.0.0-stage → 0.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/LICENSE +202 -0
- package/README.md +120 -2
- package/THIRD_PARTY_NOTICES +61 -0
- package/dist/_engines/react-aria/dialog.client.js +134 -0
- package/dist/_engines/react-aria/dom-allowlist.js +19 -0
- package/dist/_engines/react-aria/dom.js +31 -0
- package/dist/_engines/react-aria/locale.client.js +13 -0
- package/dist/_engines/react-aria/menu.client.js +225 -0
- package/dist/_engines/react-aria/overlay.client.js +41 -0
- package/dist/_engines/react-aria/popup.client.js +127 -0
- package/dist/_engines/react-aria/select.client.js +170 -0
- package/dist/_engines/react-aria/tabs.client.js +95 -0
- package/dist/_engines/react-aria/tooltip.client.js +72 -0
- package/dist/_internal/cx.js +11 -0
- package/dist/_internal/engine-part.d.ts +1 -0
- package/dist/_internal/field.js +20 -0
- package/dist/_internal/glyphs.js +34 -0
- package/dist/_internal/keys.js +62 -0
- package/dist/_internal/overlay.d.ts +9 -0
- package/dist/_virtual/_rolldown/runtime.js +13 -0
- package/dist/alert/alert-dismiss.client.d.ts +32 -0
- package/dist/alert/alert-dismiss.client.js +36 -0
- package/dist/alert/alert.d.ts +28 -0
- package/dist/alert/alert.js +44 -0
- package/dist/alert/index.d.ts +3 -0
- package/dist/alert/index.js +3 -0
- package/dist/augment.d.ts +13 -0
- package/dist/augment.js +0 -0
- package/dist/badge/badge.d.ts +19 -0
- package/dist/badge/badge.js +22 -0
- package/dist/badge/index.d.ts +2 -0
- package/dist/badge/index.js +1 -0
- package/dist/button/button.d.ts +54 -0
- package/dist/button/button.js +62 -0
- package/dist/button/index.d.ts +2 -0
- package/dist/button/index.js +1 -0
- package/dist/card/card.d.ts +57 -0
- package/dist/card/card.js +62 -0
- package/dist/card/card.parts.d.ts +6 -0
- package/dist/card/card.parts.js +14 -0
- package/dist/card/index.d.ts +3 -0
- package/dist/card/index.js +3 -0
- package/dist/checkbox/checkbox.client.d.ts +37 -0
- package/dist/checkbox/checkbox.client.js +81 -0
- package/dist/checkbox/index.d.ts +2 -0
- package/dist/checkbox/index.js +1 -0
- package/dist/config/config.client.d.ts +9 -0
- package/dist/config/config.client.js +18 -0
- package/dist/config/index.d.ts +2 -0
- package/dist/config/index.js +1 -0
- package/dist/container/container.d.ts +13 -0
- package/dist/container/container.js +16 -0
- package/dist/container/index.d.ts +2 -0
- package/dist/container/index.js +1 -0
- package/dist/contracts/details.d.ts +13 -0
- package/dist/contracts/details.js +9 -0
- package/dist/contracts/index.d.ts +5 -0
- package/dist/contracts/index.js +5 -0
- package/dist/contracts/merge-props.d.ts +16 -0
- package/dist/contracts/merge-props.js +76 -0
- package/dist/contracts/render.d.ts +17 -0
- package/dist/contracts/render.js +43 -0
- package/dist/contracts/state.d.ts +42 -0
- package/dist/contracts/state.js +42 -0
- package/dist/css/alert.css +2 -0
- package/dist/css/badge.css +2 -0
- package/dist/css/base.css +2 -0
- package/dist/css/button.css +2 -0
- package/dist/css/card.css +2 -0
- package/dist/css/checkbox.css +2 -0
- package/dist/css/container.css +2 -0
- package/dist/css/delta.css +2 -0
- package/dist/css/dialog.css +2 -0
- package/dist/css/empty-state.css +2 -0
- package/dist/css/field.css +2 -0
- package/dist/css/fieldset.css +2 -0
- package/dist/css/grid.css +2 -0
- package/dist/css/heading.css +2 -0
- package/dist/css/icon-button.css +2 -0
- package/dist/css/image.css +2 -0
- package/dist/css/inline-error.css +2 -0
- package/dist/css/inline.css +2 -0
- package/dist/css/input.css +2 -0
- package/dist/css/kbd.css +2 -0
- package/dist/css/menu.css +2 -0
- package/dist/css/meter.css +2 -0
- package/dist/css/native-select.css +2 -0
- package/dist/css/progress-bar.css +2 -0
- package/dist/css/progress-ring.css +2 -0
- package/dist/css/radio-group.css +2 -0
- package/dist/css/segmented-control.css +2 -0
- package/dist/css/select.css +2 -0
- package/dist/css/separator.css +2 -0
- package/dist/css/skeleton.css +2 -0
- package/dist/css/stack.css +2 -0
- package/dist/css/switch.css +2 -0
- package/dist/css/tab-nav.css +2 -0
- package/dist/css/tabs.css +2 -0
- package/dist/css/text.css +2 -0
- package/dist/css/textarea.css +2 -0
- package/dist/css/tooltip.css +2 -0
- package/dist/delta/delta.d.ts +32 -0
- package/dist/delta/delta.js +50 -0
- package/dist/delta/index.d.ts +2 -0
- package/dist/delta/index.js +1 -0
- package/dist/dialog/dialog.client.d.ts +25 -0
- package/dist/dialog/dialog.client.js +167 -0
- package/dist/dialog/dialog.contract.d.ts +97 -0
- package/dist/dialog/dialog.parts.d.ts +6 -0
- package/dist/dialog/dialog.parts.js +15 -0
- package/dist/dialog/index.d.ts +5 -0
- package/dist/dialog/index.js +3 -0
- package/dist/empty-state/empty-state.d.ts +18 -0
- package/dist/empty-state/empty-state.js +32 -0
- package/dist/empty-state/index.d.ts +2 -0
- package/dist/empty-state/index.js +1 -0
- package/dist/field/field-scope.client.d.ts +50 -0
- package/dist/field/field-scope.client.js +205 -0
- package/dist/field/field-static.d.ts +122 -0
- package/dist/field/field-static.js +159 -0
- package/dist/field/field.d.ts +5 -0
- package/dist/field/field.js +53 -0
- package/dist/field/index.d.ts +4 -0
- package/dist/field/index.js +4 -0
- package/dist/fieldset/fieldset.d.ts +36 -0
- package/dist/fieldset/fieldset.js +63 -0
- package/dist/fieldset/index.d.ts +2 -0
- package/dist/fieldset/index.js +1 -0
- package/dist/grid/grid.d.ts +38 -0
- package/dist/grid/grid.js +28 -0
- package/dist/grid/index.d.ts +2 -0
- package/dist/grid/index.js +1 -0
- package/dist/heading/heading.d.ts +27 -0
- package/dist/heading/heading.js +26 -0
- package/dist/heading/index.d.ts +2 -0
- package/dist/heading/index.js +1 -0
- package/dist/icon-button/icon-button-static.d.ts +23 -0
- package/dist/icon-button/icon-button-static.js +83 -0
- package/dist/icon-button/icon-button.client.js +29 -0
- package/dist/icon-button/icon-button.contract.d.ts +89 -0
- package/dist/icon-button/icon-button.d.ts +5 -0
- package/dist/icon-button/icon-button.js +21 -0
- package/dist/icon-button/index.d.ts +4 -0
- package/dist/icon-button/index.js +3 -0
- package/dist/image/image.d.ts +28 -0
- package/dist/image/image.js +24 -0
- package/dist/image/index.d.ts +2 -0
- package/dist/image/index.js +1 -0
- package/dist/index.d.ts +95 -0
- package/dist/index.js +51 -0
- package/dist/inline/index.d.ts +2 -0
- package/dist/inline/index.js +1 -0
- package/dist/inline/inline.d.ts +16 -0
- package/dist/inline/inline.js +14 -0
- package/dist/inline-error/index.d.ts +2 -0
- package/dist/inline-error/index.js +1 -0
- package/dist/inline-error/inline-error.d.ts +17 -0
- package/dist/inline-error/inline-error.js +33 -0
- package/dist/input/index.d.ts +2 -0
- package/dist/input/index.js +1 -0
- package/dist/input/input.client.d.ts +39 -0
- package/dist/input/input.client.js +82 -0
- package/dist/kbd/index.d.ts +2 -0
- package/dist/kbd/index.js +1 -0
- package/dist/kbd/kbd.d.ts +19 -0
- package/dist/kbd/kbd.js +68 -0
- package/dist/menu/index.d.ts +5 -0
- package/dist/menu/index.js +3 -0
- package/dist/menu/menu.client.d.ts +14 -0
- package/dist/menu/menu.client.js +152 -0
- package/dist/menu/menu.contract.d.ts +152 -0
- package/dist/menu/menu.parts.d.ts +6 -0
- package/dist/menu/menu.parts.js +17 -0
- package/dist/meter/index.d.ts +2 -0
- package/dist/meter/index.js +1 -0
- package/dist/meter/meter.d.ts +43 -0
- package/dist/meter/meter.js +59 -0
- package/dist/native-select/index.d.ts +2 -0
- package/dist/native-select/index.js +1 -0
- package/dist/native-select/native-select.d.ts +43 -0
- package/dist/native-select/native-select.js +56 -0
- package/dist/progress-bar/index.d.ts +2 -0
- package/dist/progress-bar/index.js +1 -0
- package/dist/progress-bar/progress-bar.d.ts +34 -0
- package/dist/progress-bar/progress-bar.js +55 -0
- package/dist/progress-ring/index.d.ts +2 -0
- package/dist/progress-ring/index.js +1 -0
- package/dist/progress-ring/progress-ring.d.ts +38 -0
- package/dist/progress-ring/progress-ring.js +67 -0
- package/dist/radio-group/index.d.ts +3 -0
- package/dist/radio-group/index.js +3 -0
- package/dist/radio-group/radio-group.client.d.ts +22 -0
- package/dist/radio-group/radio-group.client.js +70 -0
- package/dist/radio-group/radio-group.d.ts +28 -0
- package/dist/radio-group/radio-group.js +35 -0
- package/dist/segmented-control/index.d.ts +3 -0
- package/dist/segmented-control/index.js +3 -0
- package/dist/segmented-control/segmented-control.client.d.ts +61 -0
- package/dist/segmented-control/segmented-control.client.js +156 -0
- package/dist/segmented-control/segmented-control.parts.d.ts +6 -0
- package/dist/segmented-control/segmented-control.parts.js +9 -0
- package/dist/select/index.d.ts +5 -0
- package/dist/select/index.js +3 -0
- package/dist/select/select.client.d.ts +12 -0
- package/dist/select/select.client.js +152 -0
- package/dist/select/select.contract.d.ts +119 -0
- package/dist/select/select.parts.d.ts +6 -0
- package/dist/select/select.parts.js +15 -0
- package/dist/separator/index.d.ts +2 -0
- package/dist/separator/index.js +1 -0
- package/dist/separator/separator.d.ts +26 -0
- package/dist/separator/separator.js +23 -0
- package/dist/skeleton/index.d.ts +2 -0
- package/dist/skeleton/index.js +1 -0
- package/dist/skeleton/skeleton.d.ts +20 -0
- package/dist/skeleton/skeleton.js +19 -0
- package/dist/stack/index.d.ts +2 -0
- package/dist/stack/index.js +1 -0
- package/dist/stack/stack.d.ts +17 -0
- package/dist/stack/stack.js +14 -0
- package/dist/styles.css +536 -0
- package/dist/switch/index.d.ts +2 -0
- package/dist/switch/index.js +1 -0
- package/dist/switch/switch.client.d.ts +33 -0
- package/dist/switch/switch.client.js +63 -0
- package/dist/tab-nav/index.d.ts +3 -0
- package/dist/tab-nav/index.js +3 -0
- package/dist/tab-nav/tab-nav.d.ts +36 -0
- package/dist/tab-nav/tab-nav.js +47 -0
- package/dist/tab-nav/tab-nav.parts.d.ts +6 -0
- package/dist/tab-nav/tab-nav.parts.js +9 -0
- package/dist/tabs/index.d.ts +4 -0
- package/dist/tabs/index.js +3 -0
- package/dist/tabs/tabs.client.d.ts +8 -0
- package/dist/tabs/tabs.client.js +68 -0
- package/dist/tabs/tabs.contract.d.ts +89 -0
- package/dist/tabs/tabs.parts.d.ts +6 -0
- package/dist/tabs/tabs.parts.js +11 -0
- package/dist/text/index.d.ts +2 -0
- package/dist/text/index.js +1 -0
- package/dist/text/text.d.ts +21 -0
- package/dist/text/text.js +17 -0
- package/dist/textarea/index.d.ts +2 -0
- package/dist/textarea/index.js +1 -0
- package/dist/textarea/textarea.client.d.ts +18 -0
- package/dist/textarea/textarea.client.js +31 -0
- package/dist/theme-script/index.d.ts +2 -0
- package/dist/theme-script/index.js +1 -0
- package/dist/theme-script/theme-script.d.ts +43 -0
- package/dist/theme-script/theme-script.js +46 -0
- package/dist/tooltip/index.d.ts +5 -0
- package/dist/tooltip/index.js +3 -0
- package/dist/tooltip/tooltip.client.d.ts +12 -0
- package/dist/tooltip/tooltip.client.js +51 -0
- package/dist/tooltip/tooltip.contract.d.ts +60 -0
- package/dist/tooltip/tooltip.parts.d.ts +6 -0
- package/dist/tooltip/tooltip.parts.js +10 -0
- package/package.json +284 -3
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import { RenderProp } from "../contracts/render.js";
|
|
2
|
+
import { ChangeDetails, OpenReason } from "../contracts/details.js";
|
|
3
|
+
import "../_internal/engine-part.js";
|
|
4
|
+
import { ReturnFocusTarget } from "../_internal/overlay.js";
|
|
5
|
+
import { ComponentPropsWithRef, ReactElement, ReactNode } from "react";
|
|
6
|
+
//#region src/dialog/dialog.contract.d.ts
|
|
7
|
+
/** Figma Modal `Type`: Default → `dialog`, Destructive → `alertdialog`. */
|
|
8
|
+
export type DialogRole = "dialog" | "alertdialog";
|
|
9
|
+
/** `md` is Figma's only Modal width (480 px); `sm` (400) and `lg` (640) are provisional. */
|
|
10
|
+
export type DialogSize = "sm" | "md" | "lg";
|
|
11
|
+
export type DialogTitleLevel = 2 | 3 | 4 | 5 | 6;
|
|
12
|
+
/**
|
|
13
|
+
* Strings the Dialog renders (§9.3 rule 7, §16.4). `close` is the accessible name of the default
|
|
14
|
+
* `Dialog.Close` (an IconButton showing the close glyph), set through that part's `labels`.
|
|
15
|
+
* Engine-owned with React Aria (not overridable): `dismiss`, the visually hidden "Dismiss" button
|
|
16
|
+
* rendered inside a dismissable dialog.
|
|
17
|
+
*/
|
|
18
|
+
export interface DialogLabels {
|
|
19
|
+
/** @default 'Close' */
|
|
20
|
+
close: string;
|
|
21
|
+
dismiss: string;
|
|
22
|
+
}
|
|
23
|
+
export interface DialogRootProps {
|
|
24
|
+
open?: boolean;
|
|
25
|
+
defaultOpen?: boolean;
|
|
26
|
+
/** `details.reason` is `'unknown'` with React Aria, which reports no cause. */
|
|
27
|
+
onOpenChange?: (open: boolean, details: ChangeDetails<OpenReason>) => void;
|
|
28
|
+
/**
|
|
29
|
+
* Where focus goes when the dialog closes (§12.2 Focus return). `true` returns it to the trigger
|
|
30
|
+
* (the element that opened the dialog), else to the trigger of the overlay it was opened from (a
|
|
31
|
+
* Menu button, after a Menu item opened it), else it stays on `<body>` and development builds warn.
|
|
32
|
+
* An element ref, or a function returning an element, goes first while that element is on the page;
|
|
33
|
+
* `false` leaves focus where the browser puts it, for an app that moves it itself.
|
|
34
|
+
* @default true
|
|
35
|
+
*/
|
|
36
|
+
returnFocus?: ReturnFocusTarget;
|
|
37
|
+
children: ReactNode;
|
|
38
|
+
}
|
|
39
|
+
export interface DialogTriggerState {
|
|
40
|
+
open: boolean;
|
|
41
|
+
pressed: boolean;
|
|
42
|
+
focusVisible: boolean;
|
|
43
|
+
disabled: boolean;
|
|
44
|
+
}
|
|
45
|
+
export interface DialogPopupState {
|
|
46
|
+
entering: boolean;
|
|
47
|
+
exiting: boolean;
|
|
48
|
+
}
|
|
49
|
+
export interface DialogCloseState {
|
|
50
|
+
pressed: boolean;
|
|
51
|
+
focusVisible: boolean;
|
|
52
|
+
disabled: boolean;
|
|
53
|
+
}
|
|
54
|
+
export interface DialogTriggerProps extends Omit<ComponentPropsWithRef<"button">, "children"> {
|
|
55
|
+
/** Must render a `<button>`, for example `render={<Button variant="critical">Delete</Button>}`. */
|
|
56
|
+
render?: RenderProp<DialogTriggerState>;
|
|
57
|
+
children?: ReactNode;
|
|
58
|
+
}
|
|
59
|
+
export interface DialogPopupProps extends Omit<ComponentPropsWithRef<"div">, "children" | "role"> {
|
|
60
|
+
/** `alertdialog` disables outside-press dismissal. @default 'dialog' */
|
|
61
|
+
role?: DialogRole;
|
|
62
|
+
/** @default 'md' */
|
|
63
|
+
size?: DialogSize;
|
|
64
|
+
/** The scrim element. Defaults to on for the root modal and off for nested modals. */
|
|
65
|
+
backdrop?: boolean;
|
|
66
|
+
/** Portal container. Defaults to the parent overlay, else `document.body` (§12.1 L2). */
|
|
67
|
+
container?: Element | null;
|
|
68
|
+
children: ReactNode;
|
|
69
|
+
}
|
|
70
|
+
export interface DialogTitleProps extends Omit<ComponentPropsWithRef<"h2">, "id"> {
|
|
71
|
+
/** @default 2 */
|
|
72
|
+
level?: DialogTitleLevel;
|
|
73
|
+
render?: RenderProp<Record<string, never>>;
|
|
74
|
+
}
|
|
75
|
+
export interface DialogDescriptionProps extends Omit<ComponentPropsWithRef<"p">, "id"> {
|
|
76
|
+
render?: RenderProp<Record<string, never>>;
|
|
77
|
+
}
|
|
78
|
+
export interface DialogBodyProps extends ComponentPropsWithRef<"div"> {
|
|
79
|
+
render?: RenderProp<Record<string, never>>;
|
|
80
|
+
}
|
|
81
|
+
export interface DialogFooterProps extends ComponentPropsWithRef<"div"> {
|
|
82
|
+
render?: RenderProp<Record<string, never>>;
|
|
83
|
+
}
|
|
84
|
+
export interface DialogCloseProps extends Omit<ComponentPropsWithRef<"button">, "children"> {
|
|
85
|
+
/**
|
|
86
|
+
* Must render a `<button>`, for example `render={<Button>Cancel</Button>}`. With neither `render`
|
|
87
|
+
* nor `children`, the part is an IconButton showing the close glyph, named by `labels.close`, which
|
|
88
|
+
* sits in the popup's top corner when it is a direct child of `Dialog.Popup` (§12.3).
|
|
89
|
+
*/
|
|
90
|
+
render?: RenderProp<DialogCloseState>;
|
|
91
|
+
/** Text content, rendered in a plain `<button>`; leave it out for the default IconButton. */
|
|
92
|
+
children?: ReactNode;
|
|
93
|
+
/** The default IconButton's accessible name; an `aria-label` you pass wins. */
|
|
94
|
+
labels?: Partial<Pick<DialogLabels, "close">>;
|
|
95
|
+
}
|
|
96
|
+
//#endregion
|
|
97
|
+
export type { OpenReason };
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { DialogBody, DialogClose, DialogDescription, DialogFooter, DialogPopup, DialogRoot, DialogTitle, DialogTrigger } from "./dialog.client.js";
|
|
2
|
+
declare namespace dialog_parts_d_exports {
|
|
3
|
+
export { DialogBody as Body, DialogClose as Close, DialogDescription as Description, DialogFooter as Footer, DialogPopup as Popup, DialogRoot as Root, DialogTitle as Title, DialogTrigger as Trigger };
|
|
4
|
+
}
|
|
5
|
+
//#endregion
|
|
6
|
+
export { DialogBody as Body, DialogClose as Close, DialogDescription as Description, DialogFooter as Footer, DialogPopup as Popup, DialogRoot as Root, DialogTitle as Title, DialogTrigger as Trigger, dialog_parts_d_exports };
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { __exportAll } from "../_virtual/_rolldown/runtime.js";
|
|
2
|
+
import { DialogBody, DialogClose, DialogDescription, DialogFooter, DialogPopup, DialogRoot, DialogTitle, DialogTrigger } from "./dialog.client.js";
|
|
3
|
+
//#region src/dialog/dialog.parts.ts
|
|
4
|
+
var dialog_parts_exports = /* @__PURE__ */ __exportAll({
|
|
5
|
+
Body: () => DialogBody,
|
|
6
|
+
Close: () => DialogClose,
|
|
7
|
+
Description: () => DialogDescription,
|
|
8
|
+
Footer: () => DialogFooter,
|
|
9
|
+
Popup: () => DialogPopup,
|
|
10
|
+
Root: () => DialogRoot,
|
|
11
|
+
Title: () => DialogTitle,
|
|
12
|
+
Trigger: () => DialogTrigger
|
|
13
|
+
});
|
|
14
|
+
//#endregion
|
|
15
|
+
export { DialogBody as Body, DialogClose as Close, DialogDescription as Description, DialogFooter as Footer, DialogPopup as Popup, DialogRoot as Root, DialogTitle as Title, DialogTrigger as Trigger, dialog_parts_exports };
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { OpenReason } from "../contracts/details.js";
|
|
2
|
+
import { DialogBodyProps, DialogCloseProps, DialogCloseState, DialogDescriptionProps, DialogFooterProps, DialogLabels, DialogPopupProps, DialogPopupState, DialogRole, DialogRootProps, DialogSize, DialogTitleLevel, DialogTitleProps, DialogTriggerProps, DialogTriggerState } from "./dialog.contract.js";
|
|
3
|
+
import { DialogBody, DialogClose, DialogDescription, DialogFooter, DialogPopup, DialogRoot, DialogTitle, DialogTrigger } from "./dialog.client.js";
|
|
4
|
+
import { dialog_parts_d_exports } from "./dialog.parts.js";
|
|
5
|
+
export { dialog_parts_d_exports as Dialog, DialogBody, type DialogBodyProps, DialogClose, type DialogCloseProps, type DialogCloseState, DialogDescription, type DialogDescriptionProps, DialogFooter, type DialogFooterProps, type DialogLabels, DialogPopup, type DialogPopupProps, type DialogPopupState, type DialogRole, DialogRoot, type DialogRootProps, type DialogSize, DialogTitle, type DialogTitleLevel, type DialogTitleProps, DialogTrigger, type DialogTriggerProps, type DialogTriggerState, type OpenReason };
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import { DialogBody, DialogClose, DialogDescription, DialogFooter, DialogPopup, DialogRoot, DialogTitle, DialogTrigger } from "./dialog.client.js";
|
|
2
|
+
import { dialog_parts_exports } from "./dialog.parts.js";
|
|
3
|
+
export { dialog_parts_exports as Dialog, DialogBody, DialogClose, DialogDescription, DialogFooter, DialogPopup, DialogRoot, DialogTitle, DialogTrigger };
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { RenderProp } from "../contracts/render.js";
|
|
2
|
+
import { ComponentPropsWithRef, ReactElement, ReactNode } from "react";
|
|
3
|
+
//#region src/empty-state/empty-state.d.ts
|
|
4
|
+
export type EmptyStateTitleLevel = 2 | 3 | 4 | 5 | 6;
|
|
5
|
+
export interface EmptyStateProps extends Omit<ComponentPropsWithRef<"div">, "title" | "children"> {
|
|
6
|
+
/** The headline. Its look is Heading/H3 at every `level`. */
|
|
7
|
+
title: ReactNode;
|
|
8
|
+
/** @default 2 */
|
|
9
|
+
level?: EmptyStateTitleLevel;
|
|
10
|
+
/** A render or illustration above the title, for example `<Image … />`. */
|
|
11
|
+
media?: ReactNode;
|
|
12
|
+
/** One action, for example `<Button variant="primary">Share your store</Button>`. */
|
|
13
|
+
actions?: ReactNode;
|
|
14
|
+
render?: RenderProp<Record<string, never>>;
|
|
15
|
+
}
|
|
16
|
+
/** Figma: "A render, a headline, one action. No paragraphs." */
|
|
17
|
+
export declare function EmptyState({ title, level, media, actions, render, className, ...rest }: EmptyStateProps): ReactElement;
|
|
18
|
+
//#endregion
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { cx } from "../_internal/cx.js";
|
|
2
|
+
import { renderElement } from "../contracts/render.js";
|
|
3
|
+
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
4
|
+
//#region src/empty-state/empty-state.tsx
|
|
5
|
+
/** Figma: "A render, a headline, one action. No paragraphs." */
|
|
6
|
+
function EmptyState({ title, level = 2, media, actions, render, className, ...rest }) {
|
|
7
|
+
const Title = `h${level}`;
|
|
8
|
+
return renderElement("div", render, {}, {
|
|
9
|
+
"data-slot": "empty-state",
|
|
10
|
+
...rest,
|
|
11
|
+
className: cx("nz-empty-state", className),
|
|
12
|
+
children: /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
13
|
+
media != null && /* @__PURE__ */ jsx("div", {
|
|
14
|
+
className: "nz-empty-state-media",
|
|
15
|
+
"data-slot": "empty-state-media",
|
|
16
|
+
children: media
|
|
17
|
+
}),
|
|
18
|
+
/* @__PURE__ */ jsx(Title, {
|
|
19
|
+
className: "nz-empty-state-title",
|
|
20
|
+
"data-slot": "empty-state-title",
|
|
21
|
+
children: title
|
|
22
|
+
}),
|
|
23
|
+
actions != null && /* @__PURE__ */ jsx("div", {
|
|
24
|
+
className: "nz-empty-state-actions",
|
|
25
|
+
"data-slot": "empty-state-actions",
|
|
26
|
+
children: actions
|
|
27
|
+
})
|
|
28
|
+
] })
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
//#endregion
|
|
32
|
+
export { EmptyState };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { EmptyState } from "./empty-state.js";
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { FieldControlProps } from "./field-static.js";
|
|
2
|
+
import { FocusEvent, ReactElement, ReactNode, SyntheticEvent } from "react";
|
|
3
|
+
//#region src/field/field-scope.client.d.ts
|
|
4
|
+
/** A native element that takes part in constraint validation. */
|
|
5
|
+
export type FieldValidatable = HTMLInputElement | HTMLTextAreaElement | HTMLSelectElement;
|
|
6
|
+
/** What a control passes in: its own props, which win over the Field's (FIELD-CONTRACT.md). */
|
|
7
|
+
export interface FieldControlOptions {
|
|
8
|
+
id?: string | undefined;
|
|
9
|
+
name?: string | undefined;
|
|
10
|
+
required?: boolean | undefined;
|
|
11
|
+
disabled?: boolean | undefined;
|
|
12
|
+
readOnly?: boolean | undefined;
|
|
13
|
+
invalid?: boolean | undefined;
|
|
14
|
+
/** Joined after the Field's description and error ids, for example a text affix or a count. */
|
|
15
|
+
"aria-describedby"?: string | undefined;
|
|
16
|
+
/**
|
|
17
|
+
* `'focus'`: a click on the Field label focuses the control and does nothing else. For button
|
|
18
|
+
* controls (Select, third-party pickers): a `<label for>` a button presses it, which would open its
|
|
19
|
+
* popup. Omitted, the label keeps the browser's behaviour.
|
|
20
|
+
*/
|
|
21
|
+
labelBehavior?: "focus" | undefined;
|
|
22
|
+
}
|
|
23
|
+
/** `controlProps`: the attributes plus the Field's validation handlers, inside a Field. */
|
|
24
|
+
export type FieldControlElementProps = FieldControlProps & {
|
|
25
|
+
onInvalid?: ((event: SyntheticEvent<FieldValidatable>) => void) | undefined;
|
|
26
|
+
onInput?: ((event: SyntheticEvent<FieldValidatable>) => void) | undefined;
|
|
27
|
+
onBlur?: ((event: FocusEvent<FieldValidatable>) => void) | undefined;
|
|
28
|
+
};
|
|
29
|
+
export interface FieldControl {
|
|
30
|
+
/** A Field is around the control. */
|
|
31
|
+
inField: boolean;
|
|
32
|
+
id: string | undefined;
|
|
33
|
+
/** The Field label's id, for a control named by `aria-labelledby` (button or group controls). */
|
|
34
|
+
labelledBy: string | undefined;
|
|
35
|
+
describedBy: string | undefined;
|
|
36
|
+
name: string | undefined;
|
|
37
|
+
required: boolean;
|
|
38
|
+
disabled: boolean;
|
|
39
|
+
readOnly: boolean;
|
|
40
|
+
/** An error message is presented (`data-invalid` semantics, §8.3). */
|
|
41
|
+
invalid: boolean;
|
|
42
|
+
/** Spread on the native element, merged with the consumer's props through `mergeProps`. */
|
|
43
|
+
controlProps: FieldControlElementProps;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Field wiring for a control (FIELD-CONTRACT.md). The control's own props win; `aria-describedby`
|
|
47
|
+
* is joined. With no Field around the control, everything comes from `options`.
|
|
48
|
+
*/
|
|
49
|
+
export declare function useFieldControl(options?: FieldControlOptions): FieldControl;
|
|
50
|
+
//#endregion
|
|
@@ -0,0 +1,205 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { renderElement } from "../contracts/render.js";
|
|
3
|
+
import { joinIds, presented } from "../_internal/field.js";
|
|
4
|
+
import { describedBy, fieldControlProps, fieldRootProps, fieldState } from "./field-static.js";
|
|
5
|
+
import { createContext, use, useEffect, useLayoutEffect, useMemo, useRef, useState } from "react";
|
|
6
|
+
import { jsx } from "react/jsx-runtime";
|
|
7
|
+
//#region src/field/field-scope.client.tsx
|
|
8
|
+
const FieldContext = createContext(null);
|
|
9
|
+
/** Internal: rendered only by `Field`. Every prop is serialisable. */
|
|
10
|
+
function FieldScope({ anatomy, name, messages, children }) {
|
|
11
|
+
const [native, setNative] = useState(null);
|
|
12
|
+
const [toFocus, setToFocus] = useState(null);
|
|
13
|
+
const { ids, label, description, required, disabled, readOnly, validateOn } = anatomy;
|
|
14
|
+
const error = presented(anatomy.error) ? anatomy.error : native;
|
|
15
|
+
const invalid = presented(error);
|
|
16
|
+
const region = useRef(null);
|
|
17
|
+
const [said, say] = useState("");
|
|
18
|
+
const last = useRef(null);
|
|
19
|
+
const asked = useRef(false);
|
|
20
|
+
const handlers = useMemo(() => {
|
|
21
|
+
const current = (element) => element.validity.valid ? null : messageOf(element, messages);
|
|
22
|
+
return {
|
|
23
|
+
onInvalid(event) {
|
|
24
|
+
event.preventDefault();
|
|
25
|
+
const element = event.currentTarget;
|
|
26
|
+
const first = element.form === null || firstInvalid(element.form) === element;
|
|
27
|
+
if (first) arm(region, asked, last);
|
|
28
|
+
setNative(messageOf(element, messages));
|
|
29
|
+
if (first && element.form !== null) setToFocus({ element });
|
|
30
|
+
},
|
|
31
|
+
onInput(event) {
|
|
32
|
+
asked.current = false;
|
|
33
|
+
const next = current(event.currentTarget);
|
|
34
|
+
setNative((shown) => shown === null ? null : next);
|
|
35
|
+
},
|
|
36
|
+
...validateOn === "blur" && { onBlur(event) {
|
|
37
|
+
setNative(current(event.currentTarget));
|
|
38
|
+
} }
|
|
39
|
+
};
|
|
40
|
+
}, [messages, validateOn]);
|
|
41
|
+
const [labelFocus, setLabelFocus] = useState(false);
|
|
42
|
+
useLayoutEffect(() => {
|
|
43
|
+
const text = invalid && region.current?.previousSibling?.lastChild?.textContent || "";
|
|
44
|
+
if (text !== last.current) {
|
|
45
|
+
last.current = text;
|
|
46
|
+
say(asked.current && text !== "" && inside(region.current) ? text : "");
|
|
47
|
+
if (text !== "") asked.current = false;
|
|
48
|
+
}
|
|
49
|
+
}, [
|
|
50
|
+
error,
|
|
51
|
+
invalid,
|
|
52
|
+
toFocus
|
|
53
|
+
]);
|
|
54
|
+
useLayoutEffect(() => {
|
|
55
|
+
const element = toFocus?.element;
|
|
56
|
+
if (element?.form != null && firstInvalid(element.form) === element) element.focus();
|
|
57
|
+
}, [toFocus]);
|
|
58
|
+
useEffect(() => {
|
|
59
|
+
const doc = region.current?.ownerDocument;
|
|
60
|
+
const onSubmit = () => arm(region, asked);
|
|
61
|
+
doc?.addEventListener("submit", onSubmit, true);
|
|
62
|
+
return () => doc?.removeEventListener("submit", onSubmit, true);
|
|
63
|
+
}, []);
|
|
64
|
+
useEffect(() => {
|
|
65
|
+
if (said === "") return void 0;
|
|
66
|
+
const timer = setTimeout(say, 7e3, "");
|
|
67
|
+
return () => clearTimeout(timer);
|
|
68
|
+
}, [said]);
|
|
69
|
+
const scope = useMemo(() => ({
|
|
70
|
+
id: ids.control,
|
|
71
|
+
labelledBy: presented(label) ? ids.label : void 0,
|
|
72
|
+
describedBy: describedBy(ids, description, invalid),
|
|
73
|
+
name,
|
|
74
|
+
required,
|
|
75
|
+
disabled,
|
|
76
|
+
readOnly,
|
|
77
|
+
invalid,
|
|
78
|
+
handlers,
|
|
79
|
+
setLabelFocus
|
|
80
|
+
}), [
|
|
81
|
+
ids,
|
|
82
|
+
label,
|
|
83
|
+
description,
|
|
84
|
+
invalid,
|
|
85
|
+
name,
|
|
86
|
+
required,
|
|
87
|
+
disabled,
|
|
88
|
+
readOnly,
|
|
89
|
+
handlers
|
|
90
|
+
]);
|
|
91
|
+
const field = {
|
|
92
|
+
...anatomy,
|
|
93
|
+
error,
|
|
94
|
+
onLabelClick: labelFocus ? focusControl : void 0,
|
|
95
|
+
announcer: /* @__PURE__ */ jsx("span", {
|
|
96
|
+
ref: region,
|
|
97
|
+
className: "nz-visually-hidden",
|
|
98
|
+
"aria-live": "polite",
|
|
99
|
+
"aria-atomic": "true",
|
|
100
|
+
children: said
|
|
101
|
+
}),
|
|
102
|
+
children
|
|
103
|
+
};
|
|
104
|
+
return /* @__PURE__ */ jsx(FieldContext, {
|
|
105
|
+
value: scope,
|
|
106
|
+
children: renderElement("div", anatomy.render, fieldState(field), fieldRootProps(field))
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Field wiring for a control (FIELD-CONTRACT.md). The control's own props win; `aria-describedby`
|
|
111
|
+
* is joined. With no Field around the control, everything comes from `options`.
|
|
112
|
+
*/
|
|
113
|
+
function useFieldControl(options = {}) {
|
|
114
|
+
const scope = use(FieldContext);
|
|
115
|
+
const id = options.id ?? scope?.id;
|
|
116
|
+
const name = options.name ?? scope?.name;
|
|
117
|
+
const required = options.required ?? scope?.required ?? false;
|
|
118
|
+
const disabled = options.disabled ?? scope?.disabled ?? false;
|
|
119
|
+
const readOnly = options.readOnly ?? scope?.readOnly ?? false;
|
|
120
|
+
const invalid = options.invalid ?? scope?.invalid ?? false;
|
|
121
|
+
const described = joinIds(scope?.describedBy, options["aria-describedby"]);
|
|
122
|
+
const setLabelFocus = options.labelBehavior === "focus" ? scope?.setLabelFocus : void 0;
|
|
123
|
+
useEffect(() => {
|
|
124
|
+
if (setLabelFocus === void 0) return void 0;
|
|
125
|
+
setLabelFocus(true);
|
|
126
|
+
return () => setLabelFocus(false);
|
|
127
|
+
}, [setLabelFocus]);
|
|
128
|
+
return {
|
|
129
|
+
inField: scope !== null,
|
|
130
|
+
id,
|
|
131
|
+
labelledBy: scope?.labelledBy,
|
|
132
|
+
describedBy: described,
|
|
133
|
+
name,
|
|
134
|
+
required,
|
|
135
|
+
disabled,
|
|
136
|
+
readOnly,
|
|
137
|
+
invalid,
|
|
138
|
+
controlProps: {
|
|
139
|
+
...fieldControlProps({
|
|
140
|
+
id,
|
|
141
|
+
name,
|
|
142
|
+
required,
|
|
143
|
+
disabled,
|
|
144
|
+
readOnly,
|
|
145
|
+
invalid,
|
|
146
|
+
describedBy: described
|
|
147
|
+
}),
|
|
148
|
+
...scope?.handlers
|
|
149
|
+
}
|
|
150
|
+
};
|
|
151
|
+
}
|
|
152
|
+
/**
|
|
153
|
+
* `labelBehavior: 'focus'`: a `<label for>` a button presses it, which would open its popup. Cancel
|
|
154
|
+
* that and focus the control, with the ring showing where focus went, as React Aria's own Select
|
|
155
|
+
* label does. A disabled control takes no focus.
|
|
156
|
+
*/
|
|
157
|
+
function focusControl(event) {
|
|
158
|
+
event.preventDefault();
|
|
159
|
+
event.currentTarget.control?.focus({ focusVisible: true });
|
|
160
|
+
}
|
|
161
|
+
const VALIDITY_KEYS = [
|
|
162
|
+
"valueMissing",
|
|
163
|
+
"typeMismatch",
|
|
164
|
+
"patternMismatch",
|
|
165
|
+
"tooLong",
|
|
166
|
+
"tooShort",
|
|
167
|
+
"rangeUnderflow",
|
|
168
|
+
"rangeOverflow",
|
|
169
|
+
"stepMismatch",
|
|
170
|
+
"badInput",
|
|
171
|
+
"customError"
|
|
172
|
+
];
|
|
173
|
+
/** The Field's message for the first failing validity flag, else the browser's own text. */
|
|
174
|
+
function messageOf(element, messages) {
|
|
175
|
+
const key = VALIDITY_KEYS.find((flag) => element.validity[flag]);
|
|
176
|
+
return (key === void 0 ? void 0 : messages?.[key]) ?? element.validationMessage;
|
|
177
|
+
}
|
|
178
|
+
/**
|
|
179
|
+
* The form's first control that fails validation, in tree order. Not `querySelector(':invalid')`:
|
|
180
|
+
* `fieldset:invalid` matches the ancestor first.
|
|
181
|
+
*/
|
|
182
|
+
function firstInvalid(form) {
|
|
183
|
+
for (const element of form.elements) if (isValidatable(element) && element.willValidate && !element.validity.valid) return element;
|
|
184
|
+
}
|
|
185
|
+
/**
|
|
186
|
+
* A validation request: with focus in the Field, the next error text that commits is spoken. With
|
|
187
|
+
* `last` (native validation, which answers in the same commit) the current text also counts as not
|
|
188
|
+
* yet seen. A submit passes none: its reply comes later, and the re-renders before it (a pending
|
|
189
|
+
* state, an `error` node rebuilt) keep the old text, which must not count as new.
|
|
190
|
+
*/
|
|
191
|
+
function arm(region, asked, last) {
|
|
192
|
+
if (inside(region.current)) {
|
|
193
|
+
asked.current = true;
|
|
194
|
+
if (last) last.current = null;
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
/** Focus is in the Field root that holds the announcer (a group control's radios included). */
|
|
198
|
+
function inside(region) {
|
|
199
|
+
return region?.parentNode?.contains(region.ownerDocument.activeElement) === true;
|
|
200
|
+
}
|
|
201
|
+
function isValidatable(element) {
|
|
202
|
+
return "validity" in element && "willValidate" in element;
|
|
203
|
+
}
|
|
204
|
+
//#endregion
|
|
205
|
+
export { FieldScope, useFieldControl };
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
import { RenderProp } from "../contracts/render.js";
|
|
2
|
+
import { ComponentPropsWithRef, ReactElement, ReactNode } from "react";
|
|
3
|
+
//#region src/field/field-static.d.ts
|
|
4
|
+
/** When native validation messages are presented. */
|
|
5
|
+
export type FieldValidateOn = "submit" | "blur";
|
|
6
|
+
/** The `ValidityState` flags a `messages` entry can replace. */
|
|
7
|
+
export type FieldValidityKey = "valueMissing" | "typeMismatch" | "patternMismatch" | "tooLong" | "tooShort" | "rangeUnderflow" | "rangeOverflow" | "stepMismatch" | "badInput" | "customError";
|
|
8
|
+
/** Ids a Field generates; each one given here replaces the generated one (Conform, tests). */
|
|
9
|
+
export interface FieldIds {
|
|
10
|
+
control?: string | undefined;
|
|
11
|
+
label?: string | undefined;
|
|
12
|
+
description?: string | undefined;
|
|
13
|
+
error?: string | undefined;
|
|
14
|
+
}
|
|
15
|
+
export interface FieldState {
|
|
16
|
+
/** An error message is presented. */
|
|
17
|
+
invalid: boolean;
|
|
18
|
+
disabled: boolean;
|
|
19
|
+
required: boolean;
|
|
20
|
+
readOnly: boolean;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Attributes for the native element of a control: what a function child receives, and the base of
|
|
24
|
+
* `useFieldControl().controlProps`. Serialisable; flags are `true` or `undefined`, never `false`.
|
|
25
|
+
*/
|
|
26
|
+
export type FieldControlProps = {
|
|
27
|
+
id?: string | undefined;
|
|
28
|
+
name?: string | undefined;
|
|
29
|
+
required?: boolean | undefined;
|
|
30
|
+
disabled?: boolean | undefined;
|
|
31
|
+
readOnly?: boolean | undefined;
|
|
32
|
+
"aria-describedby"?: string | undefined;
|
|
33
|
+
"aria-invalid"?: boolean | undefined;
|
|
34
|
+
};
|
|
35
|
+
export interface FieldProps extends Omit<ComponentPropsWithRef<"div">, "children"> {
|
|
36
|
+
/** The visible name, a `<label for>` the control. */
|
|
37
|
+
label?: ReactNode;
|
|
38
|
+
/** Help text under the control, joined to its `aria-describedby`. */
|
|
39
|
+
description?: ReactNode;
|
|
40
|
+
/**
|
|
41
|
+
* The error message, rendered through InlineError with an icon (never colour alone). Its presence
|
|
42
|
+
* is what "invalid" means (§8.3): `aria-invalid` on the control and `data-invalid` on the Field.
|
|
43
|
+
* It is not a live region; around a client control, the Field's one announcer speaks a new error
|
|
44
|
+
* while focus is already in the Field (§16.5's one exception, FIELD-CONTRACT.md). `null`, `false`
|
|
45
|
+
* and `''` present no error.
|
|
46
|
+
*/
|
|
47
|
+
error?: ReactNode;
|
|
48
|
+
/** Replaces the internal error mark (`circle-x`). Decorative. */
|
|
49
|
+
errorIcon?: ReactNode;
|
|
50
|
+
/**
|
|
51
|
+
* The control is a group of native controls under one root (SegmentedControl, a third-party
|
|
52
|
+
* picker), not one labelable element: the label then has no `for`, and names the group through
|
|
53
|
+
* the `aria-labelledby` the control puts on its root (FIELD-CONTRACT.md). @default false
|
|
54
|
+
*/
|
|
55
|
+
group?: boolean;
|
|
56
|
+
/** Passed to the control. */
|
|
57
|
+
name?: string;
|
|
58
|
+
/** The control is required: native `required`, and an `aria-hidden` mark after the label. @default false */
|
|
59
|
+
required?: boolean;
|
|
60
|
+
/** @default false */
|
|
61
|
+
disabled?: boolean;
|
|
62
|
+
/** @default false */
|
|
63
|
+
readOnly?: boolean;
|
|
64
|
+
ids?: FieldIds;
|
|
65
|
+
/** Messages for native validation, by validity flag, instead of the browser's own text. */
|
|
66
|
+
messages?: Partial<Record<FieldValidityKey, string>>;
|
|
67
|
+
/** Native messages appear on submit, or also when the control loses focus. @default 'submit' */
|
|
68
|
+
validateOn?: FieldValidateOn;
|
|
69
|
+
/** Composition of the root `<div>`. */
|
|
70
|
+
render?: RenderProp<FieldState>;
|
|
71
|
+
/**
|
|
72
|
+
* The control. A function receives ready-made control attributes and renders with no client code
|
|
73
|
+
* at all (zero-JS mode, for Server-Component forms and plain elements); its second argument,
|
|
74
|
+
* `field`, carries the ids for anything else, as on `FieldStatic`. A NativeSelect placed directly
|
|
75
|
+
* inside is wired the same way, with no function. Client controls (Input, Checkbox, …) read the
|
|
76
|
+
* wiring through `useFieldControl`.
|
|
77
|
+
*/
|
|
78
|
+
children?: ReactNode | ((control: FieldControlProps, field: FieldStaticWiring) => ReactNode);
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* What a FieldStatic function child receives as its second argument: the wiring FieldStatic does
|
|
82
|
+
* not do for you, since it provides no context. Use it for a control that is not one labelable
|
|
83
|
+
* element (`aria-labelledby` on a group root or a button) or to point other elements at the parts.
|
|
84
|
+
*/
|
|
85
|
+
export interface FieldStaticWiring extends FieldState {
|
|
86
|
+
/** Every id the Field renders, generated or taken from `ids`. */
|
|
87
|
+
ids: {
|
|
88
|
+
control: string;
|
|
89
|
+
label: string;
|
|
90
|
+
description: string;
|
|
91
|
+
error: string;
|
|
92
|
+
};
|
|
93
|
+
/** The label's id while a label renders, for `aria-labelledby`; `undefined` without a label. */
|
|
94
|
+
labelledBy: string | undefined;
|
|
95
|
+
/** The description and error ids that render, in that order; the control's `aria-describedby`. */
|
|
96
|
+
describedBy: string | undefined;
|
|
97
|
+
}
|
|
98
|
+
export interface FieldStaticProps extends Omit<FieldProps, "children" | "messages" | "validateOn"> {
|
|
99
|
+
/**
|
|
100
|
+
* Not on FieldStatic: nothing intercepts native validation, so the browser shows its own bubble.
|
|
101
|
+
* For inline native messages use `Field`.
|
|
102
|
+
*/
|
|
103
|
+
messages?: never;
|
|
104
|
+
/** Not on FieldStatic: see `messages`. */
|
|
105
|
+
validateOn?: never;
|
|
106
|
+
/**
|
|
107
|
+
* The control, always a function: FieldStatic provides no context, so a Nizivo client control
|
|
108
|
+
* placed directly inside (`<Input />`) would not be wired, and that is a type error here (use
|
|
109
|
+
* `Field`). Spread `control` on the element that holds the value (`<input {...control} />`,
|
|
110
|
+
* `<NativeSelect {...control}>`); `field` carries the ids for anything else.
|
|
111
|
+
*/
|
|
112
|
+
children: (control: FieldControlProps, field: FieldStaticWiring) => ReactNode;
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* The Field anatomy with no client code: label, control, description and error, the same HTML and
|
|
116
|
+
* ids as `Field` with a function child (M31). Server-safe, and its module imports no client leaf,
|
|
117
|
+
* so a page that renders only FieldStatic ships no Field JavaScript in any bundler. It provides no
|
|
118
|
+
* context and no announcer, and native validation shows the browser's own bubble; the function
|
|
119
|
+
* child wires the control (FIELD-CONTRACT.md "FieldStatic").
|
|
120
|
+
*/
|
|
121
|
+
export declare function FieldStatic({ label, description, error, errorIcon, group, name, required, disabled, readOnly, ids, render, children, messages: _messages, validateOn: _validateOn, ...root }: FieldStaticProps): ReactElement;
|
|
122
|
+
//#endregion
|