@mediaradar/design-components 0.8.1 → 0.10.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 +108 -42
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +135 -20
- package/dist/index.d.ts +135 -20
- package/dist/index.js +107 -42
- package/dist/index.js.map +1 -1
- package/package.json +63 -63
package/dist/index.js
CHANGED
|
@@ -390,9 +390,39 @@ function OptionRow({
|
|
|
390
390
|
|
|
391
391
|
// src/CheckBox.tsx
|
|
392
392
|
import { Check as Check2, Minus } from "lucide-react";
|
|
393
|
+
|
|
394
|
+
// src/cn.ts
|
|
395
|
+
import { clsx } from "clsx";
|
|
396
|
+
import { twMerge } from "tailwind-merge";
|
|
397
|
+
function cn(...inputs) {
|
|
398
|
+
return twMerge(clsx(inputs));
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
// src/CheckBox.tsx
|
|
393
402
|
import { jsx as jsx4 } from "react/jsx-runtime";
|
|
394
|
-
function
|
|
395
|
-
|
|
403
|
+
function boxClass(on, disabled) {
|
|
404
|
+
return cn(
|
|
405
|
+
"flex h-[18px] w-[18px] shrink-0 items-center justify-center rounded-[5px] border transition-colors",
|
|
406
|
+
on ? "border-transparent bg-brand-primaryAction text-white" : "border-border-interactive bg-input",
|
|
407
|
+
disabled && "cursor-not-allowed opacity-50"
|
|
408
|
+
);
|
|
409
|
+
}
|
|
410
|
+
function Glyph({ checked, indeterminate }) {
|
|
411
|
+
if (indeterminate) return /* @__PURE__ */ jsx4(Minus, { size: 13, strokeWidth: 3 });
|
|
412
|
+
return checked ? /* @__PURE__ */ jsx4(Check2, { size: 13, strokeWidth: 3 }) : null;
|
|
413
|
+
}
|
|
414
|
+
function CheckBox({
|
|
415
|
+
checked,
|
|
416
|
+
indeterminate,
|
|
417
|
+
onChange,
|
|
418
|
+
ariaLabel,
|
|
419
|
+
disabled,
|
|
420
|
+
stopPropagation = true,
|
|
421
|
+
testId,
|
|
422
|
+
title,
|
|
423
|
+
className
|
|
424
|
+
}) {
|
|
425
|
+
const on = checked || !!indeterminate;
|
|
396
426
|
return /* @__PURE__ */ jsx4(
|
|
397
427
|
"button",
|
|
398
428
|
{
|
|
@@ -404,25 +434,26 @@ function CheckBox({ checked, indeterminate, onChange, ariaLabel, disabled, testI
|
|
|
404
434
|
disabled,
|
|
405
435
|
"data-testid": testId,
|
|
406
436
|
onClick: (e) => {
|
|
407
|
-
e.stopPropagation();
|
|
437
|
+
if (stopPropagation) e.stopPropagation();
|
|
408
438
|
onChange();
|
|
409
439
|
},
|
|
410
|
-
className:
|
|
411
|
-
|
|
440
|
+
className: cn(
|
|
441
|
+
boxClass(on, disabled),
|
|
412
442
|
"focus-visible:outline-solid focus-visible:outline-2 focus-visible:outline-border-focus",
|
|
413
|
-
on
|
|
443
|
+
!on && "hover:border-brand-primaryAction",
|
|
414
444
|
// Cancels the unchecked hover-border preview when disabled -- without
|
|
415
445
|
// this, a disabled box still visually previews the "you can click
|
|
416
446
|
// this" affordance on hover even though the click does nothing.
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
].filter(Boolean).join(" "),
|
|
422
|
-
children: indeterminate ? /* @__PURE__ */ jsx4(Minus, { size: 13, strokeWidth: 3 }) : checked ? /* @__PURE__ */ jsx4(Check2, { size: 13, strokeWidth: 3 }) : null
|
|
447
|
+
disabled && "hover:border-border-interactive",
|
|
448
|
+
className
|
|
449
|
+
),
|
|
450
|
+
children: /* @__PURE__ */ jsx4(Glyph, { checked, indeterminate })
|
|
423
451
|
}
|
|
424
452
|
);
|
|
425
453
|
}
|
|
454
|
+
function CheckBoxBox({ checked, indeterminate, disabled, className }) {
|
|
455
|
+
return /* @__PURE__ */ jsx4("span", { "aria-hidden": "true", className: cn(boxClass(checked || !!indeterminate, disabled), className), children: /* @__PURE__ */ jsx4(Glyph, { checked, indeterminate }) });
|
|
456
|
+
}
|
|
426
457
|
|
|
427
458
|
// src/DateRangeFilter.tsx
|
|
428
459
|
import { useEffect as useEffect3, useMemo as useMemo2, useRef as useRef3, useState as useState3 } from "react";
|
|
@@ -2558,15 +2589,6 @@ import { forwardRef as forwardRef2 } from "react";
|
|
|
2558
2589
|
import { Slot } from "@radix-ui/react-slot";
|
|
2559
2590
|
import { cva } from "class-variance-authority";
|
|
2560
2591
|
import { Loader2 as Loader22 } from "lucide-react";
|
|
2561
|
-
|
|
2562
|
-
// src/cn.ts
|
|
2563
|
-
import { clsx } from "clsx";
|
|
2564
|
-
import { twMerge } from "tailwind-merge";
|
|
2565
|
-
function cn(...inputs) {
|
|
2566
|
-
return twMerge(clsx(inputs));
|
|
2567
|
-
}
|
|
2568
|
-
|
|
2569
|
-
// src/Button.tsx
|
|
2570
2592
|
import { jsx as jsx24, jsxs as jsxs22 } from "react/jsx-runtime";
|
|
2571
2593
|
var buttonVariants = cva(
|
|
2572
2594
|
"inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-control font-medium transition-all duration-(--mr-motion-duration-interactive) ease-interactive disabled:pointer-events-none disabled:opacity-40 focus-visible:outline-hidden focus-visible:ring-0",
|
|
@@ -2640,8 +2662,21 @@ function FilterDropdownFooter({
|
|
|
2640
2662
|
import { useEffect as useEffect10, useState as useState11 } from "react";
|
|
2641
2663
|
import { createPortal as createPortal5 } from "react-dom";
|
|
2642
2664
|
import { jsx as jsx26, jsxs as jsxs24 } from "react/jsx-runtime";
|
|
2643
|
-
function NameListModal({
|
|
2665
|
+
function NameListModal({
|
|
2666
|
+
title,
|
|
2667
|
+
initialName,
|
|
2668
|
+
submitLabel,
|
|
2669
|
+
onCancel,
|
|
2670
|
+
onSubmit,
|
|
2671
|
+
fieldLabel = "List name",
|
|
2672
|
+
placeholder = "e.g. Q4 prospecting targets",
|
|
2673
|
+
options
|
|
2674
|
+
}) {
|
|
2644
2675
|
const [name, setName] = useState11(initialName);
|
|
2676
|
+
const [checked, setChecked] = useState11(
|
|
2677
|
+
() => Object.fromEntries((options ?? []).map((o) => [o.key, !!o.initial]))
|
|
2678
|
+
);
|
|
2679
|
+
const toggle = (key) => setChecked((c) => ({ ...c, [key]: !c[key] }));
|
|
2645
2680
|
useEffect10(() => {
|
|
2646
2681
|
const onKey = (e) => e.key === "Escape" && onCancel();
|
|
2647
2682
|
window.addEventListener("keydown", onKey);
|
|
@@ -2666,7 +2701,7 @@ function NameListModal({ title, initialName, submitLabel, onCancel, onSubmit })
|
|
|
2666
2701
|
children: [
|
|
2667
2702
|
/* @__PURE__ */ jsx26("h2", { className: "text-[16px] font-semibold text-text-primary", children: title }),
|
|
2668
2703
|
/* @__PURE__ */ jsxs24("div", { className: "mt-4 flex flex-col gap-1.5", children: [
|
|
2669
|
-
/* @__PURE__ */ jsx26("label", { htmlFor: "account-list-name", className: "text-[12px] font-medium text-text-secondary", children:
|
|
2704
|
+
/* @__PURE__ */ jsx26("label", { htmlFor: "account-list-name", className: "text-[12px] font-medium text-text-secondary", children: fieldLabel }),
|
|
2670
2705
|
/* @__PURE__ */ jsx26(
|
|
2671
2706
|
"input",
|
|
2672
2707
|
{
|
|
@@ -2674,14 +2709,18 @@ function NameListModal({ title, initialName, submitLabel, onCancel, onSubmit })
|
|
|
2674
2709
|
autoFocus: true,
|
|
2675
2710
|
value: name,
|
|
2676
2711
|
onChange: (e) => setName(e.target.value),
|
|
2677
|
-
placeholder
|
|
2712
|
+
placeholder,
|
|
2678
2713
|
className: "h-10 rounded-control border border-border-default bg-input px-3 text-sm outline-hidden focus:border-brand-primaryAction"
|
|
2679
2714
|
}
|
|
2680
2715
|
)
|
|
2681
2716
|
] }),
|
|
2717
|
+
options && options.length > 0 && /* @__PURE__ */ jsx26("div", { className: "mt-4 flex flex-col gap-2.5", children: options.map((o) => /* @__PURE__ */ jsxs24("label", { className: "flex cursor-pointer items-center gap-2.5 text-[13px] text-text-primary", children: [
|
|
2718
|
+
/* @__PURE__ */ jsx26(CheckBox, { checked: !!checked[o.key], onChange: () => toggle(o.key), ariaLabel: o.label }),
|
|
2719
|
+
o.label
|
|
2720
|
+
] }, o.key)) }),
|
|
2682
2721
|
/* @__PURE__ */ jsxs24("div", { className: "mt-5 flex items-center justify-end gap-2", children: [
|
|
2683
2722
|
/* @__PURE__ */ jsx26(Button, { variant: "secondary", onClick: onCancel, children: "Cancel" }),
|
|
2684
|
-
/* @__PURE__ */ jsx26(Button, { disabled: !name.trim(), onClick: () => onSubmit(name.trim()), children: submitLabel })
|
|
2723
|
+
/* @__PURE__ */ jsx26(Button, { disabled: !name.trim(), onClick: () => onSubmit(name.trim(), checked), children: submitLabel })
|
|
2685
2724
|
] })
|
|
2686
2725
|
]
|
|
2687
2726
|
}
|
|
@@ -2694,12 +2733,13 @@ function NameListModal({ title, initialName, submitLabel, onCancel, onSubmit })
|
|
|
2694
2733
|
|
|
2695
2734
|
// src/ChipTrigger.tsx
|
|
2696
2735
|
import { jsx as jsx27, jsxs as jsxs25 } from "react/jsx-runtime";
|
|
2697
|
-
function chipTriggerClass() {
|
|
2736
|
+
function chipTriggerClass(variant = "box") {
|
|
2698
2737
|
return cn(
|
|
2699
2738
|
"flex h-11 items-center gap-2 rounded-control border bg-input px-2.5 text-text-secondary transition-colors hover:bg-subtle hover:text-text-primary focus-visible:outline-solid focus-visible:outline-2 focus-visible:outline-border-focus",
|
|
2700
|
-
//
|
|
2701
|
-
// control against the warm canvas
|
|
2702
|
-
|
|
2739
|
+
// Both variants sit on the input fill. `inline` carries the darker stroke
|
|
2740
|
+
// so it still reads as a control against the warm canvas with no boxed
|
|
2741
|
+
// shell behind it.
|
|
2742
|
+
variant === "inline" ? "border-border-strong" : "border-border-default"
|
|
2703
2743
|
);
|
|
2704
2744
|
}
|
|
2705
2745
|
function ChipContent({ caption, value, icon }) {
|
|
@@ -3052,6 +3092,7 @@ import { useEffect as useEffect11, useMemo as useMemo4, useRef as useRef11, useS
|
|
|
3052
3092
|
import { ChevronDown as ChevronDown10 } from "lucide-react";
|
|
3053
3093
|
import { jsx as jsx34, jsxs as jsxs30 } from "react/jsx-runtime";
|
|
3054
3094
|
var MONTH_ABBR = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"];
|
|
3095
|
+
var QUARTER_ABBR = ["Q1", "Q2", "Q3", "Q4"];
|
|
3055
3096
|
var PRESETS = ["Rolling 3 months", "Rolling 6 months", "Rolling 12 months"];
|
|
3056
3097
|
var startOfToday = () => {
|
|
3057
3098
|
const d = /* @__PURE__ */ new Date();
|
|
@@ -3100,6 +3141,7 @@ function MiniSelect({ value, onChange, options }) {
|
|
|
3100
3141
|
}
|
|
3101
3142
|
function DateRangePicker({
|
|
3102
3143
|
defaultValue = "Rolling 6 months",
|
|
3144
|
+
granularity = "month",
|
|
3103
3145
|
align = "left",
|
|
3104
3146
|
presets = PRESETS,
|
|
3105
3147
|
onChange,
|
|
@@ -3118,6 +3160,8 @@ function DateRangePicker({
|
|
|
3118
3160
|
const [fromYr, setFromYr] = useState12(end.getFullYear() - 1);
|
|
3119
3161
|
const [toMo, setToMo] = useState12(end.getMonth());
|
|
3120
3162
|
const [toYr, setToYr] = useState12(end.getFullYear());
|
|
3163
|
+
const [fromQ, setFromQ] = useState12(Math.floor(end.getMonth() / 3));
|
|
3164
|
+
const [toQ, setToQ] = useState12(Math.floor(end.getMonth() / 3));
|
|
3121
3165
|
useEffect11(() => {
|
|
3122
3166
|
const [s, e] = resolveRange(value, end);
|
|
3123
3167
|
onRangeChange?.(s, e);
|
|
@@ -3144,11 +3188,11 @@ function DateRangePicker({
|
|
|
3144
3188
|
onChange?.(label);
|
|
3145
3189
|
setOpen(false);
|
|
3146
3190
|
};
|
|
3147
|
-
const span = toYr * 12 + toMo - (fromYr * 12 + fromMo) + 1;
|
|
3191
|
+
const span = granularity === "year" ? toYr - fromYr + 1 : granularity === "quarter" ? toYr * 4 + toQ - (fromYr * 4 + fromQ) + 1 : toYr * 12 + toMo - (fromYr * 12 + fromMo) + 1;
|
|
3148
3192
|
const valid = span >= 1;
|
|
3149
3193
|
const applyCustom = () => {
|
|
3150
3194
|
if (!valid) return;
|
|
3151
|
-
const label = `${MONTH_ABBR[fromMo]} ${fromYr} \u2013 ${MONTH_ABBR[toMo]} ${toYr}`;
|
|
3195
|
+
const label = granularity === "year" ? `${fromYr} \u2013 ${toYr}` : granularity === "quarter" ? `${QUARTER_ABBR[fromQ]} ${fromYr} \u2013 ${QUARTER_ABBR[toQ]} ${toYr}` : `${MONTH_ABBR[fromMo]} ${fromYr} \u2013 ${MONTH_ABBR[toMo]} ${toYr}`;
|
|
3152
3196
|
if (showFooter) setDraft(label);
|
|
3153
3197
|
else commit(label);
|
|
3154
3198
|
};
|
|
@@ -3187,14 +3231,16 @@ function DateRangePicker({
|
|
|
3187
3231
|
/* @__PURE__ */ jsxs30("label", { className: "flex items-center justify-between gap-2 text-[12px] text-text-secondary", children: [
|
|
3188
3232
|
"From",
|
|
3189
3233
|
/* @__PURE__ */ jsxs30("span", { className: "flex gap-1", children: [
|
|
3190
|
-
/* @__PURE__ */ jsx34(MiniSelect, { value: fromMo, onChange: setFromMo, options: MONTH_ABBR.map((mm, i) => ({ label: mm, value: i })) }),
|
|
3234
|
+
granularity === "month" && /* @__PURE__ */ jsx34(MiniSelect, { value: fromMo, onChange: setFromMo, options: MONTH_ABBR.map((mm, i) => ({ label: mm, value: i })) }),
|
|
3235
|
+
granularity === "quarter" && /* @__PURE__ */ jsx34(MiniSelect, { value: fromQ, onChange: setFromQ, options: QUARTER_ABBR.map((qq, i) => ({ label: qq, value: i })) }),
|
|
3191
3236
|
/* @__PURE__ */ jsx34(MiniSelect, { value: fromYr, onChange: setFromYr, options: yearOptions.map((y) => ({ label: String(y), value: y })) })
|
|
3192
3237
|
] })
|
|
3193
3238
|
] }),
|
|
3194
3239
|
/* @__PURE__ */ jsxs30("label", { className: "flex items-center justify-between gap-2 text-[12px] text-text-secondary", children: [
|
|
3195
3240
|
"To",
|
|
3196
3241
|
/* @__PURE__ */ jsxs30("span", { className: "flex gap-1", children: [
|
|
3197
|
-
/* @__PURE__ */ jsx34(MiniSelect, { value: toMo, onChange: setToMo, options: MONTH_ABBR.map((mm, i) => ({ label: mm, value: i })) }),
|
|
3242
|
+
granularity === "month" && /* @__PURE__ */ jsx34(MiniSelect, { value: toMo, onChange: setToMo, options: MONTH_ABBR.map((mm, i) => ({ label: mm, value: i })) }),
|
|
3243
|
+
granularity === "quarter" && /* @__PURE__ */ jsx34(MiniSelect, { value: toQ, onChange: setToQ, options: QUARTER_ABBR.map((qq, i) => ({ label: qq, value: i })) }),
|
|
3198
3244
|
/* @__PURE__ */ jsx34(MiniSelect, { value: toYr, onChange: setToYr, options: yearOptions.map((y) => ({ label: String(y), value: y })) })
|
|
3199
3245
|
] })
|
|
3200
3246
|
] }),
|
|
@@ -3223,6 +3269,8 @@ function MultiSelectFilter({
|
|
|
3223
3269
|
caption,
|
|
3224
3270
|
options = [],
|
|
3225
3271
|
groups,
|
|
3272
|
+
counts,
|
|
3273
|
+
variant = "box",
|
|
3226
3274
|
selected,
|
|
3227
3275
|
onChange,
|
|
3228
3276
|
allLabel = "All",
|
|
@@ -3280,14 +3328,18 @@ function MultiSelectFilter({
|
|
|
3280
3328
|
return next;
|
|
3281
3329
|
});
|
|
3282
3330
|
const toggleGroup = (g) => setDraft((cur) => {
|
|
3283
|
-
const ids = groupLeaves(g).map((c) => c.id);
|
|
3331
|
+
const ids = groupLeaves(g).map((c) => c.id).filter((id) => !counts || (counts[id] ?? 0) > 0 || cur.includes(id));
|
|
3332
|
+
if (!ids.length) return cur;
|
|
3284
3333
|
const allSel = ids.every((id) => cur.includes(id));
|
|
3285
3334
|
const next = allSel ? cur.filter((id) => !ids.includes(id)) : [.../* @__PURE__ */ new Set([...cur, ...ids])];
|
|
3286
3335
|
if (next.length < min) return cur;
|
|
3287
3336
|
return next;
|
|
3288
3337
|
});
|
|
3338
|
+
const isAvailable = (id) => !counts || (counts[id] ?? 0) > 0 || draft.includes(id);
|
|
3339
|
+
const countFor = (id) => counts?.[id] ?? 0;
|
|
3289
3340
|
const groupState = (g) => {
|
|
3290
|
-
const ids = groupLeaves(g).map((c) => c.id);
|
|
3341
|
+
const ids = groupLeaves(g).map((c) => c.id).filter(isAvailable);
|
|
3342
|
+
if (!ids.length) return "none";
|
|
3291
3343
|
const sel = ids.filter((id) => draft.includes(id)).length;
|
|
3292
3344
|
return sel === 0 ? "none" : sel === ids.length ? "all" : "some";
|
|
3293
3345
|
};
|
|
@@ -3295,10 +3347,12 @@ function MultiSelectFilter({
|
|
|
3295
3347
|
const isAll = shown.length === 0 || fullIsAll && shown.length === leafOptions.length;
|
|
3296
3348
|
const value = isAll ? allLabel : shown.length === 1 ? leafOptions.find((o) => o.id === shown[0])?.label ?? `${shown.length} selected` : `${shown.length} selected`;
|
|
3297
3349
|
const ql = q.trim().toLowerCase();
|
|
3298
|
-
const items = options.filter((o) => !ql || o.label.toLowerCase().includes(ql));
|
|
3350
|
+
const items = options.filter((o) => isAvailable(o.id) && (!ql || o.label.toLowerCase().includes(ql)));
|
|
3299
3351
|
const visibleGroups = groups ? groups.map((g) => {
|
|
3300
|
-
|
|
3301
|
-
|
|
3352
|
+
const live = g.children.filter((c) => isAvailable(c.id));
|
|
3353
|
+
if (!live.length && !isAvailable(g.id)) return null;
|
|
3354
|
+
if (!ql || g.label.toLowerCase().includes(ql)) return { ...g, children: live };
|
|
3355
|
+
const kids = live.filter((c) => c.label.toLowerCase().includes(ql));
|
|
3302
3356
|
return kids.length ? { ...g, children: kids } : null;
|
|
3303
3357
|
}).filter((g) => g !== null) : [];
|
|
3304
3358
|
return /* @__PURE__ */ jsxs31("div", { className: cn("relative", fullWidth && "w-full"), ref, children: [
|
|
@@ -3308,7 +3362,7 @@ function MultiSelectFilter({
|
|
|
3308
3362
|
type: "button",
|
|
3309
3363
|
onClick: () => open ? close() : openTray(),
|
|
3310
3364
|
"aria-expanded": open,
|
|
3311
|
-
className: cn(chipTriggerClass(), fullWidth && "w-full justify-between"),
|
|
3365
|
+
className: cn(chipTriggerClass(variant), fullWidth && "w-full justify-between"),
|
|
3312
3366
|
children: [
|
|
3313
3367
|
/* @__PURE__ */ jsx35(ChipContent, { caption, value, icon }),
|
|
3314
3368
|
/* @__PURE__ */ jsx35(
|
|
@@ -3359,7 +3413,8 @@ function MultiSelectFilter({
|
|
|
3359
3413
|
className: "flex w-full items-center gap-2.5 rounded-control px-2 py-2 text-left transition-colors hover:bg-subtle",
|
|
3360
3414
|
children: [
|
|
3361
3415
|
/* @__PURE__ */ jsx35(TriCheck, { state }),
|
|
3362
|
-
/* @__PURE__ */ jsx35("span", { className: cn("flex-1 text-[14px] text-text-primary", !plainParent && "font-semibold"), children: g.label })
|
|
3416
|
+
/* @__PURE__ */ jsx35("span", { className: cn("flex-1 text-[14px] text-text-primary", !plainParent && "font-semibold"), children: g.label }),
|
|
3417
|
+
counts && /* @__PURE__ */ jsx35(OptionCount, { n: countFor(g.id) })
|
|
3363
3418
|
]
|
|
3364
3419
|
}
|
|
3365
3420
|
),
|
|
@@ -3373,7 +3428,8 @@ function MultiSelectFilter({
|
|
|
3373
3428
|
className: "flex w-full items-center gap-2.5 rounded-control py-2 pl-9 pr-2 text-left transition-colors hover:bg-subtle",
|
|
3374
3429
|
children: [
|
|
3375
3430
|
/* @__PURE__ */ jsx35(TriCheck, { state: checked ? "all" : "none" }),
|
|
3376
|
-
/* @__PURE__ */ jsx35("span", { className: "flex-1 text-[14px] text-text-primary", children: c.label })
|
|
3431
|
+
/* @__PURE__ */ jsx35("span", { className: "flex-1 text-[14px] text-text-primary", children: c.label }),
|
|
3432
|
+
counts && /* @__PURE__ */ jsx35(OptionCount, { n: countFor(c.id) })
|
|
3377
3433
|
]
|
|
3378
3434
|
},
|
|
3379
3435
|
c.id
|
|
@@ -3399,7 +3455,8 @@ function MultiSelectFilter({
|
|
|
3399
3455
|
children: checked && /* @__PURE__ */ jsx35(Check7, { size: 13, strokeWidth: 3 })
|
|
3400
3456
|
}
|
|
3401
3457
|
),
|
|
3402
|
-
/* @__PURE__ */ jsx35("span", { className: "flex-1 text-[14px] text-text-primary", children: o.label })
|
|
3458
|
+
/* @__PURE__ */ jsx35("span", { className: "flex-1 text-[14px] text-text-primary", children: o.label }),
|
|
3459
|
+
counts && /* @__PURE__ */ jsx35(OptionCount, { n: countFor(o.id) })
|
|
3403
3460
|
]
|
|
3404
3461
|
},
|
|
3405
3462
|
o.id
|
|
@@ -3440,6 +3497,13 @@ function TriCheck({ state }) {
|
|
|
3440
3497
|
}
|
|
3441
3498
|
);
|
|
3442
3499
|
}
|
|
3500
|
+
function OptionCount({ n }) {
|
|
3501
|
+
return /* @__PURE__ */ jsxs31("span", { className: "shrink-0 text-[12px] tabular-nums text-text-tertiary", children: [
|
|
3502
|
+
"(",
|
|
3503
|
+
n.toLocaleString(),
|
|
3504
|
+
")"
|
|
3505
|
+
] });
|
|
3506
|
+
}
|
|
3443
3507
|
|
|
3444
3508
|
// src/Toggle.tsx
|
|
3445
3509
|
import { jsx as jsx36 } from "react/jsx-runtime";
|
|
@@ -3525,6 +3589,7 @@ export {
|
|
|
3525
3589
|
Button,
|
|
3526
3590
|
Card,
|
|
3527
3591
|
CheckBox,
|
|
3592
|
+
CheckBoxBox,
|
|
3528
3593
|
ChipContent,
|
|
3529
3594
|
DEFAULT_SEARCH_MATCH,
|
|
3530
3595
|
DataScopeFilter,
|