@mediaradar/design-components 0.20.0 → 0.21.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/index.cjs +323 -12
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +316 -14
- package/dist/index.d.ts +316 -14
- package/dist/index.js +325 -19
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -37,11 +37,13 @@ __export(index_exports, {
|
|
|
37
37
|
DateRangeFilter: () => DateRangeFilter,
|
|
38
38
|
DateRangePicker: () => DateRangePicker,
|
|
39
39
|
Delta: () => Delta,
|
|
40
|
+
EmptyState: () => EmptyState,
|
|
40
41
|
FilterChipBar: () => FilterChipBar,
|
|
41
42
|
FilterDropdownFooter: () => FilterDropdownFooter,
|
|
42
43
|
Freshness: () => Freshness,
|
|
43
44
|
InfoTip: () => InfoTip,
|
|
44
45
|
LineChartPlaceholder: () => LineChartPlaceholder,
|
|
46
|
+
Modal: () => Modal,
|
|
45
47
|
MultiSelectFilter: () => MultiSelectFilter,
|
|
46
48
|
NO_RESULTS_BODY: () => NO_RESULTS_BODY,
|
|
47
49
|
NO_RESULTS_TITLE: () => NO_RESULTS_TITLE,
|
|
@@ -56,6 +58,7 @@ __export(index_exports, {
|
|
|
56
58
|
SearchBar: () => SearchBar,
|
|
57
59
|
SectionHeading: () => SectionHeading,
|
|
58
60
|
SectionRail: () => SectionRail,
|
|
61
|
+
SegmentedControl: () => SegmentedControl,
|
|
59
62
|
SelectAllVisible: () => SelectAllVisible,
|
|
60
63
|
SelectFilter: () => SelectFilter,
|
|
61
64
|
SelectedSection: () => SelectedSection,
|
|
@@ -63,7 +66,9 @@ __export(index_exports, {
|
|
|
63
66
|
SortButton: () => SortButton,
|
|
64
67
|
StackedColumnPlaceholder: () => StackedColumnPlaceholder,
|
|
65
68
|
TablePagination: () => TablePagination,
|
|
69
|
+
Tabs: () => Tabs,
|
|
66
70
|
Tag: () => Tag,
|
|
71
|
+
TextField: () => TextField,
|
|
67
72
|
Toast: () => Toast,
|
|
68
73
|
Toggle: () => Toggle,
|
|
69
74
|
Tooltip: () => Tooltip,
|
|
@@ -312,7 +317,7 @@ function AdvertiserQuickFilter({
|
|
|
312
317
|
"aria-label": caption,
|
|
313
318
|
"data-testid": testIdPrefix && `${testIdPrefix}-popover`,
|
|
314
319
|
children: [
|
|
315
|
-
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "border-b border-border-default p-2", children: /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "flex h-
|
|
320
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "border-b border-border-default p-2", children: /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "flex h-8 items-center gap-2 rounded-control border border-border-strong bg-input px-2.5 focus-within:outline-2 focus-within:outline-offset-1 focus-within:outline-border-focus", children: [
|
|
316
321
|
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_lucide_react3.Search, { size: 14, className: "shrink-0 text-text-secondary", "aria-hidden": "true" }),
|
|
317
322
|
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
318
323
|
"input",
|
|
@@ -991,6 +996,7 @@ function NavBtn({ children, onClick, ...rest }) {
|
|
|
991
996
|
var import_react4 = require("react");
|
|
992
997
|
var import_lucide_react7 = require("lucide-react");
|
|
993
998
|
var import_jsx_runtime8 = require("react/jsx-runtime");
|
|
999
|
+
var HEIGHT = { sm: "h-8", md: "h-10", lg: "h-11" };
|
|
994
1000
|
var DEFAULT_SEARCH_MATCH = { mode: "anyWord", wordJoin: "Or" };
|
|
995
1001
|
var MODE_LABEL = {
|
|
996
1002
|
anyWord: "Any Word",
|
|
@@ -1006,6 +1012,7 @@ function SearchBar({
|
|
|
1006
1012
|
value,
|
|
1007
1013
|
onChange,
|
|
1008
1014
|
variant = "default",
|
|
1015
|
+
size = "lg",
|
|
1009
1016
|
matchValue,
|
|
1010
1017
|
onMatchChange,
|
|
1011
1018
|
className,
|
|
@@ -1013,6 +1020,7 @@ function SearchBar({
|
|
|
1013
1020
|
}) {
|
|
1014
1021
|
const [open, setOpen] = (0, import_react4.useState)(false);
|
|
1015
1022
|
const ref = (0, import_react4.useRef)(null);
|
|
1023
|
+
const input = (0, import_react4.useRef)(null);
|
|
1016
1024
|
(0, import_react4.useEffect)(() => {
|
|
1017
1025
|
if (!open) return;
|
|
1018
1026
|
const onKey = (e) => e.key === "Escape" && setOpen(false);
|
|
@@ -1031,7 +1039,8 @@ function SearchBar({
|
|
|
1031
1039
|
"div",
|
|
1032
1040
|
{
|
|
1033
1041
|
className: cx2(
|
|
1034
|
-
"flex
|
|
1042
|
+
"flex min-w-[200px] flex-1 items-stretch rounded-control border border-border-strong bg-input focus-within:outline-2 focus-within:outline-offset-1 focus-within:outline-border-focus",
|
|
1043
|
+
HEIGHT[size],
|
|
1035
1044
|
className
|
|
1036
1045
|
),
|
|
1037
1046
|
children: [
|
|
@@ -1040,16 +1049,31 @@ function SearchBar({
|
|
|
1040
1049
|
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
1041
1050
|
"input",
|
|
1042
1051
|
{
|
|
1052
|
+
ref: input,
|
|
1043
1053
|
type: "text",
|
|
1044
1054
|
value,
|
|
1045
1055
|
onChange: (e) => onChange?.(e.target.value),
|
|
1046
1056
|
placeholder,
|
|
1047
1057
|
"aria-label": placeholder,
|
|
1048
1058
|
"data-testid": testIdPrefix && `${testIdPrefix}-search`,
|
|
1049
|
-
className: "min-w-0 flex-1 bg-transparent text-
|
|
1059
|
+
className: "min-w-0 flex-1 bg-transparent text-dense text-text-primary outline-hidden placeholder:text-text-tertiary"
|
|
1050
1060
|
}
|
|
1051
1061
|
)
|
|
1052
1062
|
] }),
|
|
1063
|
+
value && onChange && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
1064
|
+
"button",
|
|
1065
|
+
{
|
|
1066
|
+
type: "button",
|
|
1067
|
+
onClick: () => {
|
|
1068
|
+
onChange("");
|
|
1069
|
+
input.current?.focus();
|
|
1070
|
+
},
|
|
1071
|
+
"aria-label": "Clear search",
|
|
1072
|
+
"data-testid": testIdPrefix && `${testIdPrefix}-clear`,
|
|
1073
|
+
className: "mr-1.5 flex size-6 shrink-0 items-center justify-center self-center rounded-control text-text-tertiary hover:bg-subtle hover:text-text-primary focus-visible:outline-2 focus-visible:outline-border-focus",
|
|
1074
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_lucide_react7.X, { size: 14, "aria-hidden": "true" })
|
|
1075
|
+
}
|
|
1076
|
+
),
|
|
1053
1077
|
showMatch && // border-border-default, not the bare `border-border` both source
|
|
1054
1078
|
// implementations used -- confirmed by actually compiling against
|
|
1055
1079
|
// @mediaradar/design-tokens' real published theme.css (not assumed):
|
|
@@ -2401,7 +2425,7 @@ function SelectionPicker({
|
|
|
2401
2425
|
}) }),
|
|
2402
2426
|
source === "search" && /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: "flex min-w-0 flex-col gap-3", children: [
|
|
2403
2427
|
/* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: "flex flex-wrap items-center gap-2", children: [
|
|
2404
|
-
/* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: "flex h-
|
|
2428
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: "flex h-8 min-w-[200px] flex-1 items-center gap-2 rounded-control border border-border-strong bg-input px-3 focus-within:outline-2 focus-within:outline-offset-1 focus-within:outline-border-focus", children: [
|
|
2405
2429
|
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_lucide_react15.Search, { size: 15, className: "text-text-secondary", "aria-hidden": "true" }),
|
|
2406
2430
|
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
|
|
2407
2431
|
"input",
|
|
@@ -2715,7 +2739,7 @@ function FilterDropdown({
|
|
|
2715
2739
|
onClick: () => setOpen((v) => !v),
|
|
2716
2740
|
"aria-expanded": open,
|
|
2717
2741
|
"data-testid": testIdPrefix && `${testIdPrefix}-filter-${filterSlug}`,
|
|
2718
|
-
className: "inline-flex h-
|
|
2742
|
+
className: "inline-flex h-8 items-center gap-1.5 whitespace-nowrap rounded-control border border-border-strong bg-input px-3 text-[13px] font-medium text-text-secondary transition-colors hover:bg-subtle",
|
|
2719
2743
|
children: [
|
|
2720
2744
|
label,
|
|
2721
2745
|
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_lucide_react15.ChevronDown, { size: 13, "aria-hidden": "true", className: cx8("transition-transform", open && "rotate-180") })
|
|
@@ -2921,7 +2945,10 @@ var buttonVariants = (0, import_class_variance_authority.cva)(
|
|
|
2921
2945
|
size: {
|
|
2922
2946
|
xs: "h-6 px-2 text-xs",
|
|
2923
2947
|
sm: "h-8 px-3 text-sm",
|
|
2924
|
-
md: "h-10 px-4 text-sm"
|
|
2948
|
+
md: "h-10 px-4 text-sm",
|
|
2949
|
+
// 44, the filter row's height, so a button at the end of a row of
|
|
2950
|
+
// filter dropdowns lines up with them. One control scale: 32 / 40 / 44.
|
|
2951
|
+
lg: "h-11 px-5 text-sm"
|
|
2925
2952
|
},
|
|
2926
2953
|
// Shape is orthogonal to size. As a fourth SIZE, `icon` could only ever
|
|
2927
2954
|
// be one dimension, so an icon button never lined up with the labelled
|
|
@@ -2936,6 +2963,7 @@ var buttonVariants = (0, import_class_variance_authority.cva)(
|
|
|
2936
2963
|
{ size: "xs", iconOnly: true, class: "w-6" },
|
|
2937
2964
|
{ size: "sm", iconOnly: true, class: "w-8" },
|
|
2938
2965
|
{ size: "md", iconOnly: true, class: "w-10" },
|
|
2966
|
+
{ size: "lg", iconOnly: true, class: "w-11" },
|
|
2939
2967
|
// A boxed button is a target you aim at, so its label carries the weight
|
|
2940
2968
|
// of one. `link` sits inline in a sentence, where semibold reads as
|
|
2941
2969
|
// emphasis on the words rather than as a control.
|
|
@@ -3049,7 +3077,7 @@ function NameListModal({
|
|
|
3049
3077
|
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
|
|
3050
3078
|
"div",
|
|
3051
3079
|
{
|
|
3052
|
-
className: "fixed inset-0 z-
|
|
3080
|
+
className: "fixed inset-0 z-modal flex items-center justify-center bg-scrim px-4",
|
|
3053
3081
|
onMouseDown: (e) => e.target === e.currentTarget && onCancel(),
|
|
3054
3082
|
children: /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)(
|
|
3055
3083
|
"div",
|
|
@@ -3059,7 +3087,7 @@ function NameListModal({
|
|
|
3059
3087
|
"aria-modal": "true",
|
|
3060
3088
|
"aria-labelledby": titleId,
|
|
3061
3089
|
onKeyDown: trapTab,
|
|
3062
|
-
className: "w-full max-w-
|
|
3090
|
+
className: "w-full max-w-110 rounded-card border border-border-default bg-surface p-5 shadow-overlay",
|
|
3063
3091
|
children: [
|
|
3064
3092
|
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)("h2", { id: titleId, className: "text-[16px] font-semibold text-text-primary", children: title }),
|
|
3065
3093
|
/* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("div", { className: "mt-4 flex flex-col gap-1.5", children: [
|
|
@@ -3072,7 +3100,7 @@ function NameListModal({
|
|
|
3072
3100
|
value: name,
|
|
3073
3101
|
onChange: (e) => setName(e.target.value),
|
|
3074
3102
|
placeholder,
|
|
3075
|
-
className: "h-10 rounded-control border border-border-strong bg-input px-3 text-
|
|
3103
|
+
className: "h-10 rounded-control border border-border-strong bg-input px-3 text-dense focus-visible:outline-2 focus-visible:outline-offset-1 focus-visible:outline-border-focus"
|
|
3076
3104
|
}
|
|
3077
3105
|
)
|
|
3078
3106
|
] }),
|
|
@@ -3617,7 +3645,7 @@ function MiniSelect({ value, onChange, options }) {
|
|
|
3617
3645
|
const opt = options.find((o) => String(o.value) === e.target.value);
|
|
3618
3646
|
if (opt) onChange(opt.value);
|
|
3619
3647
|
},
|
|
3620
|
-
className: "rounded-control border border-border-strong bg-input px-1.5 py-1 text-[12px] text-text-primary outline-
|
|
3648
|
+
className: "rounded-control border border-border-strong bg-input px-1.5 py-1 text-[12px] text-text-primary focus-visible:outline-2 focus-visible:outline-offset-1 focus-visible:outline-border-focus",
|
|
3621
3649
|
children: options.map((o) => /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("option", { value: String(o.value), children: o.label }, String(o.value)))
|
|
3622
3650
|
}
|
|
3623
3651
|
);
|
|
@@ -3870,7 +3898,7 @@ function MultiSelectFilter({
|
|
|
3870
3898
|
role: "dialog",
|
|
3871
3899
|
"aria-label": caption,
|
|
3872
3900
|
children: [
|
|
3873
|
-
searchable && /* @__PURE__ */ (0, import_jsx_runtime38.jsx)("div", { className: "border-b border-border-default p-2", children: /* @__PURE__ */ (0, import_jsx_runtime38.jsxs)("div", { className: "flex h-
|
|
3901
|
+
searchable && /* @__PURE__ */ (0, import_jsx_runtime38.jsx)("div", { className: "border-b border-border-default p-2", children: /* @__PURE__ */ (0, import_jsx_runtime38.jsxs)("div", { className: "flex h-8 items-center gap-2 rounded-control border border-border-strong bg-input px-2.5 focus-within:outline-2 focus-within:outline-offset-1 focus-within:outline-border-focus", children: [
|
|
3874
3902
|
/* @__PURE__ */ (0, import_jsx_runtime38.jsx)(import_lucide_react23.Search, { size: 14, className: "text-text-secondary", "aria-hidden": "true" }),
|
|
3875
3903
|
/* @__PURE__ */ (0, import_jsx_runtime38.jsx)(
|
|
3876
3904
|
"input",
|
|
@@ -4080,16 +4108,294 @@ function SectionHeading({ title, description, actions, as: Tag2 = "h2", id, clas
|
|
|
4080
4108
|
}
|
|
4081
4109
|
|
|
4082
4110
|
// src/PageHeader.tsx
|
|
4111
|
+
var import_lucide_react25 = require("lucide-react");
|
|
4083
4112
|
var import_jsx_runtime43 = require("react/jsx-runtime");
|
|
4084
|
-
function PageHeader({ title, description, actions, className }) {
|
|
4113
|
+
function PageHeader({ title, description, actions, back, className }) {
|
|
4085
4114
|
return /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)("header", { className: cn("flex flex-wrap items-center justify-between gap-x-6 gap-y-3", className), children: [
|
|
4086
4115
|
/* @__PURE__ */ (0, import_jsx_runtime43.jsxs)("div", { className: "min-w-0", children: [
|
|
4116
|
+
back && /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)(
|
|
4117
|
+
"a",
|
|
4118
|
+
{
|
|
4119
|
+
href: back.href ?? "#",
|
|
4120
|
+
onClick: back.onClick,
|
|
4121
|
+
className: "mb-1.5 inline-flex items-center gap-1.5 rounded-control text-micro font-semibold uppercase tracking-wider text-text-tertiary hover:text-text-primary focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-border-focus",
|
|
4122
|
+
children: [
|
|
4123
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.jsx)(import_lucide_react25.ArrowLeft, { size: 13, "aria-hidden": "true" }),
|
|
4124
|
+
back.label
|
|
4125
|
+
]
|
|
4126
|
+
}
|
|
4127
|
+
),
|
|
4087
4128
|
/* @__PURE__ */ (0, import_jsx_runtime43.jsx)("h1", { className: "text-xl font-semibold tracking-tight text-text-primary", children: title }),
|
|
4088
4129
|
description && /* @__PURE__ */ (0, import_jsx_runtime43.jsx)("p", { className: "mt-0.5 max-w-2xl text-sm text-text-secondary", children: description })
|
|
4089
4130
|
] }),
|
|
4090
4131
|
actions && /* @__PURE__ */ (0, import_jsx_runtime43.jsx)("div", { className: "flex shrink-0 items-center gap-2", children: actions })
|
|
4091
4132
|
] });
|
|
4092
4133
|
}
|
|
4134
|
+
|
|
4135
|
+
// src/Modal.tsx
|
|
4136
|
+
var import_react19 = require("react");
|
|
4137
|
+
var import_react_dom7 = require("react-dom");
|
|
4138
|
+
var import_lucide_react26 = require("lucide-react");
|
|
4139
|
+
var import_jsx_runtime44 = require("react/jsx-runtime");
|
|
4140
|
+
var WIDTH = {
|
|
4141
|
+
sm: "max-w-110",
|
|
4142
|
+
md: "max-w-160",
|
|
4143
|
+
lg: "max-w-220"
|
|
4144
|
+
};
|
|
4145
|
+
var FOCUSABLE = 'a[href], button:not([disabled]), input:not([disabled]), select:not([disabled]), textarea:not([disabled]), [tabindex]:not([tabindex="-1"])';
|
|
4146
|
+
function Modal({ open, onClose, title, description, size = "md", footer, children, className }) {
|
|
4147
|
+
const titleId = (0, import_react19.useId)();
|
|
4148
|
+
const descId = (0, import_react19.useId)();
|
|
4149
|
+
const panel = (0, import_react19.useRef)(null);
|
|
4150
|
+
const close = (0, import_react19.useRef)(onClose);
|
|
4151
|
+
close.current = onClose;
|
|
4152
|
+
(0, import_react19.useEffect)(() => {
|
|
4153
|
+
if (!open) return;
|
|
4154
|
+
const opener = document.activeElement;
|
|
4155
|
+
const first = panel.current?.querySelector(`[data-modal-body] :is(${FOCUSABLE})`) ?? panel.current?.querySelector(`[data-modal-footer] :is(${FOCUSABLE})`);
|
|
4156
|
+
(first ?? panel.current)?.focus();
|
|
4157
|
+
const overflow = document.body.style.overflow;
|
|
4158
|
+
document.body.style.overflow = "hidden";
|
|
4159
|
+
const onKey = (e) => {
|
|
4160
|
+
if (e.key === "Escape") {
|
|
4161
|
+
e.stopPropagation();
|
|
4162
|
+
close.current();
|
|
4163
|
+
return;
|
|
4164
|
+
}
|
|
4165
|
+
if (e.key !== "Tab" || !panel.current) return;
|
|
4166
|
+
const items = Array.from(panel.current.querySelectorAll(FOCUSABLE));
|
|
4167
|
+
if (items.length === 0) return;
|
|
4168
|
+
const [head, tail] = [items[0], items[items.length - 1]];
|
|
4169
|
+
if (e.shiftKey && document.activeElement === head) {
|
|
4170
|
+
e.preventDefault();
|
|
4171
|
+
tail.focus();
|
|
4172
|
+
} else if (!e.shiftKey && document.activeElement === tail) {
|
|
4173
|
+
e.preventDefault();
|
|
4174
|
+
head.focus();
|
|
4175
|
+
}
|
|
4176
|
+
};
|
|
4177
|
+
document.addEventListener("keydown", onKey);
|
|
4178
|
+
return () => {
|
|
4179
|
+
document.removeEventListener("keydown", onKey);
|
|
4180
|
+
document.body.style.overflow = overflow;
|
|
4181
|
+
opener?.focus?.();
|
|
4182
|
+
};
|
|
4183
|
+
}, [open]);
|
|
4184
|
+
if (!open || typeof document === "undefined") return null;
|
|
4185
|
+
return (0, import_react_dom7.createPortal)(
|
|
4186
|
+
/* @__PURE__ */ (0, import_jsx_runtime44.jsx)(
|
|
4187
|
+
"div",
|
|
4188
|
+
{
|
|
4189
|
+
className: "fixed inset-0 z-modal flex items-center justify-center bg-scrim px-4 py-6",
|
|
4190
|
+
onMouseDown: (e) => e.target === e.currentTarget && onClose(),
|
|
4191
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)(
|
|
4192
|
+
"div",
|
|
4193
|
+
{
|
|
4194
|
+
ref: panel,
|
|
4195
|
+
role: "dialog",
|
|
4196
|
+
"aria-modal": "true",
|
|
4197
|
+
"aria-labelledby": titleId,
|
|
4198
|
+
"aria-describedby": description ? descId : void 0,
|
|
4199
|
+
tabIndex: -1,
|
|
4200
|
+
className: cn(
|
|
4201
|
+
"flex max-h-full w-full flex-col rounded-card border border-border-default bg-surface shadow-overlay outline-hidden",
|
|
4202
|
+
WIDTH[size],
|
|
4203
|
+
className
|
|
4204
|
+
),
|
|
4205
|
+
children: [
|
|
4206
|
+
/* @__PURE__ */ (0, import_jsx_runtime44.jsxs)("div", { className: "flex items-start gap-3 px-5 pt-5 pb-3", children: [
|
|
4207
|
+
/* @__PURE__ */ (0, import_jsx_runtime44.jsxs)("div", { className: "min-w-0 flex-1", children: [
|
|
4208
|
+
/* @__PURE__ */ (0, import_jsx_runtime44.jsx)("h2", { id: titleId, className: "text-base font-semibold text-text-primary", children: title }),
|
|
4209
|
+
description && /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("p", { id: descId, className: "mt-0.5 text-sm text-text-secondary", children: description })
|
|
4210
|
+
] }),
|
|
4211
|
+
/* @__PURE__ */ (0, import_jsx_runtime44.jsx)(
|
|
4212
|
+
"button",
|
|
4213
|
+
{
|
|
4214
|
+
type: "button",
|
|
4215
|
+
onClick: onClose,
|
|
4216
|
+
"aria-label": "Close",
|
|
4217
|
+
className: "-mr-1.5 -mt-1 flex size-8 shrink-0 items-center justify-center rounded-control text-text-tertiary hover:bg-subtle hover:text-text-primary focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-border-focus",
|
|
4218
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(import_lucide_react26.X, { size: 16, "aria-hidden": "true" })
|
|
4219
|
+
}
|
|
4220
|
+
)
|
|
4221
|
+
] }),
|
|
4222
|
+
children && /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("div", { "data-modal-body": true, className: "min-h-0 flex-1 overflow-y-auto px-5 pb-5 text-sm text-text-primary", children }),
|
|
4223
|
+
footer && /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("div", { "data-modal-footer": true, className: "flex items-center justify-end gap-2 border-t border-border-default px-5 py-3", children: footer })
|
|
4224
|
+
]
|
|
4225
|
+
}
|
|
4226
|
+
)
|
|
4227
|
+
}
|
|
4228
|
+
),
|
|
4229
|
+
document.body
|
|
4230
|
+
);
|
|
4231
|
+
}
|
|
4232
|
+
|
|
4233
|
+
// src/EmptyState.tsx
|
|
4234
|
+
var import_jsx_runtime45 = require("react/jsx-runtime");
|
|
4235
|
+
function EmptyState({ icon, title, description, action, size = "sm", className }) {
|
|
4236
|
+
const md = size === "md";
|
|
4237
|
+
return /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)(
|
|
4238
|
+
"div",
|
|
4239
|
+
{
|
|
4240
|
+
className: cn(
|
|
4241
|
+
"flex flex-col items-center text-center",
|
|
4242
|
+
md ? "gap-2 px-6 py-16" : "gap-1.5 px-4 py-8",
|
|
4243
|
+
className
|
|
4244
|
+
),
|
|
4245
|
+
children: [
|
|
4246
|
+
icon && /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(
|
|
4247
|
+
"span",
|
|
4248
|
+
{
|
|
4249
|
+
"aria-hidden": "true",
|
|
4250
|
+
className: cn(
|
|
4251
|
+
"flex items-center justify-center text-text-tertiary",
|
|
4252
|
+
md && "mb-1 size-11 rounded-full bg-subtle"
|
|
4253
|
+
),
|
|
4254
|
+
children: icon
|
|
4255
|
+
}
|
|
4256
|
+
),
|
|
4257
|
+
/* @__PURE__ */ (0, import_jsx_runtime45.jsx)("p", { className: cn("font-semibold text-text-primary", md ? "text-base" : "text-sm"), children: title }),
|
|
4258
|
+
description && /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("p", { className: cn("max-w-sm text-text-secondary", md ? "text-sm" : "text-xs"), children: description }),
|
|
4259
|
+
action && /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("div", { className: md ? "mt-3" : "mt-2", children: action })
|
|
4260
|
+
]
|
|
4261
|
+
}
|
|
4262
|
+
);
|
|
4263
|
+
}
|
|
4264
|
+
|
|
4265
|
+
// src/Tabs.tsx
|
|
4266
|
+
var import_react20 = require("react");
|
|
4267
|
+
var import_jsx_runtime46 = require("react/jsx-runtime");
|
|
4268
|
+
function arrowKeys(e, row) {
|
|
4269
|
+
if (!row || !["ArrowLeft", "ArrowRight", "Home", "End"].includes(e.key)) return;
|
|
4270
|
+
const items = Array.from(row.querySelectorAll("button:not([disabled])"));
|
|
4271
|
+
const at = items.indexOf(document.activeElement);
|
|
4272
|
+
const next = e.key === "Home" ? 0 : e.key === "End" ? items.length - 1 : (at + (e.key === "ArrowRight" ? 1 : -1) + items.length) % items.length;
|
|
4273
|
+
e.preventDefault();
|
|
4274
|
+
items[next]?.focus();
|
|
4275
|
+
items[next]?.click();
|
|
4276
|
+
}
|
|
4277
|
+
function Tabs({ items, value, onChange, idPrefix = "tabs", className, ...rest }) {
|
|
4278
|
+
const row = (0, import_react20.useRef)(null);
|
|
4279
|
+
return /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(
|
|
4280
|
+
"div",
|
|
4281
|
+
{
|
|
4282
|
+
ref: row,
|
|
4283
|
+
role: "tablist",
|
|
4284
|
+
"aria-label": rest["aria-label"],
|
|
4285
|
+
onKeyDown: (e) => arrowKeys(e, row.current),
|
|
4286
|
+
className: cn("flex gap-6 border-b border-border-default", className),
|
|
4287
|
+
children: items.map((item) => {
|
|
4288
|
+
const on = item.value === value;
|
|
4289
|
+
return /* @__PURE__ */ (0, import_jsx_runtime46.jsxs)(
|
|
4290
|
+
"button",
|
|
4291
|
+
{
|
|
4292
|
+
type: "button",
|
|
4293
|
+
role: "tab",
|
|
4294
|
+
id: `${idPrefix}-tab-${item.value}`,
|
|
4295
|
+
"aria-controls": `${idPrefix}-panel-${item.value}`,
|
|
4296
|
+
"aria-selected": on,
|
|
4297
|
+
tabIndex: on ? 0 : -1,
|
|
4298
|
+
disabled: item.disabled,
|
|
4299
|
+
onClick: () => onChange(item.value),
|
|
4300
|
+
className: cn(
|
|
4301
|
+
"-mb-px flex items-center gap-1.5 rounded-control border-b-2 pt-1 pb-2.5 text-sm focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-border-focus disabled:opacity-50",
|
|
4302
|
+
on ? "border-brand-primaryAction font-semibold text-text-primary" : "border-transparent text-text-secondary hover:text-text-primary"
|
|
4303
|
+
),
|
|
4304
|
+
children: [
|
|
4305
|
+
item.label,
|
|
4306
|
+
item.count !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime46.jsx)("span", { className: "text-xs text-text-tertiary", children: item.count })
|
|
4307
|
+
]
|
|
4308
|
+
},
|
|
4309
|
+
item.value
|
|
4310
|
+
);
|
|
4311
|
+
})
|
|
4312
|
+
}
|
|
4313
|
+
);
|
|
4314
|
+
}
|
|
4315
|
+
function SegmentedControl({
|
|
4316
|
+
options,
|
|
4317
|
+
value,
|
|
4318
|
+
onChange,
|
|
4319
|
+
size = "sm",
|
|
4320
|
+
className,
|
|
4321
|
+
...rest
|
|
4322
|
+
}) {
|
|
4323
|
+
const row = (0, import_react20.useRef)(null);
|
|
4324
|
+
return /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(
|
|
4325
|
+
"div",
|
|
4326
|
+
{
|
|
4327
|
+
ref: row,
|
|
4328
|
+
role: "radiogroup",
|
|
4329
|
+
"aria-label": rest["aria-label"],
|
|
4330
|
+
onKeyDown: (e) => arrowKeys(e, row.current),
|
|
4331
|
+
className: cn("inline-flex w-fit items-stretch gap-0.5 rounded-full bg-subtle p-1", size === "md" ? "h-10" : "h-8", className),
|
|
4332
|
+
children: options.map((o) => {
|
|
4333
|
+
const on = o.value === value;
|
|
4334
|
+
return /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(
|
|
4335
|
+
"button",
|
|
4336
|
+
{
|
|
4337
|
+
type: "button",
|
|
4338
|
+
role: "radio",
|
|
4339
|
+
"aria-checked": on,
|
|
4340
|
+
tabIndex: on ? 0 : -1,
|
|
4341
|
+
onClick: () => onChange(o.value),
|
|
4342
|
+
className: cn(
|
|
4343
|
+
"rounded-full px-3 focus-visible:outline-2 focus-visible:outline-offset-1 focus-visible:outline-border-focus",
|
|
4344
|
+
size === "md" ? "text-sm" : "text-xs",
|
|
4345
|
+
on ? "bg-surface font-semibold text-text-primary shadow-raised" : "text-text-secondary hover:text-text-primary"
|
|
4346
|
+
),
|
|
4347
|
+
children: o.label
|
|
4348
|
+
},
|
|
4349
|
+
o.value
|
|
4350
|
+
);
|
|
4351
|
+
})
|
|
4352
|
+
}
|
|
4353
|
+
);
|
|
4354
|
+
}
|
|
4355
|
+
|
|
4356
|
+
// src/TextField.tsx
|
|
4357
|
+
var import_react21 = require("react");
|
|
4358
|
+
var import_jsx_runtime47 = require("react/jsx-runtime");
|
|
4359
|
+
var HEIGHT2 = { sm: "h-8", md: "h-10", lg: "h-11" };
|
|
4360
|
+
var TextField = (0, import_react21.forwardRef)(
|
|
4361
|
+
({ label, hint, error, size = "md", icon, className, id, disabled, ...props }, ref) => {
|
|
4362
|
+
const auto = (0, import_react21.useId)();
|
|
4363
|
+
const fieldId = id ?? auto;
|
|
4364
|
+
const noteId = `${fieldId}-note`;
|
|
4365
|
+
const note = error ?? hint;
|
|
4366
|
+
return /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)("div", { className: cn("flex flex-col gap-1.5", className), children: [
|
|
4367
|
+
label && /* @__PURE__ */ (0, import_jsx_runtime47.jsx)("label", { htmlFor: fieldId, className: "text-xs font-medium text-text-secondary", children: label }),
|
|
4368
|
+
/* @__PURE__ */ (0, import_jsx_runtime47.jsxs)(
|
|
4369
|
+
"div",
|
|
4370
|
+
{
|
|
4371
|
+
className: cn(
|
|
4372
|
+
"flex items-center gap-2 rounded-control border bg-input px-3 focus-within:outline-2 focus-within:outline-offset-1 focus-within:outline-border-focus",
|
|
4373
|
+
HEIGHT2[size],
|
|
4374
|
+
error ? "border-status-danger" : "border-border-strong",
|
|
4375
|
+
disabled && "opacity-50"
|
|
4376
|
+
),
|
|
4377
|
+
children: [
|
|
4378
|
+
icon && /* @__PURE__ */ (0, import_jsx_runtime47.jsx)("span", { "aria-hidden": "true", className: "flex shrink-0 text-text-tertiary", children: icon }),
|
|
4379
|
+
/* @__PURE__ */ (0, import_jsx_runtime47.jsx)(
|
|
4380
|
+
"input",
|
|
4381
|
+
{
|
|
4382
|
+
ref,
|
|
4383
|
+
id: fieldId,
|
|
4384
|
+
disabled,
|
|
4385
|
+
"aria-invalid": error ? true : void 0,
|
|
4386
|
+
"aria-describedby": note ? noteId : void 0,
|
|
4387
|
+
className: "min-w-0 flex-1 bg-transparent text-dense text-text-primary outline-hidden placeholder:text-text-tertiary",
|
|
4388
|
+
...props
|
|
4389
|
+
}
|
|
4390
|
+
)
|
|
4391
|
+
]
|
|
4392
|
+
}
|
|
4393
|
+
),
|
|
4394
|
+
note && /* @__PURE__ */ (0, import_jsx_runtime47.jsx)("p", { id: noteId, className: cn("text-xs", error ? "text-text-danger" : "text-text-tertiary"), children: note })
|
|
4395
|
+
] });
|
|
4396
|
+
}
|
|
4397
|
+
);
|
|
4398
|
+
TextField.displayName = "TextField";
|
|
4093
4399
|
// Annotate the CommonJS export names for ESM import in node:
|
|
4094
4400
|
0 && (module.exports = {
|
|
4095
4401
|
AISpark,
|
|
@@ -4108,11 +4414,13 @@ function PageHeader({ title, description, actions, className }) {
|
|
|
4108
4414
|
DateRangeFilter,
|
|
4109
4415
|
DateRangePicker,
|
|
4110
4416
|
Delta,
|
|
4417
|
+
EmptyState,
|
|
4111
4418
|
FilterChipBar,
|
|
4112
4419
|
FilterDropdownFooter,
|
|
4113
4420
|
Freshness,
|
|
4114
4421
|
InfoTip,
|
|
4115
4422
|
LineChartPlaceholder,
|
|
4423
|
+
Modal,
|
|
4116
4424
|
MultiSelectFilter,
|
|
4117
4425
|
NO_RESULTS_BODY,
|
|
4118
4426
|
NO_RESULTS_TITLE,
|
|
@@ -4127,6 +4435,7 @@ function PageHeader({ title, description, actions, className }) {
|
|
|
4127
4435
|
SearchBar,
|
|
4128
4436
|
SectionHeading,
|
|
4129
4437
|
SectionRail,
|
|
4438
|
+
SegmentedControl,
|
|
4130
4439
|
SelectAllVisible,
|
|
4131
4440
|
SelectFilter,
|
|
4132
4441
|
SelectedSection,
|
|
@@ -4134,7 +4443,9 @@ function PageHeader({ title, description, actions, className }) {
|
|
|
4134
4443
|
SortButton,
|
|
4135
4444
|
StackedColumnPlaceholder,
|
|
4136
4445
|
TablePagination,
|
|
4446
|
+
Tabs,
|
|
4137
4447
|
Tag,
|
|
4448
|
+
TextField,
|
|
4138
4449
|
Toast,
|
|
4139
4450
|
Toggle,
|
|
4140
4451
|
Tooltip,
|