@vielzeug/refine 2.1.3 → 2.2.4

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.
Files changed (156) hide show
  1. package/dist/accordion.cjs +1 -1
  2. package/dist/accordion.cjs.map +1 -1
  3. package/dist/accordion.js +2 -2
  4. package/dist/accordion.js.map +1 -1
  5. package/dist/carousel.cjs +25 -24
  6. package/dist/carousel.cjs.map +1 -1
  7. package/dist/carousel.js +125 -135
  8. package/dist/carousel.js.map +1 -1
  9. package/dist/combobox.cjs +14 -14
  10. package/dist/combobox.cjs.map +1 -1
  11. package/dist/combobox.js +88 -98
  12. package/dist/combobox.js.map +1 -1
  13. package/dist/content/carousel/carousel.d.ts.map +1 -1
  14. package/dist/content/list/_list-item-reveal.cjs +1 -1
  15. package/dist/content/list/_list-item-reveal.cjs.map +1 -1
  16. package/dist/content/list/_list-item-reveal.d.ts +3 -3
  17. package/dist/content/list/_list-item-reveal.d.ts.map +1 -1
  18. package/dist/content/list/_list-item-reveal.js +22 -22
  19. package/dist/content/list/_list-item-reveal.js.map +1 -1
  20. package/dist/content/list/list-item.d.ts.map +1 -1
  21. package/dist/core/focus.cjs +1 -1
  22. package/dist/core/focus.cjs.map +1 -1
  23. package/dist/core/focus.d.ts.map +1 -1
  24. package/dist/core/focus.js +21 -20
  25. package/dist/core/focus.js.map +1 -1
  26. package/dist/core/index.d.ts +2 -3
  27. package/dist/core/index.d.ts.map +1 -1
  28. package/dist/core/nav.cjs +1 -1
  29. package/dist/core/nav.cjs.map +1 -1
  30. package/dist/core/nav.d.ts +3 -62
  31. package/dist/core/nav.d.ts.map +1 -1
  32. package/dist/core/nav.js +41 -124
  33. package/dist/core/nav.js.map +1 -1
  34. package/dist/core/option-list.cjs +1 -1
  35. package/dist/core/option-list.cjs.map +1 -1
  36. package/dist/core/option-list.d.ts +5 -5
  37. package/dist/core/option-list.d.ts.map +1 -1
  38. package/dist/core/option-list.js +14 -13
  39. package/dist/core/option-list.js.map +1 -1
  40. package/dist/core/overlay.cjs +1 -1
  41. package/dist/core/overlay.cjs.map +1 -1
  42. package/dist/core/overlay.d.ts +0 -8
  43. package/dist/core/overlay.d.ts.map +1 -1
  44. package/dist/core/overlay.js +1 -3
  45. package/dist/core/overlay.js.map +1 -1
  46. package/dist/custom-elements.json +5636 -5683
  47. package/dist/drawer.cjs +6 -6
  48. package/dist/drawer.cjs.map +1 -1
  49. package/dist/drawer.js +65 -75
  50. package/dist/drawer.js.map +1 -1
  51. package/dist/feedback/skeleton/skeleton.css.cjs +1 -1
  52. package/dist/feedback/skeleton/skeleton.css.cjs.map +1 -1
  53. package/dist/feedback/skeleton/skeleton.css.js +1 -1
  54. package/dist/feedback/skeleton/skeleton.css.js.map +1 -1
  55. package/dist/feedback/skeleton/skeleton.d.ts.map +1 -1
  56. package/dist/feedback/toast/toast.d.ts.map +1 -1
  57. package/dist/grid.cjs +2 -2
  58. package/dist/grid.cjs.map +1 -1
  59. package/dist/grid.js +42 -41
  60. package/dist/grid.js.map +1 -1
  61. package/dist/input.cjs.map +1 -1
  62. package/dist/input.js.map +1 -1
  63. package/dist/inputs/input/input.css.cjs +1 -1
  64. package/dist/inputs/input/input.css.cjs.map +1 -1
  65. package/dist/inputs/input/input.css.js +1 -1
  66. package/dist/inputs/input/input.css.js.map +1 -1
  67. package/dist/inputs/input/input.d.ts +2 -0
  68. package/dist/inputs/input/input.d.ts.map +1 -1
  69. package/dist/inputs/select/select.d.ts +2 -2
  70. package/dist/inputs/select/select.d.ts.map +1 -1
  71. package/dist/layout/grid/grid.d.ts.map +1 -1
  72. package/dist/layout/navbar/navbar.d.ts.map +1 -1
  73. package/dist/layout/sidebar/sidebar.d.ts.map +1 -1
  74. package/dist/list-item.cjs +2 -6
  75. package/dist/list-item.cjs.map +1 -1
  76. package/dist/list-item.js +40 -39
  77. package/dist/list-item.js.map +1 -1
  78. package/dist/list.cjs +1 -1
  79. package/dist/list.cjs.map +1 -1
  80. package/dist/list.js +2 -2
  81. package/dist/list.js.map +1 -1
  82. package/dist/marquee.cjs +1 -1
  83. package/dist/marquee.cjs.map +1 -1
  84. package/dist/marquee.js +3 -1
  85. package/dist/marquee.js.map +1 -1
  86. package/dist/menu.cjs +5 -5
  87. package/dist/menu.cjs.map +1 -1
  88. package/dist/menu.js +59 -59
  89. package/dist/menu.js.map +1 -1
  90. package/dist/navbar.cjs +9 -9
  91. package/dist/navbar.cjs.map +1 -1
  92. package/dist/navbar.js +124 -116
  93. package/dist/navbar.js.map +1 -1
  94. package/dist/otp-input.cjs +1 -1
  95. package/dist/otp-input.cjs.map +1 -1
  96. package/dist/otp-input.js +2 -2
  97. package/dist/otp-input.js.map +1 -1
  98. package/dist/overlay/drawer/drawer.d.ts.map +1 -1
  99. package/dist/overlay/menu/menu.d.ts.map +1 -1
  100. package/dist/radio-group.cjs +1 -1
  101. package/dist/radio-group.cjs.map +1 -1
  102. package/dist/radio-group.js +2 -3
  103. package/dist/radio-group.js.map +1 -1
  104. package/dist/radio.cjs +1 -1
  105. package/dist/radio.cjs.map +1 -1
  106. package/dist/radio.js +12 -11
  107. package/dist/radio.js.map +1 -1
  108. package/dist/rating.cjs +1 -1
  109. package/dist/rating.cjs.map +1 -1
  110. package/dist/rating.js +1 -1
  111. package/dist/rating.js.map +1 -1
  112. package/dist/refine.cjs +188 -195
  113. package/dist/refine.cjs.map +1 -1
  114. package/dist/refine.iife.js +212 -219
  115. package/dist/refine.iife.js.map +1 -1
  116. package/dist/refine.js +392 -399
  117. package/dist/refine.js.map +1 -1
  118. package/dist/select.cjs +1 -1
  119. package/dist/select.cjs.map +1 -1
  120. package/dist/select.js +1 -0
  121. package/dist/select.js.map +1 -1
  122. package/dist/sidebar.cjs +16 -16
  123. package/dist/sidebar.cjs.map +1 -1
  124. package/dist/sidebar.js +106 -91
  125. package/dist/sidebar.js.map +1 -1
  126. package/dist/skeleton.cjs +3 -3
  127. package/dist/skeleton.cjs.map +1 -1
  128. package/dist/skeleton.js +8 -7
  129. package/dist/skeleton.js.map +1 -1
  130. package/dist/stepper.cjs +1 -1
  131. package/dist/stepper.cjs.map +1 -1
  132. package/dist/stepper.js +3 -3
  133. package/dist/stepper.js.map +1 -1
  134. package/dist/styles/fouc.css +22 -0
  135. package/dist/styles/preflight.css +2 -10
  136. package/dist/tabs.cjs +1 -1
  137. package/dist/tabs.cjs.map +1 -1
  138. package/dist/tabs.js +4 -5
  139. package/dist/tabs.js.map +1 -1
  140. package/dist/toast.cjs +13 -17
  141. package/dist/toast.cjs.map +1 -1
  142. package/dist/toast.js +86 -85
  143. package/dist/toast.js.map +1 -1
  144. package/package.json +18 -11
  145. package/dist/core/swipe.cjs +0 -2
  146. package/dist/core/swipe.cjs.map +0 -1
  147. package/dist/core/swipe.d.ts +0 -40
  148. package/dist/core/swipe.d.ts.map +0 -1
  149. package/dist/core/swipe.js +0 -63
  150. package/dist/core/swipe.js.map +0 -1
  151. package/dist/core/typeahead.cjs +0 -2
  152. package/dist/core/typeahead.cjs.map +0 -1
  153. package/dist/core/typeahead.d.ts +0 -53
  154. package/dist/core/typeahead.d.ts.map +0 -1
  155. package/dist/core/typeahead.js +0 -23
  156. package/dist/core/typeahead.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"skeleton.d.ts","sourceRoot":"","sources":["../../../src/feedback/skeleton/skeleton.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAIjD,2CAA2C;AAC3C,MAAM,MAAM,gBAAgB,GAAG;IAC7B,+BAA+B;IAC/B,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,4CAA4C;IAC5C,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,gDAAgD;IAChD,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,2DAA2D;IAC3D,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,0DAA0D;IAC1D,IAAI,CAAC,EAAE,aAAa,CAAC;IACrB,2FAA2F;IAC3F,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,4DAA4D;IAC5D,OAAO,CAAC,EAAE,MAAM,GAAG,QAAQ,GAAG,MAAM,CAAC;IACrC,2CAA2C;IAC3C,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwCG;AACH,eAAO,MAAM,YAAY,EAAG,cAAuB,CAAC"}
