softable-pixels-web 1.0.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/README.md ADDED
@@ -0,0 +1,22 @@
1
+ # pixel-tw
2
+ Reusable React component library with Tailwind-based UI components and utility tools for handling dates and data.
3
+
4
+ ## Installation
5
+
6
+ ```bash
7
+ yarn add softable-pixel
8
+ # or
9
+ npm install softable-pixel
10
+ ```
11
+
12
+ ## Components
13
+
14
+ ## Build
15
+
16
+ After cloning the repository, run:
17
+
18
+ ```bash
19
+ yarn build
20
+ ```
21
+
22
+ This compiles the components to the `dist` directory
@@ -0,0 +1,304 @@
1
+ import { useMemo } from "react";
2
+ import { motion } from "framer-motion";
3
+ import { jsx, jsxs } from "react/jsx-runtime";
4
+
5
+ //#region src/hooks/useThemedStyles/utils/resolveCommonStyleProps.ts
6
+ function toCss(v) {
7
+ return typeof v === "number" ? `${v}px` : v;
8
+ }
9
+ /**
10
+ * Source of truth: common prop -> how it maps into CSSProperties.
11
+ * Add new common props ONLY here.
12
+ */
13
+ const COMMON_MAP = {
14
+ m: (v, o) => {
15
+ o.margin = toCss(v);
16
+ },
17
+ mx: (v, o) => {
18
+ o.marginLeft = toCss(v);
19
+ o.marginRight = toCss(v);
20
+ },
21
+ my: (v, o) => {
22
+ o.marginTop = toCss(v);
23
+ o.marginBottom = toCss(v);
24
+ },
25
+ mt: (v, o) => {
26
+ o.marginTop = toCss(v);
27
+ },
28
+ mr: (v, o) => {
29
+ o.marginRight = toCss(v);
30
+ },
31
+ mb: (v, o) => {
32
+ o.marginBottom = toCss(v);
33
+ },
34
+ ml: (v, o) => {
35
+ o.marginLeft = toCss(v);
36
+ },
37
+ p: (v, o) => {
38
+ o.padding = toCss(v);
39
+ },
40
+ px: (v, o) => {
41
+ o.paddingLeft = toCss(v);
42
+ o.paddingRight = toCss(v);
43
+ },
44
+ py: (v, o) => {
45
+ o.paddingTop = toCss(v);
46
+ o.paddingBottom = toCss(v);
47
+ },
48
+ pt: (v, o) => {
49
+ o.paddingTop = toCss(v);
50
+ },
51
+ pr: (v, o) => {
52
+ o.paddingRight = toCss(v);
53
+ },
54
+ pb: (v, o) => {
55
+ o.paddingBottom = toCss(v);
56
+ },
57
+ pl: (v, o) => {
58
+ o.paddingLeft = toCss(v);
59
+ },
60
+ fontSize: (v, o) => {
61
+ o.fontSize = toCss(v);
62
+ },
63
+ fontWeight: (v, o) => {
64
+ o.fontWeight = v;
65
+ },
66
+ lineHeight: (v, o) => {
67
+ o.lineHeight = toCss(v);
68
+ },
69
+ textAlign: (v, o) => {
70
+ o.textAlign = v;
71
+ },
72
+ w: (v, o) => {
73
+ o.width = toCss(v);
74
+ },
75
+ h: (v, o) => {
76
+ o.height = toCss(v);
77
+ },
78
+ minW: (v, o) => {
79
+ o.minWidth = toCss(v);
80
+ },
81
+ maxW: (v, o) => {
82
+ o.maxWidth = toCss(v);
83
+ },
84
+ minH: (v, o) => {
85
+ o.minHeight = toCss(v);
86
+ },
87
+ maxH: (v, o) => {
88
+ o.maxHeight = toCss(v);
89
+ }
90
+ };
91
+ const COMMON_KEYS = Object.keys(COMMON_MAP);
92
+ function hasAnyCommonStyleProps(props) {
93
+ for (const k of COMMON_KEYS) if (props[k] != null) return true;
94
+ return false;
95
+ }
96
+ function resolveCommonStyleProps(props) {
97
+ const out = {};
98
+ for (const k of COMMON_KEYS) {
99
+ const value = props[k];
100
+ if (value != null) COMMON_MAP[k](value, out);
101
+ }
102
+ return out;
103
+ }
104
+
105
+ //#endregion
106
+ //#region src/hooks/useThemedStyles/utils/stripCommonProps.ts
107
+ const COMMON_KEY_SET = new Set(COMMON_KEYS);
108
+
109
+ //#endregion
110
+ //#region src/hooks/useThemedStyles/index.ts
111
+ /** biome-ignore-all lint/suspicious/noExplicitAny: <Not needed> */
112
+ /**
113
+ * Shallow-merge style maps slot-by-slot.
114
+ * - warns when override contains unknown slots (dev UX)
115
+ * - merges each slot object shallowly
116
+ */
117
+ function mergeStyleMaps(base, override) {
118
+ if (!override) return base;
119
+ const out = { ...base };
120
+ for (const key in override) {
121
+ if (!(key in base)) console.warn(`[useThemedStyles] Unknown style slot "${key}". Available slots: ${Object.keys(base).join(", ")}`);
122
+ out[key] = {
123
+ ...base[key] ?? {},
124
+ ...override[key] ?? {}
125
+ };
126
+ }
127
+ return out;
128
+ }
129
+ /**
130
+ * Applies common style props (if present) to a chosen slot of the styles map.
131
+ * Common props are resolved by `resolveCommonStyleProps`.
132
+ */
133
+ function applyCommonsToStyles(styles, props, slotOverride) {
134
+ if (!hasAnyCommonStyleProps(props)) return styles;
135
+ const keys = Object.keys(styles);
136
+ if (keys.length === 0) return styles;
137
+ const slot = slotOverride ?? ("container" in styles ? "container" : keys[0]);
138
+ const common = resolveCommonStyleProps(props);
139
+ return {
140
+ ...styles,
141
+ [slot]: {
142
+ ...styles[slot] ?? {},
143
+ ...common
144
+ }
145
+ };
146
+ }
147
+ /**
148
+ * useThemedStyles
149
+ *
150
+ * React-Native-like style factory hook for React web.
151
+ *
152
+ * Features:
153
+ * - Slot-based styles: factory returns { container, text, icon, ... }
154
+ * - Memoization control: `deps` > `pick(props)` > `[props]`
155
+ * - Optional per-slot overrides for customization
156
+ * - Optional auto-application of "common style props"
157
+ * - Supports CSS variables in inline styles
158
+ *
159
+ * Typical usage:
160
+ * @example
161
+ * const styles = useThemedStyles(props, createButtonStyles, {
162
+ * pick: pickButtonStyleProps,
163
+ * override: props.styles,
164
+ * applyCommonProps: true,
165
+ * });
166
+ *
167
+ * return (
168
+ * <button style={styles.container}>
169
+ * <span style={styles.text}>Hello</span>
170
+ * </button>
171
+ * );
172
+ */
173
+ function useThemedStyles(props, factory, options) {
174
+ const base = useMemo(() => factory(props), [factory, ...options?.deps ?? (options?.pick ? options.pick(props) : [props])]);
175
+ const merged = useMemo(() => mergeStyleMaps(base, options?.override), [base, options?.override]);
176
+ return useMemo(() => {
177
+ if (!options?.applyCommonProps) return merged;
178
+ return applyCommonsToStyles(merged, props, options.commonSlot);
179
+ }, [
180
+ merged,
181
+ props,
182
+ options?.applyCommonProps,
183
+ options?.commonSlot
184
+ ]);
185
+ }
186
+
187
+ //#endregion
188
+ //#region src/components/toolkit/TabSwitch/components/TabSwitchItem/styles.ts
189
+ function createTabSwitchItemStyles({ variant, disabled, selected, selectedColor, selectedLabelColor }) {
190
+ const labelColor = selected ? selectedLabelColor ?? "var(--px-text-primary)" : "var(--px-text-secondary)";
191
+ const accent = selectedColor ?? "var(--px-color-primary)";
192
+ return {
193
+ item: {
194
+ position: "relative",
195
+ display: "inline-flex",
196
+ alignItems: "center",
197
+ justifyContent: "center",
198
+ gap: 4,
199
+ background: "transparent",
200
+ border: 0,
201
+ padding: "8px 10px",
202
+ cursor: disabled ? "not-allowed" : "pointer",
203
+ opacity: disabled ? .5 : 1,
204
+ userSelect: "none",
205
+ whiteSpace: "nowrap"
206
+ },
207
+ label: {
208
+ zIndex: 1,
209
+ fontSize: 14,
210
+ fontWeight: 700,
211
+ color: labelColor
212
+ },
213
+ selectedBg: variant === "default" ? {
214
+ position: "absolute",
215
+ inset: 0,
216
+ borderRadius: 6,
217
+ border: "1px solid var(--px-border-primary)",
218
+ background: selected ? accent : "transparent"
219
+ } : {
220
+ position: "absolute",
221
+ left: 0,
222
+ right: 0,
223
+ bottom: -2,
224
+ height: 2,
225
+ background: selected ? accent : "transparent"
226
+ }
227
+ };
228
+ }
229
+
230
+ //#endregion
231
+ //#region src/components/toolkit/TabSwitch/components/TabSwitchItem/index.tsx
232
+ function SwitchItem(props) {
233
+ const { option, disabled, selected, layoutId, onClick } = props;
234
+ const styles = useThemedStyles(props, createTabSwitchItemStyles, { pick: (p) => [
235
+ p.variant,
236
+ p.selectedColor,
237
+ p.selected
238
+ ] });
239
+ const isDisabled = disabled || option.disabled;
240
+ return /* @__PURE__ */ jsxs("button", {
241
+ type: "button",
242
+ style: styles.item,
243
+ tabIndex: isDisabled ? -1 : 0,
244
+ onClick: () => !isDisabled && onClick(option.value),
245
+ children: [
246
+ selected ? /* @__PURE__ */ jsx(motion.div, {
247
+ layoutId: layoutId || "pixel-tabswitch-selected",
248
+ style: styles.selectedBg
249
+ }) : null,
250
+ option.icon ? /* @__PURE__ */ jsx("span", {
251
+ style: { display: "inline-flex" },
252
+ children: option.icon
253
+ }) : null,
254
+ /* @__PURE__ */ jsx("span", {
255
+ style: styles.label,
256
+ children: option.label
257
+ })
258
+ ]
259
+ });
260
+ }
261
+
262
+ //#endregion
263
+ //#region src/components/toolkit/TabSwitch/styles.ts
264
+ function createTabSwitchStyles(props) {
265
+ const { fitContent } = props;
266
+ return { container: {
267
+ display: "flex",
268
+ flexDirection: "row",
269
+ alignItems: "center",
270
+ width: fitContent ? "fit-content" : "100%",
271
+ borderBottom: "1px solid var(--pixel-border, #e5e7eb)",
272
+ gap: 0
273
+ } };
274
+ }
275
+
276
+ //#endregion
277
+ //#region src/components/toolkit/TabSwitch/index.tsx
278
+ function TabSwitch(props) {
279
+ const { options, disabled, layoutId, currentValue, variant = "default", onChange } = props;
280
+ return /* @__PURE__ */ jsx("div", {
281
+ style: useThemedStyles(props, createTabSwitchStyles, {
282
+ pick: (p) => [
283
+ p.fitContent,
284
+ p.selectedLabelColor,
285
+ p.variant
286
+ ],
287
+ override: props.styles,
288
+ applyCommonProps: true
289
+ }).container,
290
+ children: options.map((opt) => /* @__PURE__ */ jsx(SwitchItem, {
291
+ option: opt,
292
+ variant,
293
+ layoutId,
294
+ disabled,
295
+ selected: currentValue === opt.value,
296
+ selectedColor: props.selectedLabelColor,
297
+ onClick: onChange
298
+ }, String(opt.value)))
299
+ });
300
+ }
301
+
302
+ //#endregion
303
+ export { TabSwitch as t };
304
+ //# sourceMappingURL=TabSwitch-D6OPAUjC.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TabSwitch-D6OPAUjC.js","names":["COMMON_MAP: Record<\n keyof CommonStyleProps,\n (value: any, out: React.CSSProperties) => void\n>","out: React.CSSProperties"],"sources":["../src/hooks/useThemedStyles/utils/resolveCommonStyleProps.ts","../src/hooks/useThemedStyles/utils/stripCommonProps.ts","../src/hooks/useThemedStyles/index.ts","../src/components/toolkit/TabSwitch/components/TabSwitchItem/styles.ts","../src/components/toolkit/TabSwitch/components/TabSwitchItem/index.tsx","../src/components/toolkit/TabSwitch/styles.ts","../src/components/toolkit/TabSwitch/index.tsx"],"sourcesContent":["/** biome-ignore-all lint/suspicious/noExplicitAny: <Not needed> */\n\n// Types\nimport type { CommonStyleProps } from '../types'\n\nfunction toCss(v: number | string | undefined) {\n return typeof v === 'number' ? `${v}px` : v\n}\n\n/**\n * Source of truth: common prop -> how it maps into CSSProperties.\n * Add new common props ONLY here.\n */\nconst COMMON_MAP: Record<\n keyof CommonStyleProps,\n (value: any, out: React.CSSProperties) => void\n> = {\n // margin\n m: (v, o) => {\n o.margin = toCss(v)\n },\n mx: (v, o) => {\n o.marginLeft = toCss(v)\n o.marginRight = toCss(v)\n },\n my: (v, o) => {\n o.marginTop = toCss(v)\n o.marginBottom = toCss(v)\n },\n mt: (v, o) => {\n o.marginTop = toCss(v)\n },\n mr: (v, o) => {\n o.marginRight = toCss(v)\n },\n mb: (v, o) => {\n o.marginBottom = toCss(v)\n },\n ml: (v, o) => {\n o.marginLeft = toCss(v)\n },\n\n // padding\n p: (v, o) => {\n o.padding = toCss(v)\n },\n px: (v, o) => {\n o.paddingLeft = toCss(v)\n o.paddingRight = toCss(v)\n },\n py: (v, o) => {\n o.paddingTop = toCss(v)\n o.paddingBottom = toCss(v)\n },\n pt: (v, o) => {\n o.paddingTop = toCss(v)\n },\n pr: (v, o) => {\n o.paddingRight = toCss(v)\n },\n pb: (v, o) => {\n o.paddingBottom = toCss(v)\n },\n pl: (v, o) => {\n o.paddingLeft = toCss(v)\n },\n\n // text\n fontSize: (v, o) => {\n o.fontSize = toCss(v)\n },\n fontWeight: (v, o) => {\n o.fontWeight = v\n },\n lineHeight: (v, o) => {\n o.lineHeight = toCss(v)\n },\n textAlign: (v, o) => {\n o.textAlign = v\n },\n\n // layout\n w: (v, o) => {\n o.width = toCss(v)\n },\n h: (v, o) => {\n o.height = toCss(v)\n },\n minW: (v, o) => {\n o.minWidth = toCss(v)\n },\n maxW: (v, o) => {\n o.maxWidth = toCss(v)\n },\n minH: (v, o) => {\n o.minHeight = toCss(v)\n },\n maxH: (v, o) => {\n o.maxHeight = toCss(v)\n }\n}\n\nexport const COMMON_KEYS = Object.keys(COMMON_MAP) as Array<\n keyof CommonStyleProps\n>\n\nexport function hasAnyCommonStyleProps(props: Partial<CommonStyleProps>) {\n for (const k of COMMON_KEYS) {\n if (props[k] != null) return true\n }\n return false\n}\n\nexport function resolveCommonStyleProps(\n props: Partial<CommonStyleProps>\n): React.CSSProperties {\n const out: React.CSSProperties = {}\n\n for (const k of COMMON_KEYS) {\n const value = props[k]\n if (value != null) COMMON_MAP[k](value, out)\n }\n\n return out\n}\n","/** biome-ignore-all lint/suspicious/noExplicitAny: <Not needed> */\n\nimport type { CommonStyleProps } from '../types'\n\nimport { COMMON_KEYS } from './resolveCommonStyleProps'\n\nconst COMMON_KEY_SET = new Set<string>(COMMON_KEYS as readonly string[])\n\nexport function stripCommonProps<T extends object>(\n props: T\n): Omit<T, keyof CommonStyleProps> {\n const out: Record<string, unknown> = {}\n\n for (const key of Object.keys(props as any)) {\n if (!COMMON_KEY_SET.has(key)) {\n out[key] = (props as any)[key]\n }\n }\n\n return out as Omit<T, keyof CommonStyleProps>\n}\n","/** biome-ignore-all lint/suspicious/noExplicitAny: <Not needed> */\n\n// External Libraries\nimport { useMemo } from 'react'\n\n// Utils\nimport { hasAnyCommonStyleProps, resolveCommonStyleProps } from './utils'\n\n// Types\nimport type { CommonStyleProps } from './types'\n\n/**\n * Allows CSS Variables to be used in inline styles:\n * { \"--btn-bg\": \"#111\" }\n */\nexport type CSSVars = React.CSSProperties &\n Record<`--${string}`, string | number>\n\n/** A style object can be regular CSSProperties or CSSProperties + CSS Variables */\nexport type StyleObject = React.CSSProperties | CSSVars\n\n/**\n * Map of \"slots\" to style objects.\n * Example slots: { container, text, icon }\n */\nexport type StyleMap = Record<string, StyleObject>\n\n/**\n * A style factory receives component props and returns a map of slot styles.\n */\nexport type StylesFactory<TProps, TStyles extends StyleMap> = (\n props: TProps\n) => TStyles\n\nexport type UseThemedStylesOptions<TProps, TStyles extends StyleMap> = {\n /**\n * Optional optimization.\n * When provided, the hook memoizes using the returned values instead of depending\n * on the entire `props` object reference.\n *\n * Recommended pattern: create a `pickXStyleProps` per component.\n *\n * @example\n * pick: (p) => [p.variant, p.size, p.disabled, p.color]\n */\n pick?: (props: TProps) => readonly unknown[]\n\n /**\n * Optional manual dependencies (highest priority).\n * If provided, `deps` is used instead of `pick` or `props`.\n *\n * Use this if you want full control over memoization.\n */\n deps?: readonly unknown[]\n\n /**\n * Optional per-slot override. Useful to allow consumers to tweak styles\n * without creating wrapper components or duplicating the style factory.\n *\n * The override is shallow-merged per slot:\n * mergedSlot = { ...baseSlot, ...overrideSlot }\n *\n * @example\n * override: { container: { padding: \"0 24px\" } }\n */\n override?: Partial<TStyles>\n\n /**\n * When true, reads \"common style props\" from `props` (spacing, layout, typography...)\n * and applies them on top of the chosen slot (default: \"container\").\n *\n * This enables a consistent set of props like `px`, `mt`, `fontSize`, `w`, etc.\n * across multiple components.\n *\n * NOTE: You'll typically also want to remove these props before spreading props\n * to DOM elements (to avoid invalid attributes). Use a `stripCommonProps`/`splitProps`\n * helper for that.\n */\n applyCommonProps?: boolean\n\n /**\n * Where to apply common style props.\n * Defaults to:\n * - \"container\" if that slot exists\n * - otherwise the first slot key returned by the style factory\n */\n commonSlot?: keyof TStyles\n}\n\n/**\n * Shallow-merge style maps slot-by-slot.\n * - warns when override contains unknown slots (dev UX)\n * - merges each slot object shallowly\n */\nfunction mergeStyleMaps<T extends StyleMap>(base: T, override?: Partial<T>): T {\n if (!override) return base\n const out = { ...base } as T\n\n for (const key in override) {\n if (!(key in base)) {\n console.warn(\n `[useThemedStyles] Unknown style slot \"${key}\". Available slots: ${Object.keys(base).join(', ')}`\n )\n }\n\n out[key] = { ...(base[key] ?? {}), ...(override[key] ?? {}) } as any\n }\n return out\n}\n\n/**\n * Applies common style props (if present) to a chosen slot of the styles map.\n * Common props are resolved by `resolveCommonStyleProps`.\n */\nfunction applyCommonsToStyles<TStyles extends StyleMap>(\n styles: TStyles,\n props: Partial<CommonStyleProps>,\n slotOverride?: keyof TStyles\n): TStyles {\n if (!hasAnyCommonStyleProps(props)) return styles\n\n const keys = Object.keys(styles)\n if (keys.length === 0) return styles\n\n const slot =\n slotOverride ??\n (('container' in styles ? 'container' : keys[0]) as keyof TStyles)\n\n const common = resolveCommonStyleProps(props)\n\n return {\n ...styles,\n [slot]: { ...(styles[slot] ?? {}), ...common }\n } as TStyles\n}\n\n/**\n * useThemedStyles\n *\n * React-Native-like style factory hook for React web.\n *\n * Features:\n * - Slot-based styles: factory returns { container, text, icon, ... }\n * - Memoization control: `deps` > `pick(props)` > `[props]`\n * - Optional per-slot overrides for customization\n * - Optional auto-application of \"common style props\"\n * - Supports CSS variables in inline styles\n *\n * Typical usage:\n * @example\n * const styles = useThemedStyles(props, createButtonStyles, {\n * pick: pickButtonStyleProps,\n * override: props.styles,\n * applyCommonProps: true,\n * });\n *\n * return (\n * <button style={styles.container}>\n * <span style={styles.text}>Hello</span>\n * </button>\n * );\n */\nexport function useThemedStyles<TProps, TStyles extends StyleMap>(\n props: TProps,\n factory: StylesFactory<TProps, TStyles>,\n options?: UseThemedStylesOptions<TProps, TStyles>\n): TStyles {\n // Memoization priority:\n // 1) deps (manual)\n // 2) pick(props) (recommended)\n // 3) props reference (default behavior)\n const memoKey =\n options?.deps ?? (options?.pick ? options.pick(props) : [props])\n\n // biome-ignore lint/correctness/useExhaustiveDependencies: deps are intentionally controlled by the hook API (optional `deps`)\n const base = useMemo(() => factory(props), [factory, ...memoKey])\n\n // Apply per-slot overrides (if any)\n const merged = useMemo(\n () => mergeStyleMaps(base, options?.override),\n [base, options?.override]\n )\n\n // Optionally apply common style props on top of a slot\n const withCommons = useMemo(() => {\n if (!options?.applyCommonProps) return merged\n return applyCommonsToStyles(merged, props as any, options.commonSlot)\n }, [merged, props, options?.applyCommonProps, options?.commonSlot])\n\n return withCommons\n}\n","// External Libraries\nimport type { CSSProperties } from 'react'\n\ninterface Params {\n disabled?: boolean\n selected?: boolean\n selectedColor?: string\n variant: 'default' | 'underline'\n selectedLabelColor?: string\n}\n\nexport function createTabSwitchItemStyles({\n variant,\n disabled,\n selected,\n selectedColor,\n selectedLabelColor\n}: Params) {\n const labelColor = selected\n ? (selectedLabelColor ?? 'var(--px-text-primary)')\n : 'var(--px-text-secondary)'\n\n const accent = selectedColor ?? 'var(--px-color-primary)'\n\n return {\n item: {\n position: 'relative',\n display: 'inline-flex',\n alignItems: 'center',\n justifyContent: 'center',\n gap: 4,\n background: 'transparent',\n border: 0,\n padding: '8px 10px',\n cursor: disabled ? 'not-allowed' : 'pointer',\n opacity: disabled ? 0.5 : 1,\n userSelect: 'none',\n whiteSpace: 'nowrap'\n } as CSSProperties,\n\n label: {\n zIndex: 1,\n fontSize: 14,\n fontWeight: 700,\n color: labelColor\n } as CSSProperties,\n\n selectedBg:\n variant === 'default'\n ? ({\n position: 'absolute',\n inset: 0,\n borderRadius: 6,\n border: '1px solid var(--px-border-primary)',\n background: selected ? accent : 'transparent'\n } as CSSProperties)\n : ({\n position: 'absolute',\n left: 0,\n right: 0,\n bottom: -2,\n height: 2,\n background: selected ? accent : 'transparent'\n } as CSSProperties)\n }\n}\n","// External Libraries\nimport { motion } from 'framer-motion'\n\n// Types\nimport type { SwitchOption } from '../../types'\nimport { useThemedStyles } from '@hooks/useThemedStyles'\nimport { createTabSwitchItemStyles } from './styles'\n\ntype Props<T> = {\n option: SwitchOption<T>\n selected: boolean\n disabled?: boolean\n layoutId?: string\n selectedColor?: string\n variant: 'default' | 'underline'\n onClick: (value: T) => void\n}\n\nexport function SwitchItem<T>(props: Props<T>) {\n const { option, disabled, selected, layoutId, onClick } = props\n\n const styles = useThemedStyles(props, createTabSwitchItemStyles, {\n pick: p => [p.variant, p.selectedColor, p.selected]\n })\n\n const isDisabled = disabled || option.disabled\n\n return (\n <button\n type=\"button\"\n style={styles.item}\n tabIndex={isDisabled ? -1 : 0}\n onClick={() => !isDisabled && onClick(option.value)}\n >\n {selected ? (\n <motion.div\n layoutId={layoutId || 'pixel-tabswitch-selected'}\n style={styles.selectedBg}\n />\n ) : null}\n\n {option.icon ? (\n <span style={{ display: 'inline-flex' }}>{option.icon}</span>\n ) : null}\n\n <span style={styles.label}>{option.label}</span>\n </button>\n )\n}\n","// External Libraries\nimport type { CSSProperties } from 'react'\n\nimport type { TabSwitchProps } from './types'\n\nexport function createTabSwitchStyles<T>(props: TabSwitchProps<T>) {\n const { fitContent } = props\n\n return {\n container: {\n display: 'flex',\n flexDirection: 'row',\n alignItems: 'center',\n width: fitContent ? 'fit-content' : '100%',\n borderBottom: '1px solid var(--pixel-border, #e5e7eb)',\n gap: 0\n } as CSSProperties\n }\n}\n","// Hooks\nimport { useThemedStyles } from '@hooks/useThemedStyles'\n\n// Components\nimport { SwitchItem } from './components/TabSwitchItem'\n\n// Types\nimport type { TabSwitchProps } from './types'\n\n// Styles\nimport { createTabSwitchStyles } from './styles'\n\nexport * from './types'\n\nexport function TabSwitch<T>(props: TabSwitchProps<T>) {\n const {\n options,\n disabled,\n layoutId,\n currentValue,\n variant = 'default',\n onChange\n } = props\n\n const styles = useThemedStyles(props, createTabSwitchStyles, {\n pick: p => [p.fitContent, p.selectedLabelColor, p.variant],\n override: props.styles,\n applyCommonProps: true\n })\n\n return (\n <div style={styles.container}>\n {options.map(opt => (\n <SwitchItem\n key={String(opt.value)}\n option={opt}\n variant={variant}\n layoutId={layoutId}\n disabled={disabled}\n selected={currentValue === opt.value}\n selectedColor={props.selectedLabelColor}\n onClick={onChange}\n />\n ))}\n </div>\n )\n}\n"],"mappings":"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"}