luxen-ui 0.22.0 → 0.23.0

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 (396) hide show
  1. package/bin/cli.mjs +1 -1
  2. package/cdn/chunks/decorate.js +1 -1
  3. package/cdn/chunks/decorate.js.map +1 -1
  4. package/cdn/chunks/directive.js.map +1 -1
  5. package/cdn/chunks/floating-ui.dom.js +1 -1
  6. package/cdn/chunks/floating-ui.dom.js.map +1 -1
  7. package/cdn/chunks/iconify-icon.js +1 -1
  8. package/cdn/chunks/iconify-icon.js.map +1 -1
  9. package/cdn/chunks/lit-html.js +1 -1
  10. package/cdn/chunks/lit-html.js.map +1 -1
  11. package/cdn/chunks/lit.js.map +1 -1
  12. package/cdn/chunks/map.js.map +1 -1
  13. package/cdn/chunks/picker.js +2 -2
  14. package/cdn/chunks/picker.js.map +1 -1
  15. package/cdn/chunks/query.js +2 -0
  16. package/cdn/chunks/query.js.map +1 -0
  17. package/cdn/chunks/static-html.js +1 -1
  18. package/cdn/chunks/static-html.js.map +1 -1
  19. package/cdn/chunks/unsafe-html.js.map +1 -1
  20. package/cdn/color-scheme.d.ts.map +1 -1
  21. package/cdn/color-scheme.js +1 -1
  22. package/cdn/color-scheme.js.map +1 -1
  23. package/cdn/custom-elements.json +47 -3
  24. package/cdn/define.d.ts +1 -1
  25. package/cdn/define.js.map +1 -1
  26. package/cdn/elements/alert/alert.d.ts +2 -1
  27. package/cdn/elements/alert/alert.d.ts.map +1 -1
  28. package/cdn/elements/alert/alert.js +1 -1
  29. package/cdn/elements/alert/alert.js.map +1 -1
  30. package/cdn/elements/alert/index.js.map +1 -1
  31. package/cdn/elements/alert-dialog/alert-dialog.d.ts +4 -3
  32. package/cdn/elements/alert-dialog/alert-dialog.d.ts.map +1 -1
  33. package/cdn/elements/alert-dialog/alert-dialog.js +5 -5
  34. package/cdn/elements/alert-dialog/alert-dialog.js.map +1 -1
  35. package/cdn/elements/alert-dialog/index.js.map +1 -1
  36. package/cdn/elements/avatar/avatar.d.ts +2 -2
  37. package/cdn/elements/avatar/avatar.d.ts.map +1 -1
  38. package/cdn/elements/avatar/avatar.js +8 -8
  39. package/cdn/elements/avatar/avatar.js.map +1 -1
  40. package/cdn/elements/avatar/index.js.map +1 -1
  41. package/cdn/elements/badge/badge.d.ts.map +1 -1
  42. package/cdn/elements/badge/badge.js +1 -1
  43. package/cdn/elements/badge/badge.js.map +1 -1
  44. package/cdn/elements/badge/index.js.map +1 -1
  45. package/cdn/elements/button-group/button-group.d.ts.map +1 -1
  46. package/cdn/elements/button-group/button-group.js +1 -1
  47. package/cdn/elements/button-group/button-group.js.map +1 -1
  48. package/cdn/elements/button-group/index.js.map +1 -1
  49. package/cdn/elements/carousel/carousel.d.ts +6 -6
  50. package/cdn/elements/carousel/carousel.d.ts.map +1 -1
  51. package/cdn/elements/carousel/carousel.js +4 -4
  52. package/cdn/elements/carousel/carousel.js.map +1 -1
  53. package/cdn/elements/carousel/index.js.map +1 -1
  54. package/cdn/elements/carousel-item/carousel-item.d.ts +2 -2
  55. package/cdn/elements/carousel-item/carousel-item.d.ts.map +1 -1
  56. package/cdn/elements/carousel-item/carousel-item.js.map +1 -1
  57. package/cdn/elements/carousel-item/index.js.map +1 -1
  58. package/cdn/elements/color-scheme-icon/color-scheme-icon.d.ts +3 -3
  59. package/cdn/elements/color-scheme-icon/color-scheme-icon.d.ts.map +1 -1
  60. package/cdn/elements/color-scheme-icon/color-scheme-icon.js +2 -2
  61. package/cdn/elements/color-scheme-icon/color-scheme-icon.js.map +1 -1
  62. package/cdn/elements/color-scheme-icon/index.js.map +1 -1
  63. package/cdn/elements/combobox/combobox.d.ts +15 -4
  64. package/cdn/elements/combobox/combobox.d.ts.map +1 -1
  65. package/cdn/elements/combobox/combobox.js +35 -33
  66. package/cdn/elements/combobox/combobox.js.map +1 -1
  67. package/cdn/elements/combobox/index.js.map +1 -1
  68. package/cdn/elements/dialog/dialog.d.ts +4 -4
  69. package/cdn/elements/dialog/dialog.d.ts.map +1 -1
  70. package/cdn/elements/dialog/dialog.js +13 -13
  71. package/cdn/elements/dialog/dialog.js.map +1 -1
  72. package/cdn/elements/dialog/dialog.styles.d.ts +1 -1
  73. package/cdn/elements/dialog/dialog.styles.d.ts.map +1 -1
  74. package/cdn/elements/dialog/dialog.styles.js.map +1 -1
  75. package/cdn/elements/dialog/index.js.map +1 -1
  76. package/cdn/elements/divider/divider.d.ts.map +1 -1
  77. package/cdn/elements/divider/divider.js +1 -1
  78. package/cdn/elements/divider/divider.js.map +1 -1
  79. package/cdn/elements/divider/index.js.map +1 -1
  80. package/cdn/elements/drawer/drawer.d.ts +2 -2
  81. package/cdn/elements/drawer/drawer.js +1 -1
  82. package/cdn/elements/drawer/drawer.js.map +1 -1
  83. package/cdn/elements/drawer/index.js.map +1 -1
  84. package/cdn/elements/dropdown/dropdown.d.ts +13 -5
  85. package/cdn/elements/dropdown/dropdown.d.ts.map +1 -1
  86. package/cdn/elements/dropdown/dropdown.js +2 -2
  87. package/cdn/elements/dropdown/dropdown.js.map +1 -1
  88. package/cdn/elements/dropdown/index.js.map +1 -1
  89. package/cdn/elements/dropdown-item/dropdown-item.d.ts +3 -3
  90. package/cdn/elements/dropdown-item/dropdown-item.d.ts.map +1 -1
  91. package/cdn/elements/dropdown-item/dropdown-item.js +5 -5
  92. package/cdn/elements/dropdown-item/dropdown-item.js.map +1 -1
  93. package/cdn/elements/dropdown-item/index.js.map +1 -1
  94. package/cdn/elements/dropdown-label/dropdown-label.d.ts +2 -2
  95. package/cdn/elements/dropdown-label/dropdown-label.d.ts.map +1 -1
  96. package/cdn/elements/dropdown-label/dropdown-label.js.map +1 -1
  97. package/cdn/elements/dropdown-label/index.js.map +1 -1
  98. package/cdn/elements/form-field/form-field.d.ts +1 -0
  99. package/cdn/elements/form-field/form-field.d.ts.map +1 -1
  100. package/cdn/elements/form-field/form-field.js +1 -1
  101. package/cdn/elements/form-field/form-field.js.map +1 -1
  102. package/cdn/elements/form-field/index.js.map +1 -1
  103. package/cdn/elements/icon/icon.d.ts +3 -3
  104. package/cdn/elements/icon/icon.d.ts.map +1 -1
  105. package/cdn/elements/icon/icon.js +1 -1
  106. package/cdn/elements/icon/icon.js.map +1 -1
  107. package/cdn/elements/icon/index.js.map +1 -1
  108. package/cdn/elements/input-group/index.js.map +1 -1
  109. package/cdn/elements/input-group/input-group.d.ts.map +1 -1
  110. package/cdn/elements/input-group/input-group.js +1 -1
  111. package/cdn/elements/input-group/input-group.js.map +1 -1
  112. package/cdn/elements/input-otp/index.js.map +1 -1
  113. package/cdn/elements/input-otp/input-otp.d.ts.map +1 -1
  114. package/cdn/elements/input-otp/input-otp.js +1 -1
  115. package/cdn/elements/input-otp/input-otp.js.map +1 -1
  116. package/cdn/elements/input-stepper/index.js.map +1 -1
  117. package/cdn/elements/input-stepper/input-stepper.d.ts.map +1 -1
  118. package/cdn/elements/input-stepper/input-stepper.js +1 -1
  119. package/cdn/elements/input-stepper/input-stepper.js.map +1 -1
  120. package/cdn/elements/popover/index.js.map +1 -1
  121. package/cdn/elements/popover/popover.d.ts +4 -4
  122. package/cdn/elements/popover/popover.d.ts.map +1 -1
  123. package/cdn/elements/popover/popover.js +6 -6
  124. package/cdn/elements/popover/popover.js.map +1 -1
  125. package/cdn/elements/prose-editor/index.js.map +1 -1
  126. package/cdn/elements/prose-editor/prose-editor.d.ts +73 -3
  127. package/cdn/elements/prose-editor/prose-editor.d.ts.map +1 -1
  128. package/cdn/elements/prose-editor/prose-editor.js +56 -71
  129. package/cdn/elements/prose-editor/prose-editor.js.map +1 -1
  130. package/cdn/elements/rating/index.js.map +1 -1
  131. package/cdn/elements/rating/rating.d.ts +3 -3
  132. package/cdn/elements/rating/rating.d.ts.map +1 -1
  133. package/cdn/elements/rating/rating.js +6 -6
  134. package/cdn/elements/rating/rating.js.map +1 -1
  135. package/cdn/elements/segmented-control/index.js.map +1 -1
  136. package/cdn/elements/segmented-control/segmented-control.d.ts.map +1 -1
  137. package/cdn/elements/segmented-control/segmented-control.js +1 -1
  138. package/cdn/elements/segmented-control/segmented-control.js.map +1 -1
  139. package/cdn/elements/select/index.js.map +1 -1
  140. package/cdn/elements/select/select.d.ts +11 -5
  141. package/cdn/elements/select/select.d.ts.map +1 -1
  142. package/cdn/elements/select/select.js +62 -57
  143. package/cdn/elements/select/select.js.map +1 -1
  144. package/cdn/elements/skeleton/index.js.map +1 -1
  145. package/cdn/elements/skeleton/skeleton.d.ts.map +1 -1
  146. package/cdn/elements/skeleton/skeleton.js.map +1 -1
  147. package/cdn/elements/slider/index.js.map +1 -1
  148. package/cdn/elements/slider/slider.d.ts +3 -3
  149. package/cdn/elements/slider/slider.d.ts.map +1 -1
  150. package/cdn/elements/slider/slider.js +2 -2
  151. package/cdn/elements/slider/slider.js.map +1 -1
  152. package/cdn/elements/spinner/index.js.map +1 -1
  153. package/cdn/elements/spinner/spinner.d.ts +2 -2
  154. package/cdn/elements/spinner/spinner.d.ts.map +1 -1
  155. package/cdn/elements/spinner/spinner.js.map +1 -1
  156. package/cdn/elements/sticky-bar/index.js.map +1 -1
  157. package/cdn/elements/sticky-bar/sticky-bar.d.ts +3 -3
  158. package/cdn/elements/sticky-bar/sticky-bar.d.ts.map +1 -1
  159. package/cdn/elements/sticky-bar/sticky-bar.js +1 -1
  160. package/cdn/elements/sticky-bar/sticky-bar.js.map +1 -1
  161. package/cdn/elements/stories/index.js.map +1 -1
  162. package/cdn/elements/stories/stories.d.ts +1 -1
  163. package/cdn/elements/stories/stories.d.ts.map +1 -1
  164. package/cdn/elements/stories/stories.js +1 -1
  165. package/cdn/elements/stories/stories.js.map +1 -1
  166. package/cdn/elements/stories-viewer/index.js.map +1 -1
  167. package/cdn/elements/stories-viewer/stories-viewer.d.ts +4 -4
  168. package/cdn/elements/stories-viewer/stories-viewer.d.ts.map +1 -1
  169. package/cdn/elements/stories-viewer/stories-viewer.js +33 -33
  170. package/cdn/elements/stories-viewer/stories-viewer.js.map +1 -1
  171. package/cdn/elements/story/index.js.map +1 -1
  172. package/cdn/elements/story/story.d.ts +1 -1
  173. package/cdn/elements/story/story.d.ts.map +1 -1
  174. package/cdn/elements/story/story.js +8 -8
  175. package/cdn/elements/story/story.js.map +1 -1
  176. package/cdn/elements/tabs/index.js.map +1 -1
  177. package/cdn/elements/tabs/tabs.d.ts.map +1 -1
  178. package/cdn/elements/tabs/tabs.js +1 -1
  179. package/cdn/elements/tabs/tabs.js.map +1 -1
  180. package/cdn/elements/tag/index.js.map +1 -1
  181. package/cdn/elements/tag/tag.d.ts +2 -2
  182. package/cdn/elements/tag/tag.d.ts.map +1 -1
  183. package/cdn/elements/tag/tag.js +3 -3
  184. package/cdn/elements/tag/tag.js.map +1 -1
  185. package/cdn/elements/toast/index.js.map +1 -1
  186. package/cdn/elements/toast/toast.d.ts.map +1 -1
  187. package/cdn/elements/toast/toast.js +1 -1
  188. package/cdn/elements/toast/toast.js.map +1 -1
  189. package/cdn/elements/tooltip/index.js.map +1 -1
  190. package/cdn/elements/tooltip/tooltip.d.ts +4 -4
  191. package/cdn/elements/tooltip/tooltip.d.ts.map +1 -1
  192. package/cdn/elements/tooltip/tooltip.js +6 -6
  193. package/cdn/elements/tooltip/tooltip.js.map +1 -1
  194. package/cdn/elements/tree/index.js.map +1 -1
  195. package/cdn/elements/tree/tree.d.ts +4 -4
  196. package/cdn/elements/tree/tree.d.ts.map +1 -1
  197. package/cdn/elements/tree/tree.js +2 -2
  198. package/cdn/elements/tree/tree.js.map +1 -1
  199. package/cdn/elements/tree-item/index.js.map +1 -1
  200. package/cdn/elements/tree-item/tree-item.d.ts +3 -3
  201. package/cdn/elements/tree-item/tree-item.d.ts.map +1 -1
  202. package/cdn/elements/tree-item/tree-item.js +33 -33
  203. package/cdn/elements/tree-item/tree-item.js.map +1 -1
  204. package/cdn/events/after-hide.d.ts.map +1 -1
  205. package/cdn/events/after-hide.js.map +1 -1
  206. package/cdn/events/after-show.d.ts.map +1 -1
  207. package/cdn/events/after-show.js.map +1 -1
  208. package/cdn/events/hide.d.ts.map +1 -1
  209. package/cdn/events/hide.js.map +1 -1
  210. package/cdn/events/show.d.ts.map +1 -1
  211. package/cdn/events/show.js.map +1 -1
  212. package/cdn/registry.js +1 -1
  213. package/cdn/registry.js.map +1 -1
  214. package/cdn/shared/controllers/datalist-observer.d.ts +1 -1
  215. package/cdn/shared/controllers/datalist-observer.d.ts.map +1 -1
  216. package/cdn/shared/controllers/datalist-observer.js.map +1 -1
  217. package/cdn/shared/controllers/has-slot-controller.d.ts +1 -1
  218. package/cdn/shared/controllers/has-slot-controller.d.ts.map +1 -1
  219. package/cdn/shared/controllers/has-slot-controller.js +1 -1
  220. package/cdn/shared/controllers/has-slot-controller.js.map +1 -1
  221. package/cdn/shared/controllers/listbox-nav.d.ts +1 -1
  222. package/cdn/shared/controllers/listbox-nav.d.ts.map +1 -1
  223. package/cdn/shared/controllers/listbox-nav.js.map +1 -1
  224. package/cdn/shared/controllers/popover.d.ts +2 -2
  225. package/cdn/shared/controllers/popover.d.ts.map +1 -1
  226. package/cdn/shared/controllers/popover.js +1 -1
  227. package/cdn/shared/controllers/popover.js.map +1 -1
  228. package/cdn/shared/highlight.d.ts +16 -0
  229. package/cdn/shared/highlight.d.ts.map +1 -0
  230. package/cdn/shared/highlight.js +2 -0
  231. package/cdn/shared/highlight.js.map +1 -0
  232. package/cdn/shared/localize.d.ts +1 -1
  233. package/cdn/shared/localize.d.ts.map +1 -1
  234. package/cdn/shared/localize.js +1 -1
  235. package/cdn/shared/localize.js.map +1 -1
  236. package/cdn/shared/luxen-element.js.map +1 -1
  237. package/cdn/shared/luxen-form-associated-element.d.ts.map +1 -1
  238. package/cdn/shared/luxen-form-associated-element.js +1 -1
  239. package/cdn/shared/luxen-form-associated-element.js.map +1 -1
  240. package/cdn/shared/rich-option.d.ts +20 -0
  241. package/cdn/shared/rich-option.d.ts.map +1 -0
  242. package/cdn/shared/rich-option.js +2 -0
  243. package/cdn/shared/rich-option.js.map +1 -0
  244. package/cdn/shared/styles/badge-core.styles.d.ts +9 -0
  245. package/cdn/shared/styles/badge-core.styles.d.ts.map +1 -0
  246. package/cdn/shared/styles/badge-core.styles.js +2 -0
  247. package/cdn/shared/styles/badge-core.styles.js.map +1 -0
  248. package/cdn/shared/styles/button-core.styles.d.ts +1 -1
  249. package/cdn/shared/styles/button-core.styles.d.ts.map +1 -1
  250. package/cdn/shared/styles/button-core.styles.js.map +1 -1
  251. package/cdn/shared/styles/checkbox-appearance.styles.d.ts +1 -1
  252. package/cdn/shared/styles/checkbox-appearance.styles.d.ts.map +1 -1
  253. package/cdn/shared/styles/checkbox-appearance.styles.js.map +1 -1
  254. package/cdn/shared/styles/host.styles.d.ts +1 -1
  255. package/cdn/shared/styles/host.styles.d.ts.map +1 -1
  256. package/cdn/shared/styles/host.styles.js.map +1 -1
  257. package/cdn/shared/styles/select-item-suffix.styles.d.ts +8 -0
  258. package/cdn/shared/styles/select-item-suffix.styles.d.ts.map +1 -0
  259. package/cdn/shared/styles/select-item-suffix.styles.js +2 -0
  260. package/cdn/shared/styles/select-item-suffix.styles.js.map +1 -0
  261. package/cdn/standalone.css +273 -233
  262. package/cdn/standalone.js +40349 -105
  263. package/cdn/standalone.js.map +1 -1
  264. package/cdn/static-tag.d.ts +2 -2
  265. package/cdn/static-tag.js +1 -1
  266. package/cdn/static-tag.js.map +1 -1
  267. package/cdn/styles/base.css +1 -48
  268. package/cdn/styles/elements/badge.css +202 -182
  269. package/cdn/styles/elements/checkbox.css +1 -4
  270. package/cdn/styles/elements/select.css +71 -3
  271. package/cdn/styles/preset.css +4 -49
  272. package/cdn/styles/tokens/aliases.css +1 -3
  273. package/cdn/styles/tokens/forms.css +5 -3
  274. package/cdn/styles/tokens/primitives.css +1 -3
  275. package/cdn/styles/tokens.css +5 -5
  276. package/cdn/translations/en.d.ts +1 -1
  277. package/cdn/translations/en.d.ts.map +1 -1
  278. package/cdn/translations/en.js.map +1 -1
  279. package/cdn/translations/fr.d.ts +1 -1
  280. package/cdn/translations/fr.d.ts.map +1 -1
  281. package/cdn/translations/fr.js.map +1 -1
  282. package/cdn/translations/ko.d.ts +1 -1
  283. package/cdn/translations/ko.d.ts.map +1 -1
  284. package/cdn/translations/ko.js.map +1 -1
  285. package/dist/color-scheme.d.ts.map +1 -1
  286. package/dist/css/base.css +1 -48
  287. package/dist/css/elements/badge.css +202 -182
  288. package/dist/css/elements/checkbox.css +1 -4
  289. package/dist/css/elements/select.css +71 -3
  290. package/dist/css/preset.css +4 -49
  291. package/dist/css/tokens/aliases.css +1 -3
  292. package/dist/css/tokens/forms.css +5 -3
  293. package/dist/css/tokens/primitives.css +1 -3
  294. package/dist/css/tokens.css +5 -5
  295. package/dist/custom-elements.json +47 -3
  296. package/dist/elements/alert/alert.d.ts.map +1 -1
  297. package/dist/elements/alert-dialog/alert-dialog.d.ts.map +1 -1
  298. package/dist/elements/avatar/avatar.d.ts.map +1 -1
  299. package/dist/elements/badge/badge.d.ts.map +1 -1
  300. package/dist/elements/button-group/button-group.d.ts.map +1 -1
  301. package/dist/elements/carousel/carousel.d.ts.map +1 -1
  302. package/dist/elements/carousel-item/carousel-item.d.ts.map +1 -1
  303. package/dist/elements/color-scheme-icon/color-scheme-icon.d.ts.map +1 -1
  304. package/dist/elements/combobox/combobox.css +7 -3
  305. package/dist/elements/combobox/combobox.d.ts +12 -1
  306. package/dist/elements/combobox/combobox.d.ts.map +1 -1
  307. package/dist/elements/combobox/combobox.js +52 -46
  308. package/dist/elements/dialog/dialog.d.ts.map +1 -1
  309. package/dist/elements/dialog/dialog.js +10 -10
  310. package/dist/elements/dialog/dialog.styles.d.ts.map +1 -1
  311. package/dist/elements/divider/divider.d.ts.map +1 -1
  312. package/dist/elements/drawer/drawer.d.ts +1 -1
  313. package/dist/elements/dropdown/dropdown.d.ts +8 -0
  314. package/dist/elements/dropdown/dropdown.d.ts.map +1 -1
  315. package/dist/elements/dropdown/dropdown.js +33 -8
  316. package/dist/elements/dropdown-item/dropdown-item.d.ts.map +1 -1
  317. package/dist/elements/dropdown-item/dropdown-item.js +3 -3
  318. package/dist/elements/dropdown-label/dropdown-label.d.ts.map +1 -1
  319. package/dist/elements/form-field/form-field.d.ts +1 -0
  320. package/dist/elements/form-field/form-field.d.ts.map +1 -1
  321. package/dist/elements/form-field/form-field.js +14 -2
  322. package/dist/elements/icon/icon.d.ts.map +1 -1
  323. package/dist/elements/input-group/input-group.d.ts.map +1 -1
  324. package/dist/elements/input-otp/input-otp.d.ts.map +1 -1
  325. package/dist/elements/input-stepper/input-stepper.d.ts.map +1 -1
  326. package/dist/elements/popover/popover.d.ts.map +1 -1
  327. package/dist/elements/popover/popover.js +5 -5
  328. package/dist/elements/prose-editor/prose-editor.d.ts +69 -0
  329. package/dist/elements/prose-editor/prose-editor.d.ts.map +1 -1
  330. package/dist/elements/prose-editor/prose-editor.js +183 -22
  331. package/dist/elements/rating/rating.d.ts.map +1 -1
  332. package/dist/elements/rating/rating.js +5 -5
  333. package/dist/elements/segmented-control/segmented-control.d.ts.map +1 -1
  334. package/dist/elements/select/select.css +12 -6
  335. package/dist/elements/select/select.d.ts +8 -3
  336. package/dist/elements/select/select.d.ts.map +1 -1
  337. package/dist/elements/select/select.js +68 -60
  338. package/dist/elements/skeleton/skeleton.d.ts.map +1 -1
  339. package/dist/elements/slider/slider.d.ts.map +1 -1
  340. package/dist/elements/spinner/spinner.d.ts.map +1 -1
  341. package/dist/elements/sticky-bar/sticky-bar.d.ts.map +1 -1
  342. package/dist/elements/stories/stories.d.ts.map +1 -1
  343. package/dist/elements/stories-viewer/stories-viewer.d.ts.map +1 -1
  344. package/dist/elements/stories-viewer/stories-viewer.js +16 -16
  345. package/dist/elements/story/story.d.ts.map +1 -1
  346. package/dist/elements/tabs/tabs.d.ts.map +1 -1
  347. package/dist/elements/tag/tag.css +10 -9
  348. package/dist/elements/tag/tag.d.ts.map +1 -1
  349. package/dist/elements/toast/toast.d.ts.map +1 -1
  350. package/dist/elements/tooltip/tooltip.d.ts.map +1 -1
  351. package/dist/elements/tooltip/tooltip.js +5 -5
  352. package/dist/elements/tree/tree.d.ts.map +1 -1
  353. package/dist/elements/tree-item/tree-item.css +17 -7
  354. package/dist/elements/tree-item/tree-item.d.ts.map +1 -1
  355. package/dist/elements/tree-item/tree-item.js +29 -29
  356. package/dist/events/after-hide.d.ts.map +1 -1
  357. package/dist/events/after-show.d.ts.map +1 -1
  358. package/dist/events/hide.d.ts.map +1 -1
  359. package/dist/events/show.d.ts.map +1 -1
  360. package/dist/metadata/combobox.json +23 -2
  361. package/dist/metadata/index.json +47 -5
  362. package/dist/metadata/prose-editor.json +1 -1
  363. package/dist/metadata/select.json +22 -1
  364. package/dist/shared/controllers/datalist-observer.d.ts.map +1 -1
  365. package/dist/shared/controllers/has-slot-controller.d.ts.map +1 -1
  366. package/dist/shared/controllers/listbox-nav.d.ts.map +1 -1
  367. package/dist/shared/controllers/popover.d.ts.map +1 -1
  368. package/dist/shared/highlight.d.ts +16 -0
  369. package/dist/shared/highlight.d.ts.map +1 -0
  370. package/dist/shared/highlight.js +140 -0
  371. package/dist/shared/localize.d.ts.map +1 -1
  372. package/dist/shared/localize.js +1 -1
  373. package/dist/shared/luxen-form-associated-element.d.ts.map +1 -1
  374. package/dist/shared/rich-option.d.ts +20 -0
  375. package/dist/shared/rich-option.d.ts.map +1 -0
  376. package/dist/shared/rich-option.js +82 -0
  377. package/dist/shared/styles/badge-core.css +221 -0
  378. package/dist/shared/styles/badge-core.styles.d.ts +9 -0
  379. package/dist/shared/styles/badge-core.styles.d.ts.map +1 -0
  380. package/dist/shared/styles/badge-core.styles.js +9 -0
  381. package/dist/shared/styles/button-core.styles.d.ts.map +1 -1
  382. package/dist/shared/styles/checkbox-appearance.styles.d.ts.map +1 -1
  383. package/dist/shared/styles/host.styles.d.ts.map +1 -1
  384. package/dist/shared/styles/select-item-suffix.css +60 -0
  385. package/dist/shared/styles/select-item-suffix.styles.d.ts +8 -0
  386. package/dist/shared/styles/select-item-suffix.styles.d.ts.map +1 -0
  387. package/dist/shared/styles/select-item-suffix.styles.js +8 -0
  388. package/dist/templates/elements/combobox.md +155 -1
  389. package/dist/templates/elements/prose-editor.md +2 -1
  390. package/dist/templates/elements/radio-group.md +2 -2
  391. package/dist/templates/elements/select.md +212 -3
  392. package/dist/templates/elements/textarea.md +2 -4
  393. package/dist/translations/en.d.ts.map +1 -1
  394. package/dist/translations/fr.d.ts.map +1 -1
  395. package/dist/translations/ko.d.ts.map +1 -1
  396. package/package.json +21 -21
