@noya-app/noya-designsystem 0.1.30 → 0.1.32
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 +20 -12
- package/.turbo/turbo-lint.log +15 -1
- package/CHANGELOG.md +17 -0
- package/README.md +13 -1
- package/dist/index.css +1 -0
- package/dist/index.d.ts +238 -627
- package/dist/index.js +4259 -2862
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +4159 -2764
- package/dist/index.mjs.map +1 -1
- package/package.json +17 -7
- package/src/components/ActivityIndicator.tsx +4 -36
- package/src/components/Avatar.tsx +63 -62
- package/src/components/Button.tsx +53 -170
- package/src/components/Chip.tsx +117 -150
- package/src/components/ContextMenu.tsx +13 -35
- package/src/components/Dialog.tsx +66 -54
- package/src/components/Divider.tsx +31 -41
- package/src/components/DraggableMenuButton.tsx +29 -30
- package/src/components/DropdownMenu.tsx +30 -40
- package/src/components/FillInputField.tsx +16 -26
- package/src/components/FillPreviewBackground.tsx +18 -22
- package/src/components/FloatingWindow.tsx +4 -7
- package/src/components/GridView.tsx +70 -200
- package/src/components/IconButton.tsx +1 -5
- package/src/components/InputField.tsx +258 -234
- package/src/components/InputFieldWithCompletions.tsx +20 -27
- package/src/components/InspectorContainer.tsx +4 -9
- package/src/components/InspectorPrimitives.tsx +135 -109
- package/src/components/Label.tsx +5 -36
- package/src/components/LabeledElementView.tsx +5 -26
- package/src/components/ListView.tsx +239 -167
- package/src/components/Popover.tsx +15 -39
- package/src/components/Progress.tsx +21 -44
- package/src/components/RadioGroup.tsx +6 -71
- package/src/components/ScrollArea.tsx +11 -39
- package/src/components/SelectMenu.tsx +72 -32
- package/src/components/Slider.tsx +7 -43
- package/src/components/Spacer.tsx +6 -18
- package/src/components/Switch.tsx +4 -42
- package/src/components/Text.tsx +31 -66
- package/src/components/TextArea.tsx +5 -31
- package/src/components/Toast.tsx +15 -57
- package/src/components/Tooltip.tsx +4 -13
- package/src/components/WorkspaceLayout.tsx +27 -17
- package/src/components/internal/Menu.tsx +37 -83
- package/src/contexts/DesignSystemConfiguration.tsx +1 -47
- package/src/contexts/DialogContext.tsx +2 -10
- package/src/hooks/useDarkMode.ts +14 -0
- package/src/index.css +108 -0
- package/src/index.tsx +4 -5
- package/src/theme/index.ts +4 -16
- package/src/utils/tailwind.ts +17 -0
- package/tailwind.config.ts +223 -0
- package/tailwind.d.ts +11 -0
- package/tsconfig.json +4 -1
- package/tsup.config.ts +16 -0
- package/dist/index.d.mts +0 -1455
- package/src/components/Grid.tsx +0 -54
- package/src/components/Select.tsx +0 -183
- package/src/components/Stack.tsx +0 -155
- package/src/theme/dark.ts +0 -45
- package/src/theme/light.ts +0 -226
- package/src/utils/breakpoints.ts +0 -45
|
@@ -17,14 +17,12 @@ import React, {
|
|
|
17
17
|
useRef,
|
|
18
18
|
useState,
|
|
19
19
|
} from "react";
|
|
20
|
-
import styled from "styled-components";
|
|
21
20
|
import handleNudge from "../utils/handleNudge";
|
|
22
21
|
import { Button } from "./Button";
|
|
23
22
|
import { DropdownMenu } from "./DropdownMenu";
|
|
24
23
|
import { MenuItem } from "./internal/Menu";
|
|
25
24
|
import TextInput, { TextInputProps } from "./internal/TextInput";
|
|
26
25
|
import { Popover } from "./Popover";
|
|
27
|
-
import { Stack } from "./Stack";
|
|
28
26
|
|
|
29
27
|
type LabelPosition = "start" | "end";
|
|
30
28
|
|
|
@@ -32,8 +30,8 @@ export type InputFieldSize = "small" | "medium" | "large";
|
|
|
32
30
|
|
|
33
31
|
type InputFieldContextValue = {
|
|
34
32
|
labelPosition: LabelPosition;
|
|
35
|
-
labelSize
|
|
36
|
-
|
|
33
|
+
labelSize?: number;
|
|
34
|
+
buttonSize?: number;
|
|
37
35
|
hasDropdown: boolean;
|
|
38
36
|
/** @default medium */
|
|
39
37
|
size: InputFieldSize;
|
|
@@ -42,12 +40,13 @@ type InputFieldContextValue = {
|
|
|
42
40
|
inputRef?: ForwardedRef<HTMLInputElement>;
|
|
43
41
|
setInputRef?: (ref: ForwardedRef<HTMLInputElement>) => void;
|
|
44
42
|
setLabelWidth?: (width: number) => void;
|
|
43
|
+
setButtonWidth?: (width: number) => void;
|
|
45
44
|
};
|
|
46
45
|
|
|
47
46
|
const InputFieldContext = createContext<InputFieldContextValue>({
|
|
48
47
|
labelPosition: "end",
|
|
49
|
-
labelSize:
|
|
50
|
-
|
|
48
|
+
labelSize: undefined,
|
|
49
|
+
buttonSize: undefined,
|
|
51
50
|
hasDropdown: false,
|
|
52
51
|
size: "medium",
|
|
53
52
|
isFocused: false,
|
|
@@ -58,43 +57,63 @@ const InputFieldContext = createContext<InputFieldContextValue>({
|
|
|
58
57
|
* Label
|
|
59
58
|
* ------------------------------------------------------------------------- */
|
|
60
59
|
|
|
61
|
-
const LabelContainer =
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
}
|
|
60
|
+
const LabelContainer = forwardRef<
|
|
61
|
+
HTMLLabelElement,
|
|
62
|
+
{
|
|
63
|
+
pointerEvents: Property.PointerEvents;
|
|
64
|
+
$labelPosition: LabelPosition;
|
|
65
|
+
$hasDropdown: boolean;
|
|
66
|
+
$size: InputFieldSize;
|
|
67
|
+
className?: string;
|
|
68
|
+
children?: React.ReactNode;
|
|
69
|
+
style?: React.CSSProperties;
|
|
70
|
+
}
|
|
71
|
+
>(
|
|
72
|
+
(
|
|
73
|
+
{ pointerEvents, $labelPosition, $hasDropdown, $size, className, style, ...props },
|
|
74
|
+
ref
|
|
75
|
+
) => {
|
|
76
|
+
const memoizedStyles = useMemo(() => ({
|
|
77
|
+
left: $labelPosition === "start" ? $size === "large" ? "6px" : $size === "medium" ? "2px" : "0px" : "",
|
|
78
|
+
right: $labelPosition === "end" ? $size === "large" ? "6px" : $size === "medium" ? "2px" : "0px" : "",
|
|
79
|
+
}), [$labelPosition, $size])
|
|
80
|
+
|
|
81
|
+
return (
|
|
82
|
+
<label
|
|
83
|
+
ref={ref}
|
|
84
|
+
className={`absolute top-0 bottom-0 flex items-center font-sans text-label font-bold uppercase text-text-disabled select-none ${
|
|
85
|
+
$labelPosition === "start"
|
|
86
|
+
? `justify-start pl-[6px]`
|
|
87
|
+
: $labelPosition === "end"
|
|
88
|
+
? `justify-end ${$hasDropdown ? "pr-[16px]" : "pr-[6px]"}`
|
|
89
|
+
: ""
|
|
90
|
+
} ${pointerEvents === "none" ? "pointer-events-none" : ""} ${className ?? ""}`}
|
|
91
|
+
style={{...memoizedStyles, ...style}}
|
|
92
|
+
{...props}
|
|
93
|
+
/>
|
|
94
|
+
);
|
|
95
|
+
}
|
|
96
|
+
);
|
|
85
97
|
|
|
86
98
|
interface InputFieldLabelProps {
|
|
87
99
|
children?: ReactNode;
|
|
88
100
|
pointerEvents?: Property.PointerEvents;
|
|
89
101
|
style?: React.CSSProperties;
|
|
102
|
+
className?: string;
|
|
90
103
|
}
|
|
91
104
|
|
|
105
|
+
/** Inserts a Label at the start or end of the input given a `labelPosition`on InputField.Root. Should not be used with an InputField.Button */
|
|
92
106
|
const InputFieldLabel = memo(
|
|
93
107
|
forwardRef(function InputFieldLabel(
|
|
94
|
-
{
|
|
108
|
+
{
|
|
109
|
+
children = false,
|
|
110
|
+
pointerEvents = "none",
|
|
111
|
+
style,
|
|
112
|
+
className,
|
|
113
|
+
}: InputFieldLabelProps,
|
|
95
114
|
forwardedRef: ForwardedRef<HTMLLabelElement>
|
|
96
115
|
) {
|
|
97
|
-
const { labelPosition, hasDropdown, setLabelWidth } =
|
|
116
|
+
const { labelPosition, hasDropdown, setLabelWidth, size } =
|
|
98
117
|
useContext(InputFieldContext);
|
|
99
118
|
|
|
100
119
|
const ref = useRef<HTMLLabelElement | null>(null);
|
|
@@ -111,6 +130,7 @@ const InputFieldLabel = memo(
|
|
|
111
130
|
|
|
112
131
|
return (
|
|
113
132
|
<LabelContainer
|
|
133
|
+
$size={size}
|
|
114
134
|
ref={(element) => {
|
|
115
135
|
ref.current = element;
|
|
116
136
|
assignRef(forwardedRef, element);
|
|
@@ -119,6 +139,7 @@ const InputFieldLabel = memo(
|
|
|
119
139
|
$labelPosition={labelPosition}
|
|
120
140
|
$hasDropdown={hasDropdown}
|
|
121
141
|
style={style}
|
|
142
|
+
className={className}
|
|
122
143
|
>
|
|
123
144
|
{children}
|
|
124
145
|
</LabelContainer>
|
|
@@ -130,14 +151,16 @@ const InputFieldLabel = memo(
|
|
|
130
151
|
* Dropdown
|
|
131
152
|
* ------------------------------------------------------------------------- */
|
|
132
153
|
|
|
133
|
-
const DropdownContainer =
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
}
|
|
154
|
+
const DropdownContainer = forwardRef<
|
|
155
|
+
HTMLSpanElement,
|
|
156
|
+
{ className?: string; children?: React.ReactNode }
|
|
157
|
+
>(({ className, ...props }, ref) => (
|
|
158
|
+
<span
|
|
159
|
+
ref={ref}
|
|
160
|
+
className={`absolute inset-y-0 right-0 flex flex-col ${className ?? ""}`}
|
|
161
|
+
{...props}
|
|
162
|
+
/>
|
|
163
|
+
));
|
|
141
164
|
|
|
142
165
|
interface InputFieldDropdownProps<T extends string> {
|
|
143
166
|
id?: string;
|
|
@@ -163,7 +186,12 @@ const InputFieldDropdownMenu = memo(function InputFieldDropdownMenu<
|
|
|
163
186
|
<DropdownContainer>
|
|
164
187
|
<DropdownMenu<T> items={items} onSelect={onSelect}>
|
|
165
188
|
{children || (
|
|
166
|
-
<Button
|
|
189
|
+
<Button
|
|
190
|
+
id={id}
|
|
191
|
+
variant="thin"
|
|
192
|
+
className="flex flex-1"
|
|
193
|
+
contentStyle={contentStyle}
|
|
194
|
+
>
|
|
167
195
|
<CaretDownIcon />
|
|
168
196
|
</Button>
|
|
169
197
|
)}
|
|
@@ -176,55 +204,82 @@ const InputFieldDropdownMenu = memo(function InputFieldDropdownMenu<
|
|
|
176
204
|
* Button
|
|
177
205
|
* ------------------------------------------------------------------------- */
|
|
178
206
|
|
|
179
|
-
const ButtonContainer =
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
207
|
+
const ButtonContainer = forwardRef<
|
|
208
|
+
HTMLSpanElement,
|
|
209
|
+
{ $size: InputFieldSize; className?: string; children?: React.ReactNode }
|
|
210
|
+
>(({ $size, className, ...props }, ref) => (
|
|
211
|
+
<span
|
|
212
|
+
ref={ref}
|
|
213
|
+
className={`absolute ${$size === "large" ? "right-[9px] top-[10px]" :
|
|
214
|
+
$size === "medium" ? "right-[4px] top-[4px]" :
|
|
215
|
+
$size === "small" ? "right-[2px] top-[2px]" : ""} ${className ?? ""}`}
|
|
216
|
+
{...props}
|
|
217
|
+
/>
|
|
218
|
+
));
|
|
219
|
+
|
|
220
|
+
/** Inserts a Button at the end of the input. Should not be used with an InputField.Label */
|
|
221
|
+
const InputFieldButton = memo(
|
|
222
|
+
forwardRef(function InputFieldButton(
|
|
223
|
+
props: React.ButtonHTMLAttributes<HTMLButtonElement>,
|
|
224
|
+
forwardedRef: ForwardedRef<HTMLButtonElement>
|
|
225
|
+
) {
|
|
226
|
+
const { children, onClick, ...rest } = props;
|
|
227
|
+
const { size, inputRef, setButtonWidth } = useContext(InputFieldContext);
|
|
186
228
|
|
|
187
|
-
const
|
|
188
|
-
children,
|
|
189
|
-
onClick,
|
|
190
|
-
}: {
|
|
191
|
-
children?: ReactNode;
|
|
192
|
-
onClick?: () => void;
|
|
193
|
-
}) {
|
|
194
|
-
const { size, inputRef } = useContext(InputFieldContext);
|
|
195
|
-
|
|
196
|
-
const defaultHandleClick = useCallback(
|
|
197
|
-
(event: React.MouseEvent) => {
|
|
198
|
-
if (inputRef && typeof inputRef !== "function") {
|
|
199
|
-
inputRef.current?.focus();
|
|
200
|
-
// Select all text
|
|
201
|
-
inputRef.current?.setSelectionRange(0, inputRef.current.value.length);
|
|
202
|
-
}
|
|
229
|
+
const ref = useRef<HTMLButtonElement | null>(null);
|
|
203
230
|
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
},
|
|
207
|
-
[inputRef]
|
|
208
|
-
);
|
|
231
|
+
useLayoutEffect(() => {
|
|
232
|
+
if (!setButtonWidth) return;
|
|
209
233
|
|
|
210
|
-
|
|
211
|
-
event.preventDefault();
|
|
212
|
-
event.stopPropagation();
|
|
213
|
-
}, []);
|
|
234
|
+
const width = ref.current?.getBoundingClientRect().width;
|
|
214
235
|
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
236
|
+
if (!width) return;
|
|
237
|
+
|
|
238
|
+
setButtonWidth(width);
|
|
239
|
+
}, [setButtonWidth]);
|
|
240
|
+
|
|
241
|
+
const defaultHandleClick = useCallback(
|
|
242
|
+
(event: React.MouseEvent<HTMLButtonElement>) => {
|
|
243
|
+
if (inputRef && typeof inputRef !== "function") {
|
|
244
|
+
inputRef.current?.focus();
|
|
245
|
+
// Select all text
|
|
246
|
+
inputRef.current?.setSelectionRange(0, inputRef.current.value.length);
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
event.preventDefault();
|
|
250
|
+
event.stopPropagation();
|
|
251
|
+
},
|
|
252
|
+
[inputRef]
|
|
253
|
+
);
|
|
254
|
+
|
|
255
|
+
const handlePointerDown = useCallback(
|
|
256
|
+
(event: React.PointerEvent<HTMLButtonElement>) => {
|
|
257
|
+
event.preventDefault();
|
|
258
|
+
event.stopPropagation();
|
|
259
|
+
},
|
|
260
|
+
[]
|
|
261
|
+
);
|
|
262
|
+
|
|
263
|
+
return (
|
|
264
|
+
<ButtonContainer $size={size}>
|
|
265
|
+
<Button
|
|
266
|
+
ref={(element) => {
|
|
267
|
+
ref.current = element;
|
|
268
|
+
assignRef(forwardedRef, element);
|
|
269
|
+
}}
|
|
270
|
+
variant="floating"
|
|
271
|
+
onClick={onClick ?? defaultHandleClick}
|
|
272
|
+
onPointerDown={handlePointerDown}
|
|
273
|
+
tabIndex={-1}
|
|
274
|
+
size={size === "medium" ? "normal" : size}
|
|
275
|
+
{...rest}
|
|
276
|
+
>
|
|
277
|
+
{children}
|
|
278
|
+
</Button>
|
|
279
|
+
</ButtonContainer>
|
|
280
|
+
);
|
|
281
|
+
})
|
|
282
|
+
);
|
|
228
283
|
|
|
229
284
|
/* ----------------------------------------------------------------------------
|
|
230
285
|
* Input
|
|
@@ -239,106 +294,91 @@ const InputFieldButton = memo(function InputFieldButton({
|
|
|
239
294
|
|
|
240
295
|
type InputFieldVariant = "normal" | "bare";
|
|
241
296
|
|
|
242
|
-
|
|
297
|
+
type InputElementProps = {
|
|
243
298
|
disabled?: boolean;
|
|
244
299
|
readOnly?: boolean;
|
|
245
300
|
$labelPosition: LabelPosition;
|
|
246
|
-
$labelSize
|
|
247
|
-
$hasLabel: boolean;
|
|
301
|
+
$labelSize?: number;
|
|
248
302
|
$hasDropdown: boolean;
|
|
249
303
|
$textAlign?: Property.TextAlign;
|
|
250
304
|
$variant?: InputFieldVariant;
|
|
251
305
|
$size: InputFieldSize;
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
width: "0px", // Reset intrinsic width
|
|
279
|
-
flex: "1 1 0px",
|
|
280
|
-
position: "relative",
|
|
281
|
-
border: "0",
|
|
282
|
-
outline: "none",
|
|
283
|
-
minWidth: "0",
|
|
284
|
-
textAlign: $textAlign ?? "left",
|
|
285
|
-
alignSelf: "stretch",
|
|
286
|
-
borderRadius: "4px",
|
|
287
|
-
paddingTop: $size === "large" ? "10px" : $size === "medium" ? "4px" : "1px",
|
|
288
|
-
paddingBottom:
|
|
289
|
-
$size === "large" ? "10px" : $size === "medium" ? "4px" : "1px",
|
|
290
|
-
paddingLeft:
|
|
291
|
-
($size === "large" ? 10 : $size === "medium" ? 6 : 4) +
|
|
292
|
-
($hasLabel && $labelPosition === "start" ? 6 + $labelSize : 0) +
|
|
293
|
-
"px",
|
|
294
|
-
paddingRight:
|
|
306
|
+
children?: React.ReactNode;
|
|
307
|
+
className?: string;
|
|
308
|
+
value?: string;
|
|
309
|
+
onSubmit?: (value: string) => void;
|
|
310
|
+
};
|
|
311
|
+
|
|
312
|
+
const InputElement = forwardRef(
|
|
313
|
+
(
|
|
314
|
+
{
|
|
315
|
+
disabled,
|
|
316
|
+
readOnly,
|
|
317
|
+
$labelPosition,
|
|
318
|
+
$labelSize,
|
|
319
|
+
$hasDropdown,
|
|
320
|
+
$textAlign,
|
|
321
|
+
$variant = "normal",
|
|
322
|
+
$size,
|
|
323
|
+
className,
|
|
324
|
+
children,
|
|
325
|
+
value,
|
|
326
|
+
onSubmit,
|
|
327
|
+
...props
|
|
328
|
+
}: InputElementProps,
|
|
329
|
+
ref: ForwardedRef<any>
|
|
330
|
+
) => {
|
|
331
|
+
const paddingLeft =
|
|
295
332
|
($size === "large" ? 10 : $size === "medium" ? 6 : 4) +
|
|
296
|
-
($
|
|
297
|
-
($hasDropdown ? 11 : 0) +
|
|
298
|
-
"px",
|
|
299
|
-
background: theme.colors.inputBackground,
|
|
300
|
-
"&:focus": {
|
|
301
|
-
boxShadow: `0 0 0 2px ${theme.colors.primary}`,
|
|
302
|
-
},
|
|
303
|
-
...($variant === "bare" && {
|
|
304
|
-
paddingTop: "4px",
|
|
305
|
-
paddingRight: "4px",
|
|
306
|
-
paddingBottom: "4px",
|
|
307
|
-
paddingLeft: "4px",
|
|
308
|
-
marginTop: "-4px",
|
|
309
|
-
marginRight: "-4px",
|
|
310
|
-
marginBottom: "-4px",
|
|
311
|
-
marginLeft: "-4px",
|
|
312
|
-
}),
|
|
333
|
+
($labelSize && $labelPosition === "start" ? 6 + $labelSize : 0);
|
|
313
334
|
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
// background: `url("data:image/svg+xml;utf8,${createCrossSVGString(
|
|
319
|
-
// theme.colors.icon
|
|
320
|
-
// )}") no-repeat`,
|
|
321
|
-
// },
|
|
322
|
-
};
|
|
323
|
-
});
|
|
335
|
+
const paddingRight =
|
|
336
|
+
($size === "large" ? 10 : $size === "medium" ? 6 : 1) +
|
|
337
|
+
($labelSize && $labelPosition === "end" ? 6 + $labelSize : 0) +
|
|
338
|
+
($hasDropdown ? 11 : 0);
|
|
324
339
|
|
|
340
|
+
const memoizedStyles = useMemo(() => ({
|
|
341
|
+
paddingLeft: `${paddingLeft}px`,
|
|
342
|
+
paddingRight: `${paddingRight}px`,
|
|
343
|
+
}), [paddingLeft, paddingRight])
|
|
344
|
+
|
|
345
|
+
return (
|
|
346
|
+
<TextInput
|
|
347
|
+
value={value ?? ""}
|
|
348
|
+
onSubmit={onSubmit ?? (() => {})}
|
|
349
|
+
ref={ref}
|
|
350
|
+
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 focus:z-10 placeholder:text-text-disabled ${readOnly ? "text-text-muted" : disabled ? "text-text-disabled" : "text-text"} font-sans font-normal ${$textAlign && `text-${$textAlign}`} ${
|
|
351
|
+
$size === "small"
|
|
352
|
+
? "text-[11px] leading-[19px] py-[1px]"
|
|
353
|
+
: $size === "large"
|
|
354
|
+
? "py-[10px] text-heading5"
|
|
355
|
+
: $size === "medium"
|
|
356
|
+
? "py-1 text-heading5"
|
|
357
|
+
: $variant === "bare" && "p-1 -m-1"
|
|
358
|
+
} ${className ?? ""}`}
|
|
359
|
+
style={memoizedStyles}
|
|
360
|
+
{...props}
|
|
361
|
+
/>
|
|
362
|
+
);
|
|
363
|
+
}
|
|
364
|
+
);
|
|
365
|
+
|
|
366
|
+
export type InputFieldInputProps = TextInputProps & {
|
|
367
|
+
textAlign?: Property.TextAlign;
|
|
368
|
+
variant?: "bare";
|
|
369
|
+
};
|
|
370
|
+
|
|
371
|
+
/** Should always be wrapped in InputField.Root */
|
|
325
372
|
const InputFieldInput = forwardRef(function InputFieldInput(
|
|
326
373
|
// onFocusChange should only be passed from the root, never directly
|
|
327
|
-
{
|
|
328
|
-
textAlign,
|
|
329
|
-
variant,
|
|
330
|
-
...rest
|
|
331
|
-
}: TextInputProps & {
|
|
332
|
-
textAlign?: Property.TextAlign;
|
|
333
|
-
variant?: "bare";
|
|
334
|
-
},
|
|
374
|
+
{ textAlign, variant, ...rest }: InputFieldInputProps,
|
|
335
375
|
forwardedRef: ForwardedRef<HTMLInputElement>
|
|
336
376
|
) {
|
|
337
377
|
const {
|
|
338
378
|
labelPosition,
|
|
339
379
|
labelSize,
|
|
340
380
|
hasDropdown,
|
|
341
|
-
|
|
381
|
+
buttonSize,
|
|
342
382
|
size,
|
|
343
383
|
onFocusChange,
|
|
344
384
|
setInputRef,
|
|
@@ -359,8 +399,7 @@ const InputFieldInput = forwardRef(function InputFieldInput(
|
|
|
359
399
|
<InputElement
|
|
360
400
|
ref={forwardedRef}
|
|
361
401
|
$labelPosition={labelPosition}
|
|
362
|
-
$labelSize={labelSize}
|
|
363
|
-
$hasLabel={hasLabel}
|
|
402
|
+
$labelSize={labelSize || buttonSize}
|
|
364
403
|
$hasDropdown={hasDropdown}
|
|
365
404
|
$size={size}
|
|
366
405
|
$variant={variant}
|
|
@@ -376,35 +415,22 @@ const InputFieldTypeahead = (props: { prefix: string; value: string }) => {
|
|
|
376
415
|
labelPosition,
|
|
377
416
|
labelSize,
|
|
378
417
|
hasDropdown,
|
|
379
|
-
hasLabel,
|
|
380
418
|
size,
|
|
381
419
|
// onFocusChange,
|
|
382
420
|
} = useContext(InputFieldContext);
|
|
383
421
|
|
|
384
422
|
return (
|
|
385
423
|
<InputElement
|
|
386
|
-
as="span"
|
|
387
424
|
$labelPosition={labelPosition}
|
|
388
425
|
$labelSize={labelSize}
|
|
389
|
-
$hasLabel={hasLabel}
|
|
390
426
|
$hasDropdown={hasDropdown}
|
|
391
427
|
$size={size}
|
|
392
428
|
// onFocusChange={onFocusChange}
|
|
393
429
|
// readOnly
|
|
394
430
|
// placeholder={props.value}
|
|
431
|
+
{...props}
|
|
395
432
|
value=""
|
|
396
|
-
|
|
397
|
-
position: "absolute",
|
|
398
|
-
top: 0,
|
|
399
|
-
left: 0,
|
|
400
|
-
right: 0,
|
|
401
|
-
bottom: 0,
|
|
402
|
-
width: "100%",
|
|
403
|
-
height: "100%",
|
|
404
|
-
pointerEvents: "none",
|
|
405
|
-
background: "transparent",
|
|
406
|
-
boxShadow: "none",
|
|
407
|
-
}}
|
|
433
|
+
className="absolute inset-0 w-full h-full pointer-events-none bg-transparent shadow-none"
|
|
408
434
|
>
|
|
409
435
|
<span style={{ opacity: 0 }}>{props.prefix}</span>
|
|
410
436
|
<span style={{ opacity: 0.5 }}>
|
|
@@ -529,15 +555,23 @@ function InputFieldNumberInput(props: InputFieldNumberInputProps) {
|
|
|
529
555
|
* Root
|
|
530
556
|
* ------------------------------------------------------------------------- */
|
|
531
557
|
|
|
532
|
-
const RootContainer =
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
558
|
+
const RootContainer = forwardRef<
|
|
559
|
+
HTMLDivElement,
|
|
560
|
+
{
|
|
561
|
+
$width?: number;
|
|
562
|
+
$flex?: string;
|
|
563
|
+
className?: string;
|
|
564
|
+
children?: React.ReactNode;
|
|
565
|
+
id?: string;
|
|
566
|
+
style?: React.CSSProperties;
|
|
567
|
+
}
|
|
568
|
+
>(({ $width, $flex, className, ...props }, ref) => (
|
|
569
|
+
<div
|
|
570
|
+
ref={ref}
|
|
571
|
+
className={`flex flex-row relative ${$flex ? `flex-[${$flex}]` : "flex-1"} ${$width || $width === 0 ? `max-w-[${$width}px]` : ""} ${className ?? ""}`}
|
|
572
|
+
{...props}
|
|
573
|
+
/>
|
|
574
|
+
));
|
|
541
575
|
|
|
542
576
|
interface InputFieldRootProps {
|
|
543
577
|
id?: string;
|
|
@@ -574,13 +608,11 @@ function InputFieldRoot({
|
|
|
574
608
|
const hasDropdown = childrenArray.some(
|
|
575
609
|
(child) => isValidElement(child) && child.type === InputFieldDropdownMenu
|
|
576
610
|
);
|
|
577
|
-
const hasLabel = childrenArray.some(
|
|
578
|
-
(child) => isValidElement(child) && child.type === InputFieldLabel
|
|
579
|
-
);
|
|
580
611
|
|
|
581
612
|
const [isFocused, setIsFocused] = React.useState(false);
|
|
582
613
|
|
|
583
614
|
const [measuredLabelSize, setMeasuredLabelSize] = React.useState<number>();
|
|
615
|
+
const [measuredButtonSize, setMeasuredButtonSize] = React.useState<number>();
|
|
584
616
|
const [measuredWidth, setMeasuredWidth] = React.useState<number>();
|
|
585
617
|
|
|
586
618
|
const handleFocusChange = useCallback(
|
|
@@ -606,22 +638,23 @@ function InputFieldRoot({
|
|
|
606
638
|
const contextValue = useMemo(
|
|
607
639
|
(): InputFieldContextValue => ({
|
|
608
640
|
labelPosition,
|
|
609
|
-
labelSize: measuredLabelSize ?? labelSize
|
|
641
|
+
labelSize: measuredLabelSize ?? labelSize,
|
|
642
|
+
buttonSize: measuredButtonSize,
|
|
610
643
|
hasDropdown,
|
|
611
|
-
hasLabel,
|
|
612
644
|
size,
|
|
613
645
|
isFocused,
|
|
614
646
|
onFocusChange: handleFocusChange,
|
|
615
647
|
inputRef,
|
|
616
648
|
setInputRef,
|
|
617
649
|
setLabelWidth: setMeasuredLabelSize,
|
|
650
|
+
setButtonWidth: setMeasuredButtonSize,
|
|
618
651
|
}),
|
|
619
652
|
[
|
|
620
653
|
labelPosition,
|
|
621
654
|
measuredLabelSize,
|
|
622
655
|
labelSize,
|
|
656
|
+
measuredButtonSize,
|
|
623
657
|
hasDropdown,
|
|
624
|
-
hasLabel,
|
|
625
658
|
size,
|
|
626
659
|
isFocused,
|
|
627
660
|
handleFocusChange,
|
|
@@ -659,9 +692,9 @@ function InputFieldRoot({
|
|
|
659
692
|
}}
|
|
660
693
|
>
|
|
661
694
|
{measuredWidth && (
|
|
662
|
-
<
|
|
695
|
+
<div className={`flex flex-col w-[${measuredWidth}] hidden`}>
|
|
663
696
|
{renderPopoverContent({ width: measuredWidth })}
|
|
664
|
-
</
|
|
697
|
+
</div>
|
|
665
698
|
)}
|
|
666
699
|
</Popover>
|
|
667
700
|
) : (
|
|
@@ -671,38 +704,29 @@ function InputFieldRoot({
|
|
|
671
704
|
);
|
|
672
705
|
}
|
|
673
706
|
|
|
674
|
-
const PrimitiveInputField =
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
flex
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
paddingRight: "6px",
|
|
698
|
-
background: theme.colors.inputBackground,
|
|
699
|
-
"&:focus": {
|
|
700
|
-
boxShadow: `0 0 0 2px ${theme.colors.primary}`,
|
|
701
|
-
},
|
|
702
|
-
userSelect: "all",
|
|
703
|
-
pointerEvents: "all",
|
|
704
|
-
};
|
|
705
|
-
});
|
|
707
|
+
const PrimitiveInputField = ({
|
|
708
|
+
readOnly,
|
|
709
|
+
disabled,
|
|
710
|
+
className,
|
|
711
|
+
...props
|
|
712
|
+
}: {
|
|
713
|
+
readOnly?: boolean;
|
|
714
|
+
disabled?: boolean;
|
|
715
|
+
} & React.DetailedHTMLProps<
|
|
716
|
+
React.InputHTMLAttributes<HTMLInputElement>,
|
|
717
|
+
HTMLInputElement
|
|
718
|
+
>) => (
|
|
719
|
+
<input
|
|
720
|
+
className={`flex w-0 flex-1 relative border-none outline-none min-w-0 self-stretch rounded py-1 px-1.5 bg-input-background select-all pointer-events-[all] focus:ring-2 focus:ring-primary focus:z-10 font-sans font-normal text-heading5 placeholder:text-text-disabled ${
|
|
721
|
+
readOnly
|
|
722
|
+
? "text-text-muted"
|
|
723
|
+
: disabled
|
|
724
|
+
? "text-text-disabled"
|
|
725
|
+
: "text-text"
|
|
726
|
+
} ${className ?? ""}`}
|
|
727
|
+
{...props}
|
|
728
|
+
/>
|
|
729
|
+
);
|
|
706
730
|
|
|
707
731
|
export namespace InputField {
|
|
708
732
|
export const Root = memo(InputFieldRoot);
|