@ttt-productions/ui-core 0.11.8 → 0.11.9
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/react/components/scroll-to-top-button.d.ts +15 -3
- package/dist/react/components/scroll-to-top-button.d.ts.map +1 -1
- package/dist/react/components/scroll-to-top-button.js +2 -2
- package/dist/react/components/scroll-to-top-button.js.map +1 -1
- package/package.json +1 -1
- package/src/react/components/scroll-to-top-button.tsx +19 -2
|
@@ -1,11 +1,22 @@
|
|
|
1
1
|
import * as React from "react";
|
|
2
2
|
import { type ButtonProps } from "./button.js";
|
|
3
|
-
|
|
3
|
+
/**
|
|
4
|
+
* Standard button DOM props forwarded to the rendered element, minus the props
|
|
5
|
+
* this component owns. Owned props are excluded (not just overridden) so a
|
|
6
|
+
* consumer can never route them through the passthrough channel: `aria-label`
|
|
7
|
+
* is set via {@link ScrollToTopButtonProps.ariaLabel}, extra classes via the
|
|
8
|
+
* merge-aware {@link ScrollToTopButtonProps.className}, content via
|
|
9
|
+
* {@link ScrollToTopButtonProps.icon}, and `onClick` is fixed to scroll-to-top.
|
|
10
|
+
* This mirrors how the sibling `Button` destructures its owned `className` out
|
|
11
|
+
* of the forwarded `...props`.
|
|
12
|
+
*/
|
|
13
|
+
type ScrollToTopButtonPassthrough = Omit<React.ComponentPropsWithoutRef<"button">, "className" | "onClick" | "aria-label" | "children">;
|
|
14
|
+
export interface ScrollToTopButtonProps extends ScrollToTopButtonPassthrough {
|
|
4
15
|
/** Scroll threshold (px) before the button appears. Default 400. */
|
|
5
16
|
threshold?: number;
|
|
6
17
|
/** Aria label. Default "Scroll to top". */
|
|
7
18
|
ariaLabel?: string;
|
|
8
|
-
/** Optional extra classes for the button. */
|
|
19
|
+
/** Optional extra classes for the button. Merged with the component's own classes. */
|
|
9
20
|
className?: string;
|
|
10
21
|
/** Optional override for the icon. */
|
|
11
22
|
icon?: React.ReactNode;
|
|
@@ -14,5 +25,6 @@ export interface ScrollToTopButtonProps {
|
|
|
14
25
|
/** Button size. Forwarded to the underlying Button. Default "icon". */
|
|
15
26
|
size?: ButtonProps["size"];
|
|
16
27
|
}
|
|
17
|
-
export declare function ScrollToTopButton({ threshold, ariaLabel, className, icon, variant, size, }: ScrollToTopButtonProps): React.JSX.Element;
|
|
28
|
+
export declare function ScrollToTopButton({ threshold, ariaLabel, className, icon, variant, size, ...rest }: ScrollToTopButtonProps): React.JSX.Element;
|
|
29
|
+
export {};
|
|
18
30
|
//# sourceMappingURL=scroll-to-top-button.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"scroll-to-top-button.d.ts","sourceRoot":"","sources":["../../../src/react/components/scroll-to-top-button.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAE/B,OAAO,EAAU,KAAK,WAAW,EAAE,MAAM,aAAa,CAAC;AAGvD,MAAM,WAAW,
|
|
1
|
+
{"version":3,"file":"scroll-to-top-button.d.ts","sourceRoot":"","sources":["../../../src/react/components/scroll-to-top-button.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAE/B,OAAO,EAAU,KAAK,WAAW,EAAE,MAAM,aAAa,CAAC;AAGvD;;;;;;;;;GASG;AACH,KAAK,4BAA4B,GAAG,IAAI,CACtC,KAAK,CAAC,wBAAwB,CAAC,QAAQ,CAAC,EACxC,WAAW,GAAG,SAAS,GAAG,YAAY,GAAG,UAAU,CACpD,CAAC;AAEF,MAAM,WAAW,sBAAuB,SAAQ,4BAA4B;IAC1E,oEAAoE;IACpE,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,2CAA2C;IAC3C,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,sFAAsF;IACtF,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,sCAAsC;IACtC,IAAI,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACvB,4FAA4F;IAC5F,OAAO,CAAC,EAAE,WAAW,CAAC,SAAS,CAAC,CAAC;IACjC,uEAAuE;IACvE,IAAI,CAAC,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;CAC5B;AAED,wBAAgB,iBAAiB,CAAC,EAChC,SAAe,EACf,SAA2B,EAC3B,SAAS,EACT,IAAI,EACJ,OAAO,EACP,IAAa,EACb,GAAG,IAAI,EACR,EAAE,sBAAsB,qBA4BxB"}
|
|
@@ -4,7 +4,7 @@ import * as React from "react";
|
|
|
4
4
|
import { ChevronUp } from "lucide-react";
|
|
5
5
|
import { Button } from "./button.js";
|
|
6
6
|
import { cn } from "../../lib/utils.js";
|
|
7
|
-
export function ScrollToTopButton({ threshold = 400, ariaLabel = "Scroll to top", className, icon, variant, size = "icon", }) {
|
|
7
|
+
export function ScrollToTopButton({ threshold = 400, ariaLabel = "Scroll to top", className, icon, variant, size = "icon", ...rest }) {
|
|
8
8
|
const [isVisible, setIsVisible] = React.useState(false);
|
|
9
9
|
React.useEffect(() => {
|
|
10
10
|
const toggle = () => setIsVisible(window.scrollY > threshold);
|
|
@@ -13,6 +13,6 @@ export function ScrollToTopButton({ threshold = 400, ariaLabel = "Scroll to top"
|
|
|
13
13
|
return () => window.removeEventListener("scroll", toggle);
|
|
14
14
|
}, [threshold]);
|
|
15
15
|
const onClick = () => window.scrollTo({ top: 0, behavior: "smooth" });
|
|
16
|
-
return (_jsx(Button, { variant: variant, size: size, onClick: onClick, "aria-label": ariaLabel, className: cn("fixed bottom-24 left-1/2 -translate-x-1/2 z-50 rounded-full shadow-lg transition-opacity duration-300", isVisible ? "opacity-100" : "opacity-0 pointer-events-none", className), children: icon ?? _jsx(ChevronUp, { className: "h-5 w-5" }) }));
|
|
16
|
+
return (_jsx(Button, { ...rest, variant: variant, size: size, onClick: onClick, "aria-label": ariaLabel, className: cn("fixed bottom-24 left-1/2 -translate-x-1/2 z-50 rounded-full shadow-lg transition-opacity duration-300", isVisible ? "opacity-100" : "opacity-0 pointer-events-none", className), children: icon ?? _jsx(ChevronUp, { className: "h-5 w-5" }) }));
|
|
17
17
|
}
|
|
18
18
|
//# sourceMappingURL=scroll-to-top-button.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"scroll-to-top-button.js","sourceRoot":"","sources":["../../../src/react/components/scroll-to-top-button.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAC;;AAEb,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AACzC,OAAO,EAAE,MAAM,EAAoB,MAAM,aAAa,CAAC;AACvD,OAAO,EAAE,EAAE,EAAE,MAAM,oBAAoB,CAAC;
|
|
1
|
+
{"version":3,"file":"scroll-to-top-button.js","sourceRoot":"","sources":["../../../src/react/components/scroll-to-top-button.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAC;;AAEb,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AACzC,OAAO,EAAE,MAAM,EAAoB,MAAM,aAAa,CAAC;AACvD,OAAO,EAAE,EAAE,EAAE,MAAM,oBAAoB,CAAC;AAgCxC,MAAM,UAAU,iBAAiB,CAAC,EAChC,SAAS,GAAG,GAAG,EACf,SAAS,GAAG,eAAe,EAC3B,SAAS,EACT,IAAI,EACJ,OAAO,EACP,IAAI,GAAG,MAAM,EACb,GAAG,IAAI,EACgB;IACvB,MAAM,CAAC,SAAS,EAAE,YAAY,CAAC,GAAG,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;IAExD,KAAK,CAAC,SAAS,CAAC,GAAG,EAAE;QACnB,MAAM,MAAM,GAAG,GAAG,EAAE,CAAC,YAAY,CAAC,MAAM,CAAC,OAAO,GAAG,SAAS,CAAC,CAAC;QAC9D,MAAM,EAAE,CAAC;QACT,MAAM,CAAC,gBAAgB,CAAC,QAAQ,EAAE,MAAM,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC;QAC7D,OAAO,GAAG,EAAE,CAAC,MAAM,CAAC,mBAAmB,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;IAC5D,CAAC,EAAE,CAAC,SAAS,CAAC,CAAC,CAAC;IAEhB,MAAM,OAAO,GAAG,GAAG,EAAE,CAAC,MAAM,CAAC,QAAQ,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,QAAQ,EAAE,QAAQ,EAAE,CAAC,CAAC;IAEtE,OAAO,CACL,KAAC,MAAM,OACD,IAAI,EACR,OAAO,EAAE,OAAO,EAChB,IAAI,EAAE,IAAI,EACV,OAAO,EAAE,OAAO,gBACJ,SAAS,EACrB,SAAS,EAAE,EAAE,CACX,uGAAuG,EACvG,SAAS,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,+BAA+B,EAC3D,SAAS,CACV,YAEA,IAAI,IAAI,KAAC,SAAS,IAAC,SAAS,EAAC,SAAS,GAAG,GACnC,CACV,CAAC;AACJ,CAAC","sourcesContent":["\"use client\";\n\nimport * as React from \"react\";\nimport { ChevronUp } from \"lucide-react\";\nimport { Button, type ButtonProps } from \"./button.js\";\nimport { cn } from \"../../lib/utils.js\";\n\n/**\n * Standard button DOM props forwarded to the rendered element, minus the props\n * this component owns. Owned props are excluded (not just overridden) so a\n * consumer can never route them through the passthrough channel: `aria-label`\n * is set via {@link ScrollToTopButtonProps.ariaLabel}, extra classes via the\n * merge-aware {@link ScrollToTopButtonProps.className}, content via\n * {@link ScrollToTopButtonProps.icon}, and `onClick` is fixed to scroll-to-top.\n * This mirrors how the sibling `Button` destructures its owned `className` out\n * of the forwarded `...props`.\n */\ntype ScrollToTopButtonPassthrough = Omit<\n React.ComponentPropsWithoutRef<\"button\">,\n \"className\" | \"onClick\" | \"aria-label\" | \"children\"\n>;\n\nexport interface ScrollToTopButtonProps extends ScrollToTopButtonPassthrough {\n /** Scroll threshold (px) before the button appears. Default 400. */\n threshold?: number;\n /** Aria label. Default \"Scroll to top\". */\n ariaLabel?: string;\n /** Optional extra classes for the button. Merged with the component's own classes. */\n className?: string;\n /** Optional override for the icon. */\n icon?: React.ReactNode;\n /** Button variant. Forwarded to the underlying Button. Defaults to Button's own default. */\n variant?: ButtonProps[\"variant\"];\n /** Button size. Forwarded to the underlying Button. Default \"icon\". */\n size?: ButtonProps[\"size\"];\n}\n\nexport function ScrollToTopButton({\n threshold = 400,\n ariaLabel = \"Scroll to top\",\n className,\n icon,\n variant,\n size = \"icon\",\n ...rest\n}: ScrollToTopButtonProps) {\n const [isVisible, setIsVisible] = React.useState(false);\n\n React.useEffect(() => {\n const toggle = () => setIsVisible(window.scrollY > threshold);\n toggle();\n window.addEventListener(\"scroll\", toggle, { passive: true });\n return () => window.removeEventListener(\"scroll\", toggle);\n }, [threshold]);\n\n const onClick = () => window.scrollTo({ top: 0, behavior: \"smooth\" });\n\n return (\n <Button\n {...rest}\n variant={variant}\n size={size}\n onClick={onClick}\n aria-label={ariaLabel}\n className={cn(\n \"fixed bottom-24 left-1/2 -translate-x-1/2 z-50 rounded-full shadow-lg transition-opacity duration-300\",\n isVisible ? \"opacity-100\" : \"opacity-0 pointer-events-none\",\n className,\n )}\n >\n {icon ?? <ChevronUp className=\"h-5 w-5\" />}\n </Button>\n );\n}\n"]}
|
package/package.json
CHANGED
|
@@ -5,12 +5,27 @@ import { ChevronUp } from "lucide-react";
|
|
|
5
5
|
import { Button, type ButtonProps } from "./button.js";
|
|
6
6
|
import { cn } from "../../lib/utils.js";
|
|
7
7
|
|
|
8
|
-
|
|
8
|
+
/**
|
|
9
|
+
* Standard button DOM props forwarded to the rendered element, minus the props
|
|
10
|
+
* this component owns. Owned props are excluded (not just overridden) so a
|
|
11
|
+
* consumer can never route them through the passthrough channel: `aria-label`
|
|
12
|
+
* is set via {@link ScrollToTopButtonProps.ariaLabel}, extra classes via the
|
|
13
|
+
* merge-aware {@link ScrollToTopButtonProps.className}, content via
|
|
14
|
+
* {@link ScrollToTopButtonProps.icon}, and `onClick` is fixed to scroll-to-top.
|
|
15
|
+
* This mirrors how the sibling `Button` destructures its owned `className` out
|
|
16
|
+
* of the forwarded `...props`.
|
|
17
|
+
*/
|
|
18
|
+
type ScrollToTopButtonPassthrough = Omit<
|
|
19
|
+
React.ComponentPropsWithoutRef<"button">,
|
|
20
|
+
"className" | "onClick" | "aria-label" | "children"
|
|
21
|
+
>;
|
|
22
|
+
|
|
23
|
+
export interface ScrollToTopButtonProps extends ScrollToTopButtonPassthrough {
|
|
9
24
|
/** Scroll threshold (px) before the button appears. Default 400. */
|
|
10
25
|
threshold?: number;
|
|
11
26
|
/** Aria label. Default "Scroll to top". */
|
|
12
27
|
ariaLabel?: string;
|
|
13
|
-
/** Optional extra classes for the button. */
|
|
28
|
+
/** Optional extra classes for the button. Merged with the component's own classes. */
|
|
14
29
|
className?: string;
|
|
15
30
|
/** Optional override for the icon. */
|
|
16
31
|
icon?: React.ReactNode;
|
|
@@ -27,6 +42,7 @@ export function ScrollToTopButton({
|
|
|
27
42
|
icon,
|
|
28
43
|
variant,
|
|
29
44
|
size = "icon",
|
|
45
|
+
...rest
|
|
30
46
|
}: ScrollToTopButtonProps) {
|
|
31
47
|
const [isVisible, setIsVisible] = React.useState(false);
|
|
32
48
|
|
|
@@ -41,6 +57,7 @@ export function ScrollToTopButton({
|
|
|
41
57
|
|
|
42
58
|
return (
|
|
43
59
|
<Button
|
|
60
|
+
{...rest}
|
|
44
61
|
variant={variant}
|
|
45
62
|
size={size}
|
|
46
63
|
onClick={onClick}
|