@@ -0,0 +1,221 @@
1
+ /*
2
+ * Shared `l-badge` appearance — the single source of truth for the badge's look.
3
+ * Lives in the HTML tree so it is both:
4
+ * - `@import`ed (and layered) by src/css/elements/badge.css for light-DOM
5
+ * badges, and
6
+ * - imported `?inline` into shadow-DOM elements whose rendered content can
7
+ * carry a badge (l-select / l-combobox copy each rich option's markup into
8
+ * their shadow root, where the global badge stylesheet cannot reach).
9
+ *
10
+ * Intentionally UNLAYERED, like button-core.css: the light-DOM import wraps it in
11
+ * `@layer components` via `@import … layer(components)`, while shadow consumers
12
+ * want it unlayered alongside their own (also unlayered) styles.
13
+ */
14
+
15
+ /*
16
+ Autonomous custom elements
17
+ https://blog.jim-nielsen.com/2021/custom-elements-without-js/
18
+ */
19
+ l-badge {
20
+ /* Per-variant primitives — set by [variant], consumed by appearance. The
21
+ public hooks that override them are threaded at the declaration sites
22
+ below rather than here, so this whole machinery stays untouched: a
23
+ consumer value is not competing with `[variant]` / `[appearance]` /
24
+ `[pill]` on specificity, it sits under them.
25
+
26
+ Four hooks, and each one earns its place by hiding something a consumer
27
+ would otherwise have to know:
28
+
29
+ --text-color the line is a tint of it, so one declaration
30
+ repaints the whole chip
31
+ --background-color which per-appearance token it is replacing
32
+ --border-color the 30% mix, and that it holds through `filled`,
33
+ whose default line is transparent
34
+ --border-radius that the corner is a squircle, not a plain arc
35
+
36
+ Size and spacing get no hook on purpose. `--height` / `--font-size` /
37
+ `--padding-inline` would be pass-throughs to the identically named
38
+ properties declared a few lines below, hiding nothing — and `size` is
39
+ already the API for that axis. Three steps are the design; a badge that
40
+ can be dialled to any height stops being a size step and starts being a
41
+ box.
42
+
43
+ The line derives from `currentColor` rather than from `--_text-color`, so
44
+ it follows the ink whoever set it — the hook, a variant, or a consumer's
45
+ own `color` declaration. */
46
+ --_text-color: var(--l-color-text-neutral);
47
+ --_background-color: transparent;
48
+ --_border-color: color-mix(in oklab, currentColor 30%, transparent);
49
+ --_border-radius: var(--l-radius-md);
50
+
51
+ /* Size defaults (md) */
52
+ --_height: 1.375rem;
53
+ --_font-size: var(--l-text-xs);
54
+ --_padding-inline: 0.375rem;
55
+ --_gap: 0.25rem;
56
+
57
+ display: inline-flex;
58
+ align-items: center;
59
+ gap: var(--_gap);
60
+ min-height: var(--_height);
61
+ padding-block: 0.25rem;
62
+ padding-inline: var(--_padding-inline);
63
+ border: 1px solid var(--border-color, var(--_border-color));
64
+ border-radius: var(--border-radius, var(--_border-radius));
65
+ corner-shape: squircle;
66
+ background-color: var(--background-color, var(--_background-color));
67
+ color: var(--text-color, var(--_text-color));
68
+ font-family: var(--l-font-neo-grotesque);
69
+ font-size: var(--_font-size);
70
+ font-weight: var(--l-font-weight-medium);
71
+ line-height: 1;
72
+ text-box: trim-both cap alphabetic;
73
+
74
+ /*
75
+ ▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬
76
+ 🆂🅸🆉🅴🆂
77
+ ▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬
78
+ */
79
+
80
+ &[size='sm'] {
81
+ --_height: 1.25rem;
82
+ --_padding-inline: 0.25rem;
83
+ --_gap: 0.125rem;
84
+ }
85
+ &[size='lg'] {
86
+ --_height: 1.5rem;
87
+ --_font-size: var(--l-text-sm);
88
+ --_padding-inline: 0.5rem;
89
+ }
90
+
91
+ /*
92
+ ▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬
93
+ 🆅🅰🆁🅸🅰🅽🆃🆂
94
+ ▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬
95
+ */
96
+
97
+ &[variant='info'] {
98
+ --_text-color: var(--l-color-text-info);
99
+ }
100
+ &[variant='success'] {
101
+ --_text-color: var(--l-color-text-success);
102
+ }
103
+ &[variant='warning'] {
104
+ --_text-color: var(--l-color-text-warning);
105
+ }
106
+ &[variant='danger'] {
107
+ --_text-color: var(--l-color-text-danger);
108
+ }
109
+
110
+ /*
111
+ ▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬
112
+ 🅰🅿🅿🅴🅰🆁🅰🅽🅲🅴
113
+ ▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬
114
+ */
115
+
116
+ &[appearance='filled'] {
117
+ --_background-color: var(--l-color-bg-fill-neutral-subtle);
118
+ --_border-color: transparent;
119
+
120
+ &[variant='info'] {
121
+ --_background-color: var(--l-color-bg-fill-info-subtle);
122
+ }
123
+ &[variant='success'] {
124
+ --_background-color: var(--l-color-bg-fill-success-subtle);
125
+ }
126
+ &[variant='warning'] {
127
+ --_background-color: var(--l-color-bg-fill-warning-subtle);
128
+ }
129
+ &[variant='danger'] {
130
+ --_background-color: var(--l-color-bg-fill-danger-subtle);
131
+ }
132
+ }
133
+
134
+ &[appearance='filled-outlined'] {
135
+ --_background-color: var(--l-color-bg-fill-neutral-subtle);
136
+
137
+ &[variant='info'] {
138
+ --_background-color: var(--l-color-bg-fill-info-subtle);
139
+ }
140
+ &[variant='success'] {
141
+ --_background-color: var(--l-color-bg-fill-success-subtle);
142
+ }
143
+ &[variant='warning'] {
144
+ --_background-color: var(--l-color-bg-fill-warning-subtle);
145
+ }
146
+ &[variant='danger'] {
147
+ --_background-color: var(--l-color-bg-fill-danger-subtle);
148
+ }
149
+ }
150
+
151
+ &[appearance='accent'] {
152
+ --_background-color: var(--l-color-bg-fill-neutral-strong);
153
+ --_text-color: var(--l-color-surface);
154
+ --_border-color: transparent;
155
+
156
+ &[variant='info'] {
157
+ --_background-color: var(--l-color-bg-fill-info-strong);
158
+ --_text-color: white;
159
+ }
160
+ &[variant='success'] {
161
+ --_background-color: var(--l-color-bg-fill-success-strong);
162
+ }
163
+ &[variant='warning'] {
164
+ --_background-color: var(--l-color-bg-fill-warning-strong);
165
+ }
166
+ &[variant='danger'] {
167
+ --_background-color: var(--l-color-bg-fill-danger-strong);
168
+ --_text-color: white;
169
+ }
170
+ }
171
+
172
+ /*
173
+ ▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬
174
+ 🅿🅸🅻🅻
175
+ ▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬
176
+ */
177
+
178
+ /* `--border-radius` keeps the squircle; `pill` is what trades it for a true
179
+ arc, because a squircle at a full radius reads as a blob. */
180
+ &[pill] {
181
+ --_border-radius: var(--l-radius-full);
182
+ corner-shape: unset;
183
+ }
184
+
185
+ /*
186
+ ▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬
187
+ 🅸🅲🅾🅽
188
+ ▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬
189
+ */
190
+
191
+ iconify-icon {
192
+ color: currentColor;
193
+ height: 1em;
194
+ }
195
+ }
196
+
197
+ /* A glyph against an edge earns a tighter padding on that side: its bounding
198
+ box already reads as air, so the label keeps the full gutter and the chip
199
+ does not go lopsided.
200
+
201
+ Matches whichever icon element the consumer composes — the library's own
202
+ `l-icon`, a raw `iconify-icon`, or the inline `<svg>` a framework Iconify
203
+ binding renders. `l-icon` needs naming explicitly: its `iconify-icon` sits
204
+ in a shadow root this selector cannot see, so matching the inner element
205
+ alone silently skipped the correction (the icon still laid out — `l-icon`
206
+ is `display: contents` — it just sat 2px too far in). Same element set
207
+ `toast.css` and `story.css` already use. */
208
+ l-badge:has(:is(iconify-icon, l-icon, svg):first-child) {
209
+ padding-inline-start: 0.25rem;
210
+ }
211
+
212
+ /* `:not(:first-child)` is what makes a trailing icon addressable at all.
213
+ `:first-child` and `:last-child` count elements, not text, so an icon that
214
+ is the badge's only element child matches both — `<l-badge>Lyon <l-icon/>`
215
+ is indistinguishable from `<l-badge><l-icon/>Lyon`, and the rule above
216
+ already claims it. Requiring a preceding element keeps that case exactly as
217
+ it was and makes this one exact: wrap the label (`<span>Lyon</span>`) and
218
+ the icon is unambiguously at the end. */
219
+ l-badge:has(:is(iconify-icon, l-icon, svg):last-child:not(:first-child)) {
220
+ padding-inline-end: 0.25rem;
221
+ }
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Wrapper module for the shared `l-badge` appearance. `unsafeCSS()` is called
3
+ * once here so every shadow-DOM element that can render a badge (l-select,
4
+ * l-combobox rich options) shares one `CSSResult` (one constructed
5
+ * `CSSStyleSheet`, not one per importer).
6
+ */
7
+ declare const _default: import("lit").CSSResult;
8
+ export default _default;
9
+ //# sourceMappingURL=badge-core.styles.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"badge-core.styles.d.ts","sourceRoot":"","sources":["../../../src/html/shared/styles/badge-core.styles.ts"],"names":[],"mappings":"AAGA;;;;;GAKG"}
@@ -0,0 +1,9 @@
1
+ import { unsafeCSS } from 'lit';
2
+ import raw from './badge-core.css?inline';
3
+ /**
4
+ * Wrapper module for the shared `l-badge` appearance. `unsafeCSS()` is called
5
+ * once here so every shadow-DOM element that can render a badge (l-select,
6
+ * l-combobox rich options) shares one `CSSResult` (one constructed
7
+ * `CSSStyleSheet`, not one per importer).
8
+ */
9
+ export default unsafeCSS(raw);
@@ -1 +1 @@
1
- {"version":3,"file":"button-core.styles.d.ts","sourceRoot":"","sources":["../../../src/html/shared/styles/button-core.styles.ts"],"names":[],"mappings":"AAGA;;;;;GAKG;;AACH,wBAA8B"}
1
+ {"version":3,"file":"button-core.styles.d.ts","sourceRoot":"","sources":["../../../src/html/shared/styles/button-core.styles.ts"],"names":[],"mappings":"AAGA;;;;;GAKG"}
@@ -1 +1 @@
1
- {"version":3,"file":"checkbox-appearance.styles.d.ts","sourceRoot":"","sources":["../../../src/html/shared/styles/checkbox-appearance.styles.ts"],"names":[],"mappings":"AAGA;;;;;GAKG;;AACH,wBAA8B"}
1
+ {"version":3,"file":"checkbox-appearance.styles.d.ts","sourceRoot":"","sources":["../../../src/html/shared/styles/checkbox-appearance.styles.ts"],"names":[],"mappings":"AAGA;;;;;GAKG"}
@@ -1 +1 @@
1
- {"version":3,"file":"host.styles.d.ts","sourceRoot":"","sources":["../../../src/html/shared/styles/host.styles.ts"],"names":[],"mappings":"AAGA;;;;;GAKG;;AACH,wBAA8B"}
1
+ {"version":3,"file":"host.styles.d.ts","sourceRoot":"","sources":["../../../src/html/shared/styles/host.styles.ts"],"names":[],"mappings":"AAGA;;;;;GAKG"}
@@ -0,0 +1,60 @@
1
+ /*
2
+ * Suffix of a rich option (`.l-select-item-suffix`) — a badge, count or
3
+ * status icon pinned to the inline-end of the row, after `.l-select-item-text`.
4
+ * One source for every tier, so they cannot drift apart:
5
+ * - `@import`ed (and layered) by src/css/elements/select.css for the native
6
+ * `select.l-select` picker, where `.l-select option` is the row, and
7
+ * - imported `?inline` into the l-select / l-combobox shadow roots, which copy
8
+ * each option's markup and cannot reach the global stylesheet; there
9
+ * `:host .option-rich` is the row. `:host` never matches in a document, so
10
+ * the light-DOM copy cannot reach a consumer's own `.option-rich`.
11
+ *
12
+ * A class, not a `slot="suffix"` attribute hook: in a customizable select the
13
+ * <option> has its own UA shadow root, so a child carrying a `slot` it has no
14
+ * slot for is not rendered at all. A class keeps one markup for every tier.
15
+ *
16
+ * Intentionally UNLAYERED, like button-core.css. Each tier hides the suffix in
17
+ * its own trigger next to its description rule.
18
+ */
19
+
20
+ /* The row's line box as an absolute length — the title's line, since the title
21
+ inherits the row's font and line-height. Registered so `1lh` resolves on the
22
+ row and is inherited as a length; unregistered it would resolve on the
23
+ smaller suffix. A shadow root ignores this rule, so rich-option.ts also
24
+ registers it from JS. */
25
+ @property --_select-item-line {
26
+ syntax: '<length>';
27
+ inherits: true;
28
+ initial-value: 0px;
29
+ }
30
+
31
+ :is(.l-select option, :host .option-rich) {
32
+ --_select-item-line: 1lh;
33
+ }
34
+
35
+ .l-select-item-suffix {
36
+ display: inline-flex;
37
+ /* Never shrinks: the text column gives way first and its title truncates. */
38
+ flex: 0 0 auto;
39
+ align-items: center;
40
+ /* Sits on the title's line rather than the row's middle — like the checkmark
41
+ and the media — so a wrapping description never moves it: a box exactly one
42
+ title line tall, pinned to the top, centres its content on that line. Content
43
+ taller than the line (a badge in a tight row, an avatar) overflows it evenly
44
+ above and below, into the row's padding, and never moves the title. */
45
+ align-self: flex-start;
46
+ block-size: var(--_select-item-line);
47
+ gap: 0.25rem;
48
+ margin-inline-start: auto;
49
+ white-space: nowrap;
50
+ color: var(--l-color-text-tertiary);
51
+ font-size: 0.75rem;
52
+ }
53
+
54
+ /* In a picker row that carries a suffix, the text column is pinned to the top
55
+ too, so the title shares the suffix's line in a centred row (l-combobox).
56
+ Scoped to the rows: the trigger's copy of the selected option (where the
57
+ suffix is hidden) keeps its own centring. */
58
+ :is(.l-select option, :host .option-rich) > .l-select-item-text:has(~ .l-select-item-suffix) {
59
+ align-self: flex-start;
60
+ }
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Wrapper module for the shared rich-option trailing zone. `unsafeCSS()` is
3
+ * called once here so l-select and l-combobox share one `CSSResult` (one
4
+ * constructed `CSSStyleSheet`, not one per importer).
5
+ */
6
+ declare const _default: import("lit").CSSResult;
7
+ export default _default;
8
+ //# sourceMappingURL=select-item-suffix.styles.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"select-item-suffix.styles.d.ts","sourceRoot":"","sources":["../../../src/html/shared/styles/select-item-suffix.styles.ts"],"names":[],"mappings":"AAGA;;;;GAIG"}
@@ -0,0 +1,8 @@
1
+ import { unsafeCSS } from 'lit';
2
+ import raw from './select-item-suffix.css?inline';
3
+ /**
4
+ * Wrapper module for the shared rich-option trailing zone. `unsafeCSS()` is
5
+ * called once here so l-select and l-combobox share one `CSSResult` (one
6
+ * constructed `CSSStyleSheet`, not one per importer).
7
+ */
8
+ export default unsafeCSS(raw);
@@ -94,6 +94,8 @@ Add `allow-custom` to accept a typed value that matches no option.
94
94
 
