@bearmenu/ui 0.6.1 → 0.7.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/chunk-A5ONAJCE.js +102 -0
- package/dist/chunk-AV777R4G.js +43 -0
- package/dist/{chunk-WKMLZDUT.js → chunk-FRPPIXMY.js} +1 -1
- package/dist/{chunk-PSR7N36A.js → chunk-HCM6LKM5.js} +1 -1
- package/dist/{chunk-YJ6OBKZJ.js → chunk-TL4YU2O5.js} +10 -3
- package/dist/chunk-UX6SWAKH.js +320 -0
- package/dist/{chunk-7PPCH42H.js → chunk-VQNDZVI7.js} +1 -1
- package/dist/chunk-WSRWFA6K.js +26 -0
- package/dist/chunk-YLNYXPIH.js +61 -0
- package/dist/components/accordion.js +1 -1
- package/dist/components/badge.d.ts +2 -1
- package/dist/components/badge.js +1 -1
- package/dist/components/card.js +127 -4
- package/dist/components/combobox.js +2 -2
- package/dist/components/command.js +2 -2
- package/dist/components/currency-input.js +1 -1
- package/dist/components/date-input.js +1 -1
- package/dist/components/dialog.js +1 -1
- package/dist/components/filter-category-row.d.ts +13 -0
- package/dist/components/filter-category-row.js +44 -0
- package/dist/components/input-group.d.ts +2 -0
- package/dist/components/input-group.js +10 -5
- package/dist/components/input.d.ts +1 -0
- package/dist/components/input.js +1 -1
- package/dist/components/multi-select-combobox.js +3 -3
- package/dist/components/phone-frame.js +1 -1
- package/dist/components/place-about-tab.d.ts +2 -2
- package/dist/components/place-about-tab.js +4 -3
- package/dist/components/place-details-mobile.js +5 -3
- package/dist/components/place-schedule-week.d.ts +19 -0
- package/dist/components/place-schedule-week.js +4 -0
- package/dist/components/place-types.d.ts +18 -9
- package/dist/components/scroll-fade.js +7 -2
- package/dist/components/searchable-select.js +2 -2
- package/dist/components/separator.js +3 -26
- package/dist/components/sheet.js +1 -1
- package/dist/components/sliding-panels.d.ts +1 -0
- package/dist/components/sliding-panels.js +22 -6
- package/dist/components/sort-option-list.d.ts +16 -0
- package/dist/components/sort-option-list.js +46 -0
- package/dist/components/tabs.js +98 -17
- package/dist/components/tag.js +3 -61
- package/dist/components/toast.js +1 -1
- package/dist/components/toaster.js +1 -1
- package/package.json +23 -113
- package/src/components/accordion.tsx +1 -1
- package/src/components/badge.tsx +9 -2
- package/src/components/card.tsx +22 -18
- package/src/components/dialog.tsx +1 -1
- package/src/components/filter-category-row.tsx +52 -0
- package/src/components/input-group.tsx +9 -4
- package/src/components/input.tsx +8 -3
- package/src/components/phone-frame.tsx +1 -1
- package/src/components/place-about-tab.stories.tsx +24 -13
- package/src/components/place-about-tab.test.tsx +92 -38
- package/src/components/place-about-tab.tsx +310 -344
- package/src/components/place-schedule-week.tsx +128 -0
- package/src/components/place-types.ts +27 -8
- package/src/components/scroll-fade.tsx +9 -4
- package/src/components/sheet.tsx +1 -1
- package/src/components/sliding-panels.tsx +33 -6
- package/src/components/sort-option-list.tsx +57 -0
- package/src/components/tabs.tsx +76 -11
- package/src/components/toast.tsx +1 -1
- package/src/globals.css +77 -19
- package/src/lib/motion.ts +137 -0
- package/dist/chunk-BAZFVSSG.js +0 -279
- package/dist/chunk-RIDXFY6M.js +0 -38
- package/dist/chunk-XK2ZDQVE.js +0 -122
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { cn } from '../chunk-FEK5XGZW.js';
|
|
2
|
+
import '../chunk-3GWWZKX7.js';
|
|
3
|
+
import { Check } from 'lucide-react';
|
|
4
|
+
import { jsx, jsxs } from 'react/jsx-runtime';
|
|
5
|
+
|
|
6
|
+
function SortOptionList({
|
|
7
|
+
options,
|
|
8
|
+
value,
|
|
9
|
+
onChange,
|
|
10
|
+
ariaLabel,
|
|
11
|
+
className
|
|
12
|
+
}) {
|
|
13
|
+
return /* @__PURE__ */ jsx(
|
|
14
|
+
"div",
|
|
15
|
+
{
|
|
16
|
+
role: "radiogroup",
|
|
17
|
+
"aria-label": ariaLabel,
|
|
18
|
+
className: cn("px-2 pb-6", className),
|
|
19
|
+
children: options.map((option) => {
|
|
20
|
+
const isActive = option.value === value;
|
|
21
|
+
return /* @__PURE__ */ jsxs(
|
|
22
|
+
"button",
|
|
23
|
+
{
|
|
24
|
+
type: "button",
|
|
25
|
+
role: "radio",
|
|
26
|
+
"aria-checked": isActive,
|
|
27
|
+
onClick: () => onChange(option.value),
|
|
28
|
+
className: cn(
|
|
29
|
+
"flex w-full items-center justify-between rounded-lg px-3 py-3 text-left text-sm cursor-pointer",
|
|
30
|
+
"transition-colors duration-150 motion-reduce:transition-none",
|
|
31
|
+
"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary/30",
|
|
32
|
+
isActive ? "bg-accent/10 text-accent font-semibold" : "text-foreground hover:bg-muted/50"
|
|
33
|
+
),
|
|
34
|
+
children: [
|
|
35
|
+
/* @__PURE__ */ jsx("span", { children: option.label }),
|
|
36
|
+
isActive && /* @__PURE__ */ jsx(Check, { className: "h-4 w-4", "aria-hidden": true })
|
|
37
|
+
]
|
|
38
|
+
},
|
|
39
|
+
option.value
|
|
40
|
+
);
|
|
41
|
+
})
|
|
42
|
+
}
|
|
43
|
+
);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export { SortOptionList };
|
package/dist/components/tabs.js
CHANGED
|
@@ -1,12 +1,38 @@
|
|
|
1
1
|
import { cn } from '../chunk-FEK5XGZW.js';
|
|
2
|
-
import {
|
|
2
|
+
import { __spreadValues, __objRest, __spreadProps } from '../chunk-3GWWZKX7.js';
|
|
3
3
|
import * as React from 'react';
|
|
4
4
|
import * as TabsPrimitive from '@radix-ui/react-tabs';
|
|
5
|
-
import {
|
|
5
|
+
import { motion } from 'framer-motion';
|
|
6
|
+
import { jsx, jsxs } from 'react/jsx-runtime';
|
|
6
7
|
|
|
8
|
+
var springSnappy = {
|
|
9
|
+
type: "spring",
|
|
10
|
+
damping: 30,
|
|
11
|
+
stiffness: 380
|
|
12
|
+
};
|
|
13
|
+
var springSmooth = {
|
|
14
|
+
type: "spring",
|
|
15
|
+
damping: 30,
|
|
16
|
+
stiffness: 220
|
|
17
|
+
};
|
|
18
|
+
var springSoft = {
|
|
19
|
+
type: "spring",
|
|
20
|
+
damping: 35,
|
|
21
|
+
stiffness: 140
|
|
22
|
+
};
|
|
23
|
+
var archetype = {
|
|
24
|
+
/** Drawer / Sheet / Dialog entrance. Surface arrives first; content layers after. */
|
|
25
|
+
surfaceOpen: __spreadValues({}, springSmooth),
|
|
26
|
+
/** First-reveal stagger for card grids. Per-item spring. Cap stagger at 8 items. */
|
|
27
|
+
listReveal: __spreadValues({}, springSoft),
|
|
28
|
+
/** Bottom-sheet / side-drawer entry. */
|
|
29
|
+
edgeEnter: __spreadValues({}, springSmooth),
|
|
30
|
+
/** Active tab pill, active filter chip — use with Framer Motion `layoutId`. */
|
|
31
|
+
indicatorMorph: __spreadValues({}, springSnappy)};
|
|
7
32
|
var TabsContext = React.createContext({
|
|
8
33
|
variant: "pill",
|
|
9
|
-
orientation: "horizontal"
|
|
34
|
+
orientation: "horizontal",
|
|
35
|
+
indicatorId: "tabs-indicator"
|
|
10
36
|
});
|
|
11
37
|
var Tabs = React.forwardRef((_a, ref) => {
|
|
12
38
|
var _b = _a, { className, orientation = "horizontal" } = _b, props = __objRest(_b, ["className", "orientation"]);
|
|
@@ -29,7 +55,8 @@ var TabsList = React.forwardRef((_a, ref) => {
|
|
|
29
55
|
var _b = _a, { className, variant = "pill", scrollable, children } = _b, props = __objRest(_b, ["className", "variant", "scrollable", "children"]);
|
|
30
56
|
const orientation = props["aria-orientation"] === "vertical" ? "vertical" : "horizontal";
|
|
31
57
|
const allowScroll = scrollable != null ? scrollable : orientation === "horizontal";
|
|
32
|
-
|
|
58
|
+
const indicatorId = React.useId();
|
|
59
|
+
return /* @__PURE__ */ jsx(TabsContext.Provider, { value: { variant, orientation, indicatorId }, children: /* @__PURE__ */ jsx(
|
|
33
60
|
TabsPrimitive.List,
|
|
34
61
|
__spreadProps(__spreadValues({
|
|
35
62
|
ref,
|
|
@@ -46,36 +73,90 @@ var TabsList = React.forwardRef((_a, ref) => {
|
|
|
46
73
|
});
|
|
47
74
|
TabsList.displayName = TabsPrimitive.List.displayName;
|
|
48
75
|
var TabsTrigger = React.forwardRef((_a, ref) => {
|
|
49
|
-
var _b = _a, { className } = _b, props = __objRest(_b, ["className"]);
|
|
50
|
-
const { variant, orientation } = React.useContext(TabsContext);
|
|
51
|
-
|
|
76
|
+
var _b = _a, { className, children } = _b, props = __objRest(_b, ["className", "children"]);
|
|
77
|
+
const { variant, orientation, indicatorId } = React.useContext(TabsContext);
|
|
78
|
+
const triggerRef = React.useRef(null);
|
|
79
|
+
const [isActive, setIsActive] = React.useState(false);
|
|
80
|
+
React.useEffect(() => {
|
|
81
|
+
const node = triggerRef.current;
|
|
82
|
+
if (!node) return;
|
|
83
|
+
const sync = () => setIsActive(node.getAttribute("data-state") === "active");
|
|
84
|
+
sync();
|
|
85
|
+
const observer = new MutationObserver(sync);
|
|
86
|
+
observer.observe(node, { attributes: true, attributeFilter: ["data-state"] });
|
|
87
|
+
return () => observer.disconnect();
|
|
88
|
+
}, []);
|
|
89
|
+
const composedRef = React.useCallback(
|
|
90
|
+
(node) => {
|
|
91
|
+
triggerRef.current = node;
|
|
92
|
+
if (typeof ref === "function") ref(node);
|
|
93
|
+
else if (ref) ref.current = node;
|
|
94
|
+
},
|
|
95
|
+
[ref]
|
|
96
|
+
);
|
|
97
|
+
return /* @__PURE__ */ jsxs(
|
|
52
98
|
TabsPrimitive.Trigger,
|
|
53
|
-
__spreadValues({
|
|
54
|
-
ref,
|
|
99
|
+
__spreadProps(__spreadValues({
|
|
100
|
+
ref: composedRef,
|
|
55
101
|
"data-slot": "tabs-trigger",
|
|
56
102
|
className: cn(
|
|
57
|
-
"inline-flex items-center justify-center whitespace-nowrap text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50",
|
|
58
|
-
variant === "pill" && "rounded-xl px-4 py-1.5 text-muted-foreground hover:text-foreground data-[state=active]:
|
|
59
|
-
variant === "underline" && orientation === "horizontal" && "
|
|
60
|
-
variant === "underline" && orientation === "vertical" && "
|
|
103
|
+
"relative inline-flex items-center justify-center whitespace-nowrap text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50",
|
|
104
|
+
variant === "pill" && "rounded-xl px-4 py-1.5 text-muted-foreground hover:text-foreground data-[state=active]:text-foreground",
|
|
105
|
+
variant === "underline" && orientation === "horizontal" && "h-11 rounded-none px-4 text-muted-foreground hover:text-foreground data-[state=active]:text-foreground",
|
|
106
|
+
variant === "underline" && orientation === "vertical" && "rounded-none px-4 py-2 -mr-px text-muted-foreground hover:text-foreground data-[state=active]:text-foreground justify-start",
|
|
61
107
|
className
|
|
62
108
|
)
|
|
63
|
-
}, props)
|
|
109
|
+
}, props), {
|
|
110
|
+
children: [
|
|
111
|
+
isActive && /* @__PURE__ */ jsx(
|
|
112
|
+
motion.span,
|
|
113
|
+
{
|
|
114
|
+
"aria-hidden": true,
|
|
115
|
+
layoutId: indicatorId,
|
|
116
|
+
transition: archetype.indicatorMorph,
|
|
117
|
+
className: cn(
|
|
118
|
+
"absolute inset-0 -z-0 motion-reduce:hidden",
|
|
119
|
+
variant === "pill" && "rounded-xl bg-background shadow-sm",
|
|
120
|
+
variant === "underline" && orientation === "horizontal" && "border-b-2 border-primary",
|
|
121
|
+
variant === "underline" && orientation === "vertical" && "border-r-2 border-primary"
|
|
122
|
+
)
|
|
123
|
+
}
|
|
124
|
+
),
|
|
125
|
+
isActive && /* @__PURE__ */ jsx(
|
|
126
|
+
"span",
|
|
127
|
+
{
|
|
128
|
+
"aria-hidden": true,
|
|
129
|
+
className: cn(
|
|
130
|
+
"absolute inset-0 -z-0 hidden motion-reduce:block",
|
|
131
|
+
variant === "pill" && "rounded-xl bg-background shadow-sm",
|
|
132
|
+
variant === "underline" && orientation === "horizontal" && "border-b-2 border-primary",
|
|
133
|
+
variant === "underline" && orientation === "vertical" && "border-r-2 border-primary"
|
|
134
|
+
)
|
|
135
|
+
}
|
|
136
|
+
),
|
|
137
|
+
/* @__PURE__ */ jsx("span", { className: "relative z-10 flex items-center gap-2", children })
|
|
138
|
+
]
|
|
139
|
+
})
|
|
64
140
|
);
|
|
65
141
|
});
|
|
66
142
|
TabsTrigger.displayName = TabsPrimitive.Trigger.displayName;
|
|
67
143
|
var TabsContent = React.forwardRef((_a, ref) => {
|
|
68
|
-
var _b = _a, { className } = _b, props = __objRest(_b, ["className"]);
|
|
144
|
+
var _b = _a, { className, children } = _b, props = __objRest(_b, ["className", "children"]);
|
|
69
145
|
return /* @__PURE__ */ jsx(
|
|
70
146
|
TabsPrimitive.Content,
|
|
71
|
-
__spreadValues({
|
|
147
|
+
__spreadProps(__spreadValues({
|
|
72
148
|
ref,
|
|
73
149
|
"data-slot": "tabs-content",
|
|
74
150
|
className: cn(
|
|
75
151
|
"flex-1 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 rounded-md",
|
|
152
|
+
// v1.0 motion: content-swap on activation. CSS animation so this works
|
|
153
|
+
// even outside a Framer-Motion-wrapped layout. Disabled for reduced-motion.
|
|
154
|
+
"data-[state=active]:animate-in data-[state=active]:fade-in-0 data-[state=active]:slide-in-from-bottom-1 data-[state=active]:duration-[var(--duration-quick)] data-[state=active]:ease-[var(--ease-standard)] motion-reduce:data-[state=active]:animate-none",
|
|
76
155
|
className
|
|
77
156
|
)
|
|
78
|
-
}, props)
|
|
157
|
+
}, props), {
|
|
158
|
+
children
|
|
159
|
+
})
|
|
79
160
|
);
|
|
80
161
|
});
|
|
81
162
|
TabsContent.displayName = TabsPrimitive.Content.displayName;
|
package/dist/components/tag.js
CHANGED
|
@@ -1,61 +1,3 @@
|
|
|
1
|
-
|
|
2
|
-
import
|
|
3
|
-
import
|
|
4
|
-
import { X } from 'lucide-react';
|
|
5
|
-
import { cva } from 'class-variance-authority';
|
|
6
|
-
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
7
|
-
|
|
8
|
-
var tagVariants = cva(
|
|
9
|
-
"inline-flex items-center gap-1 rounded-full border text-xs font-medium transition-colors",
|
|
10
|
-
{
|
|
11
|
-
variants: {
|
|
12
|
-
variant: {
|
|
13
|
-
default: "border-border bg-muted text-foreground",
|
|
14
|
-
primary: "border-primary/30 bg-primary/10 text-primary",
|
|
15
|
-
success: "border-success/30 bg-success/10 text-success",
|
|
16
|
-
warning: "border-warning/30 bg-warning/10 text-warning",
|
|
17
|
-
destructive: "border-destructive/30 bg-destructive/10 text-destructive",
|
|
18
|
-
outline: "border-border bg-transparent text-foreground"
|
|
19
|
-
},
|
|
20
|
-
size: {
|
|
21
|
-
sm: "h-5 px-2 text-[10px]",
|
|
22
|
-
default: "h-6 px-2.5",
|
|
23
|
-
lg: "h-7 px-3 text-sm"
|
|
24
|
-
}
|
|
25
|
-
},
|
|
26
|
-
defaultVariants: {
|
|
27
|
-
variant: "default",
|
|
28
|
-
size: "default"
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
);
|
|
32
|
-
var Tag = React.forwardRef(
|
|
33
|
-
(_a, ref) => {
|
|
34
|
-
var _b = _a, { className, variant, size, onRemove, removeLabel = "Remove", children } = _b, props = __objRest(_b, ["className", "variant", "size", "onRemove", "removeLabel", "children"]);
|
|
35
|
-
return /* @__PURE__ */ jsxs(
|
|
36
|
-
"span",
|
|
37
|
-
__spreadProps(__spreadValues({
|
|
38
|
-
ref,
|
|
39
|
-
"data-slot": "tag",
|
|
40
|
-
className: cn(tagVariants({ variant, size }), className)
|
|
41
|
-
}, props), {
|
|
42
|
-
children: [
|
|
43
|
-
children,
|
|
44
|
-
onRemove && /* @__PURE__ */ jsx(
|
|
45
|
-
"button",
|
|
46
|
-
{
|
|
47
|
-
type: "button",
|
|
48
|
-
"aria-label": removeLabel,
|
|
49
|
-
onClick: onRemove,
|
|
50
|
-
className: "-mr-0.5 inline-flex size-3.5 items-center justify-center rounded-full transition-colors hover:bg-foreground/10 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",
|
|
51
|
-
children: /* @__PURE__ */ jsx(X, { className: "size-3" })
|
|
52
|
-
}
|
|
53
|
-
)
|
|
54
|
-
]
|
|
55
|
-
})
|
|
56
|
-
);
|
|
57
|
-
}
|
|
58
|
-
);
|
|
59
|
-
Tag.displayName = "Tag";
|
|
60
|
-
|
|
61
|
-
export { Tag, tagVariants };
|
|
1
|
+
export { Tag, tagVariants } from '../chunk-YLNYXPIH.js';
|
|
2
|
+
import '../chunk-FEK5XGZW.js';
|
|
3
|
+
import '../chunk-3GWWZKX7.js';
|
package/dist/components/toast.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
export { Toast, ToastAction, ToastClose, ToastDescription, ToastProvider, ToastTitle, ToastViewport } from '../chunk-
|
|
1
|
+
export { Toast, ToastAction, ToastClose, ToastDescription, ToastProvider, ToastTitle, ToastViewport } from '../chunk-VQNDZVI7.js';
|
|
2
2
|
import '../chunk-FEK5XGZW.js';
|
|
3
3
|
import '../chunk-3GWWZKX7.js';
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { ToastProvider, Toast, ToastTitle, ToastDescription, ToastClose, ToastViewport } from '../chunk-7PPCH42H.js';
|
|
2
1
|
import { useToast } from '../chunk-EBAMCZDW.js';
|
|
2
|
+
import { ToastProvider, Toast, ToastTitle, ToastDescription, ToastClose, ToastViewport } from '../chunk-VQNDZVI7.js';
|
|
3
3
|
import '../chunk-FEK5XGZW.js';
|
|
4
4
|
import { __objRest, __spreadProps, __spreadValues } from '../chunk-3GWWZKX7.js';
|
|
5
5
|
import { jsxs, jsx } from 'react/jsx-runtime';
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bearmenu/ui",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.7.0",
|
|
4
4
|
"description": "BearMenu design system — shared UI tokens, primitives, and components",
|
|
5
5
|
"license": "UNLICENSED",
|
|
6
6
|
"repository": {
|
|
@@ -17,119 +17,19 @@
|
|
|
17
17
|
],
|
|
18
18
|
"exports": {
|
|
19
19
|
"./globals.css": "./src/globals.css",
|
|
20
|
-
"./components
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
"./
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
"./
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
"./components/carousel": "./src/components/carousel.tsx",
|
|
32
|
-
"./components/checkbox": "./src/components/checkbox.tsx",
|
|
33
|
-
"./components/circular-progress": "./src/components/circular-progress.tsx",
|
|
34
|
-
"./components/collapsible": "./src/components/collapsible.tsx",
|
|
35
|
-
"./components/combobox": "./src/components/combobox.tsx",
|
|
36
|
-
"./components/command": "./src/components/command.tsx",
|
|
37
|
-
"./components/currency-input": "./src/components/currency-input.tsx",
|
|
38
|
-
"./components/date-input": "./src/components/date-input.tsx",
|
|
39
|
-
"./components/description-list": "./src/components/description-list.tsx",
|
|
40
|
-
"./components/dialog": "./src/components/dialog.tsx",
|
|
41
|
-
"./components/drawer": "./src/components/drawer.tsx",
|
|
42
|
-
"./components/dropdown-menu": "./src/components/dropdown-menu.tsx",
|
|
43
|
-
"./components/empty-state": "./src/components/empty-state.tsx",
|
|
44
|
-
"./components/field": "./src/components/field.tsx",
|
|
45
|
-
"./components/form": "./src/components/form.tsx",
|
|
46
|
-
"./components/haptic-button": "./src/components/haptic-button.tsx",
|
|
47
|
-
"./components/input-group": "./src/components/input-group.tsx",
|
|
48
|
-
"./components/input-otp": "./src/components/input-otp.tsx",
|
|
49
|
-
"./components/input": "./src/components/input.tsx",
|
|
50
|
-
"./components/item": "./src/components/item.tsx",
|
|
51
|
-
"./components/kbd": "./src/components/kbd.tsx",
|
|
52
|
-
"./components/label": "./src/components/label.tsx",
|
|
53
|
-
"./components/lazy-markdown": "./src/components/lazy-markdown.tsx",
|
|
54
|
-
"./components/link-button": "./src/components/link-button.tsx",
|
|
55
|
-
"./components/markdown-renderer": "./src/components/markdown-renderer.tsx",
|
|
56
|
-
"./components/multi-select-combobox": "./src/components/multi-select-combobox.tsx",
|
|
57
|
-
"./components/multi-select-menu": "./src/components/multi-select-menu.tsx",
|
|
58
|
-
"./components/native-select": "./src/components/native-select.tsx",
|
|
59
|
-
"./components/pagination": "./src/components/pagination.tsx",
|
|
60
|
-
"./components/phone-frame": "./src/components/phone-frame.tsx",
|
|
61
|
-
"./components/place-about-tab": "./src/components/place-about-tab.tsx",
|
|
62
|
-
"./components/place-card": "./src/components/place-card.tsx",
|
|
63
|
-
"./components/place-details-mobile": "./src/components/place-details-mobile.tsx",
|
|
64
|
-
"./components/place-types": "./src/components/place-types.ts",
|
|
65
|
-
"./components/popover": "./src/components/popover.tsx",
|
|
66
|
-
"./components/progress": "./src/components/progress.tsx",
|
|
67
|
-
"./components/radio-group": "./src/components/radio-group.tsx",
|
|
68
|
-
"./components/rating": "./src/components/rating.tsx",
|
|
69
|
-
"./components/scroll-area": "./src/components/scroll-area.tsx",
|
|
70
|
-
"./components/scroll-fade": "./src/components/scroll-fade.tsx",
|
|
71
|
-
"./components/search-bar": "./src/components/search-bar.tsx",
|
|
72
|
-
"./components/searchable-select": "./src/components/searchable-select.tsx",
|
|
73
|
-
"./components/select": "./src/components/select.tsx",
|
|
74
|
-
"./components/selection-bar": "./src/components/selection-bar.tsx",
|
|
75
|
-
"./components/separator": "./src/components/separator.tsx",
|
|
76
|
-
"./components/sheet": "./src/components/sheet.tsx",
|
|
77
|
-
"./components/skeleton-card": "./src/components/skeleton-card.tsx",
|
|
78
|
-
"./components/skeleton": "./src/components/skeleton.tsx",
|
|
79
|
-
"./components/slider": "./src/components/slider.tsx",
|
|
80
|
-
"./components/sliding-panels": "./src/components/sliding-panels.tsx",
|
|
81
|
-
"./components/sonner": "./src/components/sonner.tsx",
|
|
82
|
-
"./components/spinner": "./src/components/spinner.tsx",
|
|
83
|
-
"./components/stepper": "./src/components/stepper.tsx",
|
|
84
|
-
"./components/sticky-container": "./src/components/sticky-container.tsx",
|
|
85
|
-
"./components/switch": "./src/components/switch.tsx",
|
|
86
|
-
"./components/table": "./src/components/table.tsx",
|
|
87
|
-
"./components/tabs": "./src/components/tabs.tsx",
|
|
88
|
-
"./components/tag-group": "./src/components/tag-group.tsx",
|
|
89
|
-
"./components/tag": "./src/components/tag.tsx",
|
|
90
|
-
"./components/text": "./src/components/text.tsx",
|
|
91
|
-
"./components/textarea": "./src/components/textarea.tsx",
|
|
92
|
-
"./components/toast": "./src/components/toast.tsx",
|
|
93
|
-
"./components/toaster": "./src/components/toaster.tsx",
|
|
94
|
-
"./components/toggle-group": "./src/components/toggle-group.tsx",
|
|
95
|
-
"./components/toggle": "./src/components/toggle.tsx",
|
|
96
|
-
"./components/tooltip": "./src/components/tooltip.tsx",
|
|
97
|
-
"./components/use-mobile": "./src/components/use-mobile.tsx",
|
|
98
|
-
"./components/use-toast": "./src/components/use-toast.ts",
|
|
99
|
-
"./hooks/use-haptic": "./src/hooks/use-haptic.ts",
|
|
100
|
-
"./hooks/use-mobile": "./src/hooks/use-mobile.ts",
|
|
101
|
-
"./hooks/use-mounted-theme": "./src/hooks/use-mounted-theme.ts",
|
|
102
|
-
"./hooks/use-sticky": "./src/hooks/use-sticky.ts",
|
|
103
|
-
"./lib/utils": "./src/lib/utils.ts"
|
|
104
|
-
},
|
|
105
|
-
"publishConfig": {
|
|
106
|
-
"exports": {
|
|
107
|
-
"./globals.css": "./src/globals.css",
|
|
108
|
-
"./components/*": {
|
|
109
|
-
"types": "./dist/components/*.d.ts",
|
|
110
|
-
"import": "./dist/components/*.js"
|
|
111
|
-
},
|
|
112
|
-
"./hooks/*": {
|
|
113
|
-
"types": "./dist/hooks/*.d.ts",
|
|
114
|
-
"import": "./dist/hooks/*.js"
|
|
115
|
-
},
|
|
116
|
-
"./lib/*": {
|
|
117
|
-
"types": "./dist/lib/*.d.ts",
|
|
118
|
-
"import": "./dist/lib/*.js"
|
|
119
|
-
}
|
|
20
|
+
"./components/*": {
|
|
21
|
+
"types": "./dist/components/*.d.ts",
|
|
22
|
+
"import": "./dist/components/*.js"
|
|
23
|
+
},
|
|
24
|
+
"./hooks/*": {
|
|
25
|
+
"types": "./dist/hooks/*.d.ts",
|
|
26
|
+
"import": "./dist/hooks/*.js"
|
|
27
|
+
},
|
|
28
|
+
"./lib/*": {
|
|
29
|
+
"types": "./dist/lib/*.d.ts",
|
|
30
|
+
"import": "./dist/lib/*.js"
|
|
120
31
|
}
|
|
121
32
|
},
|
|
122
|
-
"scripts": {
|
|
123
|
-
"storybook": "storybook dev -p 6006",
|
|
124
|
-
"build-storybook": "storybook build",
|
|
125
|
-
"build": "tsup",
|
|
126
|
-
"dev": "tsup --watch",
|
|
127
|
-
"typecheck": "tsc --noEmit",
|
|
128
|
-
"test": "vitest run",
|
|
129
|
-
"test:watch": "vitest",
|
|
130
|
-
"clean": "rm -rf dist",
|
|
131
|
-
"prepublishOnly": "pnpm run build"
|
|
132
|
-
},
|
|
133
33
|
"peerDependencies": {
|
|
134
34
|
"@hookform/resolvers": "^3.0.0 || ^5.0.0",
|
|
135
35
|
"@radix-ui/react-accordion": "*",
|
|
@@ -237,5 +137,15 @@
|
|
|
237
137
|
"vaul": "^1.1.2",
|
|
238
138
|
"vitest": "^4.1.5",
|
|
239
139
|
"zod": "^3.25.67"
|
|
140
|
+
},
|
|
141
|
+
"scripts": {
|
|
142
|
+
"storybook": "storybook dev -p 6006",
|
|
143
|
+
"build-storybook": "storybook build",
|
|
144
|
+
"build": "tsup",
|
|
145
|
+
"dev": "tsup --watch",
|
|
146
|
+
"typecheck": "tsc --noEmit",
|
|
147
|
+
"test": "vitest run",
|
|
148
|
+
"test:watch": "vitest",
|
|
149
|
+
"clean": "rm -rf dist"
|
|
240
150
|
}
|
|
241
|
-
}
|
|
151
|
+
}
|
|
@@ -38,7 +38,7 @@ const AccordionTrigger = React.forwardRef<
|
|
|
38
38
|
{...props}
|
|
39
39
|
>
|
|
40
40
|
{children}
|
|
41
|
-
<ChevronDown className="size-4 shrink-0 text-muted-foreground transition-transform duration-
|
|
41
|
+
<ChevronDown className="size-4 shrink-0 text-muted-foreground transition-transform duration-[var(--duration-quick)] ease-[var(--ease-standard)]" />
|
|
42
42
|
</AccordionPrimitive.Trigger>
|
|
43
43
|
</AccordionPrimitive.Header>
|
|
44
44
|
));
|
package/src/components/badge.tsx
CHANGED
|
@@ -22,9 +22,16 @@ const badgeVariants = cva(
|
|
|
22
22
|
"border-transparent bg-warning text-warning-foreground",
|
|
23
23
|
brown: "border-transparent bg-brown text-brown-foreground",
|
|
24
24
|
},
|
|
25
|
+
// v1.0 motion: "live" surface signal — applies `live-pulse` archetype.
|
|
26
|
+
// Pair with a colored variant (e.g. variant="destructive" live).
|
|
27
|
+
live: {
|
|
28
|
+
true: "motion-live-pulse motion-reduce:animate-none",
|
|
29
|
+
false: "",
|
|
30
|
+
},
|
|
25
31
|
},
|
|
26
32
|
defaultVariants: {
|
|
27
33
|
variant: "default",
|
|
34
|
+
live: false,
|
|
28
35
|
},
|
|
29
36
|
}
|
|
30
37
|
);
|
|
@@ -32,8 +39,8 @@ const badgeVariants = cva(
|
|
|
32
39
|
export interface BadgeProps
|
|
33
40
|
extends React.HTMLAttributes<HTMLDivElement>, VariantProps<typeof badgeVariants> {}
|
|
34
41
|
|
|
35
|
-
function Badge({ className, variant, ...props }: BadgeProps) {
|
|
36
|
-
return <div data-slot="badge" className={cn(badgeVariants({ variant }), className)} {...props} />;
|
|
42
|
+
function Badge({ className, variant, live, ...props }: BadgeProps) {
|
|
43
|
+
return <div data-slot="badge" className={cn(badgeVariants({ variant, live }), className)} {...props} />;
|
|
37
44
|
}
|
|
38
45
|
|
|
39
46
|
export { Badge, badgeVariants };
|
package/src/components/card.tsx
CHANGED
|
@@ -3,25 +3,29 @@ import { cva, type VariantProps } from "class-variance-authority";
|
|
|
3
3
|
import { cn } from "../lib/utils";
|
|
4
4
|
import { textVariants } from "./text";
|
|
5
5
|
|
|
6
|
-
const cardVariants = cva(
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
6
|
+
const cardVariants = cva(
|
|
7
|
+
"rounded-3xl text-card-foreground transition-[background-color,border-color] duration-[var(--duration-quick)] ease-[var(--ease-standard)]",
|
|
8
|
+
{
|
|
9
|
+
variants: {
|
|
10
|
+
variant: {
|
|
11
|
+
surface: "bg-card border border-border",
|
|
12
|
+
glass: "glass",
|
|
13
|
+
outline: "bg-transparent border border-border",
|
|
14
|
+
muted: "bg-muted border border-transparent",
|
|
15
|
+
},
|
|
16
|
+
size: {
|
|
17
|
+
sm: "[&_[data-slot=card-header]]:p-4 [&_[data-slot=card-content]]:p-4 [&_[data-slot=card-content]]:pt-0 [&_[data-slot=card-footer]]:p-4 [&_[data-slot=card-footer]]:pt-0",
|
|
18
|
+
default:
|
|
19
|
+
"[&_[data-slot=card-header]]:p-6 [&_[data-slot=card-content]]:p-6 [&_[data-slot=card-content]]:pt-0 [&_[data-slot=card-footer]]:p-6 [&_[data-slot=card-footer]]:pt-0",
|
|
20
|
+
lg: "[&_[data-slot=card-header]]:p-8 [&_[data-slot=card-content]]:p-8 [&_[data-slot=card-content]]:pt-0 [&_[data-slot=card-footer]]:p-8 [&_[data-slot=card-footer]]:pt-0",
|
|
21
|
+
},
|
|
22
|
+
// Interactive variant follows v1.0 `press-response` archetype:
|
|
23
|
+
// hover lift via shadow + translate (200ms), press scale-down (instant).
|
|
24
|
+
interactive: {
|
|
25
|
+
true: "cursor-pointer transition-[transform,border-color,box-shadow] duration-[var(--duration-quick)] ease-[var(--ease-standard)] hover:border-primary/40 hover:-translate-y-0.5 hover:shadow-md active:scale-[0.97] active:duration-[var(--duration-instant)] motion-reduce:hover:translate-y-0 motion-reduce:active:scale-100",
|
|
26
|
+
false: "",
|
|
27
|
+
},
|
|
13
28
|
},
|
|
14
|
-
size: {
|
|
15
|
-
sm: "[&_[data-slot=card-header]]:p-4 [&_[data-slot=card-content]]:p-4 [&_[data-slot=card-content]]:pt-0 [&_[data-slot=card-footer]]:p-4 [&_[data-slot=card-footer]]:pt-0",
|
|
16
|
-
default:
|
|
17
|
-
"[&_[data-slot=card-header]]:p-6 [&_[data-slot=card-content]]:p-6 [&_[data-slot=card-content]]:pt-0 [&_[data-slot=card-footer]]:p-6 [&_[data-slot=card-footer]]:pt-0",
|
|
18
|
-
lg: "[&_[data-slot=card-header]]:p-8 [&_[data-slot=card-content]]:p-8 [&_[data-slot=card-content]]:pt-0 [&_[data-slot=card-footer]]:p-8 [&_[data-slot=card-footer]]:pt-0",
|
|
19
|
-
},
|
|
20
|
-
interactive: {
|
|
21
|
-
true: "cursor-pointer hover:border-primary/40 hover:-translate-y-0.5 transition-[transform,border-color] duration-200",
|
|
22
|
-
false: "",
|
|
23
|
-
},
|
|
24
|
-
},
|
|
25
29
|
defaultVariants: {
|
|
26
30
|
variant: "surface",
|
|
27
31
|
size: "default",
|
|
@@ -28,7 +28,7 @@ const DialogOverlay = React.forwardRef<
|
|
|
28
28
|
DialogOverlay.displayName = DialogPrimitive.Overlay.displayName;
|
|
29
29
|
|
|
30
30
|
const dialogContentVariants = cva(
|
|
31
|
-
"fixed left-[50%] top-[50%] z-[1000] grid w-full translate-x-[-50%] translate-y-[-50%] gap-4 bg-card p-6 shadow-2xl
|
|
31
|
+
"fixed left-[50%] top-[50%] z-[1000] grid w-full translate-x-[-50%] translate-y-[-50%] gap-4 bg-card p-6 shadow-2xl data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=open]:duration-[var(--duration-deliberate)] data-[state=closed]:duration-[var(--duration-exit-standard)] data-[state=open]:ease-[var(--ease-enter)] data-[state=closed]:ease-[var(--ease-exit)] data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 rounded-2xl border border-border",
|
|
32
32
|
{
|
|
33
33
|
variants: {
|
|
34
34
|
size: {
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import { ChevronRight, type LucideIcon } from "lucide-react";
|
|
4
|
+
import { Badge } from "./badge";
|
|
5
|
+
import { Text } from "./text";
|
|
6
|
+
|
|
7
|
+
interface FilterCategoryRowProps {
|
|
8
|
+
icon: LucideIcon;
|
|
9
|
+
label: string;
|
|
10
|
+
description: string;
|
|
11
|
+
count?: number;
|
|
12
|
+
onClick: () => void;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export function FilterCategoryRow({
|
|
16
|
+
icon: Icon,
|
|
17
|
+
label,
|
|
18
|
+
description,
|
|
19
|
+
count = 0,
|
|
20
|
+
onClick,
|
|
21
|
+
}: FilterCategoryRowProps) {
|
|
22
|
+
return (
|
|
23
|
+
<button
|
|
24
|
+
type="button"
|
|
25
|
+
onClick={onClick}
|
|
26
|
+
className="flex items-center justify-between w-full py-3 transition-colors hover:bg-muted/50 rounded-lg px-2 -mx-2"
|
|
27
|
+
>
|
|
28
|
+
<div className="flex items-center gap-3">
|
|
29
|
+
<Icon
|
|
30
|
+
aria-hidden="true"
|
|
31
|
+
className="w-5 h-5 text-muted-foreground flex-shrink-0"
|
|
32
|
+
/>
|
|
33
|
+
<div className="text-left">
|
|
34
|
+
<Text as="p" weight="medium">
|
|
35
|
+
{label}
|
|
36
|
+
</Text>
|
|
37
|
+
<Text as="p" variant="body-sm" color="muted">
|
|
38
|
+
{description}
|
|
39
|
+
</Text>
|
|
40
|
+
</div>
|
|
41
|
+
</div>
|
|
42
|
+
<div className="flex items-center gap-2">
|
|
43
|
+
{count > 0 && (
|
|
44
|
+
<Badge variant="secondary" className="text-xs">
|
|
45
|
+
{count}
|
|
46
|
+
</Badge>
|
|
47
|
+
)}
|
|
48
|
+
<ChevronRight className="w-5 h-5 text-muted-foreground" />
|
|
49
|
+
</div>
|
|
50
|
+
</button>
|
|
51
|
+
);
|
|
52
|
+
}
|
|
@@ -6,7 +6,7 @@ import { cva, type VariantProps } from "class-variance-authority";
|
|
|
6
6
|
import { cn } from "../lib/utils";
|
|
7
7
|
|
|
8
8
|
const inputGroupVariants = cva(
|
|
9
|
-
"flex items-center w-full
|
|
9
|
+
"flex items-center w-full border border-border bg-background text-base md:text-sm text-foreground transition-colors focus-within:outline-none focus-within:ring-2 focus-within:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 has-[input:disabled]:cursor-not-allowed has-[input:disabled]:opacity-50 aria-invalid:border-destructive aria-invalid:focus-within:ring-destructive/40",
|
|
10
10
|
{
|
|
11
11
|
variants: {
|
|
12
12
|
size: {
|
|
@@ -14,9 +14,14 @@ const inputGroupVariants = cva(
|
|
|
14
14
|
default: "h-11",
|
|
15
15
|
lg: "h-12",
|
|
16
16
|
},
|
|
17
|
+
shape: {
|
|
18
|
+
rounded: "rounded-xl focus-within:ring-ring",
|
|
19
|
+
pill: "rounded-full shadow-[var(--shadow-card)] focus-within:ring-accent/30",
|
|
20
|
+
},
|
|
17
21
|
},
|
|
18
22
|
defaultVariants: {
|
|
19
23
|
size: "default",
|
|
24
|
+
shape: "rounded",
|
|
20
25
|
},
|
|
21
26
|
}
|
|
22
27
|
);
|
|
@@ -27,12 +32,12 @@ const InputGroupContext = React.createContext<InputGroupContextValue>({});
|
|
|
27
32
|
const InputGroup = React.forwardRef<
|
|
28
33
|
HTMLDivElement,
|
|
29
34
|
React.HTMLAttributes<HTMLDivElement> & VariantProps<typeof inputGroupVariants>
|
|
30
|
-
>(({ className, size, children, ...props }, ref) => (
|
|
31
|
-
<InputGroupContext.Provider value={{ size }}>
|
|
35
|
+
>(({ className, size, shape, children, ...props }, ref) => (
|
|
36
|
+
<InputGroupContext.Provider value={{ size, shape }}>
|
|
32
37
|
<div
|
|
33
38
|
ref={ref}
|
|
34
39
|
data-slot="input-group"
|
|
35
|
-
className={cn(inputGroupVariants({ size }), className)}
|
|
40
|
+
className={cn(inputGroupVariants({ size, shape }), className)}
|
|
36
41
|
{...props}
|
|
37
42
|
>
|
|
38
43
|
{children}
|