@noya-app/noya-designsystem 0.1.38 → 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.
Files changed (50) hide show
  1. package/.turbo/turbo-build.log +10 -10
  2. package/CHANGELOG.md +16 -0
  3. package/dist/index.css +1 -1
  4. package/dist/index.d.mts +416 -321
  5. package/dist/index.d.ts +416 -321
  6. package/dist/index.js +9555 -11325
  7. package/dist/index.js.map +1 -1
  8. package/dist/index.mjs +5057 -6832
  9. package/dist/index.mjs.map +1 -1
  10. package/package.json +4 -4
  11. package/src/components/ActivityIndicator.tsx +13 -4
  12. package/src/components/AnimatePresence.tsx +261 -0
  13. package/src/components/Avatar.tsx +202 -80
  14. package/src/components/Button.tsx +10 -6
  15. package/src/components/Checkbox.tsx +10 -9
  16. package/src/components/Chip.tsx +88 -132
  17. package/src/components/{InputFieldWithCompletions.tsx → Combobox.tsx} +10 -3
  18. package/src/components/ContextMenu.tsx +9 -5
  19. package/src/components/Dialog.tsx +20 -23
  20. package/src/components/Divider.tsx +15 -7
  21. package/src/components/DraggableMenuButton.tsx +9 -5
  22. package/src/components/DropdownMenu.tsx +8 -5
  23. package/src/components/FillInputField.tsx +5 -1
  24. package/src/components/FillPreviewBackground.tsx +1 -5
  25. package/src/components/GridView.tsx +71 -46
  26. package/src/components/InputField.tsx +140 -75
  27. package/src/components/InspectorPrimitives.tsx +17 -11
  28. package/src/components/Label.tsx +5 -1
  29. package/src/components/ListView.tsx +28 -15
  30. package/src/components/Progress.tsx +10 -7
  31. package/src/components/SelectMenu.tsx +20 -8
  32. package/src/components/Slider.tsx +70 -8
  33. package/src/components/Sortable.tsx +3 -3
  34. package/src/components/Switch.tsx +19 -2
  35. package/src/components/Text.tsx +5 -1
  36. package/src/components/TextArea.tsx +5 -1
  37. package/src/components/TreeView.tsx +4 -10
  38. package/src/components/UserPointer.tsx +170 -0
  39. package/src/components/WorkspaceLayout.tsx +5 -0
  40. package/src/components/internal/Menu.tsx +14 -5
  41. package/src/components/internal/TextInput.tsx +13 -0
  42. package/src/contexts/DialogContext.tsx +30 -18
  43. package/src/hooks/useTheme.ts +50 -0
  44. package/src/index.css +16 -13
  45. package/src/index.tsx +14 -26
  46. package/src/utils/classNames.ts +5 -0
  47. package/src/utils/colorFromString.ts +44 -0
  48. package/tailwind.config.ts +16 -13
  49. package/src/hooks/useDarkMode.ts +0 -14
  50. package/src/utils/tailwind.ts +0 -9
@@ -2,6 +2,7 @@ import { Sketch } from "@noya-app/noya-file-format";
2
2
  import React, { forwardRef, memo } from "react";
3
3
  import { SketchPattern } from "../utils/sketchPattern";
4
4
  import { FillPreviewBackground } from "./FillPreviewBackground";
5
+ import { cx } from "../utils/classNames";
5
6
 
6
7
  const FillButton = forwardRef<
7
8
  HTMLButtonElement,
@@ -9,7 +10,10 @@ const FillButton = forwardRef<
9
10
  >(({ className, ...props }, ref) => (
10
11
  <button
11
12
  ref={ref}
12
- className={`outline-none p-0 w-[50px] h-[27px] rounded overflow-hidden border-none shadow-[0_0_0_1px_var(--divider)_inset] bg-transparent relative focus:shadow-[0_0_0_1px_var(--sidebar-background),0_0_0_3px_var(--primary)] ${className ?? ""}`}
13
+ className={cx(
14
+ `outline-none p-0 w-[50px] h-[27px] rounded overflow-hidden border-none shadow-[0_0_0_1px_var(--divider)_inset] bg-transparent relative focus:shadow-[0_0_0_1px_var(--sidebar-background),0_0_0_3px_var(--primary)] `,
15
+ className
16
+ )}
13
17
  {...props}
14
18
  />
15
19
  ));
@@ -7,7 +7,6 @@ import { cssVars } from "../theme";
7
7
  import { getGradientBackground } from "../utils/getGradientBackground";
8
8
  import { sketchColorToRgbaString } from "../utils/sketchColor";
9
9
  import { SketchPattern } from "../utils/sketchPattern";
10
- import { cn } from "../utils/tailwind";
11
10
 
