@bearmenu/ui 0.6.0 → 0.6.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/components/alert.d.ts +2 -2
- package/dist/components/badge.d.ts +1 -1
- package/dist/components/button.d.ts +1 -1
- package/dist/components/card.d.ts +2 -2
- package/dist/components/command.d.ts +15 -15
- package/dist/components/date-input.d.ts +1 -1
- package/dist/components/item.d.ts +2 -2
- package/dist/components/scroll-fade.d.ts +15 -0
- package/dist/components/scroll-fade.js +116 -0
- package/dist/components/spinner.d.ts +2 -2
- package/dist/components/tag.d.ts +2 -2
- package/dist/components/text.d.ts +3 -3
- package/dist/components/toaster.js +1 -1
- package/package.json +2 -1
- package/src/components/scroll-fade.stories.tsx +98 -0
- package/src/components/scroll-fade.tsx +127 -0
|
@@ -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" | "destructive" | "
|
|
6
|
+
variant?: "default" | "destructive" | "success" | "warning" | 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" | "destructive" | "
|
|
9
|
+
variant?: "default" | "destructive" | "success" | "warning" | 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?: "default" | "destructive" | "
|
|
7
|
+
variant?: "default" | "destructive" | "outline" | "secondary" | "glass" | "brown" | "success" | "warning" | "overlay" | null | undefined;
|
|
8
8
|
} & class_variance_authority_types.ClassProp) | undefined) => string;
|
|
9
9
|
interface BadgeProps extends React.HTMLAttributes<HTMLDivElement>, VariantProps<typeof badgeVariants> {
|
|
10
10
|
}
|
|
@@ -3,7 +3,7 @@ import * as React from 'react';
|
|
|
3
3
|
import { VariantProps } from 'class-variance-authority';
|
|
4
4
|
|
|
5
5
|
declare const buttonVariants: (props?: ({
|
|
6
|
-
variant?: "
|
|
6
|
+
variant?: "link" | "default" | "destructive" | "outline" | "secondary" | "ghost" | "glass" | "brown" | "antagonist" | null | undefined;
|
|
7
7
|
size?: "default" | "xs" | "sm" | "lg" | "icon" | "icon-xs" | "icon-sm" | "icon-lg" | null | undefined;
|
|
8
8
|
fullWidth?: boolean | null | undefined;
|
|
9
9
|
} & class_variance_authority_types.ClassProp) | undefined) => string;
|
|
@@ -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?: "outline" | "glass" | "muted" | "surface" | 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?: "outline" | "glass" | "muted" | "surface" | 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;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
2
|
|
|
3
|
-
declare const DateInput: React.ForwardRefExoticComponent<Omit<React.InputHTMLAttributes<HTMLInputElement>, "
|
|
3
|
+
declare const DateInput: React.ForwardRefExoticComponent<Omit<React.InputHTMLAttributes<HTMLInputElement>, "type" | "size"> & {
|
|
4
4
|
/** Native input type. Defaults to "date". */
|
|
5
5
|
type?: "date" | "datetime-local" | "time" | "month" | "week";
|
|
6
6
|
size?: "sm" | "default" | "lg";
|
|
@@ -3,12 +3,12 @@ import * as React from 'react';
|
|
|
3
3
|
import { VariantProps } from 'class-variance-authority';
|
|
4
4
|
|
|
5
5
|
declare const itemVariants: (props?: ({
|
|
6
|
-
variant?: "default" | "
|
|
6
|
+
variant?: "default" | "outline" | "muted" | 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 Item: React.ForwardRefExoticComponent<React.HTMLAttributes<HTMLDivElement> & VariantProps<(props?: ({
|
|
11
|
-
variant?: "default" | "
|
|
11
|
+
variant?: "default" | "outline" | "muted" | 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> & {
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
|
|
3
|
+
type Orientation = "vertical" | "horizontal";
|
|
4
|
+
type FadeColor = "background" | "card" | "muted";
|
|
5
|
+
type Size = "sm" | "md" | "lg";
|
|
6
|
+
interface ScrollFadeProps extends React.HTMLAttributes<HTMLDivElement> {
|
|
7
|
+
orientation?: Orientation;
|
|
8
|
+
fadeColor?: FadeColor;
|
|
9
|
+
size?: Size;
|
|
10
|
+
/** Class names applied to the inner scrollable element (where overflow lives). */
|
|
11
|
+
scrollClassName?: string;
|
|
12
|
+
}
|
|
13
|
+
declare const ScrollFade: React.ForwardRefExoticComponent<ScrollFadeProps & React.RefAttributes<HTMLDivElement>>;
|
|
14
|
+
|
|
15
|
+
export { ScrollFade, type ScrollFadeProps };
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
import { cn } from '../chunk-FEK5XGZW.js';
|
|
2
|
+
import { __objRest, __spreadProps, __spreadValues } from '../chunk-3GWWZKX7.js';
|
|
3
|
+
import * as React from 'react';
|
|
4
|
+
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
5
|
+
|
|
6
|
+
var fromMap = {
|
|
7
|
+
background: "from-background",
|
|
8
|
+
card: "from-card",
|
|
9
|
+
muted: "from-muted"
|
|
10
|
+
};
|
|
11
|
+
var sizeMap = {
|
|
12
|
+
vertical: { sm: "h-6", md: "h-12", lg: "h-20" },
|
|
13
|
+
horizontal: { sm: "w-8", md: "w-16", lg: "w-28" }
|
|
14
|
+
};
|
|
15
|
+
var ScrollFade = React.forwardRef(
|
|
16
|
+
(_a, ref) => {
|
|
17
|
+
var _b = _a, {
|
|
18
|
+
orientation = "vertical",
|
|
19
|
+
fadeColor = "background",
|
|
20
|
+
size = "md",
|
|
21
|
+
className,
|
|
22
|
+
scrollClassName,
|
|
23
|
+
children
|
|
24
|
+
} = _b, props = __objRest(_b, [
|
|
25
|
+
"orientation",
|
|
26
|
+
"fadeColor",
|
|
27
|
+
"size",
|
|
28
|
+
"className",
|
|
29
|
+
"scrollClassName",
|
|
30
|
+
"children"
|
|
31
|
+
]);
|
|
32
|
+
const innerRef = React.useRef(null);
|
|
33
|
+
React.useImperativeHandle(ref, () => innerRef.current);
|
|
34
|
+
const [atStart, setAtStart] = React.useState(true);
|
|
35
|
+
const [atEnd, setAtEnd] = React.useState(true);
|
|
36
|
+
const update = React.useCallback(() => {
|
|
37
|
+
const el = innerRef.current;
|
|
38
|
+
if (!el) return;
|
|
39
|
+
if (orientation === "vertical") {
|
|
40
|
+
const overflow = el.scrollHeight - el.clientHeight;
|
|
41
|
+
setAtStart(el.scrollTop <= 1);
|
|
42
|
+
setAtEnd(overflow <= 1 || el.scrollTop >= overflow - 1);
|
|
43
|
+
} else {
|
|
44
|
+
const overflow = el.scrollWidth - el.clientWidth;
|
|
45
|
+
setAtStart(el.scrollLeft <= 1);
|
|
46
|
+
setAtEnd(overflow <= 1 || el.scrollLeft >= overflow - 1);
|
|
47
|
+
}
|
|
48
|
+
}, [orientation]);
|
|
49
|
+
React.useEffect(() => {
|
|
50
|
+
const el = innerRef.current;
|
|
51
|
+
if (!el) return;
|
|
52
|
+
update();
|
|
53
|
+
el.addEventListener("scroll", update, { passive: true });
|
|
54
|
+
const ro = new ResizeObserver(update);
|
|
55
|
+
ro.observe(el);
|
|
56
|
+
return () => {
|
|
57
|
+
el.removeEventListener("scroll", update);
|
|
58
|
+
ro.disconnect();
|
|
59
|
+
};
|
|
60
|
+
}, [update]);
|
|
61
|
+
const fromClass = fromMap[fadeColor];
|
|
62
|
+
const fadeSize = sizeMap[orientation][size];
|
|
63
|
+
return /* @__PURE__ */ jsxs(
|
|
64
|
+
"div",
|
|
65
|
+
{
|
|
66
|
+
className: cn(
|
|
67
|
+
"relative isolate flex",
|
|
68
|
+
orientation === "vertical" ? "flex-col" : "flex-row",
|
|
69
|
+
className
|
|
70
|
+
),
|
|
71
|
+
children: [
|
|
72
|
+
/* @__PURE__ */ jsx(
|
|
73
|
+
"div",
|
|
74
|
+
__spreadProps(__spreadValues({
|
|
75
|
+
ref: innerRef,
|
|
76
|
+
className: cn(
|
|
77
|
+
"min-h-0 min-w-0 flex-1",
|
|
78
|
+
orientation === "vertical" ? "overflow-y-auto" : "overflow-x-auto",
|
|
79
|
+
scrollClassName
|
|
80
|
+
)
|
|
81
|
+
}, props), {
|
|
82
|
+
children
|
|
83
|
+
})
|
|
84
|
+
),
|
|
85
|
+
/* @__PURE__ */ jsx(
|
|
86
|
+
"div",
|
|
87
|
+
{
|
|
88
|
+
"aria-hidden": true,
|
|
89
|
+
className: cn(
|
|
90
|
+
"pointer-events-none absolute z-10 transition-opacity duration-300",
|
|
91
|
+
orientation === "vertical" ? `inset-x-0 top-0 ${fadeSize} bg-gradient-to-b` : `inset-y-0 left-0 ${fadeSize} bg-gradient-to-r`,
|
|
92
|
+
fromClass,
|
|
93
|
+
atStart ? "opacity-0" : "opacity-100"
|
|
94
|
+
)
|
|
95
|
+
}
|
|
96
|
+
),
|
|
97
|
+
/* @__PURE__ */ jsx(
|
|
98
|
+
"div",
|
|
99
|
+
{
|
|
100
|
+
"aria-hidden": true,
|
|
101
|
+
className: cn(
|
|
102
|
+
"pointer-events-none absolute z-10 transition-opacity duration-300",
|
|
103
|
+
orientation === "vertical" ? `inset-x-0 bottom-0 ${fadeSize} bg-gradient-to-t` : `inset-y-0 right-0 ${fadeSize} bg-gradient-to-l`,
|
|
104
|
+
fromClass,
|
|
105
|
+
atEnd ? "opacity-0" : "opacity-100"
|
|
106
|
+
)
|
|
107
|
+
}
|
|
108
|
+
)
|
|
109
|
+
]
|
|
110
|
+
}
|
|
111
|
+
);
|
|
112
|
+
}
|
|
113
|
+
);
|
|
114
|
+
ScrollFade.displayName = "ScrollFade";
|
|
115
|
+
|
|
116
|
+
export { ScrollFade };
|
|
@@ -4,11 +4,11 @@ import { VariantProps } from 'class-variance-authority';
|
|
|
4
4
|
|
|
5
5
|
declare const spinnerVariants: (props?: ({
|
|
6
6
|
size?: "default" | "xs" | "sm" | "lg" | "xl" | null | undefined;
|
|
7
|
-
tone?: "
|
|
7
|
+
tone?: "inherit" | "default" | "destructive" | "primary" | null | undefined;
|
|
8
8
|
} & class_variance_authority_types.ClassProp) | undefined) => string;
|
|
9
9
|
declare const Spinner: React.ForwardRefExoticComponent<React.HTMLAttributes<HTMLSpanElement> & VariantProps<(props?: ({
|
|
10
10
|
size?: "default" | "xs" | "sm" | "lg" | "xl" | null | undefined;
|
|
11
|
-
tone?: "
|
|
11
|
+
tone?: "inherit" | "default" | "destructive" | "primary" | null | undefined;
|
|
12
12
|
} & class_variance_authority_types.ClassProp) | undefined) => string> & {
|
|
13
13
|
/** Visually-hidden label for screen readers. Defaults to "Loading". */
|
|
14
14
|
label?: string;
|
package/dist/components/tag.d.ts
CHANGED
|
@@ -3,11 +3,11 @@ import * as React from 'react';
|
|
|
3
3
|
import { VariantProps } from 'class-variance-authority';
|
|
4
4
|
|
|
5
5
|
declare const tagVariants: (props?: ({
|
|
6
|
-
variant?: "default" | "destructive" | "
|
|
6
|
+
variant?: "default" | "destructive" | "outline" | "success" | "warning" | "primary" | null | undefined;
|
|
7
7
|
size?: "default" | "sm" | "lg" | null | undefined;
|
|
8
8
|
} & class_variance_authority_types.ClassProp) | undefined) => string;
|
|
9
9
|
declare const Tag: React.ForwardRefExoticComponent<React.HTMLAttributes<HTMLSpanElement> & VariantProps<(props?: ({
|
|
10
|
-
variant?: "default" | "destructive" | "
|
|
10
|
+
variant?: "default" | "destructive" | "outline" | "success" | "warning" | "primary" | null | undefined;
|
|
11
11
|
size?: "default" | "sm" | "lg" | null | undefined;
|
|
12
12
|
} & class_variance_authority_types.ClassProp) | undefined) => string> & {
|
|
13
13
|
onRemove?: () => void;
|
|
@@ -4,9 +4,9 @@ import * as React from 'react';
|
|
|
4
4
|
import { VariantProps } from 'class-variance-authority';
|
|
5
5
|
|
|
6
6
|
declare const textVariants: (props?: ({
|
|
7
|
-
variant?: "
|
|
8
|
-
color?: "
|
|
9
|
-
weight?: "bold" | "
|
|
7
|
+
variant?: "h2" | "h3" | "label" | "body" | "caption" | "h1" | "h4" | "small" | "display" | "body-lg" | "body-sm" | "overline" | null | undefined;
|
|
8
|
+
color?: "inherit" | "default" | "destructive" | "muted" | "primary" | "primary-foreground" | null | undefined;
|
|
9
|
+
weight?: "bold" | "medium" | "normal" | "semibold" | null | undefined;
|
|
10
10
|
leading?: "none" | "normal" | "tight" | "snug" | "relaxed" | "loose" | null | undefined;
|
|
11
11
|
tracking?: "normal" | "tight" | "wide" | "wider" | null | undefined;
|
|
12
12
|
wrap?: "balance" | "pretty" | "nowrap" | null | undefined;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { useToast } from '../chunk-EBAMCZDW.js';
|
|
2
1
|
import { ToastProvider, Toast, ToastTitle, ToastDescription, ToastClose, ToastViewport } from '../chunk-7PPCH42H.js';
|
|
2
|
+
import { useToast } from '../chunk-EBAMCZDW.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.6.
|
|
3
|
+
"version": "0.6.1",
|
|
4
4
|
"description": "BearMenu design system — shared UI tokens, primitives, and components",
|
|
5
5
|
"license": "UNLICENSED",
|
|
6
6
|
"repository": {
|
|
@@ -67,6 +67,7 @@
|
|
|
67
67
|
"./components/radio-group": "./src/components/radio-group.tsx",
|
|
68
68
|
"./components/rating": "./src/components/rating.tsx",
|
|
69
69
|
"./components/scroll-area": "./src/components/scroll-area.tsx",
|
|
70
|
+
"./components/scroll-fade": "./src/components/scroll-fade.tsx",
|
|
70
71
|
"./components/search-bar": "./src/components/search-bar.tsx",
|
|
71
72
|
"./components/searchable-select": "./src/components/searchable-select.tsx",
|
|
72
73
|
"./components/select": "./src/components/select.tsx",
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from "@storybook/react";
|
|
2
|
+
import { ScrollFade } from "./scroll-fade";
|
|
3
|
+
|
|
4
|
+
const meta = {
|
|
5
|
+
title: "Components/ScrollFade",
|
|
6
|
+
component: ScrollFade,
|
|
7
|
+
tags: ["autodocs"],
|
|
8
|
+
parameters: {
|
|
9
|
+
docs: {
|
|
10
|
+
description: {
|
|
11
|
+
component:
|
|
12
|
+
"Scroll-position-aware fade overlay. Hides when at the corresponding edge, fades in when there's more content to scroll. Works vertically or horizontally and matches a chosen surface color.",
|
|
13
|
+
},
|
|
14
|
+
},
|
|
15
|
+
},
|
|
16
|
+
} satisfies Meta<typeof ScrollFade>;
|
|
17
|
+
|
|
18
|
+
export default meta;
|
|
19
|
+
type Story = StoryObj<typeof meta>;
|
|
20
|
+
|
|
21
|
+
const longList = Array.from({ length: 30 });
|
|
22
|
+
const wideList = Array.from({ length: 20 });
|
|
23
|
+
|
|
24
|
+
export const Vertical: Story = {
|
|
25
|
+
args: {
|
|
26
|
+
orientation: "vertical",
|
|
27
|
+
fadeColor: "background",
|
|
28
|
+
size: "md",
|
|
29
|
+
},
|
|
30
|
+
render: (args) => (
|
|
31
|
+
<ScrollFade {...args} className="h-[320px] w-[360px] rounded-lg border" scrollClassName="p-4">
|
|
32
|
+
<ul className="space-y-3">
|
|
33
|
+
{longList.map((_, i) => (
|
|
34
|
+
<li key={i} className="text-sm text-muted-foreground">
|
|
35
|
+
Item #{i + 1} — scroll to reveal the fades at the edges.
|
|
36
|
+
</li>
|
|
37
|
+
))}
|
|
38
|
+
</ul>
|
|
39
|
+
</ScrollFade>
|
|
40
|
+
),
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
export const Horizontal: Story = {
|
|
44
|
+
args: {
|
|
45
|
+
orientation: "horizontal",
|
|
46
|
+
fadeColor: "background",
|
|
47
|
+
size: "md",
|
|
48
|
+
},
|
|
49
|
+
render: (args) => (
|
|
50
|
+
<ScrollFade {...args} className="w-[480px] rounded-lg border" scrollClassName="flex gap-3 p-4">
|
|
51
|
+
{wideList.map((_, i) => (
|
|
52
|
+
<div
|
|
53
|
+
key={i}
|
|
54
|
+
className="flex h-24 w-32 shrink-0 items-center justify-center rounded-md bg-muted text-sm"
|
|
55
|
+
>
|
|
56
|
+
Card {i + 1}
|
|
57
|
+
</div>
|
|
58
|
+
))}
|
|
59
|
+
</ScrollFade>
|
|
60
|
+
),
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
export const InsideCard: Story = {
|
|
64
|
+
args: {
|
|
65
|
+
orientation: "vertical",
|
|
66
|
+
fadeColor: "card",
|
|
67
|
+
size: "md",
|
|
68
|
+
},
|
|
69
|
+
render: (args) => (
|
|
70
|
+
<div className="bg-card text-card-foreground w-[360px] rounded-2xl border shadow-md">
|
|
71
|
+
<div className="border-border border-b p-4 font-semibold">Drawer header</div>
|
|
72
|
+
<ScrollFade {...args} className="h-[280px]" scrollClassName="p-4">
|
|
73
|
+
<ul className="space-y-3">
|
|
74
|
+
{longList.map((_, i) => (
|
|
75
|
+
<li key={i} className="text-sm text-muted-foreground">
|
|
76
|
+
Row #{i + 1} — fades use <code>fadeColor="card"</code> to match the surface.
|
|
77
|
+
</li>
|
|
78
|
+
))}
|
|
79
|
+
</ul>
|
|
80
|
+
</ScrollFade>
|
|
81
|
+
</div>
|
|
82
|
+
),
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
export const NoOverflow: Story = {
|
|
86
|
+
args: {
|
|
87
|
+
orientation: "vertical",
|
|
88
|
+
fadeColor: "background",
|
|
89
|
+
size: "md",
|
|
90
|
+
},
|
|
91
|
+
render: (args) => (
|
|
92
|
+
<ScrollFade {...args} className="h-[200px] w-[320px] rounded-lg border" scrollClassName="p-4">
|
|
93
|
+
<p className="text-sm text-muted-foreground">
|
|
94
|
+
Content fits inside the box — both fades stay hidden.
|
|
95
|
+
</p>
|
|
96
|
+
</ScrollFade>
|
|
97
|
+
),
|
|
98
|
+
};
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import * as React from "react";
|
|
4
|
+
import { cn } from "../lib/utils";
|
|
5
|
+
|
|
6
|
+
type Orientation = "vertical" | "horizontal";
|
|
7
|
+
type FadeColor = "background" | "card" | "muted";
|
|
8
|
+
type Size = "sm" | "md" | "lg";
|
|
9
|
+
|
|
10
|
+
interface ScrollFadeProps extends React.HTMLAttributes<HTMLDivElement> {
|
|
11
|
+
orientation?: Orientation;
|
|
12
|
+
fadeColor?: FadeColor;
|
|
13
|
+
size?: Size;
|
|
14
|
+
/** Class names applied to the inner scrollable element (where overflow lives). */
|
|
15
|
+
scrollClassName?: string;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
// Static maps so Tailwind can statically analyze the class names.
|
|
19
|
+
const fromMap: Record<FadeColor, string> = {
|
|
20
|
+
background: "from-background",
|
|
21
|
+
card: "from-card",
|
|
22
|
+
muted: "from-muted",
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
const sizeMap: Record<Orientation, Record<Size, string>> = {
|
|
26
|
+
vertical: { sm: "h-6", md: "h-12", lg: "h-20" },
|
|
27
|
+
horizontal: { sm: "w-8", md: "w-16", lg: "w-28" },
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
const ScrollFade = React.forwardRef<HTMLDivElement, ScrollFadeProps>(
|
|
31
|
+
(
|
|
32
|
+
{
|
|
33
|
+
orientation = "vertical",
|
|
34
|
+
fadeColor = "background",
|
|
35
|
+
size = "md",
|
|
36
|
+
className,
|
|
37
|
+
scrollClassName,
|
|
38
|
+
children,
|
|
39
|
+
...props
|
|
40
|
+
},
|
|
41
|
+
ref
|
|
42
|
+
) => {
|
|
43
|
+
const innerRef = React.useRef<HTMLDivElement>(null);
|
|
44
|
+
React.useImperativeHandle(ref, () => innerRef.current as HTMLDivElement);
|
|
45
|
+
|
|
46
|
+
const [atStart, setAtStart] = React.useState(true);
|
|
47
|
+
const [atEnd, setAtEnd] = React.useState(true);
|
|
48
|
+
|
|
49
|
+
const update = React.useCallback(() => {
|
|
50
|
+
const el = innerRef.current;
|
|
51
|
+
if (!el) return;
|
|
52
|
+
if (orientation === "vertical") {
|
|
53
|
+
const overflow = el.scrollHeight - el.clientHeight;
|
|
54
|
+
setAtStart(el.scrollTop <= 1);
|
|
55
|
+
setAtEnd(overflow <= 1 || el.scrollTop >= overflow - 1);
|
|
56
|
+
} else {
|
|
57
|
+
const overflow = el.scrollWidth - el.clientWidth;
|
|
58
|
+
setAtStart(el.scrollLeft <= 1);
|
|
59
|
+
setAtEnd(overflow <= 1 || el.scrollLeft >= overflow - 1);
|
|
60
|
+
}
|
|
61
|
+
}, [orientation]);
|
|
62
|
+
|
|
63
|
+
React.useEffect(() => {
|
|
64
|
+
const el = innerRef.current;
|
|
65
|
+
if (!el) return;
|
|
66
|
+
update();
|
|
67
|
+
el.addEventListener("scroll", update, { passive: true });
|
|
68
|
+
const ro = new ResizeObserver(update);
|
|
69
|
+
ro.observe(el);
|
|
70
|
+
return () => {
|
|
71
|
+
el.removeEventListener("scroll", update);
|
|
72
|
+
ro.disconnect();
|
|
73
|
+
};
|
|
74
|
+
}, [update]);
|
|
75
|
+
|
|
76
|
+
const fromClass = fromMap[fadeColor];
|
|
77
|
+
const fadeSize = sizeMap[orientation][size];
|
|
78
|
+
|
|
79
|
+
return (
|
|
80
|
+
<div
|
|
81
|
+
className={cn(
|
|
82
|
+
"relative isolate flex",
|
|
83
|
+
orientation === "vertical" ? "flex-col" : "flex-row",
|
|
84
|
+
className
|
|
85
|
+
)}
|
|
86
|
+
>
|
|
87
|
+
<div
|
|
88
|
+
ref={innerRef}
|
|
89
|
+
className={cn(
|
|
90
|
+
"min-h-0 min-w-0 flex-1",
|
|
91
|
+
orientation === "vertical" ? "overflow-y-auto" : "overflow-x-auto",
|
|
92
|
+
scrollClassName
|
|
93
|
+
)}
|
|
94
|
+
{...props}
|
|
95
|
+
>
|
|
96
|
+
{children}
|
|
97
|
+
</div>
|
|
98
|
+
<div
|
|
99
|
+
aria-hidden
|
|
100
|
+
className={cn(
|
|
101
|
+
"pointer-events-none absolute z-10 transition-opacity duration-300",
|
|
102
|
+
orientation === "vertical"
|
|
103
|
+
? `inset-x-0 top-0 ${fadeSize} bg-gradient-to-b`
|
|
104
|
+
: `inset-y-0 left-0 ${fadeSize} bg-gradient-to-r`,
|
|
105
|
+
fromClass,
|
|
106
|
+
atStart ? "opacity-0" : "opacity-100"
|
|
107
|
+
)}
|
|
108
|
+
/>
|
|
109
|
+
<div
|
|
110
|
+
aria-hidden
|
|
111
|
+
className={cn(
|
|
112
|
+
"pointer-events-none absolute z-10 transition-opacity duration-300",
|
|
113
|
+
orientation === "vertical"
|
|
114
|
+
? `inset-x-0 bottom-0 ${fadeSize} bg-gradient-to-t`
|
|
115
|
+
: `inset-y-0 right-0 ${fadeSize} bg-gradient-to-l`,
|
|
116
|
+
fromClass,
|
|
117
|
+
atEnd ? "opacity-0" : "opacity-100"
|
|
118
|
+
)}
|
|
119
|
+
/>
|
|
120
|
+
</div>
|
|
121
|
+
);
|
|
122
|
+
}
|
|
123
|
+
);
|
|
124
|
+
ScrollFade.displayName = "ScrollFade";
|
|
125
|
+
|
|
126
|
+
export { ScrollFade };
|
|
127
|
+
export type { ScrollFadeProps };
|