@mono-lit/helper 0.0.0-stage → 0.0.1

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 (538) hide show
  1. package/LICENSE.md +55 -0
  2. package/README.md +34 -2
  3. package/dist/breakpoints-CAbhDUht.js +84 -0
  4. package/dist/checkbox-Cqpie9Ap.js +4 -0
  5. package/dist/chip-DBUUa2eB.js +4 -0
  6. package/dist/chip-limits-BMoO31JM.js +213 -0
  7. package/dist/chip-strip-Cw3gyz0q.js +213 -0
  8. package/dist/color-DHYrfXsX.js +253 -0
  9. package/dist/css-class-BRKRzHx-.js +60 -0
  10. package/dist/css-size-DhHSVZJK.js +37 -0
  11. package/dist/data/theme/presets.json.d.ts +140 -0
  12. package/dist/data-search-Bwo5bg8K.js +573 -0
  13. package/dist/data-source-controller-C50Qyfzh.js +178 -0
  14. package/dist/data-source-options-BTpfrOZ_.js +535 -0
  15. package/dist/data-source-options-CQSTZHPE.js +537 -0
  16. package/dist/data-source-read-CUX-lgrQ.js +216 -0
  17. package/dist/data-source-read-DL88aH8t.js +217 -0
  18. package/dist/decorate-DEXtNagw.js +141 -0
  19. package/dist/element-props-CLB6yvbm.js +114 -0
  20. package/dist/esm-Ptok4SQZ.js +2026 -0
  21. package/dist/excel-CY6zGkcx.js +608 -0
  22. package/dist/excel-DopRbEMK.js +608 -0
  23. package/dist/export-BvlBx_GZ.js +2302 -0
  24. package/dist/export.d.ts +1 -0
  25. package/dist/export.js +2302 -0
  26. package/dist/field-icons-BoOG6KrL.js +51 -0
  27. package/dist/field-path-C92eGLg3.js +251 -0
  28. package/dist/filter-builder-Bke3qOgJ.js +205 -0
  29. package/dist/filter-builder-CE4zE0V5.js +205 -0
  30. package/dist/filter-eval-DIfU2EAn.js +173 -0
  31. package/dist/filter-odata-C1vSGZaY.js +591 -0
  32. package/dist/form-control-core-B8d7k6vk.js +223 -0
  33. package/dist/form-control-core-eeRr0zLU.js +223 -0
  34. package/dist/hydration-flush-RB5Tz5nl.js +1001 -0
  35. package/dist/icon-CJkTlmTb.js +55 -0
  36. package/dist/icon-dVhYJUIH.js +17 -0
  37. package/dist/import-BgJdkwBI.js +606 -0
  38. package/dist/import.d.ts +1 -0
  39. package/dist/import.js +606 -0
  40. package/dist/index.d.ts +1 -0
  41. package/dist/index.js +16 -0
  42. package/dist/index.node-DjvYOL-J.js +395 -0
  43. package/dist/index.node.d.ts +1 -0
  44. package/dist/index.node.js +16 -0
  45. package/dist/input-zGOULADt.js +4 -0
  46. package/dist/layout-var-CZnzMC0s.js +73 -0
  47. package/dist/light-slots-BVJwyg_2.js +244 -0
  48. package/dist/light-slots-DW1WgfgT.js +254 -0
  49. package/dist/markdown-DfqrfOJN.js +20146 -0
  50. package/dist/mono-button-CoVnBLav.js +873 -0
  51. package/dist/mono-button.shadow-FfP_hMH4.js +784 -0
  52. package/dist/mono-data-chart-ChU4Ii3p.js +738 -0
  53. package/dist/mono-data-dropdown-BAUl58kW.js +357 -0
  54. package/dist/mono-data-grid-CLBK8clE.js +4140 -0
  55. package/dist/mono-data-grid-Db80FzdZ.js +4142 -0
  56. package/dist/mono-element-B0kP_96P.js +232 -0
  57. package/dist/mono-event-Bi1qP9uN.js +129 -0
  58. package/dist/mono-form-controller-5PfsU4qa.js +409 -0
  59. package/dist/mono-modal-controller-BMO3n3rP.js +223 -0
  60. package/dist/mono-ui-CPV7rrdo.js +358 -0
  61. package/dist/notifier-CE4yxMUQ.js +88 -0
  62. package/dist/nuxt.d.ts +1 -0
  63. package/dist/nuxt.js +130 -0
  64. package/dist/popup-portal-BziRX1yG.js +465 -0
  65. package/dist/popup-stack-CEEMib__.js +189 -0
  66. package/dist/rate-limit-BBa2PO79.js +521 -0
  67. package/dist/reactive-BHsqVjRh.js +789 -0
  68. package/dist/reactive-D3EERqgO.js +47 -0
  69. package/dist/search.d.ts +1 -0
  70. package/dist/search.js +97 -0
  71. package/dist/src/components/accordion/accordion-core.d.ts +62 -0
  72. package/dist/src/components/accordion/accordion-types.d.ts +62 -0
  73. package/dist/src/components/accordion/index.d.ts +3 -0
  74. package/dist/src/components/accordion/index.shadow.d.ts +5 -0
  75. package/dist/src/components/accordion/mono-accordion.d.ts +55 -0
  76. package/dist/src/components/accordion/mono-accordion.shadow.d.ts +56 -0
  77. package/dist/src/components/alert/alert-core.d.ts +46 -0
  78. package/dist/src/components/alert/alert-types.d.ts +44 -0
  79. package/dist/src/components/alert/index.d.ts +3 -0
  80. package/dist/src/components/alert/index.shadow.d.ts +5 -0
  81. package/dist/src/components/alert/mono-alert.d.ts +44 -0
  82. package/dist/src/components/alert/mono-alert.shadow.d.ts +34 -0
  83. package/dist/src/components/breadcrumb/breadcrumb-core.d.ts +61 -0
  84. package/dist/src/components/breadcrumb/breadcrumb-list-core.d.ts +49 -0
  85. package/dist/src/components/breadcrumb/breadcrumb-render.d.ts +31 -0
  86. package/dist/src/components/breadcrumb/breadcrumb-types.d.ts +117 -0
  87. package/dist/src/components/breadcrumb/breadcrumb-utils.d.ts +43 -0
  88. package/dist/src/components/breadcrumb/index.d.ts +6 -0
  89. package/dist/src/components/breadcrumb/index.shadow.d.ts +8 -0
  90. package/dist/src/components/breadcrumb/mono-breadcrumb-list.d.ts +29 -0
  91. package/dist/src/components/breadcrumb/mono-breadcrumb-list.shadow.d.ts +48 -0
  92. package/dist/src/components/breadcrumb/mono-breadcrumb.d.ts +38 -0
  93. package/dist/src/components/breadcrumb/mono-breadcrumb.shadow.d.ts +73 -0
  94. package/dist/src/components/button/button-core.d.ts +90 -0
  95. package/dist/src/components/button/button-dropdown-core.d.ts +57 -0
  96. package/dist/src/components/button/button-dropdown-types.d.ts +129 -0
  97. package/dist/src/components/button/button-types.d.ts +219 -0
  98. package/dist/src/components/button/button-utils.d.ts +18 -0
  99. package/dist/src/components/button/index.button-dropdown.d.ts +4 -0
  100. package/dist/src/components/button/index.button-dropdown.shadow.d.ts +4 -0
  101. package/dist/src/components/button/index.d.ts +8 -0
  102. package/dist/src/components/button/index.shadow.d.ts +5 -0
  103. package/dist/src/components/button/mono-button-dropdown.d.ts +35 -0
  104. package/dist/src/components/button/mono-button-dropdown.shadow.d.ts +45 -0
  105. package/dist/src/components/button/mono-button.d.ts +123 -0
  106. package/dist/src/components/button/mono-button.shadow.d.ts +56 -0
  107. package/dist/src/components/card/card-core.d.ts +74 -0
  108. package/dist/src/components/card/card-types.d.ts +137 -0
  109. package/dist/src/components/card/card-utils.d.ts +23 -0
  110. package/dist/src/components/card/index.d.ts +4 -0
  111. package/dist/src/components/card/index.shadow.d.ts +6 -0
  112. package/dist/src/components/card/mono-card.d.ts +56 -0
  113. package/dist/src/components/card/mono-card.shadow.d.ts +52 -0
  114. package/dist/src/components/chart/chart-core.d.ts +43 -0
  115. package/dist/src/components/chart/chart-odata.d.ts +52 -0
  116. package/dist/src/components/chart/chart-types.d.ts +337 -0
  117. package/dist/src/components/chart/index.d.ts +8 -0
  118. package/dist/src/components/chart/index.shadow.d.ts +7 -0
  119. package/dist/src/components/chart/mono-chart-presets.d.ts +43 -0
  120. package/dist/src/components/chart/mono-chart-presets.shadow.d.ts +43 -0
  121. package/dist/src/components/chart/mono-chart.d.ts +30 -0
  122. package/dist/src/components/chart/mono-chart.shadow.d.ts +22 -0
  123. package/dist/src/components/chart/mono-data-chart.d.ts +27 -0
  124. package/dist/src/components/checkbox/checkbox-core.d.ts +53 -0
  125. package/dist/src/components/checkbox/checkbox-types.d.ts +69 -0
  126. package/dist/src/components/checkbox/checkbox-utils.d.ts +35 -0
  127. package/dist/src/components/checkbox/index.d.ts +4 -0
  128. package/dist/src/components/checkbox/index.shadow.d.ts +5 -0
  129. package/dist/src/components/checkbox/mono-checkbox.d.ts +34 -0
  130. package/dist/src/components/checkbox/mono-checkbox.shadow.d.ts +45 -0
  131. package/dist/src/components/chip/chip-core.d.ts +58 -0
  132. package/dist/src/components/chip/chip-types.d.ts +142 -0
  133. package/dist/src/components/chip/chip-utils.d.ts +24 -0
  134. package/dist/src/components/chip/index.d.ts +8 -0
  135. package/dist/src/components/chip/index.shadow.d.ts +6 -0
  136. package/dist/src/components/chip/mono-chip.d.ts +48 -0
  137. package/dist/src/components/chip/mono-chip.shadow.d.ts +33 -0
  138. package/dist/src/components/chip/mono-status-dot.d.ts +34 -0
  139. package/dist/src/components/date/date-core.d.ts +80 -0
  140. package/dist/src/components/date/date-types.d.ts +163 -0
  141. package/dist/src/components/date/index.d.ts +3 -0
  142. package/dist/src/components/date/index.shadow.d.ts +4 -0
  143. package/dist/src/components/date/mono-date.d.ts +22 -0
  144. package/dist/src/components/date/mono-date.shadow.d.ts +31 -0
  145. package/dist/src/components/drawer/drawer-core.d.ts +99 -0
  146. package/dist/src/components/drawer/drawer-types.d.ts +153 -0
  147. package/dist/src/components/drawer/index.d.ts +3 -0
  148. package/dist/src/components/drawer/index.shadow.d.ts +4 -0
  149. package/dist/src/components/drawer/mono-drawer.d.ts +45 -0
  150. package/dist/src/components/drawer/mono-drawer.shadow.d.ts +46 -0
  151. package/dist/src/components/dropdown/dropdown-core.d.ts +33 -0
  152. package/dist/src/components/dropdown/dropdown-types.d.ts +88 -0
  153. package/dist/src/components/dropdown/index.d.ts +3 -0
  154. package/dist/src/components/dropdown/index.shadow.d.ts +4 -0
  155. package/dist/src/components/dropdown/mono-dropdown.d.ts +34 -0
  156. package/dist/src/components/dropdown/mono-dropdown.shadow.d.ts +28 -0
  157. package/dist/src/components/dropdown-table/dropdown-table-core.d.ts +65 -0
  158. package/dist/src/components/dropdown-table/dropdown-table-types.d.ts +278 -0
  159. package/dist/src/components/dropdown-table/index.d.ts +5 -0
  160. package/dist/src/components/dropdown-table/index.shadow.d.ts +6 -0
  161. package/dist/src/components/dropdown-table/mono-data-dropdown.d.ts +152 -0
  162. package/dist/src/components/dropdown-table/mono-dropdown-table.d.ts +46 -0
  163. package/dist/src/components/dropdown-table/mono-dropdown-table.shadow.d.ts +22 -0
  164. package/dist/src/components/file-upload/file-upload-core.d.ts +60 -0
  165. package/dist/src/components/file-upload/file-upload-types.d.ts +145 -0
  166. package/dist/src/components/file-upload/file-upload-utils.d.ts +16 -0
  167. package/dist/src/components/file-upload/index.d.ts +4 -0
  168. package/dist/src/components/file-upload/index.shadow.d.ts +5 -0
  169. package/dist/src/components/file-upload/mono-file-upload.d.ts +33 -0
  170. package/dist/src/components/file-upload/mono-file-upload.shadow.d.ts +50 -0
  171. package/dist/src/components/filter/filter-builder-core.d.ts +36 -0
  172. package/dist/src/components/filter/filter-builder.d.ts +23 -0
  173. package/dist/src/components/filter/filter-odata.d.ts +27 -0
  174. package/dist/src/components/filter/filter-operators.d.ts +13 -0
  175. package/dist/src/components/filter/filter-types.d.ts +253 -0
  176. package/dist/src/components/filter/index.d.ts +6 -0
  177. package/dist/src/components/filter/index.shadow.d.ts +7 -0
  178. package/dist/src/components/filter/mono-filter-builder.d.ts +21 -0
  179. package/dist/src/components/filter/mono-filter-builder.shadow.d.ts +17 -0
  180. package/dist/src/components/form/form-control-core.d.ts +37 -0
  181. package/dist/src/components/form/form-rules.d.ts +25 -0
  182. package/dist/src/components/form/form-types.d.ts +307 -0
  183. package/dist/src/components/form/index.d.ts +6 -0
  184. package/dist/src/components/form/mono-form-controller.d.ts +16 -0
  185. package/dist/src/components/input/index.d.ts +6 -0
  186. package/dist/src/components/input/index.shadow.d.ts +8 -0
  187. package/dist/src/components/input/input-core.d.ts +91 -0
  188. package/dist/src/components/input/input-format.d.ts +118 -0
  189. package/dist/src/components/input/input-types.d.ts +179 -0
  190. package/dist/src/components/input/input-utils.d.ts +10 -0
  191. package/dist/src/components/input/mono-input.d.ts +46 -0
  192. package/dist/src/components/input/mono-input.shadow.d.ts +34 -0
  193. package/dist/src/components/menu/index.d.ts +6 -0
  194. package/dist/src/components/menu/index.shadow.d.ts +7 -0
  195. package/dist/src/components/menu/menu-core.d.ts +65 -0
  196. package/dist/src/components/menu/menu-render.d.ts +55 -0
  197. package/dist/src/components/menu/menu-types.d.ts +195 -0
  198. package/dist/src/components/menu/menu-utils.d.ts +53 -0
  199. package/dist/src/components/menu/mono-menu-list.d.ts +118 -0
  200. package/dist/src/components/menu/mono-menu.d.ts +39 -0
  201. package/dist/src/components/menu/mono-menu.shadow.d.ts +40 -0
  202. package/dist/src/components/modal/index.d.ts +4 -0
  203. package/dist/src/components/modal/index.shadow.d.ts +5 -0
  204. package/dist/src/components/modal/modal-core.d.ts +110 -0
  205. package/dist/src/components/modal/modal-types.d.ts +304 -0
  206. package/dist/src/components/modal/mono-modal-controller.d.ts +4 -0
  207. package/dist/src/components/modal/mono-modal.d.ts +45 -0
  208. package/dist/src/components/modal/mono-modal.shadow.d.ts +50 -0
  209. package/dist/src/components/nav/index.d.ts +4 -0
  210. package/dist/src/components/nav/index.shadow.d.ts +6 -0
  211. package/dist/src/components/nav/mono-nav.d.ts +41 -0
  212. package/dist/src/components/nav/mono-nav.shadow.d.ts +21 -0
  213. package/dist/src/components/nav/nav-core.d.ts +34 -0
  214. package/dist/src/components/nav/nav-types.d.ts +48 -0
  215. package/dist/src/components/nav/nav-utils.d.ts +12 -0
  216. package/dist/src/components/radio/index.d.ts +4 -0
  217. package/dist/src/components/radio/index.shadow.d.ts +5 -0
  218. package/dist/src/components/radio/mono-radio.d.ts +31 -0
  219. package/dist/src/components/radio/mono-radio.shadow.d.ts +35 -0
  220. package/dist/src/components/radio/radio-core.d.ts +45 -0
  221. package/dist/src/components/radio/radio-types.d.ts +58 -0
  222. package/dist/src/components/radio/radio-utils.d.ts +12 -0
  223. package/dist/src/components/rich-text-editor/index.d.ts +5 -0
  224. package/dist/src/components/rich-text-editor/index.shadow.d.ts +6 -0
  225. package/dist/src/components/rich-text-editor/mono-rich-text-editor.d.ts +31 -0
  226. package/dist/src/components/rich-text-editor/mono-rich-text-editor.shadow.d.ts +34 -0
  227. package/dist/src/components/rich-text-editor/rich-text-editor-core.d.ts +100 -0
  228. package/dist/src/components/rich-text-editor/rich-text-editor-loader.d.ts +17 -0
  229. package/dist/src/components/rich-text-editor/rich-text-editor-toolbar.d.ts +65 -0
  230. package/dist/src/components/rich-text-editor/rich-text-editor-types.d.ts +231 -0
  231. package/dist/src/components/select/index.d.ts +4 -0
  232. package/dist/src/components/select/index.shadow.d.ts +5 -0
  233. package/dist/src/components/select/mono-select.d.ts +69 -0
  234. package/dist/src/components/select/mono-select.shadow.d.ts +48 -0
  235. package/dist/src/components/select/select-core.d.ts +98 -0
  236. package/dist/src/components/select/select-types.d.ts +258 -0
  237. package/dist/src/components/select/select-utils.d.ts +7 -0
  238. package/dist/src/components/sidebar/index.d.ts +4 -0
  239. package/dist/src/components/sidebar/index.shadow.d.ts +6 -0
  240. package/dist/src/components/sidebar/mono-sidebar.d.ts +34 -0
  241. package/dist/src/components/sidebar/mono-sidebar.shadow.d.ts +27 -0
  242. package/dist/src/components/sidebar/sidebar-core.d.ts +51 -0
  243. package/dist/src/components/sidebar/sidebar-types.d.ts +119 -0
  244. package/dist/src/components/sidebar/sidebar-utils.d.ts +55 -0
  245. package/dist/src/components/switch/index.d.ts +4 -0
  246. package/dist/src/components/switch/index.shadow.d.ts +5 -0
  247. package/dist/src/components/switch/mono-switch.d.ts +31 -0
  248. package/dist/src/components/switch/mono-switch.shadow.d.ts +36 -0
  249. package/dist/src/components/switch/switch-core.d.ts +49 -0
  250. package/dist/src/components/switch/switch-types.d.ts +64 -0
  251. package/dist/src/components/switch/switch-utils.d.ts +12 -0
  252. package/dist/src/components/table/array-source.d.ts +44 -0
  253. package/dist/src/components/table/date-filter-tree.d.ts +93 -0
  254. package/dist/src/components/table/grouping.d.ts +55 -0
  255. package/dist/src/components/table/index.d.ts +33 -0
  256. package/dist/src/components/table/index.shadow.d.ts +47 -0
  257. package/dist/src/components/table/mono-data-grid.d.ts +1756 -0
  258. package/dist/src/components/table/mono-table-checkbox-core.d.ts +76 -0
  259. package/dist/src/components/table/mono-table-checkbox.d.ts +34 -0
  260. package/dist/src/components/table/mono-table-checkbox.shadow.d.ts +26 -0
  261. package/dist/src/components/table/mono-table-detail-core.d.ts +87 -0
  262. package/dist/src/components/table/mono-table-detail.d.ts +32 -0
  263. package/dist/src/components/table/mono-table-detail.shadow.d.ts +31 -0
  264. package/dist/src/components/table/mono-table-empty-core.d.ts +60 -0
  265. package/dist/src/components/table/mono-table-empty.d.ts +35 -0
  266. package/dist/src/components/table/mono-table-empty.shadow.d.ts +40 -0
  267. package/dist/src/components/table/mono-table-error-core.d.ts +84 -0
  268. package/dist/src/components/table/mono-table-error.d.ts +28 -0
  269. package/dist/src/components/table/mono-table-error.shadow.d.ts +21 -0
  270. package/dist/src/components/table/mono-table-info-core.d.ts +13 -0
  271. package/dist/src/components/table/mono-table-info.d.ts +19 -0
  272. package/dist/src/components/table/mono-table-info.shadow.d.ts +14 -0
  273. package/dist/src/components/table/mono-table-loading-core.d.ts +41 -0
  274. package/dist/src/components/table/mono-table-loading.d.ts +50 -0
  275. package/dist/src/components/table/mono-table-loading.shadow.d.ts +14 -0
  276. package/dist/src/components/table/mono-table-page-size-core.d.ts +14 -0
  277. package/dist/src/components/table/mono-table-page-size.d.ts +16 -0
  278. package/dist/src/components/table/mono-table-page-size.shadow.d.ts +11 -0
  279. package/dist/src/components/table/mono-table-paging-core.d.ts +22 -0
  280. package/dist/src/components/table/mono-table-paging-group-core.d.ts +18 -0
  281. package/dist/src/components/table/mono-table-paging-group.d.ts +20 -0
  282. package/dist/src/components/table/mono-table-paging-group.shadow.d.ts +13 -0
  283. package/dist/src/components/table/mono-table-paging.d.ts +16 -0
  284. package/dist/src/components/table/mono-table-paging.shadow.d.ts +11 -0
  285. package/dist/src/components/table/mono-table-search-core.d.ts +74 -0
  286. package/dist/src/components/table/mono-table-search.d.ts +34 -0
  287. package/dist/src/components/table/mono-table-search.shadow.d.ts +21 -0
  288. package/dist/src/components/table/mono-table-sort-core.d.ts +35 -0
  289. package/dist/src/components/table/mono-table-sort.d.ts +38 -0
  290. package/dist/src/components/table/mono-table-sort.shadow.d.ts +20 -0
  291. package/dist/src/components/table/mono-table-summary-core.d.ts +26 -0
  292. package/dist/src/components/table/mono-table-summary.d.ts +24 -0
  293. package/dist/src/components/table/mono-table-summary.shadow.d.ts +14 -0
  294. package/dist/src/components/table/mono-table-th-core.d.ts +56 -0
  295. package/dist/src/components/table/mono-table-th.d.ts +41 -0
  296. package/dist/src/components/table/mono-table-th.shadow.d.ts +19 -0
  297. package/dist/src/components/table/store-group-source.d.ts +24 -0
  298. package/dist/src/components/table/table-controller-core.d.ts +40 -0
  299. package/dist/src/components/table/table-filter-icons.d.ts +3 -0
  300. package/dist/src/components/table/table-menu-core.d.ts +65 -0
  301. package/dist/src/components/table/table-overlay.d.ts +165 -0
  302. package/dist/src/components/table/table-sort-icons.d.ts +4 -0
  303. package/dist/src/components/table/table-sort-utils.d.ts +20 -0
  304. package/dist/src/components/table/table-types.d.ts +475 -0
  305. package/dist/src/components/tabs/index.d.ts +3 -0
  306. package/dist/src/components/tabs/index.shadow.d.ts +4 -0
  307. package/dist/src/components/tabs/mono-tabs.d.ts +33 -0
  308. package/dist/src/components/tabs/mono-tabs.shadow.d.ts +37 -0
  309. package/dist/src/components/tabs/tabs-core.d.ts +57 -0
  310. package/dist/src/components/tabs/tabs-types.d.ts +65 -0
  311. package/dist/src/components/tag-input/index.d.ts +4 -0
  312. package/dist/src/components/tag-input/index.shadow.d.ts +5 -0
  313. package/dist/src/components/tag-input/mono-tag-input.d.ts +66 -0
  314. package/dist/src/components/tag-input/mono-tag-input.shadow.d.ts +40 -0
  315. package/dist/src/components/tag-input/tag-input-core.d.ts +108 -0
  316. package/dist/src/components/tag-input/tag-input-types.d.ts +394 -0
  317. package/dist/src/components/tag-input/tag-input-utils.d.ts +8 -0
  318. package/dist/src/components/textarea/index.d.ts +4 -0
  319. package/dist/src/components/textarea/index.shadow.d.ts +5 -0
  320. package/dist/src/components/textarea/mono-textarea.d.ts +29 -0
  321. package/dist/src/components/textarea/mono-textarea.shadow.d.ts +31 -0
  322. package/dist/src/components/textarea/textarea-core.d.ts +60 -0
  323. package/dist/src/components/textarea/textarea-types.d.ts +131 -0
  324. package/dist/src/components/textarea/textarea-utils.d.ts +7 -0
  325. package/dist/src/components/tooltip/control-tooltip.d.ts +36 -0
  326. package/dist/src/components/tooltip/index.d.ts +6 -0
  327. package/dist/src/components/tooltip/tooltip-config.d.ts +27 -0
  328. package/dist/src/components/tooltip/tooltip-declarative.d.ts +41 -0
  329. package/dist/src/components/tooltip/tooltip-loader.d.ts +1 -0
  330. package/dist/src/components/tooltip/tooltip-types.d.ts +110 -0
  331. package/dist/src/composables/breakpoints.d.ts +59 -0
  332. package/dist/src/composables/chip-limits.d.ts +48 -0
  333. package/dist/src/composables/chip-strip.d.ts +93 -0
  334. package/dist/src/composables/color.d.ts +103 -0
  335. package/dist/src/composables/css-class.d.ts +27 -0
  336. package/dist/src/composables/css-size.d.ts +40 -0
  337. package/dist/src/composables/data-source-controller.d.ts +84 -0
  338. package/dist/src/composables/element-props.d.ts +46 -0
  339. package/dist/src/composables/field-icons.d.ts +7 -0
  340. package/dist/src/composables/hybird-prop.d.ts +79 -0
  341. package/dist/src/composables/hydration-flush.d.ts +34 -0
  342. package/dist/src/composables/icon.d.ts +17 -0
  343. package/dist/src/composables/layout-var.d.ts +34 -0
  344. package/dist/src/composables/light-slots.d.ts +133 -0
  345. package/dist/src/composables/mdi-glyphs.d.ts +4 -0
  346. package/dist/src/composables/mono-element.d.ts +9 -0
  347. package/dist/src/composables/mono-event.d.ts +55 -0
  348. package/dist/src/composables/mono-pending.d.ts +8 -0
  349. package/dist/src/composables/mono-skeleton.d.ts +193 -0
  350. package/dist/src/composables/mono-ui.d.ts +58 -0
  351. package/dist/src/composables/notifier.d.ts +46 -0
  352. package/dist/src/composables/popup-portal.d.ts +226 -0
  353. package/dist/src/composables/popup-stack.d.ts +70 -0
  354. package/dist/src/composables/rate-limit.d.ts +108 -0
  355. package/dist/src/composables/reactive.d.ts +53 -0
  356. package/dist/src/composables/shadow-css.d.ts +42 -0
  357. package/dist/src/composables/visibility.d.ts +36 -0
  358. package/dist/src/data/theme/index.d.ts +30 -0
  359. package/dist/src/data/theme/presets.d.ts +94 -0
  360. package/dist/src/entries/index.d.ts +2 -0
  361. package/dist/src/entries/index.node.d.ts +42 -0
  362. package/dist/src/entries/search.d.ts +3 -0
  363. package/dist/src/export/detail.d.ts +29 -0
  364. package/dist/src/export/download.d.ts +9 -0
  365. package/dist/src/export/excel/index.d.ts +27 -0
  366. package/dist/src/export/excel/nodes.d.ts +123 -0
  367. package/dist/src/export/expression.d.ts +36 -0
  368. package/dist/src/export/helpers.d.ts +6 -0
  369. package/dist/src/export/index.d.ts +13 -0
  370. package/dist/src/export/markdown.d.ts +52 -0
  371. package/dist/src/export/resolve-data.d.ts +31 -0
  372. package/dist/src/export/sentinel.d.ts +97 -0
  373. package/dist/src/export/sheet-name.d.ts +45 -0
  374. package/dist/src/export/styles.d.ts +33 -0
  375. package/dist/src/export/template.d.ts +10 -0
  376. package/dist/src/export/types.d.ts +259 -0
  377. package/dist/src/import/coerce.d.ts +38 -0
  378. package/dist/src/import/index.d.ts +16 -0
  379. package/dist/src/import/match.d.ts +54 -0
  380. package/dist/src/import/parse.d.ts +15 -0
  381. package/dist/src/import/types.d.ts +153 -0
  382. package/dist/src/nuxt/index.d.ts +94 -0
  383. package/dist/src/search/data-search.d.ts +207 -0
  384. package/dist/src/search/field-path.d.ts +107 -0
  385. package/dist/src/search/filter-eval.d.ts +30 -0
  386. package/dist/src/search/index.d.ts +22 -0
  387. package/dist/src/search/odata-search.d.ts +18 -0
  388. package/dist/src/search/search-expr.d.ts +160 -0
  389. package/dist/src/utils/data-source-apply.d.ts +97 -0
  390. package/dist/src/utils/data-source-options.d.ts +116 -0
  391. package/dist/src/utils/data-source-read.d.ts +85 -0
  392. package/dist/src/utils/data-source-summary.d.ts +55 -0
  393. package/dist/src/utils/normalize-error.d.ts +60 -0
  394. package/dist/src/vite/index.d.ts +48 -0
  395. package/dist/src/vite/mono-client-only.d.ts +35 -0
  396. package/dist/src/vite/mono-ssr-stub.d.ts +20 -0
  397. package/dist/src/vite/shadow-manifest.d.ts +8 -0
  398. package/dist/styles-BIJ31TM4.js +20146 -0
  399. package/dist/tooltip-CysgRgBi.js +760 -0
  400. package/dist/tooltip.d.ts +1 -0
  401. package/dist/tooltip.js +2 -0
  402. package/dist/ui/accordion.d.ts +1 -0
  403. package/dist/ui/accordion.js +466 -0
  404. package/dist/ui/alert.d.ts +1 -0
  405. package/dist/ui/alert.js +221 -0
  406. package/dist/ui/breadcrumb.d.ts +1 -0
  407. package/dist/ui/breadcrumb.js +902 -0
  408. package/dist/ui/button-dropdown.d.ts +1 -0
  409. package/dist/ui/button-dropdown.js +679 -0
  410. package/dist/ui/button.d.ts +1 -0
  411. package/dist/ui/button.js +63 -0
  412. package/dist/ui/card.d.ts +1 -0
  413. package/dist/ui/card.js +511 -0
  414. package/dist/ui/chart.d.ts +1 -0
  415. package/dist/ui/chart.js +808 -0
  416. package/dist/ui/checkbox.d.ts +1 -0
  417. package/dist/ui/checkbox.js +413 -0
  418. package/dist/ui/chip.d.ts +1 -0
  419. package/dist/ui/chip.js +558 -0
  420. package/dist/ui/date.d.ts +1 -0
  421. package/dist/ui/date.js +686 -0
  422. package/dist/ui/drawer.d.ts +1 -0
  423. package/dist/ui/drawer.js +901 -0
  424. package/dist/ui/dropdown-table.d.ts +1 -0
  425. package/dist/ui/dropdown-table.js +1291 -0
  426. package/dist/ui/dropdown.d.ts +1 -0
  427. package/dist/ui/dropdown.js +586 -0
  428. package/dist/ui/file-upload.d.ts +1 -0
  429. package/dist/ui/file-upload.js +688 -0
  430. package/dist/ui/filter.d.ts +1 -0
  431. package/dist/ui/filter.js +400 -0
  432. package/dist/ui/font/files/geist-47c091c9.woff2 +0 -0
  433. package/dist/ui/font/files/geist-8dd77544.woff2 +0 -0
  434. package/dist/ui/font/files/geist-b9248b1e.woff2 +0 -0
  435. package/dist/ui/font/files/geist-d40d74b4.woff2 +0 -0
  436. package/dist/ui/font/files/geist-f493429a.woff2 +0 -0
  437. package/dist/ui/font/files/geistmono-03737868.woff2 +0 -0
  438. package/dist/ui/font/files/geistmono-421a7e38.woff2 +0 -0
  439. package/dist/ui/font/files/geistmono-48ef518d.woff2 +0 -0
  440. package/dist/ui/font/files/geistmono-5df35d39.woff2 +0 -0
  441. package/dist/ui/font/files/geistmono-7de289a4.woff2 +0 -0
  442. package/dist/ui/font/files/geistmono-e976128f.woff2 +0 -0
  443. package/dist/ui/font/files/inter-05cf802c.woff2 +0 -0
  444. package/dist/ui/font/files/inter-2b2f25a4.woff2 +0 -0
  445. package/dist/ui/font/files/inter-467acc7a.woff2 +0 -0
  446. package/dist/ui/font/files/inter-6e85163c.woff2 +0 -0
  447. package/dist/ui/font/files/inter-7048add3.woff2 +0 -0
  448. package/dist/ui/font/files/inter-9be0371e.woff2 +0 -0
  449. package/dist/ui/font/files/inter-a28b7e31.woff2 +0 -0
  450. package/dist/ui/font/files/poppins-054df55a.woff2 +0 -0
  451. package/dist/ui/font/files/poppins-0ee5dc9a.woff2 +0 -0
  452. package/dist/ui/font/files/poppins-0f44cb18.woff2 +0 -0
  453. package/dist/ui/font/files/poppins-0ff0d30c.woff2 +0 -0
  454. package/dist/ui/font/files/poppins-13045147.woff2 +0 -0
  455. package/dist/ui/font/files/poppins-1db57cd9.woff2 +0 -0
  456. package/dist/ui/font/files/poppins-2cf2a902.woff2 +0 -0
  457. package/dist/ui/font/files/poppins-39e7f079.woff2 +0 -0
  458. package/dist/ui/font/files/poppins-9607042d.woff2 +0 -0
  459. package/dist/ui/font/files/poppins-9a88fc1f.woff2 +0 -0
  460. package/dist/ui/font/files/poppins-b8f4f752.woff2 +0 -0
  461. package/dist/ui/font/files/poppins-f5e57db4.woff2 +0 -0
  462. package/dist/ui/font/geist-mono.css +104 -0
  463. package/dist/ui/font/geist.css +168 -0
  464. package/dist/ui/font/inter.css +232 -0
  465. package/dist/ui/font/poppins.css +104 -0
  466. package/dist/ui/form.d.ts +1 -0
  467. package/dist/ui/form.js +3 -0
  468. package/dist/ui/index.css +21826 -0
  469. package/dist/ui/input.d.ts +1 -0
  470. package/dist/ui/input.js +1176 -0
  471. package/dist/ui/menu.d.ts +1 -0
  472. package/dist/ui/menu.js +1289 -0
  473. package/dist/ui/modal.d.ts +1 -0
  474. package/dist/ui/modal.js +995 -0
  475. package/dist/ui/nav.d.ts +1 -0
  476. package/dist/ui/nav.js +295 -0
  477. package/dist/ui/radio.d.ts +1 -0
  478. package/dist/ui/radio.js +379 -0
  479. package/dist/ui/rich-text-editor.d.ts +1 -0
  480. package/dist/ui/rich-text-editor.js +1338 -0
  481. package/dist/ui/select.d.ts +1 -0
  482. package/dist/ui/select.js +2066 -0
  483. package/dist/ui/shadow/accordion.js +442 -0
  484. package/dist/ui/shadow/alert.js +218 -0
  485. package/dist/ui/shadow/breadcrumb.js +919 -0
  486. package/dist/ui/shadow/button-dropdown.js +696 -0
  487. package/dist/ui/shadow/button.js +63 -0
  488. package/dist/ui/shadow/card.js +524 -0
  489. package/dist/ui/shadow/chart.js +1569 -0
  490. package/dist/ui/shadow/checkbox.js +457 -0
  491. package/dist/ui/shadow/chip.js +559 -0
  492. package/dist/ui/shadow/date.js +712 -0
  493. package/dist/ui/shadow/drawer.js +869 -0
  494. package/dist/ui/shadow/dropdown-table.js +1620 -0
  495. package/dist/ui/shadow/dropdown.js +547 -0
  496. package/dist/ui/shadow/file-upload.js +731 -0
  497. package/dist/ui/shadow/filter.js +402 -0
  498. package/dist/ui/shadow/input.js +1150 -0
  499. package/dist/ui/shadow/menu.js +899 -0
  500. package/dist/ui/shadow/modal.js +1193 -0
  501. package/dist/ui/shadow/nav.js +240 -0
  502. package/dist/ui/shadow/radio.js +408 -0
  503. package/dist/ui/shadow/rich-text-editor.js +1344 -0
  504. package/dist/ui/shadow/select.js +2033 -0
  505. package/dist/ui/shadow/sidebar.js +606 -0
  506. package/dist/ui/shadow/switch.js +428 -0
  507. package/dist/ui/shadow/table.js +4755 -0
  508. package/dist/ui/shadow/tabs.js +372 -0
  509. package/dist/ui/shadow/tag-input.js +2846 -0
  510. package/dist/ui/shadow/textarea.js +816 -0
  511. package/dist/ui/sidebar.d.ts +1 -0
  512. package/dist/ui/sidebar.js +659 -0
  513. package/dist/ui/switch.d.ts +1 -0
  514. package/dist/ui/switch.js +398 -0
  515. package/dist/ui/table.d.ts +1 -0
  516. package/dist/ui/table.js +4654 -0
  517. package/dist/ui/tabs.d.ts +1 -0
  518. package/dist/ui/tabs.js +379 -0
  519. package/dist/ui/tag-input.d.ts +1 -0
  520. package/dist/ui/tag-input.js +2819 -0
  521. package/dist/ui/textarea.d.ts +1 -0
  522. package/dist/ui/textarea.js +819 -0
  523. package/dist/ui/theme/legacy.css +293 -0
  524. package/dist/ui/theme/luma.css +743 -0
  525. package/dist/ui/theme/lyra.css +754 -0
  526. package/dist/ui/theme/maia.css +673 -0
  527. package/dist/ui/theme/mira.css +802 -0
  528. package/dist/ui/theme/nova.css +662 -0
  529. package/dist/ui/theme/one.css +699 -0
  530. package/dist/ui/theme/rhea.css +742 -0
  531. package/dist/ui/theme/sera.css +845 -0
  532. package/dist/ui/theme/tokens.css +261 -0
  533. package/dist/ui/theme/vega.css +467 -0
  534. package/dist/vite-C5iUK7so.js +329 -0
  535. package/dist/vite.d.ts +1 -0
  536. package/dist/vite.js +2 -0
  537. package/dist/vue.d.ts +282 -0
  538. package/package.json +411 -3
