@timmbr/ui 1.11.1 → 1.13.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/Inline/Inline.d.ts.map +1 -1
- package/dist/components/Inline/Inline.js +2 -1
- package/dist/components/Inline/Inline.types.d.ts +5 -0
- package/dist/components/Inline/Inline.types.d.ts.map +1 -1
- package/dist/components/ScrollRail/ScrollRail.d.ts +4 -0
- package/dist/components/ScrollRail/ScrollRail.d.ts.map +1 -0
- package/dist/components/ScrollRail/ScrollRail.js +103 -0
- package/dist/components/ScrollRail/ScrollRail.styles.d.ts +10 -0
- package/dist/components/ScrollRail/ScrollRail.styles.d.ts.map +1 -0
- package/dist/components/ScrollRail/ScrollRail.styles.js +31 -0
- package/dist/components/ScrollRail/ScrollRail.types.d.ts +16 -0
- package/dist/components/ScrollRail/ScrollRail.types.d.ts.map +1 -0
- package/dist/components/ScrollRail/index.d.ts +4 -0
- package/dist/components/ScrollRail/index.d.ts.map +1 -0
- package/dist/components/Stack/Stack.d.ts.map +1 -1
- package/dist/components/Stack/Stack.js +2 -1
- package/dist/components/Stack/Stack.types.d.ts +5 -0
- package/dist/components/Stack/Stack.types.d.ts.map +1 -1
- package/dist/components/ZoneProgress/ZoneProgress.d.ts +6 -0
- package/dist/components/ZoneProgress/ZoneProgress.d.ts.map +1 -0
- package/dist/components/ZoneProgress/ZoneProgress.js +96 -0
- package/dist/components/ZoneProgress/index.d.ts +2 -0
- package/dist/components/ZoneProgress/index.d.ts.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -0
- package/package.json +5 -5
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Inline.d.ts","sourceRoot":"","sources":["../../../src/components/Inline/Inline.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAK/B,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAElD,eAAO,MAAM,MAAM,
|
|
1
|
+
{"version":3,"file":"Inline.d.ts","sourceRoot":"","sources":["../../../src/components/Inline/Inline.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAK/B,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAElD,eAAO,MAAM,MAAM,oFAqDlB,CAAC"}
|
|
@@ -17,11 +17,12 @@ const Inline = React.forwardRef(
|
|
|
17
17
|
justify = "start",
|
|
18
18
|
wrap = true,
|
|
19
19
|
divider,
|
|
20
|
+
as,
|
|
20
21
|
asChild = false,
|
|
21
22
|
children,
|
|
22
23
|
...props
|
|
23
24
|
}, ref) => {
|
|
24
|
-
const Component = asChild ? Slot : "div";
|
|
25
|
+
const Component = asChild ? Slot : as ?? "div";
|
|
25
26
|
const gapClass = formatGap(gap);
|
|
26
27
|
const renderChildren = () => {
|
|
27
28
|
if (!divider) return children;
|
|
@@ -14,6 +14,11 @@ export interface InlineProps extends Omit<React.HTMLAttributes<HTMLDivElement>,
|
|
|
14
14
|
* Optional divider element rendered between each inline child.
|
|
15
15
|
*/
|
|
16
16
|
divider?: React.ReactNode;
|
|
17
|
+
/**
|
|
18
|
+
* Renders as a different HTML element or component while keeping Inline styles.
|
|
19
|
+
* e.g. `as="nav"`, `as="footer"`. Ignored when `asChild` is true.
|
|
20
|
+
*/
|
|
21
|
+
as?: React.ElementType;
|
|
17
22
|
/**
|
|
18
23
|
* If true, renders child element via Radix Slot.
|
|
19
24
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Inline.types.d.ts","sourceRoot":"","sources":["../../../src/components/Inline/Inline.types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,KAAK,MAAM,OAAO,CAAC;AACpC,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AACtD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAEhD,MAAM,WAAW,WACf,SAAQ,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,cAAc,CAAC,EAAE,KAAK,CAAC,EACvD,IAAI,CAAC,cAAc,EAAE,KAAK,CAAC;IAC7B;;OAEG;IACH,GAAG,CAAC,EAAE,QAAQ,CAAC;IACf,8DAA8D;IAC9D,MAAM,CAAC,EAAE,QAAQ,CAAC;IAClB,kEAAkE;IAClE,MAAM,CAAC,EAAE,QAAQ,CAAC;IAClB;;OAEG;IACH,OAAO,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B;;OAEG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB"}
|
|
1
|
+
{"version":3,"file":"Inline.types.d.ts","sourceRoot":"","sources":["../../../src/components/Inline/Inline.types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,KAAK,MAAM,OAAO,CAAC;AACpC,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AACtD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAEhD,MAAM,WAAW,WACf,SAAQ,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,cAAc,CAAC,EAAE,KAAK,CAAC,EACvD,IAAI,CAAC,cAAc,EAAE,KAAK,CAAC;IAC7B;;OAEG;IACH,GAAG,CAAC,EAAE,QAAQ,CAAC;IACf,8DAA8D;IAC9D,MAAM,CAAC,EAAE,QAAQ,CAAC;IAClB,kEAAkE;IAClE,MAAM,CAAC,EAAE,QAAQ,CAAC;IAClB;;OAEG;IACH,OAAO,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B;;;OAGG;IACH,EAAE,CAAC,EAAE,KAAK,CAAC,WAAW,CAAC;IACvB;;OAEG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ScrollRail.d.ts","sourceRoot":"","sources":["../../../src/components/ScrollRail/ScrollRail.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAU/B,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAI1D,eAAO,MAAM,UAAU,wFA+GtB,CAAC"}
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
3
|
+
import * as React from 'react';
|
|
4
|
+
import { ChevronLeft, ChevronRight } from '@timmbr/icons';
|
|
5
|
+
import { cn } from '@timmbr/utils';
|
|
6
|
+
import { tapGestures, hoverGestures, Presence, motion, fadeVariants } from '@timmbr/motion';
|
|
7
|
+
import { scrollRailVariants, scrollRailChevronVariants, scrollRailWrapperVariants } from './ScrollRail.styles.js';
|
|
8
|
+
import { useGlobalAnimation } from '../../providers/AnimationProvider.js';
|
|
9
|
+
|
|
10
|
+
const SCROLL_THRESHOLD = 4;
|
|
11
|
+
const ScrollRail = React.forwardRef(
|
|
12
|
+
({
|
|
13
|
+
gap,
|
|
14
|
+
scrollAmount,
|
|
15
|
+
hideChevrons = false,
|
|
16
|
+
labelPrev = "Scroll left",
|
|
17
|
+
labelNext = "Scroll right",
|
|
18
|
+
className,
|
|
19
|
+
children,
|
|
20
|
+
...props
|
|
21
|
+
}, ref) => {
|
|
22
|
+
const globalMotion = useGlobalAnimation();
|
|
23
|
+
const trackRef = React.useRef(null);
|
|
24
|
+
const [canScrollLeft, setCanScrollLeft] = React.useState(false);
|
|
25
|
+
const [canScrollRight, setCanScrollRight] = React.useState(false);
|
|
26
|
+
const updateScrollState = React.useCallback(() => {
|
|
27
|
+
const t = trackRef.current;
|
|
28
|
+
if (!t) return;
|
|
29
|
+
setCanScrollLeft(t.scrollLeft > SCROLL_THRESHOLD);
|
|
30
|
+
setCanScrollRight(t.scrollLeft + t.clientWidth < t.scrollWidth - SCROLL_THRESHOLD);
|
|
31
|
+
}, []);
|
|
32
|
+
React.useLayoutEffect(() => {
|
|
33
|
+
updateScrollState();
|
|
34
|
+
}, [updateScrollState]);
|
|
35
|
+
React.useEffect(() => {
|
|
36
|
+
const t = trackRef.current;
|
|
37
|
+
if (!t || typeof ResizeObserver === "undefined") return;
|
|
38
|
+
const ro = new ResizeObserver(updateScrollState);
|
|
39
|
+
ro.observe(t);
|
|
40
|
+
return () => ro.disconnect();
|
|
41
|
+
}, [updateScrollState]);
|
|
42
|
+
const getScrollAmount = () => scrollAmount ?? (trackRef.current?.clientWidth ?? 320) * 0.8;
|
|
43
|
+
const gestureProps = globalMotion ? { whileHover: hoverGestures.scale, whileTap: tapGestures.compress } : {};
|
|
44
|
+
return /* @__PURE__ */ jsxs(
|
|
45
|
+
"div",
|
|
46
|
+
{
|
|
47
|
+
ref,
|
|
48
|
+
"data-slot": "scroll-rail",
|
|
49
|
+
className: cn(scrollRailWrapperVariants(), className),
|
|
50
|
+
...props,
|
|
51
|
+
children: [
|
|
52
|
+
/* @__PURE__ */ jsx(
|
|
53
|
+
"div",
|
|
54
|
+
{
|
|
55
|
+
ref: trackRef,
|
|
56
|
+
"data-slot": "scroll-rail-track",
|
|
57
|
+
className: scrollRailVariants({ gap }),
|
|
58
|
+
onScroll: updateScrollState,
|
|
59
|
+
children
|
|
60
|
+
}
|
|
61
|
+
),
|
|
62
|
+
!hideChevrons && /* @__PURE__ */ jsx(Presence, { initial: false, children: canScrollLeft && /* @__PURE__ */ jsx(
|
|
63
|
+
motion.button,
|
|
64
|
+
{
|
|
65
|
+
type: "button",
|
|
66
|
+
"aria-label": labelPrev,
|
|
67
|
+
"data-slot": "scroll-rail-prev",
|
|
68
|
+
className: scrollRailChevronVariants({ side: "left" }),
|
|
69
|
+
initial: "hidden",
|
|
70
|
+
animate: "visible",
|
|
71
|
+
exit: "exit",
|
|
72
|
+
variants: fadeVariants,
|
|
73
|
+
onClick: () => trackRef.current?.scrollBy({ left: -getScrollAmount(), behavior: "smooth" }),
|
|
74
|
+
...gestureProps,
|
|
75
|
+
children: /* @__PURE__ */ jsx(ChevronLeft, { "aria-hidden": "true", className: "size-5" })
|
|
76
|
+
},
|
|
77
|
+
"scroll-rail-prev"
|
|
78
|
+
) }),
|
|
79
|
+
!hideChevrons && /* @__PURE__ */ jsx(Presence, { initial: false, children: canScrollRight && /* @__PURE__ */ jsx(
|
|
80
|
+
motion.button,
|
|
81
|
+
{
|
|
82
|
+
type: "button",
|
|
83
|
+
"aria-label": labelNext,
|
|
84
|
+
"data-slot": "scroll-rail-next",
|
|
85
|
+
className: scrollRailChevronVariants({ side: "right" }),
|
|
86
|
+
initial: "hidden",
|
|
87
|
+
animate: "visible",
|
|
88
|
+
exit: "exit",
|
|
89
|
+
variants: fadeVariants,
|
|
90
|
+
onClick: () => trackRef.current?.scrollBy({ left: getScrollAmount(), behavior: "smooth" }),
|
|
91
|
+
...gestureProps,
|
|
92
|
+
children: /* @__PURE__ */ jsx(ChevronRight, { "aria-hidden": "true", className: "size-5" })
|
|
93
|
+
},
|
|
94
|
+
"scroll-rail-next"
|
|
95
|
+
) })
|
|
96
|
+
]
|
|
97
|
+
}
|
|
98
|
+
);
|
|
99
|
+
}
|
|
100
|
+
);
|
|
101
|
+
ScrollRail.displayName = "ScrollRail";
|
|
102
|
+
|
|
103
|
+
export { ScrollRail };
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { type VariantProps } from 'class-variance-authority';
|
|
2
|
+
export declare const scrollRailWrapperVariants: (props?: import("class-variance-authority/types").ClassProp | undefined) => string;
|
|
3
|
+
export declare const scrollRailVariants: (props?: ({
|
|
4
|
+
gap?: "sm" | "md" | "lg" | null | undefined;
|
|
5
|
+
} & import("class-variance-authority/types").ClassProp) | undefined) => string;
|
|
6
|
+
export declare const scrollRailChevronVariants: (props?: ({
|
|
7
|
+
side?: "left" | "right" | null | undefined;
|
|
8
|
+
} & import("class-variance-authority/types").ClassProp) | undefined) => string;
|
|
9
|
+
export type ScrollRailVariants = VariantProps<typeof scrollRailVariants>;
|
|
10
|
+
//# sourceMappingURL=ScrollRail.styles.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ScrollRail.styles.d.ts","sourceRoot":"","sources":["../../../src/components/ScrollRail/ScrollRail.styles.ts"],"names":[],"mappings":"AAAA,OAAO,EAAO,KAAK,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAElE,eAAO,MAAM,yBAAyB,oFAAyB,CAAC;AAEhE,eAAO,MAAM,kBAAkB;;8EAc9B,CAAC;AAEF,eAAO,MAAM,yBAAyB;;8EAUrC,CAAC;AAEF,MAAM,MAAM,kBAAkB,GAAG,YAAY,CAAC,OAAO,kBAAkB,CAAC,CAAC"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { cva } from 'class-variance-authority';
|
|
2
|
+
|
|
3
|
+
const scrollRailWrapperVariants = cva("relative w-full");
|
|
4
|
+
const scrollRailVariants = cva(
|
|
5
|
+
"w-full overflow-x-auto pb-4 pt-1 px-1 flex snap-x snap-mandatory scroll-smooth focus:outline-none [-ms-overflow-style:none] [scrollbar-width:none] [&::-webkit-scrollbar]:hidden",
|
|
6
|
+
{
|
|
7
|
+
variants: {
|
|
8
|
+
gap: {
|
|
9
|
+
sm: "gap-3",
|
|
10
|
+
md: "gap-5 sm:gap-6",
|
|
11
|
+
lg: "gap-6 sm:gap-8"
|
|
12
|
+
}
|
|
13
|
+
},
|
|
14
|
+
defaultVariants: {
|
|
15
|
+
gap: "md"
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
);
|
|
19
|
+
const scrollRailChevronVariants = cva(
|
|
20
|
+
"absolute top-1/2 z-10 hidden size-10 -translate-y-1/2 items-center justify-center rounded-full bg-grey-50/70 text-grey-950 shadow-sm backdrop-blur-sm transition-colors hover:bg-grey-50 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring md:flex",
|
|
21
|
+
{
|
|
22
|
+
variants: {
|
|
23
|
+
side: {
|
|
24
|
+
left: "left-2",
|
|
25
|
+
right: "right-2"
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
);
|
|
30
|
+
|
|
31
|
+
export { scrollRailChevronVariants, scrollRailVariants, scrollRailWrapperVariants };
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type * as React from 'react';
|
|
2
|
+
import type { ScrollRailVariants } from './ScrollRail.styles';
|
|
3
|
+
export interface ScrollRailProps extends React.HTMLAttributes<HTMLDivElement>, ScrollRailVariants {
|
|
4
|
+
gap?: 'sm' | 'md' | 'lg';
|
|
5
|
+
/** Override px amount scrolled per chevron click. Default: 80% of track clientWidth. */
|
|
6
|
+
scrollAmount?: number;
|
|
7
|
+
/** Suppress chevrons entirely (touch-only contexts). */
|
|
8
|
+
hideChevrons?: boolean;
|
|
9
|
+
/** Accessible label for the left button. @default 'Scroll left' */
|
|
10
|
+
labelPrev?: string;
|
|
11
|
+
/** Accessible label for the right button. @default 'Scroll right' */
|
|
12
|
+
labelNext?: string;
|
|
13
|
+
children?: React.ReactNode;
|
|
14
|
+
className?: string;
|
|
15
|
+
}
|
|
16
|
+
//# sourceMappingURL=ScrollRail.types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ScrollRail.types.d.ts","sourceRoot":"","sources":["../../../src/components/ScrollRail/ScrollRail.types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,KAAK,MAAM,OAAO,CAAC;AACpC,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AAE9D,MAAM,WAAW,eACf,SAAQ,KAAK,CAAC,cAAc,CAAC,cAAc,CAAC,EAC1C,kBAAkB;IACpB,GAAG,CAAC,EAAE,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;IACzB,wFAAwF;IACxF,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,wDAAwD;IACxD,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,mEAAmE;IACnE,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,qEAAqE;IACrE,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC3B,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/ScrollRail/index.ts"],"names":[],"mappings":"AAAA,cAAc,cAAc,CAAC;AAC7B,cAAc,qBAAqB,CAAC;AACpC,cAAc,oBAAoB,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Stack.d.ts","sourceRoot":"","sources":["../../../src/components/Stack/Stack.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAK/B,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAqBhD,eAAO,MAAM,KAAK,
|
|
1
|
+
{"version":3,"file":"Stack.d.ts","sourceRoot":"","sources":["../../../src/components/Stack/Stack.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAK/B,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAqBhD,eAAO,MAAM,KAAK,mFA6CjB,CAAC"}
|
|
@@ -29,11 +29,12 @@ const Stack = React.forwardRef(
|
|
|
29
29
|
align = "stretch",
|
|
30
30
|
justify = "start",
|
|
31
31
|
divider,
|
|
32
|
+
as,
|
|
32
33
|
asChild = false,
|
|
33
34
|
children,
|
|
34
35
|
...props
|
|
35
36
|
}, ref) => {
|
|
36
|
-
const Component = asChild ? Slot : "div";
|
|
37
|
+
const Component = asChild ? Slot : as ?? "div";
|
|
37
38
|
const gapClass = formatGap(gap);
|
|
38
39
|
const renderChildren = () => {
|
|
39
40
|
if (!divider) return children;
|
|
@@ -22,6 +22,11 @@ export interface StackProps extends Omit<React.HTMLAttributes<HTMLDivElement>, '
|
|
|
22
22
|
* Optional divider element rendered between each child in the stack.
|
|
23
23
|
*/
|
|
24
24
|
divider?: React.ReactNode;
|
|
25
|
+
/**
|
|
26
|
+
* Renders as a different HTML element or component while keeping Stack styles.
|
|
27
|
+
* e.g. `as="article"`, `as="section"`, `as="header"`. Ignored when `asChild` is true.
|
|
28
|
+
*/
|
|
29
|
+
as?: React.ElementType;
|
|
25
30
|
/**
|
|
26
31
|
* If true, renders child element via Radix Slot.
|
|
27
32
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Stack.types.d.ts","sourceRoot":"","sources":["../../../src/components/Stack/Stack.types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,KAAK,MAAM,OAAO,CAAC;AACpC,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AACpD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAEhD,qDAAqD;AACrD,MAAM,WAAW,mBAAmB;IAClC,IAAI,CAAC,EAAE,QAAQ,GAAG,KAAK,CAAC;IACxB,EAAE,CAAC,EAAE,QAAQ,GAAG,KAAK,CAAC;IACtB,EAAE,CAAC,EAAE,QAAQ,GAAG,KAAK,CAAC;IACtB,EAAE,CAAC,EAAE,QAAQ,GAAG,KAAK,CAAC;CACvB;AAED,MAAM,WAAW,UACf,SAAQ,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,cAAc,CAAC,EAAE,KAAK,CAAC,EACvD,IAAI,CAAC,aAAa,EAAE,KAAK,CAAC;IAC5B;;OAEG;IACH,GAAG,CAAC,EAAE,QAAQ,CAAC;IACf;;;OAGG;IACH,SAAS,CAAC,EAAE,QAAQ,GAAG,KAAK,GAAG,mBAAmB,CAAC;IACnD;;OAEG;IACH,OAAO,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B;;OAEG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB"}
|
|
1
|
+
{"version":3,"file":"Stack.types.d.ts","sourceRoot":"","sources":["../../../src/components/Stack/Stack.types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,KAAK,MAAM,OAAO,CAAC;AACpC,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AACpD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAEhD,qDAAqD;AACrD,MAAM,WAAW,mBAAmB;IAClC,IAAI,CAAC,EAAE,QAAQ,GAAG,KAAK,CAAC;IACxB,EAAE,CAAC,EAAE,QAAQ,GAAG,KAAK,CAAC;IACtB,EAAE,CAAC,EAAE,QAAQ,GAAG,KAAK,CAAC;IACtB,EAAE,CAAC,EAAE,QAAQ,GAAG,KAAK,CAAC;CACvB;AAED,MAAM,WAAW,UACf,SAAQ,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,cAAc,CAAC,EAAE,KAAK,CAAC,EACvD,IAAI,CAAC,aAAa,EAAE,KAAK,CAAC;IAC5B;;OAEG;IACH,GAAG,CAAC,EAAE,QAAQ,CAAC;IACf;;;OAGG;IACH,SAAS,CAAC,EAAE,QAAQ,GAAG,KAAK,GAAG,mBAAmB,CAAC;IACnD;;OAEG;IACH,OAAO,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B;;;OAGG;IACH,EAAE,CAAC,EAAE,KAAK,CAAC,WAAW,CAAC;IACvB;;OAEG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ZoneProgress.d.ts","sourceRoot":"","sources":["../../../src/components/ZoneProgress/ZoneProgress.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AA0B/B,wBAAgB,YAAY,sBA2F3B;yBA3Fe,YAAY"}
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx } from 'react/jsx-runtime';
|
|
3
|
+
import * as React from 'react';
|
|
4
|
+
import { usePathname } from 'next/navigation';
|
|
5
|
+
import { PageProgress } from '../PageProgress/PageProgress.js';
|
|
6
|
+
|
|
7
|
+
function trickle(p) {
|
|
8
|
+
if (p < 20) return p + 5;
|
|
9
|
+
if (p < 50) return p + 3;
|
|
10
|
+
if (p < 70) return p + 2;
|
|
11
|
+
if (p < 85) return p + 1;
|
|
12
|
+
return p;
|
|
13
|
+
}
|
|
14
|
+
function ZoneProgress() {
|
|
15
|
+
const pathname = usePathname();
|
|
16
|
+
const [loading, setLoading] = React.useState(false);
|
|
17
|
+
const [progress, setProgress] = React.useState(void 0);
|
|
18
|
+
const tickRef = React.useRef(null);
|
|
19
|
+
const committedPathnameRef = React.useRef(pathname);
|
|
20
|
+
React.useLayoutEffect(() => {
|
|
21
|
+
committedPathnameRef.current = pathname;
|
|
22
|
+
});
|
|
23
|
+
const startProgress = React.useCallback(() => {
|
|
24
|
+
if (tickRef.current) clearInterval(tickRef.current);
|
|
25
|
+
setLoading(true);
|
|
26
|
+
setProgress(5);
|
|
27
|
+
tickRef.current = setInterval(() => {
|
|
28
|
+
setProgress((p) => p !== void 0 ? trickle(p) : p);
|
|
29
|
+
}, 200);
|
|
30
|
+
}, []);
|
|
31
|
+
const finishProgress = React.useCallback(() => {
|
|
32
|
+
if (tickRef.current) {
|
|
33
|
+
clearInterval(tickRef.current);
|
|
34
|
+
tickRef.current = null;
|
|
35
|
+
}
|
|
36
|
+
setProgress(100);
|
|
37
|
+
setTimeout(() => {
|
|
38
|
+
setLoading(false);
|
|
39
|
+
setProgress(void 0);
|
|
40
|
+
}, 400);
|
|
41
|
+
}, []);
|
|
42
|
+
React.useEffect(() => {
|
|
43
|
+
const handleClick = (e) => {
|
|
44
|
+
const anchor = e.target.closest("a");
|
|
45
|
+
if (!(anchor instanceof HTMLAnchorElement)) return;
|
|
46
|
+
if (e.defaultPrevented || e.metaKey || e.ctrlKey || e.shiftKey || e.altKey) return;
|
|
47
|
+
if (anchor.target === "_blank") return;
|
|
48
|
+
const href = anchor.getAttribute("href");
|
|
49
|
+
if (!href || href.startsWith("#") || href.startsWith("javascript:")) return;
|
|
50
|
+
try {
|
|
51
|
+
const url = new URL(href, location.origin);
|
|
52
|
+
if (url.origin !== location.origin) return;
|
|
53
|
+
if (url.pathname + url.search === location.pathname + location.search) return;
|
|
54
|
+
} catch {
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
startProgress();
|
|
58
|
+
};
|
|
59
|
+
const handlePopState = () => {
|
|
60
|
+
if (location.pathname !== committedPathnameRef.current) {
|
|
61
|
+
startProgress();
|
|
62
|
+
}
|
|
63
|
+
};
|
|
64
|
+
document.addEventListener("click", handleClick);
|
|
65
|
+
window.addEventListener("popstate", handlePopState);
|
|
66
|
+
return () => {
|
|
67
|
+
document.removeEventListener("click", handleClick);
|
|
68
|
+
window.removeEventListener("popstate", handlePopState);
|
|
69
|
+
if (tickRef.current) clearInterval(tickRef.current);
|
|
70
|
+
};
|
|
71
|
+
}, [startProgress]);
|
|
72
|
+
React.useEffect(() => {
|
|
73
|
+
if (loading) finishProgress();
|
|
74
|
+
}, [pathname, finishProgress]);
|
|
75
|
+
React.useEffect(() => {
|
|
76
|
+
const onHover = (e) => {
|
|
77
|
+
const a = e.target.closest('a[data-cross-zone="true"]');
|
|
78
|
+
if (!(a instanceof HTMLAnchorElement)) return;
|
|
79
|
+
const { href } = a;
|
|
80
|
+
if (!href) return;
|
|
81
|
+
const escaped = href.replace(/"/g, '\\"');
|
|
82
|
+
if (!document.querySelector(`link[rel="prefetch"][href="${escaped}"]`)) {
|
|
83
|
+
const el = document.createElement("link");
|
|
84
|
+
el.rel = "prefetch";
|
|
85
|
+
el.href = href;
|
|
86
|
+
document.head.appendChild(el);
|
|
87
|
+
}
|
|
88
|
+
};
|
|
89
|
+
document.addEventListener("mouseover", onHover);
|
|
90
|
+
return () => document.removeEventListener("mouseover", onHover);
|
|
91
|
+
}, []);
|
|
92
|
+
return /* @__PURE__ */ jsx(PageProgress, { loading, progress });
|
|
93
|
+
}
|
|
94
|
+
ZoneProgress.displayName = "ZoneProgress";
|
|
95
|
+
|
|
96
|
+
export { ZoneProgress };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/ZoneProgress/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC"}
|
package/dist/index.d.ts
CHANGED
|
@@ -6,6 +6,7 @@ export * from './components/Grid';
|
|
|
6
6
|
export * from './components/Center';
|
|
7
7
|
export * from './components/Stack';
|
|
8
8
|
export * from './components/Inline';
|
|
9
|
+
export * from './components/ScrollRail';
|
|
9
10
|
export * from './components/Input';
|
|
10
11
|
export * from './components/Textarea';
|
|
11
12
|
export * from './components/Select';
|
|
@@ -49,6 +50,7 @@ export * from './components/Text';
|
|
|
49
50
|
export * from './components/Alert';
|
|
50
51
|
export * from './components/Progress';
|
|
51
52
|
export * from './components/PageProgress';
|
|
53
|
+
export * from './components/ZoneProgress';
|
|
52
54
|
export * from './components/Spinner';
|
|
53
55
|
export * from './components/Skeleton';
|
|
54
56
|
export * from './components/EmptyState';
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,cAAc,gBAAgB,CAAC;AAC/B,YAAY,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAG3D,cAAc,aAAa,CAAC;AAG5B,cAAc,wBAAwB,CAAC;AACvC,cAAc,mBAAmB,CAAC;AAClC,cAAc,qBAAqB,CAAC;AACpC,cAAc,oBAAoB,CAAC;AACnC,cAAc,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,cAAc,gBAAgB,CAAC;AAC/B,YAAY,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAG3D,cAAc,aAAa,CAAC;AAG5B,cAAc,wBAAwB,CAAC;AACvC,cAAc,mBAAmB,CAAC;AAClC,cAAc,qBAAqB,CAAC;AACpC,cAAc,oBAAoB,CAAC;AACnC,cAAc,qBAAqB,CAAC;AACpC,cAAc,yBAAyB,CAAC;AAGxC,cAAc,oBAAoB,CAAC;AACnC,cAAc,uBAAuB,CAAC;AACtC,cAAc,qBAAqB,CAAC;AACpC,cAAc,oBAAoB,CAAC;AACnC,cAAc,wBAAwB,CAAC;AACvC,cAAc,uBAAuB,CAAC;AACtC,cAAc,qBAAqB,CAAC;AACpC,cAAc,0BAA0B,CAAC;AACzC,cAAc,0BAA0B,CAAC;AACzC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,oBAAoB,CAAC;AACnC,cAAc,wBAAwB,CAAC;AACvC,cAAc,0BAA0B,CAAC;AACzC,cAAc,uBAAuB,CAAC;AAGtC,cAAc,0BAA0B,CAAC;AACzC,cAAc,qBAAqB,CAAC;AACpC,cAAc,qBAAqB,CAAC;AACpC,cAAc,+BAA+B,CAAC;AAC9C,cAAc,uBAAuB,CAAC;AACtC,cAAc,sBAAsB,CAAC;AACrC,cAAc,oBAAoB,CAAC;AACnC,cAAc,uBAAuB,CAAC;AACtC,cAAc,sBAAsB,CAAC;AACrC,cAAc,mBAAmB,CAAC;AAClC,cAAc,gCAAgC,CAAC;AAC/C,cAAc,wBAAwB,CAAC;AACvC,cAAc,6BAA6B,CAAC;AAC5C,cAAc,yBAAyB,CAAC;AACxC,cAAc,wBAAwB,CAAC;AACvC,cAAc,wBAAwB,CAAC;AAGvC,cAAc,qBAAqB,CAAC;AACpC,cAAc,yBAAyB,CAAC;AACxC,cAAc,wBAAwB,CAAC;AACvC,cAAc,qBAAqB,CAAC;AACpC,cAAc,oBAAoB,CAAC;AACnC,cAAc,mBAAmB,CAAC;AAClC,cAAc,sBAAsB,CAAC;AACrC,cAAc,sBAAsB,CAAC;AACrC,cAAc,mBAAmB,CAAC;AAClC,cAAc,mBAAmB,CAAC;AAGlC,cAAc,oBAAoB,CAAC;AACnC,cAAc,uBAAuB,CAAC;AACtC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,2BAA2B,CAAC;AAC1C,cAAc,sBAAsB,CAAC;AACrC,cAAc,uBAAuB,CAAC;AACtC,cAAc,yBAAyB,CAAC;AAGxC,cAAc,oBAAoB,CAAC;AACnC,cAAc,yBAAyB,CAAC;AACxC,cAAc,uBAAuB,CAAC;AACtC,cAAc,mBAAmB,CAAC;AAClC,cAAc,mBAAmB,CAAC;AAClC,cAAc,0BAA0B,CAAC;AACzC,cAAc,qBAAqB,CAAC;AACpC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,8BAA8B,CAAC;AAC7C,cAAc,yBAAyB,CAAC;AACxC,cAAc,6BAA6B,CAAC;AAC5C,cAAc,mBAAmB,CAAC;AAClC,cAAc,qBAAqB,CAAC;AACpC,cAAc,yBAAyB,CAAC;AACxC,cAAc,sBAAsB,CAAC;AACrC,cAAc,wBAAwB,CAAC;AACvC,cAAc,oBAAoB,CAAC;AACnC,cAAc,qBAAqB,CAAC;AACpC,cAAc,uBAAuB,CAAC;AACtC,cAAc,6BAA6B,CAAC;AAC5C,cAAc,uBAAuB,CAAC;AACtC,cAAc,0BAA0B,CAAC;AACzC,cAAc,4BAA4B,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -81,6 +81,7 @@ export { RadioCard } from './components/RadioCard/RadioCard.js';
|
|
|
81
81
|
export { RangeSlider } from './components/RangeSlider/RangeSlider.js';
|
|
82
82
|
export { Rating } from './components/Rating/Rating.js';
|
|
83
83
|
export { SNACKBAR_EXIT_MS, snackbar, snackbarStore } from './components/Snackbar/snackbarStore.js';
|
|
84
|
+
export { ScrollRail } from './components/ScrollRail/ScrollRail.js';
|
|
84
85
|
export { Select, SelectContent, SelectGroup, SelectItem, SelectLabel, SelectRoot, SelectSeparator, SelectTrigger, SelectValue } from './components/Select/Select.js';
|
|
85
86
|
export { SideBarNavigation } from './components/SideBarNavigation/SideBarNavigation.js';
|
|
86
87
|
export { SidebarBranding } from './components/SideBarNavigation/subcomponents/SidebarBranding.js';
|
|
@@ -113,6 +114,7 @@ export { Toast, ToastAction, ToastClose, ToastDescription, ToastProvider, ToastT
|
|
|
113
114
|
export { ToastContainer } from './components/Toast/ToastContainer.js';
|
|
114
115
|
export { Tooltip, TooltipArrow, TooltipContent, TooltipPortal, TooltipProvider, TooltipRoot, TooltipTrigger } from './components/Tooltip/Tooltip.js';
|
|
115
116
|
export { VisuallyHidden } from './components/VisuallyHidden/VisuallyHidden.js';
|
|
117
|
+
export { ZoneProgress } from './components/ZoneProgress/ZoneProgress.js';
|
|
116
118
|
export { accordionContentVariants, accordionItemVariants, accordionTriggerVariants } from './components/Accordion/Accordion.styles.js';
|
|
117
119
|
export { alertDialogBodyVariants, alertDialogContentVariants, alertDialogDescriptionVariants, alertDialogFooterVariants, alertDialogHeaderVariants, alertDialogMediaVariants, alertDialogOverlayVariants, alertDialogTitleVariants } from './components/AlertDialog/AlertDialog.styles.js';
|
|
118
120
|
export { alertIconVariants, alertVariants } from './components/Alert/Alert.styles.js';
|
|
@@ -163,6 +165,7 @@ export { radioCardDotClass, radioCardMarkerClass, radioCardVariants } from './co
|
|
|
163
165
|
export { radioIndicatorVariants, radioItemVariants } from './components/Radio/Radio.styles.js';
|
|
164
166
|
export { rangeSliderRangeVariants, rangeSliderRootVariants, rangeSliderThumbVariants, rangeSliderTrackVariants } from './components/RangeSlider/RangeSlider.styles.js';
|
|
165
167
|
export { ratingVariants } from './components/Rating/Rating.styles.js';
|
|
168
|
+
export { scrollRailChevronVariants, scrollRailVariants, scrollRailWrapperVariants } from './components/ScrollRail/ScrollRail.styles.js';
|
|
166
169
|
export { selectContentVariants, selectItemVariants, selectTriggerVariants } from './components/Select/Select.styles.js';
|
|
167
170
|
export { skeletonVariants } from './components/Skeleton/Skeleton.styles.js';
|
|
168
171
|
export { snackbarActionVariants, snackbarCloseVariants, snackbarHostVariants, snackbarIconVariants, snackbarVariants } from './components/Snackbar/Snackbar.styles.js';
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@timmbr/ui",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.13.1",
|
|
4
4
|
"description": "High-performance, Next.js App Router-compatible UI design system components for Timmbr",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -42,11 +42,11 @@
|
|
|
42
42
|
"@radix-ui/react-tooltip": "^1.2.16",
|
|
43
43
|
"class-variance-authority": "^0.7.1",
|
|
44
44
|
"input-otp": "^1.5.0",
|
|
45
|
-
"@timmbr/
|
|
46
|
-
"@timmbr/hooks": "1.1.0",
|
|
47
|
-
"@timmbr/utils": "1.6.0",
|
|
45
|
+
"@timmbr/hooks": "1.2.0",
|
|
48
46
|
"@timmbr/theme": "1.3.0",
|
|
49
|
-
"@timmbr/motion": "1.2.5"
|
|
47
|
+
"@timmbr/motion": "1.2.5",
|
|
48
|
+
"@timmbr/icons": "1.6.0",
|
|
49
|
+
"@timmbr/utils": "1.6.0"
|
|
50
50
|
},
|
|
51
51
|
"peerDependencies": {
|
|
52
52
|
"next": ">=13.0.0 || >=14.0.0 || >=15.0.0 || >=16.0.0",
|