@mediaradar/design-components 0.7.0 → 0.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/index.cjs +621 -0
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +233 -3
- package/dist/index.d.ts +233 -3
- package/dist/index.js +613 -0
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -20,6 +20,7 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
20
20
|
// src/index.ts
|
|
21
21
|
var index_exports = {};
|
|
22
22
|
__export(index_exports, {
|
|
23
|
+
AISpark: () => AISpark,
|
|
23
24
|
AdvertiserNoResults: () => AdvertiserNoResults,
|
|
24
25
|
AdvertiserQuickFilter: () => AdvertiserQuickFilter,
|
|
25
26
|
AdvertiserSearchPrompt: () => AdvertiserSearchPrompt,
|
|
@@ -31,10 +32,13 @@ __export(index_exports, {
|
|
|
31
32
|
DEFAULT_SEARCH_MATCH: () => DEFAULT_SEARCH_MATCH,
|
|
32
33
|
DataScopeFilter: () => DataScopeFilter,
|
|
33
34
|
DateRangeFilter: () => DateRangeFilter,
|
|
35
|
+
DateRangePicker: () => DateRangePicker,
|
|
34
36
|
FilterChipBar: () => FilterChipBar,
|
|
35
37
|
FilterDropdownFooter: () => FilterDropdownFooter,
|
|
38
|
+
Freshness: () => Freshness,
|
|
36
39
|
InfoTip: () => InfoTip,
|
|
37
40
|
LineChartPlaceholder: () => LineChartPlaceholder,
|
|
41
|
+
MultiSelectFilter: () => MultiSelectFilter,
|
|
38
42
|
NO_RESULTS_BODY: () => NO_RESULTS_BODY,
|
|
39
43
|
NO_RESULTS_TITLE: () => NO_RESULTS_TITLE,
|
|
40
44
|
NameListModal: () => NameListModal,
|
|
@@ -52,6 +56,9 @@ __export(index_exports, {
|
|
|
52
56
|
SelectionPicker: () => SelectionPicker,
|
|
53
57
|
SortButton: () => SortButton,
|
|
54
58
|
StackedColumnPlaceholder: () => StackedColumnPlaceholder,
|
|
59
|
+
TablePagination: () => TablePagination,
|
|
60
|
+
Tag: () => Tag,
|
|
61
|
+
Toggle: () => Toggle,
|
|
55
62
|
Tooltip: () => Tooltip,
|
|
56
63
|
WorkspaceAvatar: () => WorkspaceAvatar,
|
|
57
64
|
WorkspaceSelectedCard: () => WorkspaceSelectedCard,
|
|
@@ -59,6 +66,7 @@ __export(index_exports, {
|
|
|
59
66
|
chipTriggerClass: () => chipTriggerClass,
|
|
60
67
|
cycleSort: () => cycleSort,
|
|
61
68
|
noResultsBody: () => noResultsBody,
|
|
69
|
+
resolveRange: () => resolveRange,
|
|
62
70
|
sortProp: () => sortProp
|
|
63
71
|
});
|
|
64
72
|
module.exports = __toCommonJS(index_exports);
|
|
@@ -2976,8 +2984,614 @@ function WorkspaceAvatar({ name, size = "md" }) {
|
|
|
2976
2984
|
}
|
|
2977
2985
|
);
|
|
2978
2986
|
}
|
|
2987
|
+
|
|
2988
|
+
// src/Tag.tsx
|
|
2989
|
+
var import_jsx_runtime32 = require("react/jsx-runtime");
|
|
2990
|
+
function Tag({ children, className }) {
|
|
2991
|
+
return /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
|
|
2992
|
+
"span",
|
|
2993
|
+
{
|
|
2994
|
+
className: cn(
|
|
2995
|
+
"inline-flex items-center whitespace-nowrap rounded-full bg-subtle px-2 py-0.5 text-[11px] font-medium text-text-secondary",
|
|
2996
|
+
className
|
|
2997
|
+
),
|
|
2998
|
+
children
|
|
2999
|
+
}
|
|
3000
|
+
);
|
|
3001
|
+
}
|
|
3002
|
+
|
|
3003
|
+
// src/TablePagination.tsx
|
|
3004
|
+
var import_lucide_react19 = require("lucide-react");
|
|
3005
|
+
var import_jsx_runtime33 = require("react/jsx-runtime");
|
|
3006
|
+
function TablePagination({
|
|
3007
|
+
page,
|
|
3008
|
+
perPage,
|
|
3009
|
+
totalItems,
|
|
3010
|
+
onPageChange,
|
|
3011
|
+
onPerPageChange,
|
|
3012
|
+
perPageOptions = [25, 50, 100],
|
|
3013
|
+
itemLabel = "results",
|
|
3014
|
+
className
|
|
3015
|
+
}) {
|
|
3016
|
+
const totalPages = Math.max(1, Math.ceil(totalItems / perPage));
|
|
3017
|
+
const current = Math.min(page, totalPages);
|
|
3018
|
+
const rangeStart = totalItems === 0 ? 0 : (current - 1) * perPage + 1;
|
|
3019
|
+
const rangeEnd = Math.min(current * perPage, totalItems);
|
|
3020
|
+
const btn = "flex h-8 min-w-8 items-center justify-center rounded-control px-2 text-[13px] transition-colors";
|
|
3021
|
+
const stepBtn = cn(
|
|
3022
|
+
btn,
|
|
3023
|
+
"text-text-secondary hover:bg-subtle hover:text-text-primary disabled:pointer-events-none disabled:opacity-30"
|
|
3024
|
+
);
|
|
3025
|
+
return /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)("div", { className: cn("flex flex-wrap items-center justify-between gap-x-4 gap-y-2", className), children: [
|
|
3026
|
+
/* @__PURE__ */ (0, import_jsx_runtime33.jsxs)("label", { className: "flex items-center gap-2 text-[13px] text-text-secondary", children: [
|
|
3027
|
+
/* @__PURE__ */ (0, import_jsx_runtime33.jsxs)("span", { className: "relative", children: [
|
|
3028
|
+
/* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
|
|
3029
|
+
"select",
|
|
3030
|
+
{
|
|
3031
|
+
value: perPage,
|
|
3032
|
+
onChange: (e) => onPerPageChange(Number(e.target.value)),
|
|
3033
|
+
"aria-label": "Items per page",
|
|
3034
|
+
className: "appearance-none rounded-control border border-border-default bg-input py-1 pl-2.5 pr-7 text-[13px] font-medium text-text-primary focus:outline focus:outline-2 focus:outline-border-focus",
|
|
3035
|
+
children: perPageOptions.map((n) => /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("option", { value: n, children: n }, n))
|
|
3036
|
+
}
|
|
3037
|
+
),
|
|
3038
|
+
/* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
|
|
3039
|
+
import_lucide_react19.ChevronDown,
|
|
3040
|
+
{
|
|
3041
|
+
size: 13,
|
|
3042
|
+
"aria-hidden": "true",
|
|
3043
|
+
className: "pointer-events-none absolute right-2 top-1/2 -translate-y-1/2 text-text-secondary"
|
|
3044
|
+
}
|
|
3045
|
+
)
|
|
3046
|
+
] }),
|
|
3047
|
+
"items per page"
|
|
3048
|
+
] }),
|
|
3049
|
+
/* @__PURE__ */ (0, import_jsx_runtime33.jsxs)("nav", { className: "flex items-center gap-1", "aria-label": "Pagination", children: [
|
|
3050
|
+
/* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
|
|
3051
|
+
"button",
|
|
3052
|
+
{
|
|
3053
|
+
type: "button",
|
|
3054
|
+
onClick: () => onPageChange(1),
|
|
3055
|
+
disabled: current === 1,
|
|
3056
|
+
"aria-label": "First page",
|
|
3057
|
+
className: stepBtn,
|
|
3058
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(import_lucide_react19.ChevronFirst, { size: 16, "aria-hidden": "true" })
|
|
3059
|
+
}
|
|
3060
|
+
),
|
|
3061
|
+
/* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
|
|
3062
|
+
"button",
|
|
3063
|
+
{
|
|
3064
|
+
type: "button",
|
|
3065
|
+
onClick: () => onPageChange(current - 1),
|
|
3066
|
+
disabled: current === 1,
|
|
3067
|
+
"aria-label": "Previous page",
|
|
3068
|
+
className: stepBtn,
|
|
3069
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(import_lucide_react19.ChevronLeft, { size: 16, "aria-hidden": "true" })
|
|
3070
|
+
}
|
|
3071
|
+
),
|
|
3072
|
+
pageWindow(current, totalPages).map(
|
|
3073
|
+
(p) => typeof p === "string" ? /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("span", { className: "px-1 text-[13px] text-text-tertiary", children: "\u2026" }, p) : /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
|
|
3074
|
+
"button",
|
|
3075
|
+
{
|
|
3076
|
+
type: "button",
|
|
3077
|
+
onClick: () => onPageChange(p),
|
|
3078
|
+
"aria-current": p === current ? "page" : void 0,
|
|
3079
|
+
className: cn(
|
|
3080
|
+
btn,
|
|
3081
|
+
p === current ? "bg-brand-primaryAction font-semibold text-brand-onprimary" : "text-text-secondary hover:bg-subtle hover:text-text-primary"
|
|
3082
|
+
),
|
|
3083
|
+
children: p
|
|
3084
|
+
},
|
|
3085
|
+
p
|
|
3086
|
+
)
|
|
3087
|
+
),
|
|
3088
|
+
/* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
|
|
3089
|
+
"button",
|
|
3090
|
+
{
|
|
3091
|
+
type: "button",
|
|
3092
|
+
onClick: () => onPageChange(current + 1),
|
|
3093
|
+
disabled: current === totalPages,
|
|
3094
|
+
"aria-label": "Next page",
|
|
3095
|
+
className: stepBtn,
|
|
3096
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(import_lucide_react19.ChevronRight, { size: 16, "aria-hidden": "true" })
|
|
3097
|
+
}
|
|
3098
|
+
),
|
|
3099
|
+
/* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
|
|
3100
|
+
"button",
|
|
3101
|
+
{
|
|
3102
|
+
type: "button",
|
|
3103
|
+
onClick: () => onPageChange(totalPages),
|
|
3104
|
+
disabled: current === totalPages,
|
|
3105
|
+
"aria-label": "Last page",
|
|
3106
|
+
className: stepBtn,
|
|
3107
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(import_lucide_react19.ChevronLast, { size: 16, "aria-hidden": "true" })
|
|
3108
|
+
}
|
|
3109
|
+
)
|
|
3110
|
+
] }),
|
|
3111
|
+
/* @__PURE__ */ (0, import_jsx_runtime33.jsxs)("span", { className: "text-[13px] text-text-tertiary tabular-nums", children: [
|
|
3112
|
+
rangeStart.toLocaleString(),
|
|
3113
|
+
" \u2013 ",
|
|
3114
|
+
rangeEnd.toLocaleString(),
|
|
3115
|
+
" of ",
|
|
3116
|
+
totalItems.toLocaleString(),
|
|
3117
|
+
" ",
|
|
3118
|
+
itemLabel
|
|
3119
|
+
] })
|
|
3120
|
+
] });
|
|
3121
|
+
}
|
|
3122
|
+
|
|
3123
|
+
// src/DateRangePicker.tsx
|
|
3124
|
+
var import_react15 = require("react");
|
|
3125
|
+
var import_lucide_react20 = require("lucide-react");
|
|
3126
|
+
var import_jsx_runtime34 = require("react/jsx-runtime");
|
|
3127
|
+
var MONTH_ABBR = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"];
|
|
3128
|
+
var PRESETS = ["Rolling 3 months", "Rolling 6 months", "Rolling 12 months"];
|
|
3129
|
+
var startOfToday = () => {
|
|
3130
|
+
const d = /* @__PURE__ */ new Date();
|
|
3131
|
+
return new Date(d.getFullYear(), d.getMonth(), d.getDate());
|
|
3132
|
+
};
|
|
3133
|
+
var fmtDate = (d) => d.toLocaleDateString("en-US", { month: "short", day: "numeric", year: "numeric" });
|
|
3134
|
+
function resolveRange(label, today = startOfToday()) {
|
|
3135
|
+
const end = today;
|
|
3136
|
+
const mMonths = label.match(/Rolling (\d+) months/);
|
|
3137
|
+
if (mMonths) {
|
|
3138
|
+
return [new Date(end.getFullYear(), end.getMonth() - Number(mMonths[1]), 1), end];
|
|
3139
|
+
}
|
|
3140
|
+
const mQuarters = label.match(/Rolling (\d+) quarters/);
|
|
3141
|
+
if (mQuarters) {
|
|
3142
|
+
return [new Date(end.getFullYear(), end.getMonth() - Number(mQuarters[1]) * 3, 1), end];
|
|
3143
|
+
}
|
|
3144
|
+
const mYears = label.match(/Rolling (\d+) years/);
|
|
3145
|
+
if (mYears) {
|
|
3146
|
+
return [new Date(end.getFullYear() - Number(mYears[1]), end.getMonth(), 1), end];
|
|
3147
|
+
}
|
|
3148
|
+
const mCustom = label.match(/([A-Za-z]{3})\s+(\d{4}).*?([A-Za-z]{3})\s+(\d{4})/);
|
|
3149
|
+
if (mCustom) {
|
|
3150
|
+
const s = new Date(Number(mCustom[2]), MONTH_ABBR.indexOf(mCustom[1]), 1);
|
|
3151
|
+
const e = new Date(Number(mCustom[4]), MONTH_ABBR.indexOf(mCustom[3]) + 1, 0);
|
|
3152
|
+
return [s, e];
|
|
3153
|
+
}
|
|
3154
|
+
return [new Date(end.getFullYear(), end.getMonth() - 6, 1), end];
|
|
3155
|
+
}
|
|
3156
|
+
function spanLabel(label, today) {
|
|
3157
|
+
const [s, e] = resolveRange(label, today);
|
|
3158
|
+
return `${fmtDate(s)} \u2013 ${fmtDate(e)}`;
|
|
3159
|
+
}
|
|
3160
|
+
function MiniSelect({ value, onChange, options }) {
|
|
3161
|
+
return /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
|
|
3162
|
+
"select",
|
|
3163
|
+
{
|
|
3164
|
+
value: String(value),
|
|
3165
|
+
onChange: (e) => {
|
|
3166
|
+
const opt = options.find((o) => String(o.value) === e.target.value);
|
|
3167
|
+
if (opt) onChange(opt.value);
|
|
3168
|
+
},
|
|
3169
|
+
className: "rounded-control border border-border-default bg-input px-1.5 py-1 text-[12px] text-text-primary outline-hidden focus:border-border-focus",
|
|
3170
|
+
children: options.map((o) => /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("option", { value: String(o.value), children: o.label }, String(o.value)))
|
|
3171
|
+
}
|
|
3172
|
+
);
|
|
3173
|
+
}
|
|
3174
|
+
function DateRangePicker({
|
|
3175
|
+
defaultValue = "Rolling 6 months",
|
|
3176
|
+
align = "left",
|
|
3177
|
+
presets = PRESETS,
|
|
3178
|
+
onChange,
|
|
3179
|
+
onRangeChange,
|
|
3180
|
+
showFooter = false,
|
|
3181
|
+
today,
|
|
3182
|
+
years
|
|
3183
|
+
}) {
|
|
3184
|
+
const end = (0, import_react15.useMemo)(() => today ?? startOfToday(), [today]);
|
|
3185
|
+
const yearOptions = years ?? [3, 2, 1, 0].map((n) => end.getFullYear() - n);
|
|
3186
|
+
const [open, setOpen] = (0, import_react15.useState)(false);
|
|
3187
|
+
const [value, setValue] = (0, import_react15.useState)(defaultValue);
|
|
3188
|
+
const [draft, setDraft] = (0, import_react15.useState)(defaultValue);
|
|
3189
|
+
const ref = (0, import_react15.useRef)(null);
|
|
3190
|
+
const [fromMo, setFromMo] = (0, import_react15.useState)(end.getMonth());
|
|
3191
|
+
const [fromYr, setFromYr] = (0, import_react15.useState)(end.getFullYear() - 1);
|
|
3192
|
+
const [toMo, setToMo] = (0, import_react15.useState)(end.getMonth());
|
|
3193
|
+
const [toYr, setToYr] = (0, import_react15.useState)(end.getFullYear());
|
|
3194
|
+
(0, import_react15.useEffect)(() => {
|
|
3195
|
+
const [s, e] = resolveRange(value, end);
|
|
3196
|
+
onRangeChange?.(s, e);
|
|
3197
|
+
}, [value]);
|
|
3198
|
+
const toggleOpen = () => {
|
|
3199
|
+
if (!open) setDraft(value);
|
|
3200
|
+
setOpen((o) => !o);
|
|
3201
|
+
};
|
|
3202
|
+
(0, import_react15.useEffect)(() => {
|
|
3203
|
+
if (!open) return;
|
|
3204
|
+
const onDown = (e) => {
|
|
3205
|
+
if (ref.current && !ref.current.contains(e.target)) setOpen(false);
|
|
3206
|
+
};
|
|
3207
|
+
const onKey = (e) => e.key === "Escape" && setOpen(false);
|
|
3208
|
+
window.addEventListener("mousedown", onDown);
|
|
3209
|
+
window.addEventListener("keydown", onKey);
|
|
3210
|
+
return () => {
|
|
3211
|
+
window.removeEventListener("mousedown", onDown);
|
|
3212
|
+
window.removeEventListener("keydown", onKey);
|
|
3213
|
+
};
|
|
3214
|
+
}, [open]);
|
|
3215
|
+
const commit = (label) => {
|
|
3216
|
+
setValue(label);
|
|
3217
|
+
onChange?.(label);
|
|
3218
|
+
setOpen(false);
|
|
3219
|
+
};
|
|
3220
|
+
const span = toYr * 12 + toMo - (fromYr * 12 + fromMo) + 1;
|
|
3221
|
+
const valid = span >= 1;
|
|
3222
|
+
const applyCustom = () => {
|
|
3223
|
+
if (!valid) return;
|
|
3224
|
+
const label = `${MONTH_ABBR[fromMo]} ${fromYr} \u2013 ${MONTH_ABBR[toMo]} ${toYr}`;
|
|
3225
|
+
if (showFooter) setDraft(label);
|
|
3226
|
+
else commit(label);
|
|
3227
|
+
};
|
|
3228
|
+
return /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)("div", { className: "relative", ref, children: [
|
|
3229
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsxs)(
|
|
3230
|
+
"button",
|
|
3231
|
+
{
|
|
3232
|
+
type: "button",
|
|
3233
|
+
onClick: toggleOpen,
|
|
3234
|
+
"aria-expanded": open,
|
|
3235
|
+
"aria-haspopup": "listbox",
|
|
3236
|
+
className: chipTriggerClass(),
|
|
3237
|
+
children: [
|
|
3238
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsxs)("span", { className: "flex flex-col gap-1 text-left leading-none", children: [
|
|
3239
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsx)("span", { className: "text-[10px] text-text-tertiary", children: spanLabel(value, end) }),
|
|
3240
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsx)("span", { className: "text-[12px] font-medium text-text-primary", children: value })
|
|
3241
|
+
] }),
|
|
3242
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsx)(import_lucide_react20.ChevronDown, { size: 14, "aria-hidden": "true", className: cn("shrink-0 text-text-secondary transition-transform", open && "rotate-180") })
|
|
3243
|
+
]
|
|
3244
|
+
}
|
|
3245
|
+
),
|
|
3246
|
+
open && /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)("div", { className: cn("absolute top-[calc(100%+8px)] z-30 w-[280px] overflow-hidden rounded-card border border-border-default bg-surface py-1 shadow-overlay", align === "right" ? "right-0" : "left-0"), children: [
|
|
3247
|
+
presets.map((p) => /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
|
|
3248
|
+
"button",
|
|
3249
|
+
{
|
|
3250
|
+
type: "button",
|
|
3251
|
+
onClick: () => showFooter ? setDraft(p) : commit(p),
|
|
3252
|
+
className: cn("block w-full px-3 py-2 text-left text-[13px] transition-colors hover:bg-subtle", (showFooter ? draft : value) === p ? "font-semibold text-brand-primaryAction" : "text-text-secondary"),
|
|
3253
|
+
children: p
|
|
3254
|
+
},
|
|
3255
|
+
p
|
|
3256
|
+
)),
|
|
3257
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsxs)("div", { className: "mt-1 border-t border-border-default px-3 pb-2 pt-2", children: [
|
|
3258
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsx)("div", { className: "text-[13px] font-semibold text-text-primary", children: "Custom Range" }),
|
|
3259
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsxs)("div", { className: "mt-2 flex flex-col gap-2", children: [
|
|
3260
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsxs)("label", { className: "flex items-center justify-between gap-2 text-[12px] text-text-secondary", children: [
|
|
3261
|
+
"From",
|
|
3262
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsxs)("span", { className: "flex gap-1", children: [
|
|
3263
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsx)(MiniSelect, { value: fromMo, onChange: setFromMo, options: MONTH_ABBR.map((mm, i) => ({ label: mm, value: i })) }),
|
|
3264
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsx)(MiniSelect, { value: fromYr, onChange: setFromYr, options: yearOptions.map((y) => ({ label: String(y), value: y })) })
|
|
3265
|
+
] })
|
|
3266
|
+
] }),
|
|
3267
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsxs)("label", { className: "flex items-center justify-between gap-2 text-[12px] text-text-secondary", children: [
|
|
3268
|
+
"To",
|
|
3269
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsxs)("span", { className: "flex gap-1", children: [
|
|
3270
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsx)(MiniSelect, { value: toMo, onChange: setToMo, options: MONTH_ABBR.map((mm, i) => ({ label: mm, value: i })) }),
|
|
3271
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsx)(MiniSelect, { value: toYr, onChange: setToYr, options: yearOptions.map((y) => ({ label: String(y), value: y })) })
|
|
3272
|
+
] })
|
|
3273
|
+
] }),
|
|
3274
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
|
|
3275
|
+
"button",
|
|
3276
|
+
{
|
|
3277
|
+
type: "button",
|
|
3278
|
+
onClick: applyCustom,
|
|
3279
|
+
disabled: !valid,
|
|
3280
|
+
className: "self-start text-[13px] font-semibold text-brand-primaryAction transition-opacity hover:opacity-80 disabled:cursor-not-allowed disabled:opacity-40",
|
|
3281
|
+
children: showFooter ? "Use custom range" : "Apply"
|
|
3282
|
+
}
|
|
3283
|
+
)
|
|
3284
|
+
] })
|
|
3285
|
+
] }),
|
|
3286
|
+
showFooter && /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(FilterDropdownFooter, { onApply: () => commit(draft) })
|
|
3287
|
+
] })
|
|
3288
|
+
] });
|
|
3289
|
+
}
|
|
3290
|
+
|
|
3291
|
+
// src/MultiSelectFilter.tsx
|
|
3292
|
+
var import_react16 = require("react");
|
|
3293
|
+
var import_lucide_react21 = require("lucide-react");
|
|
3294
|
+
var import_jsx_runtime35 = require("react/jsx-runtime");
|
|
3295
|
+
function MultiSelectFilter({
|
|
3296
|
+
caption,
|
|
3297
|
+
options = [],
|
|
3298
|
+
groups,
|
|
3299
|
+
selected,
|
|
3300
|
+
onChange,
|
|
3301
|
+
allLabel = "All",
|
|
3302
|
+
searchable = false,
|
|
3303
|
+
searchPlaceholder,
|
|
3304
|
+
align = "left",
|
|
3305
|
+
fullIsAll = false,
|
|
3306
|
+
min = 0,
|
|
3307
|
+
icon,
|
|
3308
|
+
showFooter = false,
|
|
3309
|
+
clearValue = [],
|
|
3310
|
+
menuWidthClass = "w-60",
|
|
3311
|
+
plainParent = false,
|
|
3312
|
+
fullWidth = false
|
|
3313
|
+
}) {
|
|
3314
|
+
const groupLeaves = (g) => g.children.length ? g.children : [{ id: g.id, label: g.label }];
|
|
3315
|
+
const leafOptions = groups ? groups.flatMap(groupLeaves) : options;
|
|
3316
|
+
const [open, setOpen] = (0, import_react16.useState)(false);
|
|
3317
|
+
const [q, setQ] = (0, import_react16.useState)("");
|
|
3318
|
+
const [draft, setDraft] = (0, import_react16.useState)(selected);
|
|
3319
|
+
const ref = (0, import_react16.useRef)(null);
|
|
3320
|
+
const close = (0, import_react16.useCallback)(() => {
|
|
3321
|
+
setOpen(false);
|
|
3322
|
+
setQ("");
|
|
3323
|
+
if (showFooter) return;
|
|
3324
|
+
if (draft.length !== selected.length || draft.some((id) => !selected.includes(id))) {
|
|
3325
|
+
onChange(draft);
|
|
3326
|
+
}
|
|
3327
|
+
}, [draft, selected, onChange, showFooter]);
|
|
3328
|
+
const openTray = () => {
|
|
3329
|
+
setDraft(selected);
|
|
3330
|
+
setOpen(true);
|
|
3331
|
+
};
|
|
3332
|
+
const apply = () => {
|
|
3333
|
+
onChange(draft);
|
|
3334
|
+
setOpen(false);
|
|
3335
|
+
setQ("");
|
|
3336
|
+
};
|
|
3337
|
+
(0, import_react16.useEffect)(() => {
|
|
3338
|
+
if (!open) return;
|
|
3339
|
+
const onKey = (e) => e.key === "Escape" && close();
|
|
3340
|
+
const onClick = (e) => {
|
|
3341
|
+
if (ref.current && !ref.current.contains(e.target)) close();
|
|
3342
|
+
};
|
|
3343
|
+
window.addEventListener("keydown", onKey);
|
|
3344
|
+
window.addEventListener("mousedown", onClick);
|
|
3345
|
+
return () => {
|
|
3346
|
+
window.removeEventListener("keydown", onKey);
|
|
3347
|
+
window.removeEventListener("mousedown", onClick);
|
|
3348
|
+
};
|
|
3349
|
+
}, [open, close]);
|
|
3350
|
+
const toggle = (id) => setDraft((cur) => {
|
|
3351
|
+
const next = cur.includes(id) ? cur.filter((x) => x !== id) : [...cur, id];
|
|
3352
|
+
if (next.length < min) return cur;
|
|
3353
|
+
return next;
|
|
3354
|
+
});
|
|
3355
|
+
const toggleGroup = (g) => setDraft((cur) => {
|
|
3356
|
+
const ids = groupLeaves(g).map((c) => c.id);
|
|
3357
|
+
const allSel = ids.every((id) => cur.includes(id));
|
|
3358
|
+
const next = allSel ? cur.filter((id) => !ids.includes(id)) : [.../* @__PURE__ */ new Set([...cur, ...ids])];
|
|
3359
|
+
if (next.length < min) return cur;
|
|
3360
|
+
return next;
|
|
3361
|
+
});
|
|
3362
|
+
const groupState = (g) => {
|
|
3363
|
+
const ids = groupLeaves(g).map((c) => c.id);
|
|
3364
|
+
const sel = ids.filter((id) => draft.includes(id)).length;
|
|
3365
|
+
return sel === 0 ? "none" : sel === ids.length ? "all" : "some";
|
|
3366
|
+
};
|
|
3367
|
+
const shown = open && !showFooter ? draft : selected;
|
|
3368
|
+
const isAll = shown.length === 0 || fullIsAll && shown.length === leafOptions.length;
|
|
3369
|
+
const value = isAll ? allLabel : shown.length === 1 ? leafOptions.find((o) => o.id === shown[0])?.label ?? `${shown.length} selected` : `${shown.length} selected`;
|
|
3370
|
+
const ql = q.trim().toLowerCase();
|
|
3371
|
+
const items = options.filter((o) => !ql || o.label.toLowerCase().includes(ql));
|
|
3372
|
+
const visibleGroups = groups ? groups.map((g) => {
|
|
3373
|
+
if (!ql || g.label.toLowerCase().includes(ql)) return g;
|
|
3374
|
+
const kids = g.children.filter((c) => c.label.toLowerCase().includes(ql));
|
|
3375
|
+
return kids.length ? { ...g, children: kids } : null;
|
|
3376
|
+
}).filter((g) => g !== null) : [];
|
|
3377
|
+
return /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)("div", { className: cn("relative", fullWidth && "w-full"), ref, children: [
|
|
3378
|
+
/* @__PURE__ */ (0, import_jsx_runtime35.jsxs)(
|
|
3379
|
+
"button",
|
|
3380
|
+
{
|
|
3381
|
+
type: "button",
|
|
3382
|
+
onClick: () => open ? close() : openTray(),
|
|
3383
|
+
"aria-expanded": open,
|
|
3384
|
+
className: cn(chipTriggerClass(), fullWidth && "w-full justify-between"),
|
|
3385
|
+
children: [
|
|
3386
|
+
/* @__PURE__ */ (0, import_jsx_runtime35.jsx)(ChipContent, { caption, value, icon }),
|
|
3387
|
+
/* @__PURE__ */ (0, import_jsx_runtime35.jsx)(
|
|
3388
|
+
import_lucide_react21.ChevronDown,
|
|
3389
|
+
{
|
|
3390
|
+
size: 14,
|
|
3391
|
+
"aria-hidden": "true",
|
|
3392
|
+
className: cn("shrink-0 text-text-secondary transition-transform", open && "rotate-180")
|
|
3393
|
+
}
|
|
3394
|
+
)
|
|
3395
|
+
]
|
|
3396
|
+
}
|
|
3397
|
+
),
|
|
3398
|
+
open && /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)(
|
|
3399
|
+
"div",
|
|
3400
|
+
{
|
|
3401
|
+
className: cn(
|
|
3402
|
+
"absolute top-[calc(100%+8px)] z-30 flex flex-col overflow-hidden rounded-card border border-border-default bg-surface shadow-overlay",
|
|
3403
|
+
menuWidthClass,
|
|
3404
|
+
align === "right" ? "right-0" : "left-0"
|
|
3405
|
+
),
|
|
3406
|
+
role: "dialog",
|
|
3407
|
+
"aria-label": caption,
|
|
3408
|
+
children: [
|
|
3409
|
+
searchable && /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("div", { className: "border-b border-border-default p-2", children: /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)("div", { className: "flex h-9 items-center gap-2 rounded-control border border-border-default bg-input px-2.5", children: [
|
|
3410
|
+
/* @__PURE__ */ (0, import_jsx_runtime35.jsx)(import_lucide_react21.Search, { size: 14, className: "text-text-secondary", "aria-hidden": "true" }),
|
|
3411
|
+
/* @__PURE__ */ (0, import_jsx_runtime35.jsx)(
|
|
3412
|
+
"input",
|
|
3413
|
+
{
|
|
3414
|
+
type: "text",
|
|
3415
|
+
value: q,
|
|
3416
|
+
onChange: (e) => setQ(e.target.value),
|
|
3417
|
+
placeholder: searchPlaceholder ?? `Search ${caption.toLowerCase()}`,
|
|
3418
|
+
className: "h-full flex-1 bg-transparent text-[13px] outline-hidden placeholder:text-text-tertiary"
|
|
3419
|
+
}
|
|
3420
|
+
),
|
|
3421
|
+
q && /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("button", { type: "button", onClick: () => setQ(""), "aria-label": "Clear search", className: "text-text-tertiary hover:text-text-primary", children: /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(import_lucide_react21.X, { size: 13 }) })
|
|
3422
|
+
] }) }),
|
|
3423
|
+
/* @__PURE__ */ (0, import_jsx_runtime35.jsxs)("div", { className: "max-h-[280px] overflow-y-auto p-1", children: [
|
|
3424
|
+
groups ? visibleGroups.map((g) => {
|
|
3425
|
+
const state = groupState(g);
|
|
3426
|
+
return /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)("div", { children: [
|
|
3427
|
+
/* @__PURE__ */ (0, import_jsx_runtime35.jsxs)(
|
|
3428
|
+
"button",
|
|
3429
|
+
{
|
|
3430
|
+
type: "button",
|
|
3431
|
+
onClick: () => toggleGroup(g),
|
|
3432
|
+
className: "flex w-full items-center gap-2.5 rounded-control px-2 py-2 text-left transition-colors hover:bg-subtle",
|
|
3433
|
+
children: [
|
|
3434
|
+
/* @__PURE__ */ (0, import_jsx_runtime35.jsx)(TriCheck, { state }),
|
|
3435
|
+
/* @__PURE__ */ (0, import_jsx_runtime35.jsx)("span", { className: cn("flex-1 text-[14px] text-text-primary", !plainParent && "font-semibold"), children: g.label })
|
|
3436
|
+
]
|
|
3437
|
+
}
|
|
3438
|
+
),
|
|
3439
|
+
g.children.map((c) => {
|
|
3440
|
+
const checked = draft.includes(c.id);
|
|
3441
|
+
return /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)(
|
|
3442
|
+
"button",
|
|
3443
|
+
{
|
|
3444
|
+
type: "button",
|
|
3445
|
+
onClick: () => toggle(c.id),
|
|
3446
|
+
className: "flex w-full items-center gap-2.5 rounded-control py-2 pl-9 pr-2 text-left transition-colors hover:bg-subtle",
|
|
3447
|
+
children: [
|
|
3448
|
+
/* @__PURE__ */ (0, import_jsx_runtime35.jsx)(TriCheck, { state: checked ? "all" : "none" }),
|
|
3449
|
+
/* @__PURE__ */ (0, import_jsx_runtime35.jsx)("span", { className: "flex-1 text-[14px] text-text-primary", children: c.label })
|
|
3450
|
+
]
|
|
3451
|
+
},
|
|
3452
|
+
c.id
|
|
3453
|
+
);
|
|
3454
|
+
})
|
|
3455
|
+
] }, g.id);
|
|
3456
|
+
}) : items.map((o) => {
|
|
3457
|
+
const checked = draft.includes(o.id);
|
|
3458
|
+
return /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)(
|
|
3459
|
+
"button",
|
|
3460
|
+
{
|
|
3461
|
+
type: "button",
|
|
3462
|
+
onClick: () => toggle(o.id),
|
|
3463
|
+
className: "flex w-full items-center gap-2.5 rounded-control px-2 py-2 text-left transition-colors hover:bg-subtle",
|
|
3464
|
+
children: [
|
|
3465
|
+
/* @__PURE__ */ (0, import_jsx_runtime35.jsx)(
|
|
3466
|
+
"span",
|
|
3467
|
+
{
|
|
3468
|
+
className: cn(
|
|
3469
|
+
"flex h-[18px] w-[18px] shrink-0 items-center justify-center rounded-[5px] border transition-colors",
|
|
3470
|
+
checked ? "border-transparent bg-brand-primaryAction text-brand-onprimary" : "border-border-interactive bg-input"
|
|
3471
|
+
),
|
|
3472
|
+
children: checked && /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(import_lucide_react21.Check, { size: 13, strokeWidth: 3 })
|
|
3473
|
+
}
|
|
3474
|
+
),
|
|
3475
|
+
/* @__PURE__ */ (0, import_jsx_runtime35.jsx)("span", { className: "flex-1 text-[14px] text-text-primary", children: o.label })
|
|
3476
|
+
]
|
|
3477
|
+
},
|
|
3478
|
+
o.id
|
|
3479
|
+
);
|
|
3480
|
+
}),
|
|
3481
|
+
(groups && !visibleGroups.length || !groups && !items.length) && /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("div", { className: "py-6 text-center text-[13px] text-text-tertiary", children: "No matches." })
|
|
3482
|
+
] }),
|
|
3483
|
+
showFooter ? /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(FilterDropdownFooter, { onClear: () => setDraft(clearValue), onApply: apply }) : min === 0 && draft.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("div", { className: "border-t border-border-default p-2", children: /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)(
|
|
3484
|
+
"button",
|
|
3485
|
+
{
|
|
3486
|
+
type: "button",
|
|
3487
|
+
onClick: () => setDraft([]),
|
|
3488
|
+
className: "text-[12px] font-medium text-text-link hover:underline",
|
|
3489
|
+
children: [
|
|
3490
|
+
"Clear ",
|
|
3491
|
+
caption.toLowerCase()
|
|
3492
|
+
]
|
|
3493
|
+
}
|
|
3494
|
+
) })
|
|
3495
|
+
]
|
|
3496
|
+
}
|
|
3497
|
+
)
|
|
3498
|
+
] });
|
|
3499
|
+
}
|
|
3500
|
+
function TriCheck({ state }) {
|
|
3501
|
+
const filled = state !== "none";
|
|
3502
|
+
return /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)(
|
|
3503
|
+
"span",
|
|
3504
|
+
{
|
|
3505
|
+
className: cn(
|
|
3506
|
+
"flex h-[18px] w-[18px] shrink-0 items-center justify-center rounded-[5px] border transition-colors",
|
|
3507
|
+
filled ? "border-transparent bg-brand-primaryAction text-brand-onprimary" : "border-border-interactive bg-input"
|
|
3508
|
+
),
|
|
3509
|
+
children: [
|
|
3510
|
+
state === "all" && /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(import_lucide_react21.Check, { size: 13, strokeWidth: 3 }),
|
|
3511
|
+
state === "some" && /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(import_lucide_react21.Minus, { size: 13, strokeWidth: 3 })
|
|
3512
|
+
]
|
|
3513
|
+
}
|
|
3514
|
+
);
|
|
3515
|
+
}
|
|
3516
|
+
|
|
3517
|
+
// src/Toggle.tsx
|
|
3518
|
+
var import_jsx_runtime36 = require("react/jsx-runtime");
|
|
3519
|
+
var SIZES2 = {
|
|
3520
|
+
sm: { track: "h-5 w-9", knob: "h-4 w-4", on: "translate-x-[18px]" },
|
|
3521
|
+
md: { track: "h-6 w-11", knob: "h-5 w-5", on: "translate-x-[22px]" }
|
|
3522
|
+
};
|
|
3523
|
+
function Toggle({ checked, onChange, label, size = "md", disabled, className }) {
|
|
3524
|
+
const s = SIZES2[size];
|
|
3525
|
+
return /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
|
|
3526
|
+
"button",
|
|
3527
|
+
{
|
|
3528
|
+
type: "button",
|
|
3529
|
+
role: "switch",
|
|
3530
|
+
"aria-checked": checked,
|
|
3531
|
+
"aria-label": label,
|
|
3532
|
+
disabled,
|
|
3533
|
+
onClick: () => onChange(!checked),
|
|
3534
|
+
className: cn(
|
|
3535
|
+
"relative inline-flex shrink-0 items-center rounded-full transition-colors focus-visible:outline-solid focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-border-focus",
|
|
3536
|
+
s.track,
|
|
3537
|
+
checked ? "bg-brand-primaryAction" : "bg-border-interactive",
|
|
3538
|
+
disabled && "cursor-not-allowed opacity-50",
|
|
3539
|
+
className
|
|
3540
|
+
),
|
|
3541
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
|
|
3542
|
+
"span",
|
|
3543
|
+
{
|
|
3544
|
+
className: cn(
|
|
3545
|
+
"inline-block transform rounded-full bg-surface shadow-raised transition-transform",
|
|
3546
|
+
s.knob,
|
|
3547
|
+
checked ? s.on : "translate-x-0.5"
|
|
3548
|
+
)
|
|
3549
|
+
}
|
|
3550
|
+
)
|
|
3551
|
+
}
|
|
3552
|
+
);
|
|
3553
|
+
}
|
|
3554
|
+
|
|
3555
|
+
// src/AISpark.tsx
|
|
3556
|
+
var import_react17 = require("react");
|
|
3557
|
+
var import_lucide_react22 = require("lucide-react");
|
|
3558
|
+
var import_jsx_runtime37 = require("react/jsx-runtime");
|
|
3559
|
+
function AISpark({ size = 16, className }) {
|
|
3560
|
+
const id = (0, import_react17.useId)();
|
|
3561
|
+
return /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)(import_jsx_runtime37.Fragment, { children: [
|
|
3562
|
+
/* @__PURE__ */ (0, import_jsx_runtime37.jsx)("svg", { width: "0", height: "0", "aria-hidden": "true", style: { position: "absolute" }, children: /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("defs", { children: /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)("linearGradient", { id, x1: "0", y1: "0", x2: "1", y2: "1", children: [
|
|
3563
|
+
/* @__PURE__ */ (0, import_jsx_runtime37.jsx)("stop", { offset: "0%", stopColor: "var(--mr-color-brand-primary)" }),
|
|
3564
|
+
/* @__PURE__ */ (0, import_jsx_runtime37.jsx)("stop", { offset: "100%", className: "[stop-color:#9474ff] in-data-[theme=dark]:[stop-color:#a488ff]" })
|
|
3565
|
+
] }) }) }),
|
|
3566
|
+
/* @__PURE__ */ (0, import_jsx_runtime37.jsx)(import_lucide_react22.Sparkles, { size, stroke: `url(#${id})`, className, "aria-hidden": "true" })
|
|
3567
|
+
] });
|
|
3568
|
+
}
|
|
3569
|
+
|
|
3570
|
+
// src/Freshness.tsx
|
|
3571
|
+
var import_jsx_runtime38 = require("react/jsx-runtime");
|
|
3572
|
+
var dotColor = {
|
|
3573
|
+
fresh: "bg-status-success",
|
|
3574
|
+
recent: "bg-status-warning",
|
|
3575
|
+
stale: "bg-text-tertiary"
|
|
3576
|
+
};
|
|
3577
|
+
var srLabel = {
|
|
3578
|
+
fresh: "Fresh (under 4 hours)",
|
|
3579
|
+
recent: "Recent (today)",
|
|
3580
|
+
stale: "Older than a day"
|
|
3581
|
+
};
|
|
3582
|
+
function Freshness({ level }) {
|
|
3583
|
+
return /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(
|
|
3584
|
+
"span",
|
|
3585
|
+
{
|
|
3586
|
+
className: cn("inline-block h-1.5 w-1.5 shrink-0 rounded-full", dotColor[level]),
|
|
3587
|
+
role: "img",
|
|
3588
|
+
"aria-label": srLabel[level]
|
|
3589
|
+
}
|
|
3590
|
+
);
|
|
3591
|
+
}
|
|
2979
3592
|
// Annotate the CommonJS export names for ESM import in node:
|
|
2980
3593
|
0 && (module.exports = {
|
|
3594
|
+
AISpark,
|
|
2981
3595
|
AdvertiserNoResults,
|
|
2982
3596
|
AdvertiserQuickFilter,
|
|
2983
3597
|
AdvertiserSearchPrompt,
|
|
@@ -2989,10 +3603,13 @@ function WorkspaceAvatar({ name, size = "md" }) {
|
|
|
2989
3603
|
DEFAULT_SEARCH_MATCH,
|
|
2990
3604
|
DataScopeFilter,
|
|
2991
3605
|
DateRangeFilter,
|
|
3606
|
+
DateRangePicker,
|
|
2992
3607
|
FilterChipBar,
|
|
2993
3608
|
FilterDropdownFooter,
|
|
3609
|
+
Freshness,
|
|
2994
3610
|
InfoTip,
|
|
2995
3611
|
LineChartPlaceholder,
|
|
3612
|
+
MultiSelectFilter,
|
|
2996
3613
|
NO_RESULTS_BODY,
|
|
2997
3614
|
NO_RESULTS_TITLE,
|
|
2998
3615
|
NameListModal,
|
|
@@ -3010,6 +3627,9 @@ function WorkspaceAvatar({ name, size = "md" }) {
|
|
|
3010
3627
|
SelectionPicker,
|
|
3011
3628
|
SortButton,
|
|
3012
3629
|
StackedColumnPlaceholder,
|
|
3630
|
+
TablePagination,
|
|
3631
|
+
Tag,
|
|
3632
|
+
Toggle,
|
|
3013
3633
|
Tooltip,
|
|
3014
3634
|
WorkspaceAvatar,
|
|
3015
3635
|
WorkspaceSelectedCard,
|
|
@@ -3017,6 +3637,7 @@ function WorkspaceAvatar({ name, size = "md" }) {
|
|
|
3017
3637
|
chipTriggerClass,
|
|
3018
3638
|
cycleSort,
|
|
3019
3639
|
noResultsBody,
|
|
3640
|
+
resolveRange,
|
|
3020
3641
|
sortProp
|
|
3021
3642
|
});
|
|
3022
3643
|
//# sourceMappingURL=index.cjs.map
|