@fanvue/ui 3.17.0 → 3.18.0

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.
@@ -14,6 +14,11 @@ const CONTAINER_PADDING_X = {
14
14
  "40": "px-4",
15
15
  "32": "px-3"
16
16
  };
17
+ const CONTAINER_PADDING_X_WITH_ACTION = {
18
+ "48": "pl-4 pr-2",
19
+ "40": "pl-4 pr-2",
20
+ "32": "pl-3 pr-2"
21
+ };
17
22
  const CONTAINER_GAP = {
18
23
  "48": "gap-2.5",
19
24
  "40": "gap-2.5",
@@ -29,10 +34,10 @@ const SIDE_LABEL_TYPOGRAPHY = {
29
34
  "40": "typography-body-default-16px-regular",
30
35
  "32": "typography-body-small-14px-regular"
31
36
  };
32
- function getContainerClassName(size, error, disabled) {
37
+ function getContainerClassName(size, error, disabled, hasAction) {
33
38
  return cn(
34
39
  "relative flex items-center overflow-hidden rounded-sm border bg-inputs-inputs-primary has-focus-visible:shadow-focus-ring has-focus-visible:outline-none motion-safe:transition-colors",
35
- CONTAINER_PADDING_X[size],
40
+ hasAction ? CONTAINER_PADDING_X_WITH_ACTION[size] : CONTAINER_PADDING_X[size],
36
41
  CONTAINER_GAP[size],
37
42
  error ? "border-error-content" : "border-border-primary",
38
43
  !disabled && !error && "hover:border-neutral-alphas-400",
@@ -84,8 +89,8 @@ function TextFieldHelperText({
84
89
  {
85
90
  id,
86
91
  className: cn(
87
- "typography-description-12px-regular px-2 pt-2 pb-0.5",
88
- error ? "text-error-content" : "text-content-secondary"
92
+ "typography-description-12px-regular pt-2",
93
+ error ? "text-error-content" : "text-content-tertiary"
89
94
  ),
90
95
  children
91
96
  }
@@ -112,6 +117,7 @@ const TextField = React.forwardRef(
112
117
  rightIcon,
113
118
  leftLabel,
114
119
  rightLabel,
120
+ action,
115
121
  className,
116
122
  id,
117
123
  disabled,
@@ -165,7 +171,7 @@ const TextField = React.forwardRef(
165
171
  /* @__PURE__ */ jsxs(
166
172
  "div",
167
173
  {
168
- className: getContainerClassName(size, error, disabled),
174
+ className: getContainerClassName(size, error, disabled, action != null),
169
175
  onMouseDown: handleContainerMouseDown,
170
176
  children: [
171
177
  /* @__PURE__ */ jsx(LeadingIcon, { children: leftIcon }),
@@ -187,7 +193,8 @@ const TextField = React.forwardRef(
187
193
  }
188
194
  ),
189
195
  /* @__PURE__ */ jsx(SideLabel, { id: rightLabelId, size, align: "right", children: rightLabel }),
190
- /* @__PURE__ */ jsx(TrailingAdornment, { rightIcon, validated })
196
+ /* @__PURE__ */ jsx(TrailingAdornment, { rightIcon, validated }),
197
+ action != null && /* @__PURE__ */ jsx("span", { "data-tf-interactive": "", className: "flex shrink-0 items-center", children: action })
191
198
  ]
192
199
  }
193
200
  ),
@@ -1 +1 @@
1
- {"version":3,"file":"TextField.mjs","sources":["../../../src/components/TextField/TextField.tsx"],"sourcesContent":["import * as React from \"react\";\nimport { CheckOutlineIcon } from \"@/index\";\nimport { cn } from \"../../utils/cn\";\n\n/** Text field height in pixels. */\nexport type TextFieldSize = \"48\" | \"40\" | \"32\";\n\nexport interface TextFieldProps\n extends Omit<React.InputHTMLAttributes<HTMLInputElement>, \"size\" | \"prefix\"> {\n /** Label text displayed above the input. Also used as the accessible name. */\n label?: string;\n /** Helper text displayed below the input. Replaced by `errorMessage` when `error` is `true`. */\n helperText?: string;\n /** Height of the text field in pixels. @default \"48\" */\n size?: TextFieldSize;\n /** Whether the text field is in an error state. @default false */\n error?: boolean;\n /** Error message displayed below the input. Shown instead of `helperText` when `error` is `true`. */\n errorMessage?: string;\n /** Whether the text field is validated. @default false */\n validated?: boolean;\n /** Icon element displayed at the left side of the input. */\n leftIcon?: React.ReactNode;\n /** Icon element displayed at the right side of the input. */\n rightIcon?: React.ReactNode;\n /** Fixed, non-editable label pinned inside the left edge of the field — for a prefix such as a currency symbol or country code. */\n leftLabel?: React.ReactNode;\n /** Fixed, non-editable label pinned inside the right edge of the field — for a unit or suffix such as a currency code or domain. */\n rightLabel?: React.ReactNode;\n /** Whether the text field stretches to fill its container width. @default false */\n fullWidth?: boolean;\n}\n\nconst CONTAINER_HEIGHT: Record<TextFieldSize, string> = {\n \"48\": \"h-12\",\n \"40\": \"h-10\",\n \"32\": \"h-8\",\n};\n\nconst CONTAINER_PADDING_X: Record<TextFieldSize, string> = {\n \"48\": \"px-4\",\n \"40\": \"px-4\",\n \"32\": \"px-3\",\n};\n\nconst CONTAINER_GAP: Record<TextFieldSize, string> = {\n \"48\": \"gap-2.5\",\n \"40\": \"gap-2.5\",\n \"32\": \"gap-2\",\n};\n\nconst INPUT_TYPOGRAPHY: Record<TextFieldSize, string> = {\n \"48\": \"typography-body-default-16px-regular autofill-body-lg\",\n \"40\": \"typography-body-default-16px-regular autofill-body-lg\",\n \"32\": \"typography-body-small-14px-regular autofill-body-md\",\n};\n\nconst SIDE_LABEL_TYPOGRAPHY: Record<TextFieldSize, string> = {\n \"48\": \"typography-body-default-16px-regular\",\n \"40\": \"typography-body-default-16px-regular\",\n \"32\": \"typography-body-small-14px-regular\",\n};\n\nfunction getContainerClassName(size: TextFieldSize, error: boolean, disabled?: boolean) {\n return cn(\n \"relative flex items-center overflow-hidden rounded-sm border bg-inputs-inputs-primary has-focus-visible:shadow-focus-ring has-focus-visible:outline-none motion-safe:transition-colors\",\n CONTAINER_PADDING_X[size],\n CONTAINER_GAP[size],\n error ? \"border-error-content\" : \"border-border-primary\",\n !disabled && !error && \"hover:border-neutral-alphas-400\",\n CONTAINER_HEIGHT[size],\n disabled && \"opacity-50\",\n );\n}\n\nfunction LeadingIcon({ children }: { children?: React.ReactNode }) {\n if (!children) return null;\n return (\n <span className=\"pointer-events-none flex size-4 shrink-0 items-center justify-center text-content-secondary\">\n {children}\n </span>\n );\n}\n\nfunction SideLabel({\n id,\n size,\n align,\n children,\n}: {\n id?: string;\n size: TextFieldSize;\n align: \"left\" | \"right\";\n children?: React.ReactNode;\n}) {\n if (!children) return null;\n return (\n <span\n id={id}\n className={cn(\n \"shrink-0 select-none whitespace-nowrap text-content-tertiary\",\n align === \"right\" && \"text-right\",\n SIDE_LABEL_TYPOGRAPHY[size],\n )}\n >\n {children}\n </span>\n );\n}\n\nfunction TrailingAdornment({\n rightIcon,\n validated,\n}: {\n rightIcon?: React.ReactNode;\n validated: boolean;\n}) {\n if (!rightIcon && !validated) return null;\n return (\n <span className=\"flex shrink-0 items-center gap-2 text-content-secondary\">\n {rightIcon && (\n <span data-tf-interactive=\"\" className=\"flex size-4 shrink-0 items-center justify-center\">\n {rightIcon}\n </span>\n )}\n {validated && (\n <span className=\"pointer-events-none flex size-4 shrink-0 items-center justify-center\">\n <CheckOutlineIcon className=\"text-success-content\" />\n </span>\n )}\n </span>\n );\n}\n\nfunction TextFieldHelperText({\n id,\n error,\n children,\n}: {\n id: string;\n error: boolean;\n children: React.ReactNode;\n}) {\n return (\n <p\n id={id}\n className={cn(\n \"typography-description-12px-regular px-2 pt-2 pb-0.5\",\n error ? \"text-error-content\" : \"text-content-secondary\",\n )}\n >\n {children}\n </p>\n );\n}\n\nfunction warnMissingAccessibleName(label?: string, ariaLabel?: string, ariaLabelledBy?: string) {\n if (process.env.NODE_ENV !== \"production\") {\n if (!label && !ariaLabel && !ariaLabelledBy) {\n console.warn(\n \"TextField: no accessible name provided. Pass a `label`, `aria-label`, or `aria-labelledby` prop.\",\n );\n }\n }\n}\n\n/**\n * A text input field with optional label, helper/error text, icon slots, and side labels.\n *\n * Use `leftLabel` / `rightLabel` for fixed unit or prefix affordances (currency symbol,\n * country code, domain suffix). Provide at least one of `label`, `aria-label`, or\n * `aria-labelledby` for accessibility — a console warning is emitted in development if none are set.\n *\n * @example\n * ```tsx\n * <TextField\n * label=\"Email\"\n * placeholder=\"you@example.com\"\n * error={!!emailError}\n * errorMessage={emailError}\n * />\n * ```\n *\n * @example\n * ```tsx\n * <TextField label=\"Price\" leftLabel=\"$\" rightLabel=\"USD\" placeholder=\"0.00\" />\n * ```\n */\nexport const TextField = React.forwardRef<HTMLInputElement, TextFieldProps>(\n (\n {\n label,\n helperText,\n size = \"48\",\n error = false,\n errorMessage,\n validated = false,\n leftIcon,\n rightIcon,\n leftLabel,\n rightLabel,\n className,\n id,\n disabled,\n fullWidth = false,\n ...props\n },\n ref,\n ) => {\n const generatedId = React.useId();\n const inputId = id || generatedId;\n const helperTextId = `${inputId}-helper`;\n const leftLabelId = `${inputId}-left-label`;\n const rightLabelId = `${inputId}-right-label`;\n const bottomText = error && errorMessage ? errorMessage : helperText;\n\n const describedBy =\n [\n leftLabel != null ? leftLabelId : null,\n rightLabel != null ? rightLabelId : null,\n bottomText ? helperTextId : null,\n ]\n .filter(Boolean)\n .join(\" \") || undefined;\n\n const innerRef = React.useRef<HTMLInputElement>(null);\n const setRefs = React.useCallback(\n (node: HTMLInputElement | null) => {\n innerRef.current = node;\n if (typeof ref === \"function\") ref(node);\n else if (ref) (ref as React.MutableRefObject<HTMLInputElement | null>).current = node;\n },\n [ref],\n );\n\n // Keep clicks on the non-interactive adornments (icons, side labels, padding)\n // focusing the input, matching the old absolute/pointer-events-none layout.\n const handleContainerMouseDown = (event: React.MouseEvent<HTMLDivElement>) => {\n if (disabled) return;\n const target = event.target as HTMLElement;\n if (target === innerRef.current) return;\n if (target.closest(\"[data-tf-interactive]\")) return;\n event.preventDefault();\n innerRef.current?.focus();\n };\n\n warnMissingAccessibleName(label, props[\"aria-label\"], props[\"aria-labelledby\"]);\n\n return (\n <div\n className={cn(\"flex flex-col\", fullWidth && \"w-full\", className)}\n data-disabled={disabled ? \"\" : undefined}\n data-error={error ? \"\" : undefined}\n >\n {label && (\n <label\n htmlFor={inputId}\n className=\"typography-description-12px-semibold pb-2 text-content-primary\"\n >\n {label}\n </label>\n )}\n\n {/* biome-ignore lint/a11y/noStaticElementInteractions: focus bridge delegates pointer clicks on adornments to the input */}\n <div\n className={getContainerClassName(size, error, disabled)}\n onMouseDown={handleContainerMouseDown}\n >\n <LeadingIcon>{leftIcon}</LeadingIcon>\n <SideLabel id={leftLabelId} size={size} align=\"left\">\n {leftLabel}\n </SideLabel>\n\n <input\n ref={setRefs}\n id={inputId}\n disabled={disabled}\n aria-describedby={describedBy}\n aria-invalid={error || undefined}\n className={cn(\n \"h-full min-w-0 flex-1 bg-transparent text-content-primary no-underline placeholder:text-content-tertiary focus:outline-none disabled:cursor-not-allowed\",\n INPUT_TYPOGRAPHY[size],\n \"[&[type='search']::-webkit-search-cancel-button]:hidden [&[type='search']::-webkit-search-cancel-button]:appearance-none\",\n )}\n {...props}\n />\n\n <SideLabel id={rightLabelId} size={size} align=\"right\">\n {rightLabel}\n </SideLabel>\n <TrailingAdornment rightIcon={rightIcon} validated={validated} />\n </div>\n\n {bottomText && (\n <TextFieldHelperText id={helperTextId} error={error}>\n {bottomText}\n </TextFieldHelperText>\n )}\n </div>\n );\n },\n);\n\nTextField.displayName = \"TextField\";\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"TextField.mjs","sources":["../../../src/components/TextField/TextField.tsx"],"sourcesContent":["import * as React from \"react\";\nimport { CheckOutlineIcon } from \"@/index\";\nimport { cn } from \"../../utils/cn\";\n\n/** Text field height in pixels. */\nexport type TextFieldSize = \"48\" | \"40\" | \"32\";\n\nexport interface TextFieldProps\n extends Omit<React.InputHTMLAttributes<HTMLInputElement>, \"size\" | \"prefix\"> {\n /** Label text displayed above the input. Also used as the accessible name. */\n label?: string;\n /** Helper text displayed below the input. Replaced by `errorMessage` when `error` is `true`. */\n helperText?: string;\n /** Height of the text field in pixels. @default \"48\" */\n size?: TextFieldSize;\n /** Whether the text field is in an error state. @default false */\n error?: boolean;\n /** Error message displayed below the input. Shown instead of `helperText` when `error` is `true`. */\n errorMessage?: string;\n /** Whether the text field is validated. @default false */\n validated?: boolean;\n /** Icon element displayed at the left side of the input. */\n leftIcon?: React.ReactNode;\n /** Icon element displayed at the right side of the input. */\n rightIcon?: React.ReactNode;\n /** Fixed, non-editable label pinned inside the left edge of the field — for a prefix such as a currency symbol or country code. */\n leftLabel?: React.ReactNode;\n /** Fixed, non-editable label pinned inside the right edge of the field — for a unit or suffix such as a currency code or domain. */\n rightLabel?: React.ReactNode;\n /**\n * Trailing interactive element pinned to the right edge — typically a `Chip`\n * or `Button` (the \"with button\" field type). Reduces the right padding so the\n * control sits flush, and clicks on it do not steal focus from the input.\n */\n action?: React.ReactNode;\n /** Whether the text field stretches to fill its container width. @default false */\n fullWidth?: boolean;\n}\n\nconst CONTAINER_HEIGHT: Record<TextFieldSize, string> = {\n \"48\": \"h-12\",\n \"40\": \"h-10\",\n \"32\": \"h-8\",\n};\n\nconst CONTAINER_PADDING_X: Record<TextFieldSize, string> = {\n \"48\": \"px-4\",\n \"40\": \"px-4\",\n \"32\": \"px-3\",\n};\n\nconst CONTAINER_PADDING_X_WITH_ACTION: Record<TextFieldSize, string> = {\n \"48\": \"pl-4 pr-2\",\n \"40\": \"pl-4 pr-2\",\n \"32\": \"pl-3 pr-2\",\n};\n\nconst CONTAINER_GAP: Record<TextFieldSize, string> = {\n \"48\": \"gap-2.5\",\n \"40\": \"gap-2.5\",\n \"32\": \"gap-2\",\n};\n\nconst INPUT_TYPOGRAPHY: Record<TextFieldSize, string> = {\n \"48\": \"typography-body-default-16px-regular autofill-body-lg\",\n \"40\": \"typography-body-default-16px-regular autofill-body-lg\",\n \"32\": \"typography-body-small-14px-regular autofill-body-md\",\n};\n\nconst SIDE_LABEL_TYPOGRAPHY: Record<TextFieldSize, string> = {\n \"48\": \"typography-body-default-16px-regular\",\n \"40\": \"typography-body-default-16px-regular\",\n \"32\": \"typography-body-small-14px-regular\",\n};\n\nfunction getContainerClassName(\n size: TextFieldSize,\n error: boolean,\n disabled?: boolean,\n hasAction?: boolean,\n) {\n return cn(\n \"relative flex items-center overflow-hidden rounded-sm border bg-inputs-inputs-primary has-focus-visible:shadow-focus-ring has-focus-visible:outline-none motion-safe:transition-colors\",\n hasAction ? CONTAINER_PADDING_X_WITH_ACTION[size] : CONTAINER_PADDING_X[size],\n CONTAINER_GAP[size],\n error ? \"border-error-content\" : \"border-border-primary\",\n !disabled && !error && \"hover:border-neutral-alphas-400\",\n CONTAINER_HEIGHT[size],\n disabled && \"opacity-50\",\n );\n}\n\nfunction LeadingIcon({ children }: { children?: React.ReactNode }) {\n if (!children) return null;\n return (\n <span className=\"pointer-events-none flex size-4 shrink-0 items-center justify-center text-content-secondary\">\n {children}\n </span>\n );\n}\n\nfunction SideLabel({\n id,\n size,\n align,\n children,\n}: {\n id?: string;\n size: TextFieldSize;\n align: \"left\" | \"right\";\n children?: React.ReactNode;\n}) {\n if (!children) return null;\n return (\n <span\n id={id}\n className={cn(\n \"shrink-0 select-none whitespace-nowrap text-content-tertiary\",\n align === \"right\" && \"text-right\",\n SIDE_LABEL_TYPOGRAPHY[size],\n )}\n >\n {children}\n </span>\n );\n}\n\nfunction TrailingAdornment({\n rightIcon,\n validated,\n}: {\n rightIcon?: React.ReactNode;\n validated: boolean;\n}) {\n if (!rightIcon && !validated) return null;\n return (\n <span className=\"flex shrink-0 items-center gap-2 text-content-secondary\">\n {rightIcon && (\n <span data-tf-interactive=\"\" className=\"flex size-4 shrink-0 items-center justify-center\">\n {rightIcon}\n </span>\n )}\n {validated && (\n <span className=\"pointer-events-none flex size-4 shrink-0 items-center justify-center\">\n <CheckOutlineIcon className=\"text-success-content\" />\n </span>\n )}\n </span>\n );\n}\n\nfunction TextFieldHelperText({\n id,\n error,\n children,\n}: {\n id: string;\n error: boolean;\n children: React.ReactNode;\n}) {\n return (\n <p\n id={id}\n className={cn(\n \"typography-description-12px-regular pt-2\",\n error ? \"text-error-content\" : \"text-content-tertiary\",\n )}\n >\n {children}\n </p>\n );\n}\n\nfunction warnMissingAccessibleName(label?: string, ariaLabel?: string, ariaLabelledBy?: string) {\n if (process.env.NODE_ENV !== \"production\") {\n if (!label && !ariaLabel && !ariaLabelledBy) {\n console.warn(\n \"TextField: no accessible name provided. Pass a `label`, `aria-label`, or `aria-labelledby` prop.\",\n );\n }\n }\n}\n\n/**\n * A text input field with optional label, helper/error text, icon slots, and side labels.\n *\n * Use `leftLabel` / `rightLabel` for fixed unit or prefix affordances (currency symbol,\n * country code, domain suffix). Provide at least one of `label`, `aria-label`, or\n * `aria-labelledby` for accessibility — a console warning is emitted in development if none are set.\n *\n * @example\n * ```tsx\n * <TextField\n * label=\"Email\"\n * placeholder=\"you@example.com\"\n * error={!!emailError}\n * errorMessage={emailError}\n * />\n * ```\n *\n * @example\n * ```tsx\n * <TextField label=\"Price\" leftLabel=\"$\" rightLabel=\"USD\" placeholder=\"0.00\" />\n * ```\n *\n * @example\n * ```tsx\n * <TextField\n * label=\"Promo code\"\n * placeholder=\"Enter code\"\n * action={<Chip size=\"32\" onClick={apply}>Apply</Chip>}\n * />\n * ```\n */\nexport const TextField = React.forwardRef<HTMLInputElement, TextFieldProps>(\n (\n {\n label,\n helperText,\n size = \"48\",\n error = false,\n errorMessage,\n validated = false,\n leftIcon,\n rightIcon,\n leftLabel,\n rightLabel,\n action,\n className,\n id,\n disabled,\n fullWidth = false,\n ...props\n },\n ref,\n ) => {\n const generatedId = React.useId();\n const inputId = id || generatedId;\n const helperTextId = `${inputId}-helper`;\n const leftLabelId = `${inputId}-left-label`;\n const rightLabelId = `${inputId}-right-label`;\n const bottomText = error && errorMessage ? errorMessage : helperText;\n\n const describedBy =\n [\n leftLabel != null ? leftLabelId : null,\n rightLabel != null ? rightLabelId : null,\n bottomText ? helperTextId : null,\n ]\n .filter(Boolean)\n .join(\" \") || undefined;\n\n const innerRef = React.useRef<HTMLInputElement>(null);\n const setRefs = React.useCallback(\n (node: HTMLInputElement | null) => {\n innerRef.current = node;\n if (typeof ref === \"function\") ref(node);\n else if (ref) (ref as React.MutableRefObject<HTMLInputElement | null>).current = node;\n },\n [ref],\n );\n\n // Keep clicks on the non-interactive adornments (icons, side labels, padding)\n // focusing the input, matching the old absolute/pointer-events-none layout.\n const handleContainerMouseDown = (event: React.MouseEvent<HTMLDivElement>) => {\n if (disabled) return;\n const target = event.target as HTMLElement;\n if (target === innerRef.current) return;\n if (target.closest(\"[data-tf-interactive]\")) return;\n event.preventDefault();\n innerRef.current?.focus();\n };\n\n warnMissingAccessibleName(label, props[\"aria-label\"], props[\"aria-labelledby\"]);\n\n return (\n <div\n className={cn(\"flex flex-col\", fullWidth && \"w-full\", className)}\n data-disabled={disabled ? \"\" : undefined}\n data-error={error ? \"\" : undefined}\n >\n {label && (\n <label\n htmlFor={inputId}\n className=\"typography-description-12px-semibold pb-2 text-content-primary\"\n >\n {label}\n </label>\n )}\n\n {/* biome-ignore lint/a11y/noStaticElementInteractions: focus bridge delegates pointer clicks on adornments to the input */}\n <div\n className={getContainerClassName(size, error, disabled, action != null)}\n onMouseDown={handleContainerMouseDown}\n >\n <LeadingIcon>{leftIcon}</LeadingIcon>\n <SideLabel id={leftLabelId} size={size} align=\"left\">\n {leftLabel}\n </SideLabel>\n\n <input\n ref={setRefs}\n id={inputId}\n disabled={disabled}\n aria-describedby={describedBy}\n aria-invalid={error || undefined}\n className={cn(\n \"h-full min-w-0 flex-1 bg-transparent text-content-primary no-underline placeholder:text-content-tertiary focus:outline-none disabled:cursor-not-allowed\",\n INPUT_TYPOGRAPHY[size],\n \"[&[type='search']::-webkit-search-cancel-button]:hidden [&[type='search']::-webkit-search-cancel-button]:appearance-none\",\n )}\n {...props}\n />\n\n <SideLabel id={rightLabelId} size={size} align=\"right\">\n {rightLabel}\n </SideLabel>\n <TrailingAdornment rightIcon={rightIcon} validated={validated} />\n {action != null && (\n <span data-tf-interactive=\"\" className=\"flex shrink-0 items-center\">\n {action}\n </span>\n )}\n </div>\n\n {bottomText && (\n <TextFieldHelperText id={helperTextId} error={error}>\n {bottomText}\n </TextFieldHelperText>\n )}\n </div>\n );\n },\n);\n\nTextField.displayName = \"TextField\";\n"],"names":[],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -3840,6 +3840,55 @@ export declare const PeopleIcon: React_2.ForwardRefExoticComponent<React_2.SVGAt
3840
3840
  className?: string;
3841
3841
  } & React_2.RefAttributes<SVGSVGElement>>;
3842
3842
 
3843
+ /**
3844
+ * A phone number input with a country selector (flag + chevron), a fixed dial
3845
+ * code prefix, and a `tel` input. The country picker itself is owned by the
3846
+ * consumer: pass the selected country's `flag` and `dialCode`, and open your
3847
+ * picker from `onCountrySelect`.
3848
+ *
3849
+ * Provide at least one of `label`, `aria-label`, or `aria-labelledby` for
3850
+ * accessibility — a console warning is emitted in development if none are set.
3851
+ *
3852
+ * @example
3853
+ * ```tsx
3854
+ * <PhoneField
3855
+ * label="Phone number"
3856
+ * flag={<img src={italyFlag} alt="" />}
3857
+ * dialCode="+39"
3858
+ * onCountrySelect={openCountryPicker}
3859
+ * value={number}
3860
+ * onChange={(e) => setNumber(e.target.value)}
3861
+ * />
3862
+ * ```
3863
+ */
3864
+ export declare const PhoneField: React_2.ForwardRefExoticComponent<PhoneFieldProps & React_2.RefAttributes<HTMLInputElement>>;
3865
+
3866
+ export declare interface PhoneFieldProps extends Omit<React_2.InputHTMLAttributes<HTMLInputElement>, "size" | "prefix"> {
3867
+ /** Label text displayed above the input. Also used as the accessible name. */
3868
+ label?: string;
3869
+ /** Helper text displayed below the input. Replaced by `errorMessage` when `error` is `true`. */
3870
+ helperText?: string;
3871
+ /** Height of the phone field in pixels. @default "48" */
3872
+ size?: PhoneFieldSize;
3873
+ /** Whether the field is in an error state. @default false */
3874
+ error?: boolean;
3875
+ /** Error message displayed below the input. Shown instead of `helperText` when `error` is `true`. */
3876
+ errorMessage?: string;
3877
+ /** Dial code of the selected country, shown before the number (e.g. `"+39"`). */
3878
+ dialCode?: React_2.ReactNode;
3879
+ /** Flag of the selected country, rendered in the country selector (e.g. an image or flag icon). */
3880
+ flag?: React_2.ReactNode;
3881
+ /** Fired when the country selector (flag + chevron) is activated. Open the country picker here. */
3882
+ onCountrySelect?: () => void;
3883
+ /** Accessible name for the country selector button. @default "Select country" */
3884
+ countryButtonLabel?: string;
3885
+ /** Whether the field stretches to fill its container width. @default false */
3886
+ fullWidth?: boolean;
3887
+ }
3888
+
3889
+ /** Phone field height in pixels. */
3890
+ export declare type PhoneFieldSize = "48" | "40" | "32";
3891
+
3843
3892
  /**
3844
3893
  * Phone icon. Renders at sizes 16, 24, or 32 px with outlined and filled variants.
3845
3894
  *
@@ -4171,6 +4220,11 @@ export declare interface RatingCount {
4171
4220
  * followed by a per-rating histogram. Bar lengths are scaled relative to the
4172
4221
  * most-reviewed rating, so the busiest rating always fills the track.
4173
4222
  *
4223
+ * The histogram is one shared grid (with subgrid rows) rather than per-row
4224
+ * flex: the label column is sized by the widest label across all rows, so a
4225
+ * width difference between labels (e.g. "1 review" vs "3 reviews") never
4226
+ * changes a row's track length — every bar's right edge stays aligned.
4227
+ *
4174
4228
  * The brand star is decorative; the header and each histogram row expose
4175
4229
  * `role="img"` with an accessible label (override via `formatAverageLabel` /
4176
4230
  * `formatRatingLabel`) so the single-star-plus-number reads clearly.
@@ -4226,6 +4280,19 @@ export declare interface RatingSummaryProps extends Omit<React_2.HTMLAttributes<
4226
4280
  formatRatingLabel?: (rating: number, count: number) => string;
4227
4281
  }
4228
4282
 
4283
+ /**
4284
+ * Receive Money icon. Renders at sizes 16, 24, or 32 px.
4285
+ *
4286
+ * @example
4287
+ * ```tsx
4288
+ * <ReceiveMoneyIcon size={24} />
4289
+ * ```
4290
+ */
4291
+ export declare const ReceiveMoneyIcon: React_2.ForwardRefExoticComponent<BaseIconProps & React_2.RefAttributes<SVGSVGElement>>;
4292
+
4293
+ /** Props for {@link ReceiveMoneyIcon}. See {@link BaseIconProps} for the shared shape. */
4294
+ export declare type ReceiveMoneyIconProps = BaseIconProps;
4295
+
4229
4296
  /**
4230
4297
  * Repeat icon. Renders at sizes 16, 24, or 32 px.
4231
4298
  *
@@ -5509,6 +5576,15 @@ export declare type TextAreaSize = "48" | "40" | "32";
5509
5576
  * ```tsx
5510
5577
  * <TextField label="Price" leftLabel="$" rightLabel="USD" placeholder="0.00" />
5511
5578
  * ```
5579
+ *
5580
+ * @example
5581
+ * ```tsx
5582
+ * <TextField
5583
+ * label="Promo code"
5584
+ * placeholder="Enter code"
5585
+ * action={<Chip size="32" onClick={apply}>Apply</Chip>}
5586
+ * />
5587
+ * ```
5512
5588
  */
5513
5589
  export declare const TextField: React_2.ForwardRefExoticComponent<TextFieldProps & React_2.RefAttributes<HTMLInputElement>>;
5514
5590
 
@@ -5533,6 +5609,12 @@ export declare interface TextFieldProps extends Omit<React_2.InputHTMLAttributes
5533
5609
  leftLabel?: React_2.ReactNode;
5534
5610
  /** Fixed, non-editable label pinned inside the right edge of the field — for a unit or suffix such as a currency code or domain. */
5535
5611
  rightLabel?: React_2.ReactNode;
5612
+ /**
5613
+ * Trailing interactive element pinned to the right edge — typically a `Chip`
5614
+ * or `Button` (the "with button" field type). Reduces the right padding so the
5615
+ * control sits flush, and clicks on it do not steal focus from the input.
5616
+ */
5617
+ action?: React_2.ReactNode;
5536
5618
  /** Whether the text field stretches to fill its container width. @default false */
5537
5619
  fullWidth?: boolean;
5538
5620
  }
package/dist/index.mjs CHANGED
@@ -151,6 +151,7 @@ import { PlayIcon } from "./components/Icons/PlayIcon.mjs";
151
151
  import { PlusIcon } from "./components/Icons/PlusIcon.mjs";
152
152
  import { PrivacyIcon } from "./components/Icons/PrivacyIcon.mjs";
153
153
  import { QueueIcon } from "./components/Icons/QueueIcon.mjs";
154
+ import { ReceiveMoneyIcon } from "./components/Icons/ReceiveMoneyIcon.mjs";
154
155
  import { RepeatIcon } from "./components/Icons/RepeatIcon.mjs";
155
156
  import { Reply2Icon } from "./components/Icons/Reply2Icon.mjs";
156
157
  import { ReplyIcon } from "./components/Icons/ReplyIcon.mjs";
@@ -213,6 +214,7 @@ import { OnlineBlinkingIcon } from "./components/OnlineBlinkingIcon/OnlineBlinki
213
214
  import { PageSelector } from "./components/PageSelector/PageSelector.mjs";
214
215
  import { Pagination } from "./components/Pagination/Pagination.mjs";
215
216
  import { PasswordField } from "./components/PasswordField/PasswordField.mjs";
217
+ import { PhoneField } from "./components/PhoneField/PhoneField.mjs";
216
218
  import { Pill } from "./components/Pill/Pill.mjs";
217
219
  import { ProfileOnlineStatus } from "./components/ProfileOnlineStatus/ProfileOnlineStatus.mjs";
218
220
  import { ProfileStatus } from "./components/ProfileStatus/ProfileStatus.mjs";
@@ -447,6 +449,7 @@ export {
447
449
  PasswordField,
448
450
  PauseIcon,
449
451
  PeopleIcon,
452
+ PhoneField,
450
453
  PhoneIcon,
451
454
  PhoneOffIcon,
452
455
  Pill,
@@ -464,6 +467,7 @@ export {
464
467
  Radio,
465
468
  RadioGroup,
466
469
  RatingSummary,
470
+ ReceiveMoneyIcon,
467
471
  RepeatIcon,
468
472
  Reply2Icon,
469
473
  ReplyIcon,
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"index.mjs","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fanvue/ui",
3
- "version": "3.17.0",
3
+ "version": "3.18.0",
4
4
  "description": "React component library built with Tailwind CSS for Fanvue ecosystem",
5
5
  "publishConfig": {
6
6
  "registry": "https://registry.npmjs.org",