{"version":3,"file":"BqSlider-uNzfEIij.cjs","names":[],"sources":["../src/components/slider/BqSlider.ts"],"sourcesContent":["/**\r\n * Range slider input.\r\n * @element bq-slider\r\n * @prop {number}  value\r\n * @prop {number}  min\r\n * @prop {number}  max\r\n * @prop {number}  step\r\n * @prop {string}  label\r\n * @prop {boolean} disabled\r\n * @prop {boolean} show-value\r\n * @fires bq-input  - { value: number }\r\n * @fires bq-change - { value: number }\r\n */\r\nimport type { ComponentDefinition } from '@bquery/bquery/component';\r\nimport { bool, component, html } from '@bquery/bquery/component';\r\nimport { escapeHtml } from '@bquery/bquery/security';\r\nimport { t } from '../../i18n/index.js';\r\nimport { createFormProxy, type FormProxy } from '../../utils/form.js';\r\nimport { getBaseStyles } from '../../utils/styles.js';\r\n\r\ntype BqSliderProps = {\r\n  value: number;\r\n  min: number;\r\n  max: number;\r\n  step: number;\r\n  label: string;\r\n  disabled: boolean;\r\n  'show-value': boolean;\r\n};\r\n\r\nfunction syncInputAccessibility(input: HTMLInputElement, value: number): void {\r\n  input.setAttribute('aria-valuenow', String(value));\r\n  input.setAttribute('aria-valuetext', t('slider.valueText', { value }));\r\n}\r\n\r\nconst definition: ComponentDefinition<BqSliderProps> = {\r\n  props: {\r\n    value: { type: Number, default: 50 },\r\n    min: { type: Number, default: 0 },\r\n    max: { type: Number, default: 100 },\r\n    step: { type: Number, default: 1 },\r\n    label: { type: String, default: '' },\r\n    disabled: { type: Boolean, default: false },\r\n    'show-value': { type: Boolean, default: false },\r\n  },\r\n  styles: `\r\n    ${getBaseStyles()}\r\n    *, *::before, *::after { box-sizing: border-box; }\r\n    :host { display: block; }\r\n    .wrapper { display: flex; flex-direction: column; gap: 0.375rem; font-family: var(--bq-font-family-sans); }\r\n    .header { display: flex; justify-content: space-between; align-items: center; }\r\n    .label-text { font-size: var(--bq-font-size-sm,0.875rem); font-weight: var(--bq-font-weight-medium,500); color: var(--bq-text-base,#0f172a); }\r\n    .value { font-size: var(--bq-font-size-sm,0.875rem); color: var(--bq-text-muted,#475569); }\r\n    input[type=\"range\"] {\r\n      width: 100%; height: 0.375rem; cursor: pointer;\r\n      accent-color: var(--bq-color-primary-600,#2563eb);\r\n    }\r\n    input[type=\"range\"]:disabled { opacity: 0.5; cursor: not-allowed; }\r\n    input[type=\"range\"]:focus-visible { outline: 2px solid transparent; box-shadow: var(--bq-focus-ring); }\r\n  `,\r\n  connected() {\r\n    const self = this;\r\n\r\n    // Form proxy for native <form> participation\r\n    const name = self.getAttribute('name') ?? '';\r\n    const value = self.getAttribute('value') ?? '50';\r\n    const disabled = self.hasAttribute('disabled');\r\n    const proxy = createFormProxy(self, name, value, disabled, {\r\n      getLiveValue: () => {\r\n        const input = self.shadowRoot?.querySelector(\r\n          'input[type=\"range\"]'\r\n        ) as HTMLInputElement | null;\r\n        return input ? input.value : (self.getAttribute('value') ?? '50');\r\n      },\r\n    });\r\n    (self as unknown as Record<string, unknown>)['_formProxy'] = proxy;\r\n\r\n    const ih = (e: Event) => {\r\n      const input = e.target as HTMLInputElement | null;\r\n      if (!input) return;\r\n      const v = Number(input.value);\r\n      // Update form proxy and value display directly without re-rendering (prevents jank during drag)\r\n      proxy.setValue(String(v));\r\n      syncInputAccessibility(input, v);\r\n      const valueSpan = self.shadowRoot?.querySelector('.value');\r\n      if (valueSpan) valueSpan.textContent = String(v);\r\n      self.dispatchEvent(\r\n        new CustomEvent('bq-input', {\r\n          detail: { value: v },\r\n          bubbles: true,\r\n          composed: true,\r\n        })\r\n      );\r\n    };\r\n    const ch = (e: Event) => {\r\n      const input = e.target as HTMLInputElement | null;\r\n      if (!input) return;\r\n      const v = Number(input.value);\r\n      // Commit value to attribute on change (drag end) — triggers one clean re-render\r\n      self.setAttribute('value', String(v));\r\n      proxy.setValue(String(v));\r\n      syncInputAccessibility(input, v);\r\n      self.dispatchEvent(\r\n        new CustomEvent('bq-change', {\r\n          detail: { value: v },\r\n          bubbles: true,\r\n          composed: true,\r\n        })\r\n      );\r\n    };\r\n    (self as unknown as Record<string, unknown>)['_ih'] = ih;\r\n    (self as unknown as Record<string, unknown>)['_ch'] = ch;\r\n    self.shadowRoot?.addEventListener('input', ih);\r\n    self.shadowRoot?.addEventListener('change', ch);\r\n  },\r\n  disconnected() {\r\n    const s = this as unknown as Record<string, unknown>;\r\n    const ih = s['_ih'] as EventListener | undefined;\r\n    const ch = s['_ch'] as EventListener | undefined;\r\n    if (ih) this.shadowRoot?.removeEventListener('input', ih);\r\n    if (ch) this.shadowRoot?.removeEventListener('change', ch);\r\n    (\r\n      (this as unknown as Record<string, unknown>)['_formProxy'] as\r\n        | FormProxy\r\n        | undefined\r\n    )?.cleanup();\r\n  },\r\n  updated() {\r\n    const s = this as unknown as Record<string, unknown>;\r\n    const proxy = s['_formProxy'] as FormProxy | undefined;\r\n    if (proxy) {\r\n      proxy.setName(this.getAttribute('name') ?? '');\r\n      proxy.setValue(this.getAttribute('value') ?? '50');\r\n      proxy.setDisabled(this.hasAttribute('disabled'));\r\n    }\r\n  },\r\n  render({ props }) {\r\n    return html`\r\n      <div class=\"wrapper\" part=\"wrapper\">\r\n        ${props.label || props['show-value']\r\n          ? `<div class=\"header\">\r\n          ${props.label ? `<label class=\"label-text\" part=\"label\">${escapeHtml(props.label)}</label>` : ''}\r\n          ${props['show-value'] ? `<span class=\"value\" part=\"value\" aria-live=\"polite\">${String(props.value)}</span>` : ''}\r\n        </div>`\r\n          : ''}\r\n        <input\r\n          type=\"range\"\r\n          part=\"input\"\r\n          min=\"${String(props.min)}\"\r\n          max=\"${String(props.max)}\"\r\n          value=\"${String(props.value)}\"\r\n          step=\"${String(props.step)}\"\r\n          ${bool('disabled', props.disabled)}\r\n          aria-label=\"${escapeHtml(props.label || t('slider.ariaLabel'))}\"\r\n          aria-valuemin=\"${String(props.min)}\"\r\n          aria-valuemax=\"${String(props.max)}\"\r\n          aria-valuenow=\"${String(props.value)}\"\r\n          aria-valuetext=\"${escapeHtml(\r\n            t('slider.valueText', { value: props.value })\r\n          )}\"\r\n        />\r\n      </div>\r\n    `;\r\n  },\r\n};\r\n\r\ncomponent<BqSliderProps>('bq-slider', definition);\r\n"],"mappings":"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"}