@bearmenu/ui 0.6.1 → 0.7.1
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-LEAYBICI.js +84 -0
- 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 +74 -16
- package/dist/components/tag.js +3 -61
- package/dist/components/toast.js +1 -1
- package/dist/components/toaster.js +1 -1
- package/dist/lib/motion.d.ts +83 -0
- package/dist/lib/motion.js +2 -0
- 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
|
@@ -2,6 +2,7 @@ import { Button } from '../chunk-ZFNOCP6W.js';
|
|
|
2
2
|
import '../chunk-R47NEOSI.js';
|
|
3
3
|
import { cn } from '../chunk-FEK5XGZW.js';
|
|
4
4
|
import '../chunk-3GWWZKX7.js';
|
|
5
|
+
import * as React from 'react';
|
|
5
6
|
import { useRef, useState, useLayoutEffect } from 'react';
|
|
6
7
|
import { ChevronLeft } from 'lucide-react';
|
|
7
8
|
import { jsx, jsxs } from 'react/jsx-runtime';
|
|
@@ -16,6 +17,18 @@ var SlidingPanels = ({
|
|
|
16
17
|
const currentPanelData = panels[currentIndex];
|
|
17
18
|
const panelRefs = useRef([]);
|
|
18
19
|
const [containerHeight, setContainerHeight] = useState();
|
|
20
|
+
const usesTreeModel = panels.some((p) => p.parentId);
|
|
21
|
+
const activeAncestors = React.useMemo(() => {
|
|
22
|
+
if (!usesTreeModel) return /* @__PURE__ */ new Set();
|
|
23
|
+
const ancestors = /* @__PURE__ */ new Set();
|
|
24
|
+
let cursor = panels.find((p) => p.id === currentPanel);
|
|
25
|
+
while (cursor == null ? void 0 : cursor.parentId) {
|
|
26
|
+
ancestors.add(cursor.parentId);
|
|
27
|
+
const nextId = cursor.parentId;
|
|
28
|
+
cursor = panels.find((p) => p.id === nextId);
|
|
29
|
+
}
|
|
30
|
+
return ancestors;
|
|
31
|
+
}, [panels, currentPanel, usesTreeModel]);
|
|
19
32
|
useLayoutEffect(() => {
|
|
20
33
|
const activeEl = panelRefs.current[currentIndex];
|
|
21
34
|
if (!activeEl) return;
|
|
@@ -26,13 +39,16 @@ var SlidingPanels = ({
|
|
|
26
39
|
return () => ro.disconnect();
|
|
27
40
|
}, [currentIndex]);
|
|
28
41
|
const handleBack = () => {
|
|
29
|
-
const previousPanel = panels[currentIndex - 1];
|
|
30
|
-
if (!previousPanel) return;
|
|
31
42
|
if (currentPanelData == null ? void 0 : currentPanelData.onBack) {
|
|
32
43
|
currentPanelData.onBack();
|
|
33
|
-
|
|
34
|
-
onPanelChange(previousPanel.id);
|
|
44
|
+
return;
|
|
35
45
|
}
|
|
46
|
+
if (currentPanelData == null ? void 0 : currentPanelData.parentId) {
|
|
47
|
+
onPanelChange(currentPanelData.parentId);
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
const previousPanel = panels[currentIndex - 1];
|
|
51
|
+
if (previousPanel) onPanelChange(previousPanel.id);
|
|
36
52
|
};
|
|
37
53
|
return /* @__PURE__ */ jsx(
|
|
38
54
|
"div",
|
|
@@ -44,8 +60,8 @@ var SlidingPanels = ({
|
|
|
44
60
|
style: { height: containerHeight, overflowClipMargin: "8px" },
|
|
45
61
|
children: panels.map((panel, index) => {
|
|
46
62
|
const isActive = panel.id === currentPanel;
|
|
47
|
-
const isLeft = index < currentIndex;
|
|
48
|
-
const isRight =
|
|
63
|
+
const isLeft = usesTreeModel ? activeAncestors.has(panel.id) : index < currentIndex;
|
|
64
|
+
const isRight = !isActive && !isLeft;
|
|
49
65
|
return /* @__PURE__ */ jsxs(
|
|
50
66
|
"div",
|
|
51
67
|
{
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
+
|
|
3
|
+
type SortOptionListItem<T extends string> = {
|
|
4
|
+
value: T;
|
|
5
|
+
label: string;
|
|
6
|
+
};
|
|
7
|
+
interface SortOptionListProps<T extends string> {
|
|
8
|
+
options: SortOptionListItem<T>[];
|
|
9
|
+
value: T;
|
|
10
|
+
onChange: (value: T) => void;
|
|
11
|
+
ariaLabel: string;
|
|
12
|
+
className?: string;
|
|
13
|
+
}
|
|
14
|
+
declare function SortOptionList<T extends string>({ options, value, onChange, ariaLabel, className, }: SortOptionListProps<T>): react_jsx_runtime.JSX.Element;
|
|
15
|
+
|
|
16
|
+
export { SortOptionList, type SortOptionListItem };
|
|
@@ -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,15 @@
|
|
|
1
|
+
import { archetype } from '../chunk-LEAYBICI.js';
|
|
1
2
|
import { cn } from '../chunk-FEK5XGZW.js';
|
|
2
3
|
import { __objRest, __spreadValues, __spreadProps } from '../chunk-3GWWZKX7.js';
|
|
3
4
|
import * as React from 'react';
|
|
4
5
|
import * as TabsPrimitive from '@radix-ui/react-tabs';
|
|
5
|
-
import {
|
|
6
|
+
import { motion } from 'framer-motion';
|
|
7
|
+
import { jsx, jsxs } from 'react/jsx-runtime';
|
|
6
8
|
|
|
7
9
|
var TabsContext = React.createContext({
|
|
8
10
|
variant: "pill",
|
|
9
|
-
orientation: "horizontal"
|
|
11
|
+
orientation: "horizontal",
|
|
12
|
+
indicatorId: "tabs-indicator"
|
|
10
13
|
});
|
|
11
14
|
var Tabs = React.forwardRef((_a, ref) => {
|
|
12
15
|
var _b = _a, { className, orientation = "horizontal" } = _b, props = __objRest(_b, ["className", "orientation"]);
|
|
@@ -29,7 +32,8 @@ var TabsList = React.forwardRef((_a, ref) => {
|
|
|
29
32
|
var _b = _a, { className, variant = "pill", scrollable, children } = _b, props = __objRest(_b, ["className", "variant", "scrollable", "children"]);
|
|
30
33
|
const orientation = props["aria-orientation"] === "vertical" ? "vertical" : "horizontal";
|
|
31
34
|
const allowScroll = scrollable != null ? scrollable : orientation === "horizontal";
|
|
32
|
-
|
|
35
|
+
const indicatorId = React.useId();
|
|
36
|
+
return /* @__PURE__ */ jsx(TabsContext.Provider, { value: { variant, orientation, indicatorId }, children: /* @__PURE__ */ jsx(
|
|
33
37
|
TabsPrimitive.List,
|
|
34
38
|
__spreadProps(__spreadValues({
|
|
35
39
|
ref,
|
|
@@ -46,36 +50,90 @@ var TabsList = React.forwardRef((_a, ref) => {
|
|
|
46
50
|
});
|
|
47
51
|
TabsList.displayName = TabsPrimitive.List.displayName;
|
|
48
52
|
var TabsTrigger = React.forwardRef((_a, ref) => {
|
|
49
|
-
var _b = _a, { className } = _b, props = __objRest(_b, ["className"]);
|
|
50
|
-
const { variant, orientation } = React.useContext(TabsContext);
|
|
51
|
-
|
|
53
|
+
var _b = _a, { className, children } = _b, props = __objRest(_b, ["className", "children"]);
|
|
54
|
+
const { variant, orientation, indicatorId } = React.useContext(TabsContext);
|
|
55
|
+
const triggerRef = React.useRef(null);
|
|
56
|
+
const [isActive, setIsActive] = React.useState(false);
|
|
57
|
+
React.useEffect(() => {
|
|
58
|
+
const node = triggerRef.current;
|
|
59
|
+
if (!node) return;
|
|
60
|
+
const sync = () => setIsActive(node.getAttribute("data-state") === "active");
|
|
61
|
+
sync();
|
|
62
|
+
const observer = new MutationObserver(sync);
|
|
63
|
+
observer.observe(node, { attributes: true, attributeFilter: ["data-state"] });
|
|
64
|
+
return () => observer.disconnect();
|
|
65
|
+
}, []);
|
|
66
|
+
const composedRef = React.useCallback(
|
|
67
|
+
(node) => {
|
|
68
|
+
triggerRef.current = node;
|
|
69
|
+
if (typeof ref === "function") ref(node);
|
|
70
|
+
else if (ref) ref.current = node;
|
|
71
|
+
},
|
|
72
|
+
[ref]
|
|
73
|
+
);
|
|
74
|
+
return /* @__PURE__ */ jsxs(
|
|
52
75
|
TabsPrimitive.Trigger,
|
|
53
|
-
__spreadValues({
|
|
54
|
-
ref,
|
|
76
|
+
__spreadProps(__spreadValues({
|
|
77
|
+
ref: composedRef,
|
|
55
78
|
"data-slot": "tabs-trigger",
|
|
56
79
|
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" && "
|
|
80
|
+
"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",
|
|
81
|
+
variant === "pill" && "rounded-xl px-4 py-1.5 text-muted-foreground hover:text-foreground data-[state=active]:text-foreground",
|
|
82
|
+
variant === "underline" && orientation === "horizontal" && "h-11 rounded-none px-4 text-muted-foreground hover:text-foreground data-[state=active]:text-foreground",
|
|
83
|
+
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
84
|
className
|
|
62
85
|
)
|
|
63
|
-
}, props)
|
|
86
|
+
}, props), {
|
|
87
|
+
children: [
|
|
88
|
+
isActive && /* @__PURE__ */ jsx(
|
|
89
|
+
motion.span,
|
|
90
|
+
{
|
|
91
|
+
"aria-hidden": true,
|
|
92
|
+
layoutId: indicatorId,
|
|
93
|
+
transition: archetype.indicatorMorph,
|
|
94
|
+
className: cn(
|
|
95
|
+
"absolute inset-0 -z-0 motion-reduce:hidden",
|
|
96
|
+
variant === "pill" && "rounded-xl bg-background shadow-sm",
|
|
97
|
+
variant === "underline" && orientation === "horizontal" && "border-b-2 border-primary",
|
|
98
|
+
variant === "underline" && orientation === "vertical" && "border-r-2 border-primary"
|
|
99
|
+
)
|
|
100
|
+
}
|
|
101
|
+
),
|
|
102
|
+
isActive && /* @__PURE__ */ jsx(
|
|
103
|
+
"span",
|
|
104
|
+
{
|
|
105
|
+
"aria-hidden": true,
|
|
106
|
+
className: cn(
|
|
107
|
+
"absolute inset-0 -z-0 hidden motion-reduce:block",
|
|
108
|
+
variant === "pill" && "rounded-xl bg-background shadow-sm",
|
|
109
|
+
variant === "underline" && orientation === "horizontal" && "border-b-2 border-primary",
|
|
110
|
+
variant === "underline" && orientation === "vertical" && "border-r-2 border-primary"
|
|
111
|
+
)
|
|
112
|
+
}
|
|
113
|
+
),
|
|
114
|
+
/* @__PURE__ */ jsx("span", { className: "relative z-10 flex items-center gap-2", children })
|
|
115
|
+
]
|
|
116
|
+
})
|
|
64
117
|
);
|
|
65
118
|
});
|
|
66
119
|
TabsTrigger.displayName = TabsPrimitive.Trigger.displayName;
|
|
67
120
|
var TabsContent = React.forwardRef((_a, ref) => {
|
|
68
|
-
var _b = _a, { className } = _b, props = __objRest(_b, ["className"]);
|
|
121
|
+
var _b = _a, { className, children } = _b, props = __objRest(_b, ["className", "children"]);
|
|
69
122
|
return /* @__PURE__ */ jsx(
|
|
70
123
|
TabsPrimitive.Content,
|
|
71
|
-
__spreadValues({
|
|
124
|
+
__spreadProps(__spreadValues({
|
|
72
125
|
ref,
|
|
73
126
|
"data-slot": "tabs-content",
|
|
74
127
|
className: cn(
|
|
75
128
|
"flex-1 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 rounded-md",
|
|
129
|
+
// v1.0 motion: content-swap on activation. CSS animation so this works
|
|
130
|
+
// even outside a Framer-Motion-wrapped layout. Disabled for reduced-motion.
|
|
131
|
+
"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
132
|
className
|
|
77
133
|
)
|
|
78
|
-
}, props)
|
|
134
|
+
}, props), {
|
|
135
|
+
children
|
|
136
|
+
})
|
|
79
137
|
);
|
|
80
138
|
});
|
|
81
139
|
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';
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import { Transition, Variants } from 'framer-motion';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* BearMenu Motion System — v1.0
|
|
5
|
+
*
|
|
6
|
+
* Three layers:
|
|
7
|
+
* 1. Primitives — durations + easing curves (raw values)
|
|
8
|
+
* 2. Springs — Framer Motion spring configs (named)
|
|
9
|
+
* 3. Archetypes — compound presets that compose primitives + springs
|
|
10
|
+
*
|
|
11
|
+
* Feature code reaches for archetypes, never primitives.
|
|
12
|
+
* Adding a new archetype is a DS-maintainer task.
|
|
13
|
+
*
|
|
14
|
+
* Companion CSS custom properties live in `./globals.css`:
|
|
15
|
+
* --duration-instant / --duration-quick / --duration-standard /
|
|
16
|
+
* --duration-deliberate / --duration-narrative /
|
|
17
|
+
* --duration-exit-quick / --duration-exit-standard
|
|
18
|
+
* --ease-enter / --ease-standard / --ease-exit
|
|
19
|
+
*/
|
|
20
|
+
declare const duration: {
|
|
21
|
+
readonly instant: 0.12;
|
|
22
|
+
readonly quick: 0.18;
|
|
23
|
+
readonly standard: 0.26;
|
|
24
|
+
readonly deliberate: 0.36;
|
|
25
|
+
readonly narrative: 0.5;
|
|
26
|
+
readonly exitQuick: 0.11;
|
|
27
|
+
readonly exitStandard: 0.21;
|
|
28
|
+
};
|
|
29
|
+
declare const ease: {
|
|
30
|
+
readonly enter: readonly [0, 0, 0.2, 1];
|
|
31
|
+
readonly standard: readonly [0.4, 0, 0.2, 1];
|
|
32
|
+
readonly exit: readonly [0.55, 0, 1, 0.45];
|
|
33
|
+
};
|
|
34
|
+
declare const springSnappy: Transition;
|
|
35
|
+
declare const springSmooth: Transition;
|
|
36
|
+
declare const springSoft: Transition;
|
|
37
|
+
/** @deprecated use `springSoft`. Kept as alias during migration. */
|
|
38
|
+
declare const springGentle: Transition;
|
|
39
|
+
declare const archetype: {
|
|
40
|
+
/** Drawer / Sheet / Dialog entrance. Surface arrives first; content layers after. */
|
|
41
|
+
readonly surfaceOpen: Transition;
|
|
42
|
+
readonly surfaceClose: Transition;
|
|
43
|
+
/** First-reveal stagger for card grids. Per-item spring. Cap stagger at 8 items. */
|
|
44
|
+
readonly listReveal: Transition;
|
|
45
|
+
readonly listRevealStagger: 0.04;
|
|
46
|
+
readonly listRevealMaxItems: 8;
|
|
47
|
+
/** Tab content swap, skeleton → data swap. Opacity-only — no transform. */
|
|
48
|
+
readonly contentSwap: Transition;
|
|
49
|
+
readonly contentSwapExit: Transition;
|
|
50
|
+
/** Bottom-sheet / side-drawer entry. */
|
|
51
|
+
readonly edgeEnter: Transition;
|
|
52
|
+
readonly edgeExit: Transition;
|
|
53
|
+
/** Card / button tap feedback. */
|
|
54
|
+
readonly pressResponse: Transition;
|
|
55
|
+
/** Active tab pill, active filter chip — use with Framer Motion `layoutId`. */
|
|
56
|
+
readonly indicatorMorph: Transition;
|
|
57
|
+
/** Image enter — slight scale on load. */
|
|
58
|
+
readonly imageEnter: Transition;
|
|
59
|
+
};
|
|
60
|
+
declare const stagger: {
|
|
61
|
+
readonly tight: 0.03;
|
|
62
|
+
readonly standard: 0.04;
|
|
63
|
+
readonly loose: 0.06;
|
|
64
|
+
};
|
|
65
|
+
/**
|
|
66
|
+
* List-reveal container + item variants. Pair with Framer Motion `motion.ul`/`motion.div`.
|
|
67
|
+
* Container drives stagger; item handles the actual fade + Y-shift.
|
|
68
|
+
*/
|
|
69
|
+
declare const listRevealVariants: {
|
|
70
|
+
container: Variants;
|
|
71
|
+
item: Variants;
|
|
72
|
+
};
|
|
73
|
+
/**
|
|
74
|
+
* Content-swap variants for `AnimatePresence mode="wait"`. Opacity + tiny Y shift.
|
|
75
|
+
* Use for tab panels.
|
|
76
|
+
*/
|
|
77
|
+
declare const contentSwapVariants: Variants;
|
|
78
|
+
/**
|
|
79
|
+
* Skeleton → data swap. Opacity-only to prevent layout shift on slow networks.
|
|
80
|
+
*/
|
|
81
|
+
declare const skeletonSwapVariants: Variants;
|
|
82
|
+
|
|
83
|
+
export { archetype, contentSwapVariants, duration, ease, listRevealVariants, skeletonSwapVariants, springGentle, springSmooth, springSnappy, springSoft, stagger };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bearmenu/ui",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.7.1",
|
|
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 };
|