12
11
  const dotsHorizontalSvg = (fillColor: string) => `
13
12
  <svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 15 15' fill='${fillColor}'>
@@ -22,10 +21,7 @@ const Background = memo(function Background({
22
21
  }) {
23
22
  return (
24
23
  <span
25
- className={cn(
26
- "absolute inset-0",
27
- background ? `bg-[${background}]` : "bg-input-background"
28
- )}
24
+ className={`${background ? `bg-[${background}]` : "bg-input-background"} absolute inset-0`}
29
25
  />
30
26
  );
31
27
  });
@@ -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 = ({showBackground, children}: {showBackground?: boolean, children?: React.ReactNode}) => {
66
- return (
67
- <span
68
- className={`font-sans text-heading5 leading-[1] text-text font-medium select-none whitespace-pre overflow-hidden text-ellipsis ${
69
- showBackground &&
70
- "bg-sidebar-background border border-dividerSubtle rounded-[2px] backdrop-blur-[4px] p-[2px_4px]"
71
- }`}
72
- >
73
- {children}
74
- </span>
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 = ({showBackground, children}: {showBackground?: boolean, children?: React.ReactNode}) => {
80
- return (
81
- <span
82
- className={`font-sans text-heading5 font-normal leading-[1] text-[0.7rem] text-text-muted select-none whitespace-pre overflow-hidden text-ellipsis ${
83
- showBackground &&
84
- "bg-sidebar-background border border-dividerSubtle rounded-[2px] backdrop-blur-[4px] p-[2px_4px]"
85
- }`}
86
- >
87
- {children}
88
- </span>
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 = ({last = false, children}: { last?: boolean; children?: React.ReactNode }) => {
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 = forwardRef(function 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={cn(
187
- "flex flex-1 items-center justify-center",
188
- "bg-sidebar-background rounded-[2px] overflow-hidden",
189
- "cursor-pointer",
190
- selected
191
- ? "border border-primary"
192
- : bordered
193
- ? "border border-divider"
194
- : "border border-transparent",
195
- disabled ? "opacity-50" : "hover:opacity-85 active:opacity-70"
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 >{title}</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 onClick={handleClick} className={`flex flex-col ${scrollable ? "flex-1" : "flex-[0_0_auto]"}`}>
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 className={cn(className, "text-text grid", `grid-cols-[auto-fill,_minmax(${sizes[size].itemWidth}px,_1fr)]`)} style={gapStyle}>
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
- ? "6px"
100
+ ? `${6 + (buttonSize ?? 0)}px`
98
101
  : $size === "medium"
99
- ? "2px"
100
- : "0px"
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={`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 ${
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-[6px]`
113
- : $labelPosition === "end"
114
- ? `justify-end ${$hasDropdown ? "pr-[16px]" : "pr-[6px]"}`
115
- : ""
116
- } ${className ?? ""}`}
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={`absolute inset-y-0 right-0 flex flex-col ${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 = memo(function 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={`absolute ${
229
+ className={cx(
230
+ "absolute",
228
231
  $size === "large"
229
- ? "right-[9px] top-[10px]"
232
+ ? "right-[9px] top-2.5"
230
233
  : $size === "medium"
231
- ? "right-[4px] top-[4px]"
234
+ ? "right-1 top-1"
232
235
  : $size === "small"
233
- ? "right-[2px] top-[2px]"
234
- : ""
235
- } ${className ?? ""}`}
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
- ($size === "large" ? 10 : $size === "medium" ? 6 : 4) +
353
- ($labelSize && $labelPosition === "start" ? 6 + $labelSize : 0);
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
- ($size === "large" ? 10 : $size === "medium" ? 6 : 1) +
357
- ($labelSize && $labelPosition === "end" ? 6 + $labelSize : 0) +
358
- ($hasDropdown ? 11 : 0);
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
- labelPosition,
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
- // onFocusChange={onFocusChange}
454
- // readOnly
455
- // placeholder={props.value}
456
- {...props}
457
- value=""
458
- className="absolute inset-0 w-full h-full pointer-events-none bg-transparent shadow-none"
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, $flex, className, ...props }, ref) => (
633
+ >(({ $width, className, ...props }, ref) => (
593
634
  <div
594
635
  ref={ref}
595
- className={`flex flex-row relative ${$flex ? `flex-[${$flex}]` : "flex-1"} ${$width || $width === 0 ? `max-w-[${$width}px]` : ""} ${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
- {measuredWidth && (
722
- <div className={`flex flex-col w-[${measuredWidth}] hidden`}>
723
- {renderPopoverContent({ width: measuredWidth })}
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
- <input
747
- 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 font-sans font-normal text-heading5 placeholder:text-text-disabled focus:z-interactable ${
748
- readOnly
749
- ? "text-text-muted"
750
- : disabled
751
- ? "text-text-disabled"
752
- : "text-text"
753
- } ${className ?? ""}`}
754
- {...props}
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);