@tensor_1/react 2.6.0 → 2.8.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/dist/components/EditorialHome.d.ts +183 -0
- package/dist/components/EditorialHome.js +183 -0
- package/dist/components/Field.js +10 -4
- package/dist/components/Popover.d.ts +18 -4
- package/dist/components/Popover.js +31 -2
- package/dist/components/Toast.js +5 -4
- package/dist/components/Tooltip.d.ts +9 -5
- package/dist/components/Tooltip.js +61 -3
- package/dist/components/Tree.d.ts +15 -1
- package/dist/components/Tree.js +247 -35
- package/dist/hooks/useAnchoredPosition.d.ts +22 -0
- package/dist/hooks/useAnchoredPosition.js +44 -0
- package/dist/hooks/useDialog.js +36 -5
- package/dist/index.cjs +852 -100
- package/dist/index.d.cts +343 -11
- package/dist/index.d.ts +4 -0
- package/dist/index.js +35 -0
- package/dist/overlay-position.d.ts +59 -0
- package/dist/overlay-position.js +62 -0
- package/dist/table-engine.js +72 -6
- package/dist/tree-model.d.ts +48 -0
- package/dist/tree-model.js +49 -0
- package/package.json +1 -1
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
import * as react from 'react';
|
|
2
|
+
import { HTMLAttributes, ReactNode, ButtonHTMLAttributes } from 'react';
|
|
3
|
+
|
|
4
|
+
interface PageIntroProps extends Omit<HTMLAttributes<HTMLElement>, 'title'> {
|
|
5
|
+
/** Small line above the title (e.g. today's date). */
|
|
6
|
+
kicker?: ReactNode;
|
|
7
|
+
title: ReactNode;
|
|
8
|
+
/** Supporting copy under the title. */
|
|
9
|
+
lede?: ReactNode;
|
|
10
|
+
/** Label shown above the search well. */
|
|
11
|
+
searchLabel?: ReactNode;
|
|
12
|
+
/** The search well itself (form + `.uix-searchbar` markup, or `SearchBar`-style composition). */
|
|
13
|
+
search?: ReactNode;
|
|
14
|
+
/** Shortcut buttons; rendered inside the `.uix-shortcut-grid` full-width row. */
|
|
15
|
+
shortcuts?: ReactNode;
|
|
16
|
+
/** Accessible label for the shortcuts group. */
|
|
17
|
+
shortcutsLabel?: string;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Editorial page intro — kicker / title / lede beside a search well, with an
|
|
21
|
+
* optional full-width shortcut grid underneath (`.uix-page-intro`).
|
|
22
|
+
*/
|
|
23
|
+
declare function PageIntro({ kicker, title, lede, searchLabel, search, shortcuts, shortcutsLabel, className, children, ...props }: PageIntroProps): react.JSX.Element;
|
|
24
|
+
interface SectionHeadProps extends Omit<HTMLAttributes<HTMLDivElement>, 'title'> {
|
|
25
|
+
title: ReactNode;
|
|
26
|
+
/** id for the `<h2>`, for `aria-labelledby` wiring on the enclosing section. */
|
|
27
|
+
titleId?: string;
|
|
28
|
+
/** Right-aligned slot — a `.uix-section-link` anchor, a button, a pill. */
|
|
29
|
+
action?: ReactNode;
|
|
30
|
+
}
|
|
31
|
+
/** Section head — title row with an optional trailing action (`.uix-section-head`). */
|
|
32
|
+
declare function SectionHead({ title, titleId, action, className, ...props }: SectionHeadProps): react.JSX.Element;
|
|
33
|
+
interface NoticeQueueProps extends Omit<HTMLAttributes<HTMLElement>, 'title'> {
|
|
34
|
+
/** Leading icon slot. */
|
|
35
|
+
icon?: ReactNode;
|
|
36
|
+
/** Bolded lead-in of the notice copy. */
|
|
37
|
+
title?: ReactNode;
|
|
38
|
+
/** Rest of the notice copy, after the title. */
|
|
39
|
+
summary?: ReactNode;
|
|
40
|
+
/** Meta line under the copy (e.g. "Needs action · Required by Friday"). */
|
|
41
|
+
meta?: ReactNode;
|
|
42
|
+
/** Queue position (e.g. "1 of 4 important updates"). */
|
|
43
|
+
position?: ReactNode;
|
|
44
|
+
/**
|
|
45
|
+
* Trailing controls — previous/next arrows (put `uix-notice__arrow--previous`
|
|
46
|
+
* on the previous button to flip its icon), read/view-all buttons.
|
|
47
|
+
*/
|
|
48
|
+
actions?: ReactNode;
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Notice queue — the rotating "important updates" banner (`.uix-notice`). The
|
|
52
|
+
* copy region is `aria-live="polite"` so queue rotation is announced.
|
|
53
|
+
*/
|
|
54
|
+
declare function NoticeQueue({ icon, title, summary, meta, position, actions, className, ...props }: NoticeQueueProps): react.JSX.Element;
|
|
55
|
+
interface FeaturedStageProps extends Omit<HTMLAttributes<HTMLElement>, 'title'> {
|
|
56
|
+
/** Decorative visual (story signal + diagram). Hidden from AT unless `visualLabel` is set. */
|
|
57
|
+
visual?: ReactNode;
|
|
58
|
+
/** Accessible description of the visual; when set the visual gets `role="img"`. */
|
|
59
|
+
visualLabel?: string;
|
|
60
|
+
/**
|
|
61
|
+
* Ordinal of the story on stage (e.g. "01"), rendered as the filled
|
|
62
|
+
* `.uix-featured__now` chip in the eyebrow. Pair it with the matching
|
|
63
|
+
* `FeaturedRundownItem`'s `number` — the selected item's number renders as
|
|
64
|
+
* the same chip, and that pairing is what links rundown to stage on every
|
|
65
|
+
* breakpoint (the divider caret only exists while the zones sit side by side).
|
|
66
|
+
*/
|
|
67
|
+
ordinal?: ReactNode;
|
|
68
|
+
eyebrow?: ReactNode;
|
|
69
|
+
title: ReactNode;
|
|
70
|
+
/** id for the `<h2>` title, for `aria-labelledby` wiring. */
|
|
71
|
+
titleId?: string;
|
|
72
|
+
description?: ReactNode;
|
|
73
|
+
meta?: ReactNode;
|
|
74
|
+
/** Call-to-action slot under the meta line. */
|
|
75
|
+
action?: ReactNode;
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Featured stage — the hero story zone of the featured briefing
|
|
79
|
+
* (`.uix-featured__stage`). The briefing is ONE `.uix-featured` card: put this
|
|
80
|
+
* and `FeaturedRundown` directly inside it and the internal hairline, the
|
|
81
|
+
* selected item's caret, and the ordinal chips connect the two zones. Content
|
|
82
|
+
* is `aria-live="polite"` so swapping the featured story (from the rundown)
|
|
83
|
+
* is announced.
|
|
84
|
+
*/
|
|
85
|
+
declare function FeaturedStage({ visual, visualLabel, ordinal, eyebrow, title, titleId, description, meta, action, className, ...props }: FeaturedStageProps): react.JSX.Element;
|
|
86
|
+
interface FeaturedRundownProps extends Omit<HTMLAttributes<HTMLElement>, 'title'> {
|
|
87
|
+
/** Uppercase line above the title (e.g. "Editorial briefing"). */
|
|
88
|
+
eyebrow?: ReactNode;
|
|
89
|
+
title: ReactNode;
|
|
90
|
+
/** id for the `<h2>` title, for `aria-labelledby` wiring. */
|
|
91
|
+
titleId?: string;
|
|
92
|
+
/** Trailing head slot (e.g. a count pill). */
|
|
93
|
+
meta?: ReactNode;
|
|
94
|
+
/** `FeaturedRundownItem`s. */
|
|
95
|
+
children?: ReactNode;
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Featured rundown — the story-list zone of the featured briefing
|
|
99
|
+
* (`.uix-rundown`), sitting inside the single `.uix-featured` card beside (or,
|
|
100
|
+
* stacked, below) the `FeaturedStage`.
|
|
101
|
+
*/
|
|
102
|
+
declare function FeaturedRundown({ eyebrow, title, titleId, meta, children, className, ...props }: FeaturedRundownProps): react.JSX.Element;
|
|
103
|
+
interface FeaturedRundownItemProps extends Omit<ButtonHTMLAttributes<HTMLButtonElement>, 'title'> {
|
|
104
|
+
/** Ordinal label (e.g. "01"). */
|
|
105
|
+
number?: ReactNode;
|
|
106
|
+
/** Topic/duration line above the item title (e.g. "Company · 5 min"). */
|
|
107
|
+
topic?: ReactNode;
|
|
108
|
+
/** The story title. */
|
|
109
|
+
title: ReactNode;
|
|
110
|
+
/** Whether this story is on the stage — sets `aria-pressed` + `data-selected`. */
|
|
111
|
+
selected?: boolean;
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* One rundown story — a toggle button (`.uix-rundown__item`) whose selection
|
|
115
|
+
* is conveyed with `aria-pressed` and styled through `[data-selected]`.
|
|
116
|
+
*/
|
|
117
|
+
declare function FeaturedRundownItem({ number, topic, title, selected, className, ...props }: FeaturedRundownItemProps): react.JSX.Element;
|
|
118
|
+
interface NewsLeadProps extends Omit<HTMLAttributes<HTMLElement>, 'title'> {
|
|
119
|
+
/** Meta line above the title (pill + date). */
|
|
120
|
+
meta?: ReactNode;
|
|
121
|
+
title: ReactNode;
|
|
122
|
+
summary?: ReactNode;
|
|
123
|
+
}
|
|
124
|
+
/** News lead — the top story of a news column (`.uix-news-lead`). */
|
|
125
|
+
declare function NewsLead({ meta, title, summary, className, ...props }: NewsLeadProps): react.JSX.Element;
|
|
126
|
+
interface ContentListProps extends HTMLAttributes<HTMLUListElement> {
|
|
127
|
+
/** `ContentListItem`s. */
|
|
128
|
+
children?: ReactNode;
|
|
129
|
+
}
|
|
130
|
+
/** Content list — hairline-divided rows of titled items (`.uix-content-list`). */
|
|
131
|
+
declare function ContentList({ children, className, ...props }: ContentListProps): react.JSX.Element;
|
|
132
|
+
interface ContentListItemProps extends Omit<HTMLAttributes<HTMLLIElement>, 'title'> {
|
|
133
|
+
title: ReactNode;
|
|
134
|
+
meta?: ReactNode;
|
|
135
|
+
/** Trailing slot — an arrow glyph, a pill. */
|
|
136
|
+
trailing?: ReactNode;
|
|
137
|
+
}
|
|
138
|
+
/** One content-list row — title + meta with an optional trailing slot. */
|
|
139
|
+
declare function ContentListItem({ title, meta, trailing, className, ...props }: ContentListItemProps): react.JSX.Element;
|
|
140
|
+
interface ResourceGridProps extends HTMLAttributes<HTMLDivElement> {
|
|
141
|
+
/** Resource buttons/links (typically `.uix-btn--outline`). */
|
|
142
|
+
children?: ReactNode;
|
|
143
|
+
}
|
|
144
|
+
/** Resource grid — a three-up grid of resource shortcuts (`.uix-resource-grid`). */
|
|
145
|
+
declare function ResourceGrid({ children, className, ...props }: ResourceGridProps): react.JSX.Element;
|
|
146
|
+
interface StatLineItem {
|
|
147
|
+
/** Stable identity for the item; falls back to the index when omitted. */
|
|
148
|
+
id?: string;
|
|
149
|
+
value: ReactNode;
|
|
150
|
+
label: ReactNode;
|
|
151
|
+
}
|
|
152
|
+
interface StatLineProps extends HTMLAttributes<HTMLDivElement> {
|
|
153
|
+
items?: StatLineItem[];
|
|
154
|
+
children?: ReactNode;
|
|
155
|
+
}
|
|
156
|
+
/**
|
|
157
|
+
* Stat line — a compact value/label summary strip over a hairline
|
|
158
|
+
* (`.uix-stat-line`). Use `items` for data-driven stats or hand-author
|
|
159
|
+
* `.uix-stat-line__item` children.
|
|
160
|
+
*/
|
|
161
|
+
declare function StatLine({ items, children, className, ...props }: StatLineProps): react.JSX.Element;
|
|
162
|
+
interface EventRowProps extends Omit<HTMLAttributes<HTMLDivElement>, 'title'> {
|
|
163
|
+
/** Calendar-block month (e.g. "Jul"). */
|
|
164
|
+
month: ReactNode;
|
|
165
|
+
/** Calendar-block day (e.g. "30"). */
|
|
166
|
+
day: ReactNode;
|
|
167
|
+
title: ReactNode;
|
|
168
|
+
meta?: ReactNode;
|
|
169
|
+
}
|
|
170
|
+
/** Event row — date block + title/meta (`.uix-event-row`). */
|
|
171
|
+
declare function EventRow({ month, day, title, meta, className, ...props }: EventRowProps): react.JSX.Element;
|
|
172
|
+
interface StatusRowProps extends HTMLAttributes<HTMLDivElement> {
|
|
173
|
+
/** Leading indicator slot (e.g. a `.uix-dot`). */
|
|
174
|
+
indicator?: ReactNode;
|
|
175
|
+
/** Service name — takes the flexible middle (`.uix-status-row__name`). */
|
|
176
|
+
name: ReactNode;
|
|
177
|
+
/** Trailing meta (e.g. "Healthy"), rendered as `.uix-list-meta`. */
|
|
178
|
+
meta?: ReactNode;
|
|
179
|
+
}
|
|
180
|
+
/** Status row — indicator + name + trailing meta (`.uix-status-row`). */
|
|
181
|
+
declare function StatusRow({ indicator, name, meta, className, ...props }: StatusRowProps): react.JSX.Element;
|
|
182
|
+
|
|
183
|
+
export { ContentList, ContentListItem, type ContentListItemProps, type ContentListProps, EventRow, type EventRowProps, FeaturedRundown, FeaturedRundownItem, type FeaturedRundownItemProps, type FeaturedRundownProps, FeaturedStage, type FeaturedStageProps, NewsLead, type NewsLeadProps, NoticeQueue, type NoticeQueueProps, PageIntro, type PageIntroProps, ResourceGrid, type ResourceGridProps, SectionHead, type SectionHeadProps, StatLine, type StatLineItem, type StatLineProps, StatusRow, type StatusRowProps };
|
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { cx } from "../cx.js";
|
|
3
|
+
function PageIntro({
|
|
4
|
+
kicker,
|
|
5
|
+
title,
|
|
6
|
+
lede,
|
|
7
|
+
searchLabel,
|
|
8
|
+
search,
|
|
9
|
+
shortcuts,
|
|
10
|
+
shortcutsLabel,
|
|
11
|
+
className,
|
|
12
|
+
children,
|
|
13
|
+
...props
|
|
14
|
+
}) {
|
|
15
|
+
return /* @__PURE__ */ jsxs("section", { className: cx("uix-page-intro", className), ...props, children: [
|
|
16
|
+
/* @__PURE__ */ jsxs("div", { children: [
|
|
17
|
+
kicker != null && /* @__PURE__ */ jsx("p", { className: "uix-page-kicker", children: kicker }),
|
|
18
|
+
/* @__PURE__ */ jsx("h1", { className: "uix-page-title", children: title }),
|
|
19
|
+
lede != null && /* @__PURE__ */ jsx("p", { className: "uix-page-lede", children: lede })
|
|
20
|
+
] }),
|
|
21
|
+
search != null && /* @__PURE__ */ jsxs("div", { children: [
|
|
22
|
+
searchLabel != null && /* @__PURE__ */ jsx("p", { className: "uix-intro-search__label", children: searchLabel }),
|
|
23
|
+
search
|
|
24
|
+
] }),
|
|
25
|
+
shortcuts != null && /* @__PURE__ */ jsx("div", { className: "uix-shortcut-grid", "aria-label": shortcutsLabel, children: shortcuts }),
|
|
26
|
+
children
|
|
27
|
+
] });
|
|
28
|
+
}
|
|
29
|
+
function SectionHead({ title, titleId, action, className, ...props }) {
|
|
30
|
+
return /* @__PURE__ */ jsxs("div", { className: cx("uix-section-head", className), ...props, children: [
|
|
31
|
+
/* @__PURE__ */ jsx("h2", { className: "uix-section-title", id: titleId, children: title }),
|
|
32
|
+
action
|
|
33
|
+
] });
|
|
34
|
+
}
|
|
35
|
+
function NoticeQueue({ icon, title, summary, meta, position, actions, className, ...props }) {
|
|
36
|
+
return /* @__PURE__ */ jsxs("section", { className: cx("uix-notice", className), ...props, children: [
|
|
37
|
+
icon,
|
|
38
|
+
/* @__PURE__ */ jsxs("div", { className: "uix-notice__content", "aria-live": "polite", children: [
|
|
39
|
+
/* @__PURE__ */ jsxs("p", { className: "uix-notice__copy", children: [
|
|
40
|
+
title != null && /* @__PURE__ */ jsx("strong", { children: title }),
|
|
41
|
+
title != null && summary != null && " ",
|
|
42
|
+
summary
|
|
43
|
+
] }),
|
|
44
|
+
meta != null && /* @__PURE__ */ jsx("p", { className: "uix-notice__meta", children: meta })
|
|
45
|
+
] }),
|
|
46
|
+
(position != null || actions != null) && /* @__PURE__ */ jsxs("div", { className: "uix-notice__actions", children: [
|
|
47
|
+
position != null && /* @__PURE__ */ jsx("span", { className: "uix-notice__position", children: position }),
|
|
48
|
+
actions
|
|
49
|
+
] })
|
|
50
|
+
] });
|
|
51
|
+
}
|
|
52
|
+
function FeaturedStage({
|
|
53
|
+
visual,
|
|
54
|
+
visualLabel,
|
|
55
|
+
ordinal,
|
|
56
|
+
eyebrow,
|
|
57
|
+
title,
|
|
58
|
+
titleId,
|
|
59
|
+
description,
|
|
60
|
+
meta,
|
|
61
|
+
action,
|
|
62
|
+
className,
|
|
63
|
+
...props
|
|
64
|
+
}) {
|
|
65
|
+
return /* @__PURE__ */ jsxs("article", { className: cx("uix-featured__stage", className), ...props, children: [
|
|
66
|
+
/* @__PURE__ */ jsx(
|
|
67
|
+
"div",
|
|
68
|
+
{
|
|
69
|
+
className: "uix-featured__visual",
|
|
70
|
+
role: visualLabel != null ? "img" : void 0,
|
|
71
|
+
"aria-label": visualLabel,
|
|
72
|
+
"aria-hidden": visualLabel == null || void 0,
|
|
73
|
+
children: visual
|
|
74
|
+
}
|
|
75
|
+
),
|
|
76
|
+
/* @__PURE__ */ jsxs("div", { className: "uix-featured__content", "aria-live": "polite", children: [
|
|
77
|
+
(eyebrow != null || ordinal != null) && /* @__PURE__ */ jsxs("p", { className: "uix-featured__eyebrow", children: [
|
|
78
|
+
ordinal != null && /* @__PURE__ */ jsx("span", { className: "uix-featured__now", children: ordinal }),
|
|
79
|
+
eyebrow
|
|
80
|
+
] }),
|
|
81
|
+
/* @__PURE__ */ jsx("h2", { className: "uix-featured__title", id: titleId, children: title }),
|
|
82
|
+
description != null && /* @__PURE__ */ jsx("p", { className: "uix-featured__description", children: description }),
|
|
83
|
+
meta != null && /* @__PURE__ */ jsx("p", { className: "uix-featured__meta", children: meta }),
|
|
84
|
+
action
|
|
85
|
+
] })
|
|
86
|
+
] });
|
|
87
|
+
}
|
|
88
|
+
function FeaturedRundown({ eyebrow, title, titleId, meta, children, className, ...props }) {
|
|
89
|
+
return /* @__PURE__ */ jsxs("aside", { className: cx("uix-rundown", className), ...props, children: [
|
|
90
|
+
/* @__PURE__ */ jsxs("div", { className: "uix-rundown__head", children: [
|
|
91
|
+
/* @__PURE__ */ jsxs("div", { children: [
|
|
92
|
+
eyebrow != null && /* @__PURE__ */ jsx("p", { className: "uix-rundown__eyebrow", children: eyebrow }),
|
|
93
|
+
/* @__PURE__ */ jsx("h2", { className: "uix-rundown__title", id: titleId, children: title })
|
|
94
|
+
] }),
|
|
95
|
+
meta
|
|
96
|
+
] }),
|
|
97
|
+
/* @__PURE__ */ jsx("div", { className: "uix-rundown__items", children })
|
|
98
|
+
] });
|
|
99
|
+
}
|
|
100
|
+
function FeaturedRundownItem({ number, topic, title, selected = false, className, ...props }) {
|
|
101
|
+
return /* @__PURE__ */ jsxs(
|
|
102
|
+
"button",
|
|
103
|
+
{
|
|
104
|
+
type: "button",
|
|
105
|
+
className: cx("uix-rundown__item", className),
|
|
106
|
+
"aria-pressed": selected,
|
|
107
|
+
"data-selected": selected ? "true" : "false",
|
|
108
|
+
...props,
|
|
109
|
+
children: [
|
|
110
|
+
number != null && /* @__PURE__ */ jsx("span", { className: "uix-rundown__number", children: number }),
|
|
111
|
+
/* @__PURE__ */ jsxs("span", { children: [
|
|
112
|
+
topic != null && /* @__PURE__ */ jsx("span", { className: "uix-rundown__topic", children: topic }),
|
|
113
|
+
/* @__PURE__ */ jsx("span", { className: "uix-rundown__item-title", children: title })
|
|
114
|
+
] })
|
|
115
|
+
]
|
|
116
|
+
}
|
|
117
|
+
);
|
|
118
|
+
}
|
|
119
|
+
function NewsLead({ meta, title, summary, className, ...props }) {
|
|
120
|
+
return /* @__PURE__ */ jsxs("article", { className: cx("uix-news-lead", className), ...props, children: [
|
|
121
|
+
meta != null && /* @__PURE__ */ jsx("p", { className: "uix-news-lead__meta", children: meta }),
|
|
122
|
+
/* @__PURE__ */ jsx("h3", { className: "uix-news-lead__title", children: title }),
|
|
123
|
+
summary != null && /* @__PURE__ */ jsx("p", { className: "uix-news-lead__summary", children: summary })
|
|
124
|
+
] });
|
|
125
|
+
}
|
|
126
|
+
function ContentList({ children, className, ...props }) {
|
|
127
|
+
return /* @__PURE__ */ jsx("ul", { className: cx("uix-content-list", className), ...props, children });
|
|
128
|
+
}
|
|
129
|
+
function ContentListItem({ title, meta, trailing, className, ...props }) {
|
|
130
|
+
return /* @__PURE__ */ jsxs("li", { className: cx("uix-content-list__item", className), ...props, children: [
|
|
131
|
+
/* @__PURE__ */ jsxs("div", { children: [
|
|
132
|
+
/* @__PURE__ */ jsx("p", { className: "uix-content-list__title", children: title }),
|
|
133
|
+
meta != null && /* @__PURE__ */ jsx("p", { className: "uix-content-list__meta", children: meta })
|
|
134
|
+
] }),
|
|
135
|
+
trailing
|
|
136
|
+
] });
|
|
137
|
+
}
|
|
138
|
+
function ResourceGrid({ children, className, ...props }) {
|
|
139
|
+
return /* @__PURE__ */ jsx("div", { className: cx("uix-resource-grid", className), ...props, children });
|
|
140
|
+
}
|
|
141
|
+
function StatLine({ items, children, className, ...props }) {
|
|
142
|
+
return /* @__PURE__ */ jsxs("div", { className: cx("uix-stat-line", className), ...props, children: [
|
|
143
|
+
items?.map((item, i) => /* @__PURE__ */ jsxs("div", { className: "uix-stat-line__item", children: [
|
|
144
|
+
/* @__PURE__ */ jsx("span", { className: "uix-stat-line__value", children: item.value }),
|
|
145
|
+
/* @__PURE__ */ jsx("span", { className: "uix-stat-line__label", children: item.label })
|
|
146
|
+
] }, item.id ?? i)),
|
|
147
|
+
children
|
|
148
|
+
] });
|
|
149
|
+
}
|
|
150
|
+
function EventRow({ month, day, title, meta, className, ...props }) {
|
|
151
|
+
return /* @__PURE__ */ jsxs("div", { className: cx("uix-event-row", className), ...props, children: [
|
|
152
|
+
/* @__PURE__ */ jsxs("div", { className: "uix-event-date", children: [
|
|
153
|
+
/* @__PURE__ */ jsx("span", { className: "uix-event-date__month", children: month }),
|
|
154
|
+
/* @__PURE__ */ jsx("span", { className: "uix-event-date__day", children: day })
|
|
155
|
+
] }),
|
|
156
|
+
/* @__PURE__ */ jsxs("div", { children: [
|
|
157
|
+
/* @__PURE__ */ jsx("p", { className: "uix-event-row__title", children: title }),
|
|
158
|
+
meta != null && /* @__PURE__ */ jsx("p", { className: "uix-event-row__meta", children: meta })
|
|
159
|
+
] })
|
|
160
|
+
] });
|
|
161
|
+
}
|
|
162
|
+
function StatusRow({ indicator, name, meta, className, ...props }) {
|
|
163
|
+
return /* @__PURE__ */ jsxs("div", { className: cx("uix-status-row", className), ...props, children: [
|
|
164
|
+
indicator,
|
|
165
|
+
/* @__PURE__ */ jsx("span", { className: "uix-status-row__name", children: name }),
|
|
166
|
+
meta != null && /* @__PURE__ */ jsx("span", { className: "uix-list-meta", children: meta })
|
|
167
|
+
] });
|
|
168
|
+
}
|
|
169
|
+
export {
|
|
170
|
+
ContentList,
|
|
171
|
+
ContentListItem,
|
|
172
|
+
EventRow,
|
|
173
|
+
FeaturedRundown,
|
|
174
|
+
FeaturedRundownItem,
|
|
175
|
+
FeaturedStage,
|
|
176
|
+
NewsLead,
|
|
177
|
+
NoticeQueue,
|
|
178
|
+
PageIntro,
|
|
179
|
+
ResourceGrid,
|
|
180
|
+
SectionHead,
|
|
181
|
+
StatLine,
|
|
182
|
+
StatusRow
|
|
183
|
+
};
|
package/dist/components/Field.js
CHANGED
|
@@ -1,12 +1,18 @@
|
|
|
1
1
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { cloneElement, isValidElement, useId } from "react";
|
|
2
3
|
import { cx } from "../cx.js";
|
|
3
4
|
function Field({ label, hint, error, success, required, children, className, htmlFor }) {
|
|
5
|
+
const uid = useId();
|
|
6
|
+
const msgId = `${uid}-msg`;
|
|
7
|
+
const describedBy = error || success || hint ? msgId : void 0;
|
|
8
|
+
const control = isValidElement(children) ? cloneElement(children, {
|
|
9
|
+
"aria-describedby": [children.props["aria-describedby"], describedBy].filter(Boolean).join(" ") || void 0,
|
|
10
|
+
"aria-invalid": error ? true : children.props["aria-invalid"]
|
|
11
|
+
}) : children;
|
|
4
12
|
return /* @__PURE__ */ jsxs("div", { className: cx("uix-field", className), children: [
|
|
5
13
|
label && /* @__PURE__ */ jsx("label", { className: "uix-field__label", htmlFor, "data-required": required || void 0, children: label }),
|
|
6
|
-
|
|
7
|
-
error
|
|
8
|
-
success && !error && /* @__PURE__ */ jsx("span", { className: "uix-field__success", children: success }),
|
|
9
|
-
hint && !error && !success && /* @__PURE__ */ jsx("span", { className: "uix-field__hint", children: hint })
|
|
14
|
+
control,
|
|
15
|
+
/* @__PURE__ */ jsx("div", { className: "uix-field__msg", id: msgId, children: error ? /* @__PURE__ */ jsx("span", { className: "uix-field__error", role: "alert", children: error }) : success ? /* @__PURE__ */ jsx("span", { className: "uix-field__success", children: success }) : hint ? /* @__PURE__ */ jsx("span", { className: "uix-field__hint", children: hint }) : null })
|
|
10
16
|
] });
|
|
11
17
|
}
|
|
12
18
|
export {
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import * as react from 'react';
|
|
2
|
-
import { HTMLAttributes, ReactNode } from 'react';
|
|
2
|
+
import { HTMLAttributes, RefObject, ReactNode } from 'react';
|
|
3
|
+
import { Placement } from '../overlay-position.js';
|
|
3
4
|
|
|
4
5
|
interface PopoverProps extends HTMLAttributes<HTMLDivElement> {
|
|
5
6
|
/**
|
|
@@ -7,12 +8,25 @@ interface PopoverProps extends HTMLAttributes<HTMLDivElement> {
|
|
|
7
8
|
* wires to it via `popoverTarget={id}`. Pass `"manual"` to control open state yourself.
|
|
8
9
|
*/
|
|
9
10
|
popover?: 'auto' | 'manual';
|
|
11
|
+
/**
|
|
12
|
+
* Element (or ref) to anchor against. When set, the popover is placed with
|
|
13
|
+
* cross-browser JS positioning — flip when it won't fit, shift to stay on-screen —
|
|
14
|
+
* instead of relying on CSS `anchor()`, which is Chromium-only and detaches the
|
|
15
|
+
* popover from its trigger everywhere else. The native Popover API still provides
|
|
16
|
+
* the top layer (so it escapes `overflow` clipping) and light-dismiss.
|
|
17
|
+
*/
|
|
18
|
+
anchor?: RefObject<HTMLElement | null> | HTMLElement | null;
|
|
19
|
+
/** Preferred placement when `anchor` is set. Default `'bottom-start'`. */
|
|
20
|
+
placement?: Placement;
|
|
21
|
+
/** Gap between the trigger and the popover, in px. Default 6. */
|
|
22
|
+
offset?: number;
|
|
10
23
|
children?: ReactNode;
|
|
11
24
|
}
|
|
12
25
|
/**
|
|
13
|
-
* Anchored surface over `.uix-popover`, using the native Popover API.
|
|
14
|
-
*
|
|
26
|
+
* Anchored surface over `.uix-popover`, using the native Popover API. Compose ITSM
|
|
27
|
+
* things like a filter popover, menu, or rich select by putting controls inside.
|
|
28
|
+
* Pass `anchor` to get collision-aware, cross-browser placement (UIX-FIX-02).
|
|
15
29
|
*/
|
|
16
|
-
declare function Popover({ popover,
|
|
30
|
+
declare function Popover({ popover, anchor, placement, offset, className, children, ...props }: PopoverProps): react.JSX.Element;
|
|
17
31
|
|
|
18
32
|
export { Popover, type PopoverProps };
|
|
@@ -1,8 +1,37 @@
|
|
|
1
|
+
"use client";
|
|
1
2
|
import { jsx } from "react/jsx-runtime";
|
|
3
|
+
import { useEffect, useRef, useState } from "react";
|
|
2
4
|
import { cx } from "../cx.js";
|
|
3
|
-
|
|
5
|
+
import { useAnchoredPosition } from "../hooks/useAnchoredPosition.js";
|
|
6
|
+
function Popover({
|
|
7
|
+
popover = "auto",
|
|
8
|
+
anchor,
|
|
9
|
+
placement = "bottom-start",
|
|
10
|
+
offset = 6,
|
|
11
|
+
className,
|
|
12
|
+
children,
|
|
13
|
+
...props
|
|
14
|
+
}) {
|
|
15
|
+
const ref = useRef(null);
|
|
16
|
+
const [open, setOpen] = useState(false);
|
|
4
17
|
const popoverAttr = { popover };
|
|
5
|
-
|
|
18
|
+
const reposition = useAnchoredPosition(anchor ?? null, ref, {
|
|
19
|
+
open: open && !!anchor,
|
|
20
|
+
placement,
|
|
21
|
+
offset
|
|
22
|
+
});
|
|
23
|
+
useEffect(() => {
|
|
24
|
+
const el = ref.current;
|
|
25
|
+
if (!el || !anchor) return;
|
|
26
|
+
const sync = () => {
|
|
27
|
+
const isOpen = el.matches(":popover-open");
|
|
28
|
+
if (isOpen) reposition();
|
|
29
|
+
setOpen(isOpen);
|
|
30
|
+
};
|
|
31
|
+
el.addEventListener("toggle", sync);
|
|
32
|
+
return () => el.removeEventListener("toggle", sync);
|
|
33
|
+
}, [anchor, reposition]);
|
|
34
|
+
return /* @__PURE__ */ jsx("div", { ref, className: cx("uix-popover", className), ...popoverAttr, ...props, children });
|
|
6
35
|
}
|
|
7
36
|
export {
|
|
8
37
|
Popover
|
package/dist/components/Toast.js
CHANGED
|
@@ -1,16 +1,17 @@
|
|
|
1
1
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { cx } from "../cx.js";
|
|
3
3
|
function Toast({ title, message, tone, icon, onClose, leaving, className, ...props }) {
|
|
4
|
+
const assertive = tone === "danger";
|
|
4
5
|
return /* @__PURE__ */ jsxs(
|
|
5
6
|
"div",
|
|
6
7
|
{
|
|
7
8
|
className: cx("uix-toast", tone && `uix-toast--${tone}`, className),
|
|
8
9
|
"data-leaving": leaving || void 0,
|
|
9
|
-
role: "status",
|
|
10
|
-
"aria-live": "polite",
|
|
10
|
+
role: assertive ? "alert" : "status",
|
|
11
|
+
"aria-live": assertive ? "assertive" : "polite",
|
|
11
12
|
...props,
|
|
12
13
|
children: [
|
|
13
|
-
icon && /* @__PURE__ */ jsx("div", { className: "uix-toast__icon", children: icon }),
|
|
14
|
+
icon && /* @__PURE__ */ jsx("div", { className: "uix-toast__icon", "aria-hidden": "true", children: icon }),
|
|
14
15
|
/* @__PURE__ */ jsxs("div", { className: "uix-toast__body", children: [
|
|
15
16
|
title && /* @__PURE__ */ jsx("div", { className: "uix-toast__title", children: title }),
|
|
16
17
|
message && /* @__PURE__ */ jsx("div", { className: "uix-toast__msg", children: message })
|
|
@@ -21,7 +22,7 @@ function Toast({ title, message, tone, icon, onClose, leaving, className, ...pro
|
|
|
21
22
|
);
|
|
22
23
|
}
|
|
23
24
|
function Toaster({ children, className, ...props }) {
|
|
24
|
-
return /* @__PURE__ */ jsx("div", { className: cx("uix-toaster", className),
|
|
25
|
+
return /* @__PURE__ */ jsx("div", { className: cx("uix-toaster", className), ...props, children });
|
|
25
26
|
}
|
|
26
27
|
export {
|
|
27
28
|
Toast,
|
|
@@ -1,16 +1,20 @@
|
|
|
1
1
|
import * as react from 'react';
|
|
2
2
|
import { HTMLAttributes, ReactNode } from 'react';
|
|
3
|
+
import { Placement } from '../overlay-position.js';
|
|
3
4
|
|
|
4
5
|
interface TooltipProps extends HTMLAttributes<HTMLSpanElement> {
|
|
5
|
-
/** Tooltip text.
|
|
6
|
+
/** Tooltip text. */
|
|
6
7
|
label: string;
|
|
8
|
+
/** Preferred placement. Default `'top'`. */
|
|
9
|
+
placement?: Placement;
|
|
7
10
|
children?: ReactNode;
|
|
8
11
|
}
|
|
9
12
|
/**
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
+
* Tooltip whose bubble renders in the top layer via the native Popover API, so it
|
|
14
|
+
* escapes any `overflow: hidden/scroll` ancestor that would clip the old CSS-only
|
|
15
|
+
* `[data-uix-tip]` tooltip (UIX-FIX-02). Positioned by the shared overlay engine
|
|
16
|
+
* (flip/shift), shown on hover and keyboard focus, dismissed on blur or Escape.
|
|
13
17
|
*/
|
|
14
|
-
declare function Tooltip({ label, children, ...props }: TooltipProps): react.JSX.Element;
|
|
18
|
+
declare function Tooltip({ label, placement, className, children, ...props }: TooltipProps): react.JSX.Element;
|
|
15
19
|
|
|
16
20
|
export { Tooltip, type TooltipProps };
|
|
@@ -1,6 +1,64 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { useEffect, useId, useRef, useState } from "react";
|
|
4
|
+
import { cx } from "../cx.js";
|
|
5
|
+
import { useAnchoredPosition } from "../hooks/useAnchoredPosition.js";
|
|
6
|
+
function Tooltip({ label, placement = "top", className, children, ...props }) {
|
|
7
|
+
const triggerRef = useRef(null);
|
|
8
|
+
const bubbleRef = useRef(null);
|
|
9
|
+
const [open, setOpen] = useState(false);
|
|
10
|
+
const id = useId();
|
|
11
|
+
useAnchoredPosition(triggerRef, bubbleRef, { open, placement, offset: 6 });
|
|
12
|
+
const show = () => {
|
|
13
|
+
const b = bubbleRef.current;
|
|
14
|
+
if (b && !b.matches(":popover-open")) {
|
|
15
|
+
try {
|
|
16
|
+
b.showPopover();
|
|
17
|
+
} catch {
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
setOpen(true);
|
|
21
|
+
};
|
|
22
|
+
const hide = () => {
|
|
23
|
+
const b = bubbleRef.current;
|
|
24
|
+
if (b && b.matches(":popover-open")) {
|
|
25
|
+
try {
|
|
26
|
+
b.hidePopover();
|
|
27
|
+
} catch {
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
setOpen(false);
|
|
31
|
+
};
|
|
32
|
+
useEffect(() => () => {
|
|
33
|
+
const b = bubbleRef.current;
|
|
34
|
+
if (b && b.matches(":popover-open")) {
|
|
35
|
+
try {
|
|
36
|
+
b.hidePopover();
|
|
37
|
+
} catch {
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
}, []);
|
|
41
|
+
const bubbleAttr = { popover: "manual" };
|
|
42
|
+
return /* @__PURE__ */ jsxs(
|
|
43
|
+
"span",
|
|
44
|
+
{
|
|
45
|
+
ref: triggerRef,
|
|
46
|
+
className: cx("uix-tooltip", className),
|
|
47
|
+
"aria-describedby": id,
|
|
48
|
+
onMouseEnter: show,
|
|
49
|
+
onMouseLeave: hide,
|
|
50
|
+
onFocus: show,
|
|
51
|
+
onBlur: hide,
|
|
52
|
+
onKeyDown: (e) => {
|
|
53
|
+
if (e.key === "Escape") hide();
|
|
54
|
+
},
|
|
55
|
+
...props,
|
|
56
|
+
children: [
|
|
57
|
+
children,
|
|
58
|
+
/* @__PURE__ */ jsx("span", { ref: bubbleRef, id, role: "tooltip", className: "uix-tooltip__bubble", ...bubbleAttr, children: label })
|
|
59
|
+
]
|
|
60
|
+
}
|
|
61
|
+
);
|
|
4
62
|
}
|
|
5
63
|
export {
|
|
6
64
|
Tooltip
|
|
@@ -11,8 +11,11 @@ interface TreeNodeProps {
|
|
|
11
11
|
node: TreeNodeData;
|
|
12
12
|
expanded: Set<string>;
|
|
13
13
|
selected?: string;
|
|
14
|
+
selectable: boolean;
|
|
15
|
+
tabbableId?: string;
|
|
14
16
|
onToggle: (id: string) => void;
|
|
15
17
|
onSelect?: (id: string) => void;
|
|
18
|
+
onFocusNode: (id: string) => void;
|
|
16
19
|
level?: number;
|
|
17
20
|
}
|
|
18
21
|
interface TreeProps extends Omit<HTMLAttributes<HTMLUListElement>, 'onSelect' | 'onChange'> {
|
|
@@ -22,7 +25,18 @@ interface TreeProps extends Omit<HTMLAttributes<HTMLUListElement>, 'onSelect' |
|
|
|
22
25
|
selected?: string;
|
|
23
26
|
onToggle?: (id: string) => void;
|
|
24
27
|
onSelect?: (id: string) => void;
|
|
28
|
+
/**
|
|
29
|
+
* Virtualize a large tree — render only the rows in view (UIX-FIX-05). Defaults to auto
|
|
30
|
+
* (on past the engine's `shouldVirtualize` threshold of visible rows). When on, the tree is
|
|
31
|
+
* flattened to a scrollable list of `maxHeight` with fixed-height rows; a11y is preserved via
|
|
32
|
+
* `aria-level` / `aria-setsize` / `aria-posinset` instead of nested `role="group"`s.
|
|
33
|
+
*/
|
|
34
|
+
virtualize?: boolean;
|
|
35
|
+
/** Fixed row height (px) used for virtualization. Default 32. */
|
|
36
|
+
rowHeight?: number;
|
|
37
|
+
/** Scroll-viewport height (px) when virtualizing. Default 384. */
|
|
38
|
+
maxHeight?: number;
|
|
25
39
|
}
|
|
26
|
-
declare function Tree({ nodes, expanded: controlledExpanded, defaultExpanded, selected, onToggle, onSelect, className, ...props }: TreeProps): react.JSX.Element;
|
|
40
|
+
declare function Tree({ nodes, expanded: controlledExpanded, defaultExpanded, selected, onToggle, onSelect, virtualize, rowHeight, maxHeight, className, ...props }: TreeProps): react.JSX.Element;
|
|
27
41
|
|
|
28
42
|
export { Tree, type TreeNodeData, type TreeNodeProps, type TreeProps };
|