@lobehub/ui 5.15.7 → 5.15.8
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/es/base-ui/DropdownMenu/sharedStyle.mjs +9 -4
- package/es/base-ui/DropdownMenu/sharedStyle.mjs.map +1 -1
- package/es/base-ui/Switch/atoms.d.mts +2 -4
- package/es/base-ui/Switch/atoms.mjs +12 -8
- package/es/base-ui/Switch/atoms.mjs.map +1 -1
- package/es/base-ui/Switch/style.mjs +36 -10
- package/es/base-ui/Switch/style.mjs.map +1 -1
- package/es/base-ui/Switch/type.d.mts +1 -0
- package/package.json +1 -1
|
@@ -38,14 +38,19 @@ const styles = createStaticStyles(({ css, cssVar }) => ({
|
|
|
38
38
|
groupLabel: css`
|
|
39
39
|
user-select: none;
|
|
40
40
|
|
|
41
|
-
padding-block: 4px
|
|
41
|
+
padding-block: 8px 4px;
|
|
42
42
|
padding-inline: 12px;
|
|
43
43
|
|
|
44
|
-
font-size:
|
|
45
|
-
font-weight:
|
|
44
|
+
font-size: 10px;
|
|
45
|
+
font-weight: 600;
|
|
46
46
|
line-height: 14px;
|
|
47
47
|
color: ${cssVar.colorTextTertiary};
|
|
48
|
-
text-transform:
|
|
48
|
+
text-transform: uppercase;
|
|
49
|
+
letter-spacing: 0.6px;
|
|
50
|
+
|
|
51
|
+
[role='group']:first-child > & {
|
|
52
|
+
padding-block-start: 4px;
|
|
53
|
+
}
|
|
49
54
|
`,
|
|
50
55
|
icon: css`
|
|
51
56
|
display: flex;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sharedStyle.mjs","names":[],"sources":["../../../src/base-ui/DropdownMenu/sharedStyle.ts"],"sourcesContent":["import { createStaticStyles } from 'antd-style';\n\nexport const styles = createStaticStyles(({ css, cssVar }) => ({\n danger: css`\n --lobe-menu-icon-color: ${cssVar.colorError};\n\n color: ${cssVar.colorError} !important;\n\n &:hover {\n background: ${cssVar.colorErrorBg} !important;\n }\n `,\n\n empty: css`\n cursor: default;\n font-style: italic;\n color: ${cssVar.colorTextTertiary};\n `,\n\n extra: css`\n margin-inline-start: auto;\n padding-inline-start: 16px;\n\n font-family: ${cssVar.fontFamilyCode};\n font-size: 12px;\n color: ${cssVar.colorTextTertiary};\n `,\n\n footer: css`\n flex-shrink: 0;\n padding-block: 8px;\n padding-inline: 12px;\n border-block-start: 1px solid ${cssVar.colorBorder};\n `,\n\n header: css`\n flex-shrink: 0;\n padding-block: 8px;\n padding-inline: 12px;\n border-block-end: 1px solid ${cssVar.colorBorder};\n `,\n\n groupLabel: css`\n user-select: none;\n\n padding-block: 4px
|
|
1
|
+
{"version":3,"file":"sharedStyle.mjs","names":[],"sources":["../../../src/base-ui/DropdownMenu/sharedStyle.ts"],"sourcesContent":["import { createStaticStyles } from 'antd-style';\n\nexport const styles = createStaticStyles(({ css, cssVar }) => ({\n danger: css`\n --lobe-menu-icon-color: ${cssVar.colorError};\n\n color: ${cssVar.colorError} !important;\n\n &:hover {\n background: ${cssVar.colorErrorBg} !important;\n }\n `,\n\n empty: css`\n cursor: default;\n font-style: italic;\n color: ${cssVar.colorTextTertiary};\n `,\n\n extra: css`\n margin-inline-start: auto;\n padding-inline-start: 16px;\n\n font-family: ${cssVar.fontFamilyCode};\n font-size: 12px;\n color: ${cssVar.colorTextTertiary};\n `,\n\n footer: css`\n flex-shrink: 0;\n padding-block: 8px;\n padding-inline: 12px;\n border-block-start: 1px solid ${cssVar.colorBorder};\n `,\n\n header: css`\n flex-shrink: 0;\n padding-block: 8px;\n padding-inline: 12px;\n border-block-end: 1px solid ${cssVar.colorBorder};\n `,\n\n groupLabel: css`\n user-select: none;\n\n padding-block: 8px 4px;\n padding-inline: 12px;\n\n font-size: 10px;\n font-weight: 600;\n line-height: 14px;\n color: ${cssVar.colorTextTertiary};\n text-transform: uppercase;\n letter-spacing: 0.6px;\n\n [role='group']:first-child > & {\n padding-block-start: 4px;\n }\n `,\n\n icon: css`\n display: flex;\n flex-shrink: 0;\n align-items: center;\n justify-content: center;\n\n width: 14px;\n height: 14px;\n margin-inline-end: 12px;\n\n color: var(--lobe-menu-icon-color, ${cssVar.colorTextSecondary});\n\n & svg {\n width: 100%;\n height: 100%;\n }\n `,\n\n item: css`\n user-select: none;\n\n position: relative;\n\n overflow: hidden;\n display: flex;\n align-items: center;\n\n width: 100%;\n min-height: 32px;\n padding-block: 6px;\n padding-inline: 12px;\n border-radius: ${cssVar.borderRadiusSM};\n\n font-size: 14px;\n line-height: 20px;\n color: ${cssVar.colorText};\n\n outline: none;\n\n transition: all 150ms ${cssVar.motionEaseOut};\n\n &:hover {\n background: ${cssVar.colorFillTertiary};\n }\n\n &:active {\n background: ${cssVar.colorFillSecondary};\n }\n\n &[data-disabled] {\n cursor: not-allowed;\n color: ${cssVar.colorTextDisabled};\n opacity: 0.5;\n\n &:hover {\n background: transparent;\n }\n }\n\n &[data-highlighted]:not([data-disabled]) {\n background: ${cssVar.colorFillTertiary};\n }\n\n &[data-state='open']:not([data-disabled]),\n &[data-open]:not([data-disabled]),\n &[aria-expanded='true']:not([data-disabled]) {\n background: ${cssVar.colorFillTertiary};\n }\n `,\n\n itemContent: css`\n display: flex;\n flex: 1;\n gap: 0;\n align-items: center;\n `,\n\n itemContentAlignStart: css`\n align-items: flex-start;\n `,\n\n iconAlignStart: css`\n align-self: flex-start;\n margin-block-start: 2px;\n `,\n\n label: css`\n overflow: hidden;\n flex: 1;\n text-overflow: ellipsis;\n white-space: nowrap;\n\n & a,\n & a:visited,\n & a:hover,\n & a:active {\n color: inherit;\n }\n `,\n\n labelGroup: css`\n overflow: hidden;\n display: flex;\n flex: 1;\n flex-direction: column;\n\n min-width: 0;\n `,\n\n desc: css`\n overflow: hidden;\n\n font-size: 12px;\n line-height: 16px;\n color: ${cssVar.colorTextTertiary};\n text-overflow: ellipsis;\n white-space: nowrap;\n `,\n\n popup: css`\n min-width: 220px;\n padding: 4px;\n border-radius: ${cssVar.borderRadius};\n\n background: ${cssVar.colorBgElevated};\n outline: none;\n box-shadow:\n 0 0 0 1px ${cssVar.colorBorder},\n 0 4px 12px 0 rgb(0 0 0 / 8%),\n 0 1px 3px 0 rgb(0 0 0 / 6%);\n\n &[data-has-header] {\n padding-block-start: 0;\n }\n\n &[data-has-footer] {\n padding-block-end: 0;\n }\n `,\n\n popupWithSlots: css`\n overflow: hidden;\n display: flex;\n flex-direction: column;\n max-height: var(--available-height);\n `,\n\n slotViewport: css`\n overflow-y: auto;\n flex: 1;\n min-height: 0;\n `,\n\n positioner: css`\n --lobe-dropdown-animation-duration: 140ms;\n --lobe-dropdown-animation-scale-y: 0.92;\n --lobe-dropdown-animation-ease-in: ease-in;\n --lobe-dropdown-animation-ease-out: ${cssVar.motionEaseOut};\n\n z-index: 1100;\n\n & > * {\n will-change: opacity, transform;\n transform-origin: var(--transform-origin);\n animation: none;\n }\n\n &[data-open] > * {\n transform: scaleY(1);\n opacity: 1;\n transition:\n opacity var(--lobe-dropdown-animation-duration) var(--lobe-dropdown-animation-ease-out),\n transform var(--lobe-dropdown-animation-duration) var(--lobe-dropdown-animation-ease-out);\n }\n\n &[data-open] > *[data-starting-style] {\n transform: scaleY(var(--lobe-dropdown-animation-scale-y));\n opacity: 0;\n }\n\n &[data-closed] > * {\n transform: scaleY(var(--lobe-dropdown-animation-scale-y));\n opacity: 0;\n transition:\n opacity var(--lobe-dropdown-animation-duration) var(--lobe-dropdown-animation-ease-in),\n transform var(--lobe-dropdown-animation-duration) var(--lobe-dropdown-animation-ease-in);\n }\n\n &[data-hover-trigger] {\n --lobe-dropdown-animation-duration: 140ms;\n }\n\n &[data-submenu],\n &[data-nested] {\n --lobe-dropdown-animation-duration: 0ms;\n --lobe-dropdown-animation-scale-y: 1;\n\n z-index: 1199;\n }\n\n &[data-side='left'],\n &[data-side='right'] {\n --lobe-dropdown-animation-duration: 0ms;\n --lobe-dropdown-animation-scale-y: 1;\n }\n `,\n\n separator: css`\n height: 1px;\n margin-block: 4px;\n margin-inline: 0;\n background: ${cssVar.colorBorder};\n `,\n\n submenuArrow: css`\n display: flex;\n flex-shrink: 0;\n align-items: center;\n justify-content: center;\n\n width: 16px;\n height: 16px;\n margin-inline-start: 8px;\n\n color: var(--lobe-menu-icon-color, ${cssVar.colorTextSecondary});\n\n & svg {\n width: 12px;\n height: 12px;\n }\n `,\n}));\n"],"mappings":";;AAEA,MAAa,SAAS,oBAAoB,EAAE,KAAK,cAAc;CAC7D,QAAQ,GAAG;8BACiB,OAAO,WAAW;;aAEnC,OAAO,WAAW;;;oBAGX,OAAO,aAAa;;;CAItC,OAAO,GAAG;;;aAGC,OAAO,kBAAkB;;CAGpC,OAAO,GAAG;;;;mBAIO,OAAO,eAAe;;aAE5B,OAAO,kBAAkB;;CAGpC,QAAQ,GAAG;;;;oCAIuB,OAAO,YAAY;;CAGrD,QAAQ,GAAG;;;;kCAIqB,OAAO,YAAY;;CAGnD,YAAY,GAAG;;;;;;;;;aASJ,OAAO,kBAAkB;;;;;;;;CASpC,MAAM,GAAG;;;;;;;;;;yCAU8B,OAAO,mBAAmB;;;;;;;CAQjE,MAAM,GAAG;;;;;;;;;;;;;qBAaU,OAAO,eAAe;;;;aAI9B,OAAO,UAAU;;;;4BAIF,OAAO,cAAc;;;oBAG7B,OAAO,kBAAkB;;;;oBAIzB,OAAO,mBAAmB;;;;;eAK/B,OAAO,kBAAkB;;;;;;;;;oBASpB,OAAO,kBAAkB;;;;;;oBAMzB,OAAO,kBAAkB;;;CAI3C,aAAa,GAAG;;;;;;CAOhB,uBAAuB,GAAG;;;CAI1B,gBAAgB,GAAG;;;;CAKnB,OAAO,GAAG;;;;;;;;;;;;;CAcV,YAAY,GAAG;;;;;;;;CASf,MAAM,GAAG;;;;;aAKE,OAAO,kBAAkB;;;;CAKpC,OAAO,GAAG;;;qBAGS,OAAO,aAAa;;kBAEvB,OAAO,gBAAgB;;;kBAGvB,OAAO,YAAY;;;;;;;;;;;;CAanC,gBAAgB,GAAG;;;;;;CAOnB,cAAc,GAAG;;;;;CAMjB,YAAY,GAAG;;;;0CAIyB,OAAO,cAAc;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAkD7D,WAAW,GAAG;;;;kBAIE,OAAO,YAAY;;CAGnC,cAAc,GAAG;;;;;;;;;;yCAUsB,OAAO,mBAAmB;;;;;;;CAOlE,EAAE"}
|
|
@@ -43,12 +43,10 @@ declare const SwitchIcon: {
|
|
|
43
43
|
children,
|
|
44
44
|
className,
|
|
45
45
|
position,
|
|
46
|
+
size,
|
|
46
47
|
transition,
|
|
47
48
|
...rest
|
|
48
|
-
}: SwitchIconProps
|
|
49
|
-
children?: React.ReactNode;
|
|
50
|
-
size?: "default" | "small";
|
|
51
|
-
}): _$react_jsx_runtime0.JSX.Element;
|
|
49
|
+
}: SwitchIconProps): _$react_jsx_runtime0.JSX.Element;
|
|
52
50
|
displayName: string;
|
|
53
51
|
};
|
|
54
52
|
//#endregion
|
|
@@ -4,6 +4,7 @@ import { rootVariants, styles, thumbVariants } from "./style.mjs";
|
|
|
4
4
|
import { createContext, use, useMemo, useRef, useState } from "react";
|
|
5
5
|
import { jsx } from "react/jsx-runtime";
|
|
6
6
|
import { cx } from "antd-style";
|
|
7
|
+
import { useReducedMotion } from "motion/react";
|
|
7
8
|
import useMergeState from "use-merge-value";
|
|
8
9
|
import { Switch } from "@base-ui/react/switch";
|
|
9
10
|
//#region src/base-ui/Switch/atoms.tsx
|
|
@@ -72,19 +73,21 @@ const SwitchRoot = ({ checked, className, defaultChecked, onCheckedChange, onCli
|
|
|
72
73
|
};
|
|
73
74
|
SwitchRoot.displayName = "SwitchRoot";
|
|
74
75
|
const SwitchThumb = ({ className, pressedAnimation, size = "default", transition = {
|
|
75
|
-
damping:
|
|
76
|
-
stiffness:
|
|
76
|
+
damping: 24,
|
|
77
|
+
stiffness: 360,
|
|
77
78
|
type: "spring"
|
|
78
79
|
}, children, ...rest }) => {
|
|
79
80
|
const Motion = useMotionComponent();
|
|
80
81
|
const { isPressed } = useSwitchContext();
|
|
82
|
+
const shouldReduceMotion = useReducedMotion();
|
|
81
83
|
const baseClassName = thumbVariants({ size });
|
|
82
|
-
const
|
|
84
|
+
const effectiveAnimate = !shouldReduceMotion && isPressed ? pressedAnimation || { width: size === "small" ? 16 : 22 } : void 0;
|
|
85
|
+
const effectiveTransition = shouldReduceMotion ? { duration: 0 } : transition;
|
|
83
86
|
return /* @__PURE__ */ jsx(Switch.Thumb, { render: /* @__PURE__ */ jsx(Motion.span, {
|
|
84
87
|
layout: true,
|
|
85
|
-
animate:
|
|
88
|
+
animate: effectiveAnimate,
|
|
86
89
|
className: cx(baseClassName, className),
|
|
87
|
-
transition,
|
|
90
|
+
transition: effectiveTransition,
|
|
88
91
|
...rest,
|
|
89
92
|
children
|
|
90
93
|
}) });
|
|
@@ -95,13 +98,13 @@ const getIconPositionClass = (position, size) => {
|
|
|
95
98
|
if (position === "left") return size === "small" ? styles.iconLeftSmall : styles.iconLeft;
|
|
96
99
|
return size === "small" ? styles.iconRightSmall : styles.iconRight;
|
|
97
100
|
};
|
|
98
|
-
const SwitchIcon = ({ children, className, position, transition = {
|
|
101
|
+
const SwitchIcon = ({ children, className, position, size = "default", transition = {
|
|
99
102
|
bounce: 0,
|
|
100
103
|
type: "spring"
|
|
101
104
|
}, ...rest }) => {
|
|
102
105
|
const Motion = useMotionComponent();
|
|
103
106
|
const { isChecked } = useSwitchContext();
|
|
104
|
-
const
|
|
107
|
+
const shouldReduceMotion = useReducedMotion();
|
|
105
108
|
const isAnimated = useMemo(() => {
|
|
106
109
|
if (position === "right") return !isChecked;
|
|
107
110
|
if (position === "left") return isChecked;
|
|
@@ -109,6 +112,7 @@ const SwitchIcon = ({ children, className, position, transition = {
|
|
|
109
112
|
return false;
|
|
110
113
|
}, [position, isChecked]);
|
|
111
114
|
const positionClass = getIconPositionClass(position, size);
|
|
115
|
+
const effectiveTransition = shouldReduceMotion ? { duration: 0 } : transition;
|
|
112
116
|
return /* @__PURE__ */ jsx(Motion.span, {
|
|
113
117
|
animate: isAnimated ? {
|
|
114
118
|
opacity: 1,
|
|
@@ -118,7 +122,7 @@ const SwitchIcon = ({ children, className, position, transition = {
|
|
|
118
122
|
scale: 0
|
|
119
123
|
},
|
|
120
124
|
className: cx(styles.icon, positionClass, className),
|
|
121
|
-
transition,
|
|
125
|
+
transition: effectiveTransition,
|
|
122
126
|
...rest,
|
|
123
127
|
children
|
|
124
128
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"atoms.mjs","names":["useControlledState"],"sources":["../../../src/base-ui/Switch/atoms.tsx"],"sourcesContent":["'use client';\n\nimport { Switch } from '@base-ui/react/switch';\nimport { cx } from 'antd-style';\nimport type { KeyboardEvent, MouseEvent } from 'react';\nimport { createContext, use, useMemo, useRef, useState } from 'react';\nimport useControlledState from 'use-merge-value';\n\nimport { useMotionComponent } from '@/MotionProvider';\n\nimport { rootVariants, styles, thumbVariants } from './style';\nimport type {\n SwitchChangeEventHandler,\n SwitchContextType,\n SwitchIconPosition,\n SwitchIconProps,\n SwitchRootProps,\n SwitchThumbProps,\n} from './type';\n\nconst SwitchContext = createContext<SwitchContextType | null>(null);\n\nexport const useSwitchContext = () => {\n const context = use(SwitchContext);\n if (!context) {\n throw new Error('useSwitchContext must be used within a SwitchRoot');\n }\n return context;\n};\n\ntype SwitchRootInternalProps = Omit<SwitchRootProps, 'onCheckedChange' | 'onClick'> & {\n onCheckedChange?: SwitchChangeEventHandler;\n onClick?: SwitchChangeEventHandler;\n};\n\nexport const SwitchRoot = ({\n checked,\n className,\n defaultChecked,\n onCheckedChange,\n onClick,\n size = 'default',\n children,\n disabled,\n readOnly,\n required,\n inputRef,\n id,\n name,\n ...rest\n}: SwitchRootInternalProps) => {\n const Motion = useMotionComponent();\n const [isPressed, setIsPressed] = useState(false);\n const lastEventRef = useRef<MouseEvent<HTMLButtonElement> | KeyboardEvent<HTMLButtonElement>>(\n null,\n );\n\n const [isChecked, setIsChecked] = useControlledState(defaultChecked ?? false, {\n defaultValue: defaultChecked,\n onChange: (value: boolean) => {\n if (lastEventRef.current) {\n onCheckedChange?.(value, lastEventRef.current);\n }\n },\n value: checked,\n });\n\n const baseClassName = rootVariants({ size });\n\n const contextValue = useMemo(\n () => ({\n isChecked: Boolean(isChecked),\n isPressed,\n setIsChecked: (value: boolean) => setIsChecked(value),\n setIsPressed,\n }),\n [isChecked, isPressed, setIsChecked],\n );\n\n const handleClick = (event: MouseEvent<HTMLButtonElement>) => {\n lastEventRef.current = event;\n onClick?.(!isChecked, event);\n };\n\n const handleKeyDown = (event: KeyboardEvent<HTMLButtonElement>) => {\n if (event.key === 'Enter' || event.key === ' ') {\n lastEventRef.current = event;\n }\n (rest as any).onKeyDown?.(event);\n };\n\n return (\n <SwitchContext value={contextValue}>\n <Switch.Root\n checked={isChecked}\n defaultChecked={defaultChecked}\n disabled={disabled}\n id={id}\n inputRef={inputRef}\n name={name}\n readOnly={readOnly}\n required={required}\n render={\n <Motion.button\n {...rest}\n className={cx(baseClassName, className)}\n initial={false}\n whileTap=\"tap\"\n onClick={handleClick}\n onKeyDown={handleKeyDown}\n onTap={() => setIsPressed(false)}\n onTapCancel={() => setIsPressed(false)}\n onTapStart={() => setIsPressed(true)}\n />\n }\n onCheckedChange={setIsChecked}\n >\n {children}\n </Switch.Root>\n </SwitchContext>\n );\n};\n\nSwitchRoot.displayName = 'SwitchRoot';\n\nexport const SwitchThumb = ({\n className,\n pressedAnimation,\n size = 'default',\n transition = { damping:
|
|
1
|
+
{"version":3,"file":"atoms.mjs","names":["useControlledState"],"sources":["../../../src/base-ui/Switch/atoms.tsx"],"sourcesContent":["'use client';\n\nimport { Switch } from '@base-ui/react/switch';\nimport { cx } from 'antd-style';\nimport { useReducedMotion } from 'motion/react';\nimport type { KeyboardEvent, MouseEvent } from 'react';\nimport { createContext, use, useMemo, useRef, useState } from 'react';\nimport useControlledState from 'use-merge-value';\n\nimport { useMotionComponent } from '@/MotionProvider';\n\nimport { rootVariants, styles, thumbVariants } from './style';\nimport type {\n SwitchChangeEventHandler,\n SwitchContextType,\n SwitchIconPosition,\n SwitchIconProps,\n SwitchRootProps,\n SwitchThumbProps,\n} from './type';\n\nconst SwitchContext = createContext<SwitchContextType | null>(null);\n\nexport const useSwitchContext = () => {\n const context = use(SwitchContext);\n if (!context) {\n throw new Error('useSwitchContext must be used within a SwitchRoot');\n }\n return context;\n};\n\ntype SwitchRootInternalProps = Omit<SwitchRootProps, 'onCheckedChange' | 'onClick'> & {\n onCheckedChange?: SwitchChangeEventHandler;\n onClick?: SwitchChangeEventHandler;\n};\n\nexport const SwitchRoot = ({\n checked,\n className,\n defaultChecked,\n onCheckedChange,\n onClick,\n size = 'default',\n children,\n disabled,\n readOnly,\n required,\n inputRef,\n id,\n name,\n ...rest\n}: SwitchRootInternalProps) => {\n const Motion = useMotionComponent();\n const [isPressed, setIsPressed] = useState(false);\n const lastEventRef = useRef<MouseEvent<HTMLButtonElement> | KeyboardEvent<HTMLButtonElement>>(\n null,\n );\n\n const [isChecked, setIsChecked] = useControlledState(defaultChecked ?? false, {\n defaultValue: defaultChecked,\n onChange: (value: boolean) => {\n if (lastEventRef.current) {\n onCheckedChange?.(value, lastEventRef.current);\n }\n },\n value: checked,\n });\n\n const baseClassName = rootVariants({ size });\n\n const contextValue = useMemo(\n () => ({\n isChecked: Boolean(isChecked),\n isPressed,\n setIsChecked: (value: boolean) => setIsChecked(value),\n setIsPressed,\n }),\n [isChecked, isPressed, setIsChecked],\n );\n\n const handleClick = (event: MouseEvent<HTMLButtonElement>) => {\n lastEventRef.current = event;\n onClick?.(!isChecked, event);\n };\n\n const handleKeyDown = (event: KeyboardEvent<HTMLButtonElement>) => {\n if (event.key === 'Enter' || event.key === ' ') {\n lastEventRef.current = event;\n }\n (rest as any).onKeyDown?.(event);\n };\n\n return (\n <SwitchContext value={contextValue}>\n <Switch.Root\n checked={isChecked}\n defaultChecked={defaultChecked}\n disabled={disabled}\n id={id}\n inputRef={inputRef}\n name={name}\n readOnly={readOnly}\n required={required}\n render={\n <Motion.button\n {...rest}\n className={cx(baseClassName, className)}\n initial={false}\n whileTap=\"tap\"\n onClick={handleClick}\n onKeyDown={handleKeyDown}\n onTap={() => setIsPressed(false)}\n onTapCancel={() => setIsPressed(false)}\n onTapStart={() => setIsPressed(true)}\n />\n }\n onCheckedChange={setIsChecked}\n >\n {children}\n </Switch.Root>\n </SwitchContext>\n );\n};\n\nSwitchRoot.displayName = 'SwitchRoot';\n\nexport const SwitchThumb = ({\n className,\n pressedAnimation,\n size = 'default',\n transition = { damping: 24, stiffness: 360, type: 'spring' },\n children,\n ...rest\n}: SwitchThumbProps) => {\n const Motion = useMotionComponent();\n const { isPressed } = useSwitchContext();\n const shouldReduceMotion = useReducedMotion();\n const baseClassName = thumbVariants({ size });\n\n const defaultPressedAnimation = {\n width: size === 'small' ? 16 : 22,\n };\n\n const effectiveAnimate =\n !shouldReduceMotion && isPressed ? pressedAnimation || defaultPressedAnimation : undefined;\n const effectiveTransition = shouldReduceMotion ? { duration: 0 } : transition;\n\n return (\n <Switch.Thumb\n render={\n <Motion.span\n layout\n animate={effectiveAnimate}\n className={cx(baseClassName, className)}\n transition={effectiveTransition}\n {...rest}\n >\n {children}\n </Motion.span>\n }\n />\n );\n};\n\nSwitchThumb.displayName = 'SwitchThumb';\n\nconst getIconPositionClass = (position: SwitchIconPosition, size: 'default' | 'small') => {\n if (position === 'thumb') return styles.iconThumb;\n if (position === 'left') return size === 'small' ? styles.iconLeftSmall : styles.iconLeft;\n return size === 'small' ? styles.iconRightSmall : styles.iconRight;\n};\n\nexport const SwitchIcon = ({\n children,\n className,\n position,\n size = 'default',\n transition = { bounce: 0, type: 'spring' },\n ...rest\n}: SwitchIconProps) => {\n const Motion = useMotionComponent();\n const { isChecked } = useSwitchContext();\n const shouldReduceMotion = useReducedMotion();\n\n const isAnimated = useMemo(() => {\n if (position === 'right') return !isChecked;\n if (position === 'left') return isChecked;\n if (position === 'thumb') return true;\n return false;\n }, [position, isChecked]);\n\n const positionClass = getIconPositionClass(position, size);\n const effectiveTransition = shouldReduceMotion ? { duration: 0 } : transition;\n\n return (\n <Motion.span\n animate={isAnimated ? { opacity: 1, scale: 1 } : { opacity: 0, scale: 0 }}\n className={cx(styles.icon, positionClass, className)}\n transition={effectiveTransition}\n {...rest}\n >\n {children}\n </Motion.span>\n );\n};\n\nSwitchIcon.displayName = 'SwitchIcon';\n\nexport { styles as switchStyles } from './style';\n"],"mappings":"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"}
|
|
@@ -15,13 +15,13 @@ const styles = createStaticStyles(({ css, cssVar }) => ({
|
|
|
15
15
|
color: ${cssVar.colorTextLightSolid};
|
|
16
16
|
`,
|
|
17
17
|
iconLeft: css`
|
|
18
|
-
inset-inline-start:
|
|
18
|
+
inset-inline-start: 4px;
|
|
19
19
|
`,
|
|
20
20
|
iconLeftSmall: css`
|
|
21
21
|
inset-inline-start: 4px;
|
|
22
22
|
`,
|
|
23
23
|
iconRight: css`
|
|
24
|
-
inset-inline-end:
|
|
24
|
+
inset-inline-end: 4px;
|
|
25
25
|
`,
|
|
26
26
|
iconRightSmall: css`
|
|
27
27
|
inset-inline-end: 4px;
|
|
@@ -44,6 +44,10 @@ const styles = createStaticStyles(({ css, cssVar }) => ({
|
|
|
44
44
|
}
|
|
45
45
|
|
|
46
46
|
animation: lobe-switch-loading 1s linear infinite;
|
|
47
|
+
|
|
48
|
+
@media (prefers-reduced-motion: reduce) {
|
|
49
|
+
animation-duration: 0s;
|
|
50
|
+
}
|
|
47
51
|
`,
|
|
48
52
|
root: css`
|
|
49
53
|
cursor: pointer;
|
|
@@ -61,10 +65,13 @@ const styles = createStaticStyles(({ css, cssVar }) => ({
|
|
|
61
65
|
border: 0;
|
|
62
66
|
border-radius: 100px;
|
|
63
67
|
|
|
64
|
-
background: ${cssVar.
|
|
68
|
+
background: ${cssVar.colorFillSecondary};
|
|
65
69
|
outline: none;
|
|
70
|
+
box-shadow: inset 0 1.5px 2px rgb(0 0 0 / 8%);
|
|
66
71
|
|
|
67
|
-
transition:
|
|
72
|
+
transition:
|
|
73
|
+
background 200ms ${cssVar.motionEaseOut},
|
|
74
|
+
box-shadow 200ms ${cssVar.motionEaseOut};
|
|
68
75
|
|
|
69
76
|
&:focus-visible {
|
|
70
77
|
outline: 2px solid ${cssVar.colorPrimaryBorder};
|
|
@@ -72,12 +79,13 @@ const styles = createStaticStyles(({ css, cssVar }) => ({
|
|
|
72
79
|
}
|
|
73
80
|
|
|
74
81
|
&:hover:not([data-disabled]) {
|
|
75
|
-
background: ${cssVar.
|
|
82
|
+
background: ${cssVar.colorFill};
|
|
76
83
|
}
|
|
77
84
|
|
|
78
85
|
&[data-checked] {
|
|
79
86
|
justify-content: flex-end;
|
|
80
87
|
background: ${cssVar.colorPrimary};
|
|
88
|
+
box-shadow: inset 0 1.5px 3px rgb(0 0 0 / 18%);
|
|
81
89
|
|
|
82
90
|
&:hover:not([data-disabled]) {
|
|
83
91
|
background: ${cssVar.colorPrimaryHover};
|
|
@@ -86,12 +94,16 @@ const styles = createStaticStyles(({ css, cssVar }) => ({
|
|
|
86
94
|
|
|
87
95
|
&[data-disabled] {
|
|
88
96
|
cursor: not-allowed;
|
|
89
|
-
opacity: 0.
|
|
97
|
+
opacity: 0.45;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
@media (prefers-reduced-motion: reduce) {
|
|
101
|
+
transition-duration: 0s;
|
|
90
102
|
}
|
|
91
103
|
`,
|
|
92
104
|
rootDefault: css`
|
|
93
|
-
width:
|
|
94
|
-
min-width:
|
|
105
|
+
width: 36px;
|
|
106
|
+
min-width: 36px;
|
|
95
107
|
height: 22px;
|
|
96
108
|
`,
|
|
97
109
|
rootSmall: css`
|
|
@@ -109,12 +121,26 @@ const styles = createStaticStyles(({ css, cssVar }) => ({
|
|
|
109
121
|
|
|
110
122
|
background: ${cssVar.colorBgContainer};
|
|
111
123
|
box-shadow:
|
|
112
|
-
0
|
|
113
|
-
0 1px
|
|
124
|
+
0 0 0 0.5px rgb(0 0 0 / 4%),
|
|
125
|
+
0 1px 1px rgb(0 0 0 / 6%),
|
|
126
|
+
0 3px 8px rgb(0 30 80 / 16%);
|
|
127
|
+
|
|
128
|
+
transition: box-shadow 200ms ${cssVar.motionEaseOut};
|
|
129
|
+
|
|
130
|
+
[role='switch']:hover:not([data-disabled]) > & {
|
|
131
|
+
box-shadow:
|
|
132
|
+
0 0 0 0.5px rgb(0 0 0 / 4%),
|
|
133
|
+
0 1px 1px rgb(0 0 0 / 8%),
|
|
134
|
+
0 6px 14px rgb(0 30 80 / 24%);
|
|
135
|
+
}
|
|
114
136
|
|
|
115
137
|
[data-disabled] > & {
|
|
116
138
|
box-shadow: none;
|
|
117
139
|
}
|
|
140
|
+
|
|
141
|
+
@media (prefers-reduced-motion: reduce) {
|
|
142
|
+
transition-duration: 0s;
|
|
143
|
+
}
|
|
118
144
|
`,
|
|
119
145
|
thumbDefault: css`
|
|
120
146
|
width: 18px;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"style.mjs","names":[],"sources":["../../../src/base-ui/Switch/style.ts"],"sourcesContent":["import { createStaticStyles } from 'antd-style';\nimport { cva } from 'class-variance-authority';\n\nexport const styles = createStaticStyles(({ css, cssVar }) => ({\n icon: css`\n pointer-events: none;\n\n position: absolute;\n inset-block: 0;\n\n display: flex;\n align-items: center;\n justify-content: center;\n\n color: ${cssVar.colorTextLightSolid};\n `,\n iconLeft: css`\n inset-inline-start:
|
|
1
|
+
{"version":3,"file":"style.mjs","names":[],"sources":["../../../src/base-ui/Switch/style.ts"],"sourcesContent":["import { createStaticStyles } from 'antd-style';\nimport { cva } from 'class-variance-authority';\n\nexport const styles = createStaticStyles(({ css, cssVar }) => ({\n icon: css`\n pointer-events: none;\n\n position: absolute;\n inset-block: 0;\n\n display: flex;\n align-items: center;\n justify-content: center;\n\n color: ${cssVar.colorTextLightSolid};\n `,\n iconLeft: css`\n inset-inline-start: 4px;\n `,\n iconLeftSmall: css`\n inset-inline-start: 4px;\n `,\n iconRight: css`\n inset-inline-end: 4px;\n `,\n iconRightSmall: css`\n inset-inline-end: 4px;\n `,\n iconThumb: css`\n position: relative;\n inset: unset;\n transform: none;\n color: ${cssVar.colorPrimary};\n `,\n loading: css`\n @keyframes lobe-switch-loading {\n 0% {\n transform: rotate(0deg);\n }\n\n 100% {\n transform: rotate(360deg);\n }\n }\n\n animation: lobe-switch-loading 1s linear infinite;\n\n @media (prefers-reduced-motion: reduce) {\n animation-duration: 0s;\n }\n `,\n root: css`\n cursor: pointer;\n user-select: none;\n\n position: relative;\n\n overflow: hidden;\n display: inline-flex;\n align-items: center;\n justify-content: flex-start;\n\n box-sizing: border-box;\n padding: 2px;\n border: 0;\n border-radius: 100px;\n\n background: ${cssVar.colorFillSecondary};\n outline: none;\n box-shadow: inset 0 1.5px 2px rgb(0 0 0 / 8%);\n\n transition:\n background 200ms ${cssVar.motionEaseOut},\n box-shadow 200ms ${cssVar.motionEaseOut};\n\n &:focus-visible {\n outline: 2px solid ${cssVar.colorPrimaryBorder};\n outline-offset: 1px;\n }\n\n &:hover:not([data-disabled]) {\n background: ${cssVar.colorFill};\n }\n\n &[data-checked] {\n justify-content: flex-end;\n background: ${cssVar.colorPrimary};\n box-shadow: inset 0 1.5px 3px rgb(0 0 0 / 18%);\n\n &:hover:not([data-disabled]) {\n background: ${cssVar.colorPrimaryHover};\n }\n }\n\n &[data-disabled] {\n cursor: not-allowed;\n opacity: 0.45;\n }\n\n @media (prefers-reduced-motion: reduce) {\n transition-duration: 0s;\n }\n `,\n rootDefault: css`\n width: 36px;\n min-width: 36px;\n height: 22px;\n `,\n rootSmall: css`\n width: 28px;\n min-width: 28px;\n height: 16px;\n `,\n thumb: css`\n display: flex;\n flex-shrink: 0;\n align-items: center;\n justify-content: center;\n\n border-radius: 50%;\n\n background: ${cssVar.colorBgContainer};\n box-shadow:\n 0 0 0 0.5px rgb(0 0 0 / 4%),\n 0 1px 1px rgb(0 0 0 / 6%),\n 0 3px 8px rgb(0 30 80 / 16%);\n\n transition: box-shadow 200ms ${cssVar.motionEaseOut};\n\n [role='switch']:hover:not([data-disabled]) > & {\n box-shadow:\n 0 0 0 0.5px rgb(0 0 0 / 4%),\n 0 1px 1px rgb(0 0 0 / 8%),\n 0 6px 14px rgb(0 30 80 / 24%);\n }\n\n [data-disabled] > & {\n box-shadow: none;\n }\n\n @media (prefers-reduced-motion: reduce) {\n transition-duration: 0s;\n }\n `,\n thumbDefault: css`\n width: 18px;\n height: 18px;\n `,\n thumbSmall: css`\n width: 12px;\n height: 12px;\n `,\n}));\n\nexport const rootVariants = cva(styles.root, {\n defaultVariants: {\n size: 'default',\n },\n variants: {\n size: {\n default: styles.rootDefault,\n small: styles.rootSmall,\n },\n },\n});\n\nexport const thumbVariants = cva(styles.thumb, {\n defaultVariants: {\n size: 'default',\n },\n variants: {\n size: {\n default: styles.thumbDefault,\n small: styles.thumbSmall,\n },\n },\n});\n"],"mappings":";;;AAGA,MAAa,SAAS,oBAAoB,EAAE,KAAK,cAAc;CAC7D,MAAM,GAAG;;;;;;;;;;aAUE,OAAO,oBAAoB;;CAEtC,UAAU,GAAG;;;CAGb,eAAe,GAAG;;;CAGlB,WAAW,GAAG;;;CAGd,gBAAgB,GAAG;;;CAGnB,WAAW,GAAG;;;;aAIH,OAAO,aAAa;;CAE/B,SAAS,GAAG;;;;;;;;;;;;;;;;;CAiBZ,MAAM,GAAG;;;;;;;;;;;;;;;;kBAgBO,OAAO,mBAAmB;;;;;yBAKnB,OAAO,cAAc;yBACrB,OAAO,cAAc;;;2BAGnB,OAAO,mBAAmB;;;;;oBAKjC,OAAO,UAAU;;;;;oBAKjB,OAAO,aAAa;;;;sBAIlB,OAAO,kBAAkB;;;;;;;;;;;;;CAa7C,aAAa,GAAG;;;;;CAKhB,WAAW,GAAG;;;;;CAKd,OAAO,GAAG;;;;;;;;kBAQM,OAAO,iBAAiB;;;;;;mCAMP,OAAO,cAAc;;;;;;;;;;;;;;;;;CAiBtD,cAAc,GAAG;;;;CAIjB,YAAY,GAAG;;;;CAIhB,EAAE;AAEH,MAAa,eAAe,IAAI,OAAO,MAAM;CAC3C,iBAAiB,EACf,MAAM,WACP;CACD,UAAU,EACR,MAAM;EACJ,SAAS,OAAO;EAChB,OAAO,OAAO;EACf,EACF;CACF,CAAC;AAEF,MAAa,gBAAgB,IAAI,OAAO,OAAO;CAC7C,iBAAiB,EACf,MAAM,WACP;CACD,UAAU,EACR,MAAM;EACJ,SAAS,OAAO;EAChB,OAAO,OAAO;EACf,EACF;CACF,CAAC"}
|
|
@@ -33,6 +33,7 @@ type SwitchThumbProps = Omit<ComponentProps<typeof Switch.Thumb>, 'render'> & HT
|
|
|
33
33
|
type SwitchIconPosition = 'left' | 'right' | 'thumb';
|
|
34
34
|
type SwitchIconProps = HTMLMotionProps<'span'> & {
|
|
35
35
|
position: SwitchIconPosition;
|
|
36
|
+
size?: SwitchSize;
|
|
36
37
|
transition?: Transition;
|
|
37
38
|
};
|
|
38
39
|
interface SwitchProps {
|