@flikk/ui 1.0.0-beta.20 → 1.0.0-beta.21
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/Tooltip/Tooltip.theme.js +1 -1
- package/dist/components/effects/Animated/Animated.animations.js +29 -10
- package/dist/components/effects/Animated/Animated.d.ts +2 -2
- package/dist/components/effects/Animated/Animated.js +4 -3
- package/dist/components/effects/Animated/AnimatedItem.d.ts +1 -1
- package/dist/components/effects/Animated/AnimatedItem.js +5 -4
- package/dist/components/forms/Checkbox/Checkbox.theme.js +0 -4
- package/dist/components/forms/Radio/Radio.animations.js +6 -2
- package/dist/components/forms/Radio/Radio.js +1 -1
- package/dist/components/forms/Radio/Radio.theme.js +8 -8
- package/dist/components/forms/Radio/Radio.types.d.ts +1 -0
- package/dist/styles.css +1 -1
- package/package.json +1 -1
- package/src/styles/theme.css +1 -1
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
const tooltipTheme = {
|
|
2
2
|
// Base style for the tooltip - using fixed positioning for portal rendering
|
|
3
|
-
baseStyle: "fixed z-[99] rounded-[var(--tooltip-radius)] py-1 px-2 text-sm text-[var(--color-text-primary)] focus:outline-none focus-visible:ring-2 focus-visible:ring-[var(--color-primary)] focus-visible:ring-offset-2 pointer-events-none bg-white/90 backdrop-blur-md outline outline-[var(--color-border)] shadow-lg
|
|
3
|
+
baseStyle: "fixed z-[99] rounded-[var(--tooltip-radius)] py-1 px-2 text-sm text-[var(--color-text-primary)] focus:outline-none focus-visible:ring-2 focus-visible:ring-[var(--color-primary)] focus-visible:ring-offset-2 pointer-events-none bg-white/90 backdrop-blur-md outline outline-[var(--color-border)] shadow-lg " +
|
|
4
4
|
"dark:bg-[var(--color-neutral-800)]/90 dark:outline-[var(--color-border)]/80 dark:border-[var(--color-border)]",
|
|
5
5
|
};
|
|
6
6
|
|
|
@@ -12,17 +12,36 @@ const ANIMATION_PRESETS = {
|
|
|
12
12
|
slideLeft: { opacity: 0, x: -24 },
|
|
13
13
|
slideRight: { opacity: 0, x: 24 },
|
|
14
14
|
};
|
|
15
|
+
const RESOLVED_VALUES = {
|
|
16
|
+
opacity: 1,
|
|
17
|
+
y: 0,
|
|
18
|
+
x: 0,
|
|
19
|
+
scale: 1,
|
|
20
|
+
};
|
|
21
|
+
// Pre-compute visible states per preset (only keys that the preset actually animates)
|
|
22
|
+
const VISIBLE_STATES = Object.fromEntries(Object.entries(ANIMATION_PRESETS).map(([key, initial]) => {
|
|
23
|
+
const visible = {};
|
|
24
|
+
for (const k of Object.keys(initial)) {
|
|
25
|
+
visible[k] = RESOLVED_VALUES[k];
|
|
26
|
+
}
|
|
27
|
+
return [key, visible];
|
|
28
|
+
}));
|
|
29
|
+
// Pre-compute exit variants (same as hidden states)
|
|
30
|
+
const EXIT_VARIANTS = Object.fromEntries(Object.entries(ANIMATION_PRESETS).map(([key, value]) => [key, { ...value }]));
|
|
31
|
+
// Pre-compute full variant sets for default transition (zero-allocation fast path)
|
|
32
|
+
const DEFAULT_VARIANTS = Object.fromEntries(Object.entries(ANIMATION_PRESETS).map(([key, initial]) => [
|
|
33
|
+
key,
|
|
34
|
+
{
|
|
35
|
+
hidden: { ...initial },
|
|
36
|
+
visible: { ...VISIBLE_STATES[key], transition: defaultSpringTransition },
|
|
37
|
+
},
|
|
38
|
+
]));
|
|
15
39
|
function getAnimationVariants(preset, customTransition) {
|
|
16
|
-
|
|
40
|
+
if (!customTransition)
|
|
41
|
+
return DEFAULT_VARIANTS[preset];
|
|
17
42
|
return {
|
|
18
|
-
hidden: { ...
|
|
19
|
-
visible: {
|
|
20
|
-
opacity: 1,
|
|
21
|
-
y: 0,
|
|
22
|
-
x: 0,
|
|
23
|
-
scale: 1,
|
|
24
|
-
transition: customTransition !== null && customTransition !== void 0 ? customTransition : defaultSpringTransition,
|
|
25
|
-
},
|
|
43
|
+
hidden: { ...ANIMATION_PRESETS[preset] },
|
|
44
|
+
visible: { ...VISIBLE_STATES[preset], transition: customTransition },
|
|
26
45
|
};
|
|
27
46
|
}
|
|
28
47
|
function getGroupVariants(stagger, delay) {
|
|
@@ -43,7 +62,7 @@ function getGroupVariants(stagger, delay) {
|
|
|
43
62
|
};
|
|
44
63
|
}
|
|
45
64
|
function getExitVariant(preset) {
|
|
46
|
-
return
|
|
65
|
+
return EXIT_VARIANTS[preset];
|
|
47
66
|
}
|
|
48
67
|
|
|
49
68
|
export { ANIMATION_PRESETS, defaultSpringTransition, getAnimationVariants, getExitVariant, getGroupVariants };
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { AnimatedContextValue, AnimatedGroupProps } from './Animated.types';
|
|
2
2
|
export declare const useAnimatedContext: () => AnimatedContextValue | undefined;
|
|
3
3
|
export declare const Animated: {
|
|
4
|
-
Group: ({ stagger, delay, as, children, className, ...props }: AnimatedGroupProps) => import("react/jsx-runtime").JSX.Element;
|
|
5
|
-
Item: ({ animation, transition, as, delay, className, children, ...props }: import("./Animated.types").AnimatedItemProps) => import("react/jsx-runtime").JSX.Element;
|
|
4
|
+
Group: ({ stagger, delay, as, children, className, style, ...props }: AnimatedGroupProps) => import("react/jsx-runtime").JSX.Element;
|
|
5
|
+
Item: ({ animation, transition, as, delay, className, children, style, ...props }: import("./Animated.types").AnimatedItemProps) => import("react/jsx-runtime").JSX.Element;
|
|
6
6
|
};
|
|
@@ -9,14 +9,14 @@ const AnimatedContext = createContext(undefined);
|
|
|
9
9
|
const useAnimatedContext = () => {
|
|
10
10
|
return useContext(AnimatedContext);
|
|
11
11
|
};
|
|
12
|
-
const AnimatedGroup = ({ stagger = 0.1, delay = 0, as = 'div', children, className, ...props }) => {
|
|
12
|
+
const AnimatedGroup = ({ stagger = 0.1, delay = 0, as = 'div', children, className, style, ...props }) => {
|
|
13
13
|
const shouldReduceMotion = useReducedMotion();
|
|
14
|
+
const groupVariants = useMemo(() => getGroupVariants(stagger, delay), [stagger, delay]);
|
|
15
|
+
const MotionComponent = useMemo(() => motion[as], [as]);
|
|
14
16
|
if (shouldReduceMotion) {
|
|
15
17
|
const Tag = as;
|
|
16
18
|
return (jsx(Tag, { className: className, ...props, children: children }));
|
|
17
19
|
}
|
|
18
|
-
const groupVariants = useMemo(() => getGroupVariants(stagger, delay), [stagger, delay]);
|
|
19
|
-
const MotionComponent = motion[as];
|
|
20
20
|
const motionProps = {
|
|
21
21
|
initial: 'hidden',
|
|
22
22
|
animate: 'visible',
|
|
@@ -24,6 +24,7 @@ const AnimatedGroup = ({ stagger = 0.1, delay = 0, as = 'div', children, classNa
|
|
|
24
24
|
variants: groupVariants,
|
|
25
25
|
className: cn(className),
|
|
26
26
|
...props,
|
|
27
|
+
style: { willChange: 'transform, opacity', ...style },
|
|
27
28
|
};
|
|
28
29
|
return (jsx(AnimatedContext.Provider, { value: { isInsideGroup: true, stagger, delay }, children: jsx(AnimatePresence, { children: jsx(MotionComponent, { ...motionProps, children: children }) }) }));
|
|
29
30
|
};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import type { AnimatedItemProps } from './Animated.types';
|
|
2
|
-
export declare const AnimatedItem: ({ animation, transition, as, delay, className, children, ...props }: AnimatedItemProps) => import("react/jsx-runtime").JSX.Element;
|
|
2
|
+
export declare const AnimatedItem: ({ animation, transition, as, delay, className, children, style, ...props }: AnimatedItemProps) => import("react/jsx-runtime").JSX.Element;
|
|
@@ -5,20 +5,22 @@ import { cn } from '../../../utils/cn.js';
|
|
|
5
5
|
import { useAnimatedContext } from './Animated.js';
|
|
6
6
|
import { getAnimationVariants, getExitVariant } from './Animated.animations.js';
|
|
7
7
|
|
|
8
|
-
const AnimatedItem = ({ animation = 'fadeUp', transition, as = 'div', delay, className, children, ...props }) => {
|
|
8
|
+
const AnimatedItem = ({ animation = 'fadeUp', transition, as = 'div', delay, className, children, style, ...props }) => {
|
|
9
9
|
const shouldReduceMotion = useReducedMotion();
|
|
10
10
|
const groupContext = useAnimatedContext();
|
|
11
|
+
const variants = useMemo(() => getAnimationVariants(animation, transition), [animation, transition]);
|
|
12
|
+
const exitState = useMemo(() => getExitVariant(animation), [animation]);
|
|
13
|
+
const MotionComponent = useMemo(() => motion[as], [as]);
|
|
11
14
|
if (shouldReduceMotion) {
|
|
12
15
|
const Tag = as;
|
|
13
16
|
return (jsx(Tag, { className: className, ...props, children: children }));
|
|
14
17
|
}
|
|
15
|
-
const variants = useMemo(() => getAnimationVariants(animation, transition), [animation, transition]);
|
|
16
|
-
const exitState = useMemo(() => getExitVariant(animation), [animation]);
|
|
17
18
|
const motionProps = {
|
|
18
19
|
variants,
|
|
19
20
|
exit: exitState,
|
|
20
21
|
className: cn(className),
|
|
21
22
|
...props,
|
|
23
|
+
style: { willChange: 'transform, opacity', ...style },
|
|
22
24
|
};
|
|
23
25
|
if (!groupContext) {
|
|
24
26
|
motionProps.initial = 'hidden';
|
|
@@ -32,7 +34,6 @@ const AnimatedItem = ({ animation = 'fadeUp', transition, as = 'div', delay, cla
|
|
|
32
34
|
};
|
|
33
35
|
}
|
|
34
36
|
}
|
|
35
|
-
const MotionComponent = motion[as];
|
|
36
37
|
return (
|
|
37
38
|
// @ts-expect-error -- polymorphic motion element type mismatch is safe at runtime
|
|
38
39
|
jsx(MotionComponent, { ...motionProps, children: children }));
|
|
@@ -15,10 +15,6 @@ const checkboxTheme = {
|
|
|
15
15
|
"checked:border-[var(--color-primary)] checked:bg-[var(--color-primary)] " +
|
|
16
16
|
// Checked state - dark
|
|
17
17
|
" " +
|
|
18
|
-
// Checked outline - light
|
|
19
|
-
"checked:outline-2 checked:outline-[var(--color-primary-100)] checked:outline-offset-1 " +
|
|
20
|
-
// Checked outline - dark
|
|
21
|
-
"dark:checked:outline-[var(--color-primary-900)] " +
|
|
22
18
|
// Focus visible - light
|
|
23
19
|
"focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-[var(--color-primary-600)] " +
|
|
24
20
|
// Focus visible - dark
|
|
@@ -6,6 +6,8 @@ const radioDotVariants = {
|
|
|
6
6
|
unchecked: {
|
|
7
7
|
scale: 0,
|
|
8
8
|
opacity: 0,
|
|
9
|
+
x: "-50%",
|
|
10
|
+
y: "-50%",
|
|
9
11
|
transition: {
|
|
10
12
|
duration: 0.15,
|
|
11
13
|
ease: "easeOut",
|
|
@@ -14,6 +16,8 @@ const radioDotVariants = {
|
|
|
14
16
|
checked: {
|
|
15
17
|
scale: 1,
|
|
16
18
|
opacity: 1,
|
|
19
|
+
x: "-50%",
|
|
20
|
+
y: "-50%",
|
|
17
21
|
transition: {
|
|
18
22
|
type: "spring",
|
|
19
23
|
stiffness: 400,
|
|
@@ -26,8 +30,8 @@ const radioDotVariants = {
|
|
|
26
30
|
* Reduced motion variants — instant opacity toggle, no scale
|
|
27
31
|
*/
|
|
28
32
|
const reducedMotionDotVariants = {
|
|
29
|
-
unchecked: { opacity: 0 },
|
|
30
|
-
checked: { opacity: 1 },
|
|
33
|
+
unchecked: { opacity: 0, x: "-50%", y: "-50%" },
|
|
34
|
+
checked: { opacity: 1, x: "-50%", y: "-50%" },
|
|
31
35
|
};
|
|
32
36
|
|
|
33
37
|
export { radioDotVariants, reducedMotionDotVariants };
|
|
@@ -43,7 +43,7 @@ const RadioComponent = React__default.forwardRef(({ id: idProp, name: nameProp,
|
|
|
43
43
|
const inputProps = isControlled
|
|
44
44
|
? { checked }
|
|
45
45
|
: { defaultChecked };
|
|
46
|
-
return (jsxs("div", { className: cn(radioTheme.baseStyle, className), ...restProps, children: [jsxs("div", { className: cn(radioTheme.inputContainerStyle, radioTheme.sizes[size]), children: [jsx("input", { ref: ref, type: "radio", id: id, name: name, value: value, ...inputProps, onChange: handleChange, disabled: isDisabled, "aria-describedby": description ? `${id}-description` : undefined, "data-state": isDisabled ? "disabled" : "default", className: cn("peer", radioTheme.inputStyle, radioTheme.sizes[size]) }), jsx(motion.div, { className: cn(radioTheme.dotStyle, isDisabled && "saturate-0 opacity-80"
|
|
46
|
+
return (jsxs("div", { className: cn(radioTheme.baseStyle, className), ...restProps, children: [jsxs("div", { className: cn(radioTheme.inputContainerStyle, radioTheme.sizes[size]), children: [jsx("input", { ref: ref, type: "radio", id: id, name: name, value: value, ...inputProps, onChange: handleChange, disabled: isDisabled, "aria-describedby": description ? `${id}-description` : undefined, "data-state": isDisabled ? "disabled" : "default", className: cn("peer", radioTheme.inputStyle, radioTheme.sizes[size]) }), jsx(motion.div, { className: cn(radioTheme.dotStyle, radioTheme.dotSizes[size], isDisabled && "saturate-0 opacity-80"), initial: false, animate: isChecked ? "checked" : "unchecked", variants: shouldReduceMotion ? reducedMotionDotVariants : radioDotVariants })] }), (label || description) && (jsxs("label", { htmlFor: id, className: cn("cursor-pointer", isDisabled && "cursor-not-allowed"), children: [label && (typeof label === 'string' ? (jsx("span", { className: cn(formLabelTheme.baseStyle, formLabelTheme.stateStyles[state], "mb-0"), children: label })) : label), description && (typeof description === 'string' ? (jsx("div", { id: `${id}-description`, className: radioTheme.descriptionStyle, children: description })) : description)] }))] }));
|
|
47
47
|
});
|
|
48
48
|
RadioComponent.displayName = "Radio";
|
|
49
49
|
const Radio = Object.assign(RadioComponent, { Group: RadioGroup });
|
|
@@ -11,13 +11,9 @@ const radioTheme = {
|
|
|
11
11
|
// Default state - dark
|
|
12
12
|
"dark:bg-[var(--color-background-tertiary)] " +
|
|
13
13
|
// Checked state - light
|
|
14
|
-
"checked:border-[var(--color-primary)]
|
|
14
|
+
"checked:border-[var(--color-primary)] checked:bg-white " +
|
|
15
15
|
// Checked state - dark
|
|
16
|
-
"checked:bg-[var(--color-
|
|
17
|
-
// Checked outline - light
|
|
18
|
-
"checked:outline-2 checked:outline-[var(--color-primary-100)] checked:outline-offset-1 " +
|
|
19
|
-
// Checked outline - dark
|
|
20
|
-
"dark:checked:outline-[var(--color-primary-900)] " +
|
|
16
|
+
"dark:checked:bg-[var(--color-surface)] " +
|
|
21
17
|
// Focus visible - light
|
|
22
18
|
"focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-[var(--color-primary-600)] " +
|
|
23
19
|
// Focus visible - dark
|
|
@@ -28,10 +24,14 @@ const radioTheme = {
|
|
|
28
24
|
// Disabled state - dark
|
|
29
25
|
"dark:disabled:bg-[var(--color-neutral-700)] dark:disabled:border-[var(--color-neutral-600)] " +
|
|
30
26
|
"dark:data-[state=disabled]:bg-[var(--color-neutral-700)] dark:data-[state=disabled]:border-[var(--color-neutral-600)]",
|
|
31
|
-
dotStyle: "absolute
|
|
27
|
+
dotStyle: "absolute top-1/2 left-1/2 pointer-events-none rounded-full bg-[var(--color-primary)]",
|
|
28
|
+
dotSizes: {
|
|
29
|
+
sm: "size-2.5 mt-0.25",
|
|
30
|
+
md: "size-3",
|
|
31
|
+
},
|
|
32
32
|
descriptionStyle: "text-base text-[var(--color-text-secondary)]/80 mt-0.5",
|
|
33
33
|
sizes: {
|
|
34
|
-
sm: "size-5 mt-0.
|
|
34
|
+
sm: "size-5 mt-0.5",
|
|
35
35
|
md: "size-6",
|
|
36
36
|
},
|
|
37
37
|
// Group styles
|