1
+ {"version":3,"file":"skeleton.d.ts","sourceRoot":"","sources":["../../../src/feedback/skeleton/skeleton.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAIjD,2CAA2C;AAC3C,MAAM,MAAM,gBAAgB,GAAG;IAC7B,+BAA+B;IAC/B,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,4CAA4C;IAC5C,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,gDAAgD;IAChD,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,2DAA2D;IAC3D,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,0DAA0D;IAC1D,IAAI,CAAC,EAAE,aAAa,CAAC;IACrB,2FAA2F;IAC3F,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,4DAA4D;IAC5D,OAAO,CAAC,EAAE,MAAM,GAAG,QAAQ,GAAG,MAAM,CAAC;IACrC,2CAA2C;IAC3C,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwCG;AACH,eAAO,MAAM,YAAY,EAAG,cAAuB,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"toast.d.ts","sourceRoot":"","sources":["../../../src/feedback/toast/toast.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"toast.d.ts","sourceRoot":"","sources":["../../../src/feedback/toast/toast.ts"],"names":[],"mappings":"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"}
package/dist/grid.cjs CHANGED
@@ -1,4 +1,4 @@
1
- Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("./layout/grid/grid.css.cjs");let t=require("@vielzeug/ore");var n=[[`cols2xl`,`--size-screen-2xl`],[`colsXl`,`--size-screen-xl`],[`colsLg`,`--size-screen-lg`],[`colsMd`,`--size-screen-md`],[`colsSm`,`--size-screen-sm`]],r=[[`areas2xl`,`--size-screen-2xl`],[`areasXl`,`--size-screen-xl`],[`areasLg`,`--size-screen-lg`],[`areasMd`,`--size-screen-md`],[`areasSm`,`--size-screen-sm`]],i=(e,t,n)=>{let r=getComputedStyle(e).getPropertyValue(t).trim(),i=Number.parseFloat(r);return Number.isFinite(i)?i:n},a={"--size-screen-2xl":1536,"--size-screen-lg":1024,"--size-screen-md":768,"--size-screen-sm":640,"--size-screen-xl":1280},o=`ore-grid`;(0,t.define)(o,{props:{align:t.prop.string(),areas:t.prop.string(),areas2xl:t.prop.string(),areasLg:t.prop.string(),areasMd:t.prop.string(),areasSm:t.prop.string(),areasXl:t.prop.string(),cols:t.prop.string(),cols2xl:t.prop.string(),colsLg:t.prop.string(),colsMd:t.prop.string(),colsSm:t.prop.string(),colsXl:t.prop.string(),flow:t.prop.string(),fullwidth:t.prop.bool(!1),gap:t.prop.string(),justify:t.prop.string(),minColWidth:t.prop.string(),responsive:t.prop.bool(!1),rows:t.prop.string()},setup(e){let o=(0,t.getHost)(),s=t.watchEffect,c=(e,t,n)=>e===`auto`||!e&&t?`repeat(auto-fit, minmax(${n||`250px`}, 1fr))`:e?`repeat(${e}, 1fr)`:null,l=()=>{let t=o.offsetWidth,r=!!e.responsive.value,s=e.minColWidth.value??``,l;for(let[r,s]of n)if(t>=i(o,s,a[s])&&e[r].value){l=e[r].value;break}l||=e.cols.value||void 0;let u=c(l,r,s);u?o.style.setProperty(`--_cols`,u):o.style.removeProperty(`--_cols`)};s(()=>{e.cols.value,e.colsSm.value,e.colsMd.value,e.colsLg.value,e.colsXl.value,e.cols2xl.value,e.responsive.value,e.minColWidth.value,l()});let u=()=>{let t=o.offsetWidth,n=``;for(let[s,c]of r)if(t>=i(o,c,a[c])&&e[s].value){n=e[s].value;break}n||=e.areas.value||``,n?o.style.setProperty(`grid-template-areas`,n):o.style.removeProperty(`grid-template-areas`)};return s(()=>{let t=e.rows.value;t&&t!==`auto`?o.style.setProperty(`--_rows`,`repeat(${t}, 1fr)`):o.style.removeProperty(`--_rows`)}),s(()=>{e.areas.value,e.areasSm.value,e.areasMd.value,e.areasLg.value,e.areasXl.value,e.areas2xl.value,u()}),(0,t.onMounted)(()=>{let e=(0,t.resizeObserver)(o);s(()=>{e.value,l(),u()})}),t.html`
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("./layout/grid/grid.css.cjs");let t=require("@vielzeug/ore"),n=require("@vielzeug/sentinel");var r=[[`cols2xl`,`--size-screen-2xl`],[`colsXl`,`--size-screen-xl`],[`colsLg`,`--size-screen-lg`],[`colsMd`,`--size-screen-md`],[`colsSm`,`--size-screen-sm`]],i=[[`areas2xl`,`--size-screen-2xl`],[`areasXl`,`--size-screen-xl`],[`areasLg`,`--size-screen-lg`],[`areasMd`,`--size-screen-md`],[`areasSm`,`--size-screen-sm`]],a=(e,t,n)=>{let r=getComputedStyle(e).getPropertyValue(t).trim(),i=Number.parseFloat(r);return Number.isFinite(i)?i:n},o={"--size-screen-2xl":1536,"--size-screen-lg":1024,"--size-screen-md":768,"--size-screen-sm":640,"--size-screen-xl":1280},s=`ore-grid`;(0,t.define)(s,{props:{align:t.prop.string(),areas:t.prop.string(),areas2xl:t.prop.string(),areasLg:t.prop.string(),areasMd:t.prop.string(),areasSm:t.prop.string(),areasXl:t.prop.string(),cols:t.prop.string(),cols2xl:t.prop.string(),colsLg:t.prop.string(),colsMd:t.prop.string(),colsSm:t.prop.string(),colsXl:t.prop.string(),flow:t.prop.string(),fullwidth:t.prop.bool(!1),gap:t.prop.string(),justify:t.prop.string(),minColWidth:t.prop.string(),responsive:t.prop.bool(!1),rows:t.prop.string()},setup(e){let s=(0,t.getHost)(),c=t.watchEffect,l=(e,t,n)=>e===`auto`||!e&&t?`repeat(auto-fit, minmax(${n||`250px`}, 1fr))`:e?`repeat(${e}, 1fr)`:null,u=()=>{let t=s.offsetWidth,n=!!e.responsive.value,i=e.minColWidth.value??``,c;for(let[n,i]of r)if(t>=a(s,i,o[i])&&e[n].value){c=e[n].value;break}c||=e.cols.value||void 0;let u=l(c,n,i);u?s.style.setProperty(`--_cols`,u):s.style.removeProperty(`--_cols`)};c(()=>{e.cols.value,e.colsSm.value,e.colsMd.value,e.colsLg.value,e.colsXl.value,e.cols2xl.value,e.responsive.value,e.minColWidth.value,u()});let d=()=>{let t=s.offsetWidth,n=``;for(let[r,c]of i)if(t>=a(s,c,o[c])&&e[r].value){n=e[r].value;break}n||=e.areas.value||``,n?s.style.setProperty(`grid-template-areas`,n):s.style.removeProperty(`grid-template-areas`)};return c(()=>{let t=e.rows.value;t&&t!==`auto`?s.style.setProperty(`--_rows`,`repeat(${t}, 1fr)`):s.style.removeProperty(`--_rows`)}),c(()=>{e.areas.value,e.areasSm.value,e.areasMd.value,e.areasLg.value,e.areasXl.value,e.areas2xl.value,d()}),(0,t.onMounted)(()=>{let e=(0,n.createElementSize)(s);(0,t.onCleanup)(()=>e.dispose()),c(()=>{e.value&&(u(),d())})}),t.html`
2
2
  <slot></slot>
3
- `},styles:[e.default]}),exports.GRID_TAG=o;
3
+ `},styles:[e.default]}),exports.GRID_TAG=s;
4
4
  //# sourceMappingURL=grid.cjs.map
package/dist/grid.cjs.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"grid.cjs","names":[],"sources":["../src/layout/grid/grid.ts"],"sourcesContent":["import { define, getHost, html, onMounted, prop, resizeObserver, watchEffect } from '@vielzeug/ore';\n\nimport styles from './grid.css?inline';\n\nconst BREAKPOINTS: ['cols2xl' | 'colsXl' | 'colsLg' | 'colsMd' | 'colsSm', string][] = [\n ['cols2xl', '--size-screen-2xl'],\n ['colsXl', '--size-screen-xl'],\n ['colsLg', '--size-screen-lg'],\n ['colsMd', '--size-screen-md'],\n ['colsSm', '--size-screen-sm'],\n];\n\nconst AREAS_BREAKPOINTS: ['areas2xl' | 'areasXl' | 'areasLg' | 'areasMd' | 'areasSm', string][] = [\n ['areas2xl', '--size-screen-2xl'],\n ['areasXl', '--size-screen-xl'],\n ['areasLg', '--size-screen-lg'],\n ['areasMd', '--size-screen-md'],\n ['areasSm', '--size-screen-sm'],\n];\n\nconst resolveBp = (host: HTMLElement, varName: string, fallback: number): number => {\n const raw = getComputedStyle(host).getPropertyValue(varName).trim();\n const parsed = Number.parseFloat(raw);\n\n return Number.isFinite(parsed) ? parsed : fallback;\n};\n\nconst BP_FALLBACKS: Record<string, number> = {\n '--size-screen-2xl': 1536,\n '--size-screen-lg': 1024,\n '--size-screen-md': 768,\n '--size-screen-sm': 640,\n '--size-screen-xl': 1280,\n};\n\ntype ColCount = '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9' | '10' | '11' | '12' | 'auto';\n\n/** Grid component properties */\nexport type OreGridProps = {\n /** Align items vertically */\n align?: 'start' | 'center' | 'end' | 'stretch' | 'baseline';\n /** CSS grid-template-areas value */\n areas?: string;\n /** grid-template-areas at 2xl breakpoint (≥1536px) */\n areas2xl?: string;\n /** grid-template-areas at lg breakpoint (≥1024px) */\n areasLg?: string;\n /** grid-template-areas at md breakpoint (≥768px) */\n areasMd?: string;\n /** grid-template-areas at sm breakpoint (≥640px) */\n areasSm?: string;\n /** grid-template-areas at xl breakpoint (≥1280px) */\n areasXl?: string;\n /** Number of columns: '1'-'12' | 'auto' */\n cols?: ColCount;\n /** Columns at 2xl breakpoint (≥1536px) */\n cols2xl?: ColCount;\n /** Columns at lg breakpoint (≥1024px) */\n colsLg?: ColCount;\n /** Columns at md breakpoint (≥768px) */\n colsMd?: ColCount;\n /** Columns at sm breakpoint (≥640px) */\n colsSm?: ColCount;\n /** Columns at xl breakpoint (≥1280px) */\n colsXl?: ColCount;\n /** Grid auto flow direction */\n flow?: 'row' | 'column' | 'row-dense' | 'column-dense';\n /** Stretch the grid to fill its container's full width */\n fullwidth?: boolean;\n /** Gap between items */\n gap?: 'none' | 'xs' | 'sm' | 'md' | 'lg' | 'xl' | '2xl';\n /** Justify items horizontally */\n justify?: 'start' | 'center' | 'end' | 'stretch';\n /** Minimum column width for responsive mode (default: 250px) */\n minColWidth?: string;\n /** Use auto-fit responsive columns */\n responsive?: boolean;\n /** Number of rows: '1'-'12' | 'auto' */\n rows?: '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9' | '10' | '11' | '12' | 'auto';\n};\n\n/**\n * ore-grid — Flexible grid layout with responsive column control.\n *\n * Columns are computed in JS and applied as `--_cols` inline, so they respond\n * to the element's own width via ResizeObserver. CSS custom properties\n * `--grid-cols`, `--grid-rows`, `--grid-gap`, `--grid-row-gap`, `--grid-col-gap`\n * are honoured as fallbacks when no attribute is set.\n *\n * @element ore-grid\n *\n * @attr {string} cols - Column count: '1'–'12' | 'auto'\n * @attr {string} cols-sm - Columns when width ≥ 640px\n * @attr {string} cols-md - Columns when width ≥ 768px\n * @attr {string} cols-lg - Columns when width ≥ 1024px\n * @attr {string} cols-xl - Columns when width ≥ 1280px\n * @attr {string} cols-2xl - Columns when width ≥ 1536px\n * @attr {string} rows - Row count: '1'–'12' | 'auto'\n * @attr {string} gap - Gap token: 'none' | 'xs' | 'sm' | 'md' | 'lg' | 'xl' | '2xl'\n * @attr {string} align - align-items: 'start' | 'center' | 'end' | 'stretch' | 'baseline'\n * @attr {string} justify - justify-items: 'start' | 'center' | 'end' | 'stretch'\n * @attr {string} flow - grid-auto-flow: 'row' | 'column' | 'row-dense' | 'column-dense'\n * @attr {boolean} responsive - Enables auto-fit columns without a fixed count\n * @attr {string} min-col-width - Min column width for responsive mode (default: 250px)\n * @attr {boolean} fullwidth - Stretch the grid to fill its container's full width\n * @attr {string} areas - CSS grid-template-areas value (e.g. \"'header header' 'nav main'\")\n * @attr {string} areas-sm - grid-template-areas when width ≥ 640px\n * @attr {string} areas-md - grid-template-areas when width ≥ 768px\n * @attr {string} areas-lg - grid-template-areas when width ≥ 1024px\n * @attr {string} areas-xl - grid-template-areas when width ≥ 1280px\n * @attr {string} areas-2xl - grid-template-areas when width ≥ 1536px\n *\n * @slot - Grid items\n *\n * @cssprop --grid-cols - Fallback column template (used when no cols attr is set)\n * @cssprop --grid-rows - Fallback row template\n * @cssprop --grid-gap - Fallback gap\n * @cssprop --grid-row-gap - Fallback row gap\n * @cssprop --grid-col-gap - Fallback column gap\n *\n * @example\n * <ore-grid cols=\"1\" cols-sm=\"2\" cols-lg=\"4\" gap=\"md\">\n * <div>Item</div>\n * </ore-grid>\n *\n * @example\n * <!-- Responsive auto-fit -->\n * <ore-grid responsive min-col-width=\"200px\" gap=\"sm\">\n * <div>Card</div>\n * </ore-grid>\n *\n * @example\n * <!-- Named grid areas -->\n * <ore-grid cols=\"2\" rows=\"2\" areas=\"'header header' 'nav main'\">\n * <header style=\"grid-area: header\">Header</header>\n * <nav style=\"grid-area: nav\">Nav</nav>\n * <main style=\"grid-area: main\">Main</main>\n * </ore-grid>\n */\nexport const GRID_TAG = 'ore-grid' as const;\ndefine<OreGridProps>(GRID_TAG, {\n props: {\n align: prop.string<'start' | 'center' | 'end' | 'stretch' | 'baseline'>(),\n areas: prop.string(),\n areas2xl: prop.string(),\n areasLg: prop.string(),\n areasMd: prop.string(),\n areasSm: prop.string(),\n areasXl: prop.string(),\n cols: prop.string<ColCount>(),\n cols2xl: prop.string<ColCount>(),\n colsLg: prop.string<ColCount>(),\n colsMd: prop.string<ColCount>(),\n colsSm: prop.string<ColCount>(),\n colsXl: prop.string<ColCount>(),\n flow: prop.string<'row' | 'column' | 'row-dense' | 'column-dense'>(),\n fullwidth: prop.bool(false),\n gap: prop.string<'none' | 'xs' | 'sm' | 'md' | 'lg' | 'xl' | '2xl'>(),\n justify: prop.string<'start' | 'center' | 'end' | 'stretch'>(),\n minColWidth: prop.string(),\n responsive: prop.bool(false),\n rows: prop.string<'1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9' | '10' | '11' | '12' | 'auto'>(),\n },\n\n setup(props) {\n const el = getHost();\n const watch = watchEffect;\n\n const computeCols = (activeCols: string | undefined, responsive: boolean, minW: string): string | null => {\n if (activeCols === 'auto' || (!activeCols && responsive)) {\n return `repeat(auto-fit, minmax(${minW || '250px'}, 1fr))`;\n }\n\n return activeCols ? `repeat(${activeCols}, 1fr)` : null;\n };\n const updateCols = () => {\n const w = el.offsetWidth;\n const responsive = Boolean(props.responsive.value);\n const minW = props.minColWidth.value ?? '';\n let activeCols: string | undefined;\n\n for (const [key, cssVar] of BREAKPOINTS) {\n if (w >= resolveBp(el, cssVar, BP_FALLBACKS[cssVar]) && props[key].value) {\n activeCols = props[key].value!;\n break;\n }\n }\n activeCols ||= props.cols.value || undefined;\n\n const colsValue = computeCols(activeCols, responsive, minW);\n\n if (colsValue) {\n el.style.setProperty('--_cols', colsValue);\n } else {\n el.style.removeProperty('--_cols');\n }\n };\n\n // Re-run cols whenever any responsive prop changes\n watch(() => {\n void [\n props.cols.value,\n props.colsSm.value,\n props.colsMd.value,\n props.colsLg.value,\n props.colsXl.value,\n props.cols2xl.value,\n props.responsive.value,\n props.minColWidth.value,\n ];\n updateCols();\n });\n\n const updateAreas = () => {\n const w = el.offsetWidth;\n let active = '';\n\n for (const [key, cssVar] of AREAS_BREAKPOINTS) {\n if (w >= resolveBp(el, cssVar, BP_FALLBACKS[cssVar]) && props[key].value) {\n active = props[key].value!;\n break;\n }\n }\n active ||= props.areas.value || '';\n\n if (active) {\n el.style.setProperty('grid-template-areas', active);\n } else {\n el.style.removeProperty('grid-template-areas');\n }\n };\n\n // Rows\n watch(() => {\n const rows = props.rows.value;\n\n if (rows && rows !== 'auto') {\n el.style.setProperty('--_rows', `repeat(${rows}, 1fr)`);\n } else {\n el.style.removeProperty('--_rows');\n }\n });\n // Grid template areas (responsive)\n watch(() => {\n void [\n props.areas.value,\n props.areasSm.value,\n props.areasMd.value,\n props.areasLg.value,\n props.areasXl.value,\n props.areas2xl.value,\n ];\n updateAreas();\n });\n\n // Also, update on element resize (drives breakpoint switching)\n onMounted(() => {\n const size = resizeObserver(el);\n\n watch(() => {\n void size.value;\n updateCols();\n updateAreas();\n });\n });\n\n return html`\n <slot></slot>\n `;\n },\n\n styles: [styles],\n});\n"],"mappings":"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"}
1
+ {"version":3,"file":"grid.cjs","names":[],"sources":["../src/layout/grid/grid.ts"],"sourcesContent":["import { define, getHost, html, onCleanup, onMounted, prop, watchEffect } from '@vielzeug/ore';\nimport { createElementSize } from '@vielzeug/sentinel';\n\nimport styles from './grid.css?inline';\n\nconst BREAKPOINTS: ['cols2xl' | 'colsXl' | 'colsLg' | 'colsMd' | 'colsSm', string][] = [\n ['cols2xl', '--size-screen-2xl'],\n ['colsXl', '--size-screen-xl'],\n ['colsLg', '--size-screen-lg'],\n ['colsMd', '--size-screen-md'],\n ['colsSm', '--size-screen-sm'],\n];\n\nconst AREAS_BREAKPOINTS: ['areas2xl' | 'areasXl' | 'areasLg' | 'areasMd' | 'areasSm', string][] = [\n ['areas2xl', '--size-screen-2xl'],\n ['areasXl', '--size-screen-xl'],\n ['areasLg', '--size-screen-lg'],\n ['areasMd', '--size-screen-md'],\n ['areasSm', '--size-screen-sm'],\n];\n\nconst resolveBp = (host: HTMLElement, varName: string, fallback: number): number => {\n const raw = getComputedStyle(host).getPropertyValue(varName).trim();\n const parsed = Number.parseFloat(raw);\n\n return Number.isFinite(parsed) ? parsed : fallback;\n};\n\nconst BP_FALLBACKS: Record<string, number> = {\n '--size-screen-2xl': 1536,\n '--size-screen-lg': 1024,\n '--size-screen-md': 768,\n '--size-screen-sm': 640,\n '--size-screen-xl': 1280,\n};\n\ntype ColCount = '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9' | '10' | '11' | '12' | 'auto';\n\n/** Grid component properties */\nexport type OreGridProps = {\n /** Align items vertically */\n align?: 'start' | 'center' | 'end' | 'stretch' | 'baseline';\n /** CSS grid-template-areas value */\n areas?: string;\n /** grid-template-areas at 2xl breakpoint (≥1536px) */\n areas2xl?: string;\n /** grid-template-areas at lg breakpoint (≥1024px) */\n areasLg?: string;\n /** grid-template-areas at md breakpoint (≥768px) */\n areasMd?: string;\n /** grid-template-areas at sm breakpoint (≥640px) */\n areasSm?: string;\n /** grid-template-areas at xl breakpoint (≥1280px) */\n areasXl?: string;\n /** Number of columns: '1'-'12' | 'auto' */\n cols?: ColCount;\n /** Columns at 2xl breakpoint (≥1536px) */\n cols2xl?: ColCount;\n /** Columns at lg breakpoint (≥1024px) */\n colsLg?: ColCount;\n /** Columns at md breakpoint (≥768px) */\n colsMd?: ColCount;\n /** Columns at sm breakpoint (≥640px) */\n colsSm?: ColCount;\n /** Columns at xl breakpoint (≥1280px) */\n colsXl?: ColCount;\n /** Grid auto flow direction */\n flow?: 'row' | 'column' | 'row-dense' | 'column-dense';\n /** Stretch the grid to fill its container's full width */\n fullwidth?: boolean;\n /** Gap between items */\n gap?: 'none' | 'xs' | 'sm' | 'md' | 'lg' | 'xl' | '2xl';\n /** Justify items horizontally */\n justify?: 'start' | 'center' | 'end' | 'stretch';\n /** Minimum column width for responsive mode (default: 250px) */\n minColWidth?: string;\n /** Use auto-fit responsive columns */\n responsive?: boolean;\n /** Number of rows: '1'-'12' | 'auto' */\n rows?: '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9' | '10' | '11' | '12' | 'auto';\n};\n\n/**\n * ore-grid — Flexible grid layout with responsive column control.\n *\n * Columns are computed in JS and applied as `--_cols` inline, so they respond\n * to the element's own width via ResizeObserver. CSS custom properties\n * `--grid-cols`, `--grid-rows`, `--grid-gap`, `--grid-row-gap`, `--grid-col-gap`\n * are honoured as fallbacks when no attribute is set.\n *\n * @element ore-grid\n *\n * @attr {string} cols - Column count: '1'–'12' | 'auto'\n * @attr {string} cols-sm - Columns when width ≥ 640px\n * @attr {string} cols-md - Columns when width ≥ 768px\n * @attr {string} cols-lg - Columns when width ≥ 1024px\n * @attr {string} cols-xl - Columns when width ≥ 1280px\n * @attr {string} cols-2xl - Columns when width ≥ 1536px\n * @attr {string} rows - Row count: '1'–'12' | 'auto'\n * @attr {string} gap - Gap token: 'none' | 'xs' | 'sm' | 'md' | 'lg' | 'xl' | '2xl'\n * @attr {string} align - align-items: 'start' | 'center' | 'end' | 'stretch' | 'baseline'\n * @attr {string} justify - justify-items: 'start' | 'center' | 'end' | 'stretch'\n * @attr {string} flow - grid-auto-flow: 'row' | 'column' | 'row-dense' | 'column-dense'\n * @attr {boolean} responsive - Enables auto-fit columns without a fixed count\n * @attr {string} min-col-width - Min column width for responsive mode (default: 250px)\n * @attr {boolean} fullwidth - Stretch the grid to fill its container's full width\n * @attr {string} areas - CSS grid-template-areas value (e.g. \"'header header' 'nav main'\")\n * @attr {string} areas-sm - grid-template-areas when width ≥ 640px\n * @attr {string} areas-md - grid-template-areas when width ≥ 768px\n * @attr {string} areas-lg - grid-template-areas when width ≥ 1024px\n * @attr {string} areas-xl - grid-template-areas when width ≥ 1280px\n * @attr {string} areas-2xl - grid-template-areas when width ≥ 1536px\n *\n * @slot - Grid items\n *\n * @cssprop --grid-cols - Fallback column template (used when no cols attr is set)\n * @cssprop --grid-rows - Fallback row template\n * @cssprop --grid-gap - Fallback gap\n * @cssprop --grid-row-gap - Fallback row gap\n * @cssprop --grid-col-gap - Fallback column gap\n *\n * @example\n * <ore-grid cols=\"1\" cols-sm=\"2\" cols-lg=\"4\" gap=\"md\">\n * <div>Item</div>\n * </ore-grid>\n *\n * @example\n * <!-- Responsive auto-fit -->\n * <ore-grid responsive min-col-width=\"200px\" gap=\"sm\">\n * <div>Card</div>\n * </ore-grid>\n *\n * @example\n * <!-- Named grid areas -->\n * <ore-grid cols=\"2\" rows=\"2\" areas=\"'header header' 'nav main'\">\n * <header style=\"grid-area: header\">Header</header>\n * <nav style=\"grid-area: nav\">Nav</nav>\n * <main style=\"grid-area: main\">Main</main>\n * </ore-grid>\n */\nexport const GRID_TAG = 'ore-grid' as const;\ndefine<OreGridProps>(GRID_TAG, {\n props: {\n align: prop.string<'start' | 'center' | 'end' | 'stretch' | 'baseline'>(),\n areas: prop.string(),\n areas2xl: prop.string(),\n areasLg: prop.string(),\n areasMd: prop.string(),\n areasSm: prop.string(),\n areasXl: prop.string(),\n cols: prop.string<ColCount>(),\n cols2xl: prop.string<ColCount>(),\n colsLg: prop.string<ColCount>(),\n colsMd: prop.string<ColCount>(),\n colsSm: prop.string<ColCount>(),\n colsXl: prop.string<ColCount>(),\n flow: prop.string<'row' | 'column' | 'row-dense' | 'column-dense'>(),\n fullwidth: prop.bool(false),\n gap: prop.string<'none' | 'xs' | 'sm' | 'md' | 'lg' | 'xl' | '2xl'>(),\n justify: prop.string<'start' | 'center' | 'end' | 'stretch'>(),\n minColWidth: prop.string(),\n responsive: prop.bool(false),\n rows: prop.string<'1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9' | '10' | '11' | '12' | 'auto'>(),\n },\n\n setup(props) {\n const el = getHost();\n const watch = watchEffect;\n\n const computeCols = (activeCols: string | undefined, responsive: boolean, minW: string): string | null => {\n if (activeCols === 'auto' || (!activeCols && responsive)) {\n return `repeat(auto-fit, minmax(${minW || '250px'}, 1fr))`;\n }\n\n return activeCols ? `repeat(${activeCols}, 1fr)` : null;\n };\n const updateCols = () => {\n const w = el.offsetWidth;\n const responsive = Boolean(props.responsive.value);\n const minW = props.minColWidth.value ?? '';\n let activeCols: string | undefined;\n\n for (const [key, cssVar] of BREAKPOINTS) {\n if (w >= resolveBp(el, cssVar, BP_FALLBACKS[cssVar]) && props[key].value) {\n activeCols = props[key].value!;\n break;\n }\n }\n activeCols ||= props.cols.value || undefined;\n\n const colsValue = computeCols(activeCols, responsive, minW);\n\n if (colsValue) {\n el.style.setProperty('--_cols', colsValue);\n } else {\n el.style.removeProperty('--_cols');\n }\n };\n\n // Re-run cols whenever any responsive prop changes\n watch(() => {\n void [\n props.cols.value,\n props.colsSm.value,\n props.colsMd.value,\n props.colsLg.value,\n props.colsXl.value,\n props.cols2xl.value,\n props.responsive.value,\n props.minColWidth.value,\n ];\n updateCols();\n });\n\n const updateAreas = () => {\n const w = el.offsetWidth;\n let active = '';\n\n for (const [key, cssVar] of AREAS_BREAKPOINTS) {\n if (w >= resolveBp(el, cssVar, BP_FALLBACKS[cssVar]) && props[key].value) {\n active = props[key].value!;\n break;\n }\n }\n active ||= props.areas.value || '';\n\n if (active) {\n el.style.setProperty('grid-template-areas', active);\n } else {\n el.style.removeProperty('grid-template-areas');\n }\n };\n\n // Rows\n watch(() => {\n const rows = props.rows.value;\n\n if (rows && rows !== 'auto') {\n el.style.setProperty('--_rows', `repeat(${rows}, 1fr)`);\n } else {\n el.style.removeProperty('--_rows');\n }\n });\n // Grid template areas (responsive)\n watch(() => {\n void [\n props.areas.value,\n props.areasSm.value,\n props.areasMd.value,\n props.areasLg.value,\n props.areasXl.value,\n props.areas2xl.value,\n ];\n updateAreas();\n });\n\n // Also, update on element resize (drives breakpoint switching)\n onMounted(() => {\n const size = createElementSize(el);\n\n onCleanup(() => size.dispose());\n\n watch(() => {\n const dims = size.value;\n if (dims) {\n updateCols();\n updateAreas();\n }\n });\n });\n\n return html`\n <slot></slot>\n `;\n },\n\n styles: [styles],\n});\n"],"mappings":"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"}
package/dist/grid.js CHANGED
@@ -1,82 +1,83 @@
1
1
  import e from "./layout/grid/grid.css.js";
