{"version":3,"names":["createMemo","useLabelableContext","useAriaLabelledBy","external","context","readExternal","externalValue","registered","getLabelIds","length","undefined","parts","push","id","join"],"sources":["use-aria-labelled-by.ts"],"sourcesContent":["import { type Accessor, createMemo } from \"solid-js\";\nimport { useLabelableContext } from \"./labelable-context\";\n\n/**\n * Compose an `aria-labelledby` string from:\n *\n * 1. the caller-supplied external `aria-labelledby` value (e.g. from a\n *    consumer prop), and\n * 2. every label id currently registered with the nearest\n *    `<LabelableProvider>`, in **registration order**.\n *\n * Returns an `Accessor<string | undefined>` — `undefined` when neither source\n * contributes anything so the attribute can be omitted entirely (per RFC 07,\n * Solid 2 treats `undefined` as \"absent\" for presence/absence attributes).\n *\n * ### Why registration order\n *\n * DOM order requires observing the rendered label elements, which would need\n * a MutationObserver or post-mount reconciliation pass. Registration order is\n * a deterministic stand-in: Base UI labels register during setup, which in\n * practice proceeds in source/render order (and therefore in DOM order for\n * the typical \"labels before control\" layout). If a consumer genuinely needs\n * a different order, they can pass the external `aria-labelledby` string to\n * override — that string wins position-wise (it comes first in the composed\n * result).\n *\n * ### Solid 2 notes\n *\n * - The `external` argument is accepted as either a plain `string | undefined`\n *   (read once during setup, won't react) or an `Accessor<string | undefined>`\n *   (tracks). Most consumers already work with accessors in Solid 2, so this\n *   dual shape is a thin convenience.\n * - Built on `createMemo`, so joining only re-runs when either the external\n *   value or the registered-ids array changes — not on every read.\n */\nexport function useAriaLabelledBy(\n\texternal?: string | undefined | Accessor<string | undefined>,\n): Accessor<string | undefined> {\n\tconst context = useLabelableContext();\n\n\tconst readExternal = (): string | undefined => {\n\t\tif (typeof external === \"function\") return external();\n\t\treturn external;\n\t};\n\n\treturn createMemo(() => {\n\t\tconst externalValue = readExternal();\n\t\tconst registered = context.getLabelIds();\n\n\t\tif (!externalValue && registered.length === 0) {\n\t\t\treturn undefined;\n\t\t}\n\n\t\t// External wins position-wise — consumers that pass an explicit\n\t\t// `aria-labelledby` expect that to come first. Empty/whitespace-only\n\t\t// registered ids are skipped to stay tidy.\n\t\tconst parts: string[] = [];\n\t\tif (externalValue) parts.push(externalValue);\n\t\tfor (const id of registered) {\n\t\t\tif (id) parts.push(id);\n\t\t}\n\n\t\treturn parts.length > 0 ? parts.join(\" \") : undefined;\n\t});\n}\n"],"mappings":"AAAA,SAAwBA,UAAU,QAAQ,UAAU;AACpD,SAASC,mBAAmB,QAAQ,qBAAqB;;AAEzD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,SAASC,iBAAiBA,CAChCC,QAA4D,EAC7B;EAC/B,MAAMC,OAAO,GAAGH,mBAAmB,CAAC,CAAC;EAErC,MAAMI,YAAY,GAAGA,CAAA,KAA0B;IAC9C,IAAI,OAAOF,QAAQ,KAAK,UAAU,EAAE,OAAOA,QAAQ,CAAC,CAAC;IACrD,OAAOA,QAAQ;EAChB,CAAC;EAED,OAAOH,UAAU,CAAC,MAAM;IACvB,MAAMM,aAAa,GAAGD,YAAY,CAAC,CAAC;IACpC,MAAME,UAAU,GAAGH,OAAO,CAACI,WAAW,CAAC,CAAC;IAExC,IAAI,CAACF,aAAa,IAAIC,UAAU,CAACE,MAAM,KAAK,CAAC,EAAE;MAC9C,OAAOC,SAAS;IACjB;;IAEA;IACA;IACA;IACA,MAAMC,KAAe,GAAG,EAAE;IAC1B,IAAIL,aAAa,EAAEK,KAAK,CAACC,IAAI,CAACN,aAAa,CAAC;IAC5C,KAAK,MAAMO,EAAE,IAAIN,UAAU,EAAE;MAC5B,IAAIM,EAAE,EAAEF,KAAK,CAACC,IAAI,CAACC,EAAE,CAAC;IACvB;IAEA,OAAOF,KAAK,CAACF,MAAM,GAAG,CAAC,GAAGE,KAAK,CAACG,IAAI,CAAC,GAAG,CAAC,GAAGJ,SAAS;EACtD,CAAC,CAAC;AACH","ignoreList":[]}