95
95
  Put markup inside each `<option>` — the same `.l-select-item-media` / `.l-select-item-text` / `.l-select-item-title` / `.l-select-item-description` classes as [`<select>`](/elements/select). Set a `label` (or `.l-select-item-title`) so filtering and the input display use the title.
96
96
 
97
+ As you type, the match is highlighted inside `.l-select-item-title` and `.l-select-item-description`, with the same accent/case-insensitive matching as plain options. Only the text is wrapped in `<mark>`; the option's markup is kept as authored.
98
+
97
99
  ```html
98
100
  <div class="w-72">
99
101
  <l-combobox
@@ -136,6 +138,71 @@ Put markup inside each `<option>` — the same `.l-select-item-media` / `.l-sele
136
138
  </div>
137
139
  ```
138
140
 
141
+ #### Suffix
142
+
143
+ Add a `.l-select-item-suffix` after `.l-select-item-text` to pin a badge, a count or a status icon to the end of the row, before the checkmark. It sits on the title's line, keeps its natural width while the title truncates, and is never matched by the filter or written into the input. Rich options are copied into the popover's shadow root: an [`<l-badge>`](/elements/badge) is styled there, but your page's own selectors don't reach that copy. To theme it, set the badge's CSS custom properties on the `<l-combobox>`: they inherit into the popover. Screen readers announce the suffix with its option, so write it as words ("12 members", not "12").
144
+
145
+ ```html
146
+ <div class="w-80">
147
+ <l-combobox
148
+ label="Team"
149
+ placeholder="Search a team…"
150
+ >
151
+ <datalist>
152
+ <option
153
+ value="design"
154
+ label="Design"
155
+ >
156
+ <span class="l-select-item-text">
157
+ <span class="l-select-item-title">Design</span>
158
+ <span class="l-select-item-description">Product and brand design</span>
159
+ </span>
160
+ <span class="l-select-item-suffix">
161
+ <l-badge
162
+ size="sm"
163
+ appearance="filled"
164
+ >12 members</l-badge
165
+ >
166
+ </span>
167
+ </option>
168
+ <option
169
+ value="engineering"
170
+ label="Engineering"
171
+ >
172
+ <span class="l-select-item-text">
173
+ <span class="l-select-item-title">Engineering</span>
174
+ <span class="l-select-item-description">Platform, web and mobile apps</span>
175
+ </span>
176
+ <span class="l-select-item-suffix">
177
+ <l-badge
178
+ size="sm"
179
+ appearance="filled"
180
+ >48 members</l-badge
181
+ >
182
+ </span>
183
+ </option>
184
+ <option
185
+ value="support"
186
+ label="Support"
187
+ >
188
+ <span class="l-select-item-text">
189
+ <span class="l-select-item-title">Support</span>
190
+ <span class="l-select-item-description">Customer success and onboarding</span>
191
+ </span>
192
+ <span class="l-select-item-suffix">
193
+ <l-badge
194
+ size="sm"
195
+ appearance="filled"
196
+ variant="warning"
197
+ >Full</l-badge
198
+ >
199
+ </span>
200
+ </option>
201
+ </datalist>
202
+ </l-combobox>
203
+ </div>
204
+ ```
205
+
139
206
  ### Disabled
140
207
 
141
208
  Native `disabled` attribute.
@@ -159,6 +226,84 @@ Native `disabled` attribute.
159
226
 
160
227
  By default options are matched case- and accent-insensitively (every space-separated keyword must appear). Override the `filter` property — `(item, query) => boolean` — for `startsWith`, fuzzy, or remote-driven filtering.
161
228
 
229
+ The default filter only reads the label (a rich option's title). To search the description too, match against the text of `item.html` — the match is then highlighted in the description as well. Try a capital or a continent:
230
+
231
+ ```html
232
+ <div class="w-72">
233
+ <l-combobox
234
+ id="demo-combobox-filter"
235
+ label="Country"
236
+ placeholder="Search a country or capital…"
237
+ >
238
+ <datalist>
239
+ <option
240
+ value="fr"
241
+ label="France"
242
+ >
243
+ <span class="l-select-item-text">
244
+ <span class="l-select-item-title">France</span>
245
+ <span class="l-select-item-description">Capital: Paris · Europe</span>
246
+ </span>
247
+ </option>
248
+ <option
249
+ value="jp"
250
+ label="Japan"
251
+ >
252
+ <span class="l-select-item-text">
253
+ <span class="l-select-item-title">Japan</span>
254
+ <span class="l-select-item-description">Capital: Tokyo · Asia</span>
255
+ </span>
256
+ </option>
257
+ <option
258
+ value="br"
259
+ label="Brazil"
260
+ >
261
+ <span class="l-select-item-text">
262
+ <span class="l-select-item-title">Brazil</span>
263
+ <span class="l-select-item-description">Capital: Brasília · South America</span>
264
+ </span>
265
+ </option>
266
+ <option
267
+ value="ke"
268
+ label="Kenya"
269
+ >
270
+ <span class="l-select-item-text">
271
+ <span class="l-select-item-title">Kenya</span>
272
+ <span class="l-select-item-description">Capital: Nairobi · Africa</span>
273
+ </span>
274
+ </option>
275
+ </datalist>
276
+ </l-combobox>
277
+ </div>
278
+ ```
279
+
280
+ ```js
281
+ const combobox = document.querySelector('l-combobox');
282
+
283
+ // `item.html` is the rich option's markup: compare against its text, not its tags.
284
+ const textOf = (html) => {
285
+ const template = document.createElement('template');
286
+ template.innerHTML = html;
287
+ return template.content.textContent;
288
+ };
289
+
290
+ combobox.filter = (item, query) =>
291
+ `${item.label} ${item.html ? textOf(item.html) : ''}`
292
+ .toLowerCase()
293
+ .includes(query.trim().toLowerCase());
294
+ ```
295
+
296
+ ### Match highlight
297
+
298
+ The part of each option that matches the query is wrapped in `<mark>`. Theme it with two form-control tokens, or set the `highlight` property to `false` to turn it off.
299
+
300
+ ```css
301
+ :root {
302
+ --l-form-control-match-background-color: transparent;
303
+ --l-form-control-match-font-weight: var(--l-font-weight-bold);
304
+ }
305
+ ```
306
+
162
307
  ### Dynamic options
163
308
 
164
309
  The `<datalist>` is watched: re-labelling, adding, removing, or disabling an `<option>` after mount updates the input and the listbox immediately — no reopen, no remount. Text the user is typing is left alone.
@@ -206,7 +351,8 @@ import 'luxen-ui/combobox';
206
351
  - **size**: `ComboboxSize` (default: `'md'`) — Control size.
207
352
  - **with-clear**: `boolean` (default: `false`) — Show a button to clear the value.
208
353
  - **allow-custom**: `boolean` (default: `false`) — Accept a typed value that matches no option.
209
- - **highlight**: `boolean` (default: `true`) — Wrap the matching substring of each option in `<mark>`.
354
+ - **highlight**: `boolean` (default: `true`) — Wrap the matching substring of each option in `<mark>` — the label of a
355
+ plain option, the title and description of a rich one.
210
356
  - **placement**: `Placement` (default: `'bottom-start'`) — Panel placement relative to the control.
211
357
  - **filter**: `ComboboxFilter` (default: `defaultFilter`) — Override the option filter. `(item, query) => boolean`.
212
358
 
@@ -227,6 +373,14 @@ import 'luxen-ui/combobox';
227
373
  - `option` — Each option row.
228
374
  - `empty` — The "no results" message.
229
375
 
376
+ ### CSS classes
377
+
378
+ - `.l-select-item-media` — Rich option: leading image or icon.
379
+ - `.l-select-item-text` — Rich option: column holding the title and the description.
380
+ - `.l-select-item-title` — Rich option: title, truncated with an ellipsis. Used as the label when the option has no `label`.
381
+ - `.l-select-item-description` — Rich option: secondary line, shown in the listbox only.
382
+ - `.l-select-item-suffix` — Rich option: trailing badge, count or status icon on the title's line. Kept out of the input and the filter.
383
+
230
384
  ### CSS custom properties
231
385
 
232
386
  - `--height` — Control height. Defaults to the form-control height.
@@ -127,7 +127,8 @@ The editor participates in forms via its `name` attribute. The submitted value i
127
127
  - `Ctrl/Cmd + U` — Toggles underline
128
128
  - `Ctrl/Cmd + Z` — Undo
129
129
  - `Ctrl/Cmd + Shift + Z` — Redo
130
- - `Escape` — Closes the emoji picker when open
130
+ - `Escape` — Closes the emoji picker when open and returns focus to where it was before: the editor, or the Emoji button when the picker was opened from the toolbar
131
+ - `Tab / Shift + Tab` — In the emoji picker, moves between its controls; tabbing out of it closes it, moving on to the editor (Tab) or back to the Emoji button (Shift + Tab)
131
132
 
132
133
  ## API reference
133
134
 
@@ -324,8 +324,8 @@ Add `disabled` to a segment's input. Arrow keys skip it, and it drops out of the
324
324
  ### Keyboard interactions
325
325
 
326
326
  - `Tab` — Moves focus into the group, onto the checked segment
327
- - `ArrowRight` — Selects and focuses the next segment, wrapping
328
- - `ArrowLeft` — Selects and focuses the previous segment, wrapping
327
+ - `ArrowRight` — Selects and focuses the next segment; wraps at the end in Chrome and Firefox, stops there in Safari (the browser’s own radio behaviour)
328
+ - `ArrowLeft` — Selects and focuses the previous segment; wraps at the start in Chrome and Firefox, stops there in Safari
329
329
  - `ArrowDown` — Same as ArrowRight
330
330
  - `ArrowUp` — Same as ArrowLeft
331
331
  - `Space` — Selects the focused segment when none was selected