@@ -0,0 +1,2033 @@
1
+ import { a as __decorate, f as customElement, i as withShadowUtilityStyles, l as defineHybridPropAliases, o as arrayHasChanged, r as toShadowCss, s as booleanStringConverter, t as flushSsrHydration } from "../../hydration-flush-RB5Tz5nl.js";
2
+ import { t as dispatchMonoEvent } from "../../mono-event-Bi1qP9uN.js";
3
+ import { n as toCssSize, t as buildSizeStyle } from "../../css-size-DhHSVZJK.js";
4
+ import { t as MonoFormControlCore } from "../../form-control-core-B8d7k6vk.js";
5
+ import { t as PopupPortalController } from "../../popup-portal-BziRX1yG.js";
6
+ import { a as rateLimitHasChanged } from "../../rate-limit-BBa2PO79.js";
7
+ import { t as getFieldValue } from "../../field-path-C92eGLg3.js";
8
+ import { a as MonoSourceSearch, c as searchRowPredicate, n as unwrapReactive, s as resolveSearchFields } from "../../reactive-BHsqVjRh.js";
9
+ import { t as LateSlotWatcher } from "../../light-slots-BVJwyg_2.js";
10
+ import { t as DataSourceController } from "../../data-source-controller-C50Qyfzh.js";
11
+ import { LitElement, html, isServer, nothing, unsafeCSS } from "lit";
12
+ import { property, query, state } from "lit/decorators.js";
13
+ import { ifDefined } from "lit/directives/if-defined.js";
14
+ import { styleMap } from "lit/directives/style-map.js";
15
+ //#region src/components/select/select-core.ts
16
+ /**
17
+ * `MonoSelectCore` — render-mode-agnostic logic for `mono-select` (props, hybrid
18
+ * aliases, value/model sync, DataSource paging, search, grouping, keyboard nav,
19
+ * the popup controller, and the full `render()`). SSR-safe: every `document` /
20
+ * `window` / focus access is `isServer`-guarded.
21
+ *
22
+ * Each build supplies `createRenderRoot()` + `static styles`, the slot strategy
23
+ * (light captures children into `data-mono-slot` placeholders; shadow uses native
24
+ * `<slot>` + a `firstUpdated` scan), and the `_slotOutlet` / `renderIcon` hooks.
25
+ * The shared `_has*SlotState` `@state` fields back both strategies.
26
+ */
27
+ var MonoSelectCore = (superClass) => {
28
+ class MonoSelectCoreClass extends MonoFormControlCore(superClass) {
29
+ constructor(...args) {
30
+ super(...args);
31
+ this.size = "md";
32
+ this.color = "primary";
33
+ this.variant = "outlined";
34
+ this.modelValue = null;
35
+ this.value = null;
36
+ this.name = "";
37
+ this.label = "";
38
+ this.placeholder = "Select option";
39
+ this.helperText = "";
40
+ this.validationState = "default";
41
+ this.validationMessage = "";
42
+ this.errorMessage = "";
43
+ this.successMessage = "";
44
+ this.disabled = false;
45
+ this.readonly = false;
46
+ this.required = false;
47
+ this.clearable = false;
48
+ this.items = [];
49
+ this.dataSource = null;
50
+ this.immediate = true;
51
+ this.pageSize = 10;
52
+ this.dropdownHeight = "";
53
+ this.dropdownMaxHeight = "";
54
+ this.flip = true;
55
+ this.shift = true;
56
+ this.keyValue = "";
57
+ this.displayValue = "";
58
+ this.displayGroup = [];
59
+ this.groupKey = "key";
60
+ this.groupItems = "items";
61
+ this.group = false;
62
+ this.groupSticky = false;
63
+ this.searchable = false;
64
+ this.stayOpen = false;
65
+ this.searchValue = "";
66
+ this.searchOperation = "contains";
67
+ this.searchDebounce = 300;
68
+ this.searchPlaceholder = "";
69
+ this.cssClass = {};
70
+ this.cssClassName = "";
71
+ this._open = false;
72
+ this._query = "";
73
+ this._searchActive = false;
74
+ this._activeIndex = -1;
75
+ this._cursorPending = false;
76
+ this._sourceSearch = new MonoSourceSearch();
77
+ this._searchVersion = 0;
78
+ this._scrollAutoMaxHeight = "";
79
+ this._hasLabelSlotState = false;
80
+ this._hasHelperSlotState = false;
81
+ this._hasPrefixSlotState = false;
82
+ this._hasSuffixSlotState = false;
83
+ this._hasListSlotState = false;
84
+ this._popup = new PopupPortalController(this, {
85
+ getPanel: () => this.renderRoot.querySelector(".mono-select-dropdown"),
86
+ getAnchor: () => this.renderRoot.querySelector(".mono-select-trigger"),
87
+ getStyleScope: () => this.renderRoot.querySelector(".mono-select"),
88
+ isOpen: () => this._open,
89
+ matchWidth: () => !toCssSize(this.dropdown?.width),
90
+ offset: () => 6,
91
+ flip: () => this.flip,
92
+ shift: () => this.shift,
93
+ constrainSize: () => true
94
+ });
95
+ this._selectId = `mono-select-${Math.random().toString(36).slice(2)}`;
96
+ this._messageId = `${this._selectId}-message`;
97
+ this._listboxId = `${this._selectId}-listbox`;
98
+ this._lateListSlot = new LateSlotWatcher(this, "list", () => this._onLateListSlot());
99
+ this._docListenersBound = false;
100
+ this._itemsEpoch = 0;
101
+ this._handleDropdownScroll = (event) => {
102
+ if (this._loadMoreMode !== "scroll") return;
103
+ if (this._ds.loadingMore || this._ds.atLastPage) return;
104
+ const el = event.currentTarget;
105
+ if (!el) return;
106
+ if (el.scrollHeight - el.scrollTop - el.clientHeight <= 24) this._ds.loadMore();
107
+ };
108
+ this._handleDocumentClick = (event) => {
109
+ if (!this._open || this.stayOpen) return;
110
+ const path = event.composedPath();
111
+ if (path.includes(this) || this._popup.containsInPath(path)) return;
112
+ this._close();
113
+ };
114
+ this._handleDocumentFocusIn = (event) => {
115
+ if (!this._open || this.stayOpen) return;
116
+ const path = event.composedPath();
117
+ if (path.includes(this) || this._popup.containsInPath(path)) return;
118
+ this._close();
119
+ };
120
+ this._handleDocumentKeydown = (event) => {
121
+ if (!this._open) return;
122
+ if (event.key === "Escape") {
123
+ event.preventDefault();
124
+ this._close();
125
+ this._triggerEl?.focus();
126
+ }
127
+ };
128
+ this._publishedEntries = [];
129
+ this._onListSlotClick = (event) => {
130
+ if (this.disabled || this.readonly) return;
131
+ const target = event.target;
132
+ const item = target ? this._entryFromNode(target)?.item : void 0;
133
+ if (!item || item.disabled) return;
134
+ this._selectItem(item, event);
135
+ };
136
+ defineHybridPropAliases(this, [
137
+ "modelValue",
138
+ "helperText",
139
+ "validationState",
140
+ "validationMessage",
141
+ "errorMessage",
142
+ "successMessage",
143
+ "ariaLabelText",
144
+ "cssClass",
145
+ "keyValue",
146
+ "displayValue",
147
+ "displayGroup",
148
+ "groupKey",
149
+ "groupItems",
150
+ "groupSticky",
151
+ "searchValue",
152
+ "searchOperation",
153
+ "searchDebounce",
154
+ "searchPlaceholder",
155
+ "dataSource",
156
+ "loadMore",
157
+ "pageSize",
158
+ "dropdownHeight",
159
+ "dropdownMaxHeight",
160
+ "minWidth",
161
+ "maxWidth",
162
+ "minHeight",
163
+ "maxHeight",
164
+ "stayOpen"
165
+ ]);
166
+ /**
167
+ * Makes these Vue usages work:
168
+ *
169
+ * <mono-select :cssClass="{}" />
170
+ * <mono-select :css-class="{}" />
171
+ * <mono-select :cssclass="{}" />
172
+ */
173
+ Object.defineProperty(this, "css-class", {
174
+ get: () => this.cssClass,
175
+ set: (value) => {
176
+ this._setCssClass(value);
177
+ },
178
+ configurable: true,
179
+ enumerable: false
180
+ });
181
+ Object.defineProperty(this, "cssclass", {
182
+ get: () => this.cssClass,
183
+ set: (value) => {
184
+ this._setCssClass(value);
185
+ },
186
+ configurable: true,
187
+ enumerable: false
188
+ });
189
+ Object.defineProperty(this, "ariaLabel", {
190
+ get: () => this.ariaLabelText,
191
+ set: (value) => {
192
+ this.ariaLabelText = value == null ? void 0 : String(value);
193
+ },
194
+ configurable: true,
195
+ enumerable: false
196
+ });
197
+ Object.defineProperty(this, "aria-label", {
198
+ get: () => this.ariaLabelText,
199
+ set: (value) => {
200
+ this.ariaLabelText = value == null ? void 0 : String(value);
201
+ },
202
+ configurable: true,
203
+ enumerable: false
204
+ });
205
+ Object.defineProperty(this, "arialabel", {
206
+ get: () => this.ariaLabelText,
207
+ set: (value) => {
208
+ this.ariaLabelText = value == null ? void 0 : String(value);
209
+ },
210
+ configurable: true,
211
+ enumerable: false
212
+ });
213
+ this._ds = new DataSourceController(this, {
214
+ getDataSource: () => this.dataSource,
215
+ getItems: () => this.items,
216
+ getImmediate: () => this.immediate,
217
+ getLoadMoreMode: () => this._loadMoreMode,
218
+ getPageSize: () => this._pageSize
219
+ });
220
+ }
221
+ static {
222
+ this.monoPendingAuto = "data";
223
+ }
224
+ _monoPendingReady() {
225
+ return !this.dataSource || !this._ds.loading;
226
+ }
227
+ static get observedAttributes() {
228
+ return [
229
+ ...super.observedAttributes ?? [],
230
+ "modelvalue",
231
+ "model-value",
232
+ "helpertext",
233
+ "validationstate",
234
+ "validationmessage",
235
+ "errormessage",
236
+ "successmessage",
237
+ "arialabeltext",
238
+ "arialabel",
239
+ "css-class",
240
+ "cssclass",
241
+ "keyvalue",
242
+ "displayvalue",
243
+ "display-value",
244
+ "stayopen"
245
+ ];
246
+ }
247
+ attributeChangedCallback(name, oldValue, newValue) {
248
+ super.attributeChangedCallback(name, oldValue, newValue);
249
+ if (oldValue === newValue) return;
250
+ if (name === "modelvalue" || name === "model-value") {
251
+ this.modelValue = this._toSelectValue(newValue);
252
+ return;
253
+ }
254
+ if (name === "helpertext") {
255
+ this.helperText = newValue ?? "";
256
+ return;
257
+ }
258
+ if (name === "validationstate") {
259
+ this.validationState = newValue ?? "default";
260
+ return;
261
+ }
262
+ if (name === "validationmessage") {
263
+ this.validationMessage = newValue ?? "";
264
+ return;
265
+ }
266
+ if (name === "errormessage") {
267
+ this.errorMessage = newValue ?? "";
268
+ return;
269
+ }
270
+ if (name === "successmessage") {
271
+ this.successMessage = newValue ?? "";
272
+ return;
273
+ }
274
+ if (name === "arialabeltext" || name === "arialabel") {
275
+ this.ariaLabelText = newValue ?? void 0;
276
+ return;
277
+ }
278
+ if (name === "keyvalue") {
279
+ this.keyValue = newValue ?? "";
280
+ return;
281
+ }
282
+ if (name === "displayvalue" || name === "display-value") {
283
+ if (typeof this.displayValue === "function") return;
284
+ const next = newValue ?? "";
285
+ if (this._looksLikeSerializedFunction(next)) return;
286
+ this.displayValue = next;
287
+ return;
288
+ }
289
+ if (name === "stayopen") {
290
+ this.stayOpen = this._toBoolean(newValue);
291
+ return;
292
+ }
293
+ if (name === "css-class" || name === "cssclass") this._setCssClass(newValue);
294
+ }
295
+ /**
296
+ * The scroll body lives inside the dropdown panel, which the portal
297
+ * controller relocates into a `<body>` portal while open — query it through
298
+ * `panelRoot` (the portal when adopted, else the host render root).
299
+ */
300
+ get _dropdownBodyEl() {
301
+ return this._popup.panelRoot.querySelector(".mono-select-dropdown-body");
302
+ }
303
+ /**
304
+ * Where the consumer's list wrapper is parked — through the SAME portal-aware root as the panel,
305
+ * since while the dropdown is open it lives in a body portal a host query would miss.
306
+ */
307
+ get _listSlotTarget() {
308
+ return this._popup.panelRoot.querySelector("[data-mono-slot=\"list\"]");
309
+ }
310
+ /** A late wrapper arrived. Overridden per build — one adopts it, the other rescans. */
311
+ _onLateListSlot() {}
312
+ connectedCallback() {
313
+ super.connectedCallback();
314
+ this._lateListSlot.start();
315
+ if (isServer) return;
316
+ if (this._open) this._bindDocumentListeners();
317
+ }
318
+ /**
319
+ * Outside-dismiss listeners, bound on OPEN rather than on connect.
320
+ *
321
+ * All three handlers begin with `if (!this._open) return`, so binding them only
322
+ * while open is behaviour-preserving — the cost they carried was pure event
323
+ * DISPATCH. Every mounted select used to hold three `document` listeners, two of
324
+ * them capture-phase, so a grid with one select per row put 600 handlers (400 in
325
+ * capture) in the path of every click, focus move and keystroke on the page.
326
+ * Measured on the 200-row fixture: 600 listeners before, 0 at rest after.
327
+ *
328
+ * Same change, and the same reasoning, as the popup viewport listeners in
329
+ * `popup-portal.ts` — which this file was explicitly the remaining example of.
330
+ */
331
+ _bindDocumentListeners() {
332
+ if (this._docListenersBound) return;
333
+ this._docListenersBound = true;
334
+ document.addEventListener("click", this._handleDocumentClick, true);
335
+ document.addEventListener("focusin", this._handleDocumentFocusIn, true);
336
+ document.addEventListener("keydown", this._handleDocumentKeydown);
337
+ }
338
+ _unbindDocumentListeners() {
339
+ if (!this._docListenersBound) return;
340
+ this._docListenersBound = false;
341
+ document.removeEventListener("click", this._handleDocumentClick, true);
342
+ document.removeEventListener("focusin", this._handleDocumentFocusIn, true);
343
+ document.removeEventListener("keydown", this._handleDocumentKeydown);
344
+ }
345
+ disconnectedCallback() {
346
+ if (this._searchTimer) {
347
+ clearTimeout(this._searchTimer);
348
+ this._searchTimer = void 0;
349
+ }
350
+ this._sourceSearch.clear(this.dataSource);
351
+ this._lateListSlot.stop();
352
+ this._stopWatchingListChrome();
353
+ if (!isServer) this._unbindDocumentListeners();
354
+ super.disconnectedCallback();
355
+ }
356
+ willUpdate(changed) {
357
+ this._itemsEpoch++;
358
+ for (const key of [
359
+ "disabled",
360
+ "readonly",
361
+ "required",
362
+ "clearable",
363
+ "immediate",
364
+ "group",
365
+ "groupSticky",
366
+ "searchable",
367
+ "stayOpen"
368
+ ]) {
369
+ const v = this[key];
370
+ if (typeof v !== "boolean") this[key] = this._toBoolean(v);
371
+ }
372
+ if (changed.has("modelValue") && !this._isSameValue(this.value, this.modelValue)) this.value = unwrapReactive(this.modelValue);
373
+ if (changed.has("value") && !this._isSameValue(this.modelValue, this.value)) this.modelValue = unwrapReactive(this.value);
374
+ if (this.group && (changed.has("dataSource") || changed.has("displayGroup") || changed.has("group"))) {
375
+ const fields = this._groupSortFields();
376
+ if (fields.length) this.dataSource?.sort?.(fields);
377
+ }
378
+ if (changed.has("dataSource")) {
379
+ this._ds.bind(this.dataSource);
380
+ this._sourceSearch.bind(this.dataSource);
381
+ }
382
+ if (changed.has("searchValue") || changed.has("searchOperation") || changed.has("displayValue") || changed.has("keyValue") || changed.has("dataSource") || changed.has("items")) this._searchVersion++;
383
+ if (changed.has("immediate")) this._ds.maybeImmediateLoad();
384
+ if (changed.has("loadMore")) this._ds.onLoadMoreModeChange();
385
+ if (changed.has("items") || changed.has("loadMore") || changed.has("pageSize")) this._ds.resetVisible();
386
+ if (changed.has("_open")) {
387
+ this._cursorPending = this._open;
388
+ if (!this._open) this._activeIndex = -1;
389
+ }
390
+ if (this._cursorPending && this._open && this._filteredItems.length) {
391
+ this._activeIndex = this._initialActiveIndex();
392
+ this._cursorPending = false;
393
+ }
394
+ }
395
+ updated(changed) {
396
+ super.updated(changed);
397
+ this._syncListEntries();
398
+ if (isServer) return;
399
+ if (changed.has("_open") && this._open && this.searchable) this._searchFieldEl?.focus();
400
+ if (changed.has("_activeIndex") && this._open && this._activeIndex >= 0) (this._popup.panelRoot?.querySelectorAll?.(".mono-select-item")?.[this._activeIndex])?.scrollIntoView?.({ block: "nearest" });
401
+ this._updateScrollAutoHeight();
402
+ if (this._open) this._bindDocumentListeners();
403
+ else this._unbindDocumentListeners();
404
+ }
405
+ /**
406
+ * Scroll-mode ergonomics: a short page (e.g. 5 items) won't overflow the
407
+ * default dropdown height, so there's nothing to scroll and the next page
408
+ * could never be triggered. Rather than eagerly fetching another page on
409
+ * open, cap the list height to the loaded rows minus a sliver — enough to
410
+ * show a scrollbar so the user scrolls to load more. No height is forced
411
+ * when the consumer set `dropdown-height`/`dropdown-max-height`, when the
412
+ * last page is reached, or when the rows already overflow.
413
+ */
414
+ _updateScrollAutoHeight() {
415
+ const userSetHeight = this._toCssLength(this.dropdownHeight) != null || this._toCssLength(this.dropdownMaxHeight) != null || toCssSize(this.dropdown?.height) != null || toCssSize(this.dropdown?.maxHeight) != null;
416
+ if (!(this._loadMoreMode === "scroll" && this._open && !this._ds.atLastPage && !userSetHeight && this._visibleItems.length > 0)) {
417
+ this._setScrollAutoMaxHeight("");
418
+ return;
419
+ }
420
+ const el = this._dropdownBodyEl;
421
+ const rowH = (el?.querySelector(".mono-select-item"))?.offsetHeight ?? 0;
422
+ if (!el || !rowH) return;
423
+ const CAP_ROWS = 7;
424
+ const rows = this._visibleItems.length;
425
+ let visible = Math.min(rows, CAP_ROWS);
426
+ if (rows <= CAP_ROWS) visible -= .5;
427
+ this._setScrollAutoMaxHeight(`${Math.round(visible * rowH)}px`);
428
+ }
429
+ _setScrollAutoMaxHeight(value) {
430
+ if (value === this._scrollAutoMaxHeight) return;
431
+ queueMicrotask(() => {
432
+ this._scrollAutoMaxHeight = value;
433
+ });
434
+ }
435
+ _setCssClass(value) {
436
+ if (value == null) {
437
+ this.cssClass = {};
438
+ this.cssClassName = "";
439
+ return;
440
+ }
441
+ if (typeof value === "object") {
442
+ this.cssClass = value;
443
+ return;
444
+ }
445
+ if (typeof value === "string") {
446
+ const trimmed = value.trim();
447
+ if (!trimmed) {
448
+ this.cssClass = {};
449
+ this.cssClassName = "";
450
+ return;
451
+ }
452
+ /**
453
+ * Optional HTML object support:
454
+ * <mono-select css-class='{"root":"...", "trigger":"..."}'>
455
+ */
456
+ if (trimmed.startsWith("{") && trimmed.endsWith("}")) try {
457
+ this.cssClass = JSON.parse(trimmed);
458
+ return;
459
+ } catch {}
460
+ this.cssClassName = trimmed;
461
+ }
462
+ }
463
+ _toSelectValue(value) {
464
+ if (value === void 0 || value === null) return null;
465
+ if (typeof value !== "string") return value;
466
+ const trimmed = value.trim();
467
+ if (!trimmed) return null;
468
+ if (/^-?\d+(?:\.\d+)?$/.test(trimmed) || trimmed === "true" || trimmed === "false" || trimmed === "null" || trimmed[0] === "{" && trimmed[trimmed.length - 1] === "}" || trimmed[0] === "[" && trimmed[trimmed.length - 1] === "]" || trimmed[0] === "\"" && trimmed[trimmed.length - 1] === "\"") try {
469
+ return JSON.parse(trimmed);
470
+ } catch {}
471
+ return trimmed;
472
+ }
473
+ /**
474
+ * Wrap bare primitives so every row is an object, and pass objects through.
475
+ *
476
+ * The `.map()` used to be unconditional, which made this an ALLOCATION on the
477
+ * overwhelmingly common path (an array of objects, where the map is an identity
478
+ * function). It is read through `_normalizedItems` / `_visibleItems` / `_leafItems`
479
+ * several times per render, so at one select per table row it was the single
480
+ * hottest allocation in the component. The scan below is O(n) reads with no
481
+ * allocation, and returns the SAME array when nothing needs wrapping.
482
+ *
483
+ * Returning the input array is safe: every caller only reads
484
+ * (`find`/`filter`/`map`/`findIndex`/`length`), and `resolveSearchFields` takes its
485
+ * rows as `readonly unknown[]`. It also makes item identity STABLE across calls for
486
+ * primitive lists, which is the safe direction — see the note on
487
+ * `_initialActiveIndex`, which explains why it deliberately does not rely on that
488
+ * identity holding.
489
+ */
490
+ _normalizeItems(items) {
491
+ if (Array.isArray(items)) {
492
+ let needsWrap = false;
493
+ for (const item of items) if (typeof item !== "object" || item === null) {
494
+ needsWrap = true;
495
+ break;
496
+ }
497
+ if (!needsWrap) return items;
498
+ return items.map((item) => {
499
+ if (typeof item === "object" && item !== null) return item;
500
+ return { value: item };
501
+ });
502
+ }
503
+ if (typeof items === "string") try {
504
+ const parsed = JSON.parse(items);
505
+ return this._normalizeItems(parsed);
506
+ } catch {
507
+ return [];
508
+ }
509
+ return [];
510
+ }
511
+ /**
512
+ * Read `field` off an option row — PATH-AWARE, like every other field name in
513
+ * the library.
514
+ *
515
+ * A plain `field in item` was the old test, and it silently produced
516
+ * `undefined` for any nested accessor: an option list grouped by a navigation
517
+ * property (`$apply=groupby((PostBudget/Nama))` returns
518
+ * `{ PostBudget: { Nama: … } }`) has no top-level `"PostBudget.Nama"` key, so
519
+ * every option resolved to no value at all — selectable in appearance, inert in
520
+ * practice. `searchExpr`, table columns and summaries have always accepted
521
+ * these paths; a select's `key-value` / `display-value` now do too.
522
+ *
523
+ * The LITERAL key is still tried first, so a row that genuinely carries a
524
+ * dotted PROPERTY NAME keeps resolving exactly as it did — only a key that is
525
+ * absent falls through to being read as a path, which previously could only
526
+ * have yielded `undefined` anyway. Nothing that worked before changes.
527
+ */
528
+ _readField(item, field) {
529
+ if (field in item) return item[field];
530
+ return getFieldValue(item, field);
531
+ }
532
+ _resolveItemValue(item) {
533
+ if (item == null) return item;
534
+ if (typeof item !== "object") return item;
535
+ if (this.keyValue) return this._readField(item, this.keyValue);
536
+ return item;
537
+ }
538
+ _resolveItemDisplay(item) {
539
+ if (item == null) return "";
540
+ if (typeof this.displayValue === "function") return String(this.displayValue(item));
541
+ if (typeof this.displayValue === "string" && this.displayValue) {
542
+ if (typeof item !== "object") return "";
543
+ const value = this._readField(item, this.displayValue);
544
+ return value == null ? "" : String(value);
545
+ }
546
+ if (typeof item === "object" && "label" in item) {
547
+ const label = item.label;
548
+ return label == null ? "" : String(label);
549
+ }
550
+ if (typeof item === "object" && "value" in item) {
551
+ const value = item.value;
552
+ return value == null ? "" : String(value);
553
+ }
554
+ return String(item);
555
+ }
556
+ _looksLikeSerializedFunction(value) {
557
+ const trimmed = value.trim();
558
+ if (!trimmed) return false;
559
+ return /^(?:async\s+)?(?:function\b|\([^)]*\)\s*=>|[A-Za-z_$][\w$]*\s*=>)/.test(trimmed);
560
+ }
561
+ /**
562
+ * Value equality. With no `key-value` the whole item IS the value, so this is
563
+ * identity — with one correction that is load-bearing under Vue.
564
+ *
565
+ * The model round-trips through the consumer's `ref`, which hands the item back
566
+ * wrapped in a **reactive Proxy**; `items` normally stays raw, so `proxy === row`
567
+ * is false and the selected row stops resolving (blank field, no highlight).
568
+ * Comparing the raw targets restores it. Still identity, not deep equality:
569
+ * two distinct rows with equal contents remain different values.
570
+ */
571
+ _isSameValue(a, b) {
572
+ if (a === b) return true;
573
+ if (a == null || b == null) return false;
574
+ const rawA = unwrapReactive(a);
575
+ const rawB = unwrapReactive(b);
576
+ if (rawA === rawB) return true;
577
+ if (typeof rawA !== "object" || typeof rawB !== "object") return false;
578
+ return false;
579
+ }
580
+ _cls(base, key) {
581
+ const extra = this.cssClass?.[key];
582
+ return extra ? `${base} ${extra}` : base;
583
+ }
584
+ _toCssLength(value) {
585
+ if (value == null || value === "") return void 0;
586
+ if (typeof value === "number") return `${value}px`;
587
+ const trimmed = String(value).trim();
588
+ if (!trimmed) return void 0;
589
+ return /^-?\d+(?:\.\d+)?$/.test(trimmed) ? `${trimmed}px` : trimmed;
590
+ }
591
+ /**
592
+ * The WIDTH half of `dropdown`, on the panel.
593
+ *
594
+ * Split from the heights below because this component's popup is two elements: the panel owns
595
+ * the box and the border, its body does the scrolling. That split is also why select needs no
596
+ * `--_…-panel-max-h` custom property the way tag-input does — the popup controller's own cap
597
+ * (`--mono-popup-avail-h`) lives on the panel and the author's on the body, so the two writers
598
+ * never meet on one declaration.
599
+ *
600
+ * The panel is positioned `left: 0; right: 0` against the field, and a width on top of that is
601
+ * the over-constrained case, which CSS resolves by dropping `right` — so the panel keeps its
602
+ * left edge and takes this size.
603
+ */
604
+ get _dropdownPanelStyle() {
605
+ const style = {};
606
+ const panel = this.dropdown;
607
+ const width = toCssSize(panel?.width);
608
+ if (width) style.width = width;
609
+ const minWidth = toCssSize(panel?.minWidth);
610
+ if (minWidth) style["min-width"] = minWidth;
611
+ const maxWidth = toCssSize(panel?.maxWidth);
612
+ if (maxWidth) style["max-width"] = maxWidth;
613
+ return style;
614
+ }
615
+ /** The HEIGHT half of `dropdown`, on the scrolling body — see `_dropdownPanelStyle`. */
616
+ get _dropdownBodyStyle() {
617
+ const style = {};
618
+ const panel = this.dropdown;
619
+ const minHeight = toCssSize(panel?.minHeight);
620
+ if (minHeight) style.minHeight = minHeight;
621
+ const height = toCssSize(panel?.height) ?? this._toCssLength(this.dropdownHeight);
622
+ if (height) style.height = height;
623
+ const maxHeight = toCssSize(panel?.maxHeight) ?? this._toCssLength(this.dropdownMaxHeight);
624
+ if (maxHeight) style.maxHeight = maxHeight;
625
+ else if (height) style.maxHeight = height;
626
+ else if (this._scrollAutoMaxHeight) style.maxHeight = this._scrollAutoMaxHeight;
627
+ return style;
628
+ }
629
+ get _normalizedItems() {
630
+ if (this._normalizedMemo?.epoch !== this._itemsEpoch) this._normalizedMemo = {
631
+ epoch: this._itemsEpoch,
632
+ items: this._normalizeItems(this._ds.sourceItems)
633
+ };
634
+ return this._normalizedMemo.items;
635
+ }
636
+ /** Sanitised chunk size for array-mode paging (>= 1). */
637
+ get _pageSize() {
638
+ const n = Math.floor(Number(this.pageSize));
639
+ return Number.isFinite(n) && n > 0 ? n : 10;
640
+ }
641
+ /**
642
+ * The effective load-more mode. Off when unset/false; otherwise 'button' only
643
+ * for the explicit `load-more="button"`, and 'scroll' for everything else that
644
+ * enables it (bare attribute, empty string, `true`, or `"scroll"`). Scroll is
645
+ * the default so enabling load-more "just works" without picking a mode.
646
+ */
647
+ get _loadMoreMode() {
648
+ const v = this.loadMore;
649
+ if (v === void 0 || v === null || v === false) return void 0;
650
+ return v === "button" ? "button" : "scroll";
651
+ }
652
+ /**
653
+ * The rows to actually render — the controller's visible slice, normalized.
654
+ * (Array load-more reveals a chunk; DataSource mode accumulates pages.)
655
+ */
656
+ get _visibleItems() {
657
+ if (this._visibleMemo?.epoch !== this._itemsEpoch) this._visibleMemo = {
658
+ epoch: this._itemsEpoch,
659
+ items: this._normalizeItems(this._ds.visibleItems)
660
+ };
661
+ return this._visibleMemo.items;
662
+ }
663
+ get _selectedItem() {
664
+ return this._leafItems.find((item) => this._isSameValue(this._resolveItemValue(item), this.value));
665
+ }
666
+ /** Grouping is active when at least one display-group accessor is given. */
667
+ get _grouped() {
668
+ return Array.isArray(this.displayGroup) && this.displayGroup.length > 0;
669
+ }
670
+ /** A node is a group when its `groupItems` field holds an array. */
671
+ _isGroupNode(x) {
672
+ return !!x && typeof x === "object" && Array.isArray(x[this.groupItems]);
673
+ }
674
+ /** Descend `groupItems[0]` to the first leaf row — the group's representative. */
675
+ _firstLeaf(node) {
676
+ let cur = node;
677
+ let guard = 0;
678
+ while (this._isGroupNode(cur) && guard++ < 50) cur = cur[this.groupItems]?.[0];
679
+ return cur ?? void 0;
680
+ }
681
+ /** Resolve a group header's label from `displayGroup[level]` over a leaf row. */
682
+ _resolveGroupLabel(node, level) {
683
+ const accessor = this.displayGroup[level];
684
+ const leaf = this._firstLeaf(node);
685
+ if (typeof accessor === "function") return String(accessor(leaf ?? {}) ?? "");
686
+ if (typeof accessor === "string" && leaf && accessor in leaf) return String(leaf[accessor] ?? "");
687
+ const key = node[this.groupKey];
688
+ return key == null ? "" : String(key);
689
+ }
690
+ /** The string `display-group` entries — usable as server group/sort fields. */
691
+ _groupSortFields() {
692
+ return (this.displayGroup ?? []).filter((a) => typeof a === "string");
693
+ }
694
+ /** A `display-group` level's key for a row (string → field, function → call). */
695
+ _groupKeyOf(row, level) {
696
+ const accessor = this.displayGroup[level];
697
+ if (typeof accessor === "function") return accessor(row);
698
+ if (typeof accessor === "string") return row[accessor];
699
+ }
700
+ /**
701
+ * `group` mode: bucket flat rows into the nested `{ [groupKey], [groupItems] }`
702
+ * shape client-side, by `display-group` level. Buckets keep first-appearance
703
+ * order, so each group is contiguous and grows in place as more pages load.
704
+ */
705
+ _buildClientTree(rows) {
706
+ const build = (items, level) => {
707
+ if (level >= this.displayGroup.length) return items;
708
+ const buckets = /* @__PURE__ */ new Map();
709
+ for (const row of items) {
710
+ const key = this._groupKeyOf(row, level);
711
+ const ks = String(key);
712
+ let bucket = buckets.get(ks);
713
+ if (!bucket) buckets.set(ks, bucket = {
714
+ key,
715
+ rows: []
716
+ });
717
+ bucket.rows.push(row);
718
+ }
719
+ return [...buckets.values()].map((b) => ({
720
+ [this.groupKey]: b.key,
721
+ [this.groupItems]: build(b.rows, level + 1)
722
+ }));
723
+ };
724
+ return build(rows, 0);
725
+ }
726
+ /** The nested group nodes to render — built client-side in `group` mode. */
727
+ _groupNodes() {
728
+ if (this.group) {
729
+ const leaves = this._visibleItems.filter((it) => this._searchMatches(it));
730
+ return this._buildClientTree(leaves);
731
+ }
732
+ return this._ds.visibleItems ?? [];
733
+ }
734
+ /** Every leaf row — for value/display lookup. */
735
+ get _leafItems() {
736
+ if (this._leafMemo?.epoch === this._itemsEpoch) return this._leafMemo.items;
737
+ const items = this._computeLeafItems();
738
+ this._leafMemo = {
739
+ epoch: this._itemsEpoch,
740
+ items
741
+ };
742
+ return items;
743
+ }
744
+ _computeLeafItems() {
745
+ if (!this._grouped) return this._normalizedItems;
746
+ if (this.group) return [...this._ds.sourceItems];
747
+ const out = [];
748
+ const walk = (nodes) => {
749
+ for (const n of nodes) if (this._isGroupNode(n)) walk(n[this.groupItems]);
750
+ else if (n != null) out.push(n);
751
+ };
752
+ walk(this._ds.sourceItems ?? []);
753
+ return out;
754
+ }
755
+ /**
756
+ * Flatten the visible group tree into ordered header / item render rows.
757
+ * Leaves are search-filtered (client mode); empty groups are dropped.
758
+ */
759
+ _groupRows() {
760
+ const filterLeaves = !this.group;
761
+ const build = (nodes, level, parentKey) => {
762
+ const rows = [];
763
+ nodes.forEach((node, i) => {
764
+ if (!this._isGroupNode(node)) {
765
+ const item = node;
766
+ if (item == null) return;
767
+ if (filterLeaves && !this._searchMatches(item)) return;
768
+ rows.push({
769
+ kind: "item",
770
+ item,
771
+ index: -1
772
+ });
773
+ return;
774
+ }
775
+ const rec = node;
776
+ const path = `${parentKey}/${String(rec[this.groupKey])}#${i}`;
777
+ const children = build(rec[this.groupItems] ?? [], level + 1, path);
778
+ if (!children.length) return;
779
+ rows.push({
780
+ kind: "group",
781
+ level,
782
+ label: this._resolveGroupLabel(rec, level),
783
+ key: `g:${level}:${path}`
784
+ });
785
+ rows.push(...children);
786
+ });
787
+ return rows;
788
+ };
789
+ let idx = 0;
790
+ return build(this._groupNodes(), 0, "").map((r) => r.kind === "item" ? {
791
+ ...r,
792
+ index: idx++
793
+ } : r);
794
+ }
795
+ /** Whether `search-value` names anything explicitly (vs falling back). */
796
+ get _hasSearchValue() {
797
+ const sv = this.searchValue;
798
+ if (Array.isArray(sv)) return sv.length > 0;
799
+ return typeof sv === "string" && !!sv.trim();
800
+ }
801
+ /**
802
+ * The natural fields searched alongside the `'*'` default when `search-value` is
803
+ * empty — the safety net, not the whole list.
804
+ *
805
+ * `'*'` resolves against loaded rows, so on a bound DataSource it expands to
806
+ * NOTHING until the first page lands (nothing loads on open, and a query can
807
+ * fire inside the debounce) — these keep that first query working. They are also
808
+ * exempt from the remote string-only rule, so a numeric `key-value` stays
809
+ * searchable. `display-value` contributes only when it's a string; a function
810
+ * builds text that no field expression can reach, which is why `_searchMatches`
811
+ * keeps matching the rendered display separately.
812
+ */
813
+ _fallbackSearchFields() {
814
+ return [typeof this.displayValue === "string" ? this.displayValue : void 0, this.keyValue];
815
+ }
816
+ /**
817
+ * A cheap signature of the rows' SHAPE, for the memo keys below.
818
+ *
819
+ * Row count alone isn't enough once `'*'` is in play: the resolved field list
820
+ * depends on the rows' keys, and a remote source paging from one full page to
821
+ * the next keeps the same length while the shape can differ. Sampling the first
822
+ * and last row keeps this O(1) while catching that case.
823
+ */
824
+ _rowsShapeKey(rows) {
825
+ const keysOf = (row) => row && typeof row === "object" ? Object.keys(row).join(",") : typeof row;
826
+ if (!rows.length) return "0";
827
+ return `${rows.length}:${keysOf(rows[0])}|${keysOf(rows[rows.length - 1])}`;
828
+ }
829
+ /**
830
+ * `search-value` resolved to concrete entries — `*` patterns expanded against
831
+ * the loaded rows. Memoized: a pattern samples up to 20 rows, so resolving per
832
+ * item (this feeds `_searchMatches`) would be O(items × fields) per keystroke.
833
+ *
834
+ * With no `search-value` this defaults to `'*'` (every top-level field) plus the
835
+ * natural fallbacks — see {@link _fallbackSearchFields}.
836
+ */
837
+ _searchEntries(remote) {
838
+ const rows = this._normalizedItems;
839
+ const key = `${this._searchVersion} ${remote ? 1 : 0} ${this._rowsShapeKey(rows)}`;
840
+ if (this._entriesCache?.key === key) return this._entriesCache.entries;
841
+ const entries = resolveSearchFields({
842
+ searchValue: this.searchValue,
843
+ fallbackFields: this._fallbackSearchFields(),
844
+ rows,
845
+ remote,
846
+ defaultToWildcard: true
847
+ });
848
+ this._entriesCache = {
849
+ key,
850
+ entries
851
+ };
852
+ return entries;
853
+ }
854
+ /** The compiled client-side predicate for the current query (memoized). */
855
+ _searchPredicate() {
856
+ const query = this._query.trim();
857
+ const operation = this.searchOperation || "contains";
858
+ const rows = this._normalizedItems;
859
+ const key = `${this._searchVersion} ${operation} ${this._rowsShapeKey(rows)} ${query}`;
860
+ if (this._predicateCache?.key === key) return this._predicateCache.pred;
861
+ const pred = searchRowPredicate(this._searchEntries(false), query, operation);
862
+ this._predicateCache = {
863
+ key,
864
+ pred
865
+ };
866
+ return pred;
867
+ }
868
+ /** A bound DataSource is searched on the server; a plain array, client-side. */
869
+ _serverSearch() {
870
+ return !!this.dataSource;
871
+ }
872
+ /** Client-side match test (server mode already filtered → always true). */
873
+ _searchMatches(item) {
874
+ if (this._serverSearch()) return true;
875
+ if (!this._searchActive) return true;
876
+ const q = this._query.trim().toLowerCase();
877
+ if (!q) return true;
878
+ if (this._hasSearchValue) {
879
+ const pred = this._searchPredicate();
880
+ return pred ? pred(item) : true;
881
+ }
882
+ const display = this._resolveItemDisplay(item).toLowerCase();
883
+ const val = this._resolveItemValue(item);
884
+ const valStr = val == null ? "" : String(val).toLowerCase();
885
+ const pred = this._searchPredicate();
886
+ return display.includes(q) || valStr.includes(q) || (pred ? pred(item) : false);
887
+ }
888
+ _onSearchInput(event) {
889
+ if (this.disabled || this.readonly) return;
890
+ this._query = event.target.value;
891
+ this._searchActive = true;
892
+ this._open = true;
893
+ this._activeIndex = 0;
894
+ this._cursorPending = false;
895
+ this.requestUpdate();
896
+ if (this._searchTimer) clearTimeout(this._searchTimer);
897
+ const wait = Math.max(0, Number(this.searchDebounce) || 0);
898
+ this._searchTimer = setTimeout(() => void this._applySearch(this._query), wait);
899
+ }
900
+ /** Run the search: server query (debounced) or just re-render for client filter. */
901
+ async _applySearch(query) {
902
+ if (!this._serverSearch()) {
903
+ this.requestUpdate();
904
+ return;
905
+ }
906
+ await this._sourceSearch.apply(this.dataSource, {
907
+ query,
908
+ searchValue: this.searchValue,
909
+ fallbackFields: this._fallbackSearchFields(),
910
+ rows: this._normalizedItems,
911
+ remote: true,
912
+ defaultToWildcard: true,
913
+ operation: this.searchOperation || "contains"
914
+ });
915
+ }
916
+ /** Clear the typed query (and the source query, on close / select). */
917
+ _resetSearch() {
918
+ if (this._searchTimer) {
919
+ clearTimeout(this._searchTimer);
920
+ this._searchTimer = void 0;
921
+ }
922
+ const had = this._searchActive && !!this._query;
923
+ this._query = "";
924
+ this._searchActive = false;
925
+ this._activeIndex = -1;
926
+ if (had && this._serverSearch()) this._applySearch("");
927
+ }
928
+ /** The label shown in the field while not actively typing a query. */
929
+ get _displayText() {
930
+ const item = this._selectedItem;
931
+ return item ? this._resolveItemDisplay(item) : "";
932
+ }
933
+ /** Placeholder for the search field — a search hint while open, else the prompt. */
934
+ get _fieldPlaceholder() {
935
+ if ((this._open || this._searchActive) && this.searchPlaceholder) return this.searchPlaceholder;
936
+ return this.placeholder;
937
+ }
938
+ /**
939
+ * The selectable rows in render order — drives keyboard nav (`_activeIndex`)
940
+ * for the searchable combobox. Mirrors what `_renderItems` paints.
941
+ */
942
+ /**
943
+ * Where the keyboard cursor goes when the list opens: the row matching the
944
+ * current value, else the first row.
945
+ *
946
+ * Deliberately runs the SAME predicate that paints `.selected` in
947
+ * `_renderOption`, over `_filteredItems` — the very list ↑/↓ and Enter index
948
+ * into — so the cursor is guaranteed to land on the row drawn as selected.
949
+ * Going via `_selectedItem` + `indexOf` would not work: that searches
950
+ * `_leafItems`, an unfiltered/unpaged array whose `_normalizeItems` wraps
951
+ * primitives in fresh objects per call, so identity would not hold. Grouping
952
+ * needs no special case — `_groupRows()` numbers leaf rows only, which is
953
+ * exactly what `_filteredItems` reconstructs.
954
+ *
955
+ * `-1` when the list is empty; `0` when the selected row is not in it (a page
956
+ * the user hasn't scrolled to, or a server query that didn't return it), which
957
+ * is the behaviour this component has always had.
958
+ */
959
+ _initialActiveIndex() {
960
+ const items = this._filteredItems;
961
+ if (!items.length) return -1;
962
+ const index = items.findIndex((item) => this._isSameValue(this._resolveItemValue(item), this.value));
963
+ return index >= 0 ? index : 0;
964
+ }
965
+ get _filteredItems() {
966
+ if (this._grouped) return this._groupRows().filter((r) => r.kind === "item").map((r) => r.item);
967
+ return this._visibleItems.filter((item) => this._searchMatches(item));
968
+ }
969
+ get _hasValue() {
970
+ return this.value !== null && this.value !== void 0 && this.value !== "";
971
+ }
972
+ get _hasLabelSlot() {
973
+ return this._hasLabelSlotState;
974
+ }
975
+ get _hasHelperSlot() {
976
+ return this._hasHelperSlotState;
977
+ }
978
+ get _hasPrefixSlot() {
979
+ return this._hasPrefixSlotState;
980
+ }
981
+ get _hasSuffixSlot() {
982
+ return this._hasSuffixSlotState;
983
+ }
984
+ get _resolvedValidationState() {
985
+ if (this.validationState && this.validationState !== "default") return this.validationState;
986
+ if (this.errorMessage) return "invalid";
987
+ if (this.successMessage) return "valid";
988
+ return "default";
989
+ }
990
+ get _wrapperClasses() {
991
+ return [
992
+ "mono-select",
993
+ this.size,
994
+ this.color,
995
+ this.variant,
996
+ this._open ? "open" : "",
997
+ this.disabled ? "disabled" : "",
998
+ this.readonly ? "readonly" : "",
999
+ this._resolvedValidationState !== "default" ? `is-${this._resolvedValidationState}` : "",
1000
+ this._hasValue ? "has-value" : "",
1001
+ this._hasPrefixSlot ? "has-prefix" : "",
1002
+ this._hasSuffixSlot ? "has-suffix" : "",
1003
+ this.cssClassName,
1004
+ this.cssClass?.root
1005
+ ].filter(Boolean).join(" ");
1006
+ }
1007
+ get _triggerClasses() {
1008
+ return [
1009
+ this._cls("mono-select-trigger", "trigger"),
1010
+ this.size,
1011
+ this.color,
1012
+ this.variant,
1013
+ this.disabled ? "disabled" : "",
1014
+ this.readonly ? "readonly" : ""
1015
+ ].filter(Boolean).join(" ");
1016
+ }
1017
+ _createModelDetail(args) {
1018
+ return {
1019
+ modelValue: args.modelValue,
1020
+ currentValue: args.modelValue,
1021
+ oldValue: args.oldValue,
1022
+ value: args.modelValue,
1023
+ selectedItem: this._leafItems.find((item) => this._isSameValue(this._resolveItemValue(item), args.modelValue)),
1024
+ sourceEvent: args.sourceEvent
1025
+ };
1026
+ }
1027
+ _emitChange(detail) {
1028
+ dispatchMonoEvent(this, "change", detail);
1029
+ }
1030
+ _emitClear(detail) {
1031
+ dispatchMonoEvent(this, "clear", detail);
1032
+ }
1033
+ _toggleOpen(event) {
1034
+ event?.stopPropagation();
1035
+ if (this.disabled || this.readonly) return;
1036
+ if (this._open) this._close();
1037
+ else this._open = true;
1038
+ }
1039
+ _close() {
1040
+ this._open = false;
1041
+ this._resetSearch();
1042
+ }
1043
+ _handleTriggerKeydown(event) {
1044
+ if (this.disabled || this.readonly) return;
1045
+ if (!this._open) {
1046
+ if (event.key === "Enter" || event.key === " " || event.key === "ArrowDown") {
1047
+ event.preventDefault();
1048
+ this._open = true;
1049
+ return;
1050
+ }
1051
+ if (event.key === "Escape") {
1052
+ event.preventDefault();
1053
+ this._close();
1054
+ }
1055
+ return;
1056
+ }
1057
+ this._handleListKeydown(event);
1058
+ }
1059
+ /**
1060
+ * ↑/↓/Enter/Esc against the rendered list, shared by the trigger and the
1061
+ * search field so both modes navigate identically.
1062
+ */
1063
+ _handleListKeydown(event) {
1064
+ const items = this._filteredItems;
1065
+ if (event.key === "ArrowDown") {
1066
+ event.preventDefault();
1067
+ this._open = true;
1068
+ this._activeIndex = items.length ? Math.min(this._activeIndex + 1, items.length - 1) : -1;
1069
+ return true;
1070
+ }
1071
+ if (event.key === "ArrowUp") {
1072
+ event.preventDefault();
1073
+ this._activeIndex = items.length ? Math.max(this._activeIndex - 1, 0) : -1;
1074
+ return true;
1075
+ }
1076
+ if (event.key === "Enter") {
1077
+ const active = this._activeIndex >= 0 ? items[this._activeIndex] : void 0;
1078
+ if (!active) return false;
1079
+ event.preventDefault();
1080
+ if (!active.disabled) this._selectItem(active, event);
1081
+ return true;
1082
+ }
1083
+ if (event.key === "Escape") {
1084
+ event.preventDefault();
1085
+ this._close();
1086
+ return true;
1087
+ }
1088
+ return false;
1089
+ }
1090
+ /**
1091
+ * Focusing the field selects the shown label so the first keystroke replaces
1092
+ * it (type to filter). It does NOT open the dropdown: a Tab into the field is
1093
+ * not a request to see the list — typing, ↓, a click in the field or the
1094
+ * chevron are.
1095
+ */
1096
+ _handleSearchFocus(event) {
1097
+ if (this.disabled || this.readonly) return;
1098
+ event.target.select();
1099
+ }
1100
+ /**
1101
+ * Clicking anywhere in a SEARCHABLE field opens it and focuses the input.
1102
+ * Opens only — a click in a text input while the list is open is caret
1103
+ * placement or text selection, never a toggle; the chevron, Escape and an
1104
+ * outside click close. (The plain trigger is a button that toggles instead:
1105
+ * nothing to type there, so a second click means "close".)
1106
+ */
1107
+ _handleFieldClick(event) {
1108
+ event.stopPropagation();
1109
+ if (this.disabled || this.readonly) return;
1110
+ this._open = true;
1111
+ this._searchFieldEl?.focus();
1112
+ }
1113
+ /** Keyboard nav for the search field: arrows move, Enter selects, Esc closes. */
1114
+ _handleSearchKeydown(event) {
1115
+ if (this.disabled || this.readonly) return;
1116
+ this._handleListKeydown(event);
1117
+ }
1118
+ _selectItem(item, event) {
1119
+ event?.preventDefault();
1120
+ event?.stopPropagation();
1121
+ if (this.disabled || this.readonly || item.disabled) return;
1122
+ const oldValue = this.modelValue;
1123
+ const nextValue = this._resolveItemValue(item);
1124
+ this.value = nextValue;
1125
+ this.modelValue = nextValue;
1126
+ this._open = false;
1127
+ this._resetSearch();
1128
+ const detail = this._createModelDetail({
1129
+ modelValue: nextValue,
1130
+ oldValue,
1131
+ sourceEvent: event
1132
+ });
1133
+ this._emitChange(detail);
1134
+ if (this.searchable) this.updateComplete.then(() => this._searchFieldEl?.select());
1135
+ else this._triggerEl?.focus();
1136
+ }
1137
+ _clear(event) {
1138
+ event.preventDefault();
1139
+ event.stopPropagation();
1140
+ if (this.disabled || this.readonly) return;
1141
+ const oldValue = this.modelValue;
1142
+ const nextValue = null;
1143
+ this.value = nextValue;
1144
+ this.modelValue = nextValue;
1145
+ this._open = false;
1146
+ this._resetSearch();
1147
+ const detail = this._createModelDetail({
1148
+ modelValue: nextValue,
1149
+ oldValue,
1150
+ sourceEvent: event
1151
+ });
1152
+ this._emitChange(detail);
1153
+ this._emitClear(detail);
1154
+ if (this.searchable) this._searchFieldEl?.focus();
1155
+ }
1156
+ _renderLabel() {
1157
+ const hasContent = !!this.label || this._hasLabelSlot;
1158
+ if (!hasContent && !this._slotsAlwaysRender) return nothing;
1159
+ return html`
1160
+ <label
1161
+ class=${this._cls("mono-select-label", "label")}
1162
+ mono-label
1163
+ for=${this._selectId}
1164
+ ?mono-empty=${!hasContent}
1165
+ >
1166
+ ${this._slotOutlet("label", this.label)}
1167
+
1168
+ ${this.required ? html`
1169
+ <span class=${this._cls("mono-select-required", "required")} mono-required-mark>
1170
+ *
1171
+ </span>
1172
+ ` : nothing}
1173
+ </label>
1174
+ `;
1175
+ }
1176
+ _renderValue() {
1177
+ if (this._hasValue && this._selectedItem) return html`
1178
+ <span class=${this._cls("mono-select-value", "value")} mono-value>
1179
+ ${this._hasPrefixSlot || this._slotsAlwaysRender ? this._slotOutlet("prefix") : nothing}
1180
+
1181
+ <span>${this._resolveItemDisplay(this._selectedItem)}</span>
1182
+
1183
+ ${this._hasSuffixSlot || this._slotsAlwaysRender ? this._slotOutlet("suffix") : nothing}
1184
+ </span>
1185
+ `;
1186
+ return html`
1187
+ <span
1188
+ class=${`${this._cls("mono-select-value", "value")} ${this._cls("mono-select-placeholder", "placeholder")}`}
1189
+ mono-value
1190
+ mono-placeholder
1191
+ >
1192
+ ${this.placeholder}
1193
+ </span>
1194
+ `;
1195
+ }
1196
+ /** A single selectable option button. `index` drives the keyboard-active highlight. */
1197
+ _renderOption(item, index = -1) {
1198
+ const selected = this._isSameValue(this._resolveItemValue(item), this.value);
1199
+ const active = index >= 0 && index === this._activeIndex;
1200
+ return html`
1201
+ <button
1202
+ type="button"
1203
+ role="option"
1204
+ class=${[
1205
+ this._cls("mono-select-item", "item"),
1206
+ active ? `active ${this.cssClass?.itemActive ?? ""}` : "",
1207
+ selected ? `selected ${this.cssClass?.itemSelected ?? ""}` : "",
1208
+ item.disabled ? `disabled ${this.cssClass?.itemDisabled ?? ""}` : ""
1209
+ ].filter(Boolean).join(" ")}
1210
+ mono-item
1211
+ ?mono-active=${active}
1212
+ ?mono-selected=${selected}
1213
+ ?mono-disabled=${!!item.disabled}
1214
+ aria-selected=${selected ? "true" : "false"}
1215
+ ?disabled=${item.disabled}
1216
+ @mousedown=${(event) => event.preventDefault()}
1217
+ @click=${(event) => this._selectItem(item, event)}
1218
+ >
1219
+ ${this._resolveItemDisplay(item)}
1220
+ </button>
1221
+ `;
1222
+ }
1223
+ /**
1224
+ * The flat entry list published to `form.items()[key].list`.
1225
+ *
1226
+ * The SAME sequence the component renders — group headers interleaved with their leaves — so a
1227
+ * consumer looping it produces one node per row, in order, with nothing to pair up by hand.
1228
+ *
1229
+ * `key` is `item[keyValue]` via `_resolveItemValue`, the same value selection is keyed by, so
1230
+ * the feature introduces no second notion of a key.
1231
+ */
1232
+ _listEntries() {
1233
+ const rowEntry = (item, level, index) => ({
1234
+ type: "row",
1235
+ key: String(this._resolveItemValue(item) ?? ""),
1236
+ item,
1237
+ level,
1238
+ selected: this._isSameValue(this._resolveItemValue(item), this.value),
1239
+ active: index >= 0 && index === this._activeIndex
1240
+ });
1241
+ if (this._grouped) {
1242
+ const rows = this._groupRows();
1243
+ const leavesFrom = (start, level) => {
1244
+ const out = [];
1245
+ for (let i = start + 1; i < rows.length; i++) {
1246
+ const row = rows[i];
1247
+ if (row.kind === "group") {
1248
+ if (row.level <= level) break;
1249
+ continue;
1250
+ }
1251
+ out.push(row.item);
1252
+ }
1253
+ return out;
1254
+ };
1255
+ let rowLevel = 0;
1256
+ return rows.map((row, i) => {
1257
+ if (row.kind === "group") {
1258
+ rowLevel = row.level + 1;
1259
+ return {
1260
+ type: "group",
1261
+ key: row.key,
1262
+ label: row.label,
1263
+ level: row.level,
1264
+ items: leavesFrom(i, row.level)
1265
+ };
1266
+ }
1267
+ return rowEntry(row.item, rowLevel, row.index);
1268
+ });
1269
+ }
1270
+ return this._filteredItems.map((item, index) => rowEntry(item, 0, index));
1271
+ }
1272
+ /**
1273
+ * Hand the form the current entries — but only a NEW array when they actually moved.
1274
+ *
1275
+ * This runs from `updated()`, so it fires on every render; the controller notifies on a changed
1276
+ * list, and that notify re-renders this control. Returning the same array reference is what keeps
1277
+ * that from looping forever. Identity of `item` counts as a change: a reloaded DataSource hands
1278
+ * back fresh row objects under the same keys, and a consumer reading `e.item.Nama` must see them.
1279
+ */
1280
+ _syncListEntries() {
1281
+ const next = this._listEntries();
1282
+ const prev = this._publishedEntries;
1283
+ let same = prev.length === next.length;
1284
+ if (same) for (let i = 0; i < next.length; i++) {
1285
+ const a = prev[i];
1286
+ const b = next[i];
1287
+ if (a.type !== b.type || a.key !== b.key || a.item !== b.item || a.selected !== b.selected || a.active !== b.active) {
1288
+ same = false;
1289
+ break;
1290
+ }
1291
+ }
1292
+ if (same) return;
1293
+ this._publishedEntries = next;
1294
+ this._publishList(next);
1295
+ }
1296
+ /**
1297
+ * Where the consumer's `slot="list"` content goes — overridden per build.
1298
+ *
1299
+ * mono places that content as ONE block and never reaches inside it. Moving a `v-for`'s children
1300
+ * is not survivable: Vue inserts a new row with `parent.insertBefore(node, anchor)` where the
1301
+ * anchor is the existing node at that position, so relocating one makes the consumer's next
1302
+ * insert throw `NotFoundError`. Hence one block, and hence `data-mono-item-key` — with the rows
1303
+ * out of reach, a delegated click is the only way back to the item.
1304
+ */
1305
+ renderListSlot() {
1306
+ return html``;
1307
+ }
1308
+ /**
1309
+ * The entry a click landed on — by POSITION, so a consumer writes a plain `v-for` and nothing else.
1310
+ *
1311
+ * mono cannot read a node's item off the node: it published the list, but the DOM was built by
1312
+ * someone else. What it CAN do is count. The wrapper's Nth element child is the Nth published
1313
+ * entry, because that is the contract the slot already states — one flat loop, one node per entry,
1314
+ * in order — and here that contract is CHECKED rather than assumed: if the two lengths disagree,
1315
+ * this refuses the click instead of picking the wrong row.
1316
+ *
1317
+ * Position is resolved at CLICK time, never cached. That is what makes it safe with no observer
1318
+ * and no re-stamping: by the time a human clicks, the framework has long finished patching, so
1319
+ * there is no window where a stale pairing could be consulted.
1320
+ *
1321
+ * `data-mono-item-key` still wins when present — the escape hatch for a wrapper that cannot emit
1322
+ * exactly one element per entry (a sticky header of your own, a row that renders as a fragment).
1323
+ */
1324
+ /**
1325
+ * The consumer's `slot="list"` wrapper, wherever the build keeps it.
1326
+ *
1327
+ * The shadow build never moves it — it stays a light child of the host and is PROJECTED — so
1328
+ * that is the default. The light build moves it into the panel and overrides this with the node
1329
+ * it captured, which is also findable while the panel is closed and the wrapper parked.
1330
+ */
1331
+ get _listSlotWrapper() {
1332
+ return this._lateListSlot.find();
1333
+ }
1334
+ /**
1335
+ * Re-decorate whenever the consumer re-renders their rows.
1336
+ *
1337
+ * `_syncListChrome()` runs from `updated()`, but a framework patches the wrapper on ITS next
1338
+ * tick — so a row the search box just revealed would be born undecorated and stay that way until
1339
+ * something else made mono render. This closes that gap.
1340
+ *
1341
+ * `childList` on the WRAPPER, which is exactly the churn {@link LateSlotWatcher} refuses on the
1342
+ * host: there the consumer's row traffic is noise, here it IS the signal. No `subtree`, so
1343
+ * mono's own attribute writes cannot re-trigger it.
1344
+ */
1345
+ _watchListChrome() {
1346
+ if (typeof MutationObserver === "undefined") return;
1347
+ const wrapper = this._listSlotWrapper;
1348
+ if (!wrapper || wrapper === this._observedListWrapper) return;
1349
+ this._listChromeObserver?.disconnect();
1350
+ this._observedListWrapper = wrapper;
1351
+ this._listChromeObserver = new MutationObserver(() => this._syncListChrome());
1352
+ this._listChromeObserver.observe(wrapper, { childList: true });
1353
+ }
1354
+ _stopWatchingListChrome() {
1355
+ this._listChromeObserver?.disconnect();
1356
+ this._listChromeObserver = void 0;
1357
+ this._observedListWrapper = void 0;
1358
+ }
1359
+ /**
1360
+ * Decorate the lines the consumer rendered — the half of this feature that keeps the SLOT about
1361
+ * markup and mono about behaviour.
1362
+ *
1363
+ * Your template says what a line LOOKS like; the state it is in is stamped here, as `data-*`
1364
+ * attributes, so nothing in that template has to bind `e.selected` or `e.active` to say so.
1365
+ *
1366
+ * Where the tag input also injects a checkbox, this stops at the stamp: a select carries no
1367
+ * checkbox and no select-all, so there is no chrome to put anywhere.
1368
+ *
1369
+ * Three rules keep this safe beside a framework:
1370
+ * · children are ANNOTATED only, never moved, reordered or removed — every `insertBefore`
1371
+ * anchor a `v-for` patches against stays valid;
1372
+ * · `data-*` only, never `class` — `class` is the consumer's binding and would be clobbered;
1373
+ * · nothing is stamped unless the lines and the published entries match 1:1.
1374
+ */
1375
+ _syncListChrome() {
1376
+ if (!this._hasListSlotState) return;
1377
+ const wrapper = this._listSlotWrapper;
1378
+ if (!wrapper) return;
1379
+ const children = Array.from(wrapper.children);
1380
+ const entries = this._publishedEntries;
1381
+ if (children.length !== entries.length) return;
1382
+ for (let i = 0; i < children.length; i++) {
1383
+ const node = children[i];
1384
+ const entry = entries[i];
1385
+ node.setAttribute("data-mono-type", entry.type);
1386
+ node.setAttribute("data-mono-level", String(entry.level ?? 0));
1387
+ node.setAttribute("data-mono-key", entry.key);
1388
+ if (entry.type === "group") continue;
1389
+ node.toggleAttribute("data-mono-selected", !!entry.selected);
1390
+ node.toggleAttribute("data-mono-active", !!entry.active);
1391
+ }
1392
+ }
1393
+ _entryFromNode(node) {
1394
+ const keyed = node.closest?.("[data-mono-item-key]");
1395
+ if (keyed) {
1396
+ const key = keyed.getAttribute("data-mono-item-key");
1397
+ return this._publishedEntries.find((e) => e.type === "row" && e.key === key);
1398
+ }
1399
+ const wrapper = node.closest?.("[slot=\"list\"]");
1400
+ if (!wrapper) return void 0;
1401
+ let row = node;
1402
+ while (row && row.parentElement !== wrapper) row = row.parentElement;
1403
+ if (!row) return void 0;
1404
+ const children = Array.from(wrapper.children);
1405
+ if (children.length !== this._publishedEntries.length) {
1406
+ console.warn(`[mono-select] slot="list" rendered ${children.length} element(s) for ${this._publishedEntries.length} option(s), so a click cannot be paired with its row. Render exactly one element per entry, or put data-mono-item-key="<entry.key>" on each row.`);
1407
+ return;
1408
+ }
1409
+ const entry = this._publishedEntries[children.indexOf(row)];
1410
+ return entry?.type === "row" ? entry : void 0;
1411
+ }
1412
+ _emptyRow() {
1413
+ const text = this.dataSource && this._ds.loading ? "Loading…" : this._query ? "No matches" : "No items";
1414
+ return html`<div class=${this._cls("mono-select-item disabled", "itemDisabled")} mono-empty-row>${text}</div>`;
1415
+ }
1416
+ _renderItems() {
1417
+ if (this._hasListSlotState) return html`
1418
+ ${this._filteredItems.length ? nothing : this._emptyRow()}
1419
+ ${this.renderListSlot()}
1420
+ `;
1421
+ if (this._grouped) {
1422
+ const rows = this._groupRows();
1423
+ if (!rows.some((r) => r.kind === "item")) return this._emptyRow();
1424
+ return html`
1425
+ ${rows.map((row) => row.kind === "group" ? html`<div
1426
+ class=${`${this._cls("mono-select-group", "group")}${this.groupSticky ? " sticky" : ""}`}
1427
+ mono-group
1428
+ mono-level=${row.level}
1429
+ ?mono-sticky=${this.groupSticky}
1430
+ data-level=${row.level}
1431
+ role="presentation"
1432
+ >
1433
+ ${row.label}
1434
+ </div>` : this._renderOption(row.item, row.index))}
1435
+ `;
1436
+ }
1437
+ const items = this._visibleItems.filter((item) => this._searchMatches(item));
1438
+ if (!items.length) return this._emptyRow();
1439
+ return html`${items.map((item, index) => this._renderOption(item, index))}`;
1440
+ }
1441
+ _renderLoadMore() {
1442
+ if (!this._loadMoreMode) return nothing;
1443
+ if (!this._normalizedItems.length || this._ds.atLastPage) return nothing;
1444
+ if (this._ds.loadingMore) return html`
1445
+ <div class=${`${this._cls("mono-select-load-more", "loadMore")} loading`} mono-load-more mono-loading>
1446
+ Loading…
1447
+ </div>
1448
+ `;
1449
+ if (this._loadMoreMode !== "button") return nothing;
1450
+ return html`
1451
+ <button
1452
+ type="button"
1453
+ class=${this._cls("mono-select-load-more", "loadMore")}
1454
+ mono-load-more
1455
+ @click=${(event) => {
1456
+ event.preventDefault();
1457
+ event.stopPropagation();
1458
+ this._ds.loadMore();
1459
+ }}
1460
+ >
1461
+ Load more
1462
+ </button>
1463
+ `;
1464
+ }
1465
+ _renderHelper() {
1466
+ const base = this._cls("mono-select-message", "message");
1467
+ if (this.validationMessage) {
1468
+ const state = this._resolvedValidationState;
1469
+ return html`
1470
+ <div class=${`${base} ${state}`} mono-message=${state} role=${state === "invalid" ? "alert" : nothing}>
1471
+ ${this.validationMessage}
1472
+ </div>
1473
+ `;
1474
+ }
1475
+ if (this.errorMessage) return html`
1476
+ <div class=${`${base} invalid`} mono-message="invalid" role="alert">
1477
+ ${this.errorMessage}
1478
+ </div>
1479
+ `;
1480
+ if (this.successMessage) return html`
1481
+ <div class=${`${base} valid`} mono-message="valid">
1482
+ ${this.successMessage}
1483
+ </div>
1484
+ `;
1485
+ if (this.helperText || this._hasHelperSlot || this._slotsAlwaysRender) return html`
1486
+ <div
1487
+ class=${`${base} helper`}
1488
+ mono-message="helper"
1489
+ ?mono-empty=${!this.helperText && !this._hasHelperSlot}
1490
+ >
1491
+ ${this._slotOutlet("helper", this.helperText)}
1492
+ </div>
1493
+ `;
1494
+ return nothing;
1495
+ }
1496
+ /** Shared clear (×) / chevron action. `toggleArrow` lets the chevron close an
1497
+ * already-open dropdown in the searchable field (the plain button toggles itself).
1498
+ *
1499
+ * ONE glyph, matching `<mono-tag-input>` and `<mono-dropdown-table>`: with a
1500
+ * clearable value the corner shows `✕` alone — clearing is the useful action
1501
+ * then, and the chevron would only say what the value already says. Without a
1502
+ * value (or `clearable` off) the chevron is alone. `disabled` / `readonly`
1503
+ * show NEITHER: the field refuses every gesture, so a chevron would promise an
1504
+ * open it never delivers. The actions span still renders so the gutter — and
1505
+ * the text beside it — stays put when the state toggles.
1506
+ *
1507
+ * THE VALUE WINS over the open state. On a searchable field the chevron is the
1508
+ * only mouse way to CLOSE — the body OPENS but never closes there (a click in a
1509
+ * text input is caret placement, not a toggle) — and it was once kept beside
1510
+ * `✕` for exactly that reason. The rule now is the simpler one: while there is
1511
+ * something to clear there is no chevron, open or closed; a searchable field
1512
+ * with a value closes by picking, Escape or an outside click. `role="button"`
1513
+ * on a span, not a `<button>`: the plain trigger is itself a button and buttons
1514
+ * do not nest. `mousedown.preventDefault` keeps focus where it is (the search
1515
+ * input); `_toggleOpen` stops propagation so the plain trigger does not toggle
1516
+ * a second time. */
1517
+ _renderActions() {
1518
+ const inert = this.disabled || this.readonly;
1519
+ const canClear = this.clearable && this._hasValue && !inert;
1520
+ const showArrow = !inert && !canClear;
1521
+ return html`
1522
+ <span class=${this._cls("mono-select-actions", "actions")} mono-actions>
1523
+ ${canClear ? html`
1524
+ <span
1525
+ role="button"
1526
+ tabindex="-1"
1527
+ class=${this._cls("mono-select-clear", "clear")}
1528
+ mono-clear
1529
+ aria-label="Clear select"
1530
+ @mousedown=${(event) => event.preventDefault()}
1531
+ @click=${this._clear}
1532
+ >
1533
+ ${this.renderIcon("close")}
1534
+ </span>
1535
+ ` : nothing}
1536
+ ${showArrow ? html`
1537
+ <span
1538
+ role="button"
1539
+ tabindex="-1"
1540
+ class=${this._cls("mono-select-arrow", "arrow")}
1541
+ mono-arrow
1542
+ aria-label="Toggle options"
1543
+ aria-expanded=${this._open ? "true" : "false"}
1544
+ @mousedown=${(event) => event.preventDefault()}
1545
+ @click=${this._toggleOpen}
1546
+ >
1547
+ ${this.renderIcon("chevron")}
1548
+ </span>
1549
+ ` : nothing}
1550
+ </span>
1551
+ `;
1552
+ }
1553
+ /** Plain trigger: a button showing the selected value (non-searchable). */
1554
+ _renderButtonTrigger(ariaLabel, describedBy) {
1555
+ return html`
1556
+ <button
1557
+ id=${this._selectId}
1558
+ type="button"
1559
+ class=${this._triggerClasses}
1560
+ mono-trigger
1561
+ ?disabled=${this.disabled}
1562
+ aria-haspopup="listbox"
1563
+ aria-expanded=${this._open ? "true" : "false"}
1564
+ aria-controls=${this._listboxId}
1565
+ aria-label=${ifDefined(ariaLabel)}
1566
+ aria-describedby=${ifDefined(describedBy)}
1567
+ @click=${this._toggleOpen}
1568
+ @keydown=${this._handleTriggerKeydown}
1569
+ >
1570
+ ${this._renderValue()}
1571
+ ${this._renderActions()}
1572
+ </button>
1573
+ `;
1574
+ }
1575
+ /** Searchable trigger: the field itself is a search input (combobox). */
1576
+ _renderSearchTrigger(ariaLabel, describedBy) {
1577
+ return html`
1578
+ <div class=${this._triggerClasses} mono-trigger @click=${this._handleFieldClick}>
1579
+ <input
1580
+ id=${this._selectId}
1581
+ class=${this._cls("mono-select-search-field", "searchField")}
1582
+ mono-search-field
1583
+ type="text"
1584
+ role="combobox"
1585
+ autocomplete="off"
1586
+ aria-haspopup="listbox"
1587
+ aria-expanded=${this._open ? "true" : "false"}
1588
+ aria-controls=${this._listboxId}
1589
+ aria-label=${ifDefined(ariaLabel)}
1590
+ aria-describedby=${ifDefined(describedBy)}
1591
+ .value=${this._searchActive ? this._query : this._displayText}
1592
+ placeholder=${this._fieldPlaceholder}
1593
+ ?disabled=${this.disabled}
1594
+ ?readonly=${this.readonly}
1595
+ @input=${this._onSearchInput}
1596
+ @focus=${this._handleSearchFocus}
1597
+ @keydown=${this._handleSearchKeydown}
1598
+ />
1599
+ ${this._renderActions()}
1600
+ </div>
1601
+ `;
1602
+ }
1603
+ /** Inline sizing applied to the root wrapper. */
1604
+ _sizeStyle() {
1605
+ return buildSizeStyle(this);
1606
+ }
1607
+ render() {
1608
+ const describedBy = this.validationMessage || this.errorMessage || this.successMessage || this.helperText || this._hasHelperSlot ? this._messageId : void 0;
1609
+ const ariaLabel = this.ariaLabelText || this.label || this.placeholder || void 0;
1610
+ const state = this._resolvedValidationState;
1611
+ return html`
1612
+ <div
1613
+ class=${this._wrapperClasses}
1614
+ style=${styleMap(this._sizeStyle())}
1615
+ mono-select
1616
+ mono-size=${this.size === "md" ? nothing : this.size}
1617
+ mono-color=${this.color === "primary" ? nothing : this.color}
1618
+ mono-variant=${this.variant === "outlined" ? nothing : this.variant}
1619
+ mono-validation-state=${state === "default" ? nothing : state}
1620
+ ?mono-open=${this._open}
1621
+ ?mono-disabled=${this.disabled}
1622
+ ?mono-readonly=${this.readonly}
1623
+ ?mono-required=${this.required}
1624
+ ?mono-clearable=${this.clearable}
1625
+ ?mono-searchable=${this.searchable}
1626
+ >
1627
+ ${this._renderLabel()}
1628
+
1629
+ ${this.searchable ? this._renderSearchTrigger(ariaLabel, describedBy) : this._renderButtonTrigger(ariaLabel, describedBy)}
1630
+
1631
+ <div
1632
+ id=${this._listboxId}
1633
+ role="listbox"
1634
+ class=${this._cls("mono-select-dropdown", "dropdown")}
1635
+ mono-dropdown
1636
+ style=${styleMap(this._dropdownPanelStyle)}
1637
+ >
1638
+ <div
1639
+ class=${this._cls("mono-select-dropdown-body", "dropdownBody")}
1640
+ mono-dropdown-body
1641
+ style=${styleMap(this._dropdownBodyStyle)}
1642
+ @scroll=${this._handleDropdownScroll}
1643
+ >
1644
+ ${this._open ? this._renderItems() : nothing}
1645
+ ${this._open ? this._renderLoadMore() : nothing}
1646
+ </div>
1647
+ </div>
1648
+
1649
+ <div id=${this._messageId} class=${this.cssClass?.messageWrap ?? ""} mono-message-wrap>
1650
+ ${this._renderHelper()}
1651
+ </div>
1652
+ </div>
1653
+ `;
1654
+ }
1655
+ focus(options) {
1656
+ if (this.searchable) this._searchFieldEl?.focus(options);
1657
+ else this._triggerEl?.focus(options);
1658
+ }
1659
+ blur() {
1660
+ if (this.searchable) this._searchFieldEl?.blur();
1661
+ else this._triggerEl?.blur();
1662
+ }
1663
+ /** Whether the dropdown panel is currently open. */
1664
+ get isOpen() {
1665
+ return this._open;
1666
+ }
1667
+ open() {
1668
+ if (this.disabled || this.readonly) return;
1669
+ this._open = true;
1670
+ }
1671
+ close() {
1672
+ this._close();
1673
+ }
1674
+ toggle() {
1675
+ if (this.disabled || this.readonly) return;
1676
+ if (this._open) this._close();
1677
+ else this._open = true;
1678
+ }
1679
+ /** Coerce a possibly-stringy SSR value to a real boolean (matches
1680
+ * `booleanStringConverter`: a bare / empty attribute means present → true). */
1681
+ _toBoolean(value) {
1682
+ if (typeof value === "boolean") return value;
1683
+ if (value == null) return false;
1684
+ const s = String(value).toLowerCase().trim();
1685
+ return s === "" || s === "true";
1686
+ }
1687
+ /** Whether the slot regions render even when empty. Light: no (omit empty
1688
+ * regions). Shadow: yes — the native `<slot>`s must exist to project DSD
1689
+ * content + be scanned (hidden via `[mono-empty]` when empty). */
1690
+ get _slotsAlwaysRender() {
1691
+ return false;
1692
+ }
1693
+ _hasSlot(name) {
1694
+ return name === "label" ? this._hasLabelSlotState : name === "helper" ? this._hasHelperSlotState : name === "prefix" ? this._hasPrefixSlotState : name === "suffix" ? this._hasSuffixSlotState : this._hasListSlotState;
1695
+ }
1696
+ _setSlotState(name, has) {
1697
+ if (name === "label") this._hasLabelSlotState = has;
1698
+ else if (name === "helper") this._hasHelperSlotState = has;
1699
+ else if (name === "prefix") this._hasPrefixSlotState = has;
1700
+ else if (name === "suffix") this._hasSuffixSlotState = has;
1701
+ else this._hasListSlotState = has;
1702
+ }
1703
+ /**
1704
+ * Slot outlet. Light build (default): a `data-mono-slot` placeholder the
1705
+ * captured light-DOM nodes are re-parented into when present, else the prop
1706
+ * `fallback`. Shadow build overrides this with a native `<slot name>` that
1707
+ * carries the fallback as native slot content.
1708
+ */
1709
+ _slotOutlet(name, fallback = nothing) {
1710
+ return this._hasSlot(name) ? html`<span data-mono-slot=${name}></span>` : html`${fallback}`;
1711
+ }
1712
+ /**
1713
+ * Icon hook. Light build (default): the global `.mono-icon` / `i-mdi-*` UnoCSS
1714
+ * icon. Shadow overrides with inline SVG (UnoCSS can't reach a shadow root).
1715
+ */
1716
+ renderIcon(name) {
1717
+ return html`<span class=${`mono-icon ${name === "close" ? "i-mdi-close" : "i-mdi-chevron-down"}`} mono-icon aria-hidden="true"></span>`;
1718
+ }
1719
+ }
1720
+ __decorate([property({ type: String })], MonoSelectCoreClass.prototype, "size", void 0);
1721
+ __decorate([property({ type: String })], MonoSelectCoreClass.prototype, "color", void 0);
1722
+ __decorate([property({ type: String })], MonoSelectCoreClass.prototype, "variant", void 0);
1723
+ __decorate([property({ attribute: false })], MonoSelectCoreClass.prototype, "modelValue", void 0);
1724
+ __decorate([property({ attribute: false })], MonoSelectCoreClass.prototype, "value", void 0);
1725
+ __decorate([property({ type: String })], MonoSelectCoreClass.prototype, "name", void 0);
1726
+ __decorate([property({ type: String })], MonoSelectCoreClass.prototype, "label", void 0);
1727
+ __decorate([property({ type: String })], MonoSelectCoreClass.prototype, "placeholder", void 0);
1728
+ __decorate([property({
1729
+ type: String,
1730
+ attribute: "helper-text"
1731
+ })], MonoSelectCoreClass.prototype, "helperText", void 0);
1732
+ __decorate([property({
1733
+ type: String,
1734
+ attribute: "validation-state"
1735
+ })], MonoSelectCoreClass.prototype, "validationState", void 0);
1736
+ __decorate([property({
1737
+ type: String,
1738
+ attribute: "validation-message"
1739
+ })], MonoSelectCoreClass.prototype, "validationMessage", void 0);
1740
+ __decorate([property({
1741
+ type: String,
1742
+ attribute: "error-message"
1743
+ })], MonoSelectCoreClass.prototype, "errorMessage", void 0);
1744
+ __decorate([property({
1745
+ type: String,
1746
+ attribute: "success-message"
1747
+ })], MonoSelectCoreClass.prototype, "successMessage", void 0);
1748
+ __decorate([property({
1749
+ type: String,
1750
+ attribute: "aria-label"
1751
+ })], MonoSelectCoreClass.prototype, "ariaLabelText", void 0);
1752
+ __decorate([property({
1753
+ reflect: true,
1754
+ converter: booleanStringConverter
1755
+ })], MonoSelectCoreClass.prototype, "disabled", void 0);
1756
+ __decorate([property({
1757
+ reflect: true,
1758
+ converter: booleanStringConverter
1759
+ })], MonoSelectCoreClass.prototype, "readonly", void 0);
1760
+ __decorate([property({
1761
+ reflect: true,
1762
+ converter: booleanStringConverter
1763
+ })], MonoSelectCoreClass.prototype, "required", void 0);
1764
+ __decorate([property({
1765
+ reflect: true,
1766
+ converter: booleanStringConverter
1767
+ })], MonoSelectCoreClass.prototype, "clearable", void 0);
1768
+ __decorate([property({
1769
+ attribute: false,
1770
+ hasChanged: arrayHasChanged
1771
+ })], MonoSelectCoreClass.prototype, "items", void 0);
1772
+ __decorate([property({ attribute: false })], MonoSelectCoreClass.prototype, "dataSource", void 0);
1773
+ __decorate([property({
1774
+ attribute: "immediate",
1775
+ reflect: true,
1776
+ converter: booleanStringConverter
1777
+ })], MonoSelectCoreClass.prototype, "immediate", void 0);
1778
+ __decorate([property({
1779
+ attribute: "load-more",
1780
+ reflect: true
1781
+ })], MonoSelectCoreClass.prototype, "loadMore", void 0);
1782
+ __decorate([property({
1783
+ attribute: "page-size",
1784
+ reflect: true,
1785
+ type: Number
1786
+ })], MonoSelectCoreClass.prototype, "pageSize", void 0);
1787
+ __decorate([property({ attribute: false })], MonoSelectCoreClass.prototype, "dropdown", void 0);
1788
+ __decorate([property({
1789
+ attribute: "dropdown-height",
1790
+ reflect: true
1791
+ })], MonoSelectCoreClass.prototype, "dropdownHeight", void 0);
1792
+ __decorate([property({
1793
+ attribute: "dropdown-max-height",
1794
+ reflect: true
1795
+ })], MonoSelectCoreClass.prototype, "dropdownMaxHeight", void 0);
1796
+ __decorate([property({ converter: booleanStringConverter })], MonoSelectCoreClass.prototype, "flip", void 0);
1797
+ __decorate([property({ converter: booleanStringConverter })], MonoSelectCoreClass.prototype, "shift", void 0);
1798
+ __decorate([property({
1799
+ type: String,
1800
+ attribute: "key-value",
1801
+ reflect: true
1802
+ })], MonoSelectCoreClass.prototype, "keyValue", void 0);
1803
+ __decorate([property({ attribute: false })], MonoSelectCoreClass.prototype, "displayValue", void 0);
1804
+ __decorate([property({
1805
+ attribute: false,
1806
+ hasChanged: arrayHasChanged
1807
+ })], MonoSelectCoreClass.prototype, "displayGroup", void 0);
1808
+ __decorate([property({
1809
+ type: String,
1810
+ attribute: "group-key",
1811
+ reflect: true
1812
+ })], MonoSelectCoreClass.prototype, "groupKey", void 0);
1813
+ __decorate([property({
1814
+ type: String,
1815
+ attribute: "group-items",
1816
+ reflect: true
1817
+ })], MonoSelectCoreClass.prototype, "groupItems", void 0);
1818
+ __decorate([property({
1819
+ attribute: "group",
1820
+ reflect: true,
1821
+ converter: booleanStringConverter
1822
+ })], MonoSelectCoreClass.prototype, "group", void 0);
1823
+ __decorate([property({
1824
+ attribute: "group-sticky",
1825
+ reflect: true,
1826
+ converter: booleanStringConverter
1827
+ })], MonoSelectCoreClass.prototype, "groupSticky", void 0);
1828
+ __decorate([property({
1829
+ attribute: "searchable",
1830
+ reflect: true,
1831
+ converter: booleanStringConverter
1832
+ })], MonoSelectCoreClass.prototype, "searchable", void 0);
1833
+ __decorate([property({
1834
+ attribute: "stay-open",
1835
+ reflect: true,
1836
+ converter: booleanStringConverter
1837
+ })], MonoSelectCoreClass.prototype, "stayOpen", void 0);
1838
+ __decorate([property({
1839
+ attribute: "search-value",
1840
+ hasChanged: arrayHasChanged
1841
+ })], MonoSelectCoreClass.prototype, "searchValue", void 0);
1842
+ __decorate([property({
1843
+ type: String,
1844
+ attribute: "search-operation"
1845
+ })], MonoSelectCoreClass.prototype, "searchOperation", void 0);
1846
+ __decorate([property({
1847
+ attribute: "search-debounce",
1848
+ type: Number
1849
+ })], MonoSelectCoreClass.prototype, "searchDebounce", void 0);
1850
+ __decorate([property({
1851
+ type: String,
1852
+ attribute: "search-placeholder"
1853
+ })], MonoSelectCoreClass.prototype, "searchPlaceholder", void 0);
1854
+ __decorate([property({
1855
+ attribute: false,
1856
+ hasChanged: rateLimitHasChanged
1857
+ })], MonoSelectCoreClass.prototype, "cssClass", void 0);
1858
+ __decorate([property({ attribute: false })], MonoSelectCoreClass.prototype, "cssClassName", void 0);
1859
+ __decorate([state()], MonoSelectCoreClass.prototype, "_open", void 0);
1860
+ __decorate([state()], MonoSelectCoreClass.prototype, "_query", void 0);
1861
+ __decorate([state()], MonoSelectCoreClass.prototype, "_searchActive", void 0);
1862
+ __decorate([state()], MonoSelectCoreClass.prototype, "_activeIndex", void 0);
1863
+ __decorate([state()], MonoSelectCoreClass.prototype, "_scrollAutoMaxHeight", void 0);
1864
+ __decorate([state()], MonoSelectCoreClass.prototype, "_hasLabelSlotState", void 0);
1865
+ __decorate([state()], MonoSelectCoreClass.prototype, "_hasHelperSlotState", void 0);
1866
+ __decorate([state()], MonoSelectCoreClass.prototype, "_hasPrefixSlotState", void 0);
1867
+ __decorate([state()], MonoSelectCoreClass.prototype, "_hasSuffixSlotState", void 0);
1868
+ __decorate([state()], MonoSelectCoreClass.prototype, "_hasListSlotState", void 0);
1869
+ __decorate([query(".mono-select-search-field")], MonoSelectCoreClass.prototype, "_searchFieldEl", void 0);
1870
+ __decorate([query(".mono-select-trigger")], MonoSelectCoreClass.prototype, "_triggerEl", void 0);
1871
+ __decorate([property({ type: String })], MonoSelectCoreClass.prototype, "width", void 0);
1872
+ __decorate([property({ type: String })], MonoSelectCoreClass.prototype, "height", void 0);
1873
+ __decorate([property({
1874
+ type: String,
1875
+ attribute: "min-width"
1876
+ })], MonoSelectCoreClass.prototype, "minWidth", void 0);
1877
+ __decorate([property({
1878
+ type: String,
1879
+ attribute: "max-width"
1880
+ })], MonoSelectCoreClass.prototype, "maxWidth", void 0);
1881
+ __decorate([property({
1882
+ type: String,
1883
+ attribute: "min-height"
1884
+ })], MonoSelectCoreClass.prototype, "minHeight", void 0);
1885
+ __decorate([property({
1886
+ type: String,
1887
+ attribute: "max-height"
1888
+ })], MonoSelectCoreClass.prototype, "maxHeight", void 0);
1889
+ return MonoSelectCoreClass;
1890
+ };
1891
+ //#endregion
1892
+ //#region src/components/select/select.css?raw
1893
+ var select_default = "/* =========================================================================\r\n mono-select — a port of Basecoat's `.select` (the custom one, `.select:not(select)`)\r\n and `.combobox` (basecoat-css@1.0.2, vega style), on the `.field` / `.label`\r\n chrome mono-input already ported.\r\n\r\n Styled by ATTRIBUTE, like Basecoat (`.select > button`, `[role='option'].active`)\r\n — and the attributes mirror the element's props one for one, so hand-written\r\n markup reads like the Lit / Vue tag:\r\n\r\n <mono-select size=\"sm\" color=\"danger\" variant=\"filled\" label=\"Fruit\">\r\n <div mono-select mono-size=\"sm\" mono-color=\"danger\" mono-variant=\"filled\">\r\n <label mono-label>Fruit</label>\r\n <button mono-trigger><span mono-value mono-placeholder>Pick</span>\r\n <span mono-actions><span mono-arrow>…</span></span></button>\r\n <div mono-dropdown><div mono-dropdown-body><button mono-item>…</button></div></div>\r\n </div>\r\n\r\n An absent attribute is the prop's default (`:not([mono-size])` = md,\r\n `:not([mono-color])` = primary, `:not([mono-variant])` = outlined). The element\r\n renders these attributes on its wrapper (both builds) plus `mono-open` while\r\n the panel is open; the old classes (`.mono-select.sm.open`) are still emitted\r\n as inert hooks for consumer CSS until 2.0 but no rule here reads them.\r\n\r\n Selector map (ours ≡ upstream):\r\n [mono-select] ≡ .field (gap-3, as margins — see the root rule) + .select (position: relative)\r\n [mono-select] > [mono-label] ≡ .field > label / .label\r\n [mono-select] > [mono-trigger] ≡ .select > button (h-9 rounded-md border-input ps-2.5 pe-2 text-sm shadow-xs)\r\n [mono-select][mono-searchable] > [mono-trigger] ≡ .combobox > input[role='combobox'] (same box; the input sits inside it)\r\n [mono-trigger] > [mono-value] ≡ .select > button > span (flex-1 truncate text-start)\r\n [mono-trigger] > [mono-native] ≡ EXTENSION — a plain <select> may stand in for the value + panel (appearance: none)\r\n [mono-actions] > [mono-arrow] > [mono-icon] ≡ .select > button > svg (size-4 text-muted-foreground)\r\n [mono-actions] > [mono-clear] ≡ .combobox [data-clear] (size-6, painted as .btn[data-variant='ghost'])\r\n [mono-dropdown] ≡ .select [data-popover] (bg-popover ring-1 ring-foreground/10 rounded-md shadow-md)\r\n [mono-dropdown-body] ≡ .combobox [role='listbox'] (max-h-72 overflow-y-auto p-1 scroll-py-1)\r\n [mono-item] ≡ .select [role='option'] (gap-2 rounded-sm py-1.5 ps-2 pe-8 text-sm)\r\n [mono-item][mono-active] / :hover ≡ [role='option'].active (bg-muted text-foreground)\r\n [mono-item][mono-selected] ≡ [role='option'][aria-selected='true'] (the --check-icon at the end)\r\n [mono-group] ≡ .select [role='heading'] (px-2 py-1.5 text-xs text-muted-foreground)\r\n [mono-empty-row] ≡ .select [role='listbox']::before (py-6 text-center text-sm)\r\n [mono-load-more] ≡ EXTENSION (an option-shaped ghost button)\r\n [mono-message-wrap] > [mono-message] ≡ .field > p / .field [role='alert']\r\n [mono-validation-state=\"invalid\"] ≡ .select > button[aria-invalid='true']\r\n [mono-validation-state=\"valid|warning\"] ≡ EXTENSION (the invalid pattern in --success / --warning)\r\n [mono-size=\"xs|sm|lg|xl|xxl\"] ≡ EXTENSION (Basecoat has only data-size=sm; the ladder is --mono-control-height-*)\r\n [mono-variant=\"filled\"] ≡ EXTENSION (luma's .select > button: border-transparent bg-input/50)\r\n [mono-variant=\"underlined\"] ≡ EXTENSION (sera's: rounded-none border-b-input px-0, no ring)\r\n\r\n Inner parts are attributes too: [mono-label] (+ [mono-required-mark]),\r\n [mono-trigger], [mono-value] (+ [mono-placeholder]), [mono-search-field],\r\n [mono-native], [mono-actions], [mono-clear], [mono-arrow], [mono-icon],\r\n [mono-dropdown], [mono-dropdown-body], [mono-item] (+ [mono-active] /\r\n [mono-selected] / [mono-disabled]), [mono-group] (+ [mono-sticky],\r\n [mono-level=\"n\"]), [mono-empty-row], [mono-load-more] (+ [mono-loading]),\r\n [mono-list-slot], [mono-message-wrap] > [mono-message=\"helper|valid|invalid|warning\"].\r\n The shadow build marks an unassigned slot wrapper [mono-empty].\r\n\r\n THE PANEL IS PORTALED. The light build moves [mono-dropdown] into a\r\n `<div data-mono-popup-portal>` under <body> while open (composables/popup-\r\n portal.ts), and the portal mirrors the wrapper's class AND its mono-*\r\n attributes — so `[mono-select] > [mono-dropdown]` keeps matching there and\r\n the `--_mono-select-*` resolvers declared on `[mono-select]` re-resolve on\r\n the portal. Nothing here may rely on the panel being inside the trigger's\r\n host, and every option rule is scoped under `[mono-select]`.\r\n\r\n Values are copied from the compiled vendor sheet (vendor/basecoat/basecoat-\r\n vega.cdn.css) through the token layer; `dark:` variants travel as\r\n `--mono-mode-*` tokens (a selector cannot cross a shadow boundary; an\r\n inherited custom property can). FLAVORS set the `--mono-select-*` knobs read\r\n below — the same set as mono-input (`--mono-select-outline-*` for the outlined\r\n variant alone) plus `--mono-select-dropdown-{radius,padding,shadow,ring}`,\r\n `--mono-select-option-{radius,padding-x,padding-y,font-size,line-height,gap,font-weight}`,\r\n `--mono-select-group-*`, `--mono-select-icon-size`. Every fallback here is vega's\r\n value (`node scripts/basecoat-styles.mjs --varying \"^(\\.select:not\\(select\\)|\\.combobox)\"`).\r\n ========================================================================= */\r\n\r\nmono-select {\r\n display: block;\r\n}\r\n\r\n[mono-select] {\r\n /* ── palette: each slot is a public knob over a Basecoat token ─────────── */\r\n --_mono-select-text: var(--mono-select-color, var(--mono-select-text, var(--foreground)));\r\n --_mono-select-placeholder: var(--mono-select-placeholder, var(--muted-foreground));\r\n --_mono-select-muted: var(--mono-select-muted, var(--muted-foreground));\r\n --_mono-select-primary: var(--mono-select-primary, var(--ring));\r\n --_mono-select-secondary: var(--mono-select-secondary, var(--muted-foreground));\r\n --_mono-select-success: var(--mono-select-success, var(--success));\r\n --_mono-select-danger: var(--mono-select-danger, var(--destructive));\r\n --_mono-select-warning: var(--mono-select-warning, var(--warning));\r\n --_mono-select-info: var(--mono-select-info, var(--info));\r\n --_mono-select-teal: var(--mono-select-teal, var(--teal));\r\n --_mono-select-purple: var(--mono-select-purple, var(--purple));\r\n --_mono-select-neutral: var(--mono-select-neutral, var(--neutral));\r\n --_mono-select-dark: var(--mono-select-dark, var(--dark));\r\n --_mono-select-valid: var(--mono-select-valid, var(--success));\r\n --_mono-select-invalid: var(--mono-select-invalid, var(--destructive));\r\n\r\n /* ── the painted result — three tiers, base = .select > button (vega) ─── */\r\n --_mono-select-ring-color: var(--mono-select-ring-color, var(--mono-select-focus-color, var(--_mono-select-ring-color-preset, var(--_mono-select-primary))));\r\n --_mono-select-ring-width: var(--mono-select-ring-width, var(--_mono-select-ring-width-preset, var(--mono-ring-width)));\r\n --_mono-select-ring-alpha: var(--mono-select-ring-alpha, var(--mono-ring-alpha));\r\n --_mono-select-border-color: var(--mono-select-rest-border, var(--mono-select-border-color, var(--mono-select-border, var(--_mono-select-border-color-preset, var(--input)))));\r\n --_mono-select-bg: var(--mono-select-bg, var(--mono-select-surface, var(--_mono-select-bg-preset, var(--mono-mode-surface))));\r\n --_mono-select-hover-bg: var(--mono-select-hover-bg, var(--_mono-select-hover-bg-preset, var(--_mono-select-bg)));\r\n --_mono-select-shadow: var(--mono-select-shadow, var(--_mono-select-shadow-preset, 0 0 #0000));\r\n --_mono-select-icon: var(--mono-select-icon-size, calc(var(--mono-spacing) * 4));\r\n\r\n /* ── md metrics live on the unqualified root ON PURPOSE: hand-written\r\n `<div mono-select>` that names no size renders exactly like size=\"md\".\r\n basecoat@1.0.2 styles/vega.css .select:not(select) > button — h-9 gap-1.5\r\n rounded-md ps-2.5 pe-2 text-sm ── */\r\n --_mono-select-height: var(--mono-select-height-md, var(--mono-control-height-md));\r\n --_mono-select-radius: var(--mono-select-radius-md, var(--_mono-select-radius-preset, var(--mono-select-radius, var(--mono-radius-md))));\r\n --_mono-select-padding-start: var(--mono-select-padding-x-md, var(--mono-select-padding-x, var(--_mono-select-padding-x-preset, calc(var(--mono-spacing) * 2.5))));\r\n --_mono-select-padding-end: var(--mono-select-padding-end-md, var(--mono-select-padding-x, var(--_mono-select-padding-x-preset, calc(var(--mono-spacing) * 2))));\r\n --_mono-select-gap: var(--mono-select-trigger-gap, calc(var(--mono-spacing) * 1.5));\r\n --_mono-select-font-size: var(--mono-select-font-md, var(--mono-text-sm));\r\n --_mono-select-line-height: var(--mono-select-line-height, var(--mono-select-line-height-md, var(--mono-text-sm--lh)));\r\n --_mono-select-action: calc(var(--mono-spacing) * 6);\r\n\r\n /* basecoat@1.0.2 styles/vega.css .field — flex w-full flex-col gap-3; mono: BLOCK\r\n flow with the gap as margins, so a hand-written panel that no controller\r\n positions lands at its static position — right under the trigger, above the\r\n message — instead of a flex container's content-box top */\r\n --_mono-select-gap-y: var(--mono-select-gap, calc(var(--mono-spacing) * 3));\r\n position: relative;\r\n display: block;\r\n width: 100%;\r\n font-family: inherit;\r\n color: var(--_mono-select-text);\r\n}\r\n\r\n/* A page-level `* { box-sizing: border-box }` reset does NOT cross a shadow\r\n boundary; scoped here so both builds measure the same. */\r\n[mono-select],\r\n[mono-select] *,\r\n[mono-select] *::before,\r\n[mono-select] *::after {\r\n box-sizing: border-box;\r\n}\r\n\r\n[mono-select] :is([mono-label], [mono-message])[mono-empty] {\r\n display: none;\r\n}\r\n\r\n/* =========================================\r\n Sizes — the trigger's painted height IS the token (tests/perf/field-heights)\r\n EXTENSION: Basecoat's select has only data-size=sm; the ladder is the shared\r\n --mono-control-height-* scale and the text follows .btn's steps.\r\n ========================================= */\r\n\r\n[mono-select][mono-size=\"xs\"] {\r\n --_mono-select-height: var(--mono-select-height-xs, var(--mono-control-height-xs));\r\n --_mono-select-radius: var(--mono-select-radius-xs, var(--_mono-select-radius-preset, var(--mono-select-radius, var(--mono-radius-md))));\r\n --_mono-select-padding-start: var(--mono-select-padding-x-xs, var(--mono-select-padding-x, var(--_mono-select-padding-x-preset, calc(var(--mono-spacing) * 2))));\r\n --_mono-select-padding-end: var(--mono-select-padding-end-xs, var(--mono-select-padding-x, var(--_mono-select-padding-x-preset, calc(var(--mono-spacing) * 1.5))));\r\n --_mono-select-gap: var(--mono-select-trigger-gap, var(--mono-spacing));\r\n --_mono-select-font-size: var(--mono-select-font-xs, var(--mono-text-xs));\r\n --_mono-select-line-height: var(--mono-select-line-height, var(--mono-select-line-height-xs, var(--mono-text-xs--lh)));\r\n --_mono-select-icon: var(--mono-select-icon-size, calc(var(--mono-spacing) * 3.5));\r\n --_mono-select-action: calc(var(--mono-spacing) * 4);\r\n}\r\n\r\n/* basecoat@1.0.2 styles/vega.css .select:not(select) > button — data-[size=sm]:h-8 */\r\n[mono-select][mono-size=\"sm\"] {\r\n --_mono-select-height: var(--mono-select-height-sm, var(--mono-control-height-sm));\r\n --_mono-select-radius: var(--mono-select-radius-sm, var(--_mono-select-radius-preset, var(--mono-select-radius, var(--mono-radius-md))));\r\n --_mono-select-padding-start: var(--mono-select-padding-x-sm, var(--mono-select-padding-x, var(--_mono-select-padding-x-preset, calc(var(--mono-spacing) * 2.5))));\r\n --_mono-select-padding-end: var(--mono-select-padding-end-sm, var(--mono-select-padding-x, var(--_mono-select-padding-x-preset, calc(var(--mono-spacing) * 2))));\r\n --_mono-select-font-size: var(--mono-select-font-sm, var(--mono-select-font-md, var(--mono-text-sm)));\r\n --_mono-select-line-height: var(--mono-select-line-height, var(--mono-select-line-height-sm, var(--mono-text-sm--lh)));\r\n --_mono-select-action: calc(var(--mono-spacing) * 5);\r\n}\r\n\r\n[mono-select][mono-size=\"lg\"] {\r\n --_mono-select-height: var(--mono-select-height-lg, var(--mono-control-height-lg));\r\n --_mono-select-radius: var(--mono-select-radius-lg, var(--_mono-select-radius-preset, var(--mono-select-radius, var(--mono-radius-md))));\r\n --_mono-select-padding-start: var(--mono-select-padding-x-lg, var(--mono-select-padding-x, var(--_mono-select-padding-x-preset, calc(var(--mono-spacing) * 2.5))));\r\n --_mono-select-padding-end: var(--mono-select-padding-end-lg, var(--mono-select-padding-x, var(--_mono-select-padding-x-preset, calc(var(--mono-spacing) * 2))));\r\n --_mono-select-font-size: var(--mono-select-font-lg, var(--mono-select-font-md, var(--mono-text-sm)));\r\n --_mono-select-line-height: var(--mono-select-line-height, var(--mono-select-line-height-lg, var(--mono-text-sm--lh)));\r\n}\r\n\r\n[mono-select][mono-size=\"xl\"] {\r\n --_mono-select-height: var(--mono-select-height-xl, var(--mono-control-height-xl));\r\n --_mono-select-radius: var(--mono-select-radius-xl, var(--_mono-select-radius-preset, var(--mono-select-radius, var(--mono-radius-md))));\r\n --_mono-select-padding-start: var(--mono-select-padding-x-xl, var(--mono-select-padding-x, var(--_mono-select-padding-x-preset, calc(var(--mono-spacing) * 3))));\r\n --_mono-select-padding-end: var(--mono-select-padding-end-xl, var(--mono-select-padding-x, var(--_mono-select-padding-x-preset, calc(var(--mono-spacing) * 2.5))));\r\n --_mono-select-gap: var(--mono-select-trigger-gap, calc(var(--mono-spacing) * 2));\r\n --_mono-select-font-size: var(--mono-select-font-xl, var(--mono-text-base));\r\n --_mono-select-line-height: var(--mono-select-line-height, var(--mono-select-line-height-xl, var(--mono-text-base--lh)));\r\n --_mono-select-icon: var(--mono-select-icon-size, calc(var(--mono-spacing) * 5));\r\n --_mono-select-action: calc(var(--mono-spacing) * 7);\r\n}\r\n\r\n[mono-select][mono-size=\"xxl\"] {\r\n --_mono-select-height: var(--mono-select-height-xxl, var(--mono-control-height-xxl));\r\n --_mono-select-radius: var(--mono-select-radius-xxl, var(--_mono-select-radius-preset, var(--mono-select-radius, var(--mono-radius-md))));\r\n --_mono-select-padding-start: var(--mono-select-padding-x-xxl, var(--mono-select-padding-x, var(--_mono-select-padding-x-preset, calc(var(--mono-spacing) * 4))));\r\n --_mono-select-padding-end: var(--mono-select-padding-end-xxl, var(--mono-select-padding-x, var(--_mono-select-padding-x-preset, calc(var(--mono-spacing) * 3))));\r\n --_mono-select-gap: var(--mono-select-trigger-gap, calc(var(--mono-spacing) * 2));\r\n --_mono-select-font-size: var(--mono-select-font-xxl, var(--mono-text-lg));\r\n --_mono-select-line-height: var(--mono-select-line-height, var(--mono-select-line-height-xxl, var(--mono-text-lg--lh)));\r\n --_mono-select-icon: var(--mono-select-icon-size, calc(var(--mono-spacing) * 5));\r\n --_mono-select-action: calc(var(--mono-spacing) * 8);\r\n}\r\n\r\n/* =========================================\r\n Variants — each writes only `*-preset` slots\r\n ========================================= */\r\n\r\n/* basecoat@1.0.2 styles/vega.css .select:not(select) > button — rounded-md border\r\n border-input bg-transparent shadow-xs (dark:bg-input/30 dark:hover:bg-input/50\r\n via the mode tokens). `--mono-select-outline-*` restyle THIS variant alone. */\r\n[mono-select]:is(:not([mono-variant]), [mono-variant=\"outlined\"]) {\r\n --_mono-select-bg-preset: var(--mono-select-outline-bg);\r\n --_mono-select-hover-bg-preset: var(--mono-select-outline-hover-bg, var(--mono-mode-field-hover-bg));\r\n --_mono-select-border-color-preset: var(--mono-select-outline-border-color);\r\n --_mono-select-side-border-color-preset: var(--mono-select-outline-side-border-color);\r\n --_mono-select-shadow-preset: var(--mono-select-outline-shadow, var(--mono-shadow-xs));\r\n --_mono-select-ring-width-preset: var(--mono-select-outline-ring-width);\r\n --_mono-select-radius-preset: var(--mono-select-outline-radius);\r\n --_mono-select-padding-x-preset: var(--mono-select-outline-padding-x);\r\n}\r\n\r\n/* EXTENSION — filled ≡ basecoat@1.0.2 styles/luma.css .select:not(select) > button:\r\n border-transparent bg-input/50, no shadow-xs, no hover */\r\n[mono-select][mono-variant=\"filled\"] {\r\n --_mono-select-bg-preset: var(--mono-select-filled-bg, color-mix(in oklab, var(--input) 50%, transparent));\r\n --_mono-select-hover-bg-preset: var(--_mono-select-bg);\r\n --_mono-select-border-color-preset: transparent;\r\n --_mono-select-shadow-preset: 0 0 #0000;\r\n}\r\n\r\n/* EXTENSION — underlined ≡ basecoat@1.0.2 styles/sera.css .select:not(select) > button:\r\n rounded-none border-transparent border-b-input bg-transparent px-0, no shadow,\r\n no ring, focus-visible:border-b-ring */\r\n[mono-select][mono-variant=\"underlined\"] {\r\n --_mono-select-bg-preset: transparent;\r\n --_mono-select-hover-bg-preset: transparent;\r\n --_mono-select-side-border-color-preset: transparent;\r\n --_mono-select-shadow-preset: 0 0 #0000;\r\n --_mono-select-ring-width-preset: 0px;\r\n --_mono-select-radius-preset: 0;\r\n --_mono-select-padding-x-preset: 0;\r\n}\r\n\r\n/* =========================================\r\n Colours — the `color` prop is the FOCUS colour (ring + focused border)\r\n ========================================= */\r\n\r\n[mono-select]:is(:not([mono-color]), [mono-color=\"primary\"]) {\r\n --_mono-select-ring-color-preset: var(--_mono-select-primary);\r\n}\r\n[mono-select][mono-color=\"secondary\"] {\r\n --_mono-select-ring-color-preset: var(--_mono-select-secondary);\r\n}\r\n[mono-select][mono-color=\"success\"] {\r\n --_mono-select-ring-color-preset: var(--_mono-select-success);\r\n}\r\n[mono-select][mono-color=\"danger\"] {\r\n --_mono-select-ring-color-preset: var(--_mono-select-danger);\r\n}\r\n[mono-select][mono-color=\"warning\"] {\r\n --_mono-select-ring-color-preset: var(--_mono-select-warning);\r\n}\r\n[mono-select][mono-color=\"info\"] {\r\n --_mono-select-ring-color-preset: var(--_mono-select-info);\r\n}\r\n[mono-select][mono-color=\"teal\"] {\r\n --_mono-select-ring-color-preset: var(--_mono-select-teal);\r\n}\r\n[mono-select][mono-color=\"purple\"] {\r\n --_mono-select-ring-color-preset: var(--_mono-select-purple);\r\n}\r\n[mono-select][mono-color=\"neutral\"] {\r\n --_mono-select-ring-color-preset: var(--_mono-select-neutral);\r\n}\r\n[mono-select][mono-color=\"dark\"] {\r\n --_mono-select-ring-color-preset: var(--_mono-select-dark);\r\n}\r\n\r\n/* =========================================\r\n Label\r\n ========================================= */\r\n\r\n/* basecoat@1.0.2 styles/vega.css .field > label, .label — flex items-center\r\n gap-2 text-sm leading-none font-medium select-none w-fit */\r\n[mono-select] > [mono-label] {\r\n display: flex;\r\n align-items: center;\r\n width: fit-content;\r\n margin: 0 0 var(--_mono-select-gap-y);\r\n gap: var(--mono-select-label-gap, calc(var(--mono-spacing) * 2));\r\n font-size: var(--mono-select-label-font-size, var(--mono-text-sm));\r\n line-height: var(--mono-select-label-line-height, 1);\r\n font-weight: var(--mono-select-label-font-weight, var(--mono-label-font-weight, var(--mono-font-weight-medium)));\r\n text-transform: var(--mono-select-label-text-transform, none);\r\n letter-spacing: var(--mono-select-label-letter-spacing, normal);\r\n color: var(--_mono-select-text);\r\n user-select: none;\r\n}\r\n\r\n[mono-select][mono-disabled] > [mono-label] {\r\n opacity: 0.5;\r\n pointer-events: none;\r\n}\r\n\r\n/* basecoat@1.0.2 styles/vega.css .field — data-invalid:text-destructive */\r\n[mono-select][mono-validation-state=\"invalid\"] > [mono-label] {\r\n color: var(--_mono-select-invalid);\r\n}\r\n\r\n[mono-select] [mono-required-mark] {\r\n color: var(--_mono-select-danger);\r\n}\r\n\r\n/* =========================================\r\n The trigger — the bordered box (a <button>, or a <div> holding the combobox input)\r\n ========================================= */\r\n\r\n/* basecoat@1.0.2 components/select.css .select:not(select) > button */\r\n/* basecoat@1.0.2 styles/vega.css .select:not(select) > button — h-9 gap-1.5\r\n rounded-md border border-input bg-transparent py-2 ps-2.5 pe-2 text-sm shadow-xs\r\n focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50\r\n aria-invalid:… dark:hover:bg-input/50; mono: `--tw-ring-*` flattened to the\r\n ring + shadow slots, the height is the control token (no block padding — the\r\n token owns the height), the side edges read their own slot */\r\n[mono-select] > [mono-trigger] {\r\n --_mono-select-bc: var(--_mono-select-border-color);\r\n --_mono-select-side-bc: var(--mono-select-side-border-color, var(--_mono-select-side-border-color-preset, var(--_mono-select-bc)));\r\n --_mono-select-ring: 0 0 #0000;\r\n\r\n position: relative;\r\n display: flex;\r\n align-items: center;\r\n justify-content: space-between;\r\n gap: var(--_mono-select-gap);\r\n width: 100%;\r\n min-width: 0;\r\n min-height: var(--_mono-select-height);\r\n margin: 0;\r\n padding-block: var(--mono-select-padding-y, 0);\r\n padding-inline: var(--_mono-select-padding-start) var(--_mono-select-padding-end);\r\n outline-style: none;\r\n border: var(--mono-border-width) solid var(--_mono-select-bc);\r\n border-top-color: var(--_mono-select-side-bc);\r\n border-inline-color: var(--_mono-select-side-bc);\r\n border-radius: var(--_mono-select-radius);\r\n background: var(--_mono-select-bg);\r\n color: var(--_mono-select-text);\r\n box-shadow: var(--_mono-select-ring), var(--_mono-select-shadow);\r\n font-family: inherit;\r\n font-size: var(--_mono-select-font-size);\r\n line-height: var(--_mono-select-line-height);\r\n font-weight: var(--mono-font-weight-normal);\r\n white-space: nowrap;\r\n text-align: start;\r\n cursor: pointer;\r\n user-select: none;\r\n transition-property: color, box-shadow, border-color, background-color;\r\n transition-timing-function: var(--mono-ease);\r\n transition-duration: var(--mono-duration);\r\n\r\n &:focus,\r\n &:focus-visible,\r\n &:focus-within {\r\n outline: none !important;\r\n }\r\n\r\n /* focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 —\r\n the combobox form is a <div> whose <input> takes focus, hence :focus-within */\r\n &:focus-visible,\r\n &:focus-within {\r\n --_mono-select-bc: var(--_mono-select-ring-color);\r\n --_mono-select-ring: 0 0 0 var(--_mono-select-ring-width) color-mix(in oklab, var(--_mono-select-ring-color) var(--_mono-select-ring-alpha), transparent);\r\n }\r\n\r\n & svg,\r\n & [mono-icon] {\r\n pointer-events: none;\r\n flex-shrink: 0;\r\n }\r\n}\r\n\r\n/* dark:hover:bg-input/50 (light: none) — carried by --mono-mode-field-hover-bg */\r\n@media (hover: hover) {\r\n [mono-select]:not([mono-disabled]):not([mono-readonly]) > [mono-trigger]:hover {\r\n background: var(--_mono-select-hover-bg);\r\n }\r\n}\r\n\r\n/* basecoat@1.0.2 styles/vega.css .select:not(select) > button — aria-invalid:border-destructive\r\n aria-invalid:ring-3 aria-invalid:ring-destructive/20 (dark: /50, /40 via the mode tokens) */\r\n[mono-select][mono-validation-state=\"invalid\"] > [mono-trigger],\r\n[mono-select] > [mono-trigger][aria-invalid=\"true\"] {\r\n --_mono-select-bc: var(--mono-mode-invalid-border);\r\n --_mono-select-ring: 0 0 0 var(--_mono-select-ring-width) var(--mono-mode-invalid-ring);\r\n}\r\n\r\n/* EXTENSION — valid / warning are the invalid pattern in the role's colour */\r\n[mono-select][mono-validation-state=\"valid\"] > [mono-trigger] {\r\n --_mono-select-bc: color-mix(in oklab, var(--_mono-select-valid) var(--mono-mode-state-border-alpha), transparent);\r\n --_mono-select-ring: 0 0 0 var(--_mono-select-ring-width) color-mix(in oklab, var(--_mono-select-valid) var(--mono-mode-state-ring-alpha), transparent);\r\n}\r\n[mono-select][mono-validation-state=\"warning\"] > [mono-trigger] {\r\n --_mono-select-bc: color-mix(in oklab, var(--_mono-select-warning) var(--mono-mode-state-border-alpha), transparent);\r\n --_mono-select-ring: 0 0 0 var(--_mono-select-ring-width) color-mix(in oklab, var(--_mono-select-warning) var(--mono-mode-state-ring-alpha), transparent);\r\n}\r\n\r\n/* EXTENSION — readonly: focusable, on a muted surface, no gestures */\r\n[mono-select][mono-readonly] > [mono-trigger] {\r\n background: var(--mono-select-readonly-bg, var(--muted));\r\n cursor: default;\r\n}\r\n\r\n/* basecoat@1.0.2 components/select.css .select:not(select) > button — disabled:\r\n pointer-events-none cursor-not-allowed opacity-50 */\r\n[mono-select][mono-disabled] > [mono-trigger],\r\n[mono-select] > [mono-trigger]:disabled,\r\n/* a raw readonly select can only disable its native <select>; the root attribute wins */\r\n[mono-select]:not([mono-readonly]) > [mono-trigger]:has(> [mono-native]:disabled) {\r\n opacity: 0.5;\r\n pointer-events: none;\r\n cursor: not-allowed;\r\n background: var(--mono-select-disabled-bg, var(--_mono-select-bg));\r\n}\r\n\r\n/* =========================================\r\n Value / search field / native <select>\r\n ========================================= */\r\n\r\n/* basecoat@1.0.2 components/select.css .select:not(select) > button > span —\r\n flex flex-1 overflow-hidden text-ellipsis whitespace-nowrap text-start */\r\n/* basecoat@1.0.2 styles/vega.css .select:not(select) > button > span — gap-1.5 */\r\n[mono-select] [mono-value] {\r\n flex: 1 1 auto;\r\n min-width: 0;\r\n display: flex;\r\n align-items: center;\r\n gap: var(--_mono-select-gap);\r\n overflow: hidden;\r\n text-overflow: ellipsis;\r\n white-space: nowrap;\r\n text-align: start;\r\n color: var(--_mono-select-text);\r\n}\r\n\r\n[mono-select] [mono-value] > span {\r\n overflow: hidden;\r\n text-overflow: ellipsis;\r\n white-space: nowrap;\r\n}\r\n\r\n[mono-select] [mono-value][mono-placeholder] {\r\n color: var(--_mono-select-placeholder);\r\n}\r\n\r\n/* basecoat@1.0.2 components/combobox.css .combobox > input[role='combobox'] — the\r\n search input lives INSIDE our trigger box, so it is borderless like\r\n .input-group > input and the box around it carries the chrome */\r\n[mono-select] [mono-search-field],\r\n[mono-select] [mono-native] {\r\n flex: 1 1 auto;\r\n width: 100%;\r\n min-width: 0;\r\n align-self: stretch;\r\n appearance: none;\r\n margin: 0;\r\n padding: 0;\r\n border: 0;\r\n border-radius: 0;\r\n outline: none;\r\n background: transparent;\r\n box-shadow: none;\r\n color: var(--_mono-select-text);\r\n font: inherit;\r\n line-height: var(--_mono-select-line-height);\r\n\r\n &:focus,\r\n &:focus-visible {\r\n outline: none !important;\r\n }\r\n\r\n &::placeholder {\r\n color: var(--_mono-select-placeholder);\r\n }\r\n\r\n &:disabled {\r\n cursor: not-allowed;\r\n }\r\n}\r\n\r\n[mono-select] [mono-search-field] {\r\n cursor: text;\r\n}\r\n\r\n[mono-select] [mono-native] {\r\n cursor: inherit;\r\n}\r\n\r\n[mono-select] [mono-native] option {\r\n color: var(--_mono-select-text);\r\n background: var(--popover);\r\n}\r\n\r\n/* =========================================\r\n Actions — the chevron and the clear button\r\n ========================================= */\r\n\r\n[mono-select] [mono-actions] {\r\n display: flex;\r\n align-items: center;\r\n gap: var(--mono-spacing);\r\n flex-shrink: 0;\r\n line-height: 1;\r\n}\r\n\r\n/* basecoat@1.0.2 styles/vega.css .select:not(select) > button > svg — size-4\r\n text-muted-foreground; mono: the glyph sits in a square action box so the\r\n chevron and the clear button occupy the same gutter */\r\n/* basecoat@1.0.2 components/combobox.css .combobox [data-clear] — size-6 border-0\r\n bg-transparent p-0 text-current */\r\n[mono-select] [mono-arrow],\r\n[mono-select] [mono-clear] {\r\n display: inline-flex;\r\n align-items: center;\r\n justify-content: center;\r\n flex-shrink: 0;\r\n width: var(--_mono-select-action);\r\n height: var(--_mono-select-action);\r\n margin: 0;\r\n padding: 0;\r\n border: 0;\r\n border-radius: var(--mono-select-clear-radius, calc(var(--radius) - 5px));\r\n background: transparent;\r\n color: var(--_mono-select-muted);\r\n font: inherit;\r\n line-height: 1;\r\n cursor: pointer;\r\n transition-property: color, background-color, transform;\r\n transition-timing-function: var(--mono-ease);\r\n transition-duration: var(--mono-duration);\r\n}\r\n\r\n[mono-select] :is([mono-arrow], [mono-clear]) > :is(svg, .mono-icon, [mono-icon]) {\r\n display: block;\r\n width: var(--_mono-select-icon);\r\n height: var(--_mono-select-icon);\r\n pointer-events: none;\r\n}\r\n\r\n/* EXTENSION — the chevron turns while the panel is open */\r\n[mono-select][mono-open] [mono-arrow] > :is(svg, .mono-icon, [mono-icon]) {\r\n transform: rotate(180deg);\r\n}\r\n\r\n/* basecoat@1.0.2 styles/vega.css .btn[data-variant='ghost'] — hover:bg-muted\r\n hover:text-foreground (dark:hover:bg-muted/50 via --mono-mode-ghost-hover) */\r\n@media (hover: hover) {\r\n [mono-select] :is([mono-arrow], [mono-clear]):hover {\r\n background: var(--mono-mode-ghost-hover);\r\n color: var(--_mono-select-text);\r\n }\r\n}\r\n\r\n/* =========================================\r\n The panel\r\n ========================================= */\r\n\r\n/* basecoat@1.0.2 components/popover.css [data-popover] — absolute z-50 min-w-full\r\n overflow-x-hidden; mono: `display: none` while closed (the contents are only\r\n rendered while open), `--mono-popup-z` from the shared popup stack and\r\n `--mono-popup-avail-h` from the portal controller cap the whole panel */\r\n/* basecoat@1.0.2 styles/vega.css .select:not(select) [data-popover] — bg-popover\r\n text-popover-foreground rounded-md shadow-md ring-1 ring-foreground/10; the\r\n `p-1` moves to the scrolling body (the combobox layout), so the scrollbar\r\n never paints over the padding */\r\n[mono-select] > [mono-dropdown] {\r\n position: absolute;\r\n /* `top: auto` = the static position: the panel follows the trigger in the DOM,\r\n so in block flow it lands right under it (the popup controller overrides\r\n this inline for the element; hand-written markup relies on it). */\r\n top: auto;\r\n /* the 6px offset as a transform: the controller writes `transform: none` inline\r\n with its fixed position, so only the hand-written panel is pushed down */\r\n transform: translateY(calc(var(--mono-spacing) * 1.5));\r\n /* Both edges pinned, so the panel matches the field by default. An inline\r\n `width` from `:dropdown.prop=\"{ width }\"` is then the over-constrained case,\r\n which CSS resolves by ignoring `right` — the panel keeps this left edge and\r\n takes the given width. */\r\n left: 0;\r\n right: 0;\r\n z-index: var(--mono-popup-z, 1000);\r\n display: none;\r\n /* Basecoat's `min-w-[max(100%,9rem)]` is relative to the .select box; a portaled\r\n panel is position: fixed, where 100% would be the viewport — the controller\r\n writes the anchor's width inline instead, so only the floor stays. */\r\n min-width: var(--mono-select-dropdown-min-width, 9rem);\r\n max-height: var(--mono-popup-avail-h, none);\r\n overflow: hidden;\r\n isolation: isolate;\r\n border-radius: var(--mono-select-dropdown-radius, var(--mono-radius-md));\r\n background: var(--mono-select-dropdown-bg, var(--popover));\r\n color: var(--mono-select-dropdown-color, var(--popover-foreground));\r\n box-shadow: var(--mono-select-dropdown-ring, 0 0 0 1px color-mix(in oklab, var(--foreground) 10%, transparent)), var(--mono-select-dropdown-shadow, var(--mono-shadow-md));\r\n font-size: var(--mono-select-option-font-size, var(--mono-text-sm));\r\n line-height: var(--mono-select-option-line-height, var(--mono-text-sm--lh));\r\n}\r\n\r\n[mono-select][mono-open] > [mono-dropdown] {\r\n /* A flex column (not `block`) so the body can shrink past its own height when\r\n the panel is clamped above. */\r\n display: flex;\r\n flex-direction: column;\r\n}\r\n\r\n/* basecoat@1.0.2 styles/vega.css .combobox [role='listbox'] — max-h-[min(18rem,\r\n var(--available-height,18rem))] scroll-py-1 overflow-y-auto p-1 */\r\n[mono-select] [mono-dropdown-body] {\r\n flex: 1 1 auto;\r\n min-height: 0;\r\n max-height: 18rem;\r\n padding: var(--mono-select-dropdown-padding, var(--mono-spacing));\r\n overflow: auto;\r\n overscroll-behavior: contain;\r\n scroll-padding-block: var(--mono-select-dropdown-padding, var(--mono-spacing));\r\n outline-style: none;\r\n}\r\n\r\n/* =========================================\r\n Options\r\n -----------------------------------------\r\n Each rule also lists the stamped twin of a row rendered through `slot=\"list\"`\r\n (`[data-mono-type='row']`, `[data-mono-active]`, `[data-mono-selected]`), so\r\n the two can never drift: what you render in the slot IS an option. `:where()`\r\n wraps only the CONTAINER, keeping the twin at attribute weight.\r\n ========================================= */\r\n\r\n/* basecoat@1.0.2 components/select.css .select:not(select) [role='option'] — relative\r\n flex w-full cursor-default items-center overflow-hidden text-ellipsis whitespace-\r\n nowrap outline-none select-none; disabled: pointer-events-none opacity-50 */\r\n/* basecoat@1.0.2 styles/vega.css .select:not(select) [role='option'] — gap-2\r\n rounded-sm py-1.5 ps-2 pe-8 text-sm, svg size-4 */\r\n[mono-select] [mono-item],\r\n[mono-select] :where([mono-list-slot]) [data-mono-type='row'] {\r\n position: relative;\r\n display: flex;\r\n width: 100%;\r\n align-items: center;\r\n gap: var(--mono-select-option-gap, calc(var(--mono-spacing) * 2));\r\n margin: 0;\r\n padding-block: var(--mono-select-option-padding-y, calc(var(--mono-spacing) * 1.5));\r\n padding-inline: var(--mono-select-option-padding-x, calc(var(--mono-spacing) * 2)) var(--mono-select-option-padding-end, calc(var(--mono-spacing) * 8));\r\n min-height: var(--mono-select-option-min-height, 0);\r\n border: 0;\r\n border-radius: var(--mono-select-option-radius, var(--mono-radius-sm));\r\n /* longhands, so the selected row's check (a background-image) survives the\r\n active / hover background */\r\n background-color: transparent;\r\n background-image: none;\r\n color: var(--_mono-select-text);\r\n font-family: inherit;\r\n font-size: var(--mono-select-option-font-size, var(--mono-text-sm));\r\n line-height: var(--mono-select-option-line-height, var(--mono-text-sm--lh));\r\n font-weight: var(--mono-select-option-font-weight, var(--mono-font-weight-normal));\r\n text-align: start;\r\n overflow: hidden;\r\n text-overflow: ellipsis;\r\n white-space: nowrap;\r\n outline-style: none;\r\n user-select: none;\r\n cursor: default;\r\n transition-property: color, background-color;\r\n transition-timing-function: var(--mono-ease);\r\n transition-duration: var(--mono-duration-fast);\r\n}\r\n\r\n/* EXTENSION: a hair of air between rows. Upstream stacks its options flush, so an\r\n active row directly under the selected one read as ONE tall highlight; a 2px\r\n seam keeps the two rounded-sm washes apart. `--mono-select-option-spacing`. */\r\n[mono-select] [mono-item] + [mono-item],\r\n[mono-select] :where([mono-list-slot]) [data-mono-type='row'] + [data-mono-type='row'] {\r\n margin-top: var(--mono-select-option-spacing, 2px);\r\n}\r\n\r\n[mono-select] [mono-item] svg:not([class*='size-']),\r\n[mono-select] [mono-item] .mono-icon {\r\n width: var(--_mono-select-icon);\r\n height: var(--_mono-select-icon);\r\n flex-shrink: 0;\r\n pointer-events: none;\r\n}\r\n\r\n/* basecoat@1.0.2 styles/vega.css .select:not(select) [role='option'].active, .select:not(select) [role='option']:focus-visible\r\n — bg-muted text-foreground. The keyboard cursor and the pointer share one look. */\r\n[mono-select] [mono-item][mono-active]:not([mono-disabled]):not(:disabled),\r\n[mono-select] [mono-item]:focus-visible,\r\n[mono-select] :where([mono-list-slot]) [data-mono-active] {\r\n background-color: var(--mono-select-option-active-bg, var(--muted));\r\n color: var(--mono-select-option-active-color, var(--_mono-select-text));\r\n}\r\n\r\n/* basecoat@1.0.2 components/select.css .select:not(select):not([data-select-initialized]) [role='option']:not([aria-disabled='true']):not(:disabled):hover, .select:not(select) [role='option'].active\r\n — the pointer highlight is NOT behind (hover: hover) upstream */\r\n[mono-select] [mono-item]:hover:not([mono-disabled]):not(:disabled),\r\n[mono-select] :where([mono-list-slot]) [data-mono-type='row']:hover {\r\n background-color: var(--mono-select-option-active-bg, var(--muted));\r\n color: var(--mono-select-option-active-color, var(--_mono-select-text));\r\n}\r\n\r\n/* basecoat@1.0.2 components/select.css .select:not(select) [role='option'][aria-selected='true']\r\n — the --check-icon at the end (bg-size .875rem, center right .5rem) */\r\n[mono-select] [mono-item][mono-selected],\r\n[mono-select] :where([mono-list-slot]) [data-mono-type='row'][data-mono-selected] {\r\n background-image: var(--mono-select-check-icon, var(--check-icon));\r\n background-size: var(--mono-select-check-size, 0.875rem);\r\n background-position: center right calc(var(--mono-spacing) * 2);\r\n background-repeat: no-repeat;\r\n font-weight: var(--mono-select-option-selected-font-weight, var(--mono-select-option-font-weight, var(--mono-font-weight-normal)));\r\n}\r\n\r\n[mono-select] [mono-item][mono-selected]:dir(rtl),\r\n[mono-select] :where([mono-list-slot]) [data-mono-type='row'][data-mono-selected]:dir(rtl) {\r\n background-position: center left calc(var(--mono-spacing) * 2);\r\n}\r\n\r\n[mono-select] [mono-item][mono-disabled],\r\n[mono-select] [mono-item]:disabled {\r\n opacity: 0.5;\r\n pointer-events: none;\r\n cursor: not-allowed;\r\n}\r\n\r\n/* basecoat@1.0.2 styles/vega.css .select:not(select) [role='listbox']:not(:has([data-value]:not([aria-hidden='true'])))::before\r\n — py-6 text-center text-sm (the \"No results found\" row) */\r\n[mono-select] [mono-empty-row] {\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n padding-block: calc(var(--mono-spacing) * 6);\r\n padding-inline: calc(var(--mono-spacing) * 3);\r\n font-size: var(--mono-select-option-font-size, var(--mono-text-sm));\r\n line-height: var(--mono-select-option-line-height, var(--mono-text-sm--lh));\r\n color: var(--_mono-select-muted);\r\n text-align: center;\r\n overflow: hidden;\r\n text-overflow: ellipsis;\r\n white-space: nowrap;\r\n cursor: default;\r\n user-select: none;\r\n}\r\n\r\n/* basecoat@1.0.2 styles/vega.css .select:not(select) [role='heading'] — px-2 py-1.5\r\n text-xs text-muted-foreground; EXTENSION: one indent step per nesting level */\r\n[mono-select] [mono-group],\r\n[mono-select] :where([mono-list-slot]) [data-mono-type='group'] {\r\n --_ms-group-level: 0;\r\n padding-block: var(--mono-select-group-padding-y, calc(var(--mono-spacing) * 1.5));\r\n padding-inline: var(--mono-select-group-padding-x, calc(var(--mono-spacing) * 2));\r\n padding-inline-start: calc(var(--mono-select-group-padding-x, calc(var(--mono-spacing) * 2)) + var(--_ms-group-level) * calc(var(--mono-spacing) * 2));\r\n font-size: var(--mono-select-group-font-size, var(--mono-text-xs));\r\n line-height: var(--mono-select-group-line-height, var(--mono-text-xs--lh));\r\n font-weight: var(--mono-select-group-font-weight, var(--mono-font-weight-normal));\r\n text-transform: var(--mono-select-group-text-transform, none);\r\n letter-spacing: var(--mono-select-group-letter-spacing, normal);\r\n color: var(--_mono-select-muted);\r\n cursor: default;\r\n user-select: none;\r\n}\r\n\r\n[mono-select] [mono-group][mono-level='1'],\r\n[mono-select] :where([mono-list-slot]) [data-mono-type='group'][data-mono-level='1'] { --_ms-group-level: 1; }\r\n[mono-select] [mono-group][mono-level='2'],\r\n[mono-select] :where([mono-list-slot]) [data-mono-type='group'][data-mono-level='2'] { --_ms-group-level: 2; }\r\n[mono-select] [mono-group][mono-level='3'],\r\n[mono-select] :where([mono-list-slot]) [data-mono-type='group'][data-mono-level='3'] { --_ms-group-level: 3; }\r\n\r\n/* group-sticky: pin headers while their rows scroll; nested levels stack on the\r\n panel's own surface so options scroll cleanly underneath. */\r\n[mono-select] [mono-group][mono-sticky] {\r\n position: sticky;\r\n top: calc(var(--_ms-group-level) * 1.5rem);\r\n z-index: calc(5 - var(--_ms-group-level));\r\n background: var(--mono-select-dropdown-bg, var(--popover));\r\n}\r\n\r\n/* EXTENSION — the load-more affordance: an option-shaped ghost button */\r\n[mono-select] [mono-load-more] {\r\n display: flex;\r\n width: 100%;\r\n align-items: center;\r\n justify-content: center;\r\n gap: var(--mono-select-option-gap, calc(var(--mono-spacing) * 2));\r\n margin: 0;\r\n padding-block: var(--mono-select-option-padding-y, calc(var(--mono-spacing) * 1.5));\r\n padding-inline: var(--mono-select-option-padding-x, calc(var(--mono-spacing) * 2));\r\n border: 0;\r\n border-radius: var(--mono-select-option-radius, var(--mono-radius-sm));\r\n background: transparent;\r\n color: var(--_mono-select-muted);\r\n font-family: inherit;\r\n font-size: var(--mono-select-option-font-size, var(--mono-text-sm));\r\n line-height: var(--mono-select-option-line-height, var(--mono-text-sm--lh));\r\n font-weight: var(--mono-font-weight-medium);\r\n cursor: pointer;\r\n transition-property: color, background-color;\r\n transition-timing-function: var(--mono-ease);\r\n transition-duration: var(--mono-duration-fast);\r\n}\r\n\r\n@media (hover: hover) {\r\n [mono-select] [mono-load-more]:hover:not([mono-loading]) {\r\n background-color: var(--mono-select-option-active-bg, var(--muted));\r\n color: var(--_mono-select-text);\r\n }\r\n}\r\n\r\n[mono-select] [mono-load-more][mono-loading] {\r\n cursor: default;\r\n opacity: 0.7;\r\n}\r\n\r\n/* Consumer-rendered option rows (slot=\"list\"). `display: contents` so mono's own\r\n placement wrapper generates no box: the rows the consumer writes lay out as if\r\n they were direct children of the panel. */\r\n[mono-select] [mono-list-slot] {\r\n display: contents;\r\n}\r\n\r\n/* =========================================\r\n Message — helper / validation text under the field\r\n ========================================= */\r\n\r\n/* basecoat@1.0.2 styles/vega.css .fieldset legend + p, .field > p, .field section > p\r\n — text-sm text-muted-foreground leading-normal font-normal */\r\n[mono-select] > [mono-message-wrap] {\r\n display: block;\r\n margin-top: var(--_mono-select-gap-y);\r\n}\r\n\r\n[mono-select] > [mono-message-wrap]:not(:has([mono-message]:not([mono-empty]))) {\r\n display: none;\r\n}\r\n\r\n[mono-select] [mono-message] {\r\n font-size: var(--mono-select-message-font-size, var(--mono-text-sm));\r\n line-height: var(--mono-select-message-line-height, var(--mono-leading-normal));\r\n font-weight: var(--mono-font-weight-normal);\r\n text-align: start;\r\n color: var(--_mono-select-muted);\r\n}\r\n\r\n/* basecoat@1.0.2 styles/vega.css .field [role=\"alert\"] — text-destructive text-sm */\r\n[mono-select] [mono-message=\"invalid\"] {\r\n color: var(--_mono-select-invalid);\r\n}\r\n\r\n[mono-select] [mono-message=\"valid\"] {\r\n color: var(--_mono-select-valid);\r\n}\r\n\r\n[mono-select] [mono-message=\"warning\"] {\r\n color: var(--_mono-select-warning);\r\n}\r\n\r\n@media (prefers-reduced-motion: reduce) {\r\n [mono-select] > [mono-trigger],\r\n [mono-select] [mono-arrow],\r\n [mono-select] [mono-clear],\r\n [mono-select] [mono-item] {\r\n transition: none;\r\n }\r\n}\r\n";
1894
+ //#endregion
1895
+ //#region src/components/select/mono-select.shadow.ts
1896
+ var SHADOW_EXTRA_CSS = `
1897
+ [mono-value] > slot[name='prefix'],
1898
+ [mono-value] > slot[name='suffix'] {
1899
+ display: contents;
1900
+ }
1901
+ `;
1902
+ var MonoSelectShadow = class MonoSelectShadow extends withShadowUtilityStyles(MonoSelectCore(LitElement)) {
1903
+ static {
1904
+ this.disableWarning?.("change-in-update");
1905
+ }
1906
+ static {
1907
+ this.styles = [unsafeCSS(toShadowCss(select_default, {
1908
+ host: "mono-select",
1909
+ append: SHADOW_EXTRA_CSS
1910
+ }))];
1911
+ }
1912
+ get _slotsAlwaysRender() {
1913
+ return true;
1914
+ }
1915
+ connectedCallback() {
1916
+ super.connectedCallback();
1917
+ this._onLateListSlot();
1918
+ if (isServer) return;
1919
+ flushSsrHydration(this);
1920
+ }
1921
+ firstUpdated(changed) {
1922
+ super.firstUpdated(changed);
1923
+ if (isServer) return;
1924
+ this._scanSlots();
1925
+ }
1926
+ updated(changed) {
1927
+ super.updated(changed);
1928
+ if (isServer) return;
1929
+ this._watchListChrome();
1930
+ this._syncListChrome();
1931
+ }
1932
+ /** A wrapper appeared after connect — the flag is all this build needs, projection does the rest. */
1933
+ _onLateListSlot() {
1934
+ const has = !!this._lateListSlot.find();
1935
+ if (has !== this._hasListSlotState) this._setSlotState("list", has);
1936
+ }
1937
+ _scanSlots() {
1938
+ for (const name of [
1939
+ "label",
1940
+ "helper",
1941
+ "prefix",
1942
+ "suffix"
1943
+ ]) {
1944
+ const slot = this.renderRoot.querySelector(`slot[name="${name}"]`);
1945
+ this._setSlotState(name, this._slotHasContent(slot));
1946
+ }
1947
+ this._onLateListSlot();
1948
+ }
1949
+ _slotHasContent(slot) {
1950
+ return !!slot && slot.assignedNodes({ flatten: true }).some((n) => n.nodeType === Node.ELEMENT_NODE || !!(n.textContent ?? "").trim());
1951
+ }
1952
+ _onSlotChange(name, event) {
1953
+ this._setSlotState(name, this._slotHasContent(event.target));
1954
+ }
1955
+ /**
1956
+ * The consumer's list wrapper, PROJECTED rather than moved.
1957
+ *
1958
+ * Projection is what makes this work in a shadow root at all: slotted content stays in the light
1959
+ * DOM, so the app's own stylesheet still reaches it. Moving those nodes inside the shadow root
1960
+ * would cut them off from it — the same reason this build inlines SVGs instead of icon classes.
1961
+ */
1962
+ renderListSlot() {
1963
+ return html`<div class="mono-select-list-slot" mono-list-slot @click=${this._onListSlotClick}>
1964
+ <slot name="list" @slotchange=${() => this._scanSlots()}></slot>
1965
+ </div>`;
1966
+ }
1967
+ /** Native `<slot>` carrying the prop fallback as native slot content. */
1968
+ _slotOutlet(name, fallback = nothing) {
1969
+ return html`<slot
1970
+ name=${name}
1971
+ @slotchange=${(e) => this._onSlotChange(name, e)}
1972
+ >${fallback}</slot
1973
+ >`;
1974
+ }
1975
+ /** Inline SVG — the global `.mono-icon`/`i-mdi-*` UnoCSS icons can't reach a
1976
+ * shadow root. */
1977
+ renderIcon(name) {
1978
+ return html`<svg
1979
+ class="mono-icon"
1980
+ mono-icon
1981
+ viewBox="0 0 24 24"
1982
+ width="1em"
1983
+ height="1em"
1984
+ fill="currentColor"
1985
+ aria-hidden="true"
1986
+ >
1987
+ <path d=${name === "close" ? "M19 6.41 17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z" : "M7.41 8.58 12 13.17l4.59-4.59L18 10l-6 6-6-6z"}></path>
1988
+ </svg>`;
1989
+ }
1990
+ };
1991
+ MonoSelectShadow = __decorate([customElement("mono-shadow-select")], MonoSelectShadow);
1992
+ //#endregion
1993
+ //#region src/components/select/select-utils.ts
1994
+ function validateSelectProps(props) {
1995
+ const validSizes = [
1996
+ "xs",
1997
+ "sm",
1998
+ "md",
1999
+ "lg",
2000
+ "xl",
2001
+ "xxl"
2002
+ ];
2003
+ const validColors = [
2004
+ "primary",
2005
+ "secondary",
2006
+ "success",
2007
+ "danger",
2008
+ "warning",
2009
+ "info",
2010
+ "teal",
2011
+ "purple",
2012
+ "neutral",
2013
+ "dark"
2014
+ ];
2015
+ const validVariants = [
2016
+ "outlined",
2017
+ "filled",
2018
+ "underlined"
2019
+ ];
2020
+ const validStates = [
2021
+ "default",
2022
+ "valid",
2023
+ "invalid",
2024
+ "warning"
2025
+ ];
2026
+ if (props.size && !validSizes.includes(props.size)) return false;
2027
+ if (props.color && !validColors.includes(props.color)) return false;
2028
+ if (props.variant && !validVariants.includes(props.variant)) return false;
2029
+ if (props.validationState && !validStates.includes(props.validationState)) return false;
2030
+ return true;
2031
+ }
2032
+ //#endregion
2033
+ export { MonoSelectCore, MonoSelectShadow, validateSelectProps };