@g4rcez/components 2.0.1 → 2.0.3
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/core/button.d.ts +36 -0
- package/dist/components/core/button.d.ts.map +1 -1
- package/dist/components/core/button.js +35 -0
- package/dist/components/display/notifications.d.ts.map +1 -1
- package/dist/components/display/notifications.js +10 -10
- package/dist/components/display/progress.d.ts +2 -0
- package/dist/components/display/progress.d.ts.map +1 -1
- package/dist/components/display/progress.js +1 -1
- package/dist/components/floating/menu.js +1 -1
- package/dist/components/floating/modal.d.ts.map +1 -1
- package/dist/components/floating/modal.js +18 -12
- package/dist/components/form/autocomplete.d.ts.map +1 -1
- package/dist/components/form/autocomplete.js +9 -8
- package/dist/components/form/file-upload.js +5 -5
- package/dist/components/form/input-field.js +1 -1
- package/dist/components/form/input.d.ts +34 -0
- package/dist/components/form/input.d.ts.map +1 -1
- package/dist/components/form/input.js +30 -0
- package/dist/hooks/use-form.d.ts +46 -0
- package/dist/hooks/use-form.d.ts.map +1 -1
- package/dist/hooks/use-form.js +52 -0
- package/dist/index.css +1 -1
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +13645 -13437
- package/dist/index.mjs.map +1 -1
- package/dist/index.umd.js +56 -56
- package/dist/index.umd.js.map +1 -1
- package/dist/preset/plugin.tailwind.d.ts +7 -4
- package/dist/preset/plugin.tailwind.d.ts.map +1 -1
- package/dist/preset/plugin.tailwind.js +20 -13
- package/dist/preset/src/styles/common.d.ts +1 -1
- package/dist/preset/src/styles/common.js +1 -1
- package/dist/styles/common.d.ts +1 -1
- package/dist/styles/common.js +1 -1
- package/package.json +7 -1
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
import React, { PropsWithChildren } from "react";
|
|
2
2
|
import { CvaVariants, type Label } from "../../types";
|
|
3
3
|
import { PolymorphicProps } from "./polymorph";
|
|
4
|
+
/**
|
|
5
|
+
* Button variant definitions for styling
|
|
6
|
+
* @internal
|
|
7
|
+
*/
|
|
4
8
|
declare const variants: {
|
|
5
9
|
size: {
|
|
6
10
|
icon: string;
|
|
@@ -37,10 +41,42 @@ declare const variants: {
|
|
|
37
41
|
};
|
|
38
42
|
};
|
|
39
43
|
type Variants = CvaVariants<typeof variants>;
|
|
44
|
+
/**
|
|
45
|
+
* Props for the Button component
|
|
46
|
+
* @template T - The HTML element type to render as (defaults to "button")
|
|
47
|
+
*/
|
|
40
48
|
export type ButtonProps<T extends React.ElementType = "button"> = PropsWithChildren<PolymorphicProps<Variants & Partial<{
|
|
49
|
+
/** Icon to display in the button */
|
|
41
50
|
icon: Label;
|
|
51
|
+
/** Whether the button is in a loading state */
|
|
42
52
|
loading: boolean;
|
|
43
53
|
}>, T>>;
|
|
54
|
+
/**
|
|
55
|
+
* A versatile button component with multiple variants, sizes, and states.
|
|
56
|
+
*
|
|
57
|
+
* @example
|
|
58
|
+
* ```tsx
|
|
59
|
+
* // Basic usage
|
|
60
|
+
* <Button>Click me</Button>
|
|
61
|
+
*
|
|
62
|
+
* // With variants
|
|
63
|
+
* <Button theme="primary" size="big">Primary Button</Button>
|
|
64
|
+
*
|
|
65
|
+
* // Loading state
|
|
66
|
+
* <Button loading>Saving...</Button>
|
|
67
|
+
*
|
|
68
|
+
* // With icon
|
|
69
|
+
* <Button icon={<Icon name="plus" />}>Add Item</Button>
|
|
70
|
+
*
|
|
71
|
+
* // As different element
|
|
72
|
+
* <Button as="a" href="/link">Link Button</Button>
|
|
73
|
+
* ```
|
|
74
|
+
*
|
|
75
|
+
* @template T - The HTML element type to render as
|
|
76
|
+
* @param props - Button props including theme, size, loading state, etc.
|
|
77
|
+
* @param ref - Forwarded ref to the button element
|
|
78
|
+
* @returns A styled button component
|
|
79
|
+
*/
|
|
44
80
|
export declare const Button: <T extends React.ElementType = "button">(props: ButtonProps<T>) => React.ReactNode;
|
|
45
81
|
export {};
|
|
46
82
|
//# sourceMappingURL=button.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"button.d.ts","sourceRoot":"","sources":["../../../src/components/core/button.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,EAAc,iBAAiB,EAAE,MAAM,OAAO,CAAC;AAE7D,OAAO,EAAE,WAAW,EAAE,KAAK,KAAK,EAAE,MAAM,aAAa,CAAC;AACtD,OAAO,EAAa,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAE1D,QAAA,MAAM,QAAQ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAmCb,CAAC;
|
|
1
|
+
{"version":3,"file":"button.d.ts","sourceRoot":"","sources":["../../../src/components/core/button.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,EAAc,iBAAiB,EAAE,MAAM,OAAO,CAAC;AAE7D,OAAO,EAAE,WAAW,EAAE,KAAK,KAAK,EAAE,MAAM,aAAa,CAAC;AACtD,OAAO,EAAa,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAE1D;;;GAGG;AACH,QAAA,MAAM,QAAQ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAmCb,CAAC;AAeF,KAAK,QAAQ,GAAG,WAAW,CAAC,OAAO,QAAQ,CAAC,CAAC;AAE7C;;;GAGG;AACH,MAAM,MAAM,WAAW,CAAC,CAAC,SAAS,KAAK,CAAC,WAAW,GAAG,QAAQ,IAAI,iBAAiB,CAC/E,gBAAgB,CAAC,QAAQ,GAAG,OAAO,CAAC;IAChC,oCAAoC;IACpC,IAAI,EAAE,KAAK,CAAC;IACZ,+CAA+C;IAC/C,OAAO,EAAE,OAAO,CAAA;CACnB,CAAC,EAAE,CAAC,CAAC,CACT,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,eAAO,MAAM,MAAM,EAAE,CAAC,CAAC,SAAS,KAAK,CAAC,WAAW,GAAG,QAAQ,EAAE,KAAK,EAAE,WAAW,CAAC,CAAC,CAAC,KAAK,KAAK,CAAC,SAwB5F,CAAC"}
|
|
@@ -3,6 +3,10 @@ import { cva } from "class-variance-authority";
|
|
|
3
3
|
import { forwardRef } from "react";
|
|
4
4
|
import { css } from "../../lib/dom";
|
|
5
5
|
import { Polymorph } from "./polymorph";
|
|
6
|
+
/**
|
|
7
|
+
* Button variant definitions for styling
|
|
8
|
+
* @internal
|
|
9
|
+
*/
|
|
6
10
|
const variants = {
|
|
7
11
|
size: {
|
|
8
12
|
icon: "p-1",
|
|
@@ -38,10 +42,41 @@ const variants = {
|
|
|
38
42
|
"ghost-secondary": "bg-transparent hover:bg-secondary/20 border border-secondary text-secondary",
|
|
39
43
|
},
|
|
40
44
|
};
|
|
45
|
+
/**
|
|
46
|
+
* Class variance authority configuration for button styling
|
|
47
|
+
* Handles all visual states and variants of the button component
|
|
48
|
+
* @internal
|
|
49
|
+
*/
|
|
41
50
|
const buttonVariants = cva("relative overflow-hidden inline-flex duration-500 enabled:hover:bg-opacity-70 enabled:focus:bg-opacity-70 data-[loading=true]:opacity-30 data-[loading=true]:animate-pulse gap-1.5 items-center justify-center align-middle cursor-pointer whitespace-nowrap font-medium transition-colors ease-in disabled:cursor-not-allowed disabled:bg-opacity-40 disabled:text-opacity-80 focus-visible:outline-none focus-visible:ring-4 focus-visible:ring-ring", {
|
|
42
51
|
variants,
|
|
43
52
|
defaultVariants: { theme: "main", size: "default", rounded: "default" },
|
|
44
53
|
});
|
|
54
|
+
/**
|
|
55
|
+
* A versatile button component with multiple variants, sizes, and states.
|
|
56
|
+
*
|
|
57
|
+
* @example
|
|
58
|
+
* ```tsx
|
|
59
|
+
* // Basic usage
|
|
60
|
+
* <Button>Click me</Button>
|
|
61
|
+
*
|
|
62
|
+
* // With variants
|
|
63
|
+
* <Button theme="primary" size="big">Primary Button</Button>
|
|
64
|
+
*
|
|
65
|
+
* // Loading state
|
|
66
|
+
* <Button loading>Saving...</Button>
|
|
67
|
+
*
|
|
68
|
+
* // With icon
|
|
69
|
+
* <Button icon={<Icon name="plus" />}>Add Item</Button>
|
|
70
|
+
*
|
|
71
|
+
* // As different element
|
|
72
|
+
* <Button as="a" href="/link">Link Button</Button>
|
|
73
|
+
* ```
|
|
74
|
+
*
|
|
75
|
+
* @template T - The HTML element type to render as
|
|
76
|
+
* @param props - Button props including theme, size, loading state, etc.
|
|
77
|
+
* @param ref - Forwarded ref to the button element
|
|
78
|
+
* @returns A styled button component
|
|
79
|
+
*/
|
|
45
80
|
export const Button = forwardRef(function Button({ className, icon, loading, theme, type = "button", size, rounded, ...props }, ref) {
|
|
46
81
|
const disabled = loading || props.disabled;
|
|
47
82
|
return (_jsxs(Polymorph, { ...props, ref: ref, type: type, "data-theme": theme, disabled: disabled, "data-loading": loading, "data-component": "button", "aria-disabled": disabled, as: props.as ?? "button", "aria-busy": disabled || loading, onClick: disabled ? undefined : props.onClick, className: css(buttonVariants({ size, rounded, theme }), className), children: [icon, props.children] }));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"notifications.d.ts","sourceRoot":"","sources":["../../../src/components/display/notifications.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"notifications.d.ts","sourceRoot":"","sources":["../../../src/components/display/notifications.tsx"],"names":[],"mappings":"AACA,OAAO,EAAO,KAAK,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAIlE,OAAO,EAAgD,KAAK,iBAAiB,EAAwD,MAAM,OAAO,CAAC;AAEnJ,OAAO,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AAEpC,QAAA,MAAM,QAAQ;;mFAcb,CAAC;AAEF,KAAK,mBAAmB,GAAG,OAAO,CAAC;IAC/B,KAAK,EAAE,KAAK,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,OAAO,CAAC;IAClB,KAAK,EAAE,YAAY,CAAC,OAAO,QAAQ,CAAC,CAAC,OAAO,CAAC,CAAC;CACjD,CAAC,CAAC;AAEH,KAAK,sBAAsB,GAAG;IAAE,KAAK,EAAE,MAAM,IAAI,CAAC;IAAC,KAAK,EAAE,MAAM,IAAI,CAAA;CAAE,CAAC;AAEvE,KAAK,eAAe,GAAG,CAAC,IAAI,EAAE,KAAK,EAAE,IAAI,CAAC,EAAE,mBAAmB,KAAK,sBAAsB,CAAC;AAM3F,eAAO,MAAM,eAAe,uBAAwC,CAAC;AA+DrE,MAAM,MAAM,iBAAiB,GAAG,OAAO,CAAC;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,CAAC,CAAC;AAE3E,wBAAgB,aAAa,CAAC,EAAE,QAAQ,EAAE,GAAO,EAAE,QAAe,EAAE,EAAE,iBAAiB,CAAC,iBAAiB,CAAC,2CAyDzG"}
|
|
@@ -1,20 +1,20 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { createElement as _createElement } from "react";
|
|
3
3
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
4
|
-
import { Toast as RadixToast } from "radix-ui";
|
|
5
4
|
import { cva } from "class-variance-authority";
|
|
6
|
-
import { AnimatePresence, motion } from "motion/react";
|
|
7
5
|
import { XIcon } from "lucide-react";
|
|
6
|
+
import { AnimatePresence, motion } from "motion/react";
|
|
7
|
+
import { Toast as RadixToast } from "radix-ui";
|
|
8
8
|
import { createContext, forwardRef, useCallback, useContext, useEffect, useRef, useState } from "react";
|
|
9
9
|
import { useHover } from "../../hooks/use-hover";
|
|
10
10
|
const variants = cva("relative isolate z-tooltip flex justify-between overflow-hidden whitespace-nowrap rounded-lg border text-sm shadow-shadow-notification supports-[backdrop-filter]:backdrop-blur-xl", {
|
|
11
11
|
variants: {
|
|
12
12
|
theme: {
|
|
13
13
|
warn: "bg-warn-notification/90 text-warn-hover border-warn/50",
|
|
14
|
-
|
|
14
|
+
default: "border-card-border bg-card-background text-foreground",
|
|
15
15
|
danger: "bg-danger-notification supports-[backdrop-filter]:bg-danger-notification/60 text-danger border-danger/50",
|
|
16
16
|
success: "bg-success-notification supports-[backdrop-filter]:bg-success-notification/50 text-success border-success/50",
|
|
17
|
-
|
|
17
|
+
info: "bg-info-notification supports-[backdrop-filter]:bg-info-notification/50 supports-[backdrop-filter]:bg-info/20 text-info border-info/50",
|
|
18
18
|
},
|
|
19
19
|
},
|
|
20
20
|
defaultVariants: { theme: "default" },
|
|
@@ -34,11 +34,11 @@ const Notification = forwardRef(function Toast(props, forwardedRef) {
|
|
|
34
34
|
const duration = props.duration;
|
|
35
35
|
const variant = props.hover ? "hover" : props.isLast ? "isLast" : "other";
|
|
36
36
|
const className = variants({ theme: props.theme || "default" });
|
|
37
|
-
return (_jsx(RadixToast.Root, { ref: forwardedRef, asChild: true, forceMount: true, onOpenChange: props.onClose, duration: duration, children: _jsx(motion.li, { layout: true, layoutScroll: true, animate: variant, "data-index": props.index, initial: { y: -100, zIndex: -1 }, className: "absolute
|
|
37
|
+
return (_jsx(RadixToast.Root, { ref: forwardedRef, asChild: true, forceMount: true, onOpenChange: props.onClose, duration: duration, children: _jsx(motion.li, { layout: true, layoutScroll: true, animate: variant, "data-index": props.index, initial: { y: -100, zIndex: -1 }, className: "text-select pointer-events-auto absolute right-0 top-0 w-80", variants: {
|
|
38
38
|
isLast: { y: 10, scale: 1, animationDuration: "300ms", opacity: 1 },
|
|
39
39
|
hover: { y: 0, position: "static", scale: 1, opacity: 1 },
|
|
40
40
|
other: animatedIndex[props.reversedIndex] || animatedIndex.default,
|
|
41
|
-
}, transition: { type: "spring", mass: 1.2, damping: 30, stiffness: 200 }, exit: { opacity: [0.9, 0], transition: { opacity: { bounce: 0.25, duration: 0.3 } } }, children: _jsxs("div", { className: className, children: [_jsxs("div", { className: "flex flex-col p-4", children: [props.title ? (_jsx(RadixToast.Title, { className: "text-lg font-medium leading-relaxed
|
|
41
|
+
}, transition: { type: "spring", mass: 1.2, damping: 30, stiffness: 200 }, exit: { opacity: [0.9, 0], transition: { opacity: { bounce: 0.25, duration: 0.3 } } }, children: _jsxs("div", { className: className, children: [_jsxs("div", { className: "flex flex-col p-4", children: [props.title ? (_jsx(RadixToast.Title, { className: "select-text truncate text-lg font-medium leading-relaxed", children: props.title })) : null, _jsx(RadixToast.Description, { className: "select-text truncate", children: props.text })] }), closable ? (_jsx(RadixToast.Close, { className: "absolute right-2 top-2 rounded-full p-1 text-foreground transition hover:bg-danger/10 hover:text-danger-hover", children: _jsx(XIcon, { className: "size-5" }) })) : null] }) }) }));
|
|
42
42
|
});
|
|
43
43
|
export function Notifications({ children, max = 5, duration = 5000 }) {
|
|
44
44
|
const ref = useRef(null);
|
|
@@ -59,10 +59,10 @@ export function Notifications({ children, max = 5, duration = 5000 }) {
|
|
|
59
59
|
const close = () => setMessages((prev) => prev.filter((x) => x.id !== id));
|
|
60
60
|
return { clear, close };
|
|
61
61
|
}, [max]);
|
|
62
|
-
return (_jsxs(RadixToast.Provider, { duration: duration, swipeThreshold: 150, children: [_jsx(NotificationContext.Provider, { value: notify, children: children }), _jsx(AnimatePresence, { presenceAffectsLayout: true, mode: "popLayout", children: messages.map((toast, index, list) => {
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
62
|
+
return (_jsxs(RadixToast.Provider, { duration: duration, swipeThreshold: 150, children: [_jsx(NotificationContext.Provider, { value: notify, children: children }), _jsx(motion.ol, { children: _jsx(AnimatePresence, { presenceAffectsLayout: true, mode: "popLayout", children: messages.map((toast, index, list) => {
|
|
63
|
+
const close = () => setMessages((prev) => prev.filter((t) => t.id !== toast.id));
|
|
64
|
+
return (_createElement(Notification, { ...toast, hover: hover, index: index, key: toast.id, onClose: close, isLast: list.length - 1 === index, reversedIndex: list.length - (index + 1) }));
|
|
65
|
+
}) }) }), _jsx(RadixToast.Viewport, { ref: ref, "data-items": messages.length, style: {
|
|
66
66
|
justifyContent: "start",
|
|
67
67
|
height: `${(hover ? messages.length : Math.min(1, messages.length)) * 7}rem`,
|
|
68
68
|
}, className: "fixed right-4 top-10 flex w-80 list-none flex-col-reverse items-end gap-4 overflow-y-clip overflow-x-visible data-[items=true]:pb-8 max-sm:top-20" })] }));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"progress.d.ts","sourceRoot":"","sources":["../../../src/components/display/progress.tsx"],"names":[],"mappings":"AAGA,OAAO,EAAE,eAAe,EAAE,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"progress.d.ts","sourceRoot":"","sources":["../../../src/components/display/progress.tsx"],"names":[],"mappings":"AAGA,OAAO,EAAE,eAAe,EAAE,MAAM,OAAO,CAAC;AACxC,OAAO,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AAEpC,KAAK,aAAa,GAAG;IACnB,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,KAAK,CAAC,EAAE,KAAK,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB,CAAA;AAED,eAAO,MAAM,QAAQ,GAAI,OAAO,eAAe,CAAC,aAAa,CAAC,4CAoB7D,CAAA"}
|
|
@@ -4,6 +4,6 @@ import { Progress as RadixProgress } from "radix-ui";
|
|
|
4
4
|
import { css } from "../../lib/dom";
|
|
5
5
|
export const Progress = (props) => {
|
|
6
6
|
return (_jsxs(RadixProgress.Root, { max: props.max, value: props.percent, style: { transform: "translateZ(0)", }, className: css("overflow-hidden relative w-full rounded-full h-6 bg-background", props.container), children: [_jsx(RadixProgress.Indicator, { style: { transform: Is.number(props.percent) ? `translateX(-${100 - props.percent}%)` : undefined }, className: css("bg-primary transition-transform ease-in-out size-full duration-500", props.className) }), Is.number(props.percent)
|
|
7
|
-
?
|
|
7
|
+
? _jsx("p", { className: css("flex absolute inset-0 justify-center items-center w-full font-semibold tabular-nums text-primary-foreground", props.textClassName), children: props.label ? props.label : `${props.percent} %` })
|
|
8
8
|
: null] }));
|
|
9
9
|
};
|
|
@@ -42,7 +42,7 @@ const MenuComponent = React.forwardRef(({ children, FloatingComponent = "div", h
|
|
|
42
42
|
move: false,
|
|
43
43
|
enabled: hover,
|
|
44
44
|
delay: { open: FLOATING_DELAY },
|
|
45
|
-
handleClose: safePolygon({ blockPointerEvents: true }),
|
|
45
|
+
handleClose: safePolygon({ blockPointerEvents: true, requireIntent: false }),
|
|
46
46
|
});
|
|
47
47
|
const click = useClick(context, {
|
|
48
48
|
toggle: !isNested,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"modal.d.ts","sourceRoot":"","sources":["../../../src/components/floating/modal.tsx"],"names":[],"mappings":"AACA,OAAO,EACH,KAAK,YAAY,EASpB,MAAM,oBAAoB,CAAC;AAI5B,OAAO,EAAmB,eAAe,EAAqE,MAAM,cAAc,CAAC;AACnI,OAAO,KAAkH,MAAM,OAAO,CAAC;AAIvI,OAAO,EAAE,KAAK,EAAO,QAAQ,EAAE,MAAM,aAAa,CAAC;AAMnD,MAAM,MAAM,SAAS,GAAG,QAAQ,GAAG,QAAQ,GAAG,OAAO,CAAC;AAEtD,MAAM,MAAM,cAAc,GAAG,MAAM,GAAG,OAAO,CAAC;AAuD9C,MAAM,MAAM,UAAU,GAAG,QAAQ,CAC7B,eAAe,CAAC,KAAK,CAAC,EACtB,CAAC;IAAE,KAAK,EAAE,KAAK,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG;IAAE,SAAS,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,KAAK,CAAA;CAAE,CAAC,GAAG;IAC5E,IAAI,EAAE,OAAO,CAAC;IACd,QAAQ,EAAE,CAAC,SAAS,EAAE,OAAO,KAAK,IAAI,CAAC;CAC1C,GAAG,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"modal.d.ts","sourceRoot":"","sources":["../../../src/components/floating/modal.tsx"],"names":[],"mappings":"AACA,OAAO,EACH,KAAK,YAAY,EASpB,MAAM,oBAAoB,CAAC;AAI5B,OAAO,EAAmB,eAAe,EAAqE,MAAM,cAAc,CAAC;AACnI,OAAO,KAAkH,MAAM,OAAO,CAAC;AAIvI,OAAO,EAAE,KAAK,EAAO,QAAQ,EAAE,MAAM,aAAa,CAAC;AAMnD,MAAM,MAAM,SAAS,GAAG,QAAQ,GAAG,QAAQ,GAAG,OAAO,CAAC;AAEtD,MAAM,MAAM,cAAc,GAAG,MAAM,GAAG,OAAO,CAAC;AAuD9C,MAAM,MAAM,UAAU,GAAG,QAAQ,CAC7B,eAAe,CAAC,KAAK,CAAC,EACtB,CAAC;IAAE,KAAK,EAAE,KAAK,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG;IAAE,SAAS,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,KAAK,CAAA;CAAE,CAAC,GAAG;IAC5E,IAAI,EAAE,OAAO,CAAC;IACd,QAAQ,EAAE,CAAC,SAAS,EAAE,OAAO,KAAK,IAAI,CAAC;CAC1C,GAAG,OAAO,CAAC;IACJ,MAAM,EAAE,KAAK,CAAC;IACd,IAAI,EAAE,SAAS,CAAC;IAChB,QAAQ,EAAE,OAAO,CAAC;IAClB,OAAO,EAAE,OAAO,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,OAAO,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,OAAO,CAAC;IAClB,SAAS,EAAE,OAAO,CAAC;IACnB,aAAa,EAAE,MAAM,CAAC;IACtB,gBAAgB,EAAE,MAAM,CAAC;IACzB,QAAQ,EAAE,cAAc,CAAC;IACzB,iBAAiB,EAAE,OAAO,CAAC;IAC3B,IAAI,EAAE,QAAQ,GAAG,SAAS,CAAC;IAC3B,YAAY,EAAE,YAAY,EAAE,CAAC;IAC7B,OAAO,EAAE,KAAK,GAAG,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC;CAClC,CAAC,CACT,CAAC;AA6EF,KAAK,QAAQ,GAAG;IAAE,OAAO,EAAE,GAAG,CAAC;IAAC,QAAQ,EAAE,WAAW,GAAG,IAAI,CAAA;CAAE,CAAC;AAI/D,eAAO,MAAM,KAAK;WAtGJ,KAAK;gBAAc,MAAM;;UACzB,OAAO;cACH,CAAC,SAAS,EAAE,OAAO,KAAK,IAAI;;YAE1B,KAAK;UACP,SAAS;cACL,OAAO;aACR,OAAO;cACN,MAAM;aACP,OAAO;eACL,MAAM;cACP,OAAO;eACN,OAAO;mBACH,MAAM;sBACH,MAAM;cACd,cAAc;uBACL,OAAO;UACpB,QAAQ,GAAG,SAAS;kBACZ,YAAY,EAAE;aACnB,KAAK,GAAG,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC;;;;eAnBe,MAAM;YAAU,KAAK;;UAChE,OAAO;cACH,CAAC,SAAS,EAAE,OAAO,KAAK,IAAI;;YAE1B,KAAK;UACP,SAAS;cACL,OAAO;aACR,OAAO;cACN,MAAM;aACP,OAAO;eACL,MAAM;cACP,OAAO;eACN,OAAO;mBACH,MAAM;sBACH,MAAM;cACd,cAAc;uBACL,OAAO;UACpB,QAAQ,GAAG,SAAS;kBACZ,YAAY,EAAE;aACnB,KAAK,GAAG,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC;;;2CAoSzC,CAAC"}
|
|
@@ -30,7 +30,7 @@ const animations = {
|
|
|
30
30
|
},
|
|
31
31
|
dialog: {
|
|
32
32
|
exit: { opacity: 0, scale: 0.95, animationDuration },
|
|
33
|
-
initial: { opacity: 0.5, scale: 0.95, animationDuration, transition: { duration: 0.5, ease:
|
|
33
|
+
initial: { opacity: 0.5, scale: 0.95, animationDuration, transition: { duration: 0.5, ease: "easeInOut" } },
|
|
34
34
|
enter: { opacity: 1, scale: [1.05, 1], animationDuration },
|
|
35
35
|
},
|
|
36
36
|
};
|
|
@@ -50,7 +50,7 @@ const variants = cva("z-floating border border-card-border ring-0 outline-0 appe
|
|
|
50
50
|
defaultVariants: { position: "right", type: "dialog" },
|
|
51
51
|
});
|
|
52
52
|
const dragConstraints = { top: 0, left: 0, right: 0, bottom: 0 };
|
|
53
|
-
const calculateClose = (n) => n * 0.
|
|
53
|
+
const calculateClose = (n) => n * 0.6;
|
|
54
54
|
const Draggable = (props) => {
|
|
55
55
|
const onDrag = (_, info) => {
|
|
56
56
|
if (props.parent.current) {
|
|
@@ -65,18 +65,22 @@ const Draggable = (props) => {
|
|
|
65
65
|
const rect = div.getBoundingClientRect();
|
|
66
66
|
const v = props.value.get() || rect.height;
|
|
67
67
|
const result = Math.abs(v - info.delta.y);
|
|
68
|
-
const
|
|
68
|
+
const max = window.outerHeight;
|
|
69
|
+
const screenHeightToClose = calculateClose(max);
|
|
69
70
|
if (result >= screenHeightToClose)
|
|
70
71
|
return props.value.set(result);
|
|
72
|
+
if (document.activeElement instanceof HTMLElement) {
|
|
73
|
+
document.activeElement?.blur();
|
|
74
|
+
}
|
|
71
75
|
props.onChange(false);
|
|
72
|
-
return setTimeout(() => props.value.set(
|
|
76
|
+
return setTimeout(() => props.value.set(undefined), 350);
|
|
73
77
|
}
|
|
74
78
|
};
|
|
75
79
|
return (_jsx(motion.div, { draggable: true, dragMomentum: true, dragListener: true, dragPropagation: true, onDrag: onDrag, animate: false, initial: false, dragElastic: 0, dragDirectionLock: true, dragSnapToOrigin: true, drag: props.sheet ? "y" : "x", dragConstraints: dragConstraints, whileDrag: { cursor: "grabbing" }, className: css("absolute rounded-lg", props.sheet ? "cursor-row-resize" : "cursor-col-resize bg-floating-border", props.sheet
|
|
76
80
|
? "top-1 flex h-3 w-full justify-center py-2"
|
|
77
81
|
: props.position === "left"
|
|
78
82
|
? "right-5 top-1/2 h-10 w-2"
|
|
79
|
-
: "left-2 top-1/2 h-10 w-2"), children: props.sheet ? _jsx("div", { className: "w-1/4
|
|
83
|
+
: "left-2 top-1/2 h-10 w-2"), children: props.sheet ? _jsx("div", { className: "h-2 w-1/4 rounded-lg bg-floating-border" }) : null }));
|
|
80
84
|
};
|
|
81
85
|
const positions = { drawer: "right", sheet: "none", dialog: "none" };
|
|
82
86
|
const fetchPosition = (isDesktop, forceType, propsType, propsPosition) => {
|
|
@@ -96,12 +100,11 @@ export const Modal = forwardRef(({ open, title, footer, asChild, trigger, childr
|
|
|
96
100
|
const func = isDesktop ? animations[_type] : forceType ? animations[_type] : animations.sheet;
|
|
97
101
|
const animation = typeof func === "function" ? func(position) : func;
|
|
98
102
|
const type = isDesktop ? _type : forceType ? _type : "sheet";
|
|
99
|
-
const floating = useFloating({ open
|
|
100
|
-
const click = useClick(floating.context);
|
|
103
|
+
const floating = useFloating({ open, onOpenChange: onChange });
|
|
104
|
+
const click = useClick(floating.context, {});
|
|
101
105
|
const role = useRole(floating.context, { role: roleName });
|
|
102
106
|
const dismiss = useDismiss(floating.context, {
|
|
103
107
|
escapeKey: true,
|
|
104
|
-
referencePress: true,
|
|
105
108
|
outsidePress: overlayClickClose,
|
|
106
109
|
});
|
|
107
110
|
const interactions = useInteractions([click, role, dismiss].concat(outInteractions));
|
|
@@ -109,7 +112,7 @@ export const Modal = forwardRef(({ open, title, footer, asChild, trigger, childr
|
|
|
109
112
|
const floatingSize = useMotionValue(undefined);
|
|
110
113
|
useEffect(() => {
|
|
111
114
|
floatingSize.set(undefined);
|
|
112
|
-
}, [
|
|
115
|
+
}, [type]);
|
|
113
116
|
const onClose = () => onChange(false);
|
|
114
117
|
useImperativeHandle(externalRef, () => {
|
|
115
118
|
return { context: floating.context, floating: removeScrollRef.current };
|
|
@@ -139,10 +142,10 @@ export const Modal = forwardRef(({ open, title, footer, asChild, trigger, childr
|
|
|
139
142
|
};
|
|
140
143
|
const animationProps = animated && type === "sheet"
|
|
141
144
|
? {
|
|
145
|
+
...commonAnimated,
|
|
142
146
|
dragElastic: 0,
|
|
143
147
|
onDrag: onDrag,
|
|
144
148
|
dragConstraints,
|
|
145
|
-
...commonAnimated,
|
|
146
149
|
dragListener: true,
|
|
147
150
|
dragMomentum: true,
|
|
148
151
|
dragPropagation: true,
|
|
@@ -152,7 +155,10 @@ export const Modal = forwardRef(({ open, title, footer, asChild, trigger, childr
|
|
|
152
155
|
drag: type === "sheet" ? "y" : "x",
|
|
153
156
|
}
|
|
154
157
|
: commonAnimated;
|
|
155
|
-
|
|
158
|
+
useEffect(() => {
|
|
159
|
+
console.log({ open });
|
|
160
|
+
}, [open]);
|
|
161
|
+
return (_jsxs(Fragment, { children: [trigger ? (_jsx(Fragment, { children: asChild ? (_jsx(Slot, { ref: floating.refs.setReference, ...interactions.getReferenceProps({ layoutId: layoutId }), children: Trigger })) : (_jsx(motion.button, { ref: floating.refs.setReference, ...interactions.getReferenceProps(), layoutId: layoutId, type: "button", children: Trigger })) })) : null, _jsx(FloatingPortal, { preserveTabOrder: true, children: _jsx(AnimatePresence, { propagate: true, mode: "wait", initial: false, children: open ? (_jsx(FloatingOverlay, { lockScroll: false, className: css("inset-0 isolate z-overlay h-[100dvh] !overflow-clip bg-floating-overlay/70", type === "drawer" ? "" : "flex items-start justify-center p-10", overlayClassName), children: _jsx(FloatingFocusManager, { guards: true, visuallyHiddenDismiss: true, modal: true, closeOnFocusOut: true, context: floating.context, children: _jsxs(motion.div, { ...props, ...animationProps, ...(title
|
|
156
162
|
? {
|
|
157
163
|
"aria-labelledby": headingId,
|
|
158
164
|
"aria-describedby": descriptionId,
|
|
@@ -164,5 +170,5 @@ export const Modal = forwardRef(({ open, title, footer, asChild, trigger, childr
|
|
|
164
170
|
position,
|
|
165
171
|
type,
|
|
166
172
|
}), className, "overscroll-contain"),
|
|
167
|
-
}), "data-component": "modal", style: type === "drawer" ? { width: floatingSize } : { height: floatingSize }, children: [title ? (_jsx("header", { className: "relative w-full", children: title ? (_jsx("h2", { id: headingId, className: "px-8 pb-2 text-3xl font-medium leading-relaxed
|
|
173
|
+
}), "data-component": "modal", style: type === "drawer" ? { width: floatingSize } : { height: floatingSize }, children: [title ? (_jsx("header", { className: "relative w-full", children: title ? (_jsx("h2", { id: headingId, className: "select-text border-b border-floating-border px-8 pb-2 text-3xl font-medium leading-relaxed", children: title })) : null })) : null, _jsx("section", { "data-component": "modal-body", className: css("flex-1 select-text overflow-y-auto px-8 py-1", bodyClassName), children: children }), footer ? (_jsx("footer", { className: "w-full select-text border-t border-floating-border px-8 pt-4", children: footer })) : null, closable ? (_jsx("nav", { className: "absolute right-4 top-1 z-floating", children: _jsx("button", { type: "button", onClick: onClose, className: "p-1 opacity-70 transition-colors hover:text-danger hover:opacity-100 focus:text-danger", children: _jsx(XIcon, {}) }) })) : null, useResizer && resizer ? (_jsx(Draggable, { onChange: onChange, value: floatingSize, sheet: type === "sheet", position: position, parent: floating.refs.floating })) : null] }) }) })) : null }, headingId) })] }));
|
|
168
174
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"autocomplete.d.ts","sourceRoot":"","sources":["../../../src/components/form/autocomplete.tsx"],"names":[],"mappings":"AAgBA,OAAO,KAAoF,MAAM,OAAO,CAAC;AASzG,OAAO,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AACpC,OAAO,EAAc,eAAe,EAAE,MAAM,eAAe,CAAC;AAC5D,OAAO,EAAE,KAAK,WAAW,EAAE,MAAM,UAAU,CAAC;AAE5C,MAAM,MAAM,qBAAqB,GAAG,WAAW,GAAG;IAAE,MAAM,CAAC,EAAE,KAAK,CAAC,EAAE,CAAC,WAAW,CAAC,CAAA;CAAE,CAAC;AAErF,MAAM,MAAM,iBAAiB,GAAG,IAAI,CAAC,eAAe,CAAC,OAAO,CAAC,EAAE,OAAO,CAAC,GAAG;IACtE,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,YAAY,CAAC,EAAE,KAAK,CAAC;IACrB,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,OAAO,EAAE,qBAAqB,EAAE,CAAC;CACpC,CAAC;AAiCF,eAAO,MAAM,YAAY,
|
|
1
|
+
{"version":3,"file":"autocomplete.d.ts","sourceRoot":"","sources":["../../../src/components/form/autocomplete.tsx"],"names":[],"mappings":"AAgBA,OAAO,KAAoF,MAAM,OAAO,CAAC;AASzG,OAAO,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AACpC,OAAO,EAAc,eAAe,EAAE,MAAM,eAAe,CAAC;AAC5D,OAAO,EAAE,KAAK,WAAW,EAAE,MAAM,UAAU,CAAC;AAE5C,MAAM,MAAM,qBAAqB,GAAG,WAAW,GAAG;IAAE,MAAM,CAAC,EAAE,KAAK,CAAC,EAAE,CAAC,WAAW,CAAC,CAAA;CAAE,CAAC;AAErF,MAAM,MAAM,iBAAiB,GAAG,IAAI,CAAC,eAAe,CAAC,OAAO,CAAC,EAAE,OAAO,CAAC,GAAG;IACtE,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,YAAY,CAAC,EAAE,KAAK,CAAC;IACrB,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,OAAO,EAAE,qBAAqB,EAAE,CAAC;CACpC,CAAC;AAiCF,eAAO,MAAM,YAAY,yGAoWxB,CAAC"}
|
|
@@ -22,13 +22,13 @@ const transitionStyles = {
|
|
|
22
22
|
};
|
|
23
23
|
const emptyRef = [];
|
|
24
24
|
const List = forwardRef(function VirtualList(props, ref) {
|
|
25
|
-
return (_jsx(motion.ul, { ...props, ref: ref, className: "w-full overscroll-contain rounded-lg
|
|
25
|
+
return (_jsx(motion.ul, { ...props, ref: ref, className: "w-full overscroll-contain rounded-lg", children: _jsx(AnimatePresence, { children: props.children }) }));
|
|
26
26
|
});
|
|
27
27
|
const Item = forwardRef(function VirtualItem({ item, context, ...props }, ref) {
|
|
28
28
|
return _jsx(motion.li, { ...props, ref: ref, className: "first:rounded-t-lg last:rounded-t-lg" });
|
|
29
29
|
});
|
|
30
30
|
const components = { List, Item };
|
|
31
|
-
const MIN_SIZE =
|
|
31
|
+
const MIN_SIZE = 44;
|
|
32
32
|
export const Autocomplete = forwardRef(({ left, error, right, loading, options, container, rightLabel, interactive, emptyMessage, optionalText, labelClassName, feedback = null, hideLeft = false, required = false, dynamicOption = false, ...props }, externalRef) => {
|
|
33
33
|
const scroller = useRef(null);
|
|
34
34
|
const fieldset = useRef(null);
|
|
@@ -171,15 +171,16 @@ export const Autocomplete = forwardRef(({ left, error, right, loading, options,
|
|
|
171
171
|
setClosed();
|
|
172
172
|
};
|
|
173
173
|
const id = props.id || props.name;
|
|
174
|
+
const shadowId = `${id}-shadow`;
|
|
174
175
|
const isEmpty = displayList.length === 0;
|
|
175
|
-
return (_jsxs(InputField, { ...props, left: left, error: error, ref: fieldset, form: props.form, loading: loading, name: props.name, feedback: feedback, hideLeft: hideLeft, required: required, title: props.title, container: container, rightLabel: rightLabel, interactive: interactive, id:
|
|
176
|
+
return (_jsxs(InputField, { ...props, left: left, error: error, ref: fieldset, form: props.form, loading: loading, name: props.name, feedback: feedback, hideLeft: hideLeft, required: required, title: props.title, container: container, rightLabel: rightLabel, interactive: interactive, id: shadowId, optionalText: optionalText, componentName: "autocomplete", labelClassName: labelClassName, placeholder: props.placeholder, right: _jsxs("span", { className: "flex items-center gap-0.5", children: [right, _jsxs("button", { type: "button", className: "p-2 transition-colors link:text-primary md:p-1", onClick: onCaretDownClick, children: [_jsx(ChevronDown, { size: 20 }), _jsx("span", { className: "sr-only", children: translation.inputCaretDown })] }), value ? (_jsx("button", { type: "button", onClick: onClose, className: "p-2 transition-colors link:text-danger md:p-1", children: _jsx("svg", { width: "15", height: "15", viewBox: "0 0 15 15", fill: "none", xmlns: "http://www.w3.org/2000/svg", children: _jsx("path", { d: "M11.7816 4.03157C12.0062 3.80702 12.0062 3.44295 11.7816 3.2184C11.5571 2.99385 11.193 2.99385 10.9685 3.2184L7.50005 6.68682L4.03164 3.2184C3.80708 2.99385 3.44301 2.99385 3.21846 3.2184C2.99391 3.44295 2.99391 3.80702 3.21846 4.03157L6.68688 7.49999L3.21846 10.9684C2.99391 11.193 2.99391 11.557 3.21846 11.7816C3.44301 12.0061 3.80708 12.0061 4.03164 11.7816L7.50005 8.31316L10.9685 11.7816C11.193 12.0061 11.5571 12.0061 11.7816 11.7816C12.0062 11.557 12.0062 11.193 11.7816 10.9684L8.31322 7.49999L11.7816 4.03157Z", fill: "currentColor", fillRule: "evenodd", clipRule: "evenodd" }) }) })) : null] }), children: [_jsx("input", { "data-shadow": "true", ...getReferenceProps({
|
|
176
177
|
...props,
|
|
177
|
-
onChange,
|
|
178
178
|
onFocus,
|
|
179
179
|
pattern,
|
|
180
|
+
onChange,
|
|
181
|
+
id: shadowId,
|
|
182
|
+
name: shadowId,
|
|
180
183
|
ref: refs.setReference,
|
|
181
|
-
name: `${id}-shadow`,
|
|
182
|
-
id: `${id}-shadow`,
|
|
183
184
|
onClick: (e) => e.currentTarget.focus(),
|
|
184
185
|
onKeyDown(event) {
|
|
185
186
|
if (event.key === "Escape") {
|
|
@@ -222,8 +223,8 @@ export const Autocomplete = forwardRef(({ left, error, right, loading, options,
|
|
|
222
223
|
const ul = refs.floating.current;
|
|
223
224
|
const li = ul.querySelectorAll("li").item(0);
|
|
224
225
|
const sum = (li ? li.getBoundingClientRect().height : MIN_SIZE) * displayList.length;
|
|
225
|
-
return flushSync(() => setH(sum +
|
|
226
|
-
}, children: [isEmpty ? (_jsx("div", { role: "option", className: "w-full border-b border-tooltip-border
|
|
226
|
+
return flushSync(() => setH(sum + 10));
|
|
227
|
+
}, children: [isEmpty ? (_jsx("div", { role: "option", className: "w-full border-b border-tooltip-border", children: _jsx("span", { className: "flex w-full justify-between p-2 text-left text-disabled", children: emptyMessage || translation.autocompleteEmpty }) })) : null, _jsx(Virtuoso, { overscan: 40, ref: virtuoso, hidden: isEmpty, data: displayList, style: { height: h - 10 }, defaultItemHeight: MIN_SIZE, components: components, scrollerRef: (e) => void (scroller.current = e), className: "max-h-[calc(100%-2px)] overscroll-contain rounded-lg border-floating bg-floating-background p-0 text-foreground", itemContent: (i, option) => {
|
|
227
228
|
const Label = option.Render ?? Frag;
|
|
228
229
|
const active = value === option.value || value === option.label;
|
|
229
230
|
const selected = index === i;
|
|
@@ -48,16 +48,16 @@ const ItemViewer = (props) => {
|
|
|
48
48
|
props.onDeleteFile?.(props.file);
|
|
49
49
|
};
|
|
50
50
|
const Icon = extensionMap[props.file.name.split(".").at(-1)] ?? FileIcon;
|
|
51
|
-
const Element = info.type === "img" ? (_jsx("img", { src: info.url, className: "
|
|
52
|
-
return (_jsxs("li", { className: "flex
|
|
51
|
+
const Element = info.type === "img" ? (_jsx("img", { src: info.url, className: "object-contain w-full", alt: props.file.name })) : (_jsx(Icon, { strokeWidth: 2, absoluteStrokeWidth: true, size: 48 }));
|
|
52
|
+
return (_jsxs("li", { className: "flex flex-row gap-4 justify-between w-full border-b border-card-border last:border-b-transparent", children: [_jsxs("div", { className: "flex flex-col gap-4", children: [_jsxs("div", { className: "flex flex-row gap-4 items-center", children: [_jsx("button", { type: "button", onClick: onViewFile, className: "flex overflow-hidden justify-center items-center max-w-16 m-2 size-16", children: Element }), _jsxs("div", { className: "flex flex-col justify-start items-start text-left", children: [_jsx("span", { children: props.file.name }), _jsx("span", { className: "text-sm italic", children: info.size })] })] }), props.File ? (_jsx("div", { className: "flex-1 min-w-full", children: _jsx(props.File, { file: props.file }) })) : null] }), _jsx("div", { className: "flex justify-start py-4 transition-colors duration-300 ease-linear align-start hover:text-danger-hover", children: _jsx("button", { onClick: onDeleteFile, type: "button", className: "flex justify-center items-center size-6", children: _jsx(XIcon, { size: 16 }) }) })] }));
|
|
53
53
|
};
|
|
54
|
-
const FilesList = (props) => (_jsx("ul", { className: "
|
|
54
|
+
const FilesList = (props) => (_jsx("ul", { className: "space-y-8 w-full", children: props.files.map((file) => {
|
|
55
55
|
return _jsx(ItemViewer, { File: props.File, onDeleteFile: props.onDeleteFile, file: file }, file.name);
|
|
56
56
|
}) }));
|
|
57
57
|
const Idle = (props) => {
|
|
58
58
|
const t = useTranslations();
|
|
59
59
|
const Icon = props.dragging ? FolderOpenIcon : FolderIcon;
|
|
60
|
-
return (_jsxs("div", { className: "flex flex-col
|
|
60
|
+
return (_jsxs("div", { className: "flex flex-col justify-center items-center", children: [_jsx("div", { className: "flex flex-col gap-2 justify-center items-center", children: _jsx(Icon, { className: "text-primary", size: 80 }) }), _jsxs("div", { className: "flex flex-col gap-1 items-center my-4", children: [_jsx("p", { children: t.uploadIdle }), _jsx("button", { className: "underline text-primary", type: "button", children: t.uploadIdleButton })] })] }));
|
|
61
61
|
};
|
|
62
62
|
const InteractiveArea = (props) => {
|
|
63
63
|
if (props.isDragActive)
|
|
@@ -71,7 +71,7 @@ const DefaultIdle = _jsx(Idle, { dragging: false });
|
|
|
71
71
|
const FileViewer = (props) => {
|
|
72
72
|
const file = props.item.file;
|
|
73
73
|
const type = props.item.type;
|
|
74
|
-
return (_jsxs("div", { className: "flex flex-col gap-4", children: [_jsx("p", { className: "text-lg font-medium", children: props.item.file.name }), _jsx("p", { className: "text-base", children: props.item.size }), type === "img" ? (_jsx("img", { className: "container block w-full max-w-96", src: props.item.url, alt: file.name })) : type === "video" ? (_jsx("video", { className: "container block w-full max-w-96", src: props.item.url, controls: true, muted: true })) : type === "audio" ? (_jsx("figure", { children: _jsx("audio", { controls: true, src: props.item.url }) })) : null] }));
|
|
74
|
+
return (_jsxs("div", { className: "flex flex-col gap-4", children: [_jsx("p", { className: "text-lg font-medium", children: props.item.file.name }), _jsx("p", { className: "text-base", children: props.item.size }), type === "img" ? (_jsx("img", { className: "container inline-block w-full max-w-96", src: props.item.url, alt: file.name })) : type === "video" ? (_jsx("video", { className: "container block w-full max-w-96", src: props.item.url, controls: true, muted: true })) : type === "audio" ? (_jsx("figure", { children: _jsx("audio", { controls: true, src: props.item.url }) })) : null] }));
|
|
75
75
|
};
|
|
76
76
|
export const FileUpload = ({ idle = DefaultIdle, onDeleteFile, File, onDrop, ...props }) => {
|
|
77
77
|
const t = useTranslations();
|
|
@@ -6,7 +6,7 @@ import { useTranslations } from "../../hooks/use-translations";
|
|
|
6
6
|
import { useTweaks } from "../../hooks/use-tweaks";
|
|
7
7
|
import { css } from "../../lib/dom";
|
|
8
8
|
import { Tooltip } from "../floating/tooltip";
|
|
9
|
-
export const InputFeedback = ({ reportStatus, id, hideLeft = false, className, info, children, title }) => (_jsxs("span", { className: css("w-full justify-between", hideLeft && children === null ? "hidden" : "flex", className), children: [hideLeft ? null : (_jsxs("span", { className: "flex items-center gap-1 transition-colors group-focus-within:text-primary group-hover:text-primary group-disabled:text-disabled group-error:text-danger", children: [title, reportStatus || info ? (_jsxs("span", { className: "flex items-center justify-center gap-1", children: [info ? (_jsx(Tooltip, { as: "button", type: "button", "aria-
|
|
9
|
+
export const InputFeedback = ({ reportStatus, id, hideLeft = false, className, info, children, title }) => (_jsxs("span", { className: css("w-full justify-between", hideLeft && children === null ? "hidden" : "flex", className), children: [hideLeft ? null : (_jsxs("span", { className: "flex items-center gap-1 transition-colors group-focus-within:text-primary group-hover:text-primary group-disabled:text-disabled group-error:text-danger", children: [title, reportStatus || info ? (_jsxs("span", { className: "flex items-center justify-center gap-1", children: [info ? (_jsx(Tooltip, { as: "button", type: "button", "aria-label": typeof info === "string" ? info : undefined, "aria-describedby": typeof info === "string" ? undefined : id ? `tooltip-info-content-${id}` : undefined, title: _jsx("span", { className: "cursor-help", children: _jsx(InfoIcon, { className: "aspect-square size-3", "aria-hidden": "true", size: 16, strokeWidth: 1, absoluteStrokeWidth: true }) }), children: _jsx("div", { id: id ? `tooltip-info-content-${id}` : undefined, className: "w-full max-w-48 whitespace-break-spaces break-words", children: info }) })) : null, reportStatus ? (_jsxs("span", { className: "flex h-3 min-w-6 items-center", children: [_jsx(CheckCircle, { className: "hidden aspect-square size-3 opacity-0 transition-opacity group-assert:block group-assert:text-success group-assert:opacity-100", "aria-hidden": "true", size: 16, strokeWidth: 1, absoluteStrokeWidth: true }), _jsx(XCircle, { className: "hidden aspect-square size-3 opacity-0 transition-opacity group-error:block group-error:opacity-100", "aria-hidden": "true", size: 16, strokeWidth: 1, absoluteStrokeWidth: true })] })) : null] })) : null] })), children] }));
|
|
10
10
|
export const InputField = forwardRef(({ optionalText: _optionalText, left, rightLabel, container, feedback, interactive, right, info, children, error, form, id, labelClassName = "", name, title, componentName, placeholder, hideLeft = false, required, disabled, reportStatus, }, ref) => {
|
|
11
11
|
const tweaks = useTweaks();
|
|
12
12
|
const reportStatusDefault = reportStatus !== undefined ? reportStatus : tweaks.input.iconFeedback;
|
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
import { AllMasks, CurrencyCode, CurrencyInputProps, CurrencyMaskTypes, Locales, PercentInputMask, PercentInputProps, TheMaskProps } from "the-mask-input";
|
|
2
2
|
import { FreeTextProps } from "./free-text";
|
|
3
3
|
export type * from "the-mask-input";
|
|
4
|
+
/**
|
|
5
|
+
* Props for the Input component, extending FreeTextProps with mask functionality
|
|
6
|
+
* Supports currency, percentage, and custom mask patterns
|
|
7
|
+
*/
|
|
4
8
|
export type InputProps = FreeTextProps<"input", ({
|
|
5
9
|
mask?: CurrencyMaskTypes;
|
|
6
10
|
locale?: Locales;
|
|
@@ -14,5 +18,35 @@ export type InputProps = FreeTextProps<"input", ({
|
|
|
14
18
|
locale?: undefined;
|
|
15
19
|
currency?: undefined;
|
|
16
20
|
} & TheMaskProps)>;
|
|
21
|
+
/**
|
|
22
|
+
* A text input component with advanced masking capabilities.
|
|
23
|
+
*
|
|
24
|
+
* Supports various input masks including:
|
|
25
|
+
* - Currency formatting with locale support
|
|
26
|
+
* - Percentage inputs
|
|
27
|
+
* - Custom regex patterns
|
|
28
|
+
* - Phone numbers, dates, and other formatted inputs
|
|
29
|
+
*
|
|
30
|
+
* @example
|
|
31
|
+
* ```tsx
|
|
32
|
+
* // Basic input
|
|
33
|
+
* <Input placeholder="Enter text..." />
|
|
34
|
+
*
|
|
35
|
+
* // Phone number mask
|
|
36
|
+
* <Input mask="(99) 99999-9999" placeholder="Phone" />
|
|
37
|
+
*
|
|
38
|
+
* // Currency input
|
|
39
|
+
* <Input mask="currency" currency="USD" locale="en-US" />
|
|
40
|
+
*
|
|
41
|
+
* // Percentage input
|
|
42
|
+
* <Input mask="percentage" />
|
|
43
|
+
*
|
|
44
|
+
* // Custom mask
|
|
45
|
+
* <Input mask={["999.999.999-99"]} placeholder="CPF" />
|
|
46
|
+
* ```
|
|
47
|
+
*
|
|
48
|
+
* @param props - Input props including mask, validation, and styling options
|
|
49
|
+
* @returns A masked input component with form integration
|
|
50
|
+
*/
|
|
17
51
|
export declare const Input: import("../..").ReactComponent<FreeTextProps<"input", InputProps>>;
|
|
18
52
|
//# sourceMappingURL=input.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"input.d.ts","sourceRoot":"","sources":["../../../src/components/form/input.tsx"],"names":[],"mappings":"AACA,OAAkB,EACd,QAAQ,EACR,YAAY,EACZ,kBAAkB,EAClB,iBAAiB,EACjB,OAAO,EACP,gBAAgB,EAChB,iBAAiB,EACjB,YAAY,EACf,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAkB,aAAa,EAAE,MAAM,aAAa,CAAC;AAE5D,mBAAmB,gBAAgB,CAAC;AAEpC,MAAM,MAAM,UAAU,GAAG,aAAa,CAClC,OAAO,EACL,CAAC;IACG,IAAI,CAAC,EAAE,iBAAiB,CAAC;IACzB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,QAAQ,CAAC,EAAE,YAAY,GAAG,SAAS,CAAC;CACvC,GAAG,kBAAkB,CAAC,GACvB,CAAC;IACG,IAAI,CAAC,EAAE,gBAAgB,CAAC;IACxB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,QAAQ,CAAC,EAAE,SAAS,CAAC;CACxB,GAAG,iBAAiB,CAAC,GACtB,CAAC;IACG,IAAI,CAAC,EAAE,QAAQ,GAAG,KAAK,CAAC,MAAM,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,MAAM,KAAK,KAAK,CAAC,MAAM,GAAG,MAAM,CAAC,GAAG,QAAQ,CAAC,CAAC;IAC9F,MAAM,CAAC,EAAE,SAAS,CAAC;IACnB,QAAQ,CAAC,EAAE,SAAS,CAAC;CACxB,GAAG,YAAY,CAAC,CACtB,CAAC;AAEF,eAAO,MAAM,KAAK,oEAEhB,CAAC"}
|
|
1
|
+
{"version":3,"file":"input.d.ts","sourceRoot":"","sources":["../../../src/components/form/input.tsx"],"names":[],"mappings":"AACA,OAAkB,EACd,QAAQ,EACR,YAAY,EACZ,kBAAkB,EAClB,iBAAiB,EACjB,OAAO,EACP,gBAAgB,EAChB,iBAAiB,EACjB,YAAY,EACf,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAkB,aAAa,EAAE,MAAM,aAAa,CAAC;AAE5D,mBAAmB,gBAAgB,CAAC;AAEpC;;;GAGG;AACH,MAAM,MAAM,UAAU,GAAG,aAAa,CAClC,OAAO,EACL,CAAC;IACG,IAAI,CAAC,EAAE,iBAAiB,CAAC;IACzB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,QAAQ,CAAC,EAAE,YAAY,GAAG,SAAS,CAAC;CACvC,GAAG,kBAAkB,CAAC,GACvB,CAAC;IACG,IAAI,CAAC,EAAE,gBAAgB,CAAC;IACxB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,QAAQ,CAAC,EAAE,SAAS,CAAC;CACxB,GAAG,iBAAiB,CAAC,GACtB,CAAC;IACG,IAAI,CAAC,EAAE,QAAQ,GAAG,KAAK,CAAC,MAAM,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,MAAM,KAAK,KAAK,CAAC,MAAM,GAAG,MAAM,CAAC,GAAG,QAAQ,CAAC,CAAC;IAC9F,MAAM,CAAC,EAAE,SAAS,CAAC;IACnB,QAAQ,CAAC,EAAE,SAAS,CAAC;CACxB,GAAG,YAAY,CAAC,CACtB,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,eAAO,MAAM,KAAK,oEAEhB,CAAC"}
|
|
@@ -1,6 +1,36 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import MaskInput from "the-mask-input";
|
|
3
3
|
import { createFreeText } from "./free-text";
|
|
4
|
+
/**
|
|
5
|
+
* A text input component with advanced masking capabilities.
|
|
6
|
+
*
|
|
7
|
+
* Supports various input masks including:
|
|
8
|
+
* - Currency formatting with locale support
|
|
9
|
+
* - Percentage inputs
|
|
10
|
+
* - Custom regex patterns
|
|
11
|
+
* - Phone numbers, dates, and other formatted inputs
|
|
12
|
+
*
|
|
13
|
+
* @example
|
|
14
|
+
* ```tsx
|
|
15
|
+
* // Basic input
|
|
16
|
+
* <Input placeholder="Enter text..." />
|
|
17
|
+
*
|
|
18
|
+
* // Phone number mask
|
|
19
|
+
* <Input mask="(99) 99999-9999" placeholder="Phone" />
|
|
20
|
+
*
|
|
21
|
+
* // Currency input
|
|
22
|
+
* <Input mask="currency" currency="USD" locale="en-US" />
|
|
23
|
+
*
|
|
24
|
+
* // Percentage input
|
|
25
|
+
* <Input mask="percentage" />
|
|
26
|
+
*
|
|
27
|
+
* // Custom mask
|
|
28
|
+
* <Input mask={["999.999.999-99"]} placeholder="CPF" />
|
|
29
|
+
* ```
|
|
30
|
+
*
|
|
31
|
+
* @param props - Input props including mask, validation, and styling options
|
|
32
|
+
* @returns A masked input component with form integration
|
|
33
|
+
*/
|
|
4
34
|
export const Input = createFreeText(MaskInput, "input", {
|
|
5
35
|
type: "text",
|
|
6
36
|
});
|
package/dist/hooks/use-form.d.ts
CHANGED
|
@@ -3,6 +3,11 @@ import { type AllPaths } from "sidekicker";
|
|
|
3
3
|
import { z } from "zod";
|
|
4
4
|
import { AutocompleteProps, CheckboxProps, DatePickerProps, InputProps, MultiSelectProps, SelectProps, SwitchProps, TextareaProps } from "../components";
|
|
5
5
|
import { Any, SetState } from "../types";
|
|
6
|
+
/**
|
|
7
|
+
* Converts a form element to a JSON object
|
|
8
|
+
* @param form - The HTML form element to convert
|
|
9
|
+
* @returns A JSON object representing the form data
|
|
10
|
+
*/
|
|
6
11
|
export declare const formToJson: (form: HTMLFormElement) => any;
|
|
7
12
|
export declare const getSchemaShape: <T extends z.ZodObject<any>>(name: string, schema: T) => T;
|
|
8
13
|
type CustomOnInvalid = (args: {
|
|
@@ -34,7 +39,48 @@ export type UseFormOptions<T> = Partial<{
|
|
|
34
39
|
interceptor: Interceptor<T>;
|
|
35
40
|
state: T | Partial<T> | (() => T | Partial<T>);
|
|
36
41
|
}>;
|
|
42
|
+
/**
|
|
43
|
+
* Creates a form storage interceptor for persisting form state
|
|
44
|
+
* @param name - The unique name for the form storage
|
|
45
|
+
* @returns An interceptor object with get, set, and clear methods
|
|
46
|
+
*/
|
|
37
47
|
export declare const createFormStorage: (name: string) => Interceptor<any>;
|
|
48
|
+
/**
|
|
49
|
+
* A comprehensive form management hook with Zod schema validation.
|
|
50
|
+
*
|
|
51
|
+
* Provides form state management, validation, and component binding for React forms.
|
|
52
|
+
* Supports automatic validation, error handling, and form persistence.
|
|
53
|
+
*
|
|
54
|
+
* @example
|
|
55
|
+
* ```tsx
|
|
56
|
+
* const schema = z.object({
|
|
57
|
+
* name: z.string().min(1, "Name is required"),
|
|
58
|
+
* email: z.string().email("Invalid email"),
|
|
59
|
+
* age: z.number().min(18, "Must be 18 or older")
|
|
60
|
+
* });
|
|
61
|
+
*
|
|
62
|
+
* const MyForm = () => {
|
|
63
|
+
* const form = useForm(schema, "user-form");
|
|
64
|
+
*
|
|
65
|
+
* return (
|
|
66
|
+
* <form {...form.controller()} onSubmit={form.onSubmit((e, { data }) => {
|
|
67
|
+
* console.log("Form data:", data);
|
|
68
|
+
* })}>
|
|
69
|
+
* <Input {...form.input("name")} placeholder="Name" />
|
|
70
|
+
* <Input {...form.input("email")} type="email" placeholder="Email" />
|
|
71
|
+
* <Input {...form.input("age")} type="number" placeholder="Age" />
|
|
72
|
+
* <Button type="submit">Submit</Button>
|
|
73
|
+
* </form>
|
|
74
|
+
* );
|
|
75
|
+
* };
|
|
76
|
+
* ```
|
|
77
|
+
*
|
|
78
|
+
* @template T - The Zod schema type
|
|
79
|
+
* @param schema - Zod schema for form validation
|
|
80
|
+
* @param formName - Unique identifier for the form
|
|
81
|
+
* @param opts - Optional configuration including initial state and interceptors
|
|
82
|
+
* @returns Form management object with input helpers and handlers
|
|
83
|
+
*/
|
|
38
84
|
export declare const useForm: <T extends z.ZodObject<any>>(schema: T, formName: string, opts?: UseFormOptions<z.infer<T>>) => {
|
|
39
85
|
get: (p: AllPaths<z.TypeOf<T>>) => Any | "";
|
|
40
86
|
input: <Props extends InputProps>(name: AllPaths<z.TypeOf<T>>, props?: Props) => Props;
|