@luxfi/ui 5.5.3 → 5.6.0
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/accordion.cjs +213 -0
- package/dist/accordion.js +186 -0
- package/dist/alert.cjs +553 -0
- package/dist/alert.js +531 -0
- package/dist/avatar.cjs +149 -0
- package/dist/avatar.js +125 -0
- package/dist/badge.cjs +611 -0
- package/dist/badge.js +589 -0
- package/dist/button.cjs +689 -0
- package/dist/button.js +664 -0
- package/dist/checkbox.cjs +265 -0
- package/dist/checkbox.js +241 -0
- package/dist/close-button.cjs +73 -0
- package/dist/close-button.js +51 -0
- package/dist/collapsible.cjs +702 -0
- package/dist/collapsible.js +679 -0
- package/dist/color-mode.cjs +96 -0
- package/dist/color-mode.js +72 -0
- package/dist/dialog.cjs +279 -0
- package/dist/dialog.js +246 -0
- package/dist/drawer.cjs +207 -0
- package/dist/drawer.js +175 -0
- package/dist/empty-state.cjs +93 -0
- package/dist/empty-state.js +71 -0
- package/dist/field.cjs +183 -0
- package/dist/field.js +160 -0
- package/dist/heading.cjs +46 -0
- package/dist/heading.js +40 -0
- package/dist/icon-button.cjs +491 -0
- package/dist/icon-button.js +470 -0
- package/dist/image.cjs +572 -0
- package/dist/image.js +551 -0
- package/dist/index.cjs +5779 -0
- package/dist/index.js +5619 -0
- package/dist/input-group.cjs +155 -0
- package/dist/input-group.js +133 -0
- package/dist/input.cjs +65 -0
- package/dist/input.js +59 -0
- package/dist/link.cjs +630 -0
- package/dist/link.js +606 -0
- package/dist/menu.cjs +305 -0
- package/dist/menu.js +269 -0
- package/dist/pin-input.cjs +182 -0
- package/dist/pin-input.js +160 -0
- package/dist/popover.cjs +327 -0
- package/dist/popover.js +294 -0
- package/dist/progress-circle.cjs +152 -0
- package/dist/progress-circle.js +128 -0
- package/dist/progress.cjs +117 -0
- package/dist/progress.js +94 -0
- package/dist/provider.cjs +62 -0
- package/dist/provider.js +40 -0
- package/dist/radio.cjs +177 -0
- package/dist/radio.js +153 -0
- package/dist/rating.cjs +80 -0
- package/dist/rating.js +58 -0
- package/dist/select.cjs +791 -0
- package/dist/select.js +757 -0
- package/dist/separator.cjs +57 -0
- package/dist/separator.js +51 -0
- package/dist/skeleton.cjs +370 -0
- package/dist/skeleton.js +346 -0
- package/dist/slider.cjs +138 -0
- package/dist/slider.js +115 -0
- package/dist/switch.cjs +163 -0
- package/dist/switch.js +140 -0
- package/dist/table.cjs +1044 -0
- package/dist/table.js +1013 -0
- package/dist/tabs.cjs +240 -0
- package/dist/tabs.js +213 -0
- package/dist/tag.cjs +651 -0
- package/dist/tag.js +628 -0
- package/dist/textarea.cjs +65 -0
- package/dist/textarea.js +59 -0
- package/dist/toaster.cjs +99 -0
- package/dist/toaster.js +96 -0
- package/dist/tooltip.cjs +171 -0
- package/dist/tooltip.js +148 -0
- package/dist/utils.cjs +11 -0
- package/dist/utils.js +9 -0
- package/package.json +270 -65
- package/src/accordion.tsx +285 -0
- package/src/alert.tsx +221 -0
- package/src/avatar.tsx +174 -0
- package/src/badge.tsx +158 -0
- package/src/button.tsx +411 -0
- package/src/checkbox.tsx +307 -0
- package/src/close-button.tsx +51 -0
- package/src/collapsible.tsx +126 -0
- package/src/color-mode.tsx +125 -0
- package/src/dialog.tsx +356 -0
- package/src/drawer.tsx +186 -0
- package/src/empty-state.tsx +97 -0
- package/src/field.tsx +202 -0
- package/src/heading.tsx +55 -0
- package/src/icon-button.tsx +192 -0
- package/src/image.tsx +280 -0
- package/src/index.ts +192 -0
- package/src/input-group.tsx +159 -0
- package/src/input.tsx +60 -0
- package/src/link.tsx +326 -0
- package/src/menu.tsx +471 -0
- package/src/pin-input.tsx +187 -0
- package/src/popover.tsx +400 -0
- package/src/progress-circle.tsx +180 -0
- package/src/progress.tsx +109 -0
- package/src/provider.tsx +12 -0
- package/src/radio.tsx +175 -0
- package/src/rating.tsx +79 -0
- package/src/select.tsx +696 -0
- package/src/separator.tsx +59 -0
- package/src/skeleton.tsx +302 -0
- package/src/slider.tsx +152 -0
- package/src/switch.tsx +158 -0
- package/src/table.tsx +621 -0
- package/src/tabs.tsx +354 -0
- package/src/tag.tsx +159 -0
- package/src/textarea.tsx +60 -0
- package/src/toaster.tsx +117 -0
- package/src/tokens.css +438 -0
- package/src/tooltip.tsx +184 -0
- package/src/utils/cn.ts +7 -0
- package/src/utils.ts +6 -0
- package/tokens.css +438 -0
- package/commerce/ui/conf.ts +0 -13
- package/commerce/ui/context.tsx +0 -123
- package/commerce/ui/store.ts +0 -295
- package/components/access-code-input.tsx +0 -71
- package/components/analytics.tsx +0 -23
- package/components/auth/auth-listener.tsx +0 -29
- package/components/auth/auth-token/clear-auth-token.tsx +0 -12
- package/components/auth/auth-token/set-auth-token.tsx +0 -16
- package/components/auth/common-auth-domains.ts +0 -17
- package/components/auth/login-panel.tsx +0 -111
- package/components/auth/mobile-login-button.tsx +0 -107
- package/components/auth/signup-panel.tsx +0 -113
- package/components/back-button.tsx +0 -49
- package/components/chat-widget.tsx +0 -85
- package/components/commerce/bag-button.tsx +0 -98
- package/components/commerce/buy-button.tsx +0 -34
- package/components/commerce/checkout-button.tsx +0 -129
- package/components/commerce/checkout-panel/cart-accordian.tsx +0 -66
- package/components/commerce/checkout-panel/checkout-panel-props.ts +0 -10
- package/components/commerce/checkout-panel/desktop-bag-carousel.tsx +0 -36
- package/components/commerce/checkout-panel/desktop-cp.tsx +0 -83
- package/components/commerce/checkout-panel/index.tsx +0 -126
- package/components/commerce/checkout-panel/mobile-cp.tsx +0 -67
- package/components/commerce/checkout-panel/policy-links.tsx +0 -29
- package/components/commerce/checkout-panel/steps-indicator.tsx +0 -39
- package/components/commerce/checkout-panel/thank-you.tsx +0 -18
- package/components/commerce/desktop-bag-popup.tsx +0 -78
- package/components/commerce/drawer/index.tsx +0 -88
- package/components/commerce/drawer/micro.tsx +0 -145
- package/components/commerce/drawer/shell.tsx +0 -85
- package/components/contact-dialog/contact-form.tsx +0 -116
- package/components/contact-dialog/disclaimer.tsx +0 -13
- package/components/contact-dialog/index.tsx +0 -64
- package/components/copyright.tsx +0 -21
- package/components/drawer-margin.tsx +0 -28
- package/components/footer.tsx +0 -78
- package/components/header/desktop-nav-menu.tsx +0 -204
- package/components/header/desktop.tsx +0 -65
- package/components/header/index.tsx +0 -50
- package/components/header/mobile-bag-drawer.tsx +0 -51
- package/components/header/mobile-menu-toggle-button.tsx +0 -35
- package/components/header/mobile-nav-menu-ai.tsx +0 -51
- package/components/header/mobile-nav-menu-item.tsx +0 -47
- package/components/header/mobile-nav-menu.tsx +0 -102
- package/components/header/mobile.tsx +0 -170
- package/components/header/theme-toggle.tsx +0 -26
- package/components/icons/avatar.tsx +0 -11
- package/components/icons/bag-icon.tsx +0 -10
- package/components/icons/index.ts +0 -6
- package/components/icons/left-arrow.tsx +0 -11
- package/components/icons/lux-logo.tsx +0 -10
- package/components/icons/right-arrow.tsx +0 -10
- package/components/icons/social-icon.tsx +0 -35
- package/components/icons/social-svg.css +0 -3
- package/components/index.ts +0 -26
- package/components/logo.tsx +0 -92
- package/components/main.tsx +0 -27
- package/components/mini-chart/index.tsx +0 -8
- package/components/mini-chart/mini-chart-props.ts +0 -44
- package/components/mini-chart/mini-chart.tsx +0 -85
- package/components/mini-chart/wrapper.tsx +0 -23
- package/components/not-found/index.tsx +0 -28
- package/components/not-found/not-found-content.mdx +0 -5
- package/components/tooltip.tsx +0 -31
- package/environment.d.ts +0 -6
- package/next/analytics/fpixel.ts +0 -16
- package/next/analytics/google-analytics.ts +0 -14
- package/next/analytics/index.ts +0 -3
- package/next/analytics/pixel-analytics.tsx +0 -55
- package/next/font/get-app-router-font-classes.ts +0 -17
- package/next/font/load-and-return-lux-next-fonts-on-import.ts +0 -68
- package/next/font/local/Druk-Wide-Bold.ttf +0 -0
- package/next/font/local/Druk-Wide-Medium.ttf +0 -0
- package/next/font/local/InterVariable-Italic.ttf +0 -0
- package/next/font/local/InterVariable-Italic.woff2 +0 -0
- package/next/font/local/InterVariable.ttf +0 -0
- package/next/font/local/InterVariable.woff2 +0 -0
- package/next/font/next-font-desc.ts +0 -28
- package/next/font/pages-router-font-vars.tsx +0 -18
- package/next/head-metadata/from-next/metadata-types.ts +0 -158
- package/next/head-metadata/from-next/opengraph-types.ts +0 -267
- package/next/head-metadata/from-next/twitter-types.ts +0 -92
- package/next/head-metadata/index.tsx +0 -208
- package/next/index.ts +0 -2
- package/next/middleware/determine-device-mw.ts +0 -29
- package/root-layout/WHY_THIS_IS_SEPARATE.txt +0 -2
- package/root-layout/index.tsx +0 -112
- package/site-def/footer/community.tsx +0 -61
- package/site-def/footer/company.ts +0 -37
- package/site-def/footer/ecosystem.ts +0 -37
- package/site-def/footer/index.tsx +0 -26
- package/site-def/footer/legal.ts +0 -28
- package/site-def/footer/network.ts +0 -45
- package/site-def/footer/svg/warpcast-logo.svg +0 -12
- package/site-def/index.ts +0 -4
- package/site-def/main-nav.tsx +0 -460
- package/style/cart-animation.css +0 -29
- package/style/checkout-animation.css +0 -23
- package/style/drawer-handle-overrides.css +0 -160
- package/style/fonts/COPY_TO_PUBLIC_FOR_NON_NEXT.txt +0 -0
- package/style/fonts/Druk-Wide-Bold.ttf +0 -0
- package/style/fonts/Druk-Wide-Medium.ttf +0 -0
- package/style/fonts/InterVariable-Italic.ttf +0 -0
- package/style/fonts/InterVariable-Italic.woff2 +0 -0
- package/style/fonts/InterVariable.ttf +0 -0
- package/style/fonts/InterVariable.woff2 +0 -0
- package/style/lux-colors.css +0 -85
- package/style/lux-fonts.css +0 -30
- package/style/lux-global-non-next.css +0 -52
- package/style/lux-global.css +0 -51
- package/tailwind/fontFamily.tailwind.lux.ts +0 -18
- package/tailwind/index.ts +0 -2
- package/tailwind/lux-tw-fonts.ts +0 -40
- package/tailwind/tailwind.config.lux-preset.ts +0 -10
- package/tsconfig.json +0 -15
- package/types/chatbot-config.ts +0 -7
- package/types/chatbot-suggested-question.ts +0 -7
- package/types/contact-info.ts +0 -11
- package/types/index.ts +0 -4
- package/types/site-def.ts +0 -46
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
|
|
3
|
+
import { cn } from './utils';
|
|
4
|
+
|
|
5
|
+
type Orientation = 'horizontal' | 'vertical';
|
|
6
|
+
type Variant = 'solid' | 'dashed' | 'dotted';
|
|
7
|
+
type Size = 'xs' | 'sm' | 'md' | 'lg';
|
|
8
|
+
|
|
9
|
+
export interface SeparatorProps extends React.HTMLAttributes<HTMLHRElement> {
|
|
10
|
+
readonly orientation?: Orientation;
|
|
11
|
+
readonly variant?: Variant;
|
|
12
|
+
readonly size?: Size;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
const VARIANT_CLASSES: Record<Variant, string> = {
|
|
16
|
+
solid: 'border-solid',
|
|
17
|
+
dashed: 'border-dashed',
|
|
18
|
+
dotted: 'border-dotted',
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
const HORIZONTAL_SIZE_CLASSES: Record<Size, string> = {
|
|
22
|
+
xs: 'border-t-[0.5px]',
|
|
23
|
+
sm: 'border-t',
|
|
24
|
+
md: 'border-t-2',
|
|
25
|
+
lg: 'border-t-[3px]',
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
const VERTICAL_SIZE_CLASSES: Record<Size, string> = {
|
|
29
|
+
xs: 'border-l-[0.5px]',
|
|
30
|
+
sm: 'border-l',
|
|
31
|
+
md: 'border-l-2',
|
|
32
|
+
lg: 'border-l-[3px]',
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
export const Separator = React.forwardRef<HTMLHRElement, SeparatorProps>(
|
|
36
|
+
function Separator(
|
|
37
|
+
{ orientation = 'horizontal', variant = 'solid', size = 'sm', className, ...rest },
|
|
38
|
+
ref,
|
|
39
|
+
) {
|
|
40
|
+
const isVertical = orientation === 'vertical';
|
|
41
|
+
|
|
42
|
+
return (
|
|
43
|
+
<hr
|
|
44
|
+
ref={ ref }
|
|
45
|
+
role="separator"
|
|
46
|
+
aria-orientation={ orientation }
|
|
47
|
+
className={ cn(
|
|
48
|
+
'border-[var(--color-border-divider)]',
|
|
49
|
+
'border-0',
|
|
50
|
+
VARIANT_CLASSES[variant],
|
|
51
|
+
isVertical ? VERTICAL_SIZE_CLASSES[size] : HORIZONTAL_SIZE_CLASSES[size],
|
|
52
|
+
isVertical ? 'self-stretch h-auto w-0' : 'w-full',
|
|
53
|
+
className,
|
|
54
|
+
) }
|
|
55
|
+
{ ...rest }
|
|
56
|
+
/>
|
|
57
|
+
);
|
|
58
|
+
},
|
|
59
|
+
);
|
package/src/skeleton.tsx
ADDED
|
@@ -0,0 +1,302 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
|
|
3
|
+
import { cn } from './utils';
|
|
4
|
+
|
|
5
|
+
// ---------------------------------------------------------------------------
|
|
6
|
+
// Skeleton
|
|
7
|
+
// ---------------------------------------------------------------------------
|
|
8
|
+
|
|
9
|
+
export interface SkeletonProps extends Omit<React.HTMLAttributes<HTMLDivElement>, 'color'> {
|
|
10
|
+
readonly loading: boolean | undefined;
|
|
11
|
+
|
|
12
|
+
/** When true, the Skeleton wraps its single child element instead of adding a wrapper div. */
|
|
13
|
+
readonly asChild?: boolean;
|
|
14
|
+
|
|
15
|
+
// Legacy Chakra style-prop shims — converted to className / inline style.
|
|
16
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
17
|
+
readonly w?: any;
|
|
18
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
19
|
+
readonly h?: any;
|
|
20
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
21
|
+
readonly minW?: any;
|
|
22
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
23
|
+
readonly maxW?: any;
|
|
24
|
+
readonly display?: string;
|
|
25
|
+
readonly flexGrow?: number;
|
|
26
|
+
readonly flexShrink?: number;
|
|
27
|
+
readonly flexBasis?: string;
|
|
28
|
+
readonly fontWeight?: number | string;
|
|
29
|
+
readonly textStyle?: string;
|
|
30
|
+
readonly borderRadius?: string;
|
|
31
|
+
readonly alignSelf?: string;
|
|
32
|
+
readonly alignItems?: string;
|
|
33
|
+
readonly justifyContent?: string;
|
|
34
|
+
readonly color?: string;
|
|
35
|
+
readonly mt?: number | string;
|
|
36
|
+
readonly mb?: number | string;
|
|
37
|
+
readonly ml?: number | string;
|
|
38
|
+
readonly mr?: number | string;
|
|
39
|
+
readonly height?: string;
|
|
40
|
+
readonly overflow?: string;
|
|
41
|
+
readonly whiteSpace?: string;
|
|
42
|
+
readonly textOverflow?: string;
|
|
43
|
+
readonly textTransform?: string;
|
|
44
|
+
readonly gap?: number | string;
|
|
45
|
+
readonly gridTemplateColumns?: string;
|
|
46
|
+
readonly minWidth?: string;
|
|
47
|
+
readonly boxSize?: number | string;
|
|
48
|
+
readonly py?: number | string;
|
|
49
|
+
readonly px?: number | string;
|
|
50
|
+
readonly p?: number | string;
|
|
51
|
+
readonly hideBelow?: string;
|
|
52
|
+
readonly as?: React.ElementType;
|
|
53
|
+
readonly fontSize?: string;
|
|
54
|
+
readonly flexWrap?: React.CSSProperties['flexWrap'];
|
|
55
|
+
readonly wordBreak?: React.CSSProperties['wordBreak'];
|
|
56
|
+
readonly lineHeight?: string;
|
|
57
|
+
readonly marginRight?: string;
|
|
58
|
+
readonly position?: React.CSSProperties['position'];
|
|
59
|
+
readonly background?: string;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
const SPACING_SCALE = 4;
|
|
63
|
+
|
|
64
|
+
function toStylePx(value: number | string | undefined): string | undefined {
|
|
65
|
+
if (value === undefined) return undefined;
|
|
66
|
+
if (typeof value === 'string') return value;
|
|
67
|
+
return `${ value * SPACING_SCALE }px`;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
function extractSkeletonStyleProps(props: Record<string, unknown>): {
|
|
71
|
+
style: React.CSSProperties;
|
|
72
|
+
rest: Record<string, unknown>;
|
|
73
|
+
} {
|
|
74
|
+
const style: React.CSSProperties = {};
|
|
75
|
+
const rest: Record<string, unknown> = {};
|
|
76
|
+
|
|
77
|
+
function resolveDimension(value: unknown): string | undefined {
|
|
78
|
+
if (value === undefined || value === null) return undefined;
|
|
79
|
+
if (typeof value === 'number') return `${ value * SPACING_SCALE }px`;
|
|
80
|
+
if (typeof value === 'string') return value;
|
|
81
|
+
if (typeof value === 'object') {
|
|
82
|
+
const obj = value as Record<string, string>;
|
|
83
|
+
return obj.base ?? obj.lg ?? obj.xl ?? Object.values(obj)[0];
|
|
84
|
+
}
|
|
85
|
+
return undefined;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
for (const [ key, value ] of Object.entries(props)) {
|
|
89
|
+
if (value === undefined) continue;
|
|
90
|
+
switch (key) {
|
|
91
|
+
case 'w': {
|
|
92
|
+
const v = resolveDimension(value); if (v) style.width = v; break;
|
|
93
|
+
}
|
|
94
|
+
case 'h': {
|
|
95
|
+
const v = resolveDimension(value); if (v) style.height = v; break;
|
|
96
|
+
}
|
|
97
|
+
case 'minW': {
|
|
98
|
+
const v = resolveDimension(value); if (v) style.minWidth = v; break;
|
|
99
|
+
}
|
|
100
|
+
case 'maxW': {
|
|
101
|
+
const v = resolveDimension(value); if (v) style.maxWidth = v; break;
|
|
102
|
+
}
|
|
103
|
+
case 'height': style.height = value as string; break;
|
|
104
|
+
case 'display': style.display = value as string; break;
|
|
105
|
+
case 'flexGrow': style.flexGrow = value as number; break;
|
|
106
|
+
case 'flexShrink': style.flexShrink = value as number; break;
|
|
107
|
+
case 'flexBasis': style.flexBasis = value as string; break;
|
|
108
|
+
case 'fontWeight': style.fontWeight = value as number | string; break;
|
|
109
|
+
case 'borderRadius': style.borderRadius = value as string; break;
|
|
110
|
+
case 'alignSelf': style.alignSelf = value as string; break;
|
|
111
|
+
case 'alignItems': style.alignItems = value as string; break;
|
|
112
|
+
case 'justifyContent': style.justifyContent = value as string; break;
|
|
113
|
+
case 'color': style.color = value as string; break;
|
|
114
|
+
case 'mt': style.marginTop = toStylePx(value as number | string); break;
|
|
115
|
+
case 'mb': style.marginBottom = toStylePx(value as number | string); break;
|
|
116
|
+
case 'ml': style.marginLeft = toStylePx(value as number | string); break;
|
|
117
|
+
case 'mr': style.marginRight = toStylePx(value as number | string); break;
|
|
118
|
+
case 'overflow': style.overflow = value as string; break;
|
|
119
|
+
case 'whiteSpace': style.whiteSpace = value as string; break;
|
|
120
|
+
case 'textOverflow': style.textOverflow = value as string; break;
|
|
121
|
+
case 'textTransform': style.textTransform = value as string; break;
|
|
122
|
+
case 'gap': style.gap = typeof value === 'number' ? `${ value * SPACING_SCALE }px` : value as string; break;
|
|
123
|
+
case 'gridTemplateColumns': style.gridTemplateColumns = value as string; break;
|
|
124
|
+
case 'minWidth': style.minWidth = value as string; break;
|
|
125
|
+
case 'boxSize': {
|
|
126
|
+
const s = typeof value === 'number' ? `${ value * SPACING_SCALE }px` : value as string; style.width = s; style.height = s; break;
|
|
127
|
+
}
|
|
128
|
+
case 'py': {
|
|
129
|
+
const v = toStylePx(value as number | string); style.paddingTop = v; style.paddingBottom = v; break;
|
|
130
|
+
}
|
|
131
|
+
case 'px': {
|
|
132
|
+
const v = toStylePx(value as number | string); style.paddingLeft = v; style.paddingRight = v; break;
|
|
133
|
+
}
|
|
134
|
+
case 'p': {
|
|
135
|
+
const v = toStylePx(value as number | string); style.padding = v; break;
|
|
136
|
+
}
|
|
137
|
+
case 'hideBelow': break; // handled via className
|
|
138
|
+
case 'textStyle': break; // drop textStyle, not directly applicable
|
|
139
|
+
case 'fontSize': style.fontSize = value as string; break;
|
|
140
|
+
case 'flexWrap': style.flexWrap = value as React.CSSProperties['flexWrap']; break;
|
|
141
|
+
case 'wordBreak': style.wordBreak = value as React.CSSProperties['wordBreak']; break;
|
|
142
|
+
case 'lineHeight': style.lineHeight = value as string; break;
|
|
143
|
+
case 'marginRight': style.marginRight = value as string; break;
|
|
144
|
+
case 'position': style.position = value as React.CSSProperties['position']; break;
|
|
145
|
+
case 'background': style.background = value as string; break;
|
|
146
|
+
default: rest[key] = value; break;
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
return { style, rest };
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
export const Skeleton = React.forwardRef<HTMLDivElement, SkeletonProps>(
|
|
154
|
+
function Skeleton(props, ref) {
|
|
155
|
+
const {
|
|
156
|
+
loading = false,
|
|
157
|
+
asChild,
|
|
158
|
+
className,
|
|
159
|
+
children,
|
|
160
|
+
style: styleProp,
|
|
161
|
+
// Destructure style-prop shims so they don't leak into DOM
|
|
162
|
+
w: _w, h: _h, minW: _minW, maxW: _maxW, display: _display,
|
|
163
|
+
flexGrow: _flexGrow, flexShrink: _flexShrink, flexBasis: _flexBasis,
|
|
164
|
+
fontWeight: _fontWeight, textStyle: _textStyle, borderRadius: _borderRadius,
|
|
165
|
+
alignSelf: _alignSelf, alignItems: _alignItems, justifyContent: _justifyContent,
|
|
166
|
+
color: _color, mt: _mt, mb: _mb, ml: _ml, mr: _mr, height: _height,
|
|
167
|
+
overflow: _overflow, whiteSpace: _whiteSpace, textOverflow: _textOverflow,
|
|
168
|
+
textTransform: _textTransform, gap: _gap, gridTemplateColumns: _gridTemplateColumns,
|
|
169
|
+
minWidth: _minWidth, boxSize: _boxSize, py: _py, px: _px, p: _p,
|
|
170
|
+
hideBelow: _hideBelow, fontSize: _fontSize, flexWrap: _flexWrap, wordBreak: _wordBreak, lineHeight: _lineHeight,
|
|
171
|
+
marginRight: _marginRight, position: _position, background: _background,
|
|
172
|
+
as: Component = 'div',
|
|
173
|
+
...htmlRest
|
|
174
|
+
} = props;
|
|
175
|
+
|
|
176
|
+
// Collect legacy style props into a CSSProperties object
|
|
177
|
+
const { style: shimStyle } = extractSkeletonStyleProps({
|
|
178
|
+
w: _w, h: _h, minW: _minW, maxW: _maxW, display: _display,
|
|
179
|
+
flexGrow: _flexGrow, flexShrink: _flexShrink, flexBasis: _flexBasis,
|
|
180
|
+
fontWeight: _fontWeight, textStyle: _textStyle, borderRadius: _borderRadius,
|
|
181
|
+
alignSelf: _alignSelf, alignItems: _alignItems, justifyContent: _justifyContent,
|
|
182
|
+
color: _color, mt: _mt, mb: _mb, ml: _ml, mr: _mr, height: _height,
|
|
183
|
+
overflow: _overflow, whiteSpace: _whiteSpace, textOverflow: _textOverflow,
|
|
184
|
+
textTransform: _textTransform, gap: _gap, gridTemplateColumns: _gridTemplateColumns,
|
|
185
|
+
minWidth: _minWidth, boxSize: _boxSize, py: _py, px: _px, p: _p,
|
|
186
|
+
hideBelow: _hideBelow, fontSize: _fontSize, flexWrap: _flexWrap, wordBreak: _wordBreak, lineHeight: _lineHeight,
|
|
187
|
+
marginRight: _marginRight, position: _position, background: _background,
|
|
188
|
+
});
|
|
189
|
+
const mergedStyle = Object.keys(shimStyle).length > 0 || styleProp ?
|
|
190
|
+
{ ...shimStyle, ...styleProp } :
|
|
191
|
+
undefined;
|
|
192
|
+
|
|
193
|
+
const HIDE_BELOW_MAP: Record<string, string> = { lg: 'lg:hidden', md: 'md:hidden', sm: 'sm:hidden' };
|
|
194
|
+
const hideBelowClass = _hideBelow ? HIDE_BELOW_MAP[_hideBelow] : undefined;
|
|
195
|
+
const finalClassName = hideBelowClass ? cn(className, hideBelowClass) : className;
|
|
196
|
+
|
|
197
|
+
if (!loading) {
|
|
198
|
+
// When asChild is true, render children directly without a wrapper div
|
|
199
|
+
if (asChild && React.isValidElement(children)) {
|
|
200
|
+
return children;
|
|
201
|
+
}
|
|
202
|
+
return (
|
|
203
|
+
<Component ref={ ref } className={ finalClassName } style={ mergedStyle } { ...htmlRest }>
|
|
204
|
+
{ children }
|
|
205
|
+
</Component>
|
|
206
|
+
);
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
// When asChild is true and loading, wrap the child in skeleton styles
|
|
210
|
+
if (asChild && React.isValidElement(children)) {
|
|
211
|
+
return (
|
|
212
|
+
<Component
|
|
213
|
+
ref={ ref }
|
|
214
|
+
data-loading
|
|
215
|
+
className={ cn(
|
|
216
|
+
'animate-skeleton-shimmer rounded-sm',
|
|
217
|
+
'bg-[linear-gradient(90deg,var(--color-skeleton-start)_0%,var(--color-skeleton-end)_50%,var(--color-skeleton-start)_100%)]',
|
|
218
|
+
'bg-[length:200%_100%]',
|
|
219
|
+
'text-transparent [&_*]:invisible',
|
|
220
|
+
finalClassName,
|
|
221
|
+
) }
|
|
222
|
+
style={ mergedStyle }
|
|
223
|
+
{ ...htmlRest }
|
|
224
|
+
>
|
|
225
|
+
{ children }
|
|
226
|
+
</Component>
|
|
227
|
+
);
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
return (
|
|
231
|
+
<Component
|
|
232
|
+
ref={ ref }
|
|
233
|
+
data-loading
|
|
234
|
+
className={ cn(
|
|
235
|
+
'animate-skeleton-shimmer rounded-sm',
|
|
236
|
+
'bg-[linear-gradient(90deg,var(--color-skeleton-start)_0%,var(--color-skeleton-end)_50%,var(--color-skeleton-start)_100%)]',
|
|
237
|
+
'bg-[length:200%_100%]',
|
|
238
|
+
children ? 'text-transparent [&_*]:invisible' : 'min-h-5',
|
|
239
|
+
finalClassName,
|
|
240
|
+
) }
|
|
241
|
+
style={ mergedStyle }
|
|
242
|
+
{ ...htmlRest }
|
|
243
|
+
>
|
|
244
|
+
{ children }
|
|
245
|
+
</Component>
|
|
246
|
+
);
|
|
247
|
+
},
|
|
248
|
+
);
|
|
249
|
+
|
|
250
|
+
// ---------------------------------------------------------------------------
|
|
251
|
+
// SkeletonCircle
|
|
252
|
+
// ---------------------------------------------------------------------------
|
|
253
|
+
|
|
254
|
+
export interface SkeletonCircleProps extends React.HTMLAttributes<HTMLDivElement> {
|
|
255
|
+
readonly size?: string | number;
|
|
256
|
+
readonly loading?: boolean;
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
export const SkeletonCircle = React.forwardRef<HTMLDivElement, SkeletonCircleProps>(
|
|
260
|
+
function SkeletonCircle(props, ref) {
|
|
261
|
+
const { size = 40, loading = true, className, ...rest } = props;
|
|
262
|
+
|
|
263
|
+
const dimension = typeof size === 'number' ? `${ size }px` : size;
|
|
264
|
+
|
|
265
|
+
return (
|
|
266
|
+
<Skeleton
|
|
267
|
+
ref={ ref }
|
|
268
|
+
loading={ loading }
|
|
269
|
+
className={ cn('rounded-full shrink-0', className) }
|
|
270
|
+
style={{ width: dimension, height: dimension, ...rest.style }}
|
|
271
|
+
{ ...rest }
|
|
272
|
+
/>
|
|
273
|
+
);
|
|
274
|
+
},
|
|
275
|
+
);
|
|
276
|
+
|
|
277
|
+
// ---------------------------------------------------------------------------
|
|
278
|
+
// SkeletonText
|
|
279
|
+
// ---------------------------------------------------------------------------
|
|
280
|
+
|
|
281
|
+
export interface SkeletonTextProps extends React.HTMLAttributes<HTMLDivElement> {
|
|
282
|
+
readonly noOfLines?: number;
|
|
283
|
+
readonly loading?: boolean;
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
export const SkeletonText = React.forwardRef<HTMLDivElement, SkeletonTextProps>(
|
|
287
|
+
function SkeletonText(props, ref) {
|
|
288
|
+
const { noOfLines = 3, loading = true, className, ...rest } = props;
|
|
289
|
+
|
|
290
|
+
return (
|
|
291
|
+
<div ref={ ref } className={ cn('flex w-full flex-col gap-2', className) } { ...rest }>
|
|
292
|
+
{ Array.from({ length: noOfLines }).map((_, index) => (
|
|
293
|
+
<Skeleton
|
|
294
|
+
key={ index }
|
|
295
|
+
loading={ loading }
|
|
296
|
+
className={ cn('h-4', index === noOfLines - 1 && 'max-w-[80%]') }
|
|
297
|
+
/>
|
|
298
|
+
)) }
|
|
299
|
+
</div>
|
|
300
|
+
);
|
|
301
|
+
},
|
|
302
|
+
);
|
package/src/slider.tsx
ADDED
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
import * as RadixSlider from '@radix-ui/react-slider';
|
|
2
|
+
import * as React from 'react';
|
|
3
|
+
|
|
4
|
+
import { cn } from './utils';
|
|
5
|
+
|
|
6
|
+
export interface SliderProps {
|
|
7
|
+
readonly marks?: Array<number | { readonly value: number; readonly label: React.ReactNode }>;
|
|
8
|
+
readonly label?: React.ReactNode;
|
|
9
|
+
readonly showValue?: boolean;
|
|
10
|
+
readonly value?: Array<number>;
|
|
11
|
+
readonly defaultValue?: Array<number>;
|
|
12
|
+
readonly min?: number;
|
|
13
|
+
readonly max?: number;
|
|
14
|
+
readonly step?: number;
|
|
15
|
+
readonly disabled?: boolean;
|
|
16
|
+
readonly orientation?: 'horizontal' | 'vertical';
|
|
17
|
+
readonly name?: string;
|
|
18
|
+
readonly onValueChange?: (value: Array<number>) => void;
|
|
19
|
+
readonly onValueCommit?: (value: Array<number>) => void;
|
|
20
|
+
readonly className?: string;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
const THUMB_SIZE = 20;
|
|
24
|
+
const TRACK_HEIGHT = 6;
|
|
25
|
+
|
|
26
|
+
export const Slider = React.forwardRef<HTMLSpanElement, SliderProps>(
|
|
27
|
+
function Slider(props, ref) {
|
|
28
|
+
const {
|
|
29
|
+
marks: marksProp,
|
|
30
|
+
label,
|
|
31
|
+
showValue,
|
|
32
|
+
value,
|
|
33
|
+
defaultValue,
|
|
34
|
+
min = 0,
|
|
35
|
+
max = 100,
|
|
36
|
+
step,
|
|
37
|
+
disabled,
|
|
38
|
+
orientation,
|
|
39
|
+
name,
|
|
40
|
+
onValueChange,
|
|
41
|
+
onValueCommit,
|
|
42
|
+
className,
|
|
43
|
+
} = props;
|
|
44
|
+
|
|
45
|
+
const resolvedValue = defaultValue ?? value;
|
|
46
|
+
|
|
47
|
+
const marks = marksProp?.map((mark) => {
|
|
48
|
+
if (typeof mark === 'number') return { value: mark, label: undefined };
|
|
49
|
+
return mark;
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
const hasMarkLabel = Boolean(marks?.some((mark) => mark.label));
|
|
53
|
+
|
|
54
|
+
return (
|
|
55
|
+
<div className={ cn('flex flex-col gap-1', className) }>
|
|
56
|
+
{ label && !showValue && (
|
|
57
|
+
<label className="text-sm font-medium text-text-secondary">
|
|
58
|
+
{ label }
|
|
59
|
+
</label>
|
|
60
|
+
) }
|
|
61
|
+
{ label && showValue && (
|
|
62
|
+
<div className="flex items-center justify-between">
|
|
63
|
+
<label className="text-sm font-medium text-text-secondary">
|
|
64
|
+
{ label }
|
|
65
|
+
</label>
|
|
66
|
+
<span className="text-sm text-text-secondary">
|
|
67
|
+
{ (value ?? defaultValue ?? [])?.join(', ') }
|
|
68
|
+
</span>
|
|
69
|
+
</div>
|
|
70
|
+
) }
|
|
71
|
+
|
|
72
|
+
<RadixSlider.Root
|
|
73
|
+
ref={ ref }
|
|
74
|
+
className={ cn(
|
|
75
|
+
'relative flex w-full touch-none select-none items-center',
|
|
76
|
+
hasMarkLabel && 'mb-6',
|
|
77
|
+
) }
|
|
78
|
+
value={ value }
|
|
79
|
+
defaultValue={ defaultValue }
|
|
80
|
+
min={ min }
|
|
81
|
+
max={ max }
|
|
82
|
+
step={ step }
|
|
83
|
+
disabled={ disabled }
|
|
84
|
+
orientation={ orientation }
|
|
85
|
+
name={ name }
|
|
86
|
+
onValueChange={ onValueChange }
|
|
87
|
+
onValueCommit={ onValueCommit }
|
|
88
|
+
>
|
|
89
|
+
<RadixSlider.Track
|
|
90
|
+
className={ cn(
|
|
91
|
+
'relative grow rounded-full bg-border-divider',
|
|
92
|
+
`h-[${ TRACK_HEIGHT }px]`,
|
|
93
|
+
) }
|
|
94
|
+
>
|
|
95
|
+
<RadixSlider.Range className="absolute h-full rounded-full bg-link-primary"/>
|
|
96
|
+
</RadixSlider.Track>
|
|
97
|
+
|
|
98
|
+
{ resolvedValue?.map((_, index) => (
|
|
99
|
+
<RadixSlider.Thumb
|
|
100
|
+
key={ index }
|
|
101
|
+
className={ cn(
|
|
102
|
+
`block h-[${ THUMB_SIZE }px] w-[${ THUMB_SIZE }px]`,
|
|
103
|
+
'rounded-full border-2 border-link-primary bg-white',
|
|
104
|
+
'shadow-sm transition-colors',
|
|
105
|
+
'hover:border-link-primary-hover',
|
|
106
|
+
'focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-link-primary focus-visible:ring-offset-2',
|
|
107
|
+
'disabled:pointer-events-none disabled:opacity-50',
|
|
108
|
+
) }
|
|
109
|
+
/>
|
|
110
|
+
)) }
|
|
111
|
+
</RadixSlider.Root>
|
|
112
|
+
|
|
113
|
+
<SliderMarks marks={ marks } min={ min } max={ max }/>
|
|
114
|
+
</div>
|
|
115
|
+
);
|
|
116
|
+
},
|
|
117
|
+
);
|
|
118
|
+
|
|
119
|
+
interface SliderMarksProps {
|
|
120
|
+
readonly marks?: Array<{ readonly value: number; readonly label?: React.ReactNode }>;
|
|
121
|
+
readonly min: number;
|
|
122
|
+
readonly max: number;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
function SliderMarks(props: SliderMarksProps): React.ReactNode {
|
|
126
|
+
const { marks, min, max } = props;
|
|
127
|
+
if (!marks?.length) return null;
|
|
128
|
+
|
|
129
|
+
const range = max - min;
|
|
130
|
+
|
|
131
|
+
return (
|
|
132
|
+
<div className="relative w-full h-4">
|
|
133
|
+
{ marks.map((mark, index) => {
|
|
134
|
+
const percent = ((mark.value - min) / range) * 100;
|
|
135
|
+
return (
|
|
136
|
+
<div
|
|
137
|
+
key={ index }
|
|
138
|
+
className="absolute flex flex-col items-center -translate-x-1/2"
|
|
139
|
+
style={{ left: `${ percent }%` }}
|
|
140
|
+
>
|
|
141
|
+
<div className="h-1.5 w-0.5 bg-border-divider"/>
|
|
142
|
+
{ mark.label != null && (
|
|
143
|
+
<span className="mt-0.5 text-xs text-text-secondary whitespace-nowrap">
|
|
144
|
+
{ mark.label }
|
|
145
|
+
</span>
|
|
146
|
+
) }
|
|
147
|
+
</div>
|
|
148
|
+
);
|
|
149
|
+
}) }
|
|
150
|
+
</div>
|
|
151
|
+
);
|
|
152
|
+
}
|
package/src/switch.tsx
ADDED
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
import * as RadixSwitch from '@radix-ui/react-switch';
|
|
2
|
+
// chakra() HOC removed — pure Radix + Tailwind
|
|
3
|
+
import * as React from 'react';
|
|
4
|
+
|
|
5
|
+
import { cn } from './utils';
|
|
6
|
+
|
|
7
|
+
const NOOP = () => { /* noop */ };
|
|
8
|
+
|
|
9
|
+
// ─── Size mappings ────────────────────────────────────────────────────
|
|
10
|
+
const SIZE_CLASSES = {
|
|
11
|
+
sm: {
|
|
12
|
+
root: 'h-4 w-7',
|
|
13
|
+
thumb: 'h-3 w-3 data-[state=checked]:translate-x-3',
|
|
14
|
+
label: 'text-xs',
|
|
15
|
+
},
|
|
16
|
+
md: {
|
|
17
|
+
root: 'h-5 w-9',
|
|
18
|
+
thumb: 'h-4 w-4 data-[state=checked]:translate-x-4',
|
|
19
|
+
label: 'text-sm',
|
|
20
|
+
},
|
|
21
|
+
lg: {
|
|
22
|
+
root: 'h-6 w-11',
|
|
23
|
+
thumb: 'h-5 w-5 data-[state=checked]:translate-x-5',
|
|
24
|
+
label: 'text-base',
|
|
25
|
+
},
|
|
26
|
+
} as const;
|
|
27
|
+
|
|
28
|
+
// ─── Props ────────────────────────────────────────────────────────────
|
|
29
|
+
export interface SwitchProps extends Omit<React.ComponentPropsWithoutRef<'label'>, 'onChange' | 'dir'> {
|
|
30
|
+
inputProps?: React.InputHTMLAttributes<HTMLInputElement>;
|
|
31
|
+
labelProps?: React.ComponentPropsWithoutRef<'span'>;
|
|
32
|
+
rootRef?: React.Ref<HTMLLabelElement>;
|
|
33
|
+
trackLabel?: { on: React.ReactNode; off: React.ReactNode };
|
|
34
|
+
thumbLabel?: { on: React.ReactNode; off: React.ReactNode };
|
|
35
|
+
checked?: boolean;
|
|
36
|
+
defaultChecked?: boolean;
|
|
37
|
+
onCheckedChange?: (details: { checked: boolean }) => void;
|
|
38
|
+
onChange?: React.FormEventHandler<HTMLLabelElement>;
|
|
39
|
+
disabled?: boolean;
|
|
40
|
+
size?: 'sm' | 'md' | 'lg';
|
|
41
|
+
direction?: 'ltr' | 'rtl';
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
const SwitchBase = React.forwardRef<HTMLInputElement, SwitchProps>(
|
|
45
|
+
function Switch(props, ref) {
|
|
46
|
+
const {
|
|
47
|
+
inputProps,
|
|
48
|
+
children,
|
|
49
|
+
rootRef,
|
|
50
|
+
labelProps,
|
|
51
|
+
trackLabel,
|
|
52
|
+
thumbLabel,
|
|
53
|
+
checked: checkedProp,
|
|
54
|
+
defaultChecked,
|
|
55
|
+
onCheckedChange,
|
|
56
|
+
onChange,
|
|
57
|
+
disabled = false,
|
|
58
|
+
size = 'md',
|
|
59
|
+
direction,
|
|
60
|
+
className,
|
|
61
|
+
...rest
|
|
62
|
+
} = props;
|
|
63
|
+
|
|
64
|
+
const [ internalChecked, setInternalChecked ] = React.useState(defaultChecked ?? false);
|
|
65
|
+
|
|
66
|
+
const isControlled = checkedProp !== undefined;
|
|
67
|
+
const checkedState = isControlled ? checkedProp : internalChecked;
|
|
68
|
+
|
|
69
|
+
const handleCheckedChange = React.useCallback(
|
|
70
|
+
(nextChecked: boolean) => {
|
|
71
|
+
if (!isControlled) {
|
|
72
|
+
setInternalChecked(nextChecked);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
if (onCheckedChange) {
|
|
76
|
+
// Support both Chakra-style ({ checked }) and Radix-style (checked) signatures.
|
|
77
|
+
// We call with a single object arg; if the consumer ignores it, that's fine.
|
|
78
|
+
(onCheckedChange as (details: { checked: boolean }) => void)({ checked: nextChecked });
|
|
79
|
+
}
|
|
80
|
+
},
|
|
81
|
+
[ isControlled, onCheckedChange ],
|
|
82
|
+
);
|
|
83
|
+
|
|
84
|
+
const sizeClasses = SIZE_CLASSES[size];
|
|
85
|
+
const isRtl = direction === 'rtl';
|
|
86
|
+
|
|
87
|
+
return (
|
|
88
|
+
<label
|
|
89
|
+
ref={ rootRef }
|
|
90
|
+
className={ cn(
|
|
91
|
+
'inline-flex items-center cursor-pointer select-none gap-2',
|
|
92
|
+
isRtl && 'flex-row-reverse',
|
|
93
|
+
disabled && 'opacity-50 cursor-not-allowed',
|
|
94
|
+
className,
|
|
95
|
+
) }
|
|
96
|
+
onChange={ onChange }
|
|
97
|
+
data-disabled={ disabled || undefined }
|
|
98
|
+
{ ...rest }
|
|
99
|
+
>
|
|
100
|
+
<RadixSwitch.Root
|
|
101
|
+
checked={ checkedState }
|
|
102
|
+
onCheckedChange={ handleCheckedChange }
|
|
103
|
+
disabled={ disabled }
|
|
104
|
+
className={ cn(
|
|
105
|
+
'relative inline-flex shrink-0 items-center rounded-full',
|
|
106
|
+
'bg-gray-300 dark:bg-gray-600',
|
|
107
|
+
'data-[state=checked]:bg-gray-800 dark:bg-white',
|
|
108
|
+
'focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-gray-500',
|
|
109
|
+
'transition-colors duration-200',
|
|
110
|
+
sizeClasses.root,
|
|
111
|
+
) }
|
|
112
|
+
>
|
|
113
|
+
{ trackLabel && (
|
|
114
|
+
<span className="absolute inset-0 flex items-center justify-center text-[8px] font-bold text-white pointer-events-none">
|
|
115
|
+
{ checkedState ? trackLabel.on : trackLabel.off }
|
|
116
|
+
</span>
|
|
117
|
+
) }
|
|
118
|
+
<RadixSwitch.Thumb
|
|
119
|
+
className={ cn(
|
|
120
|
+
'block rounded-full bg-white shadow-sm',
|
|
121
|
+
'transition-transform duration-200',
|
|
122
|
+
'translate-x-0.5',
|
|
123
|
+
sizeClasses.thumb,
|
|
124
|
+
) }
|
|
125
|
+
>
|
|
126
|
+
{ thumbLabel && (
|
|
127
|
+
<span className="flex items-center justify-center h-full w-full text-[8px]">
|
|
128
|
+
{ checkedState ? thumbLabel.on : thumbLabel.off }
|
|
129
|
+
</span>
|
|
130
|
+
) }
|
|
131
|
+
</RadixSwitch.Thumb>
|
|
132
|
+
</RadixSwitch.Root>
|
|
133
|
+
{ /* Hidden native input for form compat and ref forwarding */ }
|
|
134
|
+
<input
|
|
135
|
+
ref={ ref }
|
|
136
|
+
type="checkbox"
|
|
137
|
+
className="sr-only"
|
|
138
|
+
checked={ checkedState }
|
|
139
|
+
disabled={ disabled }
|
|
140
|
+
tabIndex={ -1 }
|
|
141
|
+
aria-hidden
|
|
142
|
+
onChange={ NOOP }
|
|
143
|
+
{ ...inputProps }
|
|
144
|
+
/>
|
|
145
|
+
{ children != null && (
|
|
146
|
+
<span
|
|
147
|
+
{ ...labelProps }
|
|
148
|
+
className={ cn(sizeClasses.label, labelProps?.className) }
|
|
149
|
+
>
|
|
150
|
+
{ children }
|
|
151
|
+
</span>
|
|
152
|
+
) }
|
|
153
|
+
</label>
|
|
154
|
+
);
|
|
155
|
+
},
|
|
156
|
+
);
|
|
157
|
+
|
|
158
|
+
export const Switch = SwitchBase;
|