2
- import { define as t, getHost as n, html as r, onMounted as i, prop as a, resizeObserver as o, watchEffect as s } from "@vielzeug/ore";
2
+ import { define as t, getHost as n, html as r, onCleanup as i, onMounted as a, prop as o, watchEffect as s } from "@vielzeug/ore";
3
+ import { createElementSize as c } from "@vielzeug/sentinel";
3
4
  //#region src/layout/grid/grid.ts
4
- var c = [
5
+ var l = [
5
6
  ["cols2xl", "--size-screen-2xl"],
6
7
  ["colsXl", "--size-screen-xl"],
7
8
  ["colsLg", "--size-screen-lg"],
8
9
  ["colsMd", "--size-screen-md"],
9
10
  ["colsSm", "--size-screen-sm"]
10
- ], l = [
11
+ ], u = [
11
12
  ["areas2xl", "--size-screen-2xl"],
12
13
  ["areasXl", "--size-screen-xl"],
13
14
  ["areasLg", "--size-screen-lg"],
14
15
  ["areasMd", "--size-screen-md"],
15
16
  ["areasSm", "--size-screen-sm"]
16
- ], u = (e, t, n) => {
17
+ ], d = (e, t, n) => {
17
18
  let r = getComputedStyle(e).getPropertyValue(t).trim(), i = Number.parseFloat(r);
18
19
  return Number.isFinite(i) ? i : n;
19
- }, d = {
20
+ }, f = {
20
21
  "--size-screen-2xl": 1536,
21
22
  "--size-screen-lg": 1024,
22
23
  "--size-screen-md": 768,
23
24
  "--size-screen-sm": 640,
24
25
  "--size-screen-xl": 1280
25
- }, f = "ore-grid";
26
- t(f, {
26
+ }, p = "ore-grid";
27
+ t(p, {
27
28
  props: {
28
- align: a.string(),
29
- areas: a.string(),
30
- areas2xl: a.string(),
31
- areasLg: a.string(),
32
- areasMd: a.string(),
33
- areasSm: a.string(),
34
- areasXl: a.string(),
35
- cols: a.string(),
36
- cols2xl: a.string(),
37
- colsLg: a.string(),
38
- colsMd: a.string(),
39
- colsSm: a.string(),
40
- colsXl: a.string(),
41
- flow: a.string(),
42
- fullwidth: a.bool(!1),
43
- gap: a.string(),
44
- justify: a.string(),
45
- minColWidth: a.string(),
46
- responsive: a.bool(!1),
47
- rows: a.string()
29
+ align: o.string(),
30
+ areas: o.string(),
31
+ areas2xl: o.string(),
32
+ areasLg: o.string(),
33
+ areasMd: o.string(),
34
+ areasSm: o.string(),
35
+ areasXl: o.string(),
36
+ cols: o.string(),
37
+ cols2xl: o.string(),
38
+ colsLg: o.string(),
39
+ colsMd: o.string(),
40
+ colsSm: o.string(),
41
+ colsXl: o.string(),
42
+ flow: o.string(),
43
+ fullwidth: o.bool(!1),
44
+ gap: o.string(),
45
+ justify: o.string(),
46
+ minColWidth: o.string(),
47
+ responsive: o.bool(!1),
48
+ rows: o.string()
48
49
  },
49
50
  setup(e) {
50
- let t = n(), a = s, f = (e, t, n) => e === "auto" || !e && t ? `repeat(auto-fit, minmax(${n || "250px"}, 1fr))` : e ? `repeat(${e}, 1fr)` : null, p = () => {
51
+ let t = n(), o = s, p = (e, t, n) => e === "auto" || !e && t ? `repeat(auto-fit, minmax(${n || "250px"}, 1fr))` : e ? `repeat(${e}, 1fr)` : null, m = () => {
51
52
  let n = t.offsetWidth, r = !!e.responsive.value, i = e.minColWidth.value ?? "", a;
52
- for (let [r, i] of c) if (n >= u(t, i, d[i]) && e[r].value) {
53
+ for (let [r, i] of l) if (n >= d(t, i, f[i]) && e[r].value) {
53
54
  a = e[r].value;
54
55
  break;
55
56
  }
56
57
  a ||= e.cols.value || void 0;
57
- let o = f(a, r, i);
58
+ let o = p(a, r, i);
58
59
  o ? t.style.setProperty("--_cols", o) : t.style.removeProperty("--_cols");
59
60
  };
60
- a(() => {
61
- e.cols.value, e.colsSm.value, e.colsMd.value, e.colsLg.value, e.colsXl.value, e.cols2xl.value, e.responsive.value, e.minColWidth.value, p();
61
+ o(() => {
62
+ e.cols.value, e.colsSm.value, e.colsMd.value, e.colsLg.value, e.colsXl.value, e.cols2xl.value, e.responsive.value, e.minColWidth.value, m();
62
63
  });
63
- let m = () => {
64
+ let h = () => {
64
65
  let n = t.offsetWidth, r = "";
65
- for (let [i, a] of l) if (n >= u(t, a, d[a]) && e[i].value) {
66
+ for (let [i, a] of u) if (n >= d(t, a, f[a]) && e[i].value) {
66
67
  r = e[i].value;
67
68
  break;
68
69
  }
69
70
  r ||= e.areas.value || "", r ? t.style.setProperty("grid-template-areas", r) : t.style.removeProperty("grid-template-areas");
70
71
  };
71
- return a(() => {
72
+ return o(() => {
72
73
  let n = e.rows.value;
73
74
  n && n !== "auto" ? t.style.setProperty("--_rows", `repeat(${n}, 1fr)`) : t.style.removeProperty("--_rows");
75
+ }), o(() => {
76
+ e.areas.value, e.areasSm.value, e.areasMd.value, e.areasLg.value, e.areasXl.value, e.areas2xl.value, h();
74
77
  }), a(() => {
75
- e.areas.value, e.areasSm.value, e.areasMd.value, e.areasLg.value, e.areasXl.value, e.areas2xl.value, m();
76
- }), i(() => {
77
- let e = o(t);
78
- a(() => {
79
- e.value, p(), m();
78
+ let e = c(t);
79
+ i(() => e.dispose()), o(() => {
80
+ e.value && (m(), h());
80
81
  });
81
82
  }), r`
82
83
  <slot></slot>
@@ -85,6 +86,6 @@ t(f, {
85
86
  styles: [e]
86
87
  });
87
88
  //#endregion
88
- export { f as GRID_TAG };
89
+ export { p as GRID_TAG };
89
90
 
90
91
  //# sourceMappingURL=grid.js.map
package/dist/grid.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"grid.js","names":[],"sources":["../src/layout/grid/grid.ts"],"sourcesContent":["import { define, getHost, html, onMounted, prop, resizeObserver, watchEffect } from '@vielzeug/ore';\n\nimport styles from './grid.css?inline';\n\nconst BREAKPOINTS: ['cols2xl' | 'colsXl' | 'colsLg' | 'colsMd' | 'colsSm', string][] = [\n ['cols2xl', '--size-screen-2xl'],\n ['colsXl', '--size-screen-xl'],\n ['colsLg', '--size-screen-lg'],\n ['colsMd', '--size-screen-md'],\n ['colsSm', '--size-screen-sm'],\n];\n\nconst AREAS_BREAKPOINTS: ['areas2xl' | 'areasXl' | 'areasLg' | 'areasMd' | 'areasSm', string][] = [\n ['areas2xl', '--size-screen-2xl'],\n ['areasXl', '--size-screen-xl'],\n ['areasLg', '--size-screen-lg'],\n ['areasMd', '--size-screen-md'],\n ['areasSm', '--size-screen-sm'],\n];\n\nconst resolveBp = (host: HTMLElement, varName: string, fallback: number): number => {\n const raw = getComputedStyle(host).getPropertyValue(varName).trim();\n const parsed = Number.parseFloat(raw);\n\n return Number.isFinite(parsed) ? parsed : fallback;\n};\n\nconst BP_FALLBACKS: Record<string, number> = {\n '--size-screen-2xl': 1536,\n '--size-screen-lg': 1024,\n '--size-screen-md': 768,\n '--size-screen-sm': 640,\n '--size-screen-xl': 1280,\n};\n\ntype ColCount = '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9' | '10' | '11' | '12' | 'auto';\n\n/** Grid component properties */\nexport type OreGridProps = {\n /** Align items vertically */\n align?: 'start' | 'center' | 'end' | 'stretch' | 'baseline';\n /** CSS grid-template-areas value */\n areas?: string;\n /** grid-template-areas at 2xl breakpoint (≥1536px) */\n areas2xl?: string;\n /** grid-template-areas at lg breakpoint (≥1024px) */\n areasLg?: string;\n /** grid-template-areas at md breakpoint (≥768px) */\n areasMd?: string;\n /** grid-template-areas at sm breakpoint (≥640px) */\n areasSm?: string;\n /** grid-template-areas at xl breakpoint (≥1280px) */\n areasXl?: string;\n /** Number of columns: '1'-'12' | 'auto' */\n cols?: ColCount;\n /** Columns at 2xl breakpoint (≥1536px) */\n cols2xl?: ColCount;\n /** Columns at lg breakpoint (≥1024px) */\n colsLg?: ColCount;\n /** Columns at md breakpoint (≥768px) */\n colsMd?: ColCount;\n /** Columns at sm breakpoint (≥640px) */\n colsSm?: ColCount;\n /** Columns at xl breakpoint (≥1280px) */\n colsXl?: ColCount;\n /** Grid auto flow direction */\n flow?: 'row' | 'column' | 'row-dense' | 'column-dense';\n /** Stretch the grid to fill its container's full width */\n fullwidth?: boolean;\n /** Gap between items */\n gap?: 'none' | 'xs' | 'sm' | 'md' | 'lg' | 'xl' | '2xl';\n /** Justify items horizontally */\n justify?: 'start' | 'center' | 'end' | 'stretch';\n /** Minimum column width for responsive mode (default: 250px) */\n minColWidth?: string;\n /** Use auto-fit responsive columns */\n responsive?: boolean;\n /** Number of rows: '1'-'12' | 'auto' */\n rows?: '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9' | '10' | '11' | '12' | 'auto';\n};\n\n/**\n * ore-grid — Flexible grid layout with responsive column control.\n *\n * Columns are computed in JS and applied as `--_cols` inline, so they respond\n * to the element's own width via ResizeObserver. CSS custom properties\n * `--grid-cols`, `--grid-rows`, `--grid-gap`, `--grid-row-gap`, `--grid-col-gap`\n * are honoured as fallbacks when no attribute is set.\n *\n * @element ore-grid\n *\n * @attr {string} cols - Column count: '1'–'12' | 'auto'\n * @attr {string} cols-sm - Columns when width ≥ 640px\n * @attr {string} cols-md - Columns when width ≥ 768px\n * @attr {string} cols-lg - Columns when width ≥ 1024px\n * @attr {string} cols-xl - Columns when width ≥ 1280px\n * @attr {string} cols-2xl - Columns when width ≥ 1536px\n * @attr {string} rows - Row count: '1'–'12' | 'auto'\n * @attr {string} gap - Gap token: 'none' | 'xs' | 'sm' | 'md' | 'lg' | 'xl' | '2xl'\n * @attr {string} align - align-items: 'start' | 'center' | 'end' | 'stretch' | 'baseline'\n * @attr {string} justify - justify-items: 'start' | 'center' | 'end' | 'stretch'\n * @attr {string} flow - grid-auto-flow: 'row' | 'column' | 'row-dense' | 'column-dense'\n * @attr {boolean} responsive - Enables auto-fit columns without a fixed count\n * @attr {string} min-col-width - Min column width for responsive mode (default: 250px)\n * @attr {boolean} fullwidth - Stretch the grid to fill its container's full width\n * @attr {string} areas - CSS grid-template-areas value (e.g. \"'header header' 'nav main'\")\n * @attr {string} areas-sm - grid-template-areas when width ≥ 640px\n * @attr {string} areas-md - grid-template-areas when width ≥ 768px\n * @attr {string} areas-lg - grid-template-areas when width ≥ 1024px\n * @attr {string} areas-xl - grid-template-areas when width ≥ 1280px\n * @attr {string} areas-2xl - grid-template-areas when width ≥ 1536px\n *\n * @slot - Grid items\n *\n * @cssprop --grid-cols - Fallback column template (used when no cols attr is set)\n * @cssprop --grid-rows - Fallback row template\n * @cssprop --grid-gap - Fallback gap\n * @cssprop --grid-row-gap - Fallback row gap\n * @cssprop --grid-col-gap - Fallback column gap\n *\n * @example\n * <ore-grid cols=\"1\" cols-sm=\"2\" cols-lg=\"4\" gap=\"md\">\n * <div>Item</div>\n * </ore-grid>\n *\n * @example\n * <!-- Responsive auto-fit -->\n * <ore-grid responsive min-col-width=\"200px\" gap=\"sm\">\n * <div>Card</div>\n * </ore-grid>\n *\n * @example\n * <!-- Named grid areas -->\n * <ore-grid cols=\"2\" rows=\"2\" areas=\"'header header' 'nav main'\">\n * <header style=\"grid-area: header\">Header</header>\n * <nav style=\"grid-area: nav\">Nav</nav>\n * <main style=\"grid-area: main\">Main</main>\n * </ore-grid>\n */\nexport const GRID_TAG = 'ore-grid' as const;\ndefine<OreGridProps>(GRID_TAG, {\n props: {\n align: prop.string<'start' | 'center' | 'end' | 'stretch' | 'baseline'>(),\n areas: prop.string(),\n areas2xl: prop.string(),\n areasLg: prop.string(),\n areasMd: prop.string(),\n areasSm: prop.string(),\n areasXl: prop.string(),\n cols: prop.string<ColCount>(),\n cols2xl: prop.string<ColCount>(),\n colsLg: prop.string<ColCount>(),\n colsMd: prop.string<ColCount>(),\n colsSm: prop.string<ColCount>(),\n colsXl: prop.string<ColCount>(),\n flow: prop.string<'row' | 'column' | 'row-dense' | 'column-dense'>(),\n fullwidth: prop.bool(false),\n gap: prop.string<'none' | 'xs' | 'sm' | 'md' | 'lg' | 'xl' | '2xl'>(),\n justify: prop.string<'start' | 'center' | 'end' | 'stretch'>(),\n minColWidth: prop.string(),\n responsive: prop.bool(false),\n rows: prop.string<'1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9' | '10' | '11' | '12' | 'auto'>(),\n },\n\n setup(props) {\n const el = getHost();\n const watch = watchEffect;\n\n const computeCols = (activeCols: string | undefined, responsive: boolean, minW: string): string | null => {\n if (activeCols === 'auto' || (!activeCols && responsive)) {\n return `repeat(auto-fit, minmax(${minW || '250px'}, 1fr))`;\n }\n\n return activeCols ? `repeat(${activeCols}, 1fr)` : null;\n };\n const updateCols = () => {\n const w = el.offsetWidth;\n const responsive = Boolean(props.responsive.value);\n const minW = props.minColWidth.value ?? '';\n let activeCols: string | undefined;\n\n for (const [key, cssVar] of BREAKPOINTS) {\n if (w >= resolveBp(el, cssVar, BP_FALLBACKS[cssVar]) && props[key].value) {\n activeCols = props[key].value!;\n break;\n }\n }\n activeCols ||= props.cols.value || undefined;\n\n const colsValue = computeCols(activeCols, responsive, minW);\n\n if (colsValue) {\n el.style.setProperty('--_cols', colsValue);\n } else {\n el.style.removeProperty('--_cols');\n }\n };\n\n // Re-run cols whenever any responsive prop changes\n watch(() => {\n void [\n props.cols.value,\n props.colsSm.value,\n props.colsMd.value,\n props.colsLg.value,\n props.colsXl.value,\n props.cols2xl.value,\n props.responsive.value,\n props.minColWidth.value,\n ];\n updateCols();\n });\n\n const updateAreas = () => {\n const w = el.offsetWidth;\n let active = '';\n\n for (const [key, cssVar] of AREAS_BREAKPOINTS) {\n if (w >= resolveBp(el, cssVar, BP_FALLBACKS[cssVar]) && props[key].value) {\n active = props[key].value!;\n break;\n }\n }\n active ||= props.areas.value || '';\n\n if (active) {\n el.style.setProperty('grid-template-areas', active);\n } else {\n el.style.removeProperty('grid-template-areas');\n }\n };\n\n // Rows\n watch(() => {\n const rows = props.rows.value;\n\n if (rows && rows !== 'auto') {\n el.style.setProperty('--_rows', `repeat(${rows}, 1fr)`);\n } else {\n el.style.removeProperty('--_rows');\n }\n });\n // Grid template areas (responsive)\n watch(() => {\n void [\n props.areas.value,\n props.areasSm.value,\n props.areasMd.value,\n props.areasLg.value,\n props.areasXl.value,\n props.areas2xl.value,\n ];\n updateAreas();\n });\n\n // Also, update on element resize (drives breakpoint switching)\n onMounted(() => {\n const size = resizeObserver(el);\n\n watch(() => {\n void size.value;\n updateCols();\n updateAreas();\n });\n });\n\n return html`\n <slot></slot>\n `;\n },\n\n styles: [styles],\n});\n"],"mappings":"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"}
1
+ {"version":3,"file":"grid.js","names":[],"sources":["../src/layout/grid/grid.ts"],"sourcesContent":["import { define, getHost, html, onCleanup, onMounted, prop, watchEffect } from '@vielzeug/ore';\nimport { createElementSize } from '@vielzeug/sentinel';\n\nimport styles from './grid.css?inline';\n\nconst BREAKPOINTS: ['cols2xl' | 'colsXl' | 'colsLg' | 'colsMd' | 'colsSm', string][] = [\n ['cols2xl', '--size-screen-2xl'],\n ['colsXl', '--size-screen-xl'],\n ['colsLg', '--size-screen-lg'],\n ['colsMd', '--size-screen-md'],\n ['colsSm', '--size-screen-sm'],\n];\n\nconst AREAS_BREAKPOINTS: ['areas2xl' | 'areasXl' | 'areasLg' | 'areasMd' | 'areasSm', string][] = [\n ['areas2xl', '--size-screen-2xl'],\n ['areasXl', '--size-screen-xl'],\n ['areasLg', '--size-screen-lg'],\n ['areasMd', '--size-screen-md'],\n ['areasSm', '--size-screen-sm'],\n];\n\nconst resolveBp = (host: HTMLElement, varName: string, fallback: number): number => {\n const raw = getComputedStyle(host).getPropertyValue(varName).trim();\n const parsed = Number.parseFloat(raw);\n\n return Number.isFinite(parsed) ? parsed : fallback;\n};\n\nconst BP_FALLBACKS: Record<string, number> = {\n '--size-screen-2xl': 1536,\n '--size-screen-lg': 1024,\n '--size-screen-md': 768,\n '--size-screen-sm': 640,\n '--size-screen-xl': 1280,\n};\n\ntype ColCount = '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9' | '10' | '11' | '12' | 'auto';\n\n/** Grid component properties */\nexport type OreGridProps = {\n /** Align items vertically */\n align?: 'start' | 'center' | 'end' | 'stretch' | 'baseline';\n /** CSS grid-template-areas value */\n areas?: string;\n /** grid-template-areas at 2xl breakpoint (≥1536px) */\n areas2xl?: string;\n /** grid-template-areas at lg breakpoint (≥1024px) */\n areasLg?: string;\n /** grid-template-areas at md breakpoint (≥768px) */\n areasMd?: string;\n /** grid-template-areas at sm breakpoint (≥640px) */\n areasSm?: string;\n /** grid-template-areas at xl breakpoint (≥1280px) */\n areasXl?: string;\n /** Number of columns: '1'-'12' | 'auto' */\n cols?: ColCount;\n /** Columns at 2xl breakpoint (≥1536px) */\n cols2xl?: ColCount;\n /** Columns at lg breakpoint (≥1024px) */\n colsLg?: ColCount;\n /** Columns at md breakpoint (≥768px) */\n colsMd?: ColCount;\n /** Columns at sm breakpoint (≥640px) */\n colsSm?: ColCount;\n /** Columns at xl breakpoint (≥1280px) */\n colsXl?: ColCount;\n /** Grid auto flow direction */\n flow?: 'row' | 'column' | 'row-dense' | 'column-dense';\n /** Stretch the grid to fill its container's full width */\n fullwidth?: boolean;\n /** Gap between items */\n gap?: 'none' | 'xs' | 'sm' | 'md' | 'lg' | 'xl' | '2xl';\n /** Justify items horizontally */\n justify?: 'start' | 'center' | 'end' | 'stretch';\n /** Minimum column width for responsive mode (default: 250px) */\n minColWidth?: string;\n /** Use auto-fit responsive columns */\n responsive?: boolean;\n /** Number of rows: '1'-'12' | 'auto' */\n rows?: '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9' | '10' | '11' | '12' | 'auto';\n};\n\n/**\n * ore-grid — Flexible grid layout with responsive column control.\n *\n * Columns are computed in JS and applied as `--_cols` inline, so they respond\n * to the element's own width via ResizeObserver. CSS custom properties\n * `--grid-cols`, `--grid-rows`, `--grid-gap`, `--grid-row-gap`, `--grid-col-gap`\n * are honoured as fallbacks when no attribute is set.\n *\n * @element ore-grid\n *\n * @attr {string} cols - Column count: '1'–'12' | 'auto'\n * @attr {string} cols-sm - Columns when width ≥ 640px\n * @attr {string} cols-md - Columns when width ≥ 768px\n * @attr {string} cols-lg - Columns when width ≥ 1024px\n * @attr {string} cols-xl - Columns when width ≥ 1280px\n * @attr {string} cols-2xl - Columns when width ≥ 1536px\n * @attr {string} rows - Row count: '1'–'12' | 'auto'\n * @attr {string} gap - Gap token: 'none' | 'xs' | 'sm' | 'md' | 'lg' | 'xl' | '2xl'\n * @attr {string} align - align-items: 'start' | 'center' | 'end' | 'stretch' | 'baseline'\n * @attr {string} justify - justify-items: 'start' | 'center' | 'end' | 'stretch'\n * @attr {string} flow - grid-auto-flow: 'row' | 'column' | 'row-dense' | 'column-dense'\n * @attr {boolean} responsive - Enables auto-fit columns without a fixed count\n * @attr {string} min-col-width - Min column width for responsive mode (default: 250px)\n * @attr {boolean} fullwidth - Stretch the grid to fill its container's full width\n * @attr {string} areas - CSS grid-template-areas value (e.g. \"'header header' 'nav main'\")\n * @attr {string} areas-sm - grid-template-areas when width ≥ 640px\n * @attr {string} areas-md - grid-template-areas when width ≥ 768px\n * @attr {string} areas-lg - grid-template-areas when width ≥ 1024px\n * @attr {string} areas-xl - grid-template-areas when width ≥ 1280px\n * @attr {string} areas-2xl - grid-template-areas when width ≥ 1536px\n *\n * @slot - Grid items\n *\n * @cssprop --grid-cols - Fallback column template (used when no cols attr is set)\n * @cssprop --grid-rows - Fallback row template\n * @cssprop --grid-gap - Fallback gap\n * @cssprop --grid-row-gap - Fallback row gap\n * @cssprop --grid-col-gap - Fallback column gap\n *\n * @example\n * <ore-grid cols=\"1\" cols-sm=\"2\" cols-lg=\"4\" gap=\"md\">\n * <div>Item</div>\n * </ore-grid>\n *\n * @example\n * <!-- Responsive auto-fit -->\n * <ore-grid responsive min-col-width=\"200px\" gap=\"sm\">\n * <div>Card</div>\n * </ore-grid>\n *\n * @example\n * <!-- Named grid areas -->\n * <ore-grid cols=\"2\" rows=\"2\" areas=\"'header header' 'nav main'\">\n * <header style=\"grid-area: header\">Header</header>\n * <nav style=\"grid-area: nav\">Nav</nav>\n * <main style=\"grid-area: main\">Main</main>\n * </ore-grid>\n */\nexport const GRID_TAG = 'ore-grid' as const;\ndefine<OreGridProps>(GRID_TAG, {\n props: {\n align: prop.string<'start' | 'center' | 'end' | 'stretch' | 'baseline'>(),\n areas: prop.string(),\n areas2xl: prop.string(),\n areasLg: prop.string(),\n areasMd: prop.string(),\n areasSm: prop.string(),\n areasXl: prop.string(),\n cols: prop.string<ColCount>(),\n cols2xl: prop.string<ColCount>(),\n colsLg: prop.string<ColCount>(),\n colsMd: prop.string<ColCount>(),\n colsSm: prop.string<ColCount>(),\n colsXl: prop.string<ColCount>(),\n flow: prop.string<'row' | 'column' | 'row-dense' | 'column-dense'>(),\n fullwidth: prop.bool(false),\n gap: prop.string<'none' | 'xs' | 'sm' | 'md' | 'lg' | 'xl' | '2xl'>(),\n justify: prop.string<'start' | 'center' | 'end' | 'stretch'>(),\n minColWidth: prop.string(),\n responsive: prop.bool(false),\n rows: prop.string<'1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9' | '10' | '11' | '12' | 'auto'>(),\n },\n\n setup(props) {\n const el = getHost();\n const watch = watchEffect;\n\n const computeCols = (activeCols: string | undefined, responsive: boolean, minW: string): string | null => {\n if (activeCols === 'auto' || (!activeCols && responsive)) {\n return `repeat(auto-fit, minmax(${minW || '250px'}, 1fr))`;\n }\n\n return activeCols ? `repeat(${activeCols}, 1fr)` : null;\n };\n const updateCols = () => {\n const w = el.offsetWidth;\n const responsive = Boolean(props.responsive.value);\n const minW = props.minColWidth.value ?? '';\n let activeCols: string | undefined;\n\n for (const [key, cssVar] of BREAKPOINTS) {\n if (w >= resolveBp(el, cssVar, BP_FALLBACKS[cssVar]) && props[key].value) {\n activeCols = props[key].value!;\n break;\n }\n }\n activeCols ||= props.cols.value || undefined;\n\n const colsValue = computeCols(activeCols, responsive, minW);\n\n if (colsValue) {\n el.style.setProperty('--_cols', colsValue);\n } else {\n el.style.removeProperty('--_cols');\n }\n };\n\n // Re-run cols whenever any responsive prop changes\n watch(() => {\n void [\n props.cols.value,\n props.colsSm.value,\n props.colsMd.value,\n props.colsLg.value,\n props.colsXl.value,\n props.cols2xl.value,\n props.responsive.value,\n props.minColWidth.value,\n ];\n updateCols();\n });\n\n const updateAreas = () => {\n const w = el.offsetWidth;\n let active = '';\n\n for (const [key, cssVar] of AREAS_BREAKPOINTS) {\n if (w >= resolveBp(el, cssVar, BP_FALLBACKS[cssVar]) && props[key].value) {\n active = props[key].value!;\n break;\n }\n }\n active ||= props.areas.value || '';\n\n if (active) {\n el.style.setProperty('grid-template-areas', active);\n } else {\n el.style.removeProperty('grid-template-areas');\n }\n };\n\n // Rows\n watch(() => {\n const rows = props.rows.value;\n\n if (rows && rows !== 'auto') {\n el.style.setProperty('--_rows', `repeat(${rows}, 1fr)`);\n } else {\n el.style.removeProperty('--_rows');\n }\n });\n // Grid template areas (responsive)\n watch(() => {\n void [\n props.areas.value,\n props.areasSm.value,\n props.areasMd.value,\n props.areasLg.value,\n props.areasXl.value,\n props.areas2xl.value,\n ];\n updateAreas();\n });\n\n // Also, update on element resize (drives breakpoint switching)\n onMounted(() => {\n const size = createElementSize(el);\n\n onCleanup(() => size.dispose());\n\n watch(() => {\n const dims = size.value;\n if (dims) {\n updateCols();\n updateAreas();\n }\n });\n });\n\n return html`\n <slot></slot>\n `;\n },\n\n styles: [styles],\n});\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"input.cjs","names":[],"sources":["../src/inputs/input/input.ts"],"sourcesContent":["import { bind, define, getHost, html, live, onCleanup, onElement, prop, ref, useField, useSlots } from '@vielzeug/ore';\nimport { computed, signal } from '@vielzeug/ripple';\nimport { bindRefCallback, createTextField, lifecycleSignal } from '../../core';\nimport type { TextFieldProps } from '../../shared';\nimport { disablableBundle, FIELD_SIZE_PRESET, roundableBundle, sizableBundle, themableBundle } from '../../shared';\nimport type { InputType, VisualVariant } from '../../types';\nimport '../../content/icon/icon';\nimport {\n coarsePointerMixin,\n colorThemeMixin,\n disabledLoadingMixin,\n fieldVariantMixin,\n forcedColorsFocusMixin,\n reducedMotionMixin,\n roundedVariantMixin,\n sizeVariantMixin,\n} from '../../styles';\nimport { errorAttr } from '../shared/field-binding';\nimport { defineFieldValue, dispatchNativeFieldEvent, setFieldValue } from '../shared/native-field-event';\nimport { renderStatusIcon } from '../shared/templates';\nimport componentStyles from './input.css?inline';\n\n/** Input component properties */\n\nexport type OreInputEvents = {\n change: Event;\n input: InputEvent;\n};\n\nexport type OreInputProps = TextFieldProps<Exclude<VisualVariant, 'frost'>> & {\n /** Autocomplete hint */\n autocomplete?: string;\n /** Show a clear (×) button when the field has a value */\n clearable?: boolean;\n /** Virtual keyboard hint for mobile devices */\n inputmode?: 'none' | 'text' | 'decimal' | 'numeric' | 'tel' | 'search' | 'email' | 'url';\n /**\n * Shows an inline spinner inside the field and forces the inner `<input>` into\n * `disabled` for the duration — use while an async validation/submission request\n * is in flight (e.g. checking username availability) to prevent double-submits.\n */\n loading?: boolean;\n /** Maximum character length — shows a counter below the input */\n maxlength?: number;\n /** Minimum character length */\n minlength?: number;\n /** HTML pattern attribute for client-side validation */\n pattern?: string;\n /**\n * JS-only callback fired with the inner `<input>` element when it mounts,\n * and with `null` when it unmounts. Intended for composed components that\n * need imperative access to the raw input element.\n * Set as a JS property: `bitInput.ref = (el) => { ... }`.\n */\n ref?: ((el: HTMLInputElement | null) => void) | null;\n /** HTML input type */\n type?: InputType;\n};\n\nconst VALID_INPUT_TYPES = [\n 'text',\n 'email',\n 'password',\n 'search',\n 'url',\n 'tel',\n 'number',\n 'date',\n 'time',\n 'datetime-local',\n 'month',\n 'week',\n] as const;\n\n/**\n * A customizable text input component with multiple variants, label placements, and form features.\n *\n * @element ore-input\n *\n * @attr {string} label - Label text\n * @attr {string} label-placement - Label placement: 'inset' | 'outside'\n * @attr {string} type - HTML input type: 'text' | 'email' | 'password' | 'number' | 'tel' | 'url' | 'search'\n * @attr {string} value - Current input value\n * @attr {string} placeholder - Placeholder text\n * @attr {string} name - Form field name\n * @attr {string} helper - Helper text displayed below the input (fallback when the `helper` slot is empty)\n * @attr {string} error - Error message — marks the field as invalid (fallback when the `error` slot is empty)\n * @attr {boolean} disabled - Disable input interaction\n * @attr {boolean} readonly - Make the input read-only\n * @attr {boolean} required - Mark the field as required\n * @attr {boolean} loading - Show an inline spinner and force the field disabled\n * @attr {boolean} success - Show an inline success check icon (suppressed while `error` is set)\n * @attr {string} color - Theme color: 'primary' | 'secondary' | 'info' | 'success' | 'warning' | 'error'\n * @attr {string} variant - Visual variant: 'solid' | 'flat' | 'bordered' | 'outline' | 'ghost' | 'text'\n * @attr {string} size - Input size: 'sm' | 'md' | 'lg'\n * @attr {string} rounded - Border radius: 'none' | 'sm' | 'md' | 'lg' | 'xl' | '2xl' | '3xl' | 'full'\n *\n * @fires input - Emitted when input value changes (on every keystroke).\n * @fires change - Emitted when input loses focus with changed value.\n *\n * @slot prefix - Content before the input (e.g., icons)\n * @slot suffix - Content after the input (e.g., clear button, validation icon)\n * @slot label - Replaces the label text — slotted content takes precedence over the `label` prop\n * @slot helper - Replaces the helper text — slotted content takes precedence over the `helper` prop\n * @slot error - Replaces the error text — slotted content takes precedence over the `error` prop\n *\n * @part wrapper - The input wrapper element\n * @part label - The label element (inset or outside)\n * @part field - The field container element\n * @part input-row - The input row container element\n * @part input - The input element\n * @part status-icon - The inline error/success icon shown inside the field\n * @part spinner - The inline loading spinner shown inside the field while `loading`\n * @part helper - The helper text element\n *\n * @cssprop --input-bg - Background color\n * @cssprop --input-color - Text color\n * @cssprop --input-border-color - Border color\n * @cssprop --input-placeholder-color - Placeholder text color\n * @cssprop --input-radius - Border radius\n * @cssprop --input-padding - Inner padding (block inline)\n * @cssprop --input-gap - Gap between prefix/suffix icons and input text\n * @cssprop --input-font-size - Font size\n * @cssprop --input-height - Field height\n * @cssprop --input-hover-bg - Field background on hover (flat/ghost variants)\n * @cssprop --input-hover-border-color - Field border on hover (flat/bordered variants)\n * @cssprop --input-focus-bg - Field background when focused (flat variant)\n * @cssprop --input-focus-border-color - Field border when focused (flat/text variants)\n *\n * @example\n * ```html\n * <ore-input type=\"email\" label=\"Email\" placeholder=\"you@example.com\" />\n * <ore-input label=\"Name\" variant=\"bordered\" color=\"primary\" />\n * <ore-input label=\"Username\" error=\"That username is taken\" />\n * <ore-input label=\"Username\" success />\n * <ore-input label=\"Username\" loading />\n * ```\n */\nexport const INPUT_TAG = 'ore-input' as const;\ndefine<OreInputProps>(INPUT_TAG, {\n formAssociated: true,\n props: {\n ...themableBundle,\n ...sizableBundle,\n ...disablableBundle,\n ...roundableBundle,\n autocomplete: prop.string(),\n clearable: prop.bool(false),\n error: prop.string(),\n fullwidth: prop.bool(false),\n helper: prop.string(),\n inputmode: prop.string<'none' | 'text' | 'decimal' | 'numeric' | 'tel' | 'search' | 'email' | 'url'>(),\n label: prop.string(),\n 'label-placement': prop.oneOf(['inset', 'outside'] as const, 'inset'),\n loading: prop.bool(false),\n maxlength: prop.json(undefined as number | undefined),\n minlength: prop.json(undefined as number | undefined),\n name: prop.string(),\n pattern: prop.string(),\n placeholder: prop.string(),\n readonly: prop.bool(false),\n ref: prop.data<((el: HTMLInputElement | null) => void) | null>(),\n required: prop.bool(false),\n success: prop.bool(false),\n type: prop.oneOf(VALID_INPUT_TYPES, 'text'),\n value: prop.string(),\n variant: prop.string<'flat' | 'text' | 'solid' | 'bordered' | 'outline' | 'ghost'>(),\n },\n setup(props) {\n const el = getHost();\n const slots = useSlots();\n\n const showPassword = signal(false);\n const inputRef = ref<HTMLInputElement>();\n\n const hasLabel = computed(() => !!props.label.value || slots.has('label').value);\n // `loading` behaves like a temporary `disabled` — forces the inner <input> out of\n // constraint validation and interaction for the duration, layered on top of any real\n // `loading` is layered on top of the consumer's explicit `disabled` prop.\n const isDisabled = computed(() => props.disabled.value || props.loading.value);\n\n const abortSignal = lifecycleSignal(onCleanup);\n const tf = createTextField({\n disabled: isDisabled,\n error: props.error,\n hasLabel,\n helper: props.helper,\n label: props.label,\n labelPlacement: props['label-placement'],\n maxLength: props.maxlength,\n onChange: (_event: Event, value: string) => {\n setFieldValue(el, value);\n dispatchNativeFieldEvent(el, 'change');\n },\n onInput: (_event: Event, value: string) => {\n setFieldValue(el, value);\n dispatchNativeFieldEvent(el, 'input');\n },\n prefix: 'input',\n readonly: props.readonly,\n required: props.required,\n signal: abortSignal,\n value: props.value,\n });\n\n defineFieldValue(\n el,\n () => tf.value.value,\n (value) => {\n tf.value.value = value;\n },\n );\n\n tf.attachFormField(\n useField<string>({\n disabled: tf.disabled,\n onReset: tf.reset,\n toFormValue: (v) => v,\n validationMessage: tf.validationMessage,\n validity: tf.validity,\n value: tf.value,\n }),\n );\n\n const {\n ariaDescribedBy,\n ariaErrorMessage,\n ariaInvalid,\n ariaLabelledBy,\n assistiveId,\n clear: clearValue,\n counter,\n errorId,\n errorText,\n fieldId: inputId,\n helperText,\n labelId,\n labelVisible,\n value: fieldValue,\n wire,\n } = tf;\n\n onElement(inputRef, (el) => {\n wire(el, abortSignal);\n\n const unwireRef = bindRefCallback(props.ref, el);\n\n return () => {\n unwireRef();\n };\n });\n\n const clear = (event?: Event): void => {\n clearValue(event);\n inputRef.value?.focus();\n };\n\n const resolvedInputType = (): string =>\n props.type.value === 'password' && showPassword.value ? 'text' : (props.type.value ?? 'text');\n\n bind({\n attr: {\n error: errorAttr(errorText),\n 'has-value': () => (fieldValue.value ? true : undefined),\n size: props.size,\n // Reflects `success` only once `error` is confirmed empty — keeps the two host\n // attributes mutually exclusive even if a consumer sets both props at once.\n success: () => (props.success.value && !errorText.value ? true : undefined),\n variant: props.variant,\n },\n });\n\n const labelHidden = () => !labelVisible.value;\n const passwordToggleLabel = () => (showPassword.value ? 'Hide password' : 'Show password');\n const passwordTogglePressed = () => String(showPassword.value);\n const passwordToggleIcon = () =>\n showPassword.value\n ? html`\n <ore-icon name=\"eye-off\" size=\"14\" stroke-width=\"2\" aria-hidden=\"true\"></ore-icon>\n `\n : html`\n <ore-icon name=\"eye\" size=\"14\" stroke-width=\"2\" aria-hidden=\"true\"></ore-icon>\n `;\n const helperHidden = () => !!errorText.value || !helperText.value;\n const errorHidden = () => !errorText.value;\n const counterNearLimit = () => (counter?.value.counterNearLimit && !counter?.value.counterAtLimit ? '' : null);\n const counterAtLimit = () => (counter?.value.counterAtLimit ? '' : null);\n const counterHidden = () => !counter;\n const counterText = () => counter?.value.counterText ?? '';\n\n const clearTabIndex = () => (fieldValue.value ? '0' : '-1');\n const pwdToggleTabIndex = () => (props.type.value === 'password' ? '0' : '-1');\n\n const togglePassword = () => {\n showPassword.value = !showPassword.value;\n inputRef.value?.focus();\n };\n\n return html`\n <div class=\"input-wrapper\" part=\"wrapper\">\n <label class=\"label\" for=\"${inputId}\" id=\"${labelId}\" part=\"label\" ?hidden=\"${labelHidden}\">\n <slot name=\"label\">${props.label}</slot>\n </label>\n <div class=\"field\" part=\"field\">\n <div class=\"input-row\" part=\"input-row\">\n <slot name=\"prefix\"></slot>\n <input\n part=\"input\"\n id=\"${inputId}\"\n type=\"${resolvedInputType}\"\n name=\"${props.name}\"\n placeholder=\"${props.placeholder}\"\n autocomplete=\"${props.autocomplete}\"\n inputmode=\"${props.inputmode}\"\n maxlength=\"${props.maxlength}\"\n minlength=\"${props.minlength}\"\n pattern=\"${props.pattern}\"\n ?disabled=\"${isDisabled}\"\n ?readonly=\"${props.readonly}\"\n ?required=\"${props.required}\"\n value=\"${live(fieldValue)}\"\n aria-labelledby=\"${ariaLabelledBy}\"\n aria-describedby=\"${ariaDescribedBy}\"\n aria-errormessage=\"${ariaErrorMessage}\"\n aria-invalid=\"${ariaInvalid}\"\n aria-busy=\"${() => (props.loading.value ? 'true' : null)}\"\n ref=\"${inputRef}\" />\n <slot name=\"suffix\"></slot>\n ${renderStatusIcon(errorText)}\n <span class=\"field-spinner\" part=\"spinner\" role=\"status\" aria-label=\"Loading\"></span>\n <button\n class=\"pwd-toggle-btn\"\n part=\"pwd-toggle\"\n type=\"button\"\n aria-label=\"${passwordToggleLabel}\"\n aria-pressed=\"${passwordTogglePressed}\"\n tabindex=\"${pwdToggleTabIndex}\"\n @click=\"${togglePassword}\">\n ${passwordToggleIcon}\n </button>\n <button\n aria-label=\"Clear\"\n class=\"clear-btn\"\n part=\"clear\"\n type=\"button\"\n tabindex=\"${clearTabIndex}\"\n @click=\"${clear}\">\n <ore-icon aria-hidden=\"true\" name=\"x\" size=\"12\" stroke-width=\"2.5\"></ore-icon>\n </button>\n </div>\n </div>\n <div class=\"helper-text\" aria-live=\"polite\" id=\"${assistiveId}\" part=\"helper\" ?hidden=\"${helperHidden}\">\n <slot name=\"helper\">${() => helperText.value}</slot>\n </div>\n <div class=\"helper-text\" id=\"${errorId}\" role=\"alert\" part=\"error\" ?hidden=\"${errorHidden}\">\n <slot name=\"error\">${() => errorText.value}</slot>\n </div>\n <div\n class=\"char-counter\"\n part=\"char-counter\"\n data-near-limit=\"${counterNearLimit}\"\n data-at-limit=\"${counterAtLimit}\"\n ?hidden=\"${counterHidden}\">\n ${counterText}\n </div>\n </div>\n `;\n },\n shadow: { delegatesFocus: true },\n styles: [\n colorThemeMixin,\n coarsePointerMixin,\n reducedMotionMixin,\n roundedVariantMixin,\n disabledLoadingMixin,\n sizeVariantMixin(FIELD_SIZE_PRESET),\n forcedColorsFocusMixin('input'),\n componentStyles,\n // Must come after `componentStyles` — `@layer` precedence is fixed by which layer name is\n // *first* referenced across this whole array, and `componentStyles` is what establishes\n // `refine.base` (the unconditional `--_bg`/`--_border-color` defaults this mixin's\n // `refine.variants` rules need to win over). Placed earlier, `refine.variants` would end up\n // registered as the *lower*-priority layer, and every variant would silently render as the\n // base default — exactly the bug this ordering fixes.\n fieldVariantMixin({ container: '.field', text: 'input', tokenPrefix: 'input' }),\n ],\n});\n"],"mappings":"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"}
1
+ {"version":3,"file":"input.cjs","names":[],"sources":["../src/inputs/input/input.ts"],"sourcesContent":["import { bind, define, getHost, html, live, onCleanup, onElement, prop, ref, useField, useSlots } from '@vielzeug/ore';\nimport { computed, signal } from '@vielzeug/ripple';\nimport { bindRefCallback, createTextField, lifecycleSignal } from '../../core';\nimport type { TextFieldProps } from '../../shared';\nimport { disablableBundle, FIELD_SIZE_PRESET, roundableBundle, sizableBundle, themableBundle } from '../../shared';\nimport type { InputType, VisualVariant } from '../../types';\nimport '../../content/icon/icon';\nimport {\n coarsePointerMixin,\n colorThemeMixin,\n disabledLoadingMixin,\n fieldVariantMixin,\n forcedColorsFocusMixin,\n reducedMotionMixin,\n roundedVariantMixin,\n sizeVariantMixin,\n} from '../../styles';\nimport { errorAttr } from '../shared/field-binding';\nimport { defineFieldValue, dispatchNativeFieldEvent, setFieldValue } from '../shared/native-field-event';\nimport { renderStatusIcon } from '../shared/templates';\nimport componentStyles from './input.css?inline';\n\n/** Input component properties */\n\nexport type OreInputEvents = {\n change: Event;\n input: InputEvent;\n};\n\nexport type OreInputProps = TextFieldProps<Exclude<VisualVariant, 'frost'>> & {\n /** Autocomplete hint */\n autocomplete?: string;\n /** Show a clear (×) button when the field has a value */\n clearable?: boolean;\n /** Virtual keyboard hint for mobile devices */\n inputmode?: 'none' | 'text' | 'decimal' | 'numeric' | 'tel' | 'search' | 'email' | 'url';\n /**\n * Shows an inline spinner inside the field and forces the inner `<input>` into\n * `disabled` for the duration — use while an async validation/submission request\n * is in flight (e.g. checking username availability) to prevent double-submits.\n */\n loading?: boolean;\n /** Maximum character length — shows a counter below the input */\n maxlength?: number;\n /** Minimum character length */\n minlength?: number;\n /** HTML pattern attribute for client-side validation */\n pattern?: string;\n /**\n * JS-only callback fired with the inner `<input>` element when it mounts,\n * and with `null` when it unmounts. Intended for composed components that\n * need imperative access to the raw input element.\n * Set as a JS property: `bitInput.ref = (el) => { ... }`.\n */\n ref?: ((el: HTMLInputElement | null) => void) | null;\n /** HTML input type */\n type?: InputType;\n};\n\nconst VALID_INPUT_TYPES = [\n 'text',\n 'email',\n 'password',\n 'search',\n 'url',\n 'tel',\n 'number',\n 'date',\n 'time',\n 'datetime-local',\n 'month',\n 'week',\n] as const;\n\n/**\n * A customizable text input component with multiple variants, label placements, and form features.\n *\n * @element ore-input\n *\n * @attr {string} label - Label text\n * @attr {string} label-placement - Label placement: 'inset' | 'outside'\n * @attr {string} type - HTML input type: 'text' | 'email' | 'password' | 'number' | 'tel' | 'url' | 'search'\n * @attr {string} value - Current input value\n * @attr {string} placeholder - Placeholder text\n * @attr {string} name - Form field name\n * @attr {string} helper - Helper text displayed below the input (fallback when the `helper` slot is empty)\n * @attr {string} error - Error message — marks the field as invalid (fallback when the `error` slot is empty)\n * @attr {boolean} disabled - Disable input interaction\n * @attr {boolean} readonly - Make the input read-only\n * @attr {boolean} required - Mark the field as required\n * @attr {boolean} loading - Show an inline spinner and force the field disabled\n * @attr {boolean} success - Show an inline success check icon (suppressed while `error` is set)\n * @attr {string} color - Theme color: 'primary' | 'secondary' | 'info' | 'success' | 'warning' | 'error'\n * @attr {string} variant - Visual variant: 'solid' | 'flat' | 'bordered' | 'outline' | 'ghost' | 'text'\n * @attr {string} size - Input size: 'sm' | 'md' | 'lg'\n * @attr {string} rounded - Border radius: 'none' | 'sm' | 'md' | 'lg' | 'xl' | '2xl' | '3xl' | 'full'\n *\n * @fires input - Emitted when input value changes (on every keystroke).\n * @fires change - Emitted when input loses focus with changed value.\n *\n * @slot prefix - Content before the input (e.g., icons)\n * @slot suffix - Content after the input (e.g., clear button, validation icon)\n * @slot label - Replaces the label text — slotted content takes precedence over the `label` prop\n * @slot helper - Replaces the helper text — slotted content takes precedence over the `helper` prop\n * @slot error - Replaces the error text — slotted content takes precedence over the `error` prop\n *\n * @part wrapper - The input wrapper element\n * @part label - The label element (inset or outside)\n * @part field - The field container element\n * @part input-row - The input row container element\n * @part input - The input element\n * @part status-icon - The inline error/success icon shown inside the field\n * @part spinner - The inline loading spinner shown inside the field while `loading`\n * @part helper - The helper text element\n *\n * @cssprop --input-bg - Background color\n * @cssprop --input-color - Text color\n * @cssprop --input-border-color - Border color\n * @cssprop --input-placeholder-color - Placeholder text color\n * @cssprop --input-radius - Border radius\n * @cssprop --input-padding - Inner padding (block inline)\n * @cssprop --input-label-block-inset - Inset from the field block start for an inset label\n * @cssprop --input-label-inset - Inset from the field inline start for an inset label\n * @cssprop --input-gap - Gap between prefix/suffix icons and input text\n * @cssprop --input-font-size - Font size\n * @cssprop --input-height - Field height\n * @cssprop --input-hover-bg - Field background on hover (flat/ghost variants)\n * @cssprop --input-hover-border-color - Field border on hover (flat/bordered variants)\n * @cssprop --input-focus-bg - Field background when focused (flat variant)\n * @cssprop --input-focus-border-color - Field border when focused (flat/text variants)\n *\n * @example\n * ```html\n * <ore-input type=\"email\" label=\"Email\" placeholder=\"you@example.com\" />\n * <ore-input label=\"Name\" variant=\"bordered\" color=\"primary\" />\n * <ore-input label=\"Username\" error=\"That username is taken\" />\n * <ore-input label=\"Username\" success />\n * <ore-input label=\"Username\" loading />\n * ```\n */\nexport const INPUT_TAG = 'ore-input' as const;\ndefine<OreInputProps>(INPUT_TAG, {\n formAssociated: true,\n props: {\n ...themableBundle,\n ...sizableBundle,\n ...disablableBundle,\n ...roundableBundle,\n autocomplete: prop.string(),\n clearable: prop.bool(false),\n error: prop.string(),\n fullwidth: prop.bool(false),\n helper: prop.string(),\n inputmode: prop.string<'none' | 'text' | 'decimal' | 'numeric' | 'tel' | 'search' | 'email' | 'url'>(),\n label: prop.string(),\n 'label-placement': prop.oneOf(['inset', 'outside'] as const, 'inset'),\n loading: prop.bool(false),\n maxlength: prop.json(undefined as number | undefined),\n minlength: prop.json(undefined as number | undefined),\n name: prop.string(),\n pattern: prop.string(),\n placeholder: prop.string(),\n readonly: prop.bool(false),\n ref: prop.data<((el: HTMLInputElement | null) => void) | null>(),\n required: prop.bool(false),\n success: prop.bool(false),\n type: prop.oneOf(VALID_INPUT_TYPES, 'text'),\n value: prop.string(),\n variant: prop.string<'flat' | 'text' | 'solid' | 'bordered' | 'outline' | 'ghost'>(),\n },\n setup(props) {\n const el = getHost();\n const slots = useSlots();\n\n const showPassword = signal(false);\n const inputRef = ref<HTMLInputElement>();\n\n const hasLabel = computed(() => !!props.label.value || slots.has('label').value);\n // `loading` behaves like a temporary `disabled` — forces the inner <input> out of\n // constraint validation and interaction for the duration, layered on top of any real\n // `loading` is layered on top of the consumer's explicit `disabled` prop.\n const isDisabled = computed(() => props.disabled.value || props.loading.value);\n\n const abortSignal = lifecycleSignal(onCleanup);\n const tf = createTextField({\n disabled: isDisabled,\n error: props.error,\n hasLabel,\n helper: props.helper,\n label: props.label,\n labelPlacement: props['label-placement'],\n maxLength: props.maxlength,\n onChange: (_event: Event, value: string) => {\n setFieldValue(el, value);\n dispatchNativeFieldEvent(el, 'change');\n },\n onInput: (_event: Event, value: string) => {\n setFieldValue(el, value);\n dispatchNativeFieldEvent(el, 'input');\n },\n prefix: 'input',\n readonly: props.readonly,\n required: props.required,\n signal: abortSignal,\n value: props.value,\n });\n\n defineFieldValue(\n el,\n () => tf.value.value,\n (value) => {\n tf.value.value = value;\n },\n );\n\n tf.attachFormField(\n useField<string>({\n disabled: tf.disabled,\n onReset: tf.reset,\n toFormValue: (v) => v,\n validationMessage: tf.validationMessage,\n validity: tf.validity,\n value: tf.value,\n }),\n );\n\n const {\n ariaDescribedBy,\n ariaErrorMessage,\n ariaInvalid,\n ariaLabelledBy,\n assistiveId,\n clear: clearValue,\n counter,\n errorId,\n errorText,\n fieldId: inputId,\n helperText,\n labelId,\n labelVisible,\n value: fieldValue,\n wire,\n } = tf;\n\n onElement(inputRef, (el) => {\n wire(el, abortSignal);\n\n const unwireRef = bindRefCallback(props.ref, el);\n\n return () => {\n unwireRef();\n };\n });\n\n const clear = (event?: Event): void => {\n clearValue(event);\n inputRef.value?.focus();\n };\n\n const resolvedInputType = (): string =>\n props.type.value === 'password' && showPassword.value ? 'text' : (props.type.value ?? 'text');\n\n bind({\n attr: {\n error: errorAttr(errorText),\n 'has-value': () => (fieldValue.value ? true : undefined),\n size: props.size,\n // Reflects `success` only once `error` is confirmed empty — keeps the two host\n // attributes mutually exclusive even if a consumer sets both props at once.\n success: () => (props.success.value && !errorText.value ? true : undefined),\n variant: props.variant,\n },\n });\n\n const labelHidden = () => !labelVisible.value;\n const passwordToggleLabel = () => (showPassword.value ? 'Hide password' : 'Show password');\n const passwordTogglePressed = () => String(showPassword.value);\n const passwordToggleIcon = () =>\n showPassword.value\n ? html`\n <ore-icon name=\"eye-off\" size=\"14\" stroke-width=\"2\" aria-hidden=\"true\"></ore-icon>\n `\n : html`\n <ore-icon name=\"eye\" size=\"14\" stroke-width=\"2\" aria-hidden=\"true\"></ore-icon>\n `;\n const helperHidden = () => !!errorText.value || !helperText.value;\n const errorHidden = () => !errorText.value;\n const counterNearLimit = () => (counter?.value.counterNearLimit && !counter?.value.counterAtLimit ? '' : null);\n const counterAtLimit = () => (counter?.value.counterAtLimit ? '' : null);\n const counterHidden = () => !counter;\n const counterText = () => counter?.value.counterText ?? '';\n\n const clearTabIndex = () => (fieldValue.value ? '0' : '-1');\n const pwdToggleTabIndex = () => (props.type.value === 'password' ? '0' : '-1');\n\n const togglePassword = () => {\n showPassword.value = !showPassword.value;\n inputRef.value?.focus();\n };\n\n return html`\n <div class=\"input-wrapper\" part=\"wrapper\">\n <label class=\"label\" for=\"${inputId}\" id=\"${labelId}\" part=\"label\" ?hidden=\"${labelHidden}\">\n <slot name=\"label\">${props.label}</slot>\n </label>\n <div class=\"field\" part=\"field\">\n <div class=\"input-row\" part=\"input-row\">\n <slot name=\"prefix\"></slot>\n <input\n part=\"input\"\n id=\"${inputId}\"\n type=\"${resolvedInputType}\"\n name=\"${props.name}\"\n placeholder=\"${props.placeholder}\"\n autocomplete=\"${props.autocomplete}\"\n inputmode=\"${props.inputmode}\"\n maxlength=\"${props.maxlength}\"\n minlength=\"${props.minlength}\"\n pattern=\"${props.pattern}\"\n ?disabled=\"${isDisabled}\"\n ?readonly=\"${props.readonly}\"\n ?required=\"${props.required}\"\n value=\"${live(fieldValue)}\"\n aria-labelledby=\"${ariaLabelledBy}\"\n aria-describedby=\"${ariaDescribedBy}\"\n aria-errormessage=\"${ariaErrorMessage}\"\n aria-invalid=\"${ariaInvalid}\"\n aria-busy=\"${() => (props.loading.value ? 'true' : null)}\"\n ref=\"${inputRef}\" />\n <slot name=\"suffix\"></slot>\n ${renderStatusIcon(errorText)}\n <span class=\"field-spinner\" part=\"spinner\" role=\"status\" aria-label=\"Loading\"></span>\n <button\n class=\"pwd-toggle-btn\"\n part=\"pwd-toggle\"\n type=\"button\"\n aria-label=\"${passwordToggleLabel}\"\n aria-pressed=\"${passwordTogglePressed}\"\n tabindex=\"${pwdToggleTabIndex}\"\n @click=\"${togglePassword}\">\n ${passwordToggleIcon}\n </button>\n <button\n aria-label=\"Clear\"\n class=\"clear-btn\"\n part=\"clear\"\n type=\"button\"\n tabindex=\"${clearTabIndex}\"\n @click=\"${clear}\">\n <ore-icon aria-hidden=\"true\" name=\"x\" size=\"12\" stroke-width=\"2.5\"></ore-icon>\n </button>\n </div>\n </div>\n <div class=\"helper-text\" aria-live=\"polite\" id=\"${assistiveId}\" part=\"helper\" ?hidden=\"${helperHidden}\">\n <slot name=\"helper\">${() => helperText.value}</slot>\n </div>\n <div class=\"helper-text\" id=\"${errorId}\" role=\"alert\" part=\"error\" ?hidden=\"${errorHidden}\">\n <slot name=\"error\">${() => errorText.value}</slot>\n </div>\n <div\n class=\"char-counter\"\n part=\"char-counter\"\n data-near-limit=\"${counterNearLimit}\"\n data-at-limit=\"${counterAtLimit}\"\n ?hidden=\"${counterHidden}\">\n ${counterText}\n </div>\n </div>\n `;\n },\n shadow: { delegatesFocus: true },\n styles: [\n colorThemeMixin,\n coarsePointerMixin,\n reducedMotionMixin,\n roundedVariantMixin,\n disabledLoadingMixin,\n sizeVariantMixin(FIELD_SIZE_PRESET),\n forcedColorsFocusMixin('input'),\n componentStyles,\n // Must come after `componentStyles` — `@layer` precedence is fixed by which layer name is\n // *first* referenced across this whole array, and `componentStyles` is what establishes\n // `refine.base` (the unconditional `--_bg`/`--_border-color` defaults this mixin's\n // `refine.variants` rules need to win over). Placed earlier, `refine.variants` would end up\n // registered as the *lower*-priority layer, and every variant would silently render as the\n // base default — exactly the bug this ordering fixes.\n fieldVariantMixin({ container: '.field', text: 'input', tokenPrefix: 'input' }),\n ],\n});\n"],"mappings":"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"}
package/dist/input.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"input.js","names":[],"sources":["../src/inputs/input/input.ts"],"sourcesContent":["import { bind, define, getHost, html, live, onCleanup, onElement, prop, ref, useField, useSlots } from '@vielzeug/ore';\nimport { computed, signal } from '@vielzeug/ripple';\nimport { bindRefCallback, createTextField, lifecycleSignal } from '../../core';\nimport type { TextFieldProps } from '../../shared';\nimport { disablableBundle, FIELD_SIZE_PRESET, roundableBundle, sizableBundle, themableBundle } from '../../shared';\nimport type { InputType, VisualVariant } from '../../types';\nimport '../../content/icon/icon';\nimport {\n coarsePointerMixin,\n colorThemeMixin,\n disabledLoadingMixin,\n fieldVariantMixin,\n forcedColorsFocusMixin,\n reducedMotionMixin,\n roundedVariantMixin,\n sizeVariantMixin,\n} from '../../styles';\nimport { errorAttr } from '../shared/field-binding';\nimport { defineFieldValue, dispatchNativeFieldEvent, setFieldValue } from '../shared/native-field-event';\nimport { renderStatusIcon } from '../shared/templates';\nimport componentStyles from './input.css?inline';\n\n/** Input component properties */\n\nexport type OreInputEvents = {\n change: Event;\n input: InputEvent;\n};\n\nexport type OreInputProps = TextFieldProps<Exclude<VisualVariant, 'frost'>> & {\n /** Autocomplete hint */\n autocomplete?: string;\n /** Show a clear (×) button when the field has a value */\n clearable?: boolean;\n /** Virtual keyboard hint for mobile devices */\n inputmode?: 'none' | 'text' | 'decimal' | 'numeric' | 'tel' | 'search' | 'email' | 'url';\n /**\n * Shows an inline spinner inside the field and forces the inner `<input>` into\n * `disabled` for the duration — use while an async validation/submission request\n * is in flight (e.g. checking username availability) to prevent double-submits.\n */\n loading?: boolean;\n /** Maximum character length — shows a counter below the input */\n maxlength?: number;\n /** Minimum character length */\n minlength?: number;\n /** HTML pattern attribute for client-side validation */\n pattern?: string;\n /**\n * JS-only callback fired with the inner `<input>` element when it mounts,\n * and with `null` when it unmounts. Intended for composed components that\n * need imperative access to the raw input element.\n * Set as a JS property: `bitInput.ref = (el) => { ... }`.\n */\n ref?: ((el: HTMLInputElement | null) => void) | null;\n /** HTML input type */\n type?: InputType;\n};\n\nconst VALID_INPUT_TYPES = [\n 'text',\n 'email',\n 'password',\n 'search',\n 'url',\n 'tel',\n 'number',\n 'date',\n 'time',\n 'datetime-local',\n 'month',\n 'week',\n] as const;\n\n/**\n * A customizable text input component with multiple variants, label placements, and form features.\n *\n * @element ore-input\n *\n * @attr {string} label - Label text\n * @attr {string} label-placement - Label placement: 'inset' | 'outside'\n * @attr {string} type - HTML input type: 'text' | 'email' | 'password' | 'number' | 'tel' | 'url' | 'search'\n * @attr {string} value - Current input value\n * @attr {string} placeholder - Placeholder text\n * @attr {string} name - Form field name\n * @attr {string} helper - Helper text displayed below the input (fallback when the `helper` slot is empty)\n * @attr {string} error - Error message — marks the field as invalid (fallback when the `error` slot is empty)\n * @attr {boolean} disabled - Disable input interaction\n * @attr {boolean} readonly - Make the input read-only\n * @attr {boolean} required - Mark the field as required\n * @attr {boolean} loading - Show an inline spinner and force the field disabled\n * @attr {boolean} success - Show an inline success check icon (suppressed while `error` is set)\n * @attr {string} color - Theme color: 'primary' | 'secondary' | 'info' | 'success' | 'warning' | 'error'\n * @attr {string} variant - Visual variant: 'solid' | 'flat' | 'bordered' | 'outline' | 'ghost' | 'text'\n * @attr {string} size - Input size: 'sm' | 'md' | 'lg'\n * @attr {string} rounded - Border radius: 'none' | 'sm' | 'md' | 'lg' | 'xl' | '2xl' | '3xl' | 'full'\n *\n * @fires input - Emitted when input value changes (on every keystroke).\n * @fires change - Emitted when input loses focus with changed value.\n *\n * @slot prefix - Content before the input (e.g., icons)\n * @slot suffix - Content after the input (e.g., clear button, validation icon)\n * @slot label - Replaces the label text — slotted content takes precedence over the `label` prop\n * @slot helper - Replaces the helper text — slotted content takes precedence over the `helper` prop\n * @slot error - Replaces the error text — slotted content takes precedence over the `error` prop\n *\n * @part wrapper - The input wrapper element\n * @part label - The label element (inset or outside)\n * @part field - The field container element\n * @part input-row - The input row container element\n * @part input - The input element\n * @part status-icon - The inline error/success icon shown inside the field\n * @part spinner - The inline loading spinner shown inside the field while `loading`\n * @part helper - The helper text element\n *\n * @cssprop --input-bg - Background color\n * @cssprop --input-color - Text color\n * @cssprop --input-border-color - Border color\n * @cssprop --input-placeholder-color - Placeholder text color\n * @cssprop --input-radius - Border radius\n * @cssprop --input-padding - Inner padding (block inline)\n * @cssprop --input-gap - Gap between prefix/suffix icons and input text\n * @cssprop --input-font-size - Font size\n * @cssprop --input-height - Field height\n * @cssprop --input-hover-bg - Field background on hover (flat/ghost variants)\n * @cssprop --input-hover-border-color - Field border on hover (flat/bordered variants)\n * @cssprop --input-focus-bg - Field background when focused (flat variant)\n * @cssprop --input-focus-border-color - Field border when focused (flat/text variants)\n *\n * @example\n * ```html\n * <ore-input type=\"email\" label=\"Email\" placeholder=\"you@example.com\" />\n * <ore-input label=\"Name\" variant=\"bordered\" color=\"primary\" />\n * <ore-input label=\"Username\" error=\"That username is taken\" />\n * <ore-input label=\"Username\" success />\n * <ore-input label=\"Username\" loading />\n * ```\n */\nexport const INPUT_TAG = 'ore-input' as const;\ndefine<OreInputProps>(INPUT_TAG, {\n formAssociated: true,\n props: {\n ...themableBundle,\n ...sizableBundle,\n ...disablableBundle,\n ...roundableBundle,\n autocomplete: prop.string(),\n clearable: prop.bool(false),\n error: prop.string(),\n fullwidth: prop.bool(false),\n helper: prop.string(),\n inputmode: prop.string<'none' | 'text' | 'decimal' | 'numeric' | 'tel' | 'search' | 'email' | 'url'>(),\n label: prop.string(),\n 'label-placement': prop.oneOf(['inset', 'outside'] as const, 'inset'),\n loading: prop.bool(false),\n maxlength: prop.json(undefined as number | undefined),\n minlength: prop.json(undefined as number | undefined),\n name: prop.string(),\n pattern: prop.string(),\n placeholder: prop.string(),\n readonly: prop.bool(false),\n ref: prop.data<((el: HTMLInputElement | null) => void) | null>(),\n required: prop.bool(false),\n success: prop.bool(false),\n type: prop.oneOf(VALID_INPUT_TYPES, 'text'),\n value: prop.string(),\n variant: prop.string<'flat' | 'text' | 'solid' | 'bordered' | 'outline' | 'ghost'>(),\n },\n setup(props) {\n const el = getHost();\n const slots = useSlots();\n\n const showPassword = signal(false);\n const inputRef = ref<HTMLInputElement>();\n\n const hasLabel = computed(() => !!props.label.value || slots.has('label').value);\n // `loading` behaves like a temporary `disabled` — forces the inner <input> out of\n // constraint validation and interaction for the duration, layered on top of any real\n // `loading` is layered on top of the consumer's explicit `disabled` prop.\n const isDisabled = computed(() => props.disabled.value || props.loading.value);\n\n const abortSignal = lifecycleSignal(onCleanup);\n const tf = createTextField({\n disabled: isDisabled,\n error: props.error,\n hasLabel,\n helper: props.helper,\n label: props.label,\n labelPlacement: props['label-placement'],\n maxLength: props.maxlength,\n onChange: (_event: Event, value: string) => {\n setFieldValue(el, value);\n dispatchNativeFieldEvent(el, 'change');\n },\n onInput: (_event: Event, value: string) => {\n setFieldValue(el, value);\n dispatchNativeFieldEvent(el, 'input');\n },\n prefix: 'input',\n readonly: props.readonly,\n required: props.required,\n signal: abortSignal,\n value: props.value,\n });\n\n defineFieldValue(\n el,\n () => tf.value.value,\n (value) => {\n tf.value.value = value;\n },\n );\n\n tf.attachFormField(\n useField<string>({\n disabled: tf.disabled,\n onReset: tf.reset,\n toFormValue: (v) => v,\n validationMessage: tf.validationMessage,\n validity: tf.validity,\n value: tf.value,\n }),\n );\n\n const {\n ariaDescribedBy,\n ariaErrorMessage,\n ariaInvalid,\n ariaLabelledBy,\n assistiveId,\n clear: clearValue,\n counter,\n errorId,\n errorText,\n fieldId: inputId,\n helperText,\n labelId,\n labelVisible,\n value: fieldValue,\n wire,\n } = tf;\n\n onElement(inputRef, (el) => {\n wire(el, abortSignal);\n\n const unwireRef = bindRefCallback(props.ref, el);\n\n return () => {\n unwireRef();\n };\n });\n\n const clear = (event?: Event): void => {\n clearValue(event);\n inputRef.value?.focus();\n };\n\n const resolvedInputType = (): string =>\n props.type.value === 'password' && showPassword.value ? 'text' : (props.type.value ?? 'text');\n\n bind({\n attr: {\n error: errorAttr(errorText),\n 'has-value': () => (fieldValue.value ? true : undefined),\n size: props.size,\n // Reflects `success` only once `error` is confirmed empty — keeps the two host\n // attributes mutually exclusive even if a consumer sets both props at once.\n success: () => (props.success.value && !errorText.value ? true : undefined),\n variant: props.variant,\n },\n });\n\n const labelHidden = () => !labelVisible.value;\n const passwordToggleLabel = () => (showPassword.value ? 'Hide password' : 'Show password');\n const passwordTogglePressed = () => String(showPassword.value);\n const passwordToggleIcon = () =>\n showPassword.value\n ? html`\n <ore-icon name=\"eye-off\" size=\"14\" stroke-width=\"2\" aria-hidden=\"true\"></ore-icon>\n `\n : html`\n <ore-icon name=\"eye\" size=\"14\" stroke-width=\"2\" aria-hidden=\"true\"></ore-icon>\n `;\n const helperHidden = () => !!errorText.value || !helperText.value;\n const errorHidden = () => !errorText.value;\n const counterNearLimit = () => (counter?.value.counterNearLimit && !counter?.value.counterAtLimit ? '' : null);\n const counterAtLimit = () => (counter?.value.counterAtLimit ? '' : null);\n const counterHidden = () => !counter;\n const counterText = () => counter?.value.counterText ?? '';\n\n const clearTabIndex = () => (fieldValue.value ? '0' : '-1');\n const pwdToggleTabIndex = () => (props.type.value === 'password' ? '0' : '-1');\n\n const togglePassword = () => {\n showPassword.value = !showPassword.value;\n inputRef.value?.focus();\n };\n\n return html`\n <div class=\"input-wrapper\" part=\"wrapper\">\n <label class=\"label\" for=\"${inputId}\" id=\"${labelId}\" part=\"label\" ?hidden=\"${labelHidden}\">\n <slot name=\"label\">${props.label}</slot>\n </label>\n <div class=\"field\" part=\"field\">\n <div class=\"input-row\" part=\"input-row\">\n <slot name=\"prefix\"></slot>\n <input\n part=\"input\"\n id=\"${inputId}\"\n type=\"${resolvedInputType}\"\n name=\"${props.name}\"\n placeholder=\"${props.placeholder}\"\n autocomplete=\"${props.autocomplete}\"\n inputmode=\"${props.inputmode}\"\n maxlength=\"${props.maxlength}\"\n minlength=\"${props.minlength}\"\n pattern=\"${props.pattern}\"\n ?disabled=\"${isDisabled}\"\n ?readonly=\"${props.readonly}\"\n ?required=\"${props.required}\"\n value=\"${live(fieldValue)}\"\n aria-labelledby=\"${ariaLabelledBy}\"\n aria-describedby=\"${ariaDescribedBy}\"\n aria-errormessage=\"${ariaErrorMessage}\"\n aria-invalid=\"${ariaInvalid}\"\n aria-busy=\"${() => (props.loading.value ? 'true' : null)}\"\n ref=\"${inputRef}\" />\n <slot name=\"suffix\"></slot>\n ${renderStatusIcon(errorText)}\n <span class=\"field-spinner\" part=\"spinner\" role=\"status\" aria-label=\"Loading\"></span>\n <button\n class=\"pwd-toggle-btn\"\n part=\"pwd-toggle\"\n type=\"button\"\n aria-label=\"${passwordToggleLabel}\"\n aria-pressed=\"${passwordTogglePressed}\"\n tabindex=\"${pwdToggleTabIndex}\"\n @click=\"${togglePassword}\">\n ${passwordToggleIcon}\n </button>\n <button\n aria-label=\"Clear\"\n class=\"clear-btn\"\n part=\"clear\"\n type=\"button\"\n tabindex=\"${clearTabIndex}\"\n @click=\"${clear}\">\n <ore-icon aria-hidden=\"true\" name=\"x\" size=\"12\" stroke-width=\"2.5\"></ore-icon>\n </button>\n </div>\n </div>\n <div class=\"helper-text\" aria-live=\"polite\" id=\"${assistiveId}\" part=\"helper\" ?hidden=\"${helperHidden}\">\n <slot name=\"helper\">${() => helperText.value}</slot>\n </div>\n <div class=\"helper-text\" id=\"${errorId}\" role=\"alert\" part=\"error\" ?hidden=\"${errorHidden}\">\n <slot name=\"error\">${() => errorText.value}</slot>\n </div>\n <div\n class=\"char-counter\"\n part=\"char-counter\"\n data-near-limit=\"${counterNearLimit}\"\n data-at-limit=\"${counterAtLimit}\"\n ?hidden=\"${counterHidden}\">\n ${counterText}\n </div>\n </div>\n `;\n },\n shadow: { delegatesFocus: true },\n styles: [\n colorThemeMixin,\n coarsePointerMixin,\n reducedMotionMixin,\n roundedVariantMixin,\n disabledLoadingMixin,\n sizeVariantMixin(FIELD_SIZE_PRESET),\n forcedColorsFocusMixin('input'),\n componentStyles,\n // Must come after `componentStyles` — `@layer` precedence is fixed by which layer name is\n // *first* referenced across this whole array, and `componentStyles` is what establishes\n // `refine.base` (the unconditional `--_bg`/`--_border-color` defaults this mixin's\n // `refine.variants` rules need to win over). Placed earlier, `refine.variants` would end up\n // registered as the *lower*-priority layer, and every variant would silently render as the\n // base default — exactly the bug this ordering fixes.\n fieldVariantMixin({ container: '.field', text: 'input', tokenPrefix: 'input' }),\n ],\n});\n"],"mappings":"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"}
1
+ {"version":3,"file":"input.js","names":[],"sources":["../src/inputs/input/input.ts"],"sourcesContent":["import { bind, define, getHost, html, live, onCleanup, onElement, prop, ref, useField, useSlots } from '@vielzeug/ore';\nimport { computed, signal } from '@vielzeug/ripple';\nimport { bindRefCallback, createTextField, lifecycleSignal } from '../../core';\nimport type { TextFieldProps } from '../../shared';\nimport { disablableBundle, FIELD_SIZE_PRESET, roundableBundle, sizableBundle, themableBundle } from '../../shared';\nimport type { InputType, VisualVariant } from '../../types';\nimport '../../content/icon/icon';\nimport {\n coarsePointerMixin,\n colorThemeMixin,\n disabledLoadingMixin,\n fieldVariantMixin,\n forcedColorsFocusMixin,\n reducedMotionMixin,\n roundedVariantMixin,\n sizeVariantMixin,\n} from '../../styles';\nimport { errorAttr } from '../shared/field-binding';\nimport { defineFieldValue, dispatchNativeFieldEvent, setFieldValue } from '../shared/native-field-event';\nimport { renderStatusIcon } from '../shared/templates';\nimport componentStyles from './input.css?inline';\n\n/** Input component properties */\n\nexport type OreInputEvents = {\n change: Event;\n input: InputEvent;\n};\n\nexport type OreInputProps = TextFieldProps<Exclude<VisualVariant, 'frost'>> & {\n /** Autocomplete hint */\n autocomplete?: string;\n /** Show a clear (×) button when the field has a value */\n clearable?: boolean;\n /** Virtual keyboard hint for mobile devices */\n inputmode?: 'none' | 'text' | 'decimal' | 'numeric' | 'tel' | 'search' | 'email' | 'url';\n /**\n * Shows an inline spinner inside the field and forces the inner `<input>` into\n * `disabled` for the duration — use while an async validation/submission request\n * is in flight (e.g. checking username availability) to prevent double-submits.\n */\n loading?: boolean;\n /** Maximum character length — shows a counter below the input */\n maxlength?: number;\n /** Minimum character length */\n minlength?: number;\n /** HTML pattern attribute for client-side validation */\n pattern?: string;\n /**\n * JS-only callback fired with the inner `<input>` element when it mounts,\n * and with `null` when it unmounts. Intended for composed components that\n * need imperative access to the raw input element.\n * Set as a JS property: `bitInput.ref = (el) => { ... }`.\n */\n ref?: ((el: HTMLInputElement | null) => void) | null;\n /** HTML input type */\n type?: InputType;\n};\n\nconst VALID_INPUT_TYPES = [\n 'text',\n 'email',\n 'password',\n 'search',\n 'url',\n 'tel',\n 'number',\n 'date',\n 'time',\n 'datetime-local',\n 'month',\n 'week',\n] as const;\n\n/**\n * A customizable text input component with multiple variants, label placements, and form features.\n *\n * @element ore-input\n *\n * @attr {string} label - Label text\n * @attr {string} label-placement - Label placement: 'inset' | 'outside'\n * @attr {string} type - HTML input type: 'text' | 'email' | 'password' | 'number' | 'tel' | 'url' | 'search'\n * @attr {string} value - Current input value\n * @attr {string} placeholder - Placeholder text\n * @attr {string} name - Form field name\n * @attr {string} helper - Helper text displayed below the input (fallback when the `helper` slot is empty)\n * @attr {string} error - Error message — marks the field as invalid (fallback when the `error` slot is empty)\n * @attr {boolean} disabled - Disable input interaction\n * @attr {boolean} readonly - Make the input read-only\n * @attr {boolean} required - Mark the field as required\n * @attr {boolean} loading - Show an inline spinner and force the field disabled\n * @attr {boolean} success - Show an inline success check icon (suppressed while `error` is set)\n * @attr {string} color - Theme color: 'primary' | 'secondary' | 'info' | 'success' | 'warning' | 'error'\n * @attr {string} variant - Visual variant: 'solid' | 'flat' | 'bordered' | 'outline' | 'ghost' | 'text'\n * @attr {string} size - Input size: 'sm' | 'md' | 'lg'\n * @attr {string} rounded - Border radius: 'none' | 'sm' | 'md' | 'lg' | 'xl' | '2xl' | '3xl' | 'full'\n *\n * @fires input - Emitted when input value changes (on every keystroke).\n * @fires change - Emitted when input loses focus with changed value.\n *\n * @slot prefix - Content before the input (e.g., icons)\n * @slot suffix - Content after the input (e.g., clear button, validation icon)\n * @slot label - Replaces the label text — slotted content takes precedence over the `label` prop\n * @slot helper - Replaces the helper text — slotted content takes precedence over the `helper` prop\n * @slot error - Replaces the error text — slotted content takes precedence over the `error` prop\n *\n * @part wrapper - The input wrapper element\n * @part label - The label element (inset or outside)\n * @part field - The field container element\n * @part input-row - The input row container element\n * @part input - The input element\n * @part status-icon - The inline error/success icon shown inside the field\n * @part spinner - The inline loading spinner shown inside the field while `loading`\n * @part helper - The helper text element\n *\n * @cssprop --input-bg - Background color\n * @cssprop --input-color - Text color\n * @cssprop --input-border-color - Border color\n * @cssprop --input-placeholder-color - Placeholder text color\n * @cssprop --input-radius - Border radius\n * @cssprop --input-padding - Inner padding (block inline)\n * @cssprop --input-label-block-inset - Inset from the field block start for an inset label\n * @cssprop --input-label-inset - Inset from the field inline start for an inset label\n * @cssprop --input-gap - Gap between prefix/suffix icons and input text\n * @cssprop --input-font-size - Font size\n * @cssprop --input-height - Field height\n * @cssprop --input-hover-bg - Field background on hover (flat/ghost variants)\n * @cssprop --input-hover-border-color - Field border on hover (flat/bordered variants)\n * @cssprop --input-focus-bg - Field background when focused (flat variant)\n * @cssprop --input-focus-border-color - Field border when focused (flat/text variants)\n *\n * @example\n * ```html\n * <ore-input type=\"email\" label=\"Email\" placeholder=\"you@example.com\" />\n * <ore-input label=\"Name\" variant=\"bordered\" color=\"primary\" />\n * <ore-input label=\"Username\" error=\"That username is taken\" />\n * <ore-input label=\"Username\" success />\n * <ore-input label=\"Username\" loading />\n * ```\n */\nexport const INPUT_TAG = 'ore-input' as const;\ndefine<OreInputProps>(INPUT_TAG, {\n formAssociated: true,\n props: {\n ...themableBundle,\n ...sizableBundle,\n ...disablableBundle,\n ...roundableBundle,\n autocomplete: prop.string(),\n clearable: prop.bool(false),\n error: prop.string(),\n fullwidth: prop.bool(false),\n helper: prop.string(),\n inputmode: prop.string<'none' | 'text' | 'decimal' | 'numeric' | 'tel' | 'search' | 'email' | 'url'>(),\n label: prop.string(),\n 'label-placement': prop.oneOf(['inset', 'outside'] as const, 'inset'),\n loading: prop.bool(false),\n maxlength: prop.json(undefined as number | undefined),\n minlength: prop.json(undefined as number | undefined),\n name: prop.string(),\n pattern: prop.string(),\n placeholder: prop.string(),\n readonly: prop.bool(false),\n ref: prop.data<((el: HTMLInputElement | null) => void) | null>(),\n required: prop.bool(false),\n success: prop.bool(false),\n type: prop.oneOf(VALID_INPUT_TYPES, 'text'),\n value: prop.string(),\n variant: prop.string<'flat' | 'text' | 'solid' | 'bordered' | 'outline' | 'ghost'>(),\n },\n setup(props) {\n const el = getHost();\n const slots = useSlots();\n\n const showPassword = signal(false);\n const inputRef = ref<HTMLInputElement>();\n\n const hasLabel = computed(() => !!props.label.value || slots.has('label').value);\n // `loading` behaves like a temporary `disabled` — forces the inner <input> out of\n // constraint validation and interaction for the duration, layered on top of any real\n // `loading` is layered on top of the consumer's explicit `disabled` prop.\n const isDisabled = computed(() => props.disabled.value || props.loading.value);\n\n const abortSignal = lifecycleSignal(onCleanup);\n const tf = createTextField({\n disabled: isDisabled,\n error: props.error,\n hasLabel,\n helper: props.helper,\n label: props.label,\n labelPlacement: props['label-placement'],\n maxLength: props.maxlength,\n onChange: (_event: Event, value: string) => {\n setFieldValue(el, value);\n dispatchNativeFieldEvent(el, 'change');\n },\n onInput: (_event: Event, value: string) => {\n setFieldValue(el, value);\n dispatchNativeFieldEvent(el, 'input');\n },\n prefix: 'input',\n readonly: props.readonly,\n required: props.required,\n signal: abortSignal,\n value: props.value,\n });\n\n defineFieldValue(\n el,\n () => tf.value.value,\n (value) => {\n tf.value.value = value;\n },\n );\n\n tf.attachFormField(\n useField<string>({\n disabled: tf.disabled,\n onReset: tf.reset,\n toFormValue: (v) => v,\n validationMessage: tf.validationMessage,\n validity: tf.validity,\n value: tf.value,\n }),\n );\n\n const {\n ariaDescribedBy,\n ariaErrorMessage,\n ariaInvalid,\n ariaLabelledBy,\n assistiveId,\n clear: clearValue,\n counter,\n errorId,\n errorText,\n fieldId: inputId,\n helperText,\n labelId,\n labelVisible,\n value: fieldValue,\n wire,\n } = tf;\n\n onElement(inputRef, (el) => {\n wire(el, abortSignal);\n\n const unwireRef = bindRefCallback(props.ref, el);\n\n return () => {\n unwireRef();\n };\n });\n\n const clear = (event?: Event): void => {\n clearValue(event);\n inputRef.value?.focus();\n };\n\n const resolvedInputType = (): string =>\n props.type.value === 'password' && showPassword.value ? 'text' : (props.type.value ?? 'text');\n\n bind({\n attr: {\n error: errorAttr(errorText),\n 'has-value': () => (fieldValue.value ? true : undefined),\n size: props.size,\n // Reflects `success` only once `error` is confirmed empty — keeps the two host\n // attributes mutually exclusive even if a consumer sets both props at once.\n success: () => (props.success.value && !errorText.value ? true : undefined),\n variant: props.variant,\n },\n });\n\n const labelHidden = () => !labelVisible.value;\n const passwordToggleLabel = () => (showPassword.value ? 'Hide password' : 'Show password');\n const passwordTogglePressed = () => String(showPassword.value);\n const passwordToggleIcon = () =>\n showPassword.value\n ? html`\n <ore-icon name=\"eye-off\" size=\"14\" stroke-width=\"2\" aria-hidden=\"true\"></ore-icon>\n `\n : html`\n <ore-icon name=\"eye\" size=\"14\" stroke-width=\"2\" aria-hidden=\"true\"></ore-icon>\n `;\n const helperHidden = () => !!errorText.value || !helperText.value;\n const errorHidden = () => !errorText.value;\n const counterNearLimit = () => (counter?.value.counterNearLimit && !counter?.value.counterAtLimit ? '' : null);\n const counterAtLimit = () => (counter?.value.counterAtLimit ? '' : null);\n const counterHidden = () => !counter;\n const counterText = () => counter?.value.counterText ?? '';\n\n const clearTabIndex = () => (fieldValue.value ? '0' : '-1');\n const pwdToggleTabIndex = () => (props.type.value === 'password' ? '0' : '-1');\n\n const togglePassword = () => {\n showPassword.value = !showPassword.value;\n inputRef.value?.focus();\n };\n\n return html`\n <div class=\"input-wrapper\" part=\"wrapper\">\n <label class=\"label\" for=\"${inputId}\" id=\"${labelId}\" part=\"label\" ?hidden=\"${labelHidden}\">\n <slot name=\"label\">${props.label}</slot>\n </label>\n <div class=\"field\" part=\"field\">\n <div class=\"input-row\" part=\"input-row\">\n <slot name=\"prefix\"></slot>\n <input\n part=\"input\"\n id=\"${inputId}\"\n type=\"${resolvedInputType}\"\n name=\"${props.name}\"\n placeholder=\"${props.placeholder}\"\n autocomplete=\"${props.autocomplete}\"\n inputmode=\"${props.inputmode}\"\n maxlength=\"${props.maxlength}\"\n minlength=\"${props.minlength}\"\n pattern=\"${props.pattern}\"\n ?disabled=\"${isDisabled}\"\n ?readonly=\"${props.readonly}\"\n ?required=\"${props.required}\"\n value=\"${live(fieldValue)}\"\n aria-labelledby=\"${ariaLabelledBy}\"\n aria-describedby=\"${ariaDescribedBy}\"\n aria-errormessage=\"${ariaErrorMessage}\"\n aria-invalid=\"${ariaInvalid}\"\n aria-busy=\"${() => (props.loading.value ? 'true' : null)}\"\n ref=\"${inputRef}\" />\n <slot name=\"suffix\"></slot>\n ${renderStatusIcon(errorText)}\n <span class=\"field-spinner\" part=\"spinner\" role=\"status\" aria-label=\"Loading\"></span>\n <button\n class=\"pwd-toggle-btn\"\n part=\"pwd-toggle\"\n type=\"button\"\n aria-label=\"${passwordToggleLabel}\"\n aria-pressed=\"${passwordTogglePressed}\"\n tabindex=\"${pwdToggleTabIndex}\"\n @click=\"${togglePassword}\">\n ${passwordToggleIcon}\n </button>\n <button\n aria-label=\"Clear\"\n class=\"clear-btn\"\n part=\"clear\"\n type=\"button\"\n tabindex=\"${clearTabIndex}\"\n @click=\"${clear}\">\n <ore-icon aria-hidden=\"true\" name=\"x\" size=\"12\" stroke-width=\"2.5\"></ore-icon>\n </button>\n </div>\n </div>\n <div class=\"helper-text\" aria-live=\"polite\" id=\"${assistiveId}\" part=\"helper\" ?hidden=\"${helperHidden}\">\n <slot name=\"helper\">${() => helperText.value}</slot>\n </div>\n <div class=\"helper-text\" id=\"${errorId}\" role=\"alert\" part=\"error\" ?hidden=\"${errorHidden}\">\n <slot name=\"error\">${() => errorText.value}</slot>\n </div>\n <div\n class=\"char-counter\"\n part=\"char-counter\"\n data-near-limit=\"${counterNearLimit}\"\n data-at-limit=\"${counterAtLimit}\"\n ?hidden=\"${counterHidden}\">\n ${counterText}\n </div>\n </div>\n `;\n },\n shadow: { delegatesFocus: true },\n styles: [\n colorThemeMixin,\n coarsePointerMixin,\n reducedMotionMixin,\n roundedVariantMixin,\n disabledLoadingMixin,\n sizeVariantMixin(FIELD_SIZE_PRESET),\n forcedColorsFocusMixin('input'),\n componentStyles,\n // Must come after `componentStyles` — `@layer` precedence is fixed by which layer name is\n // *first* referenced across this whole array, and `componentStyles` is what establishes\n // `refine.base` (the unconditional `--_bg`/`--_border-color` defaults this mixin's\n // `refine.variants` rules need to win over). Placed earlier, `refine.variants` would end up\n // registered as the *lower*-priority layer, and every variant would silently render as the\n // base default — exactly the bug this ordering fixes.\n fieldVariantMixin({ container: '.field', text: 'input', tokenPrefix: 'input' }),\n ],\n});\n"],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- var e=`@layer refine.base{:host{--_font-size:var(--input-font-size,var(--text-sm));--_gap:var(--input-gap,var(--size-2));--_field-height:var(--input-height,var(--size-10));--_padding:var(--input-padding,var(--size-1-5) var(--size-3));--_radius:var(--input-radius,var(--rounded-lg));--_placeholder:var(--input-placeholder-color,var(--color-contrast-500));--_bg:var(--input-bg,var(--color-contrast-100));--_border-color:var(--input-border-color,var(--color-contrast-300));min-width:var(--input-min-width,12rem);flex-direction:column;align-items:stretch;display:inline-flex}.input-wrapper{flex-direction:column;gap:0;width:100%;display:flex}.field{box-sizing:border-box;height:var(--_field-height);min-height:var(--_field-height);padding:var(--_padding);background:var(--_bg);border:var(--border) solid var(--_border-color);border-radius:var(--_radius);box-shadow:var(--shadow-2xs);transition:var(--_motion-transition,background var(--transition-fast), backdrop-filter var(--transition-fast), border-color var(--transition-fast), box-shadow var(--transition-fast));flex-direction:column;justify-content:center;align-items:stretch;gap:0;display:flex}.input-wrapper:has(.label:not([hidden])) .field{height:auto}:host(:not([label-placement=outside])) .input-wrapper{position:relative}:host(:not([label-placement=outside])) .label{z-index:1;pointer-events:none;top:var(--size-2);position:absolute}:host(:not([label-placement=outside])) .label:not(:is(:lang(ae),:lang(ar),:lang(arc),:lang(bcc),:lang(bqi),:lang(ckb),:lang(dv),:lang(fa),:lang(glk),:lang(he),:lang(ku),:lang(mzn),:lang(nqo),:lang(pnb),:lang(ps),:lang(sd),:lang(ug),:lang(ur),:lang(yi))){left:var(--_padding-x,var(--size-3))}:host(:not([label-placement=outside])) .label:is(:lang(ae),:lang(ar),:lang(arc),:lang(bcc),:lang(bqi),:lang(ckb),:lang(dv),:lang(fa),:lang(glk),:lang(he),:lang(ku),:lang(mzn),:lang(nqo),:lang(pnb),:lang(ps),:lang(sd),:lang(ug),:lang(ur),:lang(yi)){right:var(--_padding-x,var(--size-3))}:host(:not([label-placement=outside])) .input-wrapper:has(.label:not([hidden])) .field{padding-top:calc(var(--size-2) + 1lh + 2px)}.input-row{gap:var(--_gap);flex:1;align-items:center;display:flex}.label,label.label{text-overflow:ellipsis;font-size:var(--text-xs);font-weight:var(--font-medium);line-height:var(--leading-tight);color:var(--color-contrast-500);white-space:nowrap;cursor:pointer;-webkit-user-select:none;user-select:none;transition:var(--_motion-transition,color var(--transition-fast));margin-bottom:2px;overflow:hidden}:host([label-placement=outside]) .label,:host([label-placement=outside]) label.label{font-size:var(--text-xs);line-height:var(--leading-loose);order:-1}.helper-text{margin-top:var(--size-1-5);font-size:var(--text-xs);line-height:var(--leading-tight);color:color-mix(in oklch, var(--color-contrast-500) 80%, var(--color-canvas));overflow-wrap:anywhere;padding-left:2px;padding-right:2px}.helper-text[hidden]{display:none}::slotted(svg){width:var(--_icon-size,var(--leading-6));height:var(--_icon-size,var(--leading-6));flex-shrink:0}}@layer refine.overrides{input{min-width:0;font:inherit;font-size:var(--_font-size);line-height:var(--leading-normal);color:var(--color-contrast-900);background:0 0;border:none;outline:none;flex:1}input::placeholder{color:var(--_placeholder);transition:color var(--transition-fast)}input:focus-visible{outline:none}:host(:not([disabled],[variant=bordered],[variant=flat])) .field:hover{border-color:var(--color-contrast-400)}:host(:not([disabled])) .field:focus-within .label,:host(:not([disabled])) .field:focus-within ::slotted([slot=prefix]),:host(:not([disabled])) .field:focus-within ::slotted([slot=suffix]){color:var(--_theme-focus)}.clear-btn{width:var(--size-5);min-width:var(--_touch-target);height:var(--size-5);min-height:var(--_touch-target);color:var(--color-contrast-500);cursor:pointer;border-radius:var(--rounded-sm);transition:var(--_motion-transition,color var(--transition-fast));background:0 0;border:none;flex-shrink:0;justify-content:center;align-items:center;padding:0;display:none}.clear-btn:hover{color:var(--color-contrast-900)}.clear-btn:focus-visible{outline:var(--border-2) solid var(--_theme-focus);outline-offset:var(--border)}:host([clearable]) .clear-btn{display:flex}:host([clearable]:not([has-value])) .clear-btn{visibility:hidden;pointer-events:none}.pwd-toggle-btn{width:var(--size-5);min-width:var(--_touch-target);height:var(--size-5);min-height:var(--_touch-target);color:var(--color-contrast-500);cursor:pointer;border-radius:var(--rounded-sm);transition:var(--_motion-transition,color var(--transition-fast));background:0 0;border:none;flex-shrink:0;justify-content:center;align-items:center;padding:0;display:none}.pwd-toggle-btn:hover{color:var(--color-contrast-900)}.pwd-toggle-btn:focus-visible{outline:var(--border-2) solid var(--_theme-focus);outline-offset:var(--border)}:host([type=password]) .pwd-toggle-btn{display:flex}.char-counter{font-size:var(--text-xs);line-height:var(--leading-tight);color:var(--color-contrast-400);white-space:nowrap;padding-left:2px;padding-right:2px}.char-counter:not(:is(:lang(ae),:lang(ar),:lang(arc),:lang(bcc),:lang(bqi),:lang(ckb),:lang(dv),:lang(fa),:lang(glk),:lang(he),:lang(ku),:lang(mzn),:lang(nqo),:lang(pnb),:lang(ps),:lang(sd),:lang(ug),:lang(ur),:lang(yi))){text-align:right}.char-counter:is(:lang(ae),:lang(ar),:lang(arc),:lang(bcc),:lang(bqi),:lang(ckb),:lang(dv),:lang(fa),:lang(glk),:lang(he),:lang(ku),:lang(mzn),:lang(nqo),:lang(pnb),:lang(ps),:lang(sd),:lang(ug),:lang(ur),:lang(yi)){text-align:left}.char-counter[data-near-limit]{color:var(--color-warning,#f59e0b)}.char-counter[data-at-limit]{color:var(--color-error)}:host([error]:not([error=""])) .field{border-color:var(--color-error)}:host([error]:not([error=""])) .label,.helper-text[role=alert]{color:var(--color-error)}:host([success]) .field{border-color:var(--color-success)}.status-icon{width:var(--size-5);height:var(--size-5);flex-shrink:0;justify-content:center;align-items:center;display:none}:host([error]:not([error=""])) .status-icon,:host([success]) .status-icon{display:flex}.status-icon[data-status=error]{color:var(--color-error)}.status-icon[data-status=success]{color:var(--color-success)}@keyframes spin{to{transform:rotate(360deg)}}.field-spinner{width:var(--size-4);height:var(--size-4);border:var(--border-2) solid var(--_theme-focus,currentcolor);animation:var(--_motion-animation,spin var(--transition-loader) infinite);border-radius:50%;flex-shrink:0;display:none}.field-spinner:not(:is(:lang(ae),:lang(ar),:lang(arc),:lang(bcc),:lang(bqi),:lang(ckb),:lang(dv),:lang(fa),:lang(glk),:lang(he),:lang(ku),:lang(mzn),:lang(nqo),:lang(pnb),:lang(ps),:lang(sd),:lang(ug),:lang(ur),:lang(yi))){border-right-color:#0000}.field-spinner:is(:lang(ae),:lang(ar),:lang(arc),:lang(bcc),:lang(bqi),:lang(ckb),:lang(dv),:lang(fa),:lang(glk),:lang(he),:lang(ku),:lang(mzn),:lang(nqo),:lang(pnb),:lang(ps),:lang(sd),:lang(ug),:lang(ur),:lang(yi)){border-left-color:#0000}:host([loading]) .field-spinner{display:inline-block}}@layer refine.variants{:host([variant=text]){--_bg:var(--input-bg,transparent);--_border-color:var(--input-border-color,var(--color-contrast-300))}:host([variant=text]) .field{border:none;border-bottom:var(--border) solid var(--_border-color);box-shadow:none;border-radius:0}:host([variant=text]) .field:focus-within{border-bottom:var(--border-2) solid var(--input-focus-border-color,var(--_theme-focus))}:host(:not([disabled],[variant=text],[variant=flat])) .field:focus-within{background:var(--color-canvas);border-color:var(--_theme-focus);box-shadow:var(--_theme-shadow,var(--color-primary-focus-shadow))}:host([error]:not([error=""])) .field:focus-within{border-color:var(--color-error);box-shadow:var(--color-error-focus-shadow)}:host([success]) .field:focus-within{border-color:var(--color-success);box-shadow:var(--color-success-focus-shadow)}}@layer refine.utilities{:host([fullwidth]){width:100%}}:host([disabled]){opacity:1}:host([disabled]) .field{background:var(--color-contrast-100);border-color:var(--color-contrast-200);box-shadow:none}:host([disabled]) input{color:var(--color-contrast-400)}:host([disabled]) input::placeholder{color:var(--color-contrast-300)}:host([disabled]) .label{color:var(--color-contrast-400)}`;exports.default=e;
1
+ var e=`@layer refine.base{:host{--_font-size:var(--input-font-size,var(--text-sm));--_gap:var(--input-gap,var(--size-2));--_field-height:var(--input-height,var(--size-10));--_padding:var(--input-padding,var(--size-1-5) var(--size-3));--_label-block-inset:var(--input-label-block-inset,var(--size-2));--_label-inset:var(--input-label-inset,var(--size-3));--_radius:var(--input-radius,var(--rounded-lg));--_placeholder:var(--input-placeholder-color,var(--color-contrast-500));--_bg:var(--input-bg,var(--color-contrast-100));--_border-color:var(--input-border-color,var(--color-contrast-300));min-width:var(--input-min-width,12rem);flex-direction:column;align-items:stretch;display:inline-flex}.input-wrapper{flex-direction:column;gap:0;width:100%;display:flex}.field{box-sizing:border-box;height:var(--_field-height);min-height:var(--_field-height);padding:var(--_padding);background:var(--_bg);border:var(--border) solid var(--_border-color);border-radius:var(--_radius);box-shadow:var(--shadow-2xs);transition:var(--_motion-transition,background var(--transition-fast), backdrop-filter var(--transition-fast), border-color var(--transition-fast), box-shadow var(--transition-fast));flex-direction:column;justify-content:center;align-items:stretch;gap:0;display:flex}.input-wrapper:has(.label:not([hidden])) .field{height:auto}:host(:not([label-placement=outside])) .input-wrapper{position:relative}:host(:not([label-placement=outside])) .label{z-index:1;pointer-events:none;top:var(--_label-block-inset);position:absolute}:host(:not([label-placement=outside])) .label:not(:is(:lang(ae),:lang(ar),:lang(arc),:lang(bcc),:lang(bqi),:lang(ckb),:lang(dv),:lang(fa),:lang(glk),:lang(he),:lang(ku),:lang(mzn),:lang(nqo),:lang(pnb),:lang(ps),:lang(sd),:lang(ug),:lang(ur),:lang(yi))){left:var(--_label-inset)}:host(:not([label-placement=outside])) .label:is(:lang(ae),:lang(ar),:lang(arc),:lang(bcc),:lang(bqi),:lang(ckb),:lang(dv),:lang(fa),:lang(glk),:lang(he),:lang(ku),:lang(mzn),:lang(nqo),:lang(pnb),:lang(ps),:lang(sd),:lang(ug),:lang(ur),:lang(yi)){right:var(--_label-inset)}:host(:not([label-placement=outside])) .input-wrapper:has(.label:not([hidden])) .field{padding-top:calc(var(--_label-block-inset) + 1lh + 2px)}.input-row{gap:var(--_gap);flex:1;align-items:center;display:flex}.label,label.label{text-overflow:ellipsis;font-size:var(--text-xs);font-weight:var(--font-medium);line-height:var(--leading-tight);color:var(--color-contrast-500);white-space:nowrap;cursor:pointer;-webkit-user-select:none;user-select:none;transition:var(--_motion-transition,color var(--transition-fast));margin-bottom:2px;overflow:hidden}:host([label-placement=outside]) .label,:host([label-placement=outside]) label.label{font-size:var(--text-xs);line-height:var(--leading-loose);order:-1}.helper-text{margin-top:var(--size-1-5);font-size:var(--text-xs);line-height:var(--leading-tight);color:color-mix(in oklch, var(--color-contrast-500) 80%, var(--color-canvas));overflow-wrap:anywhere;padding-left:2px;padding-right:2px}.helper-text[hidden]{display:none}::slotted(svg){width:var(--_icon-size,var(--leading-6));height:var(--_icon-size,var(--leading-6));flex-shrink:0}}@layer refine.overrides{input{min-width:0;font:inherit;font-size:var(--_font-size);line-height:var(--leading-normal);color:var(--color-contrast-900);background:0 0;border:none;outline:none;flex:1}input::placeholder{color:var(--_placeholder);transition:color var(--transition-fast)}input:focus-visible{outline:none}:host(:not([disabled],[variant=bordered],[variant=flat])) .field:hover{border-color:var(--color-contrast-400)}:host(:not([disabled])) .field:focus-within .label,:host(:not([disabled])) .field:focus-within ::slotted([slot=prefix]),:host(:not([disabled])) .field:focus-within ::slotted([slot=suffix]){color:var(--_theme-focus)}.clear-btn{width:var(--size-5);min-width:var(--_touch-target);height:var(--size-5);min-height:var(--_touch-target);color:var(--color-contrast-500);cursor:pointer;border-radius:var(--rounded-sm);transition:var(--_motion-transition,color var(--transition-fast));background:0 0;border:none;flex-shrink:0;justify-content:center;align-items:center;padding:0;display:none}.clear-btn:hover{color:var(--color-contrast-900)}.clear-btn:focus-visible{outline:var(--border-2) solid var(--_theme-focus);outline-offset:var(--border)}:host([clearable]) .clear-btn{display:flex}:host([clearable]:not([has-value])) .clear-btn{visibility:hidden;pointer-events:none}.pwd-toggle-btn{width:var(--size-5);min-width:var(--_touch-target);height:var(--size-5);min-height:var(--_touch-target);color:var(--color-contrast-500);cursor:pointer;border-radius:var(--rounded-sm);transition:var(--_motion-transition,color var(--transition-fast));background:0 0;border:none;flex-shrink:0;justify-content:center;align-items:center;padding:0;display:none}.pwd-toggle-btn:hover{color:var(--color-contrast-900)}.pwd-toggle-btn:focus-visible{outline:var(--border-2) solid var(--_theme-focus);outline-offset:var(--border)}:host([type=password]) .pwd-toggle-btn{display:flex}.char-counter{font-size:var(--text-xs);line-height:var(--leading-tight);color:var(--color-contrast-400);white-space:nowrap;padding-left:2px;padding-right:2px}.char-counter:not(:is(:lang(ae),:lang(ar),:lang(arc),:lang(bcc),:lang(bqi),:lang(ckb),:lang(dv),:lang(fa),:lang(glk),:lang(he),:lang(ku),:lang(mzn),:lang(nqo),:lang(pnb),:lang(ps),:lang(sd),:lang(ug),:lang(ur),:lang(yi))){text-align:right}.char-counter:is(:lang(ae),:lang(ar),:lang(arc),:lang(bcc),:lang(bqi),:lang(ckb),:lang(dv),:lang(fa),:lang(glk),:lang(he),:lang(ku),:lang(mzn),:lang(nqo),:lang(pnb),:lang(ps),:lang(sd),:lang(ug),:lang(ur),:lang(yi)){text-align:left}.char-counter[data-near-limit]{color:var(--color-warning,#f59e0b)}.char-counter[data-at-limit]{color:var(--color-error)}:host([error]:not([error=""])) .field{border-color:var(--color-error)}:host([error]:not([error=""])) .label,.helper-text[role=alert]{color:var(--color-error)}:host([success]) .field{border-color:var(--color-success)}.status-icon{width:var(--size-5);height:var(--size-5);flex-shrink:0;justify-content:center;align-items:center;display:none}:host([error]:not([error=""])) .status-icon,:host([success]) .status-icon{display:flex}.status-icon[data-status=error]{color:var(--color-error)}.status-icon[data-status=success]{color:var(--color-success)}@keyframes spin{to{transform:rotate(360deg)}}.field-spinner{width:var(--size-4);height:var(--size-4);border:var(--border-2) solid var(--_theme-focus,currentcolor);animation:var(--_motion-animation,spin var(--transition-loader) infinite);border-radius:50%;flex-shrink:0;display:none}.field-spinner:not(:is(:lang(ae),:lang(ar),:lang(arc),:lang(bcc),:lang(bqi),:lang(ckb),:lang(dv),:lang(fa),:lang(glk),:lang(he),:lang(ku),:lang(mzn),:lang(nqo),:lang(pnb),:lang(ps),:lang(sd),:lang(ug),:lang(ur),:lang(yi))){border-right-color:#0000}.field-spinner:is(:lang(ae),:lang(ar),:lang(arc),:lang(bcc),:lang(bqi),:lang(ckb),:lang(dv),:lang(fa),:lang(glk),:lang(he),:lang(ku),:lang(mzn),:lang(nqo),:lang(pnb),:lang(ps),:lang(sd),:lang(ug),:lang(ur),:lang(yi)){border-left-color:#0000}:host([loading]) .field-spinner{display:inline-block}}@layer refine.variants{:host([variant=text]){--_bg:var(--input-bg,transparent);--_border-color:var(--input-border-color,var(--color-contrast-300))}:host([variant=text]) .field{box-shadow:none;background:0 0;border:none;border-radius:0}:host([variant=text]) .field:focus-within{box-shadow:none}:host(:not([disabled],[variant=text],[variant=flat])) .field:focus-within{background:var(--color-canvas);border-color:var(--_theme-focus);box-shadow:var(--_theme-shadow,var(--color-primary-focus-shadow))}:host([error]:not([error=""])) .field:focus-within{border-color:var(--color-error);box-shadow:var(--color-error-focus-shadow)}:host([success]) .field:focus-within{border-color:var(--color-success);box-shadow:var(--color-success-focus-shadow)}}@layer refine.utilities{:host([fullwidth]){width:100%}}:host([disabled]){opacity:1}:host([disabled]) .field{background:var(--color-contrast-100);border-color:var(--color-contrast-200);box-shadow:none}:host([disabled]) input{color:var(--color-contrast-400)}:host([disabled]) input::placeholder{color:var(--color-contrast-300)}:host([disabled]) .label{color:var(--color-contrast-400)}`;exports.default=e;
2
2
  //# sourceMappingURL=input.css.cjs.map