@noya-app/noya-designsystem 0.1.31 → 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 +2 -1
- package/CHANGELOG.md +7 -0
- package/README.md +13 -1
- package/dist/index.css +1 -0
- package/dist/index.d.ts +132 -509
- package/dist/index.js +4167 -2716
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +4097 -2643
- package/dist/index.mjs.map +1 -1
- package/package.json +14 -5
- package/src/components/ActivityIndicator.tsx +4 -36
- package/src/components/Avatar.tsx +63 -62
- package/src/components/Button.tsx +53 -172
- 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 +191 -194
- 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 +31 -48
- 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 +4 -14
- 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 +3 -4
- package/src/theme/index.ts +4 -16
- package/src/utils/tailwind.ts +17 -0
- package/tailwind.config.ts +106 -166
- package/tsup.config.ts +16 -0
- package/dist/index.d.mts +0 -1443
- package/src/components/Grid.tsx +0 -54
- package/src/components/Stack.tsx +0 -164
- 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
|
|
|
@@ -59,46 +57,60 @@ const InputFieldContext = createContext<InputFieldContextValue>({
|
|
|
59
57
|
* Label
|
|
60
58
|
* ------------------------------------------------------------------------- */
|
|
61
59
|
|
|
62
|
-
const LabelContainer =
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
}
|
|
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
|
+
);
|
|
91
97
|
|
|
92
98
|
interface InputFieldLabelProps {
|
|
93
99
|
children?: ReactNode;
|
|
94
100
|
pointerEvents?: Property.PointerEvents;
|
|
95
101
|
style?: React.CSSProperties;
|
|
102
|
+
className?: string;
|
|
96
103
|
}
|
|
97
104
|
|
|
98
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 */
|
|
99
106
|
const InputFieldLabel = memo(
|
|
100
107
|
forwardRef(function InputFieldLabel(
|
|
101
|
-
{
|
|
108
|
+
{
|
|
109
|
+
children = false,
|
|
110
|
+
pointerEvents = "none",
|
|
111
|
+
style,
|
|
112
|
+
className,
|
|
113
|
+
}: InputFieldLabelProps,
|
|
102
114
|
forwardedRef: ForwardedRef<HTMLLabelElement>
|
|
103
115
|
) {
|
|
104
116
|
const { labelPosition, hasDropdown, setLabelWidth, size } =
|
|
@@ -127,6 +139,7 @@ const InputFieldLabel = memo(
|
|
|
127
139
|
$labelPosition={labelPosition}
|
|
128
140
|
$hasDropdown={hasDropdown}
|
|
129
141
|
style={style}
|
|
142
|
+
className={className}
|
|
130
143
|
>
|
|
131
144
|
{children}
|
|
132
145
|
</LabelContainer>
|
|
@@ -138,14 +151,16 @@ const InputFieldLabel = memo(
|
|
|
138
151
|
* Dropdown
|
|
139
152
|
* ------------------------------------------------------------------------- */
|
|
140
153
|
|
|
141
|
-
const DropdownContainer =
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
}
|
|
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
|
+
));
|
|
149
164
|
|
|
150
165
|
interface InputFieldDropdownProps<T extends string> {
|
|
151
166
|
id?: string;
|
|
@@ -171,7 +186,12 @@ const InputFieldDropdownMenu = memo(function InputFieldDropdownMenu<
|
|
|
171
186
|
<DropdownContainer>
|
|
172
187
|
<DropdownMenu<T> items={items} onSelect={onSelect}>
|
|
173
188
|
{children || (
|
|
174
|
-
<Button
|
|
189
|
+
<Button
|
|
190
|
+
id={id}
|
|
191
|
+
variant="thin"
|
|
192
|
+
className="flex flex-1"
|
|
193
|
+
contentStyle={contentStyle}
|
|
194
|
+
>
|
|
175
195
|
<CaretDownIcon />
|
|
176
196
|
</Button>
|
|
177
197
|
)}
|
|
@@ -184,26 +204,26 @@ const InputFieldDropdownMenu = memo(function InputFieldDropdownMenu<
|
|
|
184
204
|
* Button
|
|
185
205
|
* ------------------------------------------------------------------------- */
|
|
186
206
|
|
|
187
|
-
const ButtonContainer =
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
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
|
+
));
|
|
194
219
|
|
|
195
220
|
/** Inserts a Button at the end of the input. Should not be used with an InputField.Label */
|
|
196
221
|
const InputFieldButton = memo(
|
|
197
222
|
forwardRef(function InputFieldButton(
|
|
198
|
-
|
|
199
|
-
children,
|
|
200
|
-
onClick,
|
|
201
|
-
}: {
|
|
202
|
-
children?: ReactNode;
|
|
203
|
-
onClick?: () => void;
|
|
204
|
-
},
|
|
223
|
+
props: React.ButtonHTMLAttributes<HTMLButtonElement>,
|
|
205
224
|
forwardedRef: ForwardedRef<HTMLButtonElement>
|
|
206
225
|
) {
|
|
226
|
+
const { children, onClick, ...rest } = props;
|
|
207
227
|
const { size, inputRef, setButtonWidth } = useContext(InputFieldContext);
|
|
208
228
|
|
|
209
229
|
const ref = useRef<HTMLButtonElement | null>(null);
|
|
@@ -219,7 +239,7 @@ const InputFieldButton = memo(
|
|
|
219
239
|
}, [setButtonWidth]);
|
|
220
240
|
|
|
221
241
|
const defaultHandleClick = useCallback(
|
|
222
|
-
(event: React.MouseEvent) => {
|
|
242
|
+
(event: React.MouseEvent<HTMLButtonElement>) => {
|
|
223
243
|
if (inputRef && typeof inputRef !== "function") {
|
|
224
244
|
inputRef.current?.focus();
|
|
225
245
|
// Select all text
|
|
@@ -232,10 +252,13 @@ const InputFieldButton = memo(
|
|
|
232
252
|
[inputRef]
|
|
233
253
|
);
|
|
234
254
|
|
|
235
|
-
const handlePointerDown = useCallback(
|
|
236
|
-
event.
|
|
237
|
-
|
|
238
|
-
|
|
255
|
+
const handlePointerDown = useCallback(
|
|
256
|
+
(event: React.PointerEvent<HTMLButtonElement>) => {
|
|
257
|
+
event.preventDefault();
|
|
258
|
+
event.stopPropagation();
|
|
259
|
+
},
|
|
260
|
+
[]
|
|
261
|
+
);
|
|
239
262
|
|
|
240
263
|
return (
|
|
241
264
|
<ButtonContainer $size={size}>
|
|
@@ -249,6 +272,7 @@ const InputFieldButton = memo(
|
|
|
249
272
|
onPointerDown={handlePointerDown}
|
|
250
273
|
tabIndex={-1}
|
|
251
274
|
size={size === "medium" ? "normal" : size}
|
|
275
|
+
{...rest}
|
|
252
276
|
>
|
|
253
277
|
{children}
|
|
254
278
|
</Button>
|
|
@@ -270,7 +294,7 @@ const InputFieldButton = memo(
|
|
|
270
294
|
|
|
271
295
|
type InputFieldVariant = "normal" | "bare";
|
|
272
296
|
|
|
273
|
-
|
|
297
|
+
type InputElementProps = {
|
|
274
298
|
disabled?: boolean;
|
|
275
299
|
readOnly?: boolean;
|
|
276
300
|
$labelPosition: LabelPosition;
|
|
@@ -279,89 +303,75 @@ export const InputElement = styled(TextInput)<{
|
|
|
279
303
|
$textAlign?: Property.TextAlign;
|
|
280
304
|
$variant?: InputFieldVariant;
|
|
281
305
|
$size: InputFieldSize;
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
flex: "1 1 0px",
|
|
309
|
-
position: "relative",
|
|
310
|
-
border: "0",
|
|
311
|
-
outline: "none",
|
|
312
|
-
minWidth: "0",
|
|
313
|
-
textAlign: $textAlign ?? "left",
|
|
314
|
-
alignSelf: "stretch",
|
|
315
|
-
borderRadius: "4px",
|
|
316
|
-
paddingTop: $size === "large" ? "10px" : $size === "medium" ? "4px" : "1px",
|
|
317
|
-
paddingBottom:
|
|
318
|
-
$size === "large" ? "10px" : $size === "medium" ? "4px" : "1px",
|
|
319
|
-
paddingLeft:
|
|
320
|
-
($size === "large" ? 10 : $size === "medium" ? 6 : 4) +
|
|
321
|
-
($labelSize && $labelPosition === "start" ? 6 + $labelSize : 0) +
|
|
322
|
-
"px",
|
|
323
|
-
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 =
|
|
324
332
|
($size === "large" ? 10 : $size === "medium" ? 6 : 4) +
|
|
333
|
+
($labelSize && $labelPosition === "start" ? 6 + $labelSize : 0);
|
|
334
|
+
|
|
335
|
+
const paddingRight =
|
|
336
|
+
($size === "large" ? 10 : $size === "medium" ? 6 : 1) +
|
|
325
337
|
($labelSize && $labelPosition === "end" ? 6 + $labelSize : 0) +
|
|
326
|
-
($hasDropdown ? 11 : 0)
|
|
327
|
-
"px",
|
|
328
|
-
background: theme.colors.inputBackground,
|
|
329
|
-
"&:focus": {
|
|
330
|
-
boxShadow: `0 0 0 2px ${theme.colors.primary}`,
|
|
331
|
-
},
|
|
332
|
-
...($variant === "bare" && {
|
|
333
|
-
paddingTop: "4px",
|
|
334
|
-
paddingRight: "4px",
|
|
335
|
-
paddingBottom: "4px",
|
|
336
|
-
paddingLeft: "4px",
|
|
337
|
-
marginTop: "-4px",
|
|
338
|
-
marginRight: "-4px",
|
|
339
|
-
marginBottom: "-4px",
|
|
340
|
-
marginLeft: "-4px",
|
|
341
|
-
}),
|
|
338
|
+
($hasDropdown ? 11 : 0);
|
|
342
339
|
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
}
|
|
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
|
+
};
|
|
353
370
|
|
|
354
371
|
/** Should always be wrapped in InputField.Root */
|
|
355
372
|
const InputFieldInput = forwardRef(function InputFieldInput(
|
|
356
373
|
// onFocusChange should only be passed from the root, never directly
|
|
357
|
-
{
|
|
358
|
-
textAlign,
|
|
359
|
-
variant,
|
|
360
|
-
...rest
|
|
361
|
-
}: TextInputProps & {
|
|
362
|
-
textAlign?: Property.TextAlign;
|
|
363
|
-
variant?: "bare";
|
|
364
|
-
},
|
|
374
|
+
{ textAlign, variant, ...rest }: InputFieldInputProps,
|
|
365
375
|
forwardedRef: ForwardedRef<HTMLInputElement>
|
|
366
376
|
) {
|
|
367
377
|
const {
|
|
@@ -411,7 +421,6 @@ const InputFieldTypeahead = (props: { prefix: string; value: string }) => {
|
|
|
411
421
|
|
|
412
422
|
return (
|
|
413
423
|
<InputElement
|
|
414
|
-
as="span"
|
|
415
424
|
$labelPosition={labelPosition}
|
|
416
425
|
$labelSize={labelSize}
|
|
417
426
|
$hasDropdown={hasDropdown}
|
|
@@ -419,19 +428,9 @@ const InputFieldTypeahead = (props: { prefix: string; value: string }) => {
|
|
|
419
428
|
// onFocusChange={onFocusChange}
|
|
420
429
|
// readOnly
|
|
421
430
|
// placeholder={props.value}
|
|
431
|
+
{...props}
|
|
422
432
|
value=""
|
|
423
|
-
|
|
424
|
-
position: "absolute",
|
|
425
|
-
top: 0,
|
|
426
|
-
left: 0,
|
|
427
|
-
right: 0,
|
|
428
|
-
bottom: 0,
|
|
429
|
-
width: "100%",
|
|
430
|
-
height: "100%",
|
|
431
|
-
pointerEvents: "none",
|
|
432
|
-
background: "transparent",
|
|
433
|
-
boxShadow: "none",
|
|
434
|
-
}}
|
|
433
|
+
className="absolute inset-0 w-full h-full pointer-events-none bg-transparent shadow-none"
|
|
435
434
|
>
|
|
436
435
|
<span style={{ opacity: 0 }}>{props.prefix}</span>
|
|
437
436
|
<span style={{ opacity: 0.5 }}>
|
|
@@ -556,16 +555,23 @@ function InputFieldNumberInput(props: InputFieldNumberInputProps) {
|
|
|
556
555
|
* Root
|
|
557
556
|
* ------------------------------------------------------------------------- */
|
|
558
557
|
|
|
559
|
-
const RootContainer =
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
}
|
|
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
|
+
));
|
|
569
575
|
|
|
570
576
|
interface InputFieldRootProps {
|
|
571
577
|
id?: string;
|
|
@@ -686,9 +692,9 @@ function InputFieldRoot({
|
|
|
686
692
|
}}
|
|
687
693
|
>
|
|
688
694
|
{measuredWidth && (
|
|
689
|
-
<
|
|
695
|
+
<div className={`flex flex-col w-[${measuredWidth}] hidden`}>
|
|
690
696
|
{renderPopoverContent({ width: measuredWidth })}
|
|
691
|
-
</
|
|
697
|
+
</div>
|
|
692
698
|
)}
|
|
693
699
|
</Popover>
|
|
694
700
|
) : (
|
|
@@ -698,38 +704,29 @@ function InputFieldRoot({
|
|
|
698
704
|
);
|
|
699
705
|
}
|
|
700
706
|
|
|
701
|
-
const PrimitiveInputField =
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
flex
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
paddingRight: "6px",
|
|
725
|
-
background: theme.colors.inputBackground,
|
|
726
|
-
"&:focus": {
|
|
727
|
-
boxShadow: `0 0 0 2px ${theme.colors.primary}`,
|
|
728
|
-
},
|
|
729
|
-
userSelect: "all",
|
|
730
|
-
pointerEvents: "all",
|
|
731
|
-
};
|
|
732
|
-
});
|
|
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
|
+
);
|
|
733
730
|
|
|
734
731
|
export namespace InputField {
|
|
735
732
|
export const Root = memo(InputFieldRoot);
|
|
@@ -13,18 +13,16 @@ import React, {
|
|
|
13
13
|
useRef,
|
|
14
14
|
useState,
|
|
15
15
|
} from "react";
|
|
16
|
-
import styled from "styled-components";
|
|
17
16
|
import {
|
|
18
17
|
CompletionItem,
|
|
19
18
|
CompletionListItem,
|
|
20
19
|
CompletionSectionHeader,
|
|
21
20
|
} from "../utils/completions";
|
|
22
|
-
import {
|
|
21
|
+
import { fuzzyFilter, fuzzyTokenize } from "../utils/fuzzyScorer";
|
|
23
22
|
import { ActivityIndicator } from "./ActivityIndicator";
|
|
24
23
|
import { InputField, InputFieldSize } from "./InputField";
|
|
25
24
|
import { IVirtualizedList, ListView } from "./ListView";
|
|
26
25
|
import { Spacer } from "./Spacer";
|
|
27
|
-
import { Stack } from "./Stack";
|
|
28
26
|
import { Small } from "./Text";
|
|
29
27
|
|
|
30
28
|
function filterWithGroupedSections(
|
|
@@ -66,13 +64,6 @@ function filterWithGroupedSections(
|
|
|
66
64
|
});
|
|
67
65
|
}
|
|
68
66
|
|
|
69
|
-
export const CompletionToken = styled.span<{ $type: IToken["type"] }>(
|
|
70
|
-
({ $type }) => ({
|
|
71
|
-
fontWeight: $type === "match" ? "bold" : "normal",
|
|
72
|
-
whiteSpace: "pre",
|
|
73
|
-
})
|
|
74
|
-
);
|
|
75
|
-
|
|
76
67
|
interface CompletionMenuProps {
|
|
77
68
|
items: CompletionListItem[];
|
|
78
69
|
selectedIndex: number;
|
|
@@ -127,9 +118,12 @@ export const CompletionMenu = memo(
|
|
|
127
118
|
}}
|
|
128
119
|
>
|
|
129
120
|
{tokens.map((token, j) => (
|
|
130
|
-
<
|
|
121
|
+
<span
|
|
122
|
+
key={j}
|
|
123
|
+
className={`${token.type === "match" ? "font-bold" : "font-normal"} whitespace-pre`}
|
|
124
|
+
>
|
|
131
125
|
{token.text}
|
|
132
|
-
</
|
|
126
|
+
</span>
|
|
133
127
|
))}
|
|
134
128
|
{item.icon && (
|
|
135
129
|
<>
|
|
@@ -145,7 +139,7 @@ export const CompletionMenu = memo(
|
|
|
145
139
|
})
|
|
146
140
|
);
|
|
147
141
|
|
|
148
|
-
type
|
|
142
|
+
export type InputFieldWithCompletionsProps = {
|
|
149
143
|
loading?: boolean;
|
|
150
144
|
initialValue?: string;
|
|
151
145
|
placeholder?: string;
|
|
@@ -164,7 +158,7 @@ type Props = {
|
|
|
164
158
|
hideMenuWhenEmptyValue?: boolean;
|
|
165
159
|
};
|
|
166
160
|
|
|
167
|
-
export interface
|
|
161
|
+
export interface InputFieldWithCompletionsRef {
|
|
168
162
|
focus(): void;
|
|
169
163
|
setValue(value: string): void;
|
|
170
164
|
selectAllInputText(): void;
|
|
@@ -189,8 +183,8 @@ export const InputFieldWithCompletions = memo(
|
|
|
189
183
|
children,
|
|
190
184
|
hideChildrenWhenFocused = false,
|
|
191
185
|
hideMenuWhenEmptyValue = false,
|
|
192
|
-
}:
|
|
193
|
-
forwardedRef: ForwardedRef<
|
|
186
|
+
}: InputFieldWithCompletionsProps,
|
|
187
|
+
forwardedRef: ForwardedRef<InputFieldWithCompletionsRef>
|
|
194
188
|
) {
|
|
195
189
|
const ref = useRef<HTMLInputElement>(null);
|
|
196
190
|
|
|
@@ -416,12 +410,16 @@ export const InputFieldWithCompletions = memo(
|
|
|
416
410
|
return (
|
|
417
411
|
<InputField.Root
|
|
418
412
|
size={size}
|
|
419
|
-
labelSize={16}
|
|
420
413
|
renderPopoverContent={({ width }) => {
|
|
421
414
|
const listSize = { width, height };
|
|
422
415
|
|
|
423
416
|
return (
|
|
424
|
-
<
|
|
417
|
+
<div
|
|
418
|
+
className={`flex flex-col ${!filter && hideMenuWhenEmptyValue ? "none" : "flex"}`}
|
|
419
|
+
style={{
|
|
420
|
+
flex: `0 0 ${height}px`
|
|
421
|
+
}}
|
|
422
|
+
>
|
|
425
423
|
{filteredItems.length > 0 ? (
|
|
426
424
|
<CompletionMenu
|
|
427
425
|
ref={listRef}
|
|
@@ -432,18 +430,13 @@ export const InputFieldWithCompletions = memo(
|
|
|
432
430
|
listSize={listSize}
|
|
433
431
|
/>
|
|
434
432
|
) : (
|
|
435
|
-
<
|
|
436
|
-
|
|
437
|
-
padding="20px"
|
|
438
|
-
alignItems="center"
|
|
439
|
-
justifyContent="center"
|
|
440
|
-
>
|
|
441
|
-
<Small color="textDisabled">
|
|
433
|
+
<div className="flex flex-col h-[100px] p-5 items-center justify-center">
|
|
434
|
+
<Small className="text-text-disabled">
|
|
442
435
|
{loading ? "Loading" : "No results"}
|
|
443
436
|
</Small>
|
|
444
|
-
</
|
|
437
|
+
</div>
|
|
445
438
|
)}
|
|
446
|
-
</
|
|
439
|
+
</div>
|
|
447
440
|
);
|
|
448
441
|
}}
|
|
449
442
|
>
|