@bearmenu/ui 0.8.52 → 0.8.53
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/chunk-GIJGVFGC.js +177 -0
- package/dist/chunk-RKNPPYRU.js +86 -0
- package/dist/components/alert.d.ts +2 -2
- package/dist/components/badge.d.ts +1 -1
- package/dist/components/banner.d.ts +1 -1
- package/dist/components/button.d.ts +2 -2
- package/dist/components/card.d.ts +2 -2
- package/dist/components/command.d.ts +15 -15
- package/dist/components/empty-state.d.ts +2 -2
- package/dist/components/facet-group.d.ts +9 -2
- package/dist/components/facet-group.js +108 -10
- package/dist/components/filter-option-chip.d.ts +15 -0
- package/dist/components/filter-option-chip.js +3 -0
- package/dist/components/filter-option-group.d.ts +37 -0
- package/dist/components/filter-option-group.js +10 -0
- package/dist/components/filter-panel-footer.d.ts +15 -0
- package/dist/components/filter-panel-footer.js +63 -0
- package/dist/components/place-card.js +1 -1
- package/dist/components/spinner.d.ts +2 -2
- package/dist/components/tag.d.ts +2 -2
- package/dist/components/text.d.ts +2 -2
- package/dist/components/toggle.d.ts +1 -1
- package/package.json +28 -222
- package/src/components/facet-group.tsx +153 -54
- package/src/components/filter-option-chip.test.tsx +50 -0
- package/src/components/filter-option-chip.tsx +81 -0
- package/src/components/filter-option-group.stories.tsx +250 -0
- package/src/components/filter-option-group.test.tsx +100 -0
- package/src/components/filter-option-group.tsx +231 -0
- package/src/components/filter-panel-footer.tsx +63 -0
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
import { FilterOptionChip } from './chunk-RKNPPYRU.js';
|
|
2
|
+
import { Separator } from './chunk-NWZGSLPU.js';
|
|
3
|
+
import { Button } from './chunk-GHKTVHQG.js';
|
|
4
|
+
import { Text } from './chunk-ZLMRVBD7.js';
|
|
5
|
+
import { Badge } from './chunk-RYPPN2GZ.js';
|
|
6
|
+
import { cn } from './chunk-FEK5XGZW.js';
|
|
7
|
+
import { useId, useState } from 'react';
|
|
8
|
+
import { ChevronDown } from 'lucide-react';
|
|
9
|
+
import { jsxs, Fragment, jsx } from 'react/jsx-runtime';
|
|
10
|
+
|
|
11
|
+
function FilterOptionGroup({
|
|
12
|
+
title,
|
|
13
|
+
options,
|
|
14
|
+
value,
|
|
15
|
+
onValueChange,
|
|
16
|
+
selection = "multiple",
|
|
17
|
+
name,
|
|
18
|
+
defaultOpen = false,
|
|
19
|
+
collapsible = true,
|
|
20
|
+
visibleLimit = 6,
|
|
21
|
+
showAllLabel,
|
|
22
|
+
showLessLabel,
|
|
23
|
+
children,
|
|
24
|
+
footer,
|
|
25
|
+
clearLabel,
|
|
26
|
+
onClear,
|
|
27
|
+
summaryValues = value,
|
|
28
|
+
className,
|
|
29
|
+
divider = true,
|
|
30
|
+
disabled
|
|
31
|
+
}) {
|
|
32
|
+
const id = useId();
|
|
33
|
+
const [isOpen, setOpen] = useState(defaultOpen);
|
|
34
|
+
const open = !collapsible || isOpen;
|
|
35
|
+
const [expanded, setExpanded] = useState([]);
|
|
36
|
+
const selected = options.filter(
|
|
37
|
+
(option) => summaryValues.includes(option.value)
|
|
38
|
+
);
|
|
39
|
+
const sections = [];
|
|
40
|
+
for (const option of options) {
|
|
41
|
+
const last = sections[sections.length - 1];
|
|
42
|
+
if (!last || last.label !== option.section)
|
|
43
|
+
sections.push({ label: option.section, options: [option] });
|
|
44
|
+
else last.options.push(option);
|
|
45
|
+
}
|
|
46
|
+
const heading = /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
47
|
+
/* @__PURE__ */ jsxs("span", { className: "min-w-0 flex-1", children: [
|
|
48
|
+
/* @__PURE__ */ jsx(
|
|
49
|
+
Text,
|
|
50
|
+
{
|
|
51
|
+
as: "span",
|
|
52
|
+
id: `${id}-title`,
|
|
53
|
+
className: "block",
|
|
54
|
+
variant: "body-sm",
|
|
55
|
+
weight: "semibold",
|
|
56
|
+
children: title
|
|
57
|
+
}
|
|
58
|
+
),
|
|
59
|
+
!open && selected.length > 0 && /* @__PURE__ */ jsx(
|
|
60
|
+
Text,
|
|
61
|
+
{
|
|
62
|
+
as: "span",
|
|
63
|
+
variant: "caption",
|
|
64
|
+
color: "muted",
|
|
65
|
+
className: "mt-1 block leading-relaxed [overflow-wrap:anywhere]",
|
|
66
|
+
children: selected.map((option) => option.label).join(" \xB7 ")
|
|
67
|
+
}
|
|
68
|
+
)
|
|
69
|
+
] }),
|
|
70
|
+
selected.length > 0 && /* @__PURE__ */ jsx(Badge, { variant: "secondary", className: "tabular-nums", children: selected.length }),
|
|
71
|
+
collapsible && /* @__PURE__ */ jsx(
|
|
72
|
+
ChevronDown,
|
|
73
|
+
{
|
|
74
|
+
"aria-hidden": true,
|
|
75
|
+
className: cn(
|
|
76
|
+
"size-4 shrink-0 text-muted-foreground transition-transform motion-reduce:transition-none",
|
|
77
|
+
open && "rotate-180"
|
|
78
|
+
)
|
|
79
|
+
}
|
|
80
|
+
)
|
|
81
|
+
] });
|
|
82
|
+
return /* @__PURE__ */ jsxs("section", { className: cn("min-w-0", className), children: [
|
|
83
|
+
/* @__PURE__ */ jsxs("div", { className: "py-2", children: [
|
|
84
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
|
|
85
|
+
collapsible ? /* @__PURE__ */ jsx(
|
|
86
|
+
"button",
|
|
87
|
+
{
|
|
88
|
+
type: "button",
|
|
89
|
+
onClick: () => setOpen((previous) => !previous),
|
|
90
|
+
"aria-expanded": open,
|
|
91
|
+
"aria-controls": id,
|
|
92
|
+
className: "flex min-h-11 min-w-0 flex-1 items-center gap-3 rounded-lg py-2 text-left focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ring",
|
|
93
|
+
children: heading
|
|
94
|
+
}
|
|
95
|
+
) : /* @__PURE__ */ jsx("div", { className: "flex min-h-11 min-w-0 flex-1 items-center gap-3 py-2", children: heading }),
|
|
96
|
+
onClear && clearLabel && summaryValues.length > 0 && /* @__PURE__ */ jsx(
|
|
97
|
+
Button,
|
|
98
|
+
{
|
|
99
|
+
type: "button",
|
|
100
|
+
variant: "ghost",
|
|
101
|
+
className: "min-h-11 shrink-0 px-2 text-xs",
|
|
102
|
+
onClick: onClear,
|
|
103
|
+
children: clearLabel
|
|
104
|
+
}
|
|
105
|
+
)
|
|
106
|
+
] }),
|
|
107
|
+
/* @__PURE__ */ jsxs("div", { id, hidden: !open, children: [
|
|
108
|
+
children,
|
|
109
|
+
sections.map((section, index) => {
|
|
110
|
+
var _a;
|
|
111
|
+
const sectionId = `${id}-section-${index}`;
|
|
112
|
+
const key = (_a = section.label) != null ? _a : "";
|
|
113
|
+
const isExpanded = expanded.includes(key);
|
|
114
|
+
const limit = showAllLabel ? visibleLimit : Infinity;
|
|
115
|
+
const visible = isExpanded ? section.options : section.options.filter(
|
|
116
|
+
(option, i) => i < limit || value.includes(option.value)
|
|
117
|
+
);
|
|
118
|
+
return /* @__PURE__ */ jsxs("div", { children: [
|
|
119
|
+
section.label && /* @__PURE__ */ jsx(
|
|
120
|
+
Text,
|
|
121
|
+
{
|
|
122
|
+
as: "h4",
|
|
123
|
+
id: sectionId,
|
|
124
|
+
variant: "caption",
|
|
125
|
+
weight: "semibold",
|
|
126
|
+
color: "muted",
|
|
127
|
+
className: "mt-3 mb-1",
|
|
128
|
+
children: section.label
|
|
129
|
+
}
|
|
130
|
+
),
|
|
131
|
+
/* @__PURE__ */ jsx(
|
|
132
|
+
"fieldset",
|
|
133
|
+
{
|
|
134
|
+
"aria-labelledby": `${id}-title${section.label ? ` ${sectionId}` : ""}`,
|
|
135
|
+
disabled,
|
|
136
|
+
className: "m-0 flex min-w-0 flex-wrap gap-2 border-0 px-0 pt-2 pb-3",
|
|
137
|
+
children: visible.map((option) => /* @__PURE__ */ jsx(
|
|
138
|
+
FilterOptionChip,
|
|
139
|
+
{
|
|
140
|
+
label: option.label,
|
|
141
|
+
count: option.count,
|
|
142
|
+
icon: option.icon,
|
|
143
|
+
type: selection === "single" ? "radio" : "checkbox",
|
|
144
|
+
name: selection === "single" ? name != null ? name : id : void 0,
|
|
145
|
+
value: option.value,
|
|
146
|
+
checked: value.includes(option.value),
|
|
147
|
+
onChange: (event) => onValueChange(
|
|
148
|
+
selection === "single" ? [option.value] : event.target.checked ? [...value, option.value] : value.filter((item) => item !== option.value)
|
|
149
|
+
)
|
|
150
|
+
},
|
|
151
|
+
option.value
|
|
152
|
+
))
|
|
153
|
+
}
|
|
154
|
+
),
|
|
155
|
+
section.options.length > limit && /* @__PURE__ */ jsx(
|
|
156
|
+
Button,
|
|
157
|
+
{
|
|
158
|
+
type: "button",
|
|
159
|
+
variant: "link",
|
|
160
|
+
"aria-expanded": isExpanded,
|
|
161
|
+
onClick: () => setExpanded(
|
|
162
|
+
(previous) => isExpanded ? previous.filter((item) => item !== key) : [...previous, key]
|
|
163
|
+
),
|
|
164
|
+
className: "mb-1 min-h-11 px-0",
|
|
165
|
+
children: isExpanded ? showLessLabel : typeof showAllLabel === "function" ? showAllLabel(section.options.length) : showAllLabel
|
|
166
|
+
}
|
|
167
|
+
)
|
|
168
|
+
] }, key);
|
|
169
|
+
}),
|
|
170
|
+
footer
|
|
171
|
+
] })
|
|
172
|
+
] }),
|
|
173
|
+
divider && /* @__PURE__ */ jsx(Separator, {})
|
|
174
|
+
] });
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
export { FilterOptionGroup };
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import { cn } from './chunk-FEK5XGZW.js';
|
|
2
|
+
import { __objRest, __spreadProps, __spreadValues } from './chunk-MMUBH76A.js';
|
|
3
|
+
import { useId } from 'react';
|
|
4
|
+
import { Check } from 'lucide-react';
|
|
5
|
+
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
6
|
+
|
|
7
|
+
function FilterOptionChip(_a) {
|
|
8
|
+
var _b = _a, {
|
|
9
|
+
label,
|
|
10
|
+
type = "checkbox",
|
|
11
|
+
count,
|
|
12
|
+
icon,
|
|
13
|
+
className,
|
|
14
|
+
id,
|
|
15
|
+
disabled
|
|
16
|
+
} = _b, input = __objRest(_b, [
|
|
17
|
+
"label",
|
|
18
|
+
"type",
|
|
19
|
+
"count",
|
|
20
|
+
"icon",
|
|
21
|
+
"className",
|
|
22
|
+
"id",
|
|
23
|
+
"disabled"
|
|
24
|
+
]);
|
|
25
|
+
var _a2;
|
|
26
|
+
const generatedId = useId();
|
|
27
|
+
const inputId = id != null ? id : generatedId;
|
|
28
|
+
return /* @__PURE__ */ jsxs(
|
|
29
|
+
"label",
|
|
30
|
+
{
|
|
31
|
+
htmlFor: inputId,
|
|
32
|
+
className: cn(
|
|
33
|
+
"relative inline-flex max-w-full min-w-0",
|
|
34
|
+
disabled && "cursor-not-allowed opacity-50",
|
|
35
|
+
className
|
|
36
|
+
),
|
|
37
|
+
children: [
|
|
38
|
+
/* @__PURE__ */ jsx(
|
|
39
|
+
"input",
|
|
40
|
+
__spreadProps(__spreadValues({}, input), {
|
|
41
|
+
id: inputId,
|
|
42
|
+
type,
|
|
43
|
+
disabled,
|
|
44
|
+
"aria-label": (_a2 = input["aria-label"]) != null ? _a2 : label,
|
|
45
|
+
className: "peer sr-only"
|
|
46
|
+
})
|
|
47
|
+
),
|
|
48
|
+
/* @__PURE__ */ jsxs(
|
|
49
|
+
"span",
|
|
50
|
+
{
|
|
51
|
+
className: cn(
|
|
52
|
+
"flex min-h-11 min-w-0 max-w-full cursor-pointer items-center gap-2 rounded-2xl border border-border bg-background px-3 py-2 text-sm text-foreground",
|
|
53
|
+
"transition-colors hover:bg-muted motion-reduce:transition-none",
|
|
54
|
+
"peer-checked:border-primary peer-checked:bg-primary/10 peer-checked:shadow-[inset_0_0_0_1px_var(--primary)] peer-checked:text-primary",
|
|
55
|
+
"peer-focus-visible:outline-2 peer-focus-visible:outline-offset-2 peer-focus-visible:outline-ring",
|
|
56
|
+
"peer-disabled:pointer-events-none peer-disabled:cursor-not-allowed",
|
|
57
|
+
"[&_.filter-check]:hidden peer-checked:[&_.filter-check]:block peer-checked:[&_.filter-icon]:hidden"
|
|
58
|
+
),
|
|
59
|
+
children: [
|
|
60
|
+
/* @__PURE__ */ jsx(
|
|
61
|
+
Check,
|
|
62
|
+
{
|
|
63
|
+
"aria-hidden": true,
|
|
64
|
+
className: "filter-check size-4 shrink-0",
|
|
65
|
+
strokeWidth: 2.5
|
|
66
|
+
}
|
|
67
|
+
),
|
|
68
|
+
icon && /* @__PURE__ */ jsx("span", { "aria-hidden": true, className: "filter-icon shrink-0 [&>svg]:size-4", children: icon }),
|
|
69
|
+
/* @__PURE__ */ jsx("span", { className: "min-w-0 [overflow-wrap:anywhere]", children: label }),
|
|
70
|
+
count != null && /* @__PURE__ */ jsx(
|
|
71
|
+
"span",
|
|
72
|
+
{
|
|
73
|
+
"aria-hidden": true,
|
|
74
|
+
className: "shrink-0 text-xs tabular-nums text-muted-foreground",
|
|
75
|
+
children: count
|
|
76
|
+
}
|
|
77
|
+
)
|
|
78
|
+
]
|
|
79
|
+
}
|
|
80
|
+
)
|
|
81
|
+
]
|
|
82
|
+
}
|
|
83
|
+
);
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
export { FilterOptionChip };
|
|
@@ -3,10 +3,10 @@ import * as React from 'react';
|
|
|
3
3
|
import { VariantProps } from 'class-variance-authority';
|
|
4
4
|
|
|
5
5
|
declare const alertVariants: (props?: ({
|
|
6
|
-
variant?: "default" | "
|
|
6
|
+
variant?: "default" | "destructive" | "warning" | "success" | null | undefined;
|
|
7
7
|
} & class_variance_authority_types.ClassProp) | undefined) => string;
|
|
8
8
|
declare const Alert: React.ForwardRefExoticComponent<React.HTMLAttributes<HTMLDivElement> & VariantProps<(props?: ({
|
|
9
|
-
variant?: "default" | "
|
|
9
|
+
variant?: "default" | "destructive" | "warning" | "success" | null | undefined;
|
|
10
10
|
} & class_variance_authority_types.ClassProp) | undefined) => string> & React.RefAttributes<HTMLDivElement>>;
|
|
11
11
|
declare const AlertTitle: React.ForwardRefExoticComponent<React.HTMLAttributes<HTMLHeadingElement> & React.RefAttributes<HTMLParagraphElement>>;
|
|
12
12
|
declare const AlertDescription: React.ForwardRefExoticComponent<React.HTMLAttributes<HTMLParagraphElement> & React.RefAttributes<HTMLParagraphElement>>;
|
|
@@ -4,7 +4,7 @@ import * as React from 'react';
|
|
|
4
4
|
import { VariantProps } from 'class-variance-authority';
|
|
5
5
|
|
|
6
6
|
declare const badgeVariants: (props?: ({
|
|
7
|
-
variant?: "
|
|
7
|
+
variant?: "code" | "default" | "destructive" | "outline" | "secondary" | "glass" | "overlay" | "brown" | "warning" | "success" | "onPrimary" | "confirmed" | "pending" | "completed" | "assignee" | "softSuccess" | "softWarning" | "softDestructive" | "softNeutral" | null | undefined;
|
|
8
8
|
size?: "status" | "chip" | null | undefined;
|
|
9
9
|
live?: boolean | null | undefined;
|
|
10
10
|
} & class_variance_authority_types.ClassProp) | undefined) => string;
|
|
@@ -31,7 +31,7 @@ import { VariantProps } from 'class-variance-authority';
|
|
|
31
31
|
* right edge, centred on the text, and never wraps under it.
|
|
32
32
|
*/
|
|
33
33
|
declare const bannerVariants: (props?: ({
|
|
34
|
-
tone?: "
|
|
34
|
+
tone?: "destructive" | "warning" | "info" | null | undefined;
|
|
35
35
|
} & class_variance_authority_types.ClassProp) | undefined) => string;
|
|
36
36
|
type BannerProps = Omit<React.HTMLAttributes<HTMLDivElement>, "title"> & VariantProps<typeof bannerVariants> & {
|
|
37
37
|
/**
|
|
@@ -3,8 +3,8 @@ import * as React from 'react';
|
|
|
3
3
|
import { VariantProps } from 'class-variance-authority';
|
|
4
4
|
|
|
5
5
|
declare const buttonVariants: (props?: ({
|
|
6
|
-
variant?: "
|
|
7
|
-
size?: "default" | "
|
|
6
|
+
variant?: "link" | "default" | "destructive" | "outline" | "secondary" | "ghost" | "glass" | "overlay" | "ink" | "brown" | "warning" | "cta" | null | undefined;
|
|
7
|
+
size?: "default" | "cta" | "xs" | "sm" | "lg" | "pill" | "cta-sm" | "icon" | "icon-xs" | "icon-sm" | "icon-lg" | null | undefined;
|
|
8
8
|
fullWidth?: boolean | null | undefined;
|
|
9
9
|
} & class_variance_authority_types.ClassProp) | undefined) => string;
|
|
10
10
|
interface ButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement>, VariantProps<typeof buttonVariants> {
|
|
@@ -3,12 +3,12 @@ import * as React from 'react';
|
|
|
3
3
|
import { VariantProps } from 'class-variance-authority';
|
|
4
4
|
|
|
5
5
|
declare const cardVariants: (props?: ({
|
|
6
|
-
variant?: "
|
|
6
|
+
variant?: "section" | "outline" | "glass" | "muted" | "surface" | "elevated" | "elevatedPanel" | null | undefined;
|
|
7
7
|
size?: "default" | "sm" | "lg" | null | undefined;
|
|
8
8
|
interactive?: boolean | null | undefined;
|
|
9
9
|
} & class_variance_authority_types.ClassProp) | undefined) => string;
|
|
10
10
|
declare const Card: React.ForwardRefExoticComponent<React.HTMLAttributes<HTMLDivElement> & VariantProps<(props?: ({
|
|
11
|
-
variant?: "
|
|
11
|
+
variant?: "section" | "outline" | "glass" | "muted" | "surface" | "elevated" | "elevatedPanel" | null | undefined;
|
|
12
12
|
size?: "default" | "sm" | "lg" | null | undefined;
|
|
13
13
|
interactive?: boolean | null | undefined;
|
|
14
14
|
} & class_variance_authority_types.ClassProp) | undefined) => string> & React.RefAttributes<HTMLDivElement>>;
|
|
@@ -4,11 +4,11 @@ import { DialogProps } from '@radix-ui/react-dialog';
|
|
|
4
4
|
|
|
5
5
|
declare const Command: React.ForwardRefExoticComponent<Omit<{
|
|
6
6
|
children?: React.ReactNode;
|
|
7
|
-
} & Pick<Pick<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, keyof React.HTMLAttributes<HTMLDivElement
|
|
7
|
+
} & Pick<Pick<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "key" | keyof React.HTMLAttributes<HTMLDivElement>> & {
|
|
8
8
|
ref?: React.Ref<HTMLDivElement>;
|
|
9
9
|
} & {
|
|
10
10
|
asChild?: boolean;
|
|
11
|
-
}, keyof React.HTMLAttributes<HTMLDivElement> | "asChild"
|
|
11
|
+
}, "key" | keyof React.HTMLAttributes<HTMLDivElement> | "asChild"> & {
|
|
12
12
|
label?: string;
|
|
13
13
|
shouldFilter?: boolean;
|
|
14
14
|
filter?: (value: string, search: string, keywords?: string[]) => number;
|
|
@@ -28,61 +28,61 @@ declare const CommandInput: React.ForwardRefExoticComponent<Omit<Omit<Pick<Pick<
|
|
|
28
28
|
ref?: React.Ref<HTMLInputElement>;
|
|
29
29
|
} & {
|
|
30
30
|
asChild?: boolean;
|
|
31
|
-
}, "
|
|
31
|
+
}, "key" | "asChild" | keyof React.InputHTMLAttributes<HTMLInputElement>>, "onChange" | "type" | "value"> & {
|
|
32
32
|
value?: string;
|
|
33
33
|
onValueChange?: (search: string) => void;
|
|
34
34
|
} & React.RefAttributes<HTMLInputElement>, "ref"> & React.RefAttributes<HTMLInputElement>>;
|
|
35
35
|
declare const CommandList: React.ForwardRefExoticComponent<Omit<{
|
|
36
36
|
children?: React.ReactNode;
|
|
37
|
-
} & Pick<Pick<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, keyof React.HTMLAttributes<HTMLDivElement
|
|
37
|
+
} & Pick<Pick<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "key" | keyof React.HTMLAttributes<HTMLDivElement>> & {
|
|
38
38
|
ref?: React.Ref<HTMLDivElement>;
|
|
39
39
|
} & {
|
|
40
40
|
asChild?: boolean;
|
|
41
|
-
}, keyof React.HTMLAttributes<HTMLDivElement> | "asChild"
|
|
41
|
+
}, "key" | keyof React.HTMLAttributes<HTMLDivElement> | "asChild"> & {
|
|
42
42
|
label?: string;
|
|
43
43
|
} & React.RefAttributes<HTMLDivElement>, "ref"> & React.RefAttributes<HTMLDivElement>>;
|
|
44
44
|
declare const CommandEmpty: React.ForwardRefExoticComponent<Omit<{
|
|
45
45
|
children?: React.ReactNode;
|
|
46
|
-
} & Pick<Pick<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, keyof React.HTMLAttributes<HTMLDivElement
|
|
46
|
+
} & Pick<Pick<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "key" | keyof React.HTMLAttributes<HTMLDivElement>> & {
|
|
47
47
|
ref?: React.Ref<HTMLDivElement>;
|
|
48
48
|
} & {
|
|
49
49
|
asChild?: boolean;
|
|
50
|
-
}, keyof React.HTMLAttributes<HTMLDivElement> | "asChild"
|
|
50
|
+
}, "key" | keyof React.HTMLAttributes<HTMLDivElement> | "asChild"> & React.RefAttributes<HTMLDivElement>, "ref"> & React.RefAttributes<HTMLDivElement>>;
|
|
51
51
|
declare const CommandLoading: React.ForwardRefExoticComponent<Omit<{
|
|
52
52
|
children?: React.ReactNode;
|
|
53
|
-
} & Pick<Pick<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, keyof React.HTMLAttributes<HTMLDivElement
|
|
53
|
+
} & Pick<Pick<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "key" | keyof React.HTMLAttributes<HTMLDivElement>> & {
|
|
54
54
|
ref?: React.Ref<HTMLDivElement>;
|
|
55
55
|
} & {
|
|
56
56
|
asChild?: boolean;
|
|
57
|
-
}, keyof React.HTMLAttributes<HTMLDivElement> | "asChild"
|
|
57
|
+
}, "key" | keyof React.HTMLAttributes<HTMLDivElement> | "asChild"> & {
|
|
58
58
|
progress?: number;
|
|
59
59
|
label?: string;
|
|
60
60
|
} & React.RefAttributes<HTMLDivElement>, "ref"> & React.RefAttributes<HTMLDivElement>>;
|
|
61
61
|
declare const CommandGroup: React.ForwardRefExoticComponent<Omit<{
|
|
62
62
|
children?: React.ReactNode;
|
|
63
|
-
} & Omit<Pick<Pick<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, keyof React.HTMLAttributes<HTMLDivElement
|
|
63
|
+
} & Omit<Pick<Pick<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "key" | keyof React.HTMLAttributes<HTMLDivElement>> & {
|
|
64
64
|
ref?: React.Ref<HTMLDivElement>;
|
|
65
65
|
} & {
|
|
66
66
|
asChild?: boolean;
|
|
67
|
-
}, keyof React.HTMLAttributes<HTMLDivElement> | "asChild"
|
|
67
|
+
}, "key" | keyof React.HTMLAttributes<HTMLDivElement> | "asChild">, "heading" | "value"> & {
|
|
68
68
|
heading?: React.ReactNode;
|
|
69
69
|
value?: string;
|
|
70
70
|
forceMount?: boolean;
|
|
71
71
|
} & React.RefAttributes<HTMLDivElement>, "ref"> & React.RefAttributes<HTMLDivElement>>;
|
|
72
|
-
declare const CommandSeparator: React.ForwardRefExoticComponent<Omit<Pick<Pick<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, keyof React.HTMLAttributes<HTMLDivElement
|
|
72
|
+
declare const CommandSeparator: React.ForwardRefExoticComponent<Omit<Pick<Pick<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "key" | keyof React.HTMLAttributes<HTMLDivElement>> & {
|
|
73
73
|
ref?: React.Ref<HTMLDivElement>;
|
|
74
74
|
} & {
|
|
75
75
|
asChild?: boolean;
|
|
76
|
-
}, keyof React.HTMLAttributes<HTMLDivElement> | "asChild"
|
|
76
|
+
}, "key" | keyof React.HTMLAttributes<HTMLDivElement> | "asChild"> & {
|
|
77
77
|
alwaysRender?: boolean;
|
|
78
78
|
} & React.RefAttributes<HTMLDivElement>, "ref"> & React.RefAttributes<HTMLDivElement>>;
|
|
79
79
|
declare const CommandItem: React.ForwardRefExoticComponent<Omit<{
|
|
80
80
|
children?: React.ReactNode;
|
|
81
|
-
} & Omit<Pick<Pick<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, keyof React.HTMLAttributes<HTMLDivElement
|
|
81
|
+
} & Omit<Pick<Pick<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "key" | keyof React.HTMLAttributes<HTMLDivElement>> & {
|
|
82
82
|
ref?: React.Ref<HTMLDivElement>;
|
|
83
83
|
} & {
|
|
84
84
|
asChild?: boolean;
|
|
85
|
-
}, keyof React.HTMLAttributes<HTMLDivElement> | "asChild"
|
|
85
|
+
}, "key" | keyof React.HTMLAttributes<HTMLDivElement> | "asChild">, "onSelect" | "disabled" | "value"> & {
|
|
86
86
|
disabled?: boolean;
|
|
87
87
|
onSelect?: (value: string) => void;
|
|
88
88
|
value?: string;
|
|
@@ -53,7 +53,7 @@ interface EmptyStateProps {
|
|
|
53
53
|
* louder than a load failure the user can retry.
|
|
54
54
|
*/
|
|
55
55
|
declare const EmptyState: React.ForwardRefExoticComponent<EmptyStateProps & React.RefAttributes<HTMLDivElement>>;
|
|
56
|
-
declare const SearchEmptyState: React.ForwardRefExoticComponent<Omit<EmptyStateProps, "
|
|
57
|
-
declare const ErrorEmptyState: React.ForwardRefExoticComponent<Omit<EmptyStateProps, "
|
|
56
|
+
declare const SearchEmptyState: React.ForwardRefExoticComponent<Omit<EmptyStateProps, "variant" | "icon"> & React.RefAttributes<HTMLDivElement>>;
|
|
57
|
+
declare const ErrorEmptyState: React.ForwardRefExoticComponent<Omit<EmptyStateProps, "variant" | "icon"> & React.RefAttributes<HTMLDivElement>>;
|
|
58
58
|
|
|
59
59
|
export { EmptyState, ErrorEmptyState, SearchEmptyState };
|
|
@@ -58,6 +58,12 @@ type FacetGroupProps = Omit<ComponentPropsWithoutRef<"fieldset">, "title" | "chi
|
|
|
58
58
|
*/
|
|
59
59
|
name?: string;
|
|
60
60
|
size?: FacetGroupSize;
|
|
61
|
+
/** Wrapping native-input chips for filter panels. Rows remain the default. */
|
|
62
|
+
layout?: "rows" | "chips";
|
|
63
|
+
/** Optional bounded chip list; selected options always stay visible. */
|
|
64
|
+
visibleLimit?: number;
|
|
65
|
+
showAllLabel?: string | ((count: number) => string);
|
|
66
|
+
showLessLabel?: string;
|
|
61
67
|
/**
|
|
62
68
|
* Turns the legend into a disclosure toggle for this group's options.
|
|
63
69
|
*
|
|
@@ -84,7 +90,7 @@ type FacetGroupProps = Omit<ComponentPropsWithoutRef<"fieldset">, "title" | "chi
|
|
|
84
90
|
moreExpanded?: boolean;
|
|
85
91
|
className?: string;
|
|
86
92
|
};
|
|
87
|
-
declare function FacetGroup({ title, icon: Icon, options, selection, name, size, collapsible, defaultOpen, onToggle, moreLabel, onMore, moreExpanded, className, ...rest }: FacetGroupProps): react_jsx_runtime.JSX.Element;
|
|
93
|
+
declare function FacetGroup({ title, icon: Icon, options, selection, name, size, layout, visibleLimit, showAllLabel, showLessLabel, collapsible, defaultOpen, onToggle, moreLabel, onMore, moreExpanded, className, ...rest }: FacetGroupProps): react_jsx_runtime.JSX.Element;
|
|
88
94
|
type FacetGroupSkeletonProps = {
|
|
89
95
|
/** How many option rows to draw — match the expected/last-known option count. */
|
|
90
96
|
optionCount?: number;
|
|
@@ -92,9 +98,10 @@ type FacetGroupSkeletonProps = {
|
|
|
92
98
|
showMore?: boolean;
|
|
93
99
|
/** Must match the `<FacetGroup>` it stands in for, or rows shift when data lands. */
|
|
94
100
|
size?: FacetGroupSize;
|
|
101
|
+
layout?: "rows" | "chips";
|
|
95
102
|
className?: string;
|
|
96
103
|
};
|
|
97
104
|
/** Mirrors `<FacetGroup>`'s geometry exactly so nothing shifts when data lands. */
|
|
98
|
-
declare function FacetGroupSkeleton({ optionCount, showMore, size, className, }: FacetGroupSkeletonProps): react_jsx_runtime.JSX.Element;
|
|
105
|
+
declare function FacetGroupSkeleton({ optionCount, showMore, size, className, layout, }: FacetGroupSkeletonProps): react_jsx_runtime.JSX.Element;
|
|
99
106
|
|
|
100
107
|
export { FacetGroup, type FacetGroupProps, type FacetGroupSelection, type FacetGroupSize, FacetGroupSkeleton, type FacetGroupSkeletonProps, type FacetOption };
|
|
@@ -1,9 +1,17 @@
|
|
|
1
|
+
import { FilterOptionGroup } from '../chunk-GIJGVFGC.js';
|
|
2
|
+
import '../chunk-RKNPPYRU.js';
|
|
3
|
+
import '../chunk-NWZGSLPU.js';
|
|
1
4
|
import { Skeleton } from '../chunk-XBBEX4SF.js';
|
|
5
|
+
import { Button } from '../chunk-GHKTVHQG.js';
|
|
6
|
+
import '../chunk-RIH2IS7X.js';
|
|
7
|
+
import '../chunk-5YNIQ2BL.js';
|
|
8
|
+
import '../chunk-ZLMRVBD7.js';
|
|
9
|
+
import '../chunk-RYPPN2GZ.js';
|
|
2
10
|
import { cn } from '../chunk-FEK5XGZW.js';
|
|
3
11
|
import { __objRest, __spreadProps, __spreadValues } from '../chunk-MMUBH76A.js';
|
|
4
12
|
import { useId, useState } from 'react';
|
|
5
13
|
import { ChevronDown, Check } from 'lucide-react';
|
|
6
|
-
import {
|
|
14
|
+
import { jsx, jsxs } from 'react/jsx-runtime';
|
|
7
15
|
|
|
8
16
|
var ROW_SIZE = {
|
|
9
17
|
comfortable: "-mx-2 min-h-11 rounded-lg px-2",
|
|
@@ -21,6 +29,10 @@ function FacetGroup(_a) {
|
|
|
21
29
|
selection = "multiple",
|
|
22
30
|
name,
|
|
23
31
|
size = "comfortable",
|
|
32
|
+
layout = "rows",
|
|
33
|
+
visibleLimit,
|
|
34
|
+
showAllLabel,
|
|
35
|
+
showLessLabel,
|
|
24
36
|
collapsible = false,
|
|
25
37
|
defaultOpen = true,
|
|
26
38
|
onToggle,
|
|
@@ -35,6 +47,10 @@ function FacetGroup(_a) {
|
|
|
35
47
|
"selection",
|
|
36
48
|
"name",
|
|
37
49
|
"size",
|
|
50
|
+
"layout",
|
|
51
|
+
"visibleLimit",
|
|
52
|
+
"showAllLabel",
|
|
53
|
+
"showLessLabel",
|
|
38
54
|
"collapsible",
|
|
39
55
|
"defaultOpen",
|
|
40
56
|
"onToggle",
|
|
@@ -50,6 +66,48 @@ function FacetGroup(_a) {
|
|
|
50
66
|
const setOpen = setIsOpen;
|
|
51
67
|
const fallbackName = useId();
|
|
52
68
|
const groupName = name != null ? name : fallbackName;
|
|
69
|
+
if (layout === "chips") {
|
|
70
|
+
const value = options.filter((option) => option.checked).map((option) => option.id);
|
|
71
|
+
return /* @__PURE__ */ jsx(
|
|
72
|
+
FilterOptionGroup,
|
|
73
|
+
{
|
|
74
|
+
title,
|
|
75
|
+
options: options.map((option) => __spreadProps(__spreadValues({}, option), { value: option.id })),
|
|
76
|
+
value,
|
|
77
|
+
selection,
|
|
78
|
+
name: groupName,
|
|
79
|
+
defaultOpen,
|
|
80
|
+
collapsible,
|
|
81
|
+
divider: false,
|
|
82
|
+
visibleLimit,
|
|
83
|
+
showAllLabel,
|
|
84
|
+
showLessLabel,
|
|
85
|
+
disabled: rest.disabled,
|
|
86
|
+
className,
|
|
87
|
+
onValueChange: (next) => {
|
|
88
|
+
if (selection === "single") {
|
|
89
|
+
if (next[0] != null) onToggle == null ? void 0 : onToggle(String(next[0]), true);
|
|
90
|
+
return;
|
|
91
|
+
}
|
|
92
|
+
for (const option of options) {
|
|
93
|
+
const checked = next.includes(option.id);
|
|
94
|
+
if (checked !== !!option.checked) onToggle == null ? void 0 : onToggle(option.id, checked);
|
|
95
|
+
}
|
|
96
|
+
},
|
|
97
|
+
footer: moreLabel && /* @__PURE__ */ jsx(
|
|
98
|
+
Button,
|
|
99
|
+
{
|
|
100
|
+
type: "button",
|
|
101
|
+
variant: "link",
|
|
102
|
+
className: "min-h-11 px-0",
|
|
103
|
+
onClick: onMore,
|
|
104
|
+
"aria-expanded": moreExpanded,
|
|
105
|
+
children: moreLabel
|
|
106
|
+
}
|
|
107
|
+
)
|
|
108
|
+
}
|
|
109
|
+
);
|
|
110
|
+
}
|
|
53
111
|
return (
|
|
54
112
|
// NO SEPARATOR OF ITS OWN. This drew `<Separator className="absolute
|
|
55
113
|
// inset-x-0 top-0" />`, which looked like a rule above each group and was
|
|
@@ -98,7 +156,14 @@ function FacetGroup(_a) {
|
|
|
98
156
|
open ? "mb-[11px]" : "mb-0"
|
|
99
157
|
),
|
|
100
158
|
children: [
|
|
101
|
-
Icon && /* @__PURE__ */ jsx(
|
|
159
|
+
Icon && /* @__PURE__ */ jsx(
|
|
160
|
+
Icon,
|
|
161
|
+
{
|
|
162
|
+
"aria-hidden": true,
|
|
163
|
+
className: "size-3.5 shrink-0",
|
|
164
|
+
strokeWidth: 2.25
|
|
165
|
+
}
|
|
166
|
+
),
|
|
102
167
|
title,
|
|
103
168
|
/* @__PURE__ */ jsx(
|
|
104
169
|
ChevronDown,
|
|
@@ -114,7 +179,14 @@ function FacetGroup(_a) {
|
|
|
114
179
|
}
|
|
115
180
|
)
|
|
116
181
|
) : /* @__PURE__ */ jsxs("span", { className: "flex items-center gap-1.5", children: [
|
|
117
|
-
Icon && /* @__PURE__ */ jsx(
|
|
182
|
+
Icon && /* @__PURE__ */ jsx(
|
|
183
|
+
Icon,
|
|
184
|
+
{
|
|
185
|
+
"aria-hidden": true,
|
|
186
|
+
className: "size-3.5 shrink-0",
|
|
187
|
+
strokeWidth: 2.25
|
|
188
|
+
}
|
|
189
|
+
),
|
|
118
190
|
title
|
|
119
191
|
] })
|
|
120
192
|
}
|
|
@@ -164,7 +236,13 @@ function FacetGroup(_a) {
|
|
|
164
236
|
"peer-focus-visible:ring-2 peer-focus-visible:ring-ring peer-focus-visible:ring-offset-2",
|
|
165
237
|
checked ? "border-primary bg-primary" : "border-border bg-background"
|
|
166
238
|
),
|
|
167
|
-
children: checked && (isSingle ? /* @__PURE__ */ jsx("span", { className: "size-[7px] rounded-full bg-primary-foreground" }) : /* @__PURE__ */ jsx(
|
|
239
|
+
children: checked && (isSingle ? /* @__PURE__ */ jsx("span", { className: "size-[7px] rounded-full bg-primary-foreground" }) : /* @__PURE__ */ jsx(
|
|
240
|
+
Check,
|
|
241
|
+
{
|
|
242
|
+
className: "h-[11px] w-[11px] text-primary-foreground",
|
|
243
|
+
strokeWidth: 3
|
|
244
|
+
}
|
|
245
|
+
))
|
|
168
246
|
}
|
|
169
247
|
),
|
|
170
248
|
/* @__PURE__ */ jsx(
|
|
@@ -205,18 +283,38 @@ function FacetGroupSkeleton({
|
|
|
205
283
|
optionCount = 4,
|
|
206
284
|
showMore,
|
|
207
285
|
size = "comfortable",
|
|
208
|
-
className
|
|
286
|
+
className,
|
|
287
|
+
layout = "rows"
|
|
209
288
|
}) {
|
|
289
|
+
if (layout === "chips")
|
|
290
|
+
return /* @__PURE__ */ jsxs("div", { "aria-hidden": "true", className: cn("py-3", className), children: [
|
|
291
|
+
/* @__PURE__ */ jsx(Skeleton, { className: "mb-4 h-4 w-24" }),
|
|
292
|
+
/* @__PURE__ */ jsx("div", { className: "flex flex-wrap gap-2", children: Array.from({ length: optionCount }, (_, index) => /* @__PURE__ */ jsx(
|
|
293
|
+
Skeleton,
|
|
294
|
+
{
|
|
295
|
+
className: cn("h-11 rounded-2xl", index % 2 ? "w-28" : "w-24")
|
|
296
|
+
},
|
|
297
|
+
index
|
|
298
|
+
)) }),
|
|
299
|
+
showMore && /* @__PURE__ */ jsx(Skeleton, { className: "mt-3 h-4 w-20" })
|
|
300
|
+
] });
|
|
210
301
|
return (
|
|
211
302
|
// Matches the live group: no rule of its own, `py-3`, and the row gap keyed
|
|
212
303
|
// to the same density — or the panel shifts on load by the difference.
|
|
213
304
|
/* @__PURE__ */ jsxs("div", { "aria-hidden": "true", className: cn("py-3", className), children: [
|
|
214
305
|
/* @__PURE__ */ jsx(Skeleton, { className: "mb-[11px] h-3 w-20" }),
|
|
215
|
-
/* @__PURE__ */ jsx("div", { className: cn("flex flex-col", ROW_GAP[size]), children: Array.from({ length: optionCount }).map((_, index) => /* @__PURE__ */ jsxs(
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
306
|
+
/* @__PURE__ */ jsx("div", { className: cn("flex flex-col", ROW_GAP[size]), children: Array.from({ length: optionCount }).map((_, index) => /* @__PURE__ */ jsxs(
|
|
307
|
+
"div",
|
|
308
|
+
{
|
|
309
|
+
className: cn("flex items-center gap-[9px]", ROW_SIZE[size]),
|
|
310
|
+
children: [
|
|
311
|
+
/* @__PURE__ */ jsx(Skeleton, { className: "h-4 w-4 rounded-[5px]" }),
|
|
312
|
+
/* @__PURE__ */ jsx(Skeleton, { className: "h-3.5 w-24" }),
|
|
313
|
+
/* @__PURE__ */ jsx(Skeleton, { className: "ml-auto h-3 w-5" })
|
|
314
|
+
]
|
|
315
|
+
},
|
|
316
|
+
index
|
|
317
|
+
)) }),
|
|
220
318
|
showMore && /* @__PURE__ */ jsx(Skeleton, { className: "mt-[11px] h-3 w-16" })
|
|
221
319
|
] })
|
|
222
320
|
);
|