@noya-app/noya-designsystem 0.1.39 → 0.1.40
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 +10 -0
- package/dist/index.css +1 -1
- package/dist/index.d.mts +416 -321
- package/dist/index.d.ts +416 -321
- package/dist/index.js +9558 -11324
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +5694 -7465
- package/dist/index.mjs.map +1 -1
- package/package.json +4 -4
- package/src/components/ActivityIndicator.tsx +13 -4
- package/src/components/AnimatePresence.tsx +261 -0
- package/src/components/Avatar.tsx +202 -80
- package/src/components/Button.tsx +10 -6
- package/src/components/Checkbox.tsx +6 -1
- package/src/components/Chip.tsx +88 -132
- package/src/components/{InputFieldWithCompletions.tsx → Combobox.tsx} +10 -3
- package/src/components/ContextMenu.tsx +9 -5
- package/src/components/Dialog.tsx +20 -23
- package/src/components/Divider.tsx +15 -7
- package/src/components/DraggableMenuButton.tsx +9 -5
- package/src/components/DropdownMenu.tsx +8 -5
- package/src/components/FillInputField.tsx +5 -1
- package/src/components/FillPreviewBackground.tsx +1 -5
- package/src/components/GridView.tsx +71 -46
- package/src/components/InputField.tsx +140 -75
- package/src/components/InspectorPrimitives.tsx +17 -11
- package/src/components/Label.tsx +5 -1
- package/src/components/ListView.tsx +28 -15
- package/src/components/Progress.tsx +10 -7
- package/src/components/SelectMenu.tsx +20 -8
- package/src/components/Slider.tsx +70 -8
- package/src/components/Sortable.tsx +3 -3
- package/src/components/Switch.tsx +19 -2
- package/src/components/Text.tsx +5 -1
- package/src/components/TextArea.tsx +5 -1
- package/src/components/TreeView.tsx +4 -10
- package/src/components/UserPointer.tsx +170 -0
- package/src/components/WorkspaceLayout.tsx +5 -0
- package/src/components/internal/Menu.tsx +14 -5
- package/src/components/internal/TextInput.tsx +13 -0
- package/src/contexts/DialogContext.tsx +30 -18
- package/src/hooks/useTheme.ts +50 -0
- package/src/index.css +16 -13
- package/src/index.tsx +14 -26
- package/src/utils/classNames.ts +5 -0
- package/src/utils/colorFromString.ts +44 -0
- package/tailwind.config.ts +16 -13
- package/src/hooks/useDarkMode.ts +0 -14
- package/src/utils/tailwind.ts +0 -9
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { KeyModifiers } from "@noya-app/noya-keymap";
|
|
2
|
+
import { forwardRefGeneric } from "@noya-app/react-utils";
|
|
2
3
|
import React, {
|
|
3
4
|
createContext,
|
|
4
5
|
CSSProperties,
|
|
5
6
|
ForwardedRef,
|
|
6
|
-
forwardRef,
|
|
7
7
|
memo,
|
|
8
8
|
ReactNode,
|
|
9
9
|
useCallback,
|
|
@@ -11,6 +11,7 @@ import React, {
|
|
|
11
11
|
useMemo,
|
|
12
12
|
} from "react";
|
|
13
13
|
import { useHover } from "../hooks/useHover";
|
|
14
|
+
import { cx } from "../utils/classNames";
|
|
14
15
|
import withSeparatorElements from "../utils/withSeparatorElements";
|
|
15
16
|
import { ActivityIndicator } from "./ActivityIndicator";
|
|
16
17
|
import { ContextMenu } from "./ContextMenu";
|
|
@@ -18,7 +19,6 @@ import { MenuItem } from "./internal/Menu";
|
|
|
18
19
|
import { ScrollArea } from "./ScrollArea";
|
|
19
20
|
import { Spacer } from "./Spacer";
|
|
20
21
|
import { Tooltip } from "./Tooltip";
|
|
21
|
-
import { cn } from "../utils/tailwind";
|
|
22
22
|
|
|
23
23
|
export type GridViewSize = "xxs" | "xs" | "small" | "medium" | "large" | "xl";
|
|
24
24
|
|
|
@@ -62,34 +62,51 @@ const sizes: Record<
|
|
|
62
62
|
},
|
|
63
63
|
};
|
|
64
64
|
|
|
65
|
-
const ItemTitle = ({
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
}
|
|
65
|
+
const ItemTitle = ({
|
|
66
|
+
showBackground,
|
|
67
|
+
children,
|
|
68
|
+
}: {
|
|
69
|
+
showBackground?: boolean;
|
|
70
|
+
children?: React.ReactNode;
|
|
71
|
+
}) => {
|
|
72
|
+
return (
|
|
73
|
+
<span
|
|
74
|
+
className={`font-sans text-heading5 leading-[1] text-text font-medium select-none whitespace-pre overflow-hidden text-ellipsis ${
|
|
75
|
+
showBackground &&
|
|
76
|
+
"bg-sidebar-background border border-dividerSubtle rounded-[2px] backdrop-blur-[4px] p-[2px_4px]"
|
|
77
|
+
}`}
|
|
78
|
+
>
|
|
79
|
+
{children}
|
|
80
|
+
</span>
|
|
81
|
+
);
|
|
82
|
+
};
|
|
78
83
|
|
|
79
|
-
const ItemDescription = ({
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
84
|
+
const ItemDescription = ({
|
|
85
|
+
showBackground,
|
|
86
|
+
children,
|
|
87
|
+
}: {
|
|
88
|
+
showBackground?: boolean;
|
|
89
|
+
children?: React.ReactNode;
|
|
90
|
+
}) => {
|
|
91
|
+
return (
|
|
92
|
+
<span
|
|
93
|
+
className={`font-sans text-heading5 font-normal leading-[1] text-[0.7rem] text-text-muted select-none whitespace-pre overflow-hidden text-ellipsis ${
|
|
94
|
+
showBackground &&
|
|
95
|
+
"bg-sidebar-background border border-dividerSubtle rounded-[2px] backdrop-blur-[4px] p-[2px_4px]"
|
|
96
|
+
}`}
|
|
97
|
+
>
|
|
98
|
+
{children}
|
|
99
|
+
</span>
|
|
100
|
+
);
|
|
101
|
+
};
|
|
91
102
|
|
|
92
|
-
const SectionTitle = ({
|
|
103
|
+
const SectionTitle = ({
|
|
104
|
+
last = false,
|
|
105
|
+
children,
|
|
106
|
+
}: {
|
|
107
|
+
last?: boolean;
|
|
108
|
+
children?: React.ReactNode;
|
|
109
|
+
}) => {
|
|
93
110
|
return (
|
|
94
111
|
<span
|
|
95
112
|
className={`font-sans text-heading3 font-medium user-select-none whitespace-pre overflow-hidden text-ellipsis ${last ? "text-text" : "text-text-muted"}`}
|
|
@@ -116,7 +133,7 @@ interface ItemProps<MenuItemType extends string = string> {
|
|
|
116
133
|
style?: CSSProperties;
|
|
117
134
|
}
|
|
118
135
|
|
|
119
|
-
const GridViewItem =
|
|
136
|
+
const GridViewItem = forwardRefGeneric(function GridViewItem<
|
|
120
137
|
MenuItemType extends string,
|
|
121
138
|
>(
|
|
122
139
|
{
|
|
@@ -183,17 +200,18 @@ const GridViewItem = forwardRef(function GridViewItem<
|
|
|
183
200
|
onKeyDown={handleKeyDown}
|
|
184
201
|
>
|
|
185
202
|
<div
|
|
186
|
-
className={
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
203
|
+
className={`flex flex-1 items-center justify-center
|
|
204
|
+
bg-sidebar-background rounded-[2px] overflow-hidden
|
|
205
|
+
cursor-pointer
|
|
206
|
+
${
|
|
207
|
+
selected
|
|
208
|
+
? "border border-primary"
|
|
209
|
+
: bordered
|
|
210
|
+
? "border border-divider"
|
|
211
|
+
: "border border-transparent"
|
|
212
|
+
}
|
|
213
|
+
${disabled ? "opacity-50" : "hover:opacity-85 active:opacity-70"}
|
|
214
|
+
`}
|
|
197
215
|
onClick={handleClick}
|
|
198
216
|
onDoubleClick={onDoubleClick}
|
|
199
217
|
onContextMenu={onContextMenu}
|
|
@@ -237,10 +255,8 @@ const GridViewItem = forwardRef(function GridViewItem<
|
|
|
237
255
|
<Tooltip
|
|
238
256
|
content={
|
|
239
257
|
<div className="flex flex-col gap-0.5">
|
|
240
|
-
<ItemTitle
|
|
241
|
-
<ItemDescription>
|
|
242
|
-
{subtitle}
|
|
243
|
-
</ItemDescription>
|
|
258
|
+
<ItemTitle>{title}</ItemTitle>
|
|
259
|
+
<ItemDescription>{subtitle}</ItemDescription>
|
|
244
260
|
</div>
|
|
245
261
|
}
|
|
246
262
|
>
|
|
@@ -303,7 +319,10 @@ function GridViewRoot({
|
|
|
303
319
|
|
|
304
320
|
return (
|
|
305
321
|
<GridViewContext.Provider value={contextValue}>
|
|
306
|
-
<div
|
|
322
|
+
<div
|
|
323
|
+
onClick={handleClick}
|
|
324
|
+
className={`flex flex-col ${scrollable ? "flex-1" : "flex-[0_0_auto]"}`}
|
|
325
|
+
>
|
|
307
326
|
{scrollable ? <ScrollArea>{children}</ScrollArea> : children}
|
|
308
327
|
</div>
|
|
309
328
|
</GridViewContext.Provider>
|
|
@@ -321,7 +340,13 @@ function GridViewSection({
|
|
|
321
340
|
const gapStyle = { gap: `${sizes[size].gap}px` };
|
|
322
341
|
|
|
323
342
|
return (
|
|
324
|
-
<div
|
|
343
|
+
<div
|
|
344
|
+
className={cx(
|
|
345
|
+
`grid-cols-[auto-fill,_minmax(${sizes[size].itemWidth}px,_1fr)] text-text grid `,
|
|
346
|
+
className
|
|
347
|
+
)}
|
|
348
|
+
style={gapStyle}
|
|
349
|
+
>
|
|
325
350
|
{children}
|
|
326
351
|
</div>
|
|
327
352
|
);
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import { CaretDownIcon } from "@noya-app/noya-icons";
|
|
2
|
-
import { assignRef } from "@noya-app/react-utils";
|
|
2
|
+
import { assignRef, memoGeneric } from "@noya-app/react-utils";
|
|
3
3
|
import { Property } from "csstype";
|
|
4
4
|
import React, {
|
|
5
5
|
Children,
|
|
6
6
|
createContext,
|
|
7
|
+
FocusEventHandler,
|
|
7
8
|
ForwardedRef,
|
|
8
9
|
forwardRef,
|
|
9
10
|
isValidElement,
|
|
@@ -19,6 +20,7 @@ import React, {
|
|
|
19
20
|
useRef,
|
|
20
21
|
useState,
|
|
21
22
|
} from "react";
|
|
23
|
+
import { cx } from "../utils/classNames";
|
|
22
24
|
import handleNudge from "../utils/handleNudge";
|
|
23
25
|
import { Button } from "./Button";
|
|
24
26
|
import { DropdownMenu } from "./DropdownMenu";
|
|
@@ -81,6 +83,7 @@ const LabelContainer = forwardRef(function LabelContainer(
|
|
|
81
83
|
}: LabelContainerProps,
|
|
82
84
|
ref: ForwardedRef<HTMLLabelElement>
|
|
83
85
|
) {
|
|
86
|
+
const { buttonSize } = useContext(InputFieldContext);
|
|
84
87
|
const memoizedStyles = useMemo(
|
|
85
88
|
() => ({
|
|
86
89
|
left:
|
|
@@ -94,26 +97,27 @@ const LabelContainer = forwardRef(function LabelContainer(
|
|
|
94
97
|
right:
|
|
95
98
|
$labelPosition === "end"
|
|
96
99
|
? $size === "large"
|
|
97
|
-
?
|
|
100
|
+
? `${6 + (buttonSize ?? 0)}px`
|
|
98
101
|
: $size === "medium"
|
|
99
|
-
?
|
|
100
|
-
:
|
|
102
|
+
? `${2 + (buttonSize ?? 0)}px`
|
|
103
|
+
: `${buttonSize ?? 0}px`
|
|
101
104
|
: "",
|
|
102
105
|
...style,
|
|
103
106
|
}),
|
|
104
|
-
[$labelPosition, $size, style]
|
|
107
|
+
[$labelPosition, $size, buttonSize, style]
|
|
105
108
|
);
|
|
106
109
|
|
|
107
110
|
return (
|
|
108
111
|
<label
|
|
109
112
|
ref={ref}
|
|
110
|
-
className={
|
|
113
|
+
className={cx(
|
|
114
|
+
"absolute top-0 bottom-0 flex items-center font-sans text-label font-bold uppercase text-text-disabled select-none z-label pointer-events-none",
|
|
111
115
|
$labelPosition === "start"
|
|
112
|
-
? `justify-start pl-
|
|
113
|
-
: $labelPosition === "end"
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
}
|
|
116
|
+
? `justify-start pl-1.5`
|
|
117
|
+
: $labelPosition === "end" &&
|
|
118
|
+
`justify-end ${$hasDropdown ? "pr-4" : "pr-1.5"}`,
|
|
119
|
+
className
|
|
120
|
+
)}
|
|
117
121
|
style={memoizedStyles}
|
|
118
122
|
{...props}
|
|
119
123
|
/>
|
|
@@ -122,8 +126,6 @@ const LabelContainer = forwardRef(function LabelContainer(
|
|
|
122
126
|
|
|
123
127
|
/**
|
|
124
128
|
* Inserts a Label at the start or end of the input given a `labelPosition`on InputField.Root.
|
|
125
|
-
*
|
|
126
|
-
* Should not be used with an InputField.Button.
|
|
127
129
|
*/
|
|
128
130
|
const InputFieldLabel = memo(
|
|
129
131
|
forwardRef(function InputFieldLabel(
|
|
@@ -171,7 +173,7 @@ const DropdownContainer = forwardRef<
|
|
|
171
173
|
>(({ className, ...props }, ref) => (
|
|
172
174
|
<span
|
|
173
175
|
ref={ref}
|
|
174
|
-
className={
|
|
176
|
+
className={cx("absolute inset-y-0 right-0 flex flex-col", className)}
|
|
175
177
|
{...props}
|
|
176
178
|
/>
|
|
177
179
|
));
|
|
@@ -183,7 +185,7 @@ interface InputFieldDropdownProps<T extends string> {
|
|
|
183
185
|
children?: ReactNode;
|
|
184
186
|
}
|
|
185
187
|
|
|
186
|
-
const InputFieldDropdownMenu =
|
|
188
|
+
const InputFieldDropdownMenu = memoGeneric(function InputFieldDropdownMenu<
|
|
187
189
|
T extends string,
|
|
188
190
|
>({ id, items, onSelect, children }: InputFieldDropdownProps<T>) {
|
|
189
191
|
const { size } = useContext(InputFieldContext);
|
|
@@ -224,15 +226,18 @@ const ButtonContainer = forwardRef<
|
|
|
224
226
|
>(({ $size, className, ...props }, ref) => (
|
|
225
227
|
<span
|
|
226
228
|
ref={ref}
|
|
227
|
-
className={
|
|
229
|
+
className={cx(
|
|
230
|
+
"absolute",
|
|
228
231
|
$size === "large"
|
|
229
|
-
? "right-[9px] top-
|
|
232
|
+
? "right-[9px] top-2.5"
|
|
230
233
|
: $size === "medium"
|
|
231
|
-
? "right-
|
|
234
|
+
? "right-1 top-1"
|
|
232
235
|
: $size === "small"
|
|
233
|
-
? "right-
|
|
234
|
-
: ""
|
|
235
|
-
|
|
236
|
+
? "right-0.5 top-0.5"
|
|
237
|
+
: "",
|
|
238
|
+
"z-label",
|
|
239
|
+
className
|
|
240
|
+
)}
|
|
236
241
|
{...props}
|
|
237
242
|
/>
|
|
238
243
|
));
|
|
@@ -325,8 +330,10 @@ type InputElementProps = {
|
|
|
325
330
|
$size: InputFieldSize;
|
|
326
331
|
children?: React.ReactNode;
|
|
327
332
|
className?: string;
|
|
333
|
+
style?: React.CSSProperties;
|
|
328
334
|
value?: string;
|
|
329
335
|
onSubmit?: (value: string) => void;
|
|
336
|
+
as?: "input" | "span";
|
|
330
337
|
};
|
|
331
338
|
|
|
332
339
|
const InputElement = forwardRef(
|
|
@@ -344,43 +351,73 @@ const InputElement = forwardRef(
|
|
|
344
351
|
children,
|
|
345
352
|
value,
|
|
346
353
|
onSubmit,
|
|
354
|
+
as = "input",
|
|
347
355
|
...props
|
|
348
356
|
}: InputElementProps,
|
|
349
357
|
ref: ForwardedRef<any>
|
|
350
358
|
) => {
|
|
351
359
|
const paddingLeft =
|
|
352
|
-
|
|
353
|
-
|
|
360
|
+
$variant === "bare"
|
|
361
|
+
? 0
|
|
362
|
+
: ($size === "large" ? 10 : $size === "medium" ? 6 : 4) +
|
|
363
|
+
($labelSize && $labelPosition === "start" ? 6 + $labelSize : 0);
|
|
354
364
|
|
|
355
365
|
const paddingRight =
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
366
|
+
$variant === "bare"
|
|
367
|
+
? 0
|
|
368
|
+
: ($size === "large" ? 10 : $size === "medium" ? 6 : 1) +
|
|
369
|
+
($labelSize && $labelPosition === "end" ? 6 + $labelSize : 0) +
|
|
370
|
+
($hasDropdown ? 11 : 0);
|
|
359
371
|
|
|
360
372
|
const memoizedStyles = useMemo(
|
|
361
373
|
() => ({
|
|
362
374
|
paddingLeft: `${paddingLeft}px`,
|
|
363
375
|
paddingRight: `${paddingRight}px`,
|
|
376
|
+
...props.style,
|
|
364
377
|
}),
|
|
365
|
-
[paddingLeft, paddingRight]
|
|
378
|
+
[paddingLeft, paddingRight, props.style]
|
|
366
379
|
);
|
|
367
380
|
|
|
381
|
+
const inputClassName = cx(
|
|
382
|
+
"flex w-0 flex-1 relative border-0 outline-none min-w-0 self-stretch rounded bg-input-background focus:ring-2 focus:ring-primary placeholder:text-text-disabled",
|
|
383
|
+
readOnly
|
|
384
|
+
? "text-text-muted"
|
|
385
|
+
: disabled
|
|
386
|
+
? "text-text-disabled"
|
|
387
|
+
: "text-text",
|
|
388
|
+
"font-sans font-normal",
|
|
389
|
+
$textAlign && `text-${$textAlign}`,
|
|
390
|
+
$size === "small"
|
|
391
|
+
? "text-[11px] leading-[19px] py-[1px]"
|
|
392
|
+
: $size === "large"
|
|
393
|
+
? "py-2.5 text-heading5"
|
|
394
|
+
: $size === "medium"
|
|
395
|
+
? "py-1 text-heading5"
|
|
396
|
+
: $variant === "bare" && "py-1 -m-1",
|
|
397
|
+
className
|
|
398
|
+
);
|
|
399
|
+
|
|
400
|
+
if (as === "span") {
|
|
401
|
+
return (
|
|
402
|
+
<span
|
|
403
|
+
ref={ref}
|
|
404
|
+
{...props}
|
|
405
|
+
className={inputClassName}
|
|
406
|
+
style={memoizedStyles}
|
|
407
|
+
>
|
|
408
|
+
{children}
|
|
409
|
+
</span>
|
|
410
|
+
);
|
|
411
|
+
}
|
|
412
|
+
|
|
368
413
|
return (
|
|
369
414
|
<TextInput
|
|
415
|
+
ref={ref}
|
|
370
416
|
value={value ?? ""}
|
|
371
417
|
onSubmit={onSubmit ?? (() => {})}
|
|
372
|
-
ref={ref}
|
|
373
|
-
className={`flex w-0 flex-[1_1_0px] relative border-0 outline-none min-w-0 self-stretch rounded bg-input-background focus:ring-2 focus:ring-primary placeholder:text-text-disabled ${readOnly ? "text-text-muted" : disabled ? "text-text-disabled" : "text-text"} font-sans font-normal ${$textAlign && `text-${$textAlign}`} ${
|
|
374
|
-
$size === "small"
|
|
375
|
-
? "text-[11px] leading-[19px] py-[1px]"
|
|
376
|
-
: $size === "large"
|
|
377
|
-
? "py-[10px] text-heading5"
|
|
378
|
-
: $size === "medium"
|
|
379
|
-
? "py-1 text-heading5"
|
|
380
|
-
: $variant === "bare" && "p-1 -m-1"
|
|
381
|
-
} ${className ?? ""}`}
|
|
382
|
-
style={memoizedStyles}
|
|
383
418
|
{...props}
|
|
419
|
+
className={inputClassName}
|
|
420
|
+
style={memoizedStyles}
|
|
384
421
|
/>
|
|
385
422
|
);
|
|
386
423
|
}
|
|
@@ -436,26 +473,29 @@ const InputFieldInput = forwardRef(function InputFieldInput(
|
|
|
436
473
|
});
|
|
437
474
|
|
|
438
475
|
const InputFieldTypeahead = (props: { prefix: string; value: string }) => {
|
|
439
|
-
const {
|
|
440
|
-
|
|
441
|
-
labelSize,
|
|
442
|
-
hasDropdown,
|
|
443
|
-
size,
|
|
444
|
-
// onFocusChange,
|
|
445
|
-
} = useContext(InputFieldContext);
|
|
476
|
+
const { labelPosition, labelSize, hasDropdown, size } =
|
|
477
|
+
useContext(InputFieldContext);
|
|
446
478
|
|
|
447
479
|
return (
|
|
448
480
|
<InputElement
|
|
481
|
+
as="span"
|
|
449
482
|
$labelPosition={labelPosition}
|
|
450
483
|
$labelSize={labelSize}
|
|
451
484
|
$hasDropdown={hasDropdown}
|
|
452
485
|
$size={size}
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
486
|
+
style={useMemo(
|
|
487
|
+
() => ({
|
|
488
|
+
position: "absolute",
|
|
489
|
+
inset: 0,
|
|
490
|
+
width: "100%",
|
|
491
|
+
height: "100%",
|
|
492
|
+
pointerEvents: "none",
|
|
493
|
+
background: "transparent",
|
|
494
|
+
boxShadow: "none",
|
|
495
|
+
whiteSpace: "pre",
|
|
496
|
+
}),
|
|
497
|
+
[]
|
|
498
|
+
)}
|
|
459
499
|
>
|
|
460
500
|
<span style={{ opacity: 0 }}>{props.prefix}</span>
|
|
461
501
|
<span style={{ opacity: 0.5 }}>
|
|
@@ -476,6 +516,8 @@ type InputFieldNumberInputProps = Omit<
|
|
|
476
516
|
value: number | undefined;
|
|
477
517
|
onNudge?: (value: number) => void;
|
|
478
518
|
variant?: "bare";
|
|
519
|
+
onFocus?: FocusEventHandler;
|
|
520
|
+
onBlur?: FocusEventHandler;
|
|
479
521
|
} & (
|
|
480
522
|
| {
|
|
481
523
|
onChange: (value: number) => void;
|
|
@@ -584,15 +626,18 @@ const RootContainer = forwardRef<
|
|
|
584
626
|
HTMLDivElement,
|
|
585
627
|
{
|
|
586
628
|
$width?: number;
|
|
587
|
-
$flex?: string;
|
|
588
629
|
className?: string;
|
|
589
630
|
children?: React.ReactNode;
|
|
590
631
|
style?: React.CSSProperties;
|
|
591
632
|
}
|
|
592
|
-
>(({ $width,
|
|
633
|
+
>(({ $width, className, ...props }, ref) => (
|
|
593
634
|
<div
|
|
594
635
|
ref={ref}
|
|
595
|
-
className={
|
|
636
|
+
className={cx("flex flex-row relative flex-1", className)}
|
|
637
|
+
style={{
|
|
638
|
+
maxWidth: $width || $width === 0 ? `${$width}px` : undefined,
|
|
639
|
+
...props.style,
|
|
640
|
+
}}
|
|
596
641
|
{...props}
|
|
597
642
|
/>
|
|
598
643
|
));
|
|
@@ -691,16 +736,16 @@ function InputFieldRoot({
|
|
|
691
736
|
);
|
|
692
737
|
|
|
693
738
|
const rootElement = (
|
|
694
|
-
<RootContainer
|
|
695
|
-
$width={width}
|
|
696
|
-
$flex={flex}
|
|
697
|
-
style={style}
|
|
698
|
-
className={className}
|
|
699
|
-
>
|
|
739
|
+
<RootContainer $width={width} style={style} className={className}>
|
|
700
740
|
{children}
|
|
701
741
|
</RootContainer>
|
|
702
742
|
);
|
|
703
743
|
|
|
744
|
+
const measuredWidthObject = useMemo(
|
|
745
|
+
() => (measuredWidth ? { width: measuredWidth + 12 } : undefined),
|
|
746
|
+
[measuredWidth]
|
|
747
|
+
);
|
|
748
|
+
|
|
704
749
|
return (
|
|
705
750
|
<InputFieldContext.Provider value={contextValue}>
|
|
706
751
|
{renderPopoverContent ? (
|
|
@@ -718,9 +763,12 @@ function InputFieldRoot({
|
|
|
718
763
|
event.stopPropagation();
|
|
719
764
|
}}
|
|
720
765
|
>
|
|
721
|
-
{
|
|
722
|
-
<div
|
|
723
|
-
|
|
766
|
+
{measuredWidthObject && (
|
|
767
|
+
<div
|
|
768
|
+
className="flex flex-col overflow-hidden"
|
|
769
|
+
style={measuredWidthObject}
|
|
770
|
+
>
|
|
771
|
+
{renderPopoverContent(measuredWidthObject)}
|
|
724
772
|
</div>
|
|
725
773
|
)}
|
|
726
774
|
</Popover>
|
|
@@ -735,6 +783,7 @@ const PrimitiveInputField = ({
|
|
|
735
783
|
readOnly,
|
|
736
784
|
disabled,
|
|
737
785
|
className,
|
|
786
|
+
style,
|
|
738
787
|
...props
|
|
739
788
|
}: {
|
|
740
789
|
readOnly?: boolean;
|
|
@@ -742,18 +791,34 @@ const PrimitiveInputField = ({
|
|
|
742
791
|
} & React.DetailedHTMLProps<
|
|
743
792
|
React.InputHTMLAttributes<HTMLInputElement>,
|
|
744
793
|
HTMLInputElement
|
|
745
|
-
>) =>
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
);
|
|
794
|
+
>) => {
|
|
795
|
+
const { labelSize, labelPosition, buttonSize } =
|
|
796
|
+
useContext(InputFieldContext);
|
|
797
|
+
|
|
798
|
+
const memoizedStyles = useMemo(
|
|
799
|
+
() => ({
|
|
800
|
+
paddingLeft: `${labelSize && labelPosition === "start" ? 6 + labelSize : 6}px`,
|
|
801
|
+
paddingRight: `${labelPosition === "end" ? 6 + (labelSize ?? 0) + (buttonSize ?? 0) : 6}px`,
|
|
802
|
+
...style,
|
|
803
|
+
}),
|
|
804
|
+
[labelSize, labelPosition, buttonSize, style]
|
|
805
|
+
);
|
|
806
|
+
return (
|
|
807
|
+
<input
|
|
808
|
+
style={memoizedStyles}
|
|
809
|
+
className={cx(
|
|
810
|
+
"flex w-0 flex-1 relative border-none outline-none min-w-0 self-stretch rounded py-1 bg-input-background select-all pointer-events-[all] focus:ring-2 focus:ring-primary font-sans font-normal text-heading5 placeholder:text-text-disabled focus:z-interactable",
|
|
811
|
+
readOnly
|
|
812
|
+
? "text-text-muted"
|
|
813
|
+
: disabled
|
|
814
|
+
? "text-text-disabled"
|
|
815
|
+
: "text-text",
|
|
816
|
+
className
|
|
817
|
+
)}
|
|
818
|
+
{...props}
|
|
819
|
+
/>
|
|
820
|
+
);
|
|
821
|
+
};
|
|
757
822
|
|
|
758
823
|
export namespace InputField {
|
|
759
824
|
export const Root = memo(InputFieldRoot);
|
|
@@ -5,9 +5,9 @@ import React, {
|
|
|
5
5
|
memo,
|
|
6
6
|
ReactNode,
|
|
7
7
|
} from "react";
|
|
8
|
-
import { cn } from "../utils/tailwind";
|
|
9
8
|
import { Spacer } from "./Spacer";
|
|
10
9
|
import { textStyles } from "./Text";
|
|
10
|
+
import { cx } from "../utils/classNames";
|
|
11
11
|
|
|
12
12
|
export const Section = forwardRef<
|
|
13
13
|
HTMLDivElement,
|
|
@@ -15,7 +15,7 @@ export const Section = forwardRef<
|
|
|
15
15
|
>(({ className, ...props }, ref) => (
|
|
16
16
|
<div
|
|
17
17
|
ref={ref}
|
|
18
|
-
className={
|
|
18
|
+
className={cx(`flex-none flex flex-col `, className)}
|
|
19
19
|
{...props}
|
|
20
20
|
/>
|
|
21
21
|
));
|
|
@@ -24,7 +24,7 @@ export const SectionHeader = forwardRef<
|
|
|
24
24
|
HTMLDivElement,
|
|
25
25
|
React.HTMLAttributes<HTMLDivElement>
|
|
26
26
|
>(({ className, ...props }, ref) => (
|
|
27
|
-
<div ref={ref} className={
|
|
27
|
+
<div ref={ref} className={cx(`flex items-center `, className)} {...props} />
|
|
28
28
|
));
|
|
29
29
|
|
|
30
30
|
type TitleTextStyle = "small" | "heading5" | "heading4" | "heading3";
|
|
@@ -37,7 +37,10 @@ export const Title = forwardRef<
|
|
|
37
37
|
>(({ className, $textStyle, ...props }, ref) => (
|
|
38
38
|
<div
|
|
39
39
|
ref={ref}
|
|
40
|
-
className={
|
|
40
|
+
className={cx(
|
|
41
|
+
`flex select-none ${$textStyle ? `${textStyles[$textStyle]} text-text` : "font-sans text-label uppercase text-text-muted font-bold"} `,
|
|
42
|
+
className
|
|
43
|
+
)}
|
|
41
44
|
{...props}
|
|
42
45
|
/>
|
|
43
46
|
));
|
|
@@ -48,7 +51,7 @@ export const Row = forwardRef<
|
|
|
48
51
|
>(({ className, ...props }, ref) => (
|
|
49
52
|
<div
|
|
50
53
|
ref={ref}
|
|
51
|
-
className={
|
|
54
|
+
className={cx(`flex-1 flex flex-row items-center `, className)}
|
|
52
55
|
{...props}
|
|
53
56
|
/>
|
|
54
57
|
));
|
|
@@ -59,7 +62,7 @@ export const Column = forwardRef<
|
|
|
59
62
|
>(({ className, ...props }, ref) => (
|
|
60
63
|
<div
|
|
61
64
|
ref={ref}
|
|
62
|
-
className={
|
|
65
|
+
className={cx(`flex-1 flex flex-col gap-1 `, className)}
|
|
63
66
|
{...props}
|
|
64
67
|
/>
|
|
65
68
|
));
|
|
@@ -71,7 +74,7 @@ export const Checkbox = forwardRef<
|
|
|
71
74
|
<input
|
|
72
75
|
ref={ref}
|
|
73
76
|
type="checkbox"
|
|
74
|
-
className={
|
|
77
|
+
className={cx(`m-0 focus:z-interactable `, className)}
|
|
75
78
|
{...props}
|
|
76
79
|
/>
|
|
77
80
|
));
|
|
@@ -82,7 +85,7 @@ export const Text = forwardRef<
|
|
|
82
85
|
>(({ className, ...props }, ref) => (
|
|
83
86
|
<span
|
|
84
87
|
ref={ref}
|
|
85
|
-
className={
|
|
88
|
+
className={cx(`font-sans text-heading5 font-normal `, className)}
|
|
86
89
|
{...props}
|
|
87
90
|
/>
|
|
88
91
|
));
|
|
@@ -101,7 +104,7 @@ export const HorizontalSeparator = () => (
|
|
|
101
104
|
// >(({ className, ...props }, ref) => (
|
|
102
105
|
// <span
|
|
103
106
|
// ref={ref}
|
|
104
|
-
// className={`font-sans text-heading5 font-normal text-text-muted -mb-[6px]
|
|
107
|
+
// className={`font-sans text-heading5 font-normal text-text-muted -mb-[6px] `, className}
|
|
105
108
|
// {...props}
|
|
106
109
|
// />
|
|
107
110
|
// ));
|
|
@@ -119,7 +122,10 @@ export const RowLabel = forwardRef(function RowLabel(
|
|
|
119
122
|
return (
|
|
120
123
|
<label
|
|
121
124
|
ref={ref}
|
|
122
|
-
className={
|
|
125
|
+
className={cx(
|
|
126
|
+
`font-sans text-label uppercase flex items-center leading-[19px] font-bold text-text-subtle z-label ${$textStyle && textStyles[$textStyle]} `,
|
|
127
|
+
className
|
|
128
|
+
)}
|
|
123
129
|
{...props}
|
|
124
130
|
/>
|
|
125
131
|
);
|
|
@@ -143,7 +149,7 @@ export const LabeledRow = memo(function LabeledRow({
|
|
|
143
149
|
className,
|
|
144
150
|
}: LabeledRowProps) {
|
|
145
151
|
return (
|
|
146
|
-
<Row id={id} className={className
|
|
152
|
+
<Row id={id} className={className}>
|
|
147
153
|
<Column>
|
|
148
154
|
<RowLabel $textStyle={labelTextStyle}>
|
|
149
155
|
{label}
|
package/src/components/Label.tsx
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import React, { forwardRef, LabelHTMLAttributes, memo } from "react";
|
|
2
|
+
import { cx } from "../utils/classNames";
|
|
2
3
|
|
|
3
4
|
interface LabelProps extends LabelHTMLAttributes<HTMLLabelElement> {}
|
|
4
5
|
|
|
@@ -10,7 +11,10 @@ export const Label = memo(
|
|
|
10
11
|
return (
|
|
11
12
|
<label
|
|
12
13
|
ref={ref}
|
|
13
|
-
className={
|
|
14
|
+
className={cx(
|
|
15
|
+
`font-sans text-label uppercase flex items-center leading-[19px] select-none font-bold text-text-muted z-label `,
|
|
16
|
+
className
|
|
17
|
+
)}
|
|
14
18
|
{...props}
|
|
15
19
|
/>
|
|
16
20
|
);
|