@noya-app/noya-designsystem 0.1.37 → 0.1.38
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/.turbo/turbo-build.log +10 -10
- package/CHANGELOG.md +6 -0
- package/dist/index.css +1 -1
- package/dist/index.d.mts +343 -23
- package/dist/index.d.ts +343 -23
- package/dist/index.js +396 -128
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +400 -129
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
- package/src/components/Button.tsx +1 -1
- package/src/components/Checkbox.tsx +2 -0
- package/src/components/Chip.tsx +15 -8
- package/src/components/DraggableMenuButton.tsx +3 -2
- package/src/components/FillPreviewBackground.tsx +10 -9
- package/src/components/FloatingWindow.tsx +5 -6
- package/src/components/IconButton.tsx +5 -1
- package/src/components/InputField.tsx +95 -68
- package/src/components/InspectorContainer.tsx +2 -2
- package/src/components/InspectorPrimitives.tsx +19 -9
- package/src/components/Label.tsx +1 -1
- package/src/components/ListView.tsx +19 -32
- package/src/components/RadioGroup.tsx +1 -1
- package/src/components/SelectMenu.tsx +3 -3
- package/src/components/Switch.tsx +1 -1
- package/src/components/Text.tsx +20 -7
- package/src/components/TextArea.tsx +1 -1
- package/src/components/Tooltip.tsx +1 -1
- package/src/components/WorkspaceLayout.tsx +4 -3
- package/src/components/internal/TextInput.tsx +1 -0
- package/src/index.css +12 -2
- package/src/index.tsx +0 -1
- package/src/theme/index.ts +6 -3
- package/src/theme/themeUtils.ts +72 -0
- package/src/utils/tailwind.ts +4 -12
- package/tailwind.config.ts +16 -3
|
@@ -24,6 +24,7 @@ import { WindowScroller, WindowScrollerChildProps } from "react-virtualized";
|
|
|
24
24
|
import { ListChildComponentProps, VariableSizeList } from "react-window";
|
|
25
25
|
import { mergeEventHandlers } from "../hooks/mergeEventHandlers";
|
|
26
26
|
import { useHover } from "../hooks/useHover";
|
|
27
|
+
import { cssVars } from "../theme";
|
|
27
28
|
import { ContextMenu } from "./ContextMenu";
|
|
28
29
|
import { InputField, InputFieldInputProps } from "./InputField";
|
|
29
30
|
import { MenuItem } from "./internal/Menu";
|
|
@@ -180,22 +181,6 @@ function getPositionMargin(marginType: ListRowMarginType) {
|
|
|
180
181
|
* Row
|
|
181
182
|
* ------------------------------------------------------------------------- */
|
|
182
183
|
|
|
183
|
-
const theme = {
|
|
184
|
-
colors: {
|
|
185
|
-
textMuted: "var(--text-muted)",
|
|
186
|
-
listView: {
|
|
187
|
-
raisedBackground: "var(--listview-raised-background)",
|
|
188
|
-
},
|
|
189
|
-
secondary: "var(--secondary)",
|
|
190
|
-
primary: "var(--primary)",
|
|
191
|
-
textDisabled: "var(--text-disabled)",
|
|
192
|
-
primaryLight: "var(--primary-light)",
|
|
193
|
-
secondaryLight: "var(--secondary-light)",
|
|
194
|
-
activeBackground: "var(--active-background)",
|
|
195
|
-
dividerSubtle: "var(--divider-subtle)",
|
|
196
|
-
},
|
|
197
|
-
};
|
|
198
|
-
|
|
199
184
|
const RowContainer = forwardRef<
|
|
200
185
|
HTMLDivElement,
|
|
201
186
|
React.HTMLAttributes<HTMLDivElement> & {
|
|
@@ -231,6 +216,7 @@ const RowContainer = forwardRef<
|
|
|
231
216
|
$gap,
|
|
232
217
|
$backgroundColor,
|
|
233
218
|
style,
|
|
219
|
+
"aria-describedby": _, // Causes hydration warning
|
|
234
220
|
...props
|
|
235
221
|
},
|
|
236
222
|
ref
|
|
@@ -264,19 +250,19 @@ const RowContainer = forwardRef<
|
|
|
264
250
|
marginBottom: `${margin.bottom}px`,
|
|
265
251
|
}),
|
|
266
252
|
}),
|
|
267
|
-
color:
|
|
253
|
+
color: cssVars.colors.textMuted,
|
|
268
254
|
...($isSectionHeader && {
|
|
269
|
-
backgroundColor:
|
|
255
|
+
backgroundColor: cssVars.colors.listviewRaisedBackground,
|
|
270
256
|
...($sectionHeaderVariant === "label" && {
|
|
271
|
-
color:
|
|
257
|
+
color: cssVars.colors.textDisabled,
|
|
272
258
|
}),
|
|
273
259
|
}),
|
|
274
260
|
...($disabled && {
|
|
275
|
-
color:
|
|
261
|
+
color: cssVars.colors.textDisabled,
|
|
276
262
|
}),
|
|
277
263
|
...($selected && {
|
|
278
264
|
color: "white",
|
|
279
|
-
backgroundColor:
|
|
265
|
+
backgroundColor: cssVars.colors[$colorScheme],
|
|
280
266
|
}),
|
|
281
267
|
display: "flex",
|
|
282
268
|
alignItems: "center",
|
|
@@ -296,19 +282,19 @@ const RowContainer = forwardRef<
|
|
|
296
282
|
}),
|
|
297
283
|
position: "relative",
|
|
298
284
|
...($hovered && {
|
|
299
|
-
boxShadow: `0 0 0 1px ${
|
|
285
|
+
boxShadow: `0 0 0 1px ${cssVars.colors[$colorScheme]} inset`,
|
|
300
286
|
}),
|
|
301
287
|
...($showsActiveState && {
|
|
302
288
|
"&:active": {
|
|
303
289
|
backgroundColor: $selected
|
|
304
290
|
? $colorScheme === "secondary"
|
|
305
|
-
?
|
|
306
|
-
:
|
|
307
|
-
:
|
|
291
|
+
? cssVars.colors.secondaryLight
|
|
292
|
+
: cssVars.colors.primaryLight
|
|
293
|
+
: cssVars.colors.activeBackground,
|
|
308
294
|
},
|
|
309
295
|
}),
|
|
310
296
|
...($divider && {
|
|
311
|
-
borderBottom: `1px solid ${
|
|
297
|
+
borderBottom: `1px solid ${cssVars.colors.dividerSubtle}`,
|
|
312
298
|
}),
|
|
313
299
|
...($backgroundColor && {
|
|
314
300
|
backgroundColor: $backgroundColor,
|
|
@@ -360,10 +346,10 @@ const ListViewDragIndicatorElement = forwardRef<
|
|
|
360
346
|
...($relativeDropPosition === "inside"
|
|
361
347
|
? {
|
|
362
348
|
inset: 2,
|
|
363
|
-
boxShadow: `0 0 0 1px
|
|
349
|
+
boxShadow: `0 0 0 1px ${cssVars.colors.sidebarBackground}, 0 0 0 3px ${
|
|
364
350
|
$colorScheme === "secondary"
|
|
365
|
-
?
|
|
366
|
-
:
|
|
351
|
+
? cssVars.colors.secondary
|
|
352
|
+
: cssVars.colors.dragOutline
|
|
367
353
|
}`,
|
|
368
354
|
}
|
|
369
355
|
: {
|
|
@@ -380,15 +366,16 @@ const ListViewDragIndicatorElement = forwardRef<
|
|
|
380
366
|
height: 6,
|
|
381
367
|
backgroundColor:
|
|
382
368
|
$colorScheme === "secondary"
|
|
383
|
-
?
|
|
384
|
-
:
|
|
369
|
+
? cssVars.colors.secondary
|
|
370
|
+
: cssVars.colors.primary,
|
|
385
371
|
border: `2px solid white`,
|
|
386
372
|
boxShadow: "0 0 2px rgba(0,0,0,0.5)",
|
|
387
373
|
}),
|
|
388
374
|
...style,
|
|
389
375
|
}}
|
|
390
376
|
/>
|
|
391
|
-
);
|
|
377
|
+
);
|
|
378
|
+
}
|
|
392
379
|
);
|
|
393
380
|
|
|
394
381
|
interface ListViewClickInfo {
|
|
@@ -29,7 +29,7 @@ const ToggleGroupItem = forwardRef(function ToggleGroupItem(
|
|
|
29
29
|
ref={forwardedRef}
|
|
30
30
|
value={value}
|
|
31
31
|
disabled={disabled}
|
|
32
|
-
className={`font-sans text-heading5 font-normal relative flex-1 appearance-none border-none bg-none text-radio-group-item p-0 m-0 rounded inline-flex items-center justify-center align-middle focus:outline-none focus:shadow-[0_0_0_1px_var(--sidebar-background),0_0_0_3px_${colorScheme === "secondary" ? "var(--secondary)" : "var(--primary)"}] aria-checked:bg-${colorScheme ? colorScheme : "radio-group-background"} aria-checked:text-${colorScheme ? "radio-group-background" : "text"} aria-checked:shadow-${colorScheme ? "none" : "0_1px_1px_rgba(0,0,0,0.1)"}`}
|
|
32
|
+
className={`font-sans text-heading5 font-normal relative flex-1 appearance-none border-none bg-none text-radio-group-item p-0 m-0 rounded inline-flex items-center justify-center align-middle focus:outline-none focus:shadow-[0_0_0_1px_var(--sidebar-background),0_0_0_3px_${colorScheme === "secondary" ? "var(--secondary)" : "var(--primary)"}] aria-checked:bg-${colorScheme ? colorScheme : "radio-group-background"} aria-checked:text-${colorScheme ? "radio-group-background" : "text"} aria-checked:shadow-${colorScheme ? "none" : "0_1px_1px_rgba(0,0,0,0.1)"} focus:z-interactable`}
|
|
33
33
|
>
|
|
34
34
|
{children}
|
|
35
35
|
</ToggleGroupPrimitive.Item>
|
|
@@ -29,7 +29,7 @@ const readOnlyStyle: CSSProperties = {
|
|
|
29
29
|
textAlign: "left",
|
|
30
30
|
};
|
|
31
31
|
|
|
32
|
-
const labelStyles = `font-sans text-label uppercase text-text-disabled leading-[19px] font-bold text-[60%] pointer-events-none flex items-center mr-1.5`;
|
|
32
|
+
const labelStyles = `font-sans text-label uppercase text-text-disabled leading-[19px] font-bold text-[60%] pointer-events-none flex items-center mr-1.5 z-label`;
|
|
33
33
|
|
|
34
34
|
const scrollButtonStyles = `
|
|
35
35
|
flex
|
|
@@ -66,7 +66,7 @@ export const SelectMenu = memo(function SelectMenu<T extends string = string>({
|
|
|
66
66
|
id={id}
|
|
67
67
|
style={style}
|
|
68
68
|
contentStyle={readOnlyStyle}
|
|
69
|
-
className={`${className ?? ""} flex-1`}
|
|
69
|
+
className={`${className ?? ""} flex-1 focus:z-interactable`}
|
|
70
70
|
disabled={disabled}
|
|
71
71
|
>
|
|
72
72
|
{icon && (
|
|
@@ -87,7 +87,7 @@ export const SelectMenu = memo(function SelectMenu<T extends string = string>({
|
|
|
87
87
|
<Button
|
|
88
88
|
id={id}
|
|
89
89
|
style={style}
|
|
90
|
-
className={`${className ?? "w-full"} flex-1`}
|
|
90
|
+
className={`${className ?? "w-full"} flex-1 focus:z-interactable`}
|
|
91
91
|
disabled={disabled}
|
|
92
92
|
>
|
|
93
93
|
{icon && (
|
|
@@ -27,7 +27,7 @@ export const Switch = function Switch({
|
|
|
27
27
|
onCheckedChange={(newValue) => {
|
|
28
28
|
onChange(newValue);
|
|
29
29
|
}}
|
|
30
|
-
className={`all-unset w-8 h-[19px] bg-active-background rounded-full relative cursor-pointer [webkit-tap-highlight-color:rgba(0,0,0,0)] focus:ring-2 focus:ring-primary focus:ring-offset-[1px] outline-none data-[state=checked]:bg-primary ${colorScheme === "secondary" && "data-[state=checked]:bg-secondary"}`}
|
|
30
|
+
className={`all-unset w-8 h-[19px] bg-active-background rounded-full relative cursor-pointer [webkit-tap-highlight-color:rgba(0,0,0,0)] focus:ring-2 focus:ring-primary focus:ring-offset-[1px] outline-none data-[state=checked]:bg-primary ${colorScheme === "secondary" && "data-[state=checked]:bg-secondary"} focus:z-interactable`}
|
|
31
31
|
>
|
|
32
32
|
<SwitchPrimitive.Thumb className="block w-[15px] h-[15px] bg-white rounded-full transition-transform translate-x-[2px] data-[state=checked]:translate-x-[15px]" />
|
|
33
33
|
</SwitchPrimitive.Root>
|
package/src/components/Text.tsx
CHANGED
|
@@ -1,7 +1,20 @@
|
|
|
1
1
|
import React, { ForwardedRef, forwardRef, ReactHTML, ReactNode } from "react";
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
|
|
2
|
+
import { ThemeColor } from "../theme";
|
|
3
|
+
import { camelToKebabCase, KebabToCamelCase } from "../theme/themeUtils";
|
|
4
|
+
|
|
5
|
+
type Variant =
|
|
6
|
+
| "title"
|
|
7
|
+
| "subtitle"
|
|
8
|
+
| "heading1"
|
|
9
|
+
| "heading2"
|
|
10
|
+
| "heading3"
|
|
11
|
+
| "heading4"
|
|
12
|
+
| "heading5"
|
|
13
|
+
| "body"
|
|
14
|
+
| "small"
|
|
15
|
+
| "button"
|
|
16
|
+
| "code"
|
|
17
|
+
| "label";
|
|
5
18
|
|
|
6
19
|
const elements: Record<Variant, keyof ReactHTML> = {
|
|
7
20
|
title: "h1",
|
|
@@ -33,19 +46,19 @@ export const textStyles: Record<Variant, string> = {
|
|
|
33
46
|
label: "font-sans text-label font-normal uppercase",
|
|
34
47
|
} as const;
|
|
35
48
|
|
|
36
|
-
export type
|
|
49
|
+
export type TextProps = {
|
|
37
50
|
as?: keyof ReactHTML;
|
|
38
51
|
href?: string;
|
|
39
52
|
className?: string;
|
|
40
53
|
style?: React.CSSProperties;
|
|
41
54
|
variant: Variant;
|
|
42
|
-
color?: ThemeColor
|
|
55
|
+
color?: KebabToCamelCase<ThemeColor>;
|
|
43
56
|
children: ReactNode;
|
|
44
57
|
onClick?: () => void;
|
|
45
58
|
onDoubleClick?: () => void;
|
|
46
59
|
onKeyDown?: (event: React.KeyboardEvent<HTMLSpanElement>) => void;
|
|
47
60
|
tabIndex?: number;
|
|
48
|
-
}
|
|
61
|
+
};
|
|
49
62
|
|
|
50
63
|
export const Text = forwardRef(function Text(
|
|
51
64
|
{
|
|
@@ -69,7 +82,7 @@ export const Text = forwardRef(function Text(
|
|
|
69
82
|
<Component
|
|
70
83
|
// @ts-expect-error expected to be many semantic html elements
|
|
71
84
|
ref={forwardedRef}
|
|
72
|
-
className={`${textStyles[variant]} text-${
|
|
85
|
+
className={`${textStyles[variant]} text-${camelToKebabCase(String(color)) ?? "text"} ${className ?? ""}`}
|
|
73
86
|
style={style}
|
|
74
87
|
tabIndex={tabIndex}
|
|
75
88
|
onClick={onClick}
|
|
@@ -45,7 +45,7 @@ export const AutoResizingTextArea = memo(
|
|
|
45
45
|
|
|
46
46
|
return (
|
|
47
47
|
<textarea
|
|
48
|
-
className={`font-sans text-heading5 font-normal text-text bg-input-background w-0 flex-1 py-1 px-1.5 border-none outline-none h-[100px] rounded-4 resize-none placeholder:text-text-disabled focus:ring-2 focus:ring-primary
|
|
48
|
+
className={`font-sans text-heading5 font-normal text-text bg-input-background w-0 flex-1 py-1 px-1.5 border-none outline-none h-[100px] rounded-4 resize-none placeholder:text-text-disabled focus:ring-2 focus:ring-primary read-only:text-text-disabled focus:z-interactable ${className ?? ""}`}
|
|
49
49
|
ref={handleRef}
|
|
50
50
|
{...rest}
|
|
51
51
|
onChange={handleChange}
|
|
@@ -22,7 +22,7 @@ export const Tooltip = memo(function Tooltip({ children, content }: Props) {
|
|
|
22
22
|
align="center"
|
|
23
23
|
sideOffset={2}
|
|
24
24
|
collisionPadding={8}
|
|
25
|
-
className={`${textStyles.small} text-text rounded-[3px] py-small px-medium bg-popover-background shadow-[
|
|
25
|
+
className={`${textStyles.small} text-text rounded-[3px] py-small px-medium bg-popover-background shadow-[0_2px_4px_rgba(0,0,0,0.2)_0_0_12px_rgba(0,0,0,0.1)] border border-solid border-divider-strong`}
|
|
26
26
|
>
|
|
27
27
|
{content}
|
|
28
28
|
{/* <Arrow /> */}
|
|
@@ -22,6 +22,7 @@ import {
|
|
|
22
22
|
usePreservePanelSize,
|
|
23
23
|
} from "../hooks/usePreservePanelSize";
|
|
24
24
|
import { useWindowSize } from "../hooks/useWindowSize";
|
|
25
|
+
import { cssVars } from "../theme";
|
|
25
26
|
|
|
26
27
|
interface Props {
|
|
27
28
|
autoSavePrefix?: string;
|
|
@@ -184,7 +185,7 @@ const WorkspaceLayoutWithTheme = forwardRef(function WorkspaceLayoutWithTheme(
|
|
|
184
185
|
id={id}
|
|
185
186
|
className={className}
|
|
186
187
|
style={{
|
|
187
|
-
backgroundColor:
|
|
188
|
+
backgroundColor: cssVars.colors.canvasBackground,
|
|
188
189
|
display: "flex",
|
|
189
190
|
flexDirection: "row",
|
|
190
191
|
...style,
|
|
@@ -226,7 +227,7 @@ const WorkspaceLayoutWithTheme = forwardRef(function WorkspaceLayoutWithTheme(
|
|
|
226
227
|
cursor: "col-resize",
|
|
227
228
|
width: "1px",
|
|
228
229
|
height: "100%",
|
|
229
|
-
backgroundColor:
|
|
230
|
+
backgroundColor: cssVars.colors.divider,
|
|
230
231
|
}}
|
|
231
232
|
/>
|
|
232
233
|
</>
|
|
@@ -251,7 +252,7 @@ const WorkspaceLayoutWithTheme = forwardRef(function WorkspaceLayoutWithTheme(
|
|
|
251
252
|
cursor: "col-resize",
|
|
252
253
|
width: "1px",
|
|
253
254
|
height: "100%",
|
|
254
|
-
backgroundColor:
|
|
255
|
+
backgroundColor: cssVars.colors.divider,
|
|
255
256
|
}}
|
|
256
257
|
/>
|
|
257
258
|
<Panel
|
package/src/index.css
CHANGED
|
@@ -65,7 +65,17 @@
|
|
|
65
65
|
--radio-group-item: rgb(139, 139, 139);
|
|
66
66
|
--dot: rgba(0,0,0,0.25);
|
|
67
67
|
--row-highlight: #3390FF10;
|
|
68
|
-
--table-row-background: var(--background)
|
|
68
|
+
--table-row-background: var(--background);
|
|
69
|
+
--interactable-z-index: 2;
|
|
70
|
+
--label-z-index: 3;
|
|
71
|
+
--chip-primary-bg: rgba(238,229,255,0.2);
|
|
72
|
+
--chip-secondary-bg: rgba(205,238,231,0.2);
|
|
73
|
+
--chip-error-bg: rgba(255,219,219,0.2);
|
|
74
|
+
--chip-default-bg: rgba(0,0,0,0.1);
|
|
75
|
+
--chip-primary-shadow: rgb(238,229,255);
|
|
76
|
+
--chip-secondary-shadow: rgb(205,238,231);
|
|
77
|
+
--chip-error-shadow: rgb(255,219,219);
|
|
78
|
+
--chip-default-shadow: rgb(0,0,0);
|
|
69
79
|
}
|
|
70
80
|
|
|
71
81
|
[data-theme="dark"] {
|
|
@@ -105,4 +115,4 @@
|
|
|
105
115
|
--thumbnail-shadow: #1f1d3366;
|
|
106
116
|
--dot: rgba(255,255,255,0.15);
|
|
107
117
|
--table-row-background: var(--sidebar-background);
|
|
108
|
-
}
|
|
118
|
+
}
|
package/src/index.tsx
CHANGED
|
@@ -71,7 +71,6 @@ export * from "./hooks/usePlatform";
|
|
|
71
71
|
export * from "./mediaQuery";
|
|
72
72
|
export * from "./theme";
|
|
73
73
|
export { cn } from './utils/tailwind';
|
|
74
|
-
export type { ThemeColor } from './utils/tailwind';
|
|
75
74
|
export * from "./utils/createSectionedMenu";
|
|
76
75
|
export * from "./utils/getGradientBackground";
|
|
77
76
|
export * from "./hooks/usePreservePanelSize";
|
package/src/theme/index.ts
CHANGED
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
import tailwindConfig from "../../tailwind.config";
|
|
2
|
+
import { convertKebabToCamelCase } from "./themeUtils";
|
|
2
3
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
export type
|
|
4
|
+
export type Theme = (typeof tailwindConfig.theme)["extend"];
|
|
5
|
+
|
|
6
|
+
export type ThemeColor = keyof Theme["colors"];
|
|
7
|
+
|
|
8
|
+
export const cssVars = convertKebabToCamelCase(tailwindConfig.theme.extend);
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
export type KebabToCamelCase<S extends string> =
|
|
2
|
+
S extends `${infer First}-${infer Rest}`
|
|
3
|
+
? `${First}${Capitalize<KebabToCamelCase<Rest>>}`
|
|
4
|
+
: S;
|
|
5
|
+
|
|
6
|
+
type IsPlainObject<T> = T extends Array<any> | Set<any> | Map<any, any>
|
|
7
|
+
? false
|
|
8
|
+
: T extends object
|
|
9
|
+
? true
|
|
10
|
+
: false;
|
|
11
|
+
|
|
12
|
+
type KebabToCamelCaseKeys<T> = {
|
|
13
|
+
[K in keyof T as K extends string
|
|
14
|
+
? KebabToCamelCase<K>
|
|
15
|
+
: K]: T[K] extends object
|
|
16
|
+
? IsPlainObject<T[K]> extends true
|
|
17
|
+
? KebabToCamelCaseKeys<T[K]>
|
|
18
|
+
: T[K]
|
|
19
|
+
: T[K];
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
type _CamelToKebabCase<S extends string> = S extends `${infer C}${infer Rest}`
|
|
23
|
+
? C extends Uppercase<C>
|
|
24
|
+
? `-${Lowercase<C>}${_CamelToKebabCase<Rest>}`
|
|
25
|
+
: `${C}${_CamelToKebabCase<Rest>}`
|
|
26
|
+
: S;
|
|
27
|
+
|
|
28
|
+
// Remove leading hyphen if exists
|
|
29
|
+
type TrimHyphen<S extends string> = S extends `-${infer Rest}` ? Rest : S;
|
|
30
|
+
|
|
31
|
+
export type CamelToKebabCase<S extends string> = TrimHyphen<
|
|
32
|
+
_CamelToKebabCase<S>
|
|
33
|
+
>;
|
|
34
|
+
|
|
35
|
+
export function camelToKebabCase<S extends string>(
|
|
36
|
+
str: S
|
|
37
|
+
): CamelToKebabCase<S> {
|
|
38
|
+
return str.replace(/([A-Z])/g, "-$1").toLowerCase() as CamelToKebabCase<S>;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export function kebabToCamelCase<S extends string>(
|
|
42
|
+
str: S
|
|
43
|
+
): KebabToCamelCase<S> {
|
|
44
|
+
return str.replace(/-([a-z])/g, (_, letter) =>
|
|
45
|
+
letter.toUpperCase()
|
|
46
|
+
) as KebabToCamelCase<S>;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
// Runtime function to convert all keys in an object from kebab-case to camelCase
|
|
50
|
+
export function convertKebabToCamelCase<T extends object>(
|
|
51
|
+
obj: T
|
|
52
|
+
): KebabToCamelCaseKeys<T> {
|
|
53
|
+
if (Array.isArray(obj) || obj instanceof Set || obj instanceof Map) {
|
|
54
|
+
return obj as KebabToCamelCaseKeys<T>;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
const result: any = {};
|
|
58
|
+
|
|
59
|
+
for (const [key, value] of Object.entries(obj)) {
|
|
60
|
+
const camelKey = kebabToCamelCase(key);
|
|
61
|
+
result[camelKey] =
|
|
62
|
+
value &&
|
|
63
|
+
typeof value === "object" &&
|
|
64
|
+
!Array.isArray(value) &&
|
|
65
|
+
!(value instanceof Set) &&
|
|
66
|
+
!(value instanceof Map)
|
|
67
|
+
? convertKebabToCamelCase(value)
|
|
68
|
+
: value;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
return result as KebabToCamelCaseKeys<T>;
|
|
72
|
+
}
|
package/src/utils/tailwind.ts
CHANGED
|
@@ -1,17 +1,9 @@
|
|
|
1
|
-
import { Theme } from '../theme';
|
|
2
1
|
import { twMerge } from "tailwind-merge";
|
|
3
2
|
|
|
4
|
-
/**
|
|
3
|
+
/**
|
|
5
4
|
* Utility for merging classes conditionally. Right side will override left side if there are any conflicts.
|
|
6
5
|
* Usage: cn('bg-red-500 text-white', 'bg-blue-500') // Returns: 'text-white bg-blue-500'
|
|
7
6
|
* @danger do not use this function to concatenate class names. Use it to merge classes conditionally.
|
|
8
|
-
*/
|
|
9
|
-
export const cn = (...classes: (string | boolean | undefined | null)[]) =>
|
|
10
|
-
|
|
11
|
-
// @ts-expect-error TODO: figure this out
|
|
12
|
-
type ThemeExtend = NonNullable<Theme['extend']>
|
|
13
|
-
export type ThemeColor = keyof ThemeExtend['colors'];
|
|
14
|
-
|
|
15
|
-
export function camelCaseToKebabCase(string: string) {
|
|
16
|
-
return string.replace(/([a-z])([A-Z])/g, "$1-$2").toLowerCase();
|
|
17
|
-
}
|
|
7
|
+
*/
|
|
8
|
+
export const cn = (...classes: (string | boolean | undefined | null)[]) =>
|
|
9
|
+
twMerge(classes.filter(Boolean) as string[]);
|
package/tailwind.config.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { Config } from "tailwindcss";
|
|
1
|
+
import type { Config } from "tailwindcss";
|
|
2
2
|
|
|
3
|
-
const config
|
|
3
|
+
const config = {
|
|
4
4
|
content: ["./src/**/*.{ts,tsx}"],
|
|
5
5
|
corePlugins: {
|
|
6
6
|
// disables @tailwind base global styles
|
|
@@ -66,6 +66,14 @@ const config: Config = {
|
|
|
66
66
|
dot: "var(--dot)",
|
|
67
67
|
"row-highlight": "var(--row-highlight)",
|
|
68
68
|
"table-row-background": "var(--table-row-background)",
|
|
69
|
+
"chip-primary-bg": "var(--chip-primary-bg)",
|
|
70
|
+
"chip-secondary-bg": "var(--chip-secondary-bg)",
|
|
71
|
+
"chip-error-bg": "var(--chip-error-bg)",
|
|
72
|
+
"chip-default-bg": "var(--chip-default-bg)",
|
|
73
|
+
"chip-primary-shadow": "var(--chip-primary-shadow)",
|
|
74
|
+
"chip-secondary-shadow": "var(--chip-secondary-shadow)",
|
|
75
|
+
"chip-error-shadow": "var(--chip-error-shadow)",
|
|
76
|
+
"chip-default-shadow": "var(--chip-default-shadow)",
|
|
69
77
|
},
|
|
70
78
|
fontFamily: {
|
|
71
79
|
sans: [
|
|
@@ -200,6 +208,10 @@ const config: Config = {
|
|
|
200
208
|
spin: "spin 1s linear infinite",
|
|
201
209
|
shimmer: "shimmer 6s infinite linear",
|
|
202
210
|
},
|
|
211
|
+
zIndex: {
|
|
212
|
+
interactable: "var(--interactable-z-index)",
|
|
213
|
+
label: "var(--label-z-index)",
|
|
214
|
+
}
|
|
203
215
|
},
|
|
204
216
|
},
|
|
205
217
|
safelist: [
|
|
@@ -218,7 +230,8 @@ const config: Config = {
|
|
|
218
230
|
"-mr-2",
|
|
219
231
|
"border-gray-200",
|
|
220
232
|
"gap-1.5",
|
|
233
|
+
"gap-toolbar-separator",
|
|
221
234
|
],
|
|
222
|
-
};
|
|
235
|
+
} satisfies Config;
|
|
223
236
|
|
|
224
237
|
export default config;
|