@nizivo/react 0.1.0 → 0.2.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/THIRD_PARTY_NOTICES +12 -5
- package/dist/_engines/react-aria/dialog.client.js +16 -24
- package/dist/_engines/react-aria/drawer.client.js +8 -0
- package/dist/_engines/react-aria/file-upload.client.js +50 -0
- package/dist/_engines/react-aria/menu.client.js +17 -13
- package/dist/_engines/react-aria/open-state.client.js +53 -0
- package/dist/_engines/react-aria/outside-press.client.js +61 -0
- package/dist/_engines/react-aria/overlay.client.js +6 -1
- package/dist/_engines/react-aria/popover.client.js +148 -0
- package/dist/_engines/react-aria/popup.client.js +31 -5
- package/dist/_engines/react-aria/select.client.js +22 -12
- package/dist/_engines/react-aria/toast.client.js +38 -0
- package/dist/_engines/react-aria/tooltip.client.js +11 -11
- package/dist/_internal/data-status.d.ts +3 -0
- package/dist/_internal/data-status.js +13 -0
- package/dist/_internal/glyphs.js +54 -1
- package/dist/_internal/modal.client.js +54 -0
- package/dist/_internal/nested-focus.js +33 -0
- package/dist/alert/alert-dismiss.client.d.ts +1 -1
- package/dist/alert/alert-dismiss.client.js +3 -1
- package/dist/app-shell/app-shell.d.ts +24 -0
- package/dist/app-shell/app-shell.js +56 -0
- package/dist/app-shell/index.d.ts +2 -0
- package/dist/app-shell/index.js +1 -0
- package/dist/avatar/avatar.d.ts +96 -0
- package/dist/avatar/avatar.js +94 -0
- package/dist/avatar/index.d.ts +2 -0
- package/dist/avatar/index.js +1 -0
- package/dist/banner/banner-dismiss.client.d.ts +32 -0
- package/dist/banner/banner-dismiss.client.js +38 -0
- package/dist/banner/banner.d.ts +34 -0
- package/dist/banner/banner.js +47 -0
- package/dist/banner/index.d.ts +3 -0
- package/dist/banner/index.js +3 -0
- package/dist/breadcrumb/breadcrumb.d.ts +46 -0
- package/dist/breadcrumb/breadcrumb.js +46 -0
- package/dist/breadcrumb/breadcrumb.parts.d.ts +6 -0
- package/dist/breadcrumb/breadcrumb.parts.js +9 -0
- package/dist/breadcrumb/index.d.ts +3 -0
- package/dist/breadcrumb/index.js +3 -0
- package/dist/button/button.d.ts +3 -2
- package/dist/card/card.d.ts +9 -2
- package/dist/chip-group/chip-group.client.d.ts +88 -0
- package/dist/chip-group/chip-group.client.js +157 -0
- package/dist/chip-group/index.d.ts +2 -0
- package/dist/chip-group/index.js +1 -0
- package/dist/choice-card/choice-card.client.d.ts +66 -0
- package/dist/choice-card/choice-card.client.js +138 -0
- package/dist/choice-card/index.d.ts +2 -0
- package/dist/choice-card/index.js +1 -0
- package/dist/config/config.client.d.ts +16 -1
- package/dist/config/config.client.js +18 -3
- package/dist/config/index.d.ts +2 -2
- package/dist/contracts/index.d.ts +1 -1
- package/dist/css/app-shell.css +2 -0
- package/dist/css/avatar.css +2 -0
- package/dist/css/banner.css +2 -0
- package/dist/css/base.css +1 -1
- package/dist/css/breadcrumb.css +2 -0
- package/dist/css/card.css +1 -1
- package/dist/css/chip-group.css +2 -0
- package/dist/css/choice-card.css +2 -0
- package/dist/css/delta.css +1 -1
- package/dist/css/drawer.css +2 -0
- package/dist/css/file-upload.css +2 -0
- package/dist/css/form.css +2 -0
- package/dist/css/heading.css +1 -1
- package/dist/css/kpi-tile.css +2 -0
- package/dist/css/metric.css +2 -0
- package/dist/css/mobile-tab-bar.css +2 -0
- package/dist/css/mobile-top-bar.css +2 -0
- package/dist/css/motion.css +2 -0
- package/dist/css/nav-item.css +2 -0
- package/dist/css/number-value.css +2 -0
- package/dist/css/page-header.css +2 -0
- package/dist/css/pagination.css +2 -0
- package/dist/css/password-input.css +2 -0
- package/dist/css/popover.css +2 -0
- package/dist/css/ranked-list.css +2 -0
- package/dist/css/search-field.css +2 -0
- package/dist/css/sidebar.css +2 -0
- package/dist/css/split.css +2 -0
- package/dist/css/sticky-bar.css +2 -0
- package/dist/css/table-selection.css +2 -0
- package/dist/css/table.css +2 -0
- package/dist/css/text.css +1 -1
- package/dist/css/toast.css +2 -0
- package/dist/css/top-bar.css +2 -0
- package/dist/css/trend-card.css +2 -0
- package/dist/dialog/dialog.client.d.ts +1 -1
- package/dist/dialog/dialog.client.js +15 -37
- package/dist/drawer/drawer.client.d.ts +25 -0
- package/dist/drawer/drawer.client.js +154 -0
- package/dist/drawer/drawer.contract.d.ts +98 -0
- package/dist/drawer/drawer.parts.d.ts +6 -0
- package/dist/drawer/drawer.parts.js +16 -0
- package/dist/drawer/index.d.ts +5 -0
- package/dist/drawer/index.js +3 -0
- package/dist/field/field-scope.client.js +9 -2
- package/dist/file-upload/file-upload.client.d.ts +9 -0
- package/dist/file-upload/file-upload.client.js +406 -0
- package/dist/file-upload/file-upload.contract.d.ts +112 -0
- package/dist/file-upload/index.d.ts +3 -0
- package/dist/file-upload/index.js +1 -0
- package/dist/file-upload/seam.d.ts +1 -0
- package/dist/form/form.client.d.ts +38 -0
- package/dist/form/form.client.js +127 -0
- package/dist/form/form.d.ts +36 -0
- package/dist/form/form.js +29 -0
- package/dist/form/index.d.ts +4 -0
- package/dist/form/index.js +4 -0
- package/dist/form/submit-button.client.d.ts +20 -0
- package/dist/form/submit-button.client.js +19 -0
- package/dist/heading/heading.d.ts +4 -1
- package/dist/i18n/format-label.d.ts +24 -0
- package/dist/i18n/format-label.js +19 -0
- package/dist/i18n/index.d.ts +2 -0
- package/dist/i18n/index.js +1 -0
- package/dist/icon-button/icon-button.client.js +1 -1
- package/dist/icon-button/icon-button.js +1 -1
- package/dist/index.d.ts +84 -5
- package/dist/index.js +49 -4
- package/dist/kpi-tile/index.d.ts +2 -0
- package/dist/kpi-tile/index.js +1 -0
- package/dist/kpi-tile/kpi-tile.d.ts +30 -0
- package/dist/kpi-tile/kpi-tile.js +48 -0
- package/dist/locales/en-US.d.ts +77 -0
- package/dist/locales/en-US.js +83 -0
- package/dist/menu/menu.contract.d.ts +1 -1
- package/dist/metric/index.d.ts +2 -0
- package/dist/metric/index.js +1 -0
- package/dist/metric/metric.d.ts +72 -0
- package/dist/metric/metric.js +116 -0
- package/dist/mobile-tab-bar/index.d.ts +4 -0
- package/dist/mobile-tab-bar/index.js +4 -0
- package/dist/mobile-tab-bar/mobile-tab-bar-inset.client.js +38 -0
- package/dist/mobile-tab-bar/mobile-tab-bar-more.client.d.ts +26 -0
- package/dist/mobile-tab-bar/mobile-tab-bar-more.client.js +60 -0
- package/dist/mobile-tab-bar/mobile-tab-bar.d.ts +39 -0
- package/dist/mobile-tab-bar/mobile-tab-bar.js +54 -0
- package/dist/mobile-tab-bar/mobile-tab-bar.parts.d.ts +6 -0
- package/dist/mobile-tab-bar/mobile-tab-bar.parts.js +9 -0
- package/dist/mobile-top-bar/index.d.ts +2 -0
- package/dist/mobile-top-bar/index.js +1 -0
- package/dist/mobile-top-bar/mobile-top-bar.d.ts +17 -0
- package/dist/mobile-top-bar/mobile-top-bar.js +31 -0
- package/dist/motion/count-up.client.d.ts +39 -0
- package/dist/motion/count-up.client.js +109 -0
- package/dist/motion/index.d.ts +2 -0
- package/dist/motion/index.js +1 -0
- package/dist/nav-item/index.d.ts +2 -0
- package/dist/nav-item/index.js +1 -0
- package/dist/nav-item/nav-item.d.ts +35 -0
- package/dist/nav-item/nav-item.js +50 -0
- package/dist/number-value/index.d.ts +2 -0
- package/dist/number-value/index.js +1 -0
- package/dist/number-value/number-value.d.ts +25 -0
- package/dist/number-value/number-value.js +26 -0
- package/dist/page-header/index.d.ts +2 -0
- package/dist/page-header/index.js +1 -0
- package/dist/page-header/page-header.d.ts +19 -0
- package/dist/page-header/page-header.js +39 -0
- package/dist/pagination/index.d.ts +2 -0
- package/dist/pagination/index.js +1 -0
- package/dist/pagination/pagination.d.ts +74 -0
- package/dist/pagination/pagination.js +136 -0
- package/dist/password-input/index.d.ts +2 -0
- package/dist/password-input/index.js +1 -0
- package/dist/password-input/password-input.client.d.ts +52 -0
- package/dist/password-input/password-input.client.js +106 -0
- package/dist/popover/index.d.ts +5 -0
- package/dist/popover/index.js +3 -0
- package/dist/popover/popover.client.d.ts +20 -0
- package/dist/popover/popover.client.js +113 -0
- package/dist/popover/popover.contract.d.ts +88 -0
- package/dist/popover/popover.parts.d.ts +6 -0
- package/dist/popover/popover.parts.js +13 -0
- package/dist/ranked-list/index.d.ts +3 -0
- package/dist/ranked-list/index.js +3 -0
- package/dist/ranked-list/ranked-list.d.ts +85 -0
- package/dist/ranked-list/ranked-list.js +153 -0
- package/dist/ranked-list/ranked-list.parts.d.ts +6 -0
- package/dist/ranked-list/ranked-list.parts.js +10 -0
- package/dist/search-field/index.d.ts +2 -0
- package/dist/search-field/index.js +1 -0
- package/dist/search-field/search-field.client.d.ts +55 -0
- package/dist/search-field/search-field.client.js +136 -0
- package/dist/select/select.contract.d.ts +1 -1
- package/dist/sidebar/index.d.ts +4 -0
- package/dist/sidebar/index.js +4 -0
- package/dist/sidebar/sidebar-item.client.d.ts +10 -0
- package/dist/sidebar/sidebar-item.client.js +55 -0
- package/dist/sidebar/sidebar.d.ts +45 -0
- package/dist/sidebar/sidebar.js +62 -0
- package/dist/sidebar/sidebar.parts.d.ts +6 -0
- package/dist/sidebar/sidebar.parts.js +11 -0
- package/dist/split/index.d.ts +3 -0
- package/dist/split/index.js +3 -0
- package/dist/split/split.d.ts +28 -0
- package/dist/split/split.js +33 -0
- package/dist/split/split.parts.d.ts +6 -0
- package/dist/split/split.parts.js +10 -0
- package/dist/sticky-bar/index.d.ts +2 -0
- package/dist/sticky-bar/index.js +1 -0
- package/dist/sticky-bar/sticky-bar.d.ts +16 -0
- package/dist/sticky-bar/sticky-bar.js +26 -0
- package/dist/styles.css +66 -7
- package/dist/table/index.d.ts +3 -0
- package/dist/table/index.js +3 -0
- package/dist/table/table.d.ts +101 -0
- package/dist/table/table.js +121 -0
- package/dist/table/table.parts.d.ts +6 -0
- package/dist/table/table.parts.js +18 -0
- package/dist/table-selection/index.d.ts +3 -0
- package/dist/table-selection/index.js +3 -0
- package/dist/table-selection/table-selection.client.d.ts +14 -0
- package/dist/table-selection/table-selection.client.js +84 -0
- package/dist/table-selection/table-selection.d.ts +34 -0
- package/dist/table-selection/table-selection.js +50 -0
- package/dist/text/text.d.ts +13 -2
- package/dist/toast/index.d.ts +4 -0
- package/dist/toast/index.js +3 -0
- package/dist/toast/seam.d.ts +2 -0
- package/dist/toast/store.d.ts +19 -0
- package/dist/toast/store.js +136 -0
- package/dist/toast/toast.contract.d.ts +56 -0
- package/dist/toast/toaster.client.d.ts +10 -0
- package/dist/toast/toaster.client.js +305 -0
- package/dist/tooltip/tooltip.contract.d.ts +1 -1
- package/dist/top-bar/index.d.ts +2 -0
- package/dist/top-bar/index.js +1 -0
- package/dist/top-bar/top-bar.d.ts +17 -0
- package/dist/top-bar/top-bar.js +35 -0
- package/dist/trend-card/index.d.ts +2 -0
- package/dist/trend-card/index.js +1 -0
- package/dist/trend-card/trend-card.d.ts +34 -0
- package/dist/trend-card/trend-card.js +74 -0
- package/package.json +167 -4
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
import { cx } from "../_internal/cx.js";
|
|
2
|
+
import { renderElement } from "../contracts/render.js";
|
|
3
|
+
import { ChevronGlyph } from "../_internal/glyphs.js";
|
|
4
|
+
import { details } from "../contracts/details.js";
|
|
5
|
+
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
6
|
+
//#region src/pagination/pagination.tsx
|
|
7
|
+
const range = (from, to) => Array.from({ length: Math.max(0, to - from + 1) }, (_, index) => from + index);
|
|
8
|
+
/** The slots between previous and next, by the rule in this file's header. */
|
|
9
|
+
function paginationSlots(page, totalPages, siblingCount = 1, boundaryCount = 1) {
|
|
10
|
+
const count = Math.max(1, Math.floor(totalPages));
|
|
11
|
+
const current = Math.min(count, Math.max(1, Math.floor(page)));
|
|
12
|
+
const siblings = Math.max(0, Math.floor(siblingCount));
|
|
13
|
+
const boundary = Math.max(0, Math.floor(boundaryCount));
|
|
14
|
+
const start = range(1, Math.min(boundary, count));
|
|
15
|
+
const end = range(Math.max(count - boundary + 1, boundary + 1), count);
|
|
16
|
+
const siblingsStart = Math.max(Math.min(current - siblings, count - boundary - siblings * 2 - 1), boundary + 2);
|
|
17
|
+
const siblingsEnd = Math.min(Math.max(current + siblings, boundary + siblings * 2 + 2), count - boundary - 1);
|
|
18
|
+
const slots = [...start];
|
|
19
|
+
if (siblingsStart > boundary + 2) slots.push("ellipsis");
|
|
20
|
+
else if (boundary + 1 < count - boundary) slots.push(boundary + 1);
|
|
21
|
+
slots.push(...range(siblingsStart, siblingsEnd));
|
|
22
|
+
if (siblingsEnd < count - boundary - 1) slots.push("ellipsis");
|
|
23
|
+
else if (count - boundary > boundary) slots.push(count - boundary);
|
|
24
|
+
slots.push(...end);
|
|
25
|
+
return slots.filter((slot, index) => slot === "ellipsis" || slots.indexOf(slot) === index);
|
|
26
|
+
}
|
|
27
|
+
function Pagination({ page, totalPages, getHref, onPageChange, siblingCount = 1, boundaryCount = 1, size = "md", summary, previousIcon, nextIcon, locale = "en-US", labels, renderLink, render, className, ...rest }) {
|
|
28
|
+
const count = Math.max(1, Math.floor(totalPages));
|
|
29
|
+
const current = Math.min(count, Math.max(1, Math.floor(page)));
|
|
30
|
+
const number = new Intl.NumberFormat(locale);
|
|
31
|
+
const pageLabel = labels?.page ?? "Page {page}";
|
|
32
|
+
const link = (target, kind, { rel, ...props }) => {
|
|
33
|
+
if (onPageChange !== void 0) return renderElement("button", void 0, void 0, {
|
|
34
|
+
type: "button",
|
|
35
|
+
...props,
|
|
36
|
+
onClick: (event) => {
|
|
37
|
+
if (target !== current) onPageChange(target, details(kind, event.nativeEvent));
|
|
38
|
+
}
|
|
39
|
+
});
|
|
40
|
+
if (getHref === void 0) throw new Error("Pagination needs getHref (links) or onPageChange");
|
|
41
|
+
return renderElement("a", renderLink, {
|
|
42
|
+
page: target,
|
|
43
|
+
kind,
|
|
44
|
+
current: kind === "page" && target === current
|
|
45
|
+
}, {
|
|
46
|
+
href: getHref(target),
|
|
47
|
+
...props,
|
|
48
|
+
rel
|
|
49
|
+
});
|
|
50
|
+
};
|
|
51
|
+
const step = (kind, icon) => {
|
|
52
|
+
const target = kind === "previous" ? current - 1 : current + 1;
|
|
53
|
+
const slot = kind === "previous" ? {
|
|
54
|
+
"data-slot": "pagination-previous",
|
|
55
|
+
className: "nz-pagination-step nz-pagination-previous"
|
|
56
|
+
} : {
|
|
57
|
+
"data-slot": "pagination-next",
|
|
58
|
+
className: "nz-pagination-step nz-pagination-next"
|
|
59
|
+
};
|
|
60
|
+
const { className: stepClass, ...slotAttribute } = slot;
|
|
61
|
+
const props = {
|
|
62
|
+
...slot,
|
|
63
|
+
"aria-label": kind === "previous" ? labels?.previous ?? "Previous page" : labels?.next ?? "Next page",
|
|
64
|
+
children: /* @__PURE__ */ jsx("span", {
|
|
65
|
+
className: "nz-pagination-icon",
|
|
66
|
+
"data-slot": "pagination-icon",
|
|
67
|
+
"data-mirror": icon === void 0 ? "rtl" : void 0,
|
|
68
|
+
"aria-hidden": "true",
|
|
69
|
+
children: icon ?? /* @__PURE__ */ jsx(ChevronGlyph, {})
|
|
70
|
+
})
|
|
71
|
+
};
|
|
72
|
+
if ((target < 1 || target > count) && onPageChange !== void 0) return /* @__PURE__ */ jsx("button", {
|
|
73
|
+
type: "button",
|
|
74
|
+
className: stepClass,
|
|
75
|
+
...slotAttribute,
|
|
76
|
+
"aria-label": props["aria-label"],
|
|
77
|
+
disabled: true,
|
|
78
|
+
"data-disabled": "",
|
|
79
|
+
children: props.children
|
|
80
|
+
});
|
|
81
|
+
if (target < 1 || target > count) return /* @__PURE__ */ jsx("span", {
|
|
82
|
+
className: stepClass,
|
|
83
|
+
...slotAttribute,
|
|
84
|
+
role: "link",
|
|
85
|
+
"aria-label": props["aria-label"],
|
|
86
|
+
"aria-disabled": "true",
|
|
87
|
+
"data-disabled": "",
|
|
88
|
+
children: props.children
|
|
89
|
+
});
|
|
90
|
+
return link(target, kind, {
|
|
91
|
+
...props,
|
|
92
|
+
rel: kind === "previous" ? "prev" : "next"
|
|
93
|
+
});
|
|
94
|
+
};
|
|
95
|
+
const slots = paginationSlots(current, count, siblingCount, boundaryCount);
|
|
96
|
+
const firstGap = slots.indexOf("ellipsis");
|
|
97
|
+
return renderElement("nav", render, {
|
|
98
|
+
page: current,
|
|
99
|
+
totalPages: count,
|
|
100
|
+
size
|
|
101
|
+
}, {
|
|
102
|
+
"data-slot": "pagination",
|
|
103
|
+
"data-size": size,
|
|
104
|
+
"aria-label": labels?.nav ?? "Pagination",
|
|
105
|
+
...rest,
|
|
106
|
+
className: cx("nz-pagination", className),
|
|
107
|
+
children: /* @__PURE__ */ jsxs(Fragment, { children: [summary != null && /* @__PURE__ */ jsx("p", {
|
|
108
|
+
className: "nz-pagination-summary",
|
|
109
|
+
"data-slot": "pagination-summary",
|
|
110
|
+
children: summary
|
|
111
|
+
}), /* @__PURE__ */ jsxs("ul", {
|
|
112
|
+
className: "nz-pagination-list",
|
|
113
|
+
"data-slot": "pagination-list",
|
|
114
|
+
children: [
|
|
115
|
+
/* @__PURE__ */ jsx("li", { children: step("previous", previousIcon) }),
|
|
116
|
+
slots.map((slot, index) => slot === "ellipsis" ? /* @__PURE__ */ jsx("li", {
|
|
117
|
+
"aria-hidden": "true",
|
|
118
|
+
children: /* @__PURE__ */ jsx("span", {
|
|
119
|
+
className: "nz-pagination-ellipsis",
|
|
120
|
+
"data-slot": "pagination-ellipsis",
|
|
121
|
+
children: "…"
|
|
122
|
+
})
|
|
123
|
+
}, index === firstGap ? "gap-start" : "gap-end") : /* @__PURE__ */ jsx("li", { children: link(slot, "page", {
|
|
124
|
+
"data-slot": "pagination-page",
|
|
125
|
+
className: "nz-pagination-page",
|
|
126
|
+
"aria-label": pageLabel.replaceAll("{page}", number.format(slot)),
|
|
127
|
+
"aria-current": slot === current ? "page" : void 0,
|
|
128
|
+
children: number.format(slot)
|
|
129
|
+
}) }, slot)),
|
|
130
|
+
/* @__PURE__ */ jsx("li", { children: step("next", nextIcon) })
|
|
131
|
+
]
|
|
132
|
+
})] })
|
|
133
|
+
});
|
|
134
|
+
}
|
|
135
|
+
//#endregion
|
|
136
|
+
export { Pagination, paginationSlots };
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import { PasswordInput, PasswordInputLabels, PasswordInputProps, PasswordInputState, PasswordInputVisibleReason } from "./password-input.client.js";
|
|
2
|
+
export { PasswordInput, type PasswordInputLabels, type PasswordInputProps, type PasswordInputState, type PasswordInputVisibleReason };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { PasswordInput } from "./password-input.client.js";
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { RenderProp } from "../contracts/render.js";
|
|
2
|
+
import { ControlSize } from "../augment.js";
|
|
3
|
+
import { ChangeDetails } from "../contracts/details.js";
|
|
4
|
+
import { ComponentPropsWithRef, JSX, ReactNode } from "react";
|
|
5
|
+
//#region src/password-input/password-input.client.d.ts
|
|
6
|
+
/** PasswordInput's own strings (§16.4): serialisable, English defaults. */
|
|
7
|
+
export interface PasswordInputLabels {
|
|
8
|
+
/**
|
|
9
|
+
* The toggle's name, the same in both states: `aria-pressed` says whether the password shows.
|
|
10
|
+
* @default 'Show password'
|
|
11
|
+
*/
|
|
12
|
+
toggle: string;
|
|
13
|
+
}
|
|
14
|
+
/** `'toggle'`: the toggle was pressed. `'submit'`: the form submitted, which hides the password. */
|
|
15
|
+
export type PasswordInputVisibleReason = "toggle" | "submit";
|
|
16
|
+
export interface PasswordInputState {
|
|
17
|
+
size: ControlSize;
|
|
18
|
+
/** The password shows as text. */
|
|
19
|
+
visible: boolean;
|
|
20
|
+
/** An error message is presented (the Field's, or the `invalid` prop). */
|
|
21
|
+
invalid: boolean;
|
|
22
|
+
disabled: boolean;
|
|
23
|
+
readOnly: boolean;
|
|
24
|
+
}
|
|
25
|
+
export interface PasswordInputProps extends Omit<ComponentPropsWithRef<"input">, "type" | "size" | "prefix" | "children"> {
|
|
26
|
+
/** 32 / 40 / 48 px, as Input. @default 'md' */
|
|
27
|
+
size?: ControlSize;
|
|
28
|
+
/** An error message is presented for this input. Inside a Field, the Field sets it. */
|
|
29
|
+
invalid?: boolean;
|
|
30
|
+
/** The password shows as text when the input first renders. @default false */
|
|
31
|
+
defaultVisible?: boolean;
|
|
32
|
+
/** Called when the password is shown or hidden: by the toggle, or hidden by a submit. */
|
|
33
|
+
onVisibleChange?: (visible: boolean, details: ChangeDetails<PasswordInputVisibleReason>) => void;
|
|
34
|
+
/** The toggle's mark while the password is hidden. Defaults to the internal `eye` glyph. */
|
|
35
|
+
showIcon?: ReactNode;
|
|
36
|
+
/** The toggle's mark while the password shows. Defaults to the internal `eye-off` glyph. */
|
|
37
|
+
hideIcon?: ReactNode;
|
|
38
|
+
/** Overrides the toggle's name, for example `labels={{ toggle: 'Passwort anzeigen' }}`. */
|
|
39
|
+
labels?: Partial<PasswordInputLabels>;
|
|
40
|
+
/**
|
|
41
|
+
* `'current-password'` to sign in, `'new-password'` to choose one (a password manager then offers
|
|
42
|
+
* to generate one). @default 'current-password'
|
|
43
|
+
*/
|
|
44
|
+
autoComplete?: ComponentPropsWithRef<"input">["autoComplete"];
|
|
45
|
+
/**
|
|
46
|
+
* Composition of the root, the bordered box. `className` and `style` go on the root too; every
|
|
47
|
+
* other prop, `ref` included, goes on the `<input>`.
|
|
48
|
+
*/
|
|
49
|
+
render?: RenderProp<PasswordInputState>;
|
|
50
|
+
}
|
|
51
|
+
export declare function PasswordInput({ size, id, name, required, disabled, readOnly, invalid, "aria-invalid": ariaInvalid, "aria-describedby": describedBy, defaultVisible, onVisibleChange, showIcon, hideIcon, labels: labelsProp, autoComplete, render, className, style, ...rest }: PasswordInputProps): JSX.Element;
|
|
52
|
+
//#endregion
|
|
@@ -0,0 +1,106 @@
|
|
|
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 { useLabels } from "../config/config.client.js";
|
|
6
|
+
import { EyeGlyph, EyeOffGlyph } from "../_internal/glyphs.js";
|
|
7
|
+
import { details } from "../contracts/details.js";
|
|
8
|
+
import { stateAttrs } from "../contracts/state.js";
|
|
9
|
+
import { useFieldControl } from "../field/field-scope.client.js";
|
|
10
|
+
import { useEffect, useId, useRef, useState } from "react";
|
|
11
|
+
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
12
|
+
//#region src/password-input/password-input.client.tsx
|
|
13
|
+
function PasswordInput({ size = "md", id, name, required, disabled, readOnly, invalid, "aria-invalid": ariaInvalid, "aria-describedby": describedBy, defaultVisible = false, onVisibleChange, showIcon, hideIcon, labels: labelsProp, autoComplete = "current-password", render, className, style, ...rest }) {
|
|
14
|
+
const labels = useLabels("passwordInput", labelsProp);
|
|
15
|
+
const field = useFieldControl({
|
|
16
|
+
id,
|
|
17
|
+
name,
|
|
18
|
+
required,
|
|
19
|
+
disabled,
|
|
20
|
+
readOnly,
|
|
21
|
+
invalid: invalid ?? (ariaInvalid === true || ariaInvalid === "true" ? true : void 0),
|
|
22
|
+
"aria-describedby": describedBy
|
|
23
|
+
});
|
|
24
|
+
const own = useId();
|
|
25
|
+
const inputId = field.id ?? own;
|
|
26
|
+
const [visible, setVisible] = useState(defaultVisible);
|
|
27
|
+
const input = useRef(null);
|
|
28
|
+
const report = useRef(onVisibleChange);
|
|
29
|
+
useEffect(() => {
|
|
30
|
+
report.current = onVisibleChange;
|
|
31
|
+
});
|
|
32
|
+
useEffect(() => {
|
|
33
|
+
const element = input.current;
|
|
34
|
+
if (!visible || element === null) return void 0;
|
|
35
|
+
const doc = element.ownerDocument;
|
|
36
|
+
const onSubmit = (event) => {
|
|
37
|
+
if (element.form === null || event.target !== element.form) return;
|
|
38
|
+
element.type = "password";
|
|
39
|
+
setVisible(false);
|
|
40
|
+
report.current?.(false, details("submit", event));
|
|
41
|
+
};
|
|
42
|
+
doc.addEventListener("submit", onSubmit, true);
|
|
43
|
+
return () => doc.removeEventListener("submit", onSubmit, true);
|
|
44
|
+
}, [visible]);
|
|
45
|
+
const state = {
|
|
46
|
+
size,
|
|
47
|
+
visible,
|
|
48
|
+
invalid: field.invalid,
|
|
49
|
+
disabled: field.disabled,
|
|
50
|
+
readOnly: field.readOnly
|
|
51
|
+
};
|
|
52
|
+
const ownProps = {
|
|
53
|
+
...field.controlProps,
|
|
54
|
+
id: inputId,
|
|
55
|
+
ref: input,
|
|
56
|
+
autoComplete,
|
|
57
|
+
spellCheck: false,
|
|
58
|
+
autoCapitalize: "off"
|
|
59
|
+
};
|
|
60
|
+
return renderElement("span", render, state, {
|
|
61
|
+
"data-slot": "password-input",
|
|
62
|
+
"data-size": size,
|
|
63
|
+
...stateAttrs({
|
|
64
|
+
invalid: state.invalid,
|
|
65
|
+
disabled: state.disabled,
|
|
66
|
+
readOnly: state.readOnly
|
|
67
|
+
}),
|
|
68
|
+
className: cx("nz-password-input nz-input", className),
|
|
69
|
+
style,
|
|
70
|
+
onMouseDown: focusInput,
|
|
71
|
+
children: /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx("input", {
|
|
72
|
+
...mergeProps(ownProps, rest),
|
|
73
|
+
type: visible ? "text" : "password",
|
|
74
|
+
className: "nz-password-input-control nz-input-control",
|
|
75
|
+
"data-slot": "password-input-control"
|
|
76
|
+
}), /* @__PURE__ */ jsx("button", {
|
|
77
|
+
type: "button",
|
|
78
|
+
className: "nz-password-input-toggle",
|
|
79
|
+
"data-slot": "password-input-toggle",
|
|
80
|
+
"aria-label": labels?.toggle ?? "Show password",
|
|
81
|
+
"aria-pressed": visible,
|
|
82
|
+
"aria-controls": inputId,
|
|
83
|
+
disabled: field.disabled || void 0,
|
|
84
|
+
onClick: (event) => {
|
|
85
|
+
setVisible(!visible);
|
|
86
|
+
onVisibleChange?.(!visible, details("toggle", event.nativeEvent));
|
|
87
|
+
},
|
|
88
|
+
children: /* @__PURE__ */ jsx("span", {
|
|
89
|
+
className: "nz-password-input-icon",
|
|
90
|
+
"data-slot": "password-input-icon",
|
|
91
|
+
"aria-hidden": "true",
|
|
92
|
+
children: visible ? hideIcon ?? /* @__PURE__ */ jsx(EyeOffGlyph, {}) : showIcon ?? /* @__PURE__ */ jsx(EyeGlyph, {})
|
|
93
|
+
})
|
|
94
|
+
})] })
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
function focusInput(event) {
|
|
98
|
+
const input = event.currentTarget.querySelector(":scope > .nz-password-input-control");
|
|
99
|
+
const target = event.target;
|
|
100
|
+
if (input === null || target === input || input.disabled) return;
|
|
101
|
+
if (target instanceof Element && target.closest(".nz-password-input-toggle") !== null) return;
|
|
102
|
+
event.preventDefault();
|
|
103
|
+
input.focus();
|
|
104
|
+
}
|
|
105
|
+
//#endregion
|
|
106
|
+
export { PasswordInput };
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { OpenReason } from "../contracts/details.js";
|
|
2
|
+
import { PopoverCloseProps, PopoverCloseState, PopoverDescriptionProps, PopoverLabels, PopoverPopupProps, PopoverPopupState, PopoverRootProps, PopoverSide, PopoverTitleLevel, PopoverTitleProps, PopoverTriggerProps, PopoverTriggerState } from "./popover.contract.js";
|
|
3
|
+
import { PopoverClose, PopoverDescription, PopoverPopup, PopoverRoot, PopoverTitle, PopoverTrigger } from "./popover.client.js";
|
|
4
|
+
import { popover_parts_d_exports } from "./popover.parts.js";
|
|
5
|
+
export { type OpenReason, popover_parts_d_exports as Popover, PopoverClose, type PopoverCloseProps, type PopoverCloseState, PopoverDescription, type PopoverDescriptionProps, type PopoverLabels, PopoverPopup, type PopoverPopupProps, type PopoverPopupState, PopoverRoot, type PopoverRootProps, type PopoverSide, PopoverTitle, type PopoverTitleLevel, type PopoverTitleProps, PopoverTrigger, type PopoverTriggerProps, type PopoverTriggerState };
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import { PopoverClose, PopoverDescription, PopoverPopup, PopoverRoot, PopoverTitle, PopoverTrigger } from "./popover.client.js";
|
|
2
|
+
import { popover_parts_exports } from "./popover.parts.js";
|
|
3
|
+
export { popover_parts_exports as Popover, PopoverClose, PopoverDescription, PopoverPopup, PopoverRoot, PopoverTitle, PopoverTrigger };
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { PopoverCloseProps, PopoverDescriptionProps, PopoverPopupProps, PopoverRootProps, PopoverTitleProps, PopoverTriggerProps } from "./popover.contract.js";
|
|
2
|
+
import { JSX } from "react";
|
|
3
|
+
//#region src/popover/popover.client.d.ts
|
|
4
|
+
export declare function PopoverRoot(props: PopoverRootProps): JSX.Element;
|
|
5
|
+
/**
|
|
6
|
+
* Without `render`, its own `<button>`: `nz-hit-target` gives it the 44 px coarse-pointer hit area of
|
|
7
|
+
* every standalone pressable, and popover.css gives that bare button a 24 x 24 px minimum (WCAG 2.2
|
|
8
|
+
* 2.5.8, as Dialog's and Tooltip's, M27). A composed Button or IconButton keeps its own size.
|
|
9
|
+
*/
|
|
10
|
+
export declare function PopoverTrigger({ className, render, ...rest }: PopoverTriggerProps): JSX.Element;
|
|
11
|
+
export declare function PopoverPopup({ side, align, sideOffset, container, "aria-label": label, "aria-labelledby": labelledBy, "aria-describedby": describedBy, className, style, children }: PopoverPopupProps): JSX.Element;
|
|
12
|
+
export declare function PopoverTitle({ level, className, render, ...rest }: PopoverTitleProps): JSX.Element;
|
|
13
|
+
export declare function PopoverDescription({ className, render, ...rest }: PopoverDescriptionProps): JSX.Element;
|
|
14
|
+
/**
|
|
15
|
+
* With `render` or `children`, the consumer's button. With neither, an IconButton (tertiary, `sm`)
|
|
16
|
+
* showing the core close glyph, named by `labels.close`: the IconButton element's markup written out,
|
|
17
|
+
* as `Dialog.Close` does, so the Popover entry does not pull in IconButton's tooltip chain.
|
|
18
|
+
*/
|
|
19
|
+
export declare function PopoverClose({ className, render, children, labels: labelsProp, ...rest }: PopoverCloseProps): JSX.Element;
|
|
20
|
+
//#endregion
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { cx } from "../_internal/cx.js";
|
|
3
|
+
import { toRenderFn } from "../contracts/render.js";
|
|
4
|
+
import { useLabels } from "../config/config.client.js";
|
|
5
|
+
import { CloseGlyph } from "../_internal/glyphs.js";
|
|
6
|
+
import { Close, Description, Popup, Root, Title, Trigger } from "../_engines/react-aria/popover.client.js";
|
|
7
|
+
import { jsx } from "react/jsx-runtime";
|
|
8
|
+
//#region src/popover/popover.client.tsx
|
|
9
|
+
const renderDiv = toRenderFn(void 0, "div");
|
|
10
|
+
const renderP = toRenderFn(void 0, "p");
|
|
11
|
+
const TABBABLE = "a[href], button, input, select, textarea, summary, [tabindex], [contenteditable]:not([contenteditable=\"false\"])";
|
|
12
|
+
/**
|
|
13
|
+
* Focus on open (§12.2): an element marked `autoFocus` keeps it; otherwise the first tabbable element
|
|
14
|
+
* in the popup, passing over the default corner Close (focus starts on the content, not on the way
|
|
15
|
+
* out); otherwise the engine focuses the popup's content element itself.
|
|
16
|
+
*/
|
|
17
|
+
function initialFocus(content) {
|
|
18
|
+
for (const element of content.querySelectorAll(TABBABLE)) if (element.tabIndex >= 0 && !element.matches(":disabled, .nz-popover-close.nz-icon-button") && element.getClientRects().length > 0) return element;
|
|
19
|
+
return null;
|
|
20
|
+
}
|
|
21
|
+
function PopoverRoot(props) {
|
|
22
|
+
return /* @__PURE__ */ jsx(Root, { ...props });
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Without `render`, its own `<button>`: `nz-hit-target` gives it the 44 px coarse-pointer hit area of
|
|
26
|
+
* every standalone pressable, and popover.css gives that bare button a 24 x 24 px minimum (WCAG 2.2
|
|
27
|
+
* 2.5.8, as Dialog's and Tooltip's, M27). A composed Button or IconButton keeps its own size.
|
|
28
|
+
*/
|
|
29
|
+
function PopoverTrigger({ className, render, ...rest }) {
|
|
30
|
+
return /* @__PURE__ */ jsx(Trigger, {
|
|
31
|
+
...rest,
|
|
32
|
+
className: cx("nz-popover-trigger", render === void 0 && "nz-hit-target", className),
|
|
33
|
+
"data-slot": "popover-trigger",
|
|
34
|
+
render: toRenderFn(render, "button")
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
function PopoverPopup({ side = "bottom", align = "center", sideOffset = 8, container, "aria-label": label, "aria-labelledby": labelledBy, "aria-describedby": describedBy, className, style, children }) {
|
|
38
|
+
return /* @__PURE__ */ jsx(Popup, {
|
|
39
|
+
side,
|
|
40
|
+
align,
|
|
41
|
+
sideOffset,
|
|
42
|
+
container,
|
|
43
|
+
"aria-label": label,
|
|
44
|
+
"aria-labelledby": labelledBy,
|
|
45
|
+
"aria-describedby": describedBy,
|
|
46
|
+
contentProps: {
|
|
47
|
+
className: "nz-popover-content",
|
|
48
|
+
"data-slot": "popover-content"
|
|
49
|
+
},
|
|
50
|
+
initialFocus,
|
|
51
|
+
className: cx("nz-popover-popup", className),
|
|
52
|
+
style,
|
|
53
|
+
"data-slot": "popover-popup",
|
|
54
|
+
render: renderDiv,
|
|
55
|
+
children
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
const HEADINGS = {
|
|
59
|
+
2: toRenderFn(void 0, "h2"),
|
|
60
|
+
3: toRenderFn(void 0, "h3"),
|
|
61
|
+
4: toRenderFn(void 0, "h4"),
|
|
62
|
+
5: toRenderFn(void 0, "h5"),
|
|
63
|
+
6: toRenderFn(void 0, "h6")
|
|
64
|
+
};
|
|
65
|
+
function PopoverTitle({ level = 2, className, render, ...rest }) {
|
|
66
|
+
return /* @__PURE__ */ jsx(Title, {
|
|
67
|
+
...rest,
|
|
68
|
+
level,
|
|
69
|
+
className: cx("nz-popover-title", className),
|
|
70
|
+
"data-slot": "popover-title",
|
|
71
|
+
render: render === void 0 ? HEADINGS[level] : toRenderFn(render, `h${level}`)
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
function PopoverDescription({ className, render, ...rest }) {
|
|
75
|
+
return /* @__PURE__ */ jsx(Description, {
|
|
76
|
+
...rest,
|
|
77
|
+
className: cx("nz-popover-description", className),
|
|
78
|
+
"data-slot": "popover-description",
|
|
79
|
+
render: render === void 0 ? renderP : toRenderFn(render, "p")
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* With `render` or `children`, the consumer's button. With neither, an IconButton (tertiary, `sm`)
|
|
84
|
+
* showing the core close glyph, named by `labels.close`: the IconButton element's markup written out,
|
|
85
|
+
* as `Dialog.Close` does, so the Popover entry does not pull in IconButton's tooltip chain.
|
|
86
|
+
*/
|
|
87
|
+
function PopoverClose({ className, render, children, labels: labelsProp, ...rest }) {
|
|
88
|
+
const labels = useLabels("popover", labelsProp);
|
|
89
|
+
return /* @__PURE__ */ jsx(Close, {
|
|
90
|
+
...rest,
|
|
91
|
+
className: cx("nz-popover-close", className),
|
|
92
|
+
"data-slot": "popover-close",
|
|
93
|
+
render: toRenderFn(render ?? (children === void 0 ? closeIcon(rest["aria-label"] ?? labels?.close ?? "Close") : void 0), "button"),
|
|
94
|
+
children
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
function closeIcon(label) {
|
|
98
|
+
return /* @__PURE__ */ jsx("button", {
|
|
99
|
+
type: "button",
|
|
100
|
+
className: "nz-icon-button nz-hit-target",
|
|
101
|
+
"data-variant": "tertiary",
|
|
102
|
+
"data-size": "sm",
|
|
103
|
+
"aria-label": label,
|
|
104
|
+
children: /* @__PURE__ */ jsx("span", {
|
|
105
|
+
className: "nz-icon-button-icon",
|
|
106
|
+
"data-slot": "icon-button-icon",
|
|
107
|
+
"aria-hidden": "true",
|
|
108
|
+
children: /* @__PURE__ */ jsx(CloseGlyph, {})
|
|
109
|
+
})
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
//#endregion
|
|
113
|
+
export { PopoverClose, PopoverDescription, PopoverPopup, PopoverRoot, PopoverTitle, PopoverTrigger };
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import { RenderProp } from "../contracts/render.js";
|
|
2
|
+
import { ChangeDetails, OpenReason } from "../contracts/details.js";
|
|
3
|
+
import "../_internal/engine-part.js";
|
|
4
|
+
import { Align, Side } from "../contracts/state.js";
|
|
5
|
+
import { CSSProperties, ComponentPropsWithRef, ReactElement, ReactNode } from "react";
|
|
6
|
+
//#region src/popover/popover.contract.d.ts
|
|
7
|
+
/** Logical side; the resolved physical side is `data-side` on the popup. */
|
|
8
|
+
export type PopoverSide = "top" | "bottom" | "start" | "end";
|
|
9
|
+
export type PopoverTitleLevel = 2 | 3 | 4 | 5 | 6;
|
|
10
|
+
/**
|
|
11
|
+
* Strings the Popover renders (§9.3 rule 7, §16.4). `close` is the accessible name of the default
|
|
12
|
+
* `Popover.Close` (an IconButton showing the close glyph), set through that part's `labels`.
|
|
13
|
+
* Engine-owned with React Aria (not overridable): `dismiss`, the visually hidden "Dismiss" buttons
|
|
14
|
+
* at both ends of the popup.
|
|
15
|
+
*/
|
|
16
|
+
export interface PopoverLabels {
|
|
17
|
+
/** @default 'Close' */
|
|
18
|
+
close: string;
|
|
19
|
+
dismiss: string;
|
|
20
|
+
}
|
|
21
|
+
export interface PopoverRootProps {
|
|
22
|
+
open?: boolean;
|
|
23
|
+
defaultOpen?: boolean;
|
|
24
|
+
/** `details.reason` is `'unknown'` with React Aria, which reports no cause. */
|
|
25
|
+
onOpenChange?: (open: boolean, details: ChangeDetails<OpenReason>) => void;
|
|
26
|
+
children: ReactNode;
|
|
27
|
+
}
|
|
28
|
+
export interface PopoverTriggerState {
|
|
29
|
+
open: boolean;
|
|
30
|
+
pressed: boolean;
|
|
31
|
+
focusVisible: boolean;
|
|
32
|
+
disabled: boolean;
|
|
33
|
+
}
|
|
34
|
+
export interface PopoverPopupState {
|
|
35
|
+
entering: boolean;
|
|
36
|
+
exiting: boolean;
|
|
37
|
+
side: Side;
|
|
38
|
+
}
|
|
39
|
+
export interface PopoverCloseState {
|
|
40
|
+
pressed: boolean;
|
|
41
|
+
focusVisible: boolean;
|
|
42
|
+
disabled: boolean;
|
|
43
|
+
}
|
|
44
|
+
export interface PopoverTriggerProps extends Omit<ComponentPropsWithRef<"button">, "children"> {
|
|
45
|
+
/** Must render a `<button>`, for example `render={<IconButton label="Notifications" … />}`. */
|
|
46
|
+
render?: RenderProp<PopoverTriggerState>;
|
|
47
|
+
children?: ReactNode;
|
|
48
|
+
}
|
|
49
|
+
export interface PopoverPopupProps {
|
|
50
|
+
/** @default 'bottom' */
|
|
51
|
+
side?: PopoverSide;
|
|
52
|
+
/** @default 'center' */
|
|
53
|
+
align?: Align;
|
|
54
|
+
/** Distance from the trigger in px. @default 8 */
|
|
55
|
+
sideOffset?: number;
|
|
56
|
+
/** Portal container. Defaults to the parent overlay, else `document.body` (§12.1 L2). */
|
|
57
|
+
container?: Element | null;
|
|
58
|
+
/** Names the popup when it has no `Popover.Title`. */
|
|
59
|
+
"aria-label"?: string;
|
|
60
|
+
"aria-labelledby"?: string;
|
|
61
|
+
"aria-describedby"?: string;
|
|
62
|
+
className?: string;
|
|
63
|
+
style?: CSSProperties;
|
|
64
|
+
children: ReactNode;
|
|
65
|
+
}
|
|
66
|
+
export interface PopoverTitleProps extends Omit<ComponentPropsWithRef<"h2">, "id"> {
|
|
67
|
+
/** @default 2 */
|
|
68
|
+
level?: PopoverTitleLevel;
|
|
69
|
+
render?: RenderProp<Record<string, never>>;
|
|
70
|
+
}
|
|
71
|
+
export interface PopoverDescriptionProps extends Omit<ComponentPropsWithRef<"p">, "id"> {
|
|
72
|
+
render?: RenderProp<Record<string, never>>;
|
|
73
|
+
}
|
|
74
|
+
export interface PopoverCloseProps extends Omit<ComponentPropsWithRef<"button">, "children"> {
|
|
75
|
+
/**
|
|
76
|
+
* Must render a `<button>`, for example `render={<Button size="sm">Done</Button>}`. With neither
|
|
77
|
+
* `render` nor `children`, the part is a small IconButton showing the close glyph, named by
|
|
78
|
+
* `labels.close`, which sits in the popup's top corner when it is a direct child of
|
|
79
|
+
* `Popover.Popup`.
|
|
80
|
+
*/
|
|
81
|
+
render?: RenderProp<PopoverCloseState>;
|
|
82
|
+
/** Text content, rendered in a plain `<button>`; leave it out for the default IconButton. */
|
|
83
|
+
children?: ReactNode;
|
|
84
|
+
/** The default IconButton's accessible name; an `aria-label` you pass wins. */
|
|
85
|
+
labels?: Partial<Pick<PopoverLabels, "close">>;
|
|
86
|
+
}
|
|
87
|
+
//#endregion
|
|
88
|
+
export type { OpenReason };
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { PopoverClose, PopoverDescription, PopoverPopup, PopoverRoot, PopoverTitle, PopoverTrigger } from "./popover.client.js";
|
|
2
|
+
declare namespace popover_parts_d_exports {
|
|
3
|
+
export { PopoverClose as Close, PopoverDescription as Description, PopoverPopup as Popup, PopoverRoot as Root, PopoverTitle as Title, PopoverTrigger as Trigger };
|
|
4
|
+
}
|
|
5
|
+
//#endregion
|
|
6
|
+
export { PopoverClose as Close, PopoverDescription as Description, PopoverPopup as Popup, PopoverRoot as Root, PopoverTitle as Title, PopoverTrigger as Trigger, popover_parts_d_exports };
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { __exportAll } from "../_virtual/_rolldown/runtime.js";
|
|
2
|
+
import { PopoverClose, PopoverDescription, PopoverPopup, PopoverRoot, PopoverTitle, PopoverTrigger } from "./popover.client.js";
|
|
3
|
+
//#region src/popover/popover.parts.ts
|
|
4
|
+
var popover_parts_exports = /* @__PURE__ */ __exportAll({
|
|
5
|
+
Close: () => PopoverClose,
|
|
6
|
+
Description: () => PopoverDescription,
|
|
7
|
+
Popup: () => PopoverPopup,
|
|
8
|
+
Root: () => PopoverRoot,
|
|
9
|
+
Title: () => PopoverTitle,
|
|
10
|
+
Trigger: () => PopoverTrigger
|
|
11
|
+
});
|
|
12
|
+
//#endregion
|
|
13
|
+
export { PopoverClose as Close, PopoverDescription as Description, PopoverPopup as Popup, PopoverRoot as Root, PopoverTitle as Title, PopoverTrigger as Trigger, popover_parts_exports };
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import { RankedListAction, RankedListActionProps, RankedListItem, RankedListItemProps, RankedListItemState, RankedListLabels, RankedListRoot, RankedListRootProps, RankedListRootState, RankedListTitleLevel } from "./ranked-list.js";
|
|
2
|
+
import { ranked_list_parts_d_exports } from "./ranked-list.parts.js";
|
|
3
|
+
export { ranked_list_parts_d_exports as RankedList, RankedListAction, type RankedListActionProps, RankedListItem, type RankedListItemProps, type RankedListItemState, type RankedListLabels, RankedListRoot, type RankedListRootProps, type RankedListRootState, type RankedListTitleLevel };
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import { RenderProp } from "../contracts/render.js";
|
|
2
|
+
import { DataStatus } from "../_internal/data-status.js";
|
|
3
|
+
import { ComponentPropsWithRef, ReactElement, ReactNode } from "react";
|
|
4
|
+
//#region src/ranked-list/ranked-list.d.ts
|
|
5
|
+
/**
|
|
6
|
+
* RankedList's own strings (§16.4): serialisable, English defaults, Metric's wording. `{label}` is
|
|
7
|
+
* replaced by the `title` (left out when there is none).
|
|
8
|
+
*/
|
|
9
|
+
export interface RankedListLabels {
|
|
10
|
+
/** Static, visually hidden text while loading (§16.5: no live region). @default 'Loading {label}' */
|
|
11
|
+
loading: string;
|
|
12
|
+
/** Shown when there is nothing to rank and no `empty` slot. @default 'No data' */
|
|
13
|
+
empty: string;
|
|
14
|
+
/** The InlineError message on a load failure with no `error` slot. @default 'Could not load {label}' */
|
|
15
|
+
error: string;
|
|
16
|
+
}
|
|
17
|
+
export type RankedListTitleLevel = 2 | 3 | 4 | 5 | 6;
|
|
18
|
+
export interface RankedListRootState {
|
|
19
|
+
status: DataStatus;
|
|
20
|
+
pending: boolean;
|
|
21
|
+
}
|
|
22
|
+
export interface RankedListRootProps extends Omit<ComponentPropsWithRef<"div">, "title"> {
|
|
23
|
+
/** The heading ("Top channels"); it also names the list. */
|
|
24
|
+
title?: ReactNode;
|
|
25
|
+
/** The heading level; its look is Heading/H4 at every level. @default 3 */
|
|
26
|
+
titleLevel?: RankedListTitleLevel;
|
|
27
|
+
/** The header's end, for example `<RankedList.Action href="/channels">View all</RankedList.Action>`. */
|
|
28
|
+
action?: ReactNode;
|
|
29
|
+
/**
|
|
30
|
+
* The value a full bar stands for. @default the largest value among the direct
|
|
31
|
+
* `RankedList.Item` children (the leader); pass it when the items are wrapped in your own components
|
|
32
|
+
*/
|
|
33
|
+
max?: number;
|
|
34
|
+
/** Every item's number format, unless the item sets its own (`Intl.NumberFormatOptions`). */
|
|
35
|
+
format?: Intl.NumberFormatOptions;
|
|
36
|
+
/** BCP 47 tag for every item's value. @default 'en-US' */
|
|
37
|
+
locale?: string;
|
|
38
|
+
/**
|
|
39
|
+
* The data lifecycle (§16.5). A ready list with no items is `empty`. @default 'ready'
|
|
40
|
+
*/
|
|
41
|
+
status?: DataStatus;
|
|
42
|
+
/**
|
|
43
|
+
* A refresh is in flight while the rows show: `data-pending` and `aria-busy` (ready only, as in
|
|
44
|
+
* Metric). @default false
|
|
45
|
+
*/
|
|
46
|
+
pending?: boolean;
|
|
47
|
+
/** Replaces the empty message. */
|
|
48
|
+
empty?: ReactNode;
|
|
49
|
+
/** Replaces the error message, for example an `InlineError` with a retry `action`. */
|
|
50
|
+
error?: ReactNode;
|
|
51
|
+
/**
|
|
52
|
+
* How many rows loading, empty and error reserve, so the box does not change when the data
|
|
53
|
+
* arrives. Pass the number of rows you show (Figma: 5; "max ~6 rows, then View all"). @default 5
|
|
54
|
+
*/
|
|
55
|
+
rows?: number;
|
|
56
|
+
labels?: Partial<RankedListLabels>;
|
|
57
|
+
/** Composition of the root (Card's surface through the `nz-card` class). */
|
|
58
|
+
render?: RenderProp<RankedListRootState>;
|
|
59
|
+
/** `RankedList.Item` elements, the leader first. */
|
|
60
|
+
children?: ReactNode;
|
|
61
|
+
}
|
|
62
|
+
export interface RankedListItemState {
|
|
63
|
+
/** value ÷ max, from 0 to 1. */
|
|
64
|
+
ratio: number;
|
|
65
|
+
}
|
|
66
|
+
export interface RankedListItemProps extends Omit<ComponentPropsWithRef<"li">, "children"> {
|
|
67
|
+
label: ReactNode;
|
|
68
|
+
value: number;
|
|
69
|
+
/** Overrides the list's `max` for this row. */
|
|
70
|
+
max?: number | undefined;
|
|
71
|
+
/** Overrides the list's `format`. */
|
|
72
|
+
format?: Intl.NumberFormatOptions | undefined;
|
|
73
|
+
/** @default the list's `locale`, else 'en-US' */
|
|
74
|
+
locale?: string | undefined;
|
|
75
|
+
render?: RenderProp<RankedListItemState>;
|
|
76
|
+
}
|
|
77
|
+
export interface RankedListActionProps extends ComponentPropsWithRef<"a"> {
|
|
78
|
+
/** The router's link, for example `render={<Link href="/channels" />}`. It must render an `<a>`. */
|
|
79
|
+
render?: RenderProp<Record<string, never>>;
|
|
80
|
+
}
|
|
81
|
+
export declare function RankedListRoot({ title, titleLevel, action, max, format, locale, status, pending, empty, error, rows, labels, render, className, children, ...rest }: RankedListRootProps): ReactElement;
|
|
82
|
+
export declare function RankedListItem({ label, value, max, format, locale, render, className, ...rest }: RankedListItemProps): ReactElement;
|
|
83
|
+
/** "View all": a real link, at least 24 px tall (WCAG 2.5.8; figma/04 issue 7). */
|
|
84
|
+
export declare function RankedListAction({ render, className, ...rest }: RankedListActionProps): ReactElement;
|
|
85
|
+
//#endregion
|