{"version":3,"file":"field-binding.cjs","names":[],"sources":["../../../src/inputs/shared/field-binding.ts"],"sourcesContent":["import { bind } from '@vielzeug/ore';\nimport type { Readable, Signal } from '@vielzeug/ripple';\n\nimport type { ComponentSize } from '../../types';\n\n/**\n * Minimal shape of the handle returned by `createCheckable` that\n * `applyCheckableBinding` needs. Matches both checkbox (with `indeterminate`)\n * and switch (without).\n */\nexport type CheckableBindingHandle = {\n  assistiveId: string;\n  checked: Signal<boolean>;\n  disabled: Readable<boolean>;\n  errorText: Readable<string>;\n  handleClick: (event: MouseEvent) => boolean;\n  handleKeydown: (event: KeyboardEvent) => boolean;\n  helperText: Readable<string>;\n  indeterminate?: Signal<boolean>;\n  labelId: string;\n  /** Reflects `aria-required` — there's no native form control here to carry a real `required` attribute. */\n  required?: Readable<boolean | undefined>;\n};\n\n/**\n * `prop.string()` already reflects `error`'s raw value as an attribute, but that leaves the\n * attribute present-but-empty (`error=\"\"`) once set instead of removing it — this normalizes\n * an empty error back to \"no attribute at all\". Shared by every text-field component\n * (`ore-input`, `ore-textarea`, `ore-message-composer`) since `bind()`'s own `error` writer\n * needs a derived getter, not the raw prop, to get that behavior.\n *\n * @example\n * ```ts\n * bind({ attr: { error: errorAttr(errorText), size: props.size, variant: props.variant } });\n * ```\n */\nexport const errorAttr = (errorText: Readable<string>): (() => string | undefined) => {\n  return () => errorText.value || undefined;\n};\n\n/**\n * Applies the standard host bindings shared by all checkable components\n * (checkbox, switch, radio).\n *\n * Wires `role`, all ARIA attributes, `checked`, `size`, `tabindex`, the\n * `is-checked`/`is-disabled` classes, and the `click`/`keydown` event handlers.\n *\n * Pass `handle.indeterminate` for components that need it (checkbox);\n * omit it for switch/radio.\n */\nexport const applyCheckableBinding = (\n  fCtxSize: Readable<ComponentSize | undefined>,\n  handle: CheckableBindingHandle,\n  role: 'checkbox' | 'radio' | 'switch',\n): void => {\n  const {\n    assistiveId,\n    checked,\n    disabled,\n    errorText,\n    handleClick,\n    handleKeydown,\n    helperText,\n    indeterminate,\n    labelId,\n    required,\n  } = handle;\n\n  bind({\n    attr: {\n      ...(indeterminate !== undefined && { indeterminate }),\n      ariaChecked: () => {\n        if (role === 'checkbox' && indeterminate?.value) return 'mixed';\n\n        return checked.value ? 'true' : 'false';\n      },\n      ariaDescribedby: () => (errorText.value || helperText.value ? assistiveId : null),\n      ariaDisabled: () => (disabled.value ? 'true' : null),\n      ariaInvalid: () => (errorText.value ? 'true' : null),\n      ariaLabelledby: labelId,\n      ariaRequired: () => (required?.value ? 'true' : null),\n      checked,\n      role,\n      size: fCtxSize,\n      tabindex: () => (disabled.value ? undefined : 0),\n    },\n    class: () => ({\n      'is-checked': checked.value,\n      'is-disabled': disabled.value,\n      ...(indeterminate !== undefined && { 'is-indeterminate': indeterminate.value }),\n    }),\n    on: {\n      click: handleClick,\n      keydown: handleKeydown,\n    },\n  });\n};\n"],"mappings":"+BAoCA,IAAa,EAAa,OACX,EAAU,OAAS,IAAA,GAarB,GACX,EACA,EACA,IACS,CACT,GAAM,CACJ,cACA,UACA,WACA,YACA,cACA,gBACA,aACA,gBACA,UACA,YACE,GAEJ,EAAA,EAAA,KAAA,CAAK,CACH,KAAM,CACJ,GAAI,IAAkB,IAAA,IAAa,CAAE,eAAc,EACnD,gBACM,IAAS,YAAc,GAAe,MAAc,QAEjD,EAAQ,MAAQ,OAAS,QAElC,oBAAwB,EAAU,OAAS,EAAW,MAAQ,EAAc,KAC5E,iBAAqB,EAAS,MAAQ,OAAS,KAC/C,gBAAoB,EAAU,MAAQ,OAAS,KAC/C,eAAgB,EAChB,iBAAqB,GAAU,MAAQ,OAAS,KAChD,UACA,OACA,KAAM,EACN,aAAiB,EAAS,MAAQ,IAAA,GAAY,CAChD,EACA,WAAc,CACZ,aAAc,EAAQ,MACtB,cAAe,EAAS,MACxB,GAAI,IAAkB,IAAA,IAAa,CAAE,mBAAoB,EAAc,KAAM,CAC/E,GACA,GAAI,CACF,MAAO,EACP,QAAS,CACX,CACF,CAAC,CACH"}