@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 @@
|
|
|
1
|
+
export { Switch } from "./switch.client.js";
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { RenderProp } from "../contracts/render.js";
|
|
2
|
+
import { ChangeDetails } from "../contracts/details.js";
|
|
3
|
+
import { ComponentPropsWithRef, ReactElement, ReactNode } from "react";
|
|
4
|
+
//#region src/switch/switch.client.d.ts
|
|
5
|
+
/** Every change comes from the native `change` event: a click, Space, or a click on the label. */
|
|
6
|
+
export type SwitchChangeReason = "input";
|
|
7
|
+
/** What a `render` function receives for the root `<label>`. */
|
|
8
|
+
export interface SwitchState {
|
|
9
|
+
/** An error message is presented (the Field's, or the `invalid` prop). */
|
|
10
|
+
invalid: boolean;
|
|
11
|
+
disabled: boolean;
|
|
12
|
+
required: boolean;
|
|
13
|
+
}
|
|
14
|
+
export interface SwitchProps extends Omit<ComponentPropsWithRef<"input">, "type" | "role" | "children" | "readOnly" | "size"> {
|
|
15
|
+
/** Controlled state: on or off. */
|
|
16
|
+
checked?: boolean;
|
|
17
|
+
/** Uncontrolled initial state. @default false */
|
|
18
|
+
defaultChecked?: boolean;
|
|
19
|
+
/** Called after the consumer's own `onChange`, unless it called `preventDefault()`. */
|
|
20
|
+
onCheckedChange?: (checked: boolean, details: ChangeDetails<SwitchChangeReason>) => void;
|
|
21
|
+
/** An error message is presented for this switch. Inside a Field, the Field decides. */
|
|
22
|
+
invalid?: boolean;
|
|
23
|
+
/** Composition of the root `<label>`, the hit target. */
|
|
24
|
+
render?: RenderProp<SwitchState>;
|
|
25
|
+
/** The label, after the track. Without one, name the switch with `aria-label`. */
|
|
26
|
+
children?: ReactNode;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* `className` and `style` go on the root `<label>`; every other attribute, `ref` included, goes on the
|
|
30
|
+
* native `<input>`. With `name`, the form submits `value` (default `"on"`) while the switch is on.
|
|
31
|
+
*/
|
|
32
|
+
export declare function Switch({ id, name, required, disabled, invalid, "aria-describedby": describedBy, onCheckedChange, render, className, style, children, ...rest }: SwitchProps): ReactElement;
|
|
33
|
+
//#endregion
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { cx } from "../_internal/cx.js";
|
|
3
|
+
import { mergeProps } from "../contracts/merge-props.js";
|
|
4
|
+
import { renderElement } from "../contracts/render.js";
|
|
5
|
+
import { details } from "../contracts/details.js";
|
|
6
|
+
import { stateAttrs } from "../contracts/state.js";
|
|
7
|
+
import { presented } from "../_internal/field.js";
|
|
8
|
+
import { useFieldControl } from "../field/field-scope.client.js";
|
|
9
|
+
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
10
|
+
//#region src/switch/switch.client.tsx
|
|
11
|
+
/**
|
|
12
|
+
* `className` and `style` go on the root `<label>`; every other attribute, `ref` included, goes on the
|
|
13
|
+
* native `<input>`. With `name`, the form submits `value` (default `"on"`) while the switch is on.
|
|
14
|
+
*/
|
|
15
|
+
function Switch({ id, name, required, disabled, invalid, "aria-describedby": describedBy, onCheckedChange, render, className, style, children, ...rest }) {
|
|
16
|
+
const field = useFieldControl({
|
|
17
|
+
id,
|
|
18
|
+
name,
|
|
19
|
+
required,
|
|
20
|
+
disabled,
|
|
21
|
+
invalid,
|
|
22
|
+
"aria-describedby": describedBy
|
|
23
|
+
});
|
|
24
|
+
const { readOnly: _readOnly, ...control } = field.controlProps;
|
|
25
|
+
const own = {
|
|
26
|
+
...control,
|
|
27
|
+
onChange(event) {
|
|
28
|
+
onCheckedChange?.(event.currentTarget.checked, details("input", event.nativeEvent));
|
|
29
|
+
}
|
|
30
|
+
};
|
|
31
|
+
const state = {
|
|
32
|
+
invalid: field.invalid,
|
|
33
|
+
disabled: field.disabled,
|
|
34
|
+
required: field.required
|
|
35
|
+
};
|
|
36
|
+
return renderElement("label", render, state, {
|
|
37
|
+
"data-slot": "switch",
|
|
38
|
+
...stateAttrs(state),
|
|
39
|
+
className: cx("nz-switch nz-hit-target", className),
|
|
40
|
+
style,
|
|
41
|
+
children: /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
42
|
+
/* @__PURE__ */ jsx("input", {
|
|
43
|
+
...mergeProps(own, rest),
|
|
44
|
+
type: "checkbox",
|
|
45
|
+
role: "switch",
|
|
46
|
+
className: "nz-switch-input",
|
|
47
|
+
"data-slot": "switch-input"
|
|
48
|
+
}),
|
|
49
|
+
/* @__PURE__ */ jsx("span", {
|
|
50
|
+
className: "nz-switch-thumb",
|
|
51
|
+
"data-slot": "switch-thumb",
|
|
52
|
+
"aria-hidden": "true"
|
|
53
|
+
}),
|
|
54
|
+
presented(children) && /* @__PURE__ */ jsx("span", {
|
|
55
|
+
className: "nz-switch-label",
|
|
56
|
+
"data-slot": "switch-label",
|
|
57
|
+
children
|
|
58
|
+
})
|
|
59
|
+
] })
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
//#endregion
|
|
63
|
+
export { Switch };
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import { TabNavLink, TabNavLinkProps, TabNavLinkState, TabNavRoot, TabNavRootProps } from "./tab-nav.js";
|
|
2
|
+
import { tab_nav_parts_d_exports } from "./tab-nav.parts.js";
|
|
3
|
+
export { tab_nav_parts_d_exports as TabNav, TabNavLink, type TabNavLinkProps, type TabNavLinkState, TabNavRoot, type TabNavRootProps };
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { RenderProp } from "../contracts/render.js";
|
|
2
|
+
import { ComponentPropsWithRef, ReactElement, ReactNode } from "react";
|
|
3
|
+
//#region src/tab-nav/tab-nav.d.ts
|
|
4
|
+
export interface TabNavRootProps extends ComponentPropsWithRef<"nav"> {
|
|
5
|
+
/**
|
|
6
|
+
* Names the landmark ("Order status"). A page with more than one navigation landmark needs a
|
|
7
|
+
* name on each.
|
|
8
|
+
*/
|
|
9
|
+
"aria-label"?: string;
|
|
10
|
+
/** Must render a navigation landmark (a `<nav>`, or an element with `role="navigation"`). */
|
|
11
|
+
render?: RenderProp<Record<string, never>>;
|
|
12
|
+
}
|
|
13
|
+
export interface TabNavLinkState {
|
|
14
|
+
current: boolean;
|
|
15
|
+
}
|
|
16
|
+
export interface TabNavLinkProps extends Omit<ComponentPropsWithRef<"a">, "children"> {
|
|
17
|
+
/**
|
|
18
|
+
* The link to the page being shown: sets `aria-current="page"` and draws the indicator. The page
|
|
19
|
+
* knows its own route, so it says which link is current (a router's `usePathname` needs a client
|
|
20
|
+
* component; a server page reads its params). @default false
|
|
21
|
+
*/
|
|
22
|
+
current?: boolean;
|
|
23
|
+
/** A decorative glyph before the label (16 px). */
|
|
24
|
+
icon?: ReactNode;
|
|
25
|
+
/** A count after the label, such as the number of orders in a status. */
|
|
26
|
+
count?: ReactNode;
|
|
27
|
+
/**
|
|
28
|
+
* The router's link, for example `render={<Link href="/orders?status=open" />}` (Next.js, React
|
|
29
|
+
* Router, TanStack Router, Astro's plain `<a>`). It must render an `<a>`.
|
|
30
|
+
*/
|
|
31
|
+
render?: RenderProp<TabNavLinkState>;
|
|
32
|
+
children: ReactNode;
|
|
33
|
+
}
|
|
34
|
+
export declare function TabNavRoot({ render, className, ...rest }: TabNavRootProps): ReactElement;
|
|
35
|
+
export declare function TabNavLink({ current, icon, count, render, className, children, ...rest }: TabNavLinkProps): ReactElement;
|
|
36
|
+
//#endregion
|
|
@@ -0,0 +1,47 @@
|
|
|
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/tab-nav/tab-nav.tsx
|
|
5
|
+
function TabNavRoot({ render, className, ...rest }) {
|
|
6
|
+
return renderElement("nav", render, {}, {
|
|
7
|
+
"data-slot": "tab-nav",
|
|
8
|
+
...rest,
|
|
9
|
+
className: cx("nz-tab-nav", className)
|
|
10
|
+
});
|
|
11
|
+
}
|
|
12
|
+
function TabNavLink({ current = false, icon, count, render, className, children, ...rest }) {
|
|
13
|
+
return renderElement("a", render, { current }, {
|
|
14
|
+
"data-slot": "tab-nav-link",
|
|
15
|
+
"data-focus-inset": "",
|
|
16
|
+
...rest,
|
|
17
|
+
"aria-current": current ? "page" : rest["aria-current"],
|
|
18
|
+
className: cx("nz-tab-nav-link", className),
|
|
19
|
+
children: /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
20
|
+
icon != null && /* @__PURE__ */ jsx("span", {
|
|
21
|
+
className: "nz-tab-nav-icon",
|
|
22
|
+
"data-slot": "tab-nav-icon",
|
|
23
|
+
"aria-hidden": "true",
|
|
24
|
+
children: icon
|
|
25
|
+
}),
|
|
26
|
+
/* @__PURE__ */ jsxs("span", {
|
|
27
|
+
className: "nz-tab-nav-label",
|
|
28
|
+
"data-slot": "tab-nav-label",
|
|
29
|
+
children: [/* @__PURE__ */ jsx("span", {
|
|
30
|
+
className: "nz-tab-nav-text",
|
|
31
|
+
children
|
|
32
|
+
}), /* @__PURE__ */ jsx("span", {
|
|
33
|
+
className: "nz-tab-nav-sizer",
|
|
34
|
+
"aria-hidden": "true",
|
|
35
|
+
children
|
|
36
|
+
})]
|
|
37
|
+
}),
|
|
38
|
+
count != null && /* @__PURE__ */ jsx("span", {
|
|
39
|
+
className: "nz-tab-nav-count",
|
|
40
|
+
"data-slot": "tab-nav-count",
|
|
41
|
+
children: count
|
|
42
|
+
})
|
|
43
|
+
] })
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
//#endregion
|
|
47
|
+
export { TabNavLink, TabNavRoot };
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { __exportAll } from "../_virtual/_rolldown/runtime.js";
|
|
2
|
+
import { TabNavLink, TabNavRoot } from "./tab-nav.js";
|
|
3
|
+
//#region src/tab-nav/tab-nav.parts.ts
|
|
4
|
+
var tab_nav_parts_exports = /* @__PURE__ */ __exportAll({
|
|
5
|
+
Link: () => TabNavLink,
|
|
6
|
+
Root: () => TabNavRoot
|
|
7
|
+
});
|
|
8
|
+
//#endregion
|
|
9
|
+
export { TabNavLink as Link, TabNavRoot as Root, tab_nav_parts_exports };
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { TabsActivationMode, TabsListProps, TabsListState, TabsPanelProps, TabsPanelState, TabsRootProps, TabsRootState, TabsTabProps, TabsTabState, TabsValueReason } from "./tabs.contract.js";
|
|
2
|
+
import { TabsList, TabsPanel, TabsRoot, TabsTab } from "./tabs.client.js";
|
|
3
|
+
import { tabs_parts_d_exports } from "./tabs.parts.js";
|
|
4
|
+
export { tabs_parts_d_exports as Tabs, type TabsActivationMode, TabsList, type TabsListProps, type TabsListState, TabsPanel, type TabsPanelProps, type TabsPanelState, TabsRoot, type TabsRootProps, type TabsRootState, TabsTab, type TabsTabProps, type TabsTabState, type TabsValueReason };
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { TabsListProps, TabsPanelProps, TabsRootProps, TabsTabProps } from "./tabs.contract.js";
|
|
2
|
+
import { JSX } from "react";
|
|
3
|
+
//#region src/tabs/tabs.client.d.ts
|
|
4
|
+
export declare function TabsRoot({ activationMode, className, render, ...rest }: TabsRootProps): JSX.Element;
|
|
5
|
+
export declare function TabsList({ className, render, ...rest }: TabsListProps): JSX.Element;
|
|
6
|
+
export declare function TabsTab({ icon, count, className, render, children, ...rest }: TabsTabProps): JSX.Element;
|
|
7
|
+
export declare function TabsPanel({ keepMounted, className, render, ...rest }: TabsPanelProps): JSX.Element;
|
|
8
|
+
//#endregion
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { cx } from "../_internal/cx.js";
|
|
3
|
+
import { toRenderFn } from "../contracts/render.js";
|
|
4
|
+
import { List, Panel, Root, Tab } from "../_engines/react-aria/tabs.client.js";
|
|
5
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
6
|
+
//#region src/tabs/tabs.client.tsx
|
|
7
|
+
function TabsRoot({ activationMode = "automatic", className, render, ...rest }) {
|
|
8
|
+
return /* @__PURE__ */ jsx(Root, {
|
|
9
|
+
...rest,
|
|
10
|
+
activationMode,
|
|
11
|
+
className: cx("nz-tabs", className),
|
|
12
|
+
"data-slot": "tabs",
|
|
13
|
+
render: toRenderFn(render, "div")
|
|
14
|
+
});
|
|
15
|
+
}
|
|
16
|
+
function TabsList({ className, render, ...rest }) {
|
|
17
|
+
return /* @__PURE__ */ jsx(List, {
|
|
18
|
+
...rest,
|
|
19
|
+
className: cx("nz-tabs-list", className),
|
|
20
|
+
"data-slot": "tabs-list",
|
|
21
|
+
render: toRenderFn(render, "div")
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
function TabsTab({ icon, count, className, render, children, ...rest }) {
|
|
25
|
+
return /* @__PURE__ */ jsxs(Tab, {
|
|
26
|
+
...rest,
|
|
27
|
+
className: cx("nz-tabs-tab", className),
|
|
28
|
+
"data-slot": "tabs-tab",
|
|
29
|
+
"data-focus-inset": "",
|
|
30
|
+
render: toRenderFn(render, "div"),
|
|
31
|
+
children: [
|
|
32
|
+
icon != null && /* @__PURE__ */ jsx("span", {
|
|
33
|
+
className: "nz-tabs-icon",
|
|
34
|
+
"data-slot": "tabs-icon",
|
|
35
|
+
"aria-hidden": "true",
|
|
36
|
+
children: icon
|
|
37
|
+
}),
|
|
38
|
+
/* @__PURE__ */ jsxs("span", {
|
|
39
|
+
className: "nz-tabs-label",
|
|
40
|
+
"data-slot": "tabs-label",
|
|
41
|
+
children: [/* @__PURE__ */ jsx("span", {
|
|
42
|
+
className: "nz-tabs-text",
|
|
43
|
+
children
|
|
44
|
+
}), /* @__PURE__ */ jsx("span", {
|
|
45
|
+
className: "nz-tabs-sizer",
|
|
46
|
+
"aria-hidden": "true",
|
|
47
|
+
children
|
|
48
|
+
})]
|
|
49
|
+
}),
|
|
50
|
+
count != null && /* @__PURE__ */ jsx("span", {
|
|
51
|
+
className: "nz-tabs-count",
|
|
52
|
+
"data-slot": "tabs-count",
|
|
53
|
+
children: count
|
|
54
|
+
})
|
|
55
|
+
]
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
function TabsPanel({ keepMounted = false, className, render, ...rest }) {
|
|
59
|
+
return /* @__PURE__ */ jsx(Panel, {
|
|
60
|
+
...rest,
|
|
61
|
+
keepMounted,
|
|
62
|
+
className: cx("nz-tabs-panel", className),
|
|
63
|
+
"data-slot": "tabs-panel",
|
|
64
|
+
render: toRenderFn(render, "div")
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
//#endregion
|
|
68
|
+
export { TabsList, TabsPanel, TabsRoot, TabsTab };
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import { RenderProp } from "../contracts/render.js";
|
|
2
|
+
import { ChangeDetails } from "../contracts/details.js";
|
|
3
|
+
import "../_internal/engine-part.js";
|
|
4
|
+
import { ComponentPropsWithRef, ReactElement, ReactNode } from "react";
|
|
5
|
+
//#region src/tabs/tabs.contract.d.ts
|
|
6
|
+
/**
|
|
7
|
+
* Why the selected tab changed. React Aria reports no cause, so with it `details.reason` is always
|
|
8
|
+
* `'unknown'` (§9.3 rule 2); the names are the causes an engine that reports one would use.
|
|
9
|
+
*/
|
|
10
|
+
export type TabsValueReason = "tab-press" | "keyboard";
|
|
11
|
+
/**
|
|
12
|
+
* When a tab is selected (WAI-ARIA APG tabs).
|
|
13
|
+
* - `automatic`: an arrow key moves focus and selects the tab it lands on (the APG default, for
|
|
14
|
+
* panels that show without a noticeable delay);
|
|
15
|
+
* - `manual`: arrow keys only move focus; Enter or Space selects (for panels that are slow to show).
|
|
16
|
+
*/
|
|
17
|
+
export type TabsActivationMode = "automatic" | "manual";
|
|
18
|
+
export interface TabsRootState {
|
|
19
|
+
disabled: boolean;
|
|
20
|
+
}
|
|
21
|
+
export interface TabsListState {
|
|
22
|
+
disabled: boolean;
|
|
23
|
+
}
|
|
24
|
+
export interface TabsTabState {
|
|
25
|
+
selected: boolean;
|
|
26
|
+
disabled: boolean;
|
|
27
|
+
focusVisible: boolean;
|
|
28
|
+
}
|
|
29
|
+
export interface TabsPanelState {
|
|
30
|
+
/** The panel's tab is selected. False only on a `keepMounted` panel whose tab is not. */
|
|
31
|
+
selected: boolean;
|
|
32
|
+
focusVisible: boolean;
|
|
33
|
+
}
|
|
34
|
+
export interface TabsRootProps extends Omit<ComponentPropsWithRef<"div">, "children" | "defaultValue" | "onChange" | "id" | "dir"> {
|
|
35
|
+
/** Controlled: the selected tab's `value`. */
|
|
36
|
+
value?: string;
|
|
37
|
+
/** The tab selected at first (uncontrolled). Defaults to the first tab that is not disabled. */
|
|
38
|
+
defaultValue?: string;
|
|
39
|
+
/** Called when the user selects a tab. `details.reason` is `'unknown'` with React Aria. */
|
|
40
|
+
onValueChange?: (value: string, details: ChangeDetails<TabsValueReason>) => void;
|
|
41
|
+
/** @default 'automatic' */
|
|
42
|
+
activationMode?: TabsActivationMode;
|
|
43
|
+
/** Disables every tab. The selected panel still shows. */
|
|
44
|
+
disabled?: boolean;
|
|
45
|
+
/**
|
|
46
|
+
* The strip's reading direction (M26), rendered as the root's `dir` attribute: the layout and the
|
|
47
|
+
* arrow keys follow it (in `rtl`, ArrowLeft moves to the next tab). Unset, nothing is rendered and
|
|
48
|
+
* the arrows follow the direction of the `NizivoConfig` scope's `locale`. Nothing reads the DOM, so
|
|
49
|
+
* a `dir` attribute set higher up does not turn the arrows: a strip whose direction differs from
|
|
50
|
+
* its locale's sets it here. `'auto'` is not accepted for the same reason.
|
|
51
|
+
*/
|
|
52
|
+
dir?: "ltr" | "rtl";
|
|
53
|
+
/** Must render a `<div>`. */
|
|
54
|
+
render?: RenderProp<TabsRootState>;
|
|
55
|
+
/** One `Tabs.List` and its `Tabs.Panel`s. */
|
|
56
|
+
children: ReactNode;
|
|
57
|
+
}
|
|
58
|
+
export interface TabsListProps extends Omit<ComponentPropsWithRef<"div">, "children" | "id"> {
|
|
59
|
+
/** Must render a `<div>`. */
|
|
60
|
+
render?: RenderProp<TabsListState>;
|
|
61
|
+
/** `Tabs.Tab` elements. */
|
|
62
|
+
children: ReactNode;
|
|
63
|
+
}
|
|
64
|
+
export interface TabsTabProps extends Omit<ComponentPropsWithRef<"div">, "children" | "id" | "onClick"> {
|
|
65
|
+
/** Pairs the tab with the `Tabs.Panel` of the same `value`. */
|
|
66
|
+
value: string;
|
|
67
|
+
disabled?: boolean;
|
|
68
|
+
/** A decorative glyph before the label (16 px). */
|
|
69
|
+
icon?: ReactNode;
|
|
70
|
+
/** A count after the label, such as the number of orders in a status. */
|
|
71
|
+
count?: ReactNode;
|
|
72
|
+
/** Must render a `<div>`. */
|
|
73
|
+
render?: RenderProp<TabsTabState>;
|
|
74
|
+
children: ReactNode;
|
|
75
|
+
}
|
|
76
|
+
export interface TabsPanelProps extends Omit<ComponentPropsWithRef<"div">, "children" | "id"> {
|
|
77
|
+
/** The `value` of the tab that shows this panel. */
|
|
78
|
+
value: string;
|
|
79
|
+
/**
|
|
80
|
+
* Keeps the panel mounted, `hidden`, while its tab is not selected, so its state (a scroll
|
|
81
|
+
* position, a form draft) survives switching. Without it only the selected panel is rendered, on
|
|
82
|
+
* the server too. @default false
|
|
83
|
+
*/
|
|
84
|
+
keepMounted?: boolean;
|
|
85
|
+
/** Must render a `<div>`. */
|
|
86
|
+
render?: RenderProp<TabsPanelState>;
|
|
87
|
+
children?: ReactNode;
|
|
88
|
+
}
|
|
89
|
+
//#endregion
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { TabsList, TabsPanel, TabsRoot, TabsTab } from "./tabs.client.js";
|
|
2
|
+
declare namespace tabs_parts_d_exports {
|
|
3
|
+
export { TabsList as List, TabsPanel as Panel, TabsRoot as Root, TabsTab as Tab };
|
|
4
|
+
}
|
|
5
|
+
//#endregion
|
|
6
|
+
export { TabsList as List, TabsPanel as Panel, TabsRoot as Root, TabsTab as Tab, tabs_parts_d_exports };
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { __exportAll } from "../_virtual/_rolldown/runtime.js";
|
|
2
|
+
import { TabsList, TabsPanel, TabsRoot, TabsTab } from "./tabs.client.js";
|
|
3
|
+
//#region src/tabs/tabs.parts.ts
|
|
4
|
+
var tabs_parts_exports = /* @__PURE__ */ __exportAll({
|
|
5
|
+
List: () => TabsList,
|
|
6
|
+
Panel: () => TabsPanel,
|
|
7
|
+
Root: () => TabsRoot,
|
|
8
|
+
Tab: () => TabsTab
|
|
9
|
+
});
|
|
10
|
+
//#endregion
|
|
11
|
+
export { TabsList as List, TabsPanel as Panel, TabsRoot as Root, TabsTab as Tab, tabs_parts_exports };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { Text } from "./text.js";
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { RenderProp } from "../contracts/render.js";
|
|
2
|
+
import { ComponentPropsWithRef, ReactElement } from "react";
|
|
3
|
+
//#region src/text/text.d.ts
|
|
4
|
+
/** The Figma text styles as lowercase names (`Nizivo/Label/M` → `label-m`), plus the 12 px proposals. */
|
|
5
|
+
export type TextVariant = "display-l" | "display-m" | "heading-h1" | "heading-h2" | "heading-h3" | "heading-h4" | "body-l" | "body-m" | "body-m-strong" | "body-s" | "label-l" | "label-m" | "label-m-strong" | "label-s" | "numeric-display" | "numeric-kpi" | "numeric-l" | "numeric-m" | "mono-m" | "mono-m-strong";
|
|
6
|
+
/** The `text/*` colour tokens. `accent` and `on-critical` are code-owned proposals (§15.3). */
|
|
7
|
+
export type TextTone = "primary" | "secondary" | "tertiary" | "disabled" | "inverse" | "on-brand" | "on-accent" | "on-critical" | "brand" | "accent" | "success" | "warning" | "critical" | "info";
|
|
8
|
+
export interface TextState {
|
|
9
|
+
variant: TextVariant;
|
|
10
|
+
tone: TextTone | undefined;
|
|
11
|
+
}
|
|
12
|
+
export interface TextProps extends ComponentPropsWithRef<"p"> {
|
|
13
|
+
/** The text style. 12 px exists only as `body-s` and `label-s` (§15.1). @default 'body-m' */
|
|
14
|
+
variant?: TextVariant;
|
|
15
|
+
/** A `text/*` colour. Absent, the colour is inherited from the surface. */
|
|
16
|
+
tone?: TextTone;
|
|
17
|
+
/** Another element or component, for example `render={<span />}` or `render={<label htmlFor="sku" />}`. */
|
|
18
|
+
render?: RenderProp<TextState>;
|
|
19
|
+
}
|
|
20
|
+
export declare function Text({ variant, tone, render, className, ...rest }: TextProps): ReactElement;
|
|
21
|
+
//#endregion
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { cx } from "../_internal/cx.js";
|
|
2
|
+
import { renderElement } from "../contracts/render.js";
|
|
3
|
+
//#region src/text/text.tsx
|
|
4
|
+
function Text({ variant = "body-m", tone, render, className, ...rest }) {
|
|
5
|
+
return renderElement("p", render, {
|
|
6
|
+
variant,
|
|
7
|
+
tone
|
|
8
|
+
}, {
|
|
9
|
+
"data-slot": "text",
|
|
10
|
+
"data-variant": variant,
|
|
11
|
+
"data-tone": tone,
|
|
12
|
+
...rest,
|
|
13
|
+
className: cx("nz-text", className)
|
|
14
|
+
});
|
|
15
|
+
}
|
|
16
|
+
//#endregion
|
|
17
|
+
export { Text };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { Textarea } from "./textarea.client.js";
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { ComponentPropsWithRef, JSX } from "react";
|
|
2
|
+
//#region src/textarea/textarea.client.d.ts
|
|
3
|
+
export interface TextareaProps extends Omit<ComponentPropsWithRef<"textarea">, "children"> {
|
|
4
|
+
/**
|
|
5
|
+
* Visible lines of text. The height is the larger of these rows and 112 px (Figma 7367:316; the
|
|
6
|
+
* `--nz-textarea-min-block-size` hook lowers it), so up to 4 rows of Body/M sit at 112 px. Where
|
|
7
|
+
* the textarea grows with its content, that is also its minimum (1 to 10; a larger value keeps a
|
|
8
|
+
* 3-line minimum there). @default 3
|
|
9
|
+
*/
|
|
10
|
+
rows?: number;
|
|
11
|
+
/**
|
|
12
|
+
* An error message is presented for this textarea (§8.3). Inside a Field, the Field sets it; an
|
|
13
|
+
* explicit value here wins.
|
|
14
|
+
*/
|
|
15
|
+
invalid?: boolean;
|
|
16
|
+
}
|
|
17
|
+
export declare function Textarea({ rows, id, name, required, disabled, readOnly, invalid, "aria-invalid": ariaInvalid, "aria-describedby": describedBy, className, ...rest }: TextareaProps): JSX.Element;
|
|
18
|
+
//#endregion
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { cx } from "../_internal/cx.js";
|
|
3
|
+
import { mergeProps } from "../contracts/merge-props.js";
|
|
4
|
+
import { stateAttrs } from "../contracts/state.js";
|
|
5
|
+
import { useFieldControl } from "../field/field-scope.client.js";
|
|
6
|
+
import { jsx } from "react/jsx-runtime";
|
|
7
|
+
//#region src/textarea/textarea.client.tsx
|
|
8
|
+
function Textarea({ rows = 3, id, name, required, disabled, readOnly, invalid, "aria-invalid": ariaInvalid, "aria-describedby": describedBy, className, ...rest }) {
|
|
9
|
+
const field = useFieldControl({
|
|
10
|
+
id,
|
|
11
|
+
name,
|
|
12
|
+
required,
|
|
13
|
+
disabled,
|
|
14
|
+
readOnly,
|
|
15
|
+
invalid: invalid ?? (ariaInvalid === true || ariaInvalid === "true" ? true : void 0),
|
|
16
|
+
"aria-describedby": describedBy
|
|
17
|
+
});
|
|
18
|
+
return /* @__PURE__ */ jsx("textarea", {
|
|
19
|
+
...mergeProps(field.controlProps, rest),
|
|
20
|
+
...stateAttrs({
|
|
21
|
+
invalid: field.invalid,
|
|
22
|
+
disabled: field.disabled,
|
|
23
|
+
readOnly: field.readOnly
|
|
24
|
+
}),
|
|
25
|
+
rows,
|
|
26
|
+
className: cx("nz-textarea", className),
|
|
27
|
+
"data-slot": "textarea"
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
//#endregion
|
|
31
|
+
export { Textarea };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { ThemeScript, themeScript } from "./theme-script.js";
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { ReactElement } from "react";
|
|
2
|
+
//#region src/theme-script/theme-script.d.ts
|
|
3
|
+
/**
|
|
4
|
+
* The script `ThemeScript` renders, for frameworks that inline it themselves (Astro:
|
|
5
|
+
* `<script is:inline set:html={themeScript} />`; Vite: a `transformIndexHtml` tag) or that allow it
|
|
6
|
+
* by hash under a strict CSP. It runs in `<head>`, before `<body>` exists, and sets two attributes on
|
|
7
|
+
* `<html>`:
|
|
8
|
+
*
|
|
9
|
+
* - **`data-nz-theme`, the reader's saved theme.** It reads `localStorage` key `nz-theme`; when the
|
|
10
|
+
* value is `"light"`, `"dark"` or `"system"`, it sets `data-nz-theme` to that value, replacing what
|
|
11
|
+
* the server rendered (the server's value is the app's default; the stored one is the reader's
|
|
12
|
+
* choice). `"system"` is set as is, not resolved: CSS follows the operating system from it, live,
|
|
13
|
+
* with no listener. With nothing stored, any other value, or storage blocked (a sandboxed frame,
|
|
14
|
+
* disabled site data), the attribute is left as the server rendered it. A theme switch saves the
|
|
15
|
+
* choice with `localStorage.setItem('nz-theme', value)` and sets the attribute itself.
|
|
16
|
+
* - **`data-nz-platform`**: `"apple"` when the platform string matches `/mac|iphone|ipad|ipod/i`,
|
|
17
|
+
* else `"other"`. The platform string is `navigator.userAgentData.platform` where the browser has
|
|
18
|
+
* it (Chromium: `"macOS"`, `"Windows"`, …), else `navigator.platform` (`"MacIntel"`, `"iPhone"`,
|
|
19
|
+
* `"iPad"`; iPadOS reports `"MacIntel"`, which is still Apple). It never reads the user-agent
|
|
20
|
+
* string. A value already on `<html>` (set by the server, or by a test) is kept. Kbd reads the
|
|
21
|
+
* attribute to show `⌘K` or `Ctrl+K`.
|
|
22
|
+
*
|
|
23
|
+
* Each half runs in its own `try`, so blocked storage never stops the platform half, and the script
|
|
24
|
+
* never throws into the page.
|
|
25
|
+
*
|
|
26
|
+
* Under a strict CSP, allow it by hash: `script-src 'sha256-nA1HUQWDdDUFqqoxWbjzCzcYSjzWLEe0pwDdRCMGqOw='`.
|
|
27
|
+
* The hash changes only when the script does, and a change is called out in the changelog.
|
|
28
|
+
*/
|
|
29
|
+
export declare const themeScript: string;
|
|
30
|
+
export interface ThemeScriptProps {
|
|
31
|
+
/** The CSP nonce for the inline script (`script-src 'nonce-…'`). Not needed with a hash allowlist. */
|
|
32
|
+
nonce?: string;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Sets page-level attributes before first paint, so nothing changes once the page has painted: the
|
|
36
|
+
* reader's saved theme (`data-nz-theme` from `localStorage` key `nz-theme`: `light`, `dark` or
|
|
37
|
+
* `system`) and `data-nz-platform` (`apple` or `other`). The rules are on `themeScript`. Render it in
|
|
38
|
+
* `<head>` (`<head><ThemeScript nonce={nonce} /></head>` in a root layout), put the app's default
|
|
39
|
+
* theme on `<html>` (`data-nz-theme="system"`, or none for light), and put `suppressHydrationWarning`
|
|
40
|
+
* on `<html>`, whose attributes the script changes.
|
|
41
|
+
*/
|
|
42
|
+
export declare function ThemeScript({ nonce }: ThemeScriptProps): ReactElement;
|
|
43
|
+
//#endregion
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { jsx } from "react/jsx-runtime";
|
|
2
|
+
//#region src/theme-script/theme-script.tsx
|
|
3
|
+
/**
|
|
4
|
+
* The script `ThemeScript` renders, for frameworks that inline it themselves (Astro:
|
|
5
|
+
* `<script is:inline set:html={themeScript} />`; Vite: a `transformIndexHtml` tag) or that allow it
|
|
6
|
+
* by hash under a strict CSP. It runs in `<head>`, before `<body>` exists, and sets two attributes on
|
|
7
|
+
* `<html>`:
|
|
8
|
+
*
|
|
9
|
+
* - **`data-nz-theme`, the reader's saved theme.** It reads `localStorage` key `nz-theme`; when the
|
|
10
|
+
* value is `"light"`, `"dark"` or `"system"`, it sets `data-nz-theme` to that value, replacing what
|
|
11
|
+
* the server rendered (the server's value is the app's default; the stored one is the reader's
|
|
12
|
+
* choice). `"system"` is set as is, not resolved: CSS follows the operating system from it, live,
|
|
13
|
+
* with no listener. With nothing stored, any other value, or storage blocked (a sandboxed frame,
|
|
14
|
+
* disabled site data), the attribute is left as the server rendered it. A theme switch saves the
|
|
15
|
+
* choice with `localStorage.setItem('nz-theme', value)` and sets the attribute itself.
|
|
16
|
+
* - **`data-nz-platform`**: `"apple"` when the platform string matches `/mac|iphone|ipad|ipod/i`,
|
|
17
|
+
* else `"other"`. The platform string is `navigator.userAgentData.platform` where the browser has
|
|
18
|
+
* it (Chromium: `"macOS"`, `"Windows"`, …), else `navigator.platform` (`"MacIntel"`, `"iPhone"`,
|
|
19
|
+
* `"iPad"`; iPadOS reports `"MacIntel"`, which is still Apple). It never reads the user-agent
|
|
20
|
+
* string. A value already on `<html>` (set by the server, or by a test) is kept. Kbd reads the
|
|
21
|
+
* attribute to show `⌘K` or `Ctrl+K`.
|
|
22
|
+
*
|
|
23
|
+
* Each half runs in its own `try`, so blocked storage never stops the platform half, and the script
|
|
24
|
+
* never throws into the page.
|
|
25
|
+
*
|
|
26
|
+
* Under a strict CSP, allow it by hash: `script-src 'sha256-nA1HUQWDdDUFqqoxWbjzCzcYSjzWLEe0pwDdRCMGqOw='`.
|
|
27
|
+
* The hash changes only when the script does, and a change is called out in the changelog.
|
|
28
|
+
*/
|
|
29
|
+
const themeScript = "(function(d){try{var t=localStorage.getItem(\"nz-theme\");if(/^(light|dark|system)$/.test(t))d.setAttribute(\"data-nz-theme\",t)}catch(e){}try{if(!d.hasAttribute(\"data-nz-platform\")){var n=navigator,p=(n.userAgentData&&n.userAgentData.platform)||n.platform||\"\";d.setAttribute(\"data-nz-platform\",/mac|iphone|ipad|ipod/i.test(p)?\"apple\":\"other\")}}catch(e){}})(document.documentElement)";
|
|
30
|
+
/**
|
|
31
|
+
* Sets page-level attributes before first paint, so nothing changes once the page has painted: the
|
|
32
|
+
* reader's saved theme (`data-nz-theme` from `localStorage` key `nz-theme`: `light`, `dark` or
|
|
33
|
+
* `system`) and `data-nz-platform` (`apple` or `other`). The rules are on `themeScript`. Render it in
|
|
34
|
+
* `<head>` (`<head><ThemeScript nonce={nonce} /></head>` in a root layout), put the app's default
|
|
35
|
+
* theme on `<html>` (`data-nz-theme="system"`, or none for light), and put `suppressHydrationWarning`
|
|
36
|
+
* on `<html>`, whose attributes the script changes.
|
|
37
|
+
*/
|
|
38
|
+
function ThemeScript({ nonce }) {
|
|
39
|
+
return /* @__PURE__ */ jsx("script", {
|
|
40
|
+
suppressHydrationWarning: true,
|
|
41
|
+
...nonce === void 0 ? {} : { nonce },
|
|
42
|
+
dangerouslySetInnerHTML: { __html: themeScript }
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
//#endregion
|
|
46
|
+
export { ThemeScript, themeScript };
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { OpenReason } from "../contracts/details.js";
|
|
2
|
+
import { TooltipLabels, TooltipPopupProps, TooltipPopupState, TooltipRootProps, TooltipSide, TooltipTriggerProps, TooltipTriggerState } from "./tooltip.contract.js";
|
|
3
|
+
import { TooltipPopup, TooltipRoot, TooltipTrigger } from "./tooltip.client.js";
|
|
4
|
+
import { tooltip_parts_d_exports } from "./tooltip.parts.js";
|
|
5
|
+
export { type OpenReason, tooltip_parts_d_exports as Tooltip, type TooltipLabels, TooltipPopup, type TooltipPopupProps, type TooltipPopupState, TooltipRoot, type TooltipRootProps, type TooltipSide, TooltipTrigger, type TooltipTriggerProps, type TooltipTriggerState };
|