@mediquo/medicore 0.5.1 → 0.5.2
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.
|
@@ -32,3 +32,9 @@ export declare const controlPlaceholder = "placeholder:text-text-secondary disab
|
|
|
32
32
|
export declare const controlIcon = "flex shrink-0 text-text-secondary [&_svg]:size-icon-sm group-has-[:is(input,select):disabled]/control:text-text-disabled group-data-disabled/control:text-text-disabled";
|
|
33
33
|
/** Small icon button inside the box (reveal password, clear). 44px hit area. */
|
|
34
34
|
export declare const controlAction = "focus-ring touch-target -me-1 inline-flex size-6 shrink-0 cursor-pointer items-center justify-center rounded-sm text-text-secondary interactive hover:text-text-primary disabled:cursor-not-allowed disabled:text-text-disabled [&_svg]:size-icon-sm";
|
|
35
|
+
/**
|
|
36
|
+
* Browser autofill paints its own yellow or blue fill over the control. An inset
|
|
37
|
+
* shadow in the box's colour covers it and the text keeps the field's colour, so a
|
|
38
|
+
* saved email and password look like typed ones.
|
|
39
|
+
*/
|
|
40
|
+
export declare const controlAutofill: string;
|
|
@@ -22,8 +22,13 @@ const triggerControlStates = [
|
|
|
22
22
|
const controlPlaceholder = "placeholder:text-text-secondary disabled:placeholder:text-text-disabled";
|
|
23
23
|
const controlIcon = "flex shrink-0 text-text-secondary [&_svg]:size-icon-sm group-has-[:is(input,select):disabled]/control:text-text-disabled group-data-disabled/control:text-text-disabled";
|
|
24
24
|
const controlAction = "focus-ring touch-target -me-1 inline-flex size-6 shrink-0 cursor-pointer items-center justify-center rounded-sm text-text-secondary interactive hover:text-text-primary disabled:cursor-not-allowed disabled:text-text-disabled [&_svg]:size-icon-sm";
|
|
25
|
+
const controlAutofill = [
|
|
26
|
+
"autofill:shadow-[inset_0_0_0_100vmax_var(--color-background)] autofill:[-webkit-text-fill-color:var(--color-text-primary)] autofill:caret-text-primary",
|
|
27
|
+
"autofill:disabled:shadow-[inset_0_0_0_100vmax_var(--color-surface)] autofill:disabled:[-webkit-text-fill-color:var(--color-text-disabled)]"
|
|
28
|
+
].join(" ");
|
|
25
29
|
export {
|
|
26
30
|
controlAction,
|
|
31
|
+
controlAutofill,
|
|
27
32
|
controlBox,
|
|
28
33
|
controlHeight,
|
|
29
34
|
controlIcon,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"control-styles.js","sources":["../../../src/components/input/control-styles.ts"],"sourcesContent":["/*\n * The box shared by Input, Textarea, Select, NativeSelect and PhoneInput. Figma draws\n * them as the same object on purpose: same radius, padding, border and states, so a\n * field and a dropdown in the same row only differ by the chevron.\n *\n * Focus and Error are a 2px border (border-thick), not just a colour change. The\n * second pixel is an inset ring, so the content never moves when the state changes.\n * Focus wins over Error: the message under the field keeps saying what is wrong.\n */\n\n/** Border, radius, fill and text colour of the box. */\nexport const controlBox =\n \"w-full min-w-0 rounded-md border border-border bg-background text-text-primary shadow-xs ring-1 ring-transparent ring-inset interactive hover:border-border-strong\";\n\n/** One-line content: 12px side padding, 8px between icon and text, Label/Default (14). */\nexport const controlRow = \"flex items-center gap-2 px-3 text-label-default\";\n\n/** control-md (40) and control-sm (36): the same tokens as Button, so they line up. */\nexport const controlHeight = {\n default: \"h-control-md\",\n small: \"h-control-sm\",\n} as const;\n\nexport type ControlSize = keyof typeof controlHeight;\n\n/**\n * States for a box that WRAPS the real control (Input, NativeSelect, the phone\n * prefix). Read from the control inside: `aria-invalid` (set by `invalid` or by\n * Field), `:focus` and `:disabled` (of the input/select only: a native select's\n * placeholder `<option disabled>` must not grey the box out). Buttons inside the box\n * (reveal password, clear) keep their own focus ring and don't light the box up.\n */\nexport const wrappedControlStates = [\n \"has-[[aria-invalid=true]]:border-error has-[[aria-invalid=true]]:ring-error\",\n \"has-[:focus:not(button)]:border-border-focus has-[:focus:not(button)]:ring-border-focus\",\n \"has-[:is(input,select):disabled]:cursor-not-allowed has-[:is(input,select):disabled]:border-border-subtle has-[:is(input,select):disabled]:bg-surface has-[:is(input,select):disabled]:text-text-disabled has-[:is(input,select):disabled]:shadow-none\",\n].join(\" \");\n\n/** States for a box that IS the control (Textarea). */\nexport const selfControlStates = [\n \"outline-none focus:border-border-focus focus:ring-border-focus\",\n \"aria-invalid:not-focus:border-error aria-invalid:not-focus:ring-error\",\n \"disabled:cursor-not-allowed disabled:border-border-subtle disabled:bg-surface disabled:text-text-disabled disabled:shadow-none\",\n].join(\" \");\n\n/**\n * States for a button box (Select trigger). It keeps the focus border while its popup\n * is open, because focus is inside the list then.\n */\nexport const triggerControlStates = [\n \"outline-none focus:border-border-focus focus:ring-border-focus data-popup-open:border-border-focus data-popup-open:ring-border-focus\",\n \"aria-invalid:not-focus:not-data-popup-open:border-error aria-invalid:not-focus:not-data-popup-open:ring-error\",\n \"data-disabled:cursor-not-allowed data-disabled:border-border-subtle data-disabled:bg-surface data-disabled:text-text-disabled data-disabled:shadow-none\",\n].join(\" \");\n\n/** Placeholder: the same Value node in text-secondary, never a variant. */\nexport const controlPlaceholder =\n \"placeholder:text-text-secondary disabled:placeholder:text-text-disabled\";\n\n/**\n * Leading / trailing icon slot: 16px in text-secondary (5.07:1), disabled with the\n * box. The box carries `group/control`.\n */\nexport const controlIcon =\n \"flex shrink-0 text-text-secondary [&_svg]:size-icon-sm group-has-[:is(input,select):disabled]/control:text-text-disabled group-data-disabled/control:text-text-disabled\";\n\n/** Small icon button inside the box (reveal password, clear). 44px hit area. */\nexport const controlAction =\n \"focus-ring touch-target -me-1 inline-flex size-6 shrink-0 cursor-pointer items-center justify-center rounded-sm text-text-secondary interactive hover:text-text-primary disabled:cursor-not-allowed disabled:text-text-disabled [&_svg]:size-icon-sm\";\n"],"names":[],"mappings":"AAWO,MAAM,aACX;AAGK,MAAM,aAAa;AAGnB,MAAM,gBAAgB;AAAA,EAC3B,SAAS;AAAA,EACT,OAAO;AACT;AAWO,MAAM,uBAAuB;AAAA,EAClC;AAAA,EACA;AAAA,EACA;AACF,EAAE,KAAK,GAAG;AAGH,MAAM,oBAAoB;AAAA,EAC/B;AAAA,EACA;AAAA,EACA;AACF,EAAE,KAAK,GAAG;AAMH,MAAM,uBAAuB;AAAA,EAClC;AAAA,EACA;AAAA,EACA;AACF,EAAE,KAAK,GAAG;AAGH,MAAM,qBACX;AAMK,MAAM,cACX;AAGK,MAAM,gBACX;"}
|
|
1
|
+
{"version":3,"file":"control-styles.js","sources":["../../../src/components/input/control-styles.ts"],"sourcesContent":["/*\n * The box shared by Input, Textarea, Select, NativeSelect and PhoneInput. Figma draws\n * them as the same object on purpose: same radius, padding, border and states, so a\n * field and a dropdown in the same row only differ by the chevron.\n *\n * Focus and Error are a 2px border (border-thick), not just a colour change. The\n * second pixel is an inset ring, so the content never moves when the state changes.\n * Focus wins over Error: the message under the field keeps saying what is wrong.\n */\n\n/** Border, radius, fill and text colour of the box. */\nexport const controlBox =\n \"w-full min-w-0 rounded-md border border-border bg-background text-text-primary shadow-xs ring-1 ring-transparent ring-inset interactive hover:border-border-strong\";\n\n/** One-line content: 12px side padding, 8px between icon and text, Label/Default (14). */\nexport const controlRow = \"flex items-center gap-2 px-3 text-label-default\";\n\n/** control-md (40) and control-sm (36): the same tokens as Button, so they line up. */\nexport const controlHeight = {\n default: \"h-control-md\",\n small: \"h-control-sm\",\n} as const;\n\nexport type ControlSize = keyof typeof controlHeight;\n\n/**\n * States for a box that WRAPS the real control (Input, NativeSelect, the phone\n * prefix). Read from the control inside: `aria-invalid` (set by `invalid` or by\n * Field), `:focus` and `:disabled` (of the input/select only: a native select's\n * placeholder `<option disabled>` must not grey the box out). Buttons inside the box\n * (reveal password, clear) keep their own focus ring and don't light the box up.\n */\nexport const wrappedControlStates = [\n \"has-[[aria-invalid=true]]:border-error has-[[aria-invalid=true]]:ring-error\",\n \"has-[:focus:not(button)]:border-border-focus has-[:focus:not(button)]:ring-border-focus\",\n \"has-[:is(input,select):disabled]:cursor-not-allowed has-[:is(input,select):disabled]:border-border-subtle has-[:is(input,select):disabled]:bg-surface has-[:is(input,select):disabled]:text-text-disabled has-[:is(input,select):disabled]:shadow-none\",\n].join(\" \");\n\n/** States for a box that IS the control (Textarea). */\nexport const selfControlStates = [\n \"outline-none focus:border-border-focus focus:ring-border-focus\",\n \"aria-invalid:not-focus:border-error aria-invalid:not-focus:ring-error\",\n \"disabled:cursor-not-allowed disabled:border-border-subtle disabled:bg-surface disabled:text-text-disabled disabled:shadow-none\",\n].join(\" \");\n\n/**\n * States for a button box (Select trigger). It keeps the focus border while its popup\n * is open, because focus is inside the list then.\n */\nexport const triggerControlStates = [\n \"outline-none focus:border-border-focus focus:ring-border-focus data-popup-open:border-border-focus data-popup-open:ring-border-focus\",\n \"aria-invalid:not-focus:not-data-popup-open:border-error aria-invalid:not-focus:not-data-popup-open:ring-error\",\n \"data-disabled:cursor-not-allowed data-disabled:border-border-subtle data-disabled:bg-surface data-disabled:text-text-disabled data-disabled:shadow-none\",\n].join(\" \");\n\n/** Placeholder: the same Value node in text-secondary, never a variant. */\nexport const controlPlaceholder =\n \"placeholder:text-text-secondary disabled:placeholder:text-text-disabled\";\n\n/**\n * Leading / trailing icon slot: 16px in text-secondary (5.07:1), disabled with the\n * box. The box carries `group/control`.\n */\nexport const controlIcon =\n \"flex shrink-0 text-text-secondary [&_svg]:size-icon-sm group-has-[:is(input,select):disabled]/control:text-text-disabled group-data-disabled/control:text-text-disabled\";\n\n/** Small icon button inside the box (reveal password, clear). 44px hit area. */\nexport const controlAction =\n \"focus-ring touch-target -me-1 inline-flex size-6 shrink-0 cursor-pointer items-center justify-center rounded-sm text-text-secondary interactive hover:text-text-primary disabled:cursor-not-allowed disabled:text-text-disabled [&_svg]:size-icon-sm\";\n\n/**\n * Browser autofill paints its own yellow or blue fill over the control. An inset\n * shadow in the box's colour covers it and the text keeps the field's colour, so a\n * saved email and password look like typed ones.\n */\nexport const controlAutofill = [\n \"autofill:shadow-[inset_0_0_0_100vmax_var(--color-background)] autofill:[-webkit-text-fill-color:var(--color-text-primary)] autofill:caret-text-primary\",\n \"autofill:disabled:shadow-[inset_0_0_0_100vmax_var(--color-surface)] autofill:disabled:[-webkit-text-fill-color:var(--color-text-disabled)]\",\n].join(\" \");\n"],"names":[],"mappings":"AAWO,MAAM,aACX;AAGK,MAAM,aAAa;AAGnB,MAAM,gBAAgB;AAAA,EAC3B,SAAS;AAAA,EACT,OAAO;AACT;AAWO,MAAM,uBAAuB;AAAA,EAClC;AAAA,EACA;AAAA,EACA;AACF,EAAE,KAAK,GAAG;AAGH,MAAM,oBAAoB;AAAA,EAC/B;AAAA,EACA;AAAA,EACA;AACF,EAAE,KAAK,GAAG;AAMH,MAAM,uBAAuB;AAAA,EAClC;AAAA,EACA;AAAA,EACA;AACF,EAAE,KAAK,GAAG;AAGH,MAAM,qBACX;AAMK,MAAM,cACX;AAGK,MAAM,gBACX;AAOK,MAAM,kBAAkB;AAAA,EAC7B;AAAA,EACA;AACF,EAAE,KAAK,GAAG;"}
|
|
@@ -5,7 +5,7 @@ import { EyeIcon } from "../../icons/generated/eye.js";
|
|
|
5
5
|
import { EyeOffIcon } from "../../icons/generated/eye-off.js";
|
|
6
6
|
import { XCloseIcon } from "../../icons/generated/x-close.js";
|
|
7
7
|
import { cn } from "../../lib/cn.js";
|
|
8
|
-
import { controlIcon, controlPlaceholder, controlAction, wrappedControlStates, controlHeight, controlRow, controlBox } from "./control-styles.js";
|
|
8
|
+
import { controlIcon, controlAutofill, controlPlaceholder, controlAction, wrappedControlStates, controlHeight, controlRow, controlBox } from "./control-styles.js";
|
|
9
9
|
import { useMediCoreLabels } from "../../provider/medicore-provider.js";
|
|
10
10
|
function Input({
|
|
11
11
|
size = "default",
|
|
@@ -86,7 +86,8 @@ function Input({
|
|
|
86
86
|
},
|
|
87
87
|
className: cn(
|
|
88
88
|
"h-full min-w-0 flex-1 bg-transparent outline-none disabled:cursor-not-allowed",
|
|
89
|
-
controlPlaceholder
|
|
89
|
+
controlPlaceholder,
|
|
90
|
+
controlAutofill
|
|
90
91
|
),
|
|
91
92
|
...props
|
|
92
93
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"input.js","sources":["../../../src/components/input/input.tsx"],"sourcesContent":["import { Input as BaseInput } from \"@base-ui/react/input\";\nimport { type ReactNode, type Ref, useCallback, useRef, useState } from \"react\";\n\nimport { EyeIcon, EyeOffIcon, XCloseIcon } from \"../../icons\";\nimport { cn } from \"../../lib/cn\";\nimport { useMediCoreLabels } from \"../../provider\";\nimport {\n type ControlSize,\n controlAction,\n controlBox,\n controlHeight,\n controlIcon,\n controlPlaceholder,\n controlRow,\n wrappedControlStates,\n} from \"./control-styles\";\n\nexport interface InputProps\n extends Omit<BaseInput.Props, \"className\" | \"size\" | \"ref\"> {\n ref?: Ref<HTMLInputElement>;\n /** `default` 40px (control-md), `small` 36px (control-sm): the same heights as Button. */\n size?: ControlSize;\n /**\n * Red 2px border and `aria-invalid`. Never on its own: the message that says what\n * is wrong goes under the field (use `Field` with `error`, which sets this for you).\n */\n invalid?: boolean;\n /** Decorative 16px icon before the text: `SearchMdIcon`, `CalendarIcon`, `User01Icon`. */\n leadingIcon?: ReactNode;\n /** Decorative 16px icon after the text: `CalendarIcon`, `AlertCircleIcon`. */\n trailingIcon?: ReactNode;\n /** Shows an × button (\"Borrar\") while there is text. It fires `onChange` with \"\". */\n clearable?: boolean;\n /** Applied to the box, not to the `<input>`: use it for the width. */\n className?: string;\n}\n\n/**\n * One-line text field. Only the box: the label, the help text and the error go\n * OUTSIDE, in `Field`, so the message can grow to two lines.\n *\n * - It fills its container (Figma draws it at 280 as a reference). Constrain it with\n * `className=\"max-w-xs\"` or with the layout.\n * - Placeholder in text-secondary, value in text-primary. The placeholder is an\n * example, never the label.\n * - `type=\"password\"` adds the reveal button (eye / eye-off) with its accessible name.\n * - Ask the browser for help: `type=\"email\"`, `inputMode=\"numeric\"`,\n * `autoComplete=\"given-name\"`… The keyboard and autofill depend on it.\n * - Inside `Field` the label, description and `aria-invalid` wire themselves.\n */\nexport function Input({\n size = \"default\",\n invalid = false,\n leadingIcon,\n trailingIcon,\n clearable = false,\n className,\n type = \"text\",\n disabled,\n readOnly,\n value,\n defaultValue,\n onChange,\n ref,\n ...props\n}: InputProps): React.JSX.Element {\n const labels = useMediCoreLabels();\n const inputRef = useRef<HTMLInputElement | null>(null);\n const [revealed, setRevealed] = useState(false);\n const [uncontrolledFilled, setUncontrolledFilled] = useState(\n () => defaultValue != null && String(defaultValue) !== \"\",\n );\n const filled =\n value === undefined\n ? uncontrolledFilled\n : value !== null && String(value) !== \"\";\n const isPassword = type === \"password\";\n\n const setRefs = useCallback(\n (node: HTMLElement | null) => {\n const input = node as HTMLInputElement | null;\n inputRef.current = input;\n if (typeof ref === \"function\") {\n ref(input);\n } else if (ref) {\n ref.current = input;\n }\n },\n [ref],\n );\n\n function clear(): void {\n const input = inputRef.current;\n if (!input) {\n return;\n }\n // Through the native setter and a real input event, so onChange / onValueChange\n // fire exactly as if the person had deleted the text (controlled or not).\n Object.getOwnPropertyDescriptor(\n HTMLInputElement.prototype,\n \"value\",\n )?.set?.call(input, \"\");\n input.dispatchEvent(new Event(\"input\", { bubbles: true }));\n input.focus();\n }\n\n return (\n <div\n data-slot=\"input\"\n className={cn(\n \"group/control\",\n controlBox,\n controlRow,\n controlHeight[size],\n wrappedControlStates,\n className,\n )}\n >\n {leadingIcon && <span className={controlIcon}>{leadingIcon}</span>}\n <BaseInput\n ref={setRefs}\n data-slot=\"input-control\"\n type={isPassword && revealed ? \"text\" : type}\n disabled={disabled}\n readOnly={readOnly}\n value={value}\n defaultValue={defaultValue}\n aria-invalid={invalid && !disabled ? true : undefined}\n onChange={(event) => {\n setUncontrolledFilled(event.currentTarget.value !== \"\");\n onChange?.(event);\n }}\n className={cn(\n \"h-full min-w-0 flex-1 bg-transparent outline-none disabled:cursor-not-allowed\",\n controlPlaceholder,\n )}\n {...props}\n />\n {clearable && filled && !disabled && !readOnly && (\n <button\n type=\"button\"\n aria-label={labels.clear}\n className={controlAction}\n onClick={clear}\n >\n <XCloseIcon size=\"sm\" />\n </button>\n )}\n {trailingIcon && <span className={controlIcon}>{trailingIcon}</span>}\n {isPassword && (\n <button\n type=\"button\"\n aria-label={revealed ? labels.hidePassword : labels.showPassword}\n disabled={disabled}\n className={controlAction}\n onClick={() => setRevealed((current) => !current)}\n >\n {revealed ? <EyeOffIcon size=\"sm\" /> : <EyeIcon size=\"sm\" />}\n </button>\n )}\n </div>\n );\n}\n"],"names":["BaseInput"],"mappings":";;;;;;;;;
|
|
1
|
+
{"version":3,"file":"input.js","sources":["../../../src/components/input/input.tsx"],"sourcesContent":["import { Input as BaseInput } from \"@base-ui/react/input\";\nimport { type ReactNode, type Ref, useCallback, useRef, useState } from \"react\";\n\nimport { EyeIcon, EyeOffIcon, XCloseIcon } from \"../../icons\";\nimport { cn } from \"../../lib/cn\";\nimport { useMediCoreLabels } from \"../../provider\";\nimport {\n type ControlSize,\n controlAction,\n controlAutofill,\n controlBox,\n controlHeight,\n controlIcon,\n controlPlaceholder,\n controlRow,\n wrappedControlStates,\n} from \"./control-styles\";\n\nexport interface InputProps\n extends Omit<BaseInput.Props, \"className\" | \"size\" | \"ref\"> {\n ref?: Ref<HTMLInputElement>;\n /** `default` 40px (control-md), `small` 36px (control-sm): the same heights as Button. */\n size?: ControlSize;\n /**\n * Red 2px border and `aria-invalid`. Never on its own: the message that says what\n * is wrong goes under the field (use `Field` with `error`, which sets this for you).\n */\n invalid?: boolean;\n /** Decorative 16px icon before the text: `SearchMdIcon`, `CalendarIcon`, `User01Icon`. */\n leadingIcon?: ReactNode;\n /** Decorative 16px icon after the text: `CalendarIcon`, `AlertCircleIcon`. */\n trailingIcon?: ReactNode;\n /** Shows an × button (\"Borrar\") while there is text. It fires `onChange` with \"\". */\n clearable?: boolean;\n /** Applied to the box, not to the `<input>`: use it for the width. */\n className?: string;\n}\n\n/**\n * One-line text field. Only the box: the label, the help text and the error go\n * OUTSIDE, in `Field`, so the message can grow to two lines.\n *\n * - It fills its container (Figma draws it at 280 as a reference). Constrain it with\n * `className=\"max-w-xs\"` or with the layout.\n * - Placeholder in text-secondary, value in text-primary. The placeholder is an\n * example, never the label.\n * - `type=\"password\"` adds the reveal button (eye / eye-off) with its accessible name.\n * - Ask the browser for help: `type=\"email\"`, `inputMode=\"numeric\"`,\n * `autoComplete=\"given-name\"`… The keyboard and autofill depend on it.\n * - Inside `Field` the label, description and `aria-invalid` wire themselves.\n */\nexport function Input({\n size = \"default\",\n invalid = false,\n leadingIcon,\n trailingIcon,\n clearable = false,\n className,\n type = \"text\",\n disabled,\n readOnly,\n value,\n defaultValue,\n onChange,\n ref,\n ...props\n}: InputProps): React.JSX.Element {\n const labels = useMediCoreLabels();\n const inputRef = useRef<HTMLInputElement | null>(null);\n const [revealed, setRevealed] = useState(false);\n const [uncontrolledFilled, setUncontrolledFilled] = useState(\n () => defaultValue != null && String(defaultValue) !== \"\",\n );\n const filled =\n value === undefined\n ? uncontrolledFilled\n : value !== null && String(value) !== \"\";\n const isPassword = type === \"password\";\n\n const setRefs = useCallback(\n (node: HTMLElement | null) => {\n const input = node as HTMLInputElement | null;\n inputRef.current = input;\n if (typeof ref === \"function\") {\n ref(input);\n } else if (ref) {\n ref.current = input;\n }\n },\n [ref],\n );\n\n function clear(): void {\n const input = inputRef.current;\n if (!input) {\n return;\n }\n // Through the native setter and a real input event, so onChange / onValueChange\n // fire exactly as if the person had deleted the text (controlled or not).\n Object.getOwnPropertyDescriptor(\n HTMLInputElement.prototype,\n \"value\",\n )?.set?.call(input, \"\");\n input.dispatchEvent(new Event(\"input\", { bubbles: true }));\n input.focus();\n }\n\n return (\n <div\n data-slot=\"input\"\n className={cn(\n \"group/control\",\n controlBox,\n controlRow,\n controlHeight[size],\n wrappedControlStates,\n className,\n )}\n >\n {leadingIcon && <span className={controlIcon}>{leadingIcon}</span>}\n <BaseInput\n ref={setRefs}\n data-slot=\"input-control\"\n type={isPassword && revealed ? \"text\" : type}\n disabled={disabled}\n readOnly={readOnly}\n value={value}\n defaultValue={defaultValue}\n aria-invalid={invalid && !disabled ? true : undefined}\n onChange={(event) => {\n setUncontrolledFilled(event.currentTarget.value !== \"\");\n onChange?.(event);\n }}\n className={cn(\n \"h-full min-w-0 flex-1 bg-transparent outline-none disabled:cursor-not-allowed\",\n controlPlaceholder,\n controlAutofill,\n )}\n {...props}\n />\n {clearable && filled && !disabled && !readOnly && (\n <button\n type=\"button\"\n aria-label={labels.clear}\n className={controlAction}\n onClick={clear}\n >\n <XCloseIcon size=\"sm\" />\n </button>\n )}\n {trailingIcon && <span className={controlIcon}>{trailingIcon}</span>}\n {isPassword && (\n <button\n type=\"button\"\n aria-label={revealed ? labels.hidePassword : labels.showPassword}\n disabled={disabled}\n className={controlAction}\n onClick={() => setRevealed((current) => !current)}\n >\n {revealed ? <EyeOffIcon size=\"sm\" /> : <EyeIcon size=\"sm\" />}\n </button>\n )}\n </div>\n );\n}\n"],"names":["BaseInput"],"mappings":";;;;;;;;;AAmDO,SAAS,MAAM;AAAA,EACpB,OAAO;AAAA,EACP,UAAU;AAAA,EACV;AAAA,EACA;AAAA,EACA,YAAY;AAAA,EACZ;AAAA,EACA,OAAO;AAAA,EACP;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,GAAG;AACL,GAAkC;AAChC,QAAM,SAAS,kBAAA;AACf,QAAM,WAAW,OAAgC,IAAI;AACrD,QAAM,CAAC,UAAU,WAAW,IAAI,SAAS,KAAK;AAC9C,QAAM,CAAC,oBAAoB,qBAAqB,IAAI;AAAA,IAClD,MAAM,gBAAgB,QAAQ,OAAO,YAAY,MAAM;AAAA,EAAA;AAEzD,QAAM,SACJ,UAAU,SACN,qBACA,UAAU,QAAQ,OAAO,KAAK,MAAM;AAC1C,QAAM,aAAa,SAAS;AAE5B,QAAM,UAAU;AAAA,IACd,CAAC,SAA6B;AAC5B,YAAM,QAAQ;AACd,eAAS,UAAU;AACnB,UAAI,OAAO,QAAQ,YAAY;AAC7B,YAAI,KAAK;AAAA,MACX,WAAW,KAAK;AACd,YAAI,UAAU;AAAA,MAChB;AAAA,IACF;AAAA,IACA,CAAC,GAAG;AAAA,EAAA;AAGN,WAAS,QAAc;AACrB,UAAM,QAAQ,SAAS;AACvB,QAAI,CAAC,OAAO;AACV;AAAA,IACF;AAGA,WAAO;AAAA,MACL,iBAAiB;AAAA,MACjB;AAAA,IAAA,GACC,KAAK,KAAK,OAAO,EAAE;AACtB,UAAM,cAAc,IAAI,MAAM,SAAS,EAAE,SAAS,KAAA,CAAM,CAAC;AACzD,UAAM,MAAA;AAAA,EACR;AAEA,SACE;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,aAAU;AAAA,MACV,WAAW;AAAA,QACT;AAAA,QACA;AAAA,QACA;AAAA,QACA,cAAc,IAAI;AAAA,QAClB;AAAA,QACA;AAAA,MAAA;AAAA,MAGD,UAAA;AAAA,QAAA,eAAe,oBAAC,QAAA,EAAK,WAAW,aAAc,UAAA,aAAY;AAAA,QAC3D;AAAA,UAACA;AAAAA,UAAA;AAAA,YACC,KAAK;AAAA,YACL,aAAU;AAAA,YACV,MAAM,cAAc,WAAW,SAAS;AAAA,YACxC;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,YACA,gBAAc,WAAW,CAAC,WAAW,OAAO;AAAA,YAC5C,UAAU,CAAC,UAAU;AACnB,oCAAsB,MAAM,cAAc,UAAU,EAAE;AACtD,yBAAW,KAAK;AAAA,YAClB;AAAA,YACA,WAAW;AAAA,cACT;AAAA,cACA;AAAA,cACA;AAAA,YAAA;AAAA,YAED,GAAG;AAAA,UAAA;AAAA,QAAA;AAAA,QAEL,aAAa,UAAU,CAAC,YAAY,CAAC,YACpC;AAAA,UAAC;AAAA,UAAA;AAAA,YACC,MAAK;AAAA,YACL,cAAY,OAAO;AAAA,YACnB,WAAW;AAAA,YACX,SAAS;AAAA,YAET,UAAA,oBAAC,YAAA,EAAW,MAAK,KAAA,CAAK;AAAA,UAAA;AAAA,QAAA;AAAA,QAGzB,gBAAgB,oBAAC,QAAA,EAAK,WAAW,aAAc,UAAA,cAAa;AAAA,QAC5D,cACC;AAAA,UAAC;AAAA,UAAA;AAAA,YACC,MAAK;AAAA,YACL,cAAY,WAAW,OAAO,eAAe,OAAO;AAAA,YACpD;AAAA,YACA,WAAW;AAAA,YACX,SAAS,MAAM,YAAY,CAAC,YAAY,CAAC,OAAO;AAAA,YAE/C,UAAA,+BAAY,YAAA,EAAW,MAAK,MAAK,IAAK,oBAAC,SAAA,EAAQ,MAAK,KAAA,CAAK;AAAA,UAAA;AAAA,QAAA;AAAA,MAC5D;AAAA,IAAA;AAAA,EAAA;AAIR;"}
|