@deepfuture/dui-components 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 (380) hide show
  1. package/accordion/accordion-context.d.ts +15 -0
  2. package/accordion/accordion-context.js +3 -0
  3. package/accordion/accordion-item.d.ts +22 -0
  4. package/accordion/accordion-item.js +254 -0
  5. package/accordion/accordion.d.ts +20 -0
  6. package/accordion/accordion.js +185 -0
  7. package/accordion/index.d.ts +3 -0
  8. package/accordion/index.js +2 -0
  9. package/accordion/register.d.ts +1 -0
  10. package/accordion/register.js +8 -0
  11. package/alert-dialog/alert-dialog-close.d.ts +15 -0
  12. package/alert-dialog/alert-dialog-close.js +35 -0
  13. package/alert-dialog/alert-dialog-context.d.ts +13 -0
  14. package/alert-dialog/alert-dialog-context.js +3 -0
  15. package/alert-dialog/alert-dialog-popup.d.ts +34 -0
  16. package/alert-dialog/alert-dialog-popup.js +260 -0
  17. package/alert-dialog/alert-dialog-trigger.d.ts +15 -0
  18. package/alert-dialog/alert-dialog-trigger.js +52 -0
  19. package/alert-dialog/alert-dialog.d.ts +30 -0
  20. package/alert-dialog/alert-dialog.js +97 -0
  21. package/alert-dialog/index.d.ts +6 -0
  22. package/alert-dialog/index.js +4 -0
  23. package/alert-dialog/register.d.ts +1 -0
  24. package/alert-dialog/register.js +16 -0
  25. package/all.d.ts +86 -0
  26. package/all.js +191 -0
  27. package/avatar/avatar.d.ts +41 -0
  28. package/avatar/avatar.js +188 -0
  29. package/avatar/index.d.ts +2 -0
  30. package/avatar/index.js +1 -0
  31. package/avatar/register.d.ts +1 -0
  32. package/avatar/register.js +4 -0
  33. package/badge/badge.d.ts +14 -0
  34. package/badge/badge.js +43 -0
  35. package/badge/index.d.ts +2 -0
  36. package/badge/index.js +1 -0
  37. package/badge/register.d.ts +1 -0
  38. package/badge/register.js +4 -0
  39. package/breadcrumb/breadcrumb-ellipsis.d.ts +14 -0
  40. package/breadcrumb/breadcrumb-ellipsis.js +39 -0
  41. package/breadcrumb/breadcrumb-item.d.ts +13 -0
  42. package/breadcrumb/breadcrumb-item.js +31 -0
  43. package/breadcrumb/breadcrumb-link.d.ts +14 -0
  44. package/breadcrumb/breadcrumb-link.js +32 -0
  45. package/breadcrumb/breadcrumb-page.d.ts +13 -0
  46. package/breadcrumb/breadcrumb-page.js +36 -0
  47. package/breadcrumb/breadcrumb-separator.d.ts +14 -0
  48. package/breadcrumb/breadcrumb-separator.js +36 -0
  49. package/breadcrumb/breadcrumb.d.ts +14 -0
  50. package/breadcrumb/breadcrumb.js +38 -0
  51. package/breadcrumb/index.d.ts +6 -0
  52. package/breadcrumb/index.js +6 -0
  53. package/breadcrumb/register.d.ts +1 -0
  54. package/breadcrumb/register.js +14 -0
  55. package/button/button.d.ts +38 -0
  56. package/button/button.js +143 -0
  57. package/button/index.d.ts +2 -0
  58. package/button/index.js +1 -0
  59. package/button/register.d.ts +1 -0
  60. package/button/register.js +4 -0
  61. package/calendar/calendar.d.ts +33 -0
  62. package/calendar/calendar.js +428 -0
  63. package/calendar/index.d.ts +1 -0
  64. package/calendar/index.js +1 -0
  65. package/calendar/register.d.ts +1 -0
  66. package/calendar/register.js +4 -0
  67. package/center/center.d.ts +14 -0
  68. package/center/center.js +37 -0
  69. package/center/index.d.ts +1 -0
  70. package/center/index.js +1 -0
  71. package/center/register.d.ts +1 -0
  72. package/center/register.js +4 -0
  73. package/checkbox/checkbox-group-context.d.ts +11 -0
  74. package/checkbox/checkbox-group-context.js +3 -0
  75. package/checkbox/checkbox-group.d.ts +34 -0
  76. package/checkbox/checkbox-group.js +128 -0
  77. package/checkbox/checkbox.d.ts +46 -0
  78. package/checkbox/checkbox.js +314 -0
  79. package/checkbox/index.d.ts +3 -0
  80. package/checkbox/index.js +2 -0
  81. package/checkbox/register.d.ts +1 -0
  82. package/checkbox/register.js +8 -0
  83. package/collapsible/collapsible.d.ts +22 -0
  84. package/collapsible/collapsible.js +227 -0
  85. package/collapsible/index.d.ts +1 -0
  86. package/collapsible/index.js +1 -0
  87. package/collapsible/register.d.ts +1 -0
  88. package/collapsible/register.js +4 -0
  89. package/combobox/combobox.d.ts +46 -0
  90. package/combobox/combobox.js +524 -0
  91. package/combobox/index.d.ts +2 -0
  92. package/combobox/index.js +1 -0
  93. package/combobox/register.d.ts +1 -0
  94. package/combobox/register.js +4 -0
  95. package/command/command-context.d.ts +30 -0
  96. package/command/command-context.js +3 -0
  97. package/command/command-empty.d.ts +10 -0
  98. package/command/command-empty.js +50 -0
  99. package/command/command-group.d.ts +15 -0
  100. package/command/command-group.js +79 -0
  101. package/command/command-input.d.ts +13 -0
  102. package/command/command-input.js +106 -0
  103. package/command/command-item.d.ts +20 -0
  104. package/command/command-item.js +175 -0
  105. package/command/command-list.d.ts +9 -0
  106. package/command/command-list.js +43 -0
  107. package/command/command-score.d.ts +6 -0
  108. package/command/command-score.js +31 -0
  109. package/command/command-separator.d.ts +7 -0
  110. package/command/command-separator.js +15 -0
  111. package/command/command-shortcut.d.ts +7 -0
  112. package/command/command-shortcut.js +16 -0
  113. package/command/command.d.ts +25 -0
  114. package/command/command.js +278 -0
  115. package/command/index.d.ts +10 -0
  116. package/command/index.js +9 -0
  117. package/command/register.d.ts +1 -0
  118. package/command/register.js +22 -0
  119. package/data-table/data-table.d.ts +59 -0
  120. package/data-table/data-table.js +416 -0
  121. package/data-table/index.d.ts +2 -0
  122. package/data-table/index.js +1 -0
  123. package/data-table/register.d.ts +1 -0
  124. package/data-table/register.js +4 -0
  125. package/dialog/dialog-close.d.ts +15 -0
  126. package/dialog/dialog-close.js +35 -0
  127. package/dialog/dialog-context.d.ts +13 -0
  128. package/dialog/dialog-context.js +3 -0
  129. package/dialog/dialog-popup.d.ts +36 -0
  130. package/dialog/dialog-popup.js +277 -0
  131. package/dialog/dialog-trigger.d.ts +15 -0
  132. package/dialog/dialog-trigger.js +52 -0
  133. package/dialog/dialog.d.ts +30 -0
  134. package/dialog/dialog.js +97 -0
  135. package/dialog/index.d.ts +6 -0
  136. package/dialog/index.js +4 -0
  137. package/dialog/register.d.ts +1 -0
  138. package/dialog/register.js +16 -0
  139. package/dropzone/dropzone.d.ts +74 -0
  140. package/dropzone/dropzone.js +357 -0
  141. package/dropzone/index.d.ts +2 -0
  142. package/dropzone/index.js +1 -0
  143. package/dropzone/register.d.ts +1 -0
  144. package/dropzone/register.js +4 -0
  145. package/field/field-context.d.ts +20 -0
  146. package/field/field-context.js +2 -0
  147. package/field/index.d.ts +2 -0
  148. package/field/index.js +1 -0
  149. package/global.d.ts +189 -0
  150. package/hstack/hstack.d.ts +25 -0
  151. package/hstack/hstack.js +141 -0
  152. package/hstack/index.d.ts +2 -0
  153. package/hstack/index.js +1 -0
  154. package/hstack/register.d.ts +1 -0
  155. package/hstack/register.js +4 -0
  156. package/icon/icon.d.ts +16 -0
  157. package/icon/icon.js +34 -0
  158. package/icon/index.d.ts +1 -0
  159. package/icon/index.js +1 -0
  160. package/icon/register.d.ts +1 -0
  161. package/icon/register.js +4 -0
  162. package/input/index.d.ts +1 -0
  163. package/input/index.js +1 -0
  164. package/input/input.d.ts +47 -0
  165. package/input/input.js +205 -0
  166. package/input/register.d.ts +1 -0
  167. package/input/register.js +4 -0
  168. package/link/index.d.ts +1 -0
  169. package/link/index.js +1 -0
  170. package/link/link.d.ts +27 -0
  171. package/link/link.js +57 -0
  172. package/link/register.d.ts +1 -0
  173. package/link/register.js +4 -0
  174. package/menu/index.d.ts +2 -0
  175. package/menu/index.js +2 -0
  176. package/menu/menu-item.d.ts +17 -0
  177. package/menu/menu-item.js +62 -0
  178. package/menu/menu.d.ts +15 -0
  179. package/menu/menu.js +228 -0
  180. package/menu/register.d.ts +1 -0
  181. package/menu/register.js +8 -0
  182. package/menubar/index.d.ts +2 -0
  183. package/menubar/index.js +1 -0
  184. package/menubar/menubar-context.d.ts +9 -0
  185. package/menubar/menubar-context.js +2 -0
  186. package/menubar/menubar.d.ts +19 -0
  187. package/menubar/menubar.js +130 -0
  188. package/menubar/register.d.ts +1 -0
  189. package/menubar/register.js +4 -0
  190. package/number-field/index.d.ts +1 -0
  191. package/number-field/index.js +1 -0
  192. package/number-field/number-field.d.ts +34 -0
  193. package/number-field/number-field.js +326 -0
  194. package/number-field/register.d.ts +1 -0
  195. package/number-field/register.js +4 -0
  196. package/package.json +217 -0
  197. package/page-inset/index.d.ts +1 -0
  198. package/page-inset/index.js +1 -0
  199. package/page-inset/page-inset.d.ts +28 -0
  200. package/page-inset/page-inset.js +103 -0
  201. package/page-inset/register.d.ts +1 -0
  202. package/page-inset/register.js +4 -0
  203. package/popover/index.d.ts +6 -0
  204. package/popover/index.js +4 -0
  205. package/popover/popover-close.d.ts +13 -0
  206. package/popover/popover-close.js +33 -0
  207. package/popover/popover-context.d.ts +17 -0
  208. package/popover/popover-context.js +3 -0
  209. package/popover/popover-popup.d.ts +20 -0
  210. package/popover/popover-popup.js +176 -0
  211. package/popover/popover-trigger.d.ts +13 -0
  212. package/popover/popover-trigger.js +57 -0
  213. package/popover/popover.d.ts +30 -0
  214. package/popover/popover.js +140 -0
  215. package/popover/register.d.ts +1 -0
  216. package/popover/register.js +16 -0
  217. package/portal/index.d.ts +2 -0
  218. package/portal/index.js +1 -0
  219. package/portal/portal.d.ts +29 -0
  220. package/portal/portal.js +115 -0
  221. package/portal/register.d.ts +1 -0
  222. package/portal/register.js +4 -0
  223. package/preview-card/index.d.ts +5 -0
  224. package/preview-card/index.js +3 -0
  225. package/preview-card/preview-card-context.d.ts +16 -0
  226. package/preview-card/preview-card-context.js +3 -0
  227. package/preview-card/preview-card-popup.d.ts +16 -0
  228. package/preview-card/preview-card-popup.js +167 -0
  229. package/preview-card/preview-card-trigger.d.ts +13 -0
  230. package/preview-card/preview-card-trigger.js +75 -0
  231. package/preview-card/preview-card.d.ts +34 -0
  232. package/preview-card/preview-card.js +164 -0
  233. package/preview-card/register.d.ts +1 -0
  234. package/preview-card/register.js +12 -0
  235. package/progress/index.d.ts +1 -0
  236. package/progress/index.js +1 -0
  237. package/progress/progress.d.ts +19 -0
  238. package/progress/progress.js +94 -0
  239. package/progress/register.d.ts +1 -0
  240. package/progress/register.js +4 -0
  241. package/radio/index.d.ts +3 -0
  242. package/radio/index.js +2 -0
  243. package/radio/radio-group-context.d.ts +11 -0
  244. package/radio/radio-group-context.js +2 -0
  245. package/radio/radio-group.d.ts +37 -0
  246. package/radio/radio-group.js +135 -0
  247. package/radio/radio.d.ts +27 -0
  248. package/radio/radio.js +204 -0
  249. package/radio/register.d.ts +1 -0
  250. package/radio/register.js +8 -0
  251. package/scroll-area/index.d.ts +1 -0
  252. package/scroll-area/index.js +1 -0
  253. package/scroll-area/register.d.ts +1 -0
  254. package/scroll-area/register.js +4 -0
  255. package/scroll-area/scroll-area.d.ts +38 -0
  256. package/scroll-area/scroll-area.js +453 -0
  257. package/select/index.d.ts +2 -0
  258. package/select/index.js +1 -0
  259. package/select/register.d.ts +1 -0
  260. package/select/register.js +4 -0
  261. package/select/select.d.ts +36 -0
  262. package/select/select.js +404 -0
  263. package/separator/index.d.ts +1 -0
  264. package/separator/index.js +1 -0
  265. package/separator/register.d.ts +1 -0
  266. package/separator/register.js +4 -0
  267. package/separator/separator.d.ts +12 -0
  268. package/separator/separator.js +50 -0
  269. package/sidebar/index.d.ts +16 -0
  270. package/sidebar/index.js +13 -0
  271. package/sidebar/register.d.ts +1 -0
  272. package/sidebar/register.js +52 -0
  273. package/sidebar/sidebar-content.d.ts +14 -0
  274. package/sidebar/sidebar-content.js +30 -0
  275. package/sidebar/sidebar-context.d.ts +15 -0
  276. package/sidebar/sidebar-context.js +3 -0
  277. package/sidebar/sidebar-footer.d.ts +12 -0
  278. package/sidebar/sidebar-footer.js +21 -0
  279. package/sidebar/sidebar-group-label.d.ts +17 -0
  280. package/sidebar/sidebar-group-label.js +49 -0
  281. package/sidebar/sidebar-group.d.ts +15 -0
  282. package/sidebar/sidebar-group.js +29 -0
  283. package/sidebar/sidebar-header.d.ts +12 -0
  284. package/sidebar/sidebar-header.js +21 -0
  285. package/sidebar/sidebar-inset.d.ts +15 -0
  286. package/sidebar/sidebar-inset.js +29 -0
  287. package/sidebar/sidebar-menu-button.d.ts +31 -0
  288. package/sidebar/sidebar-menu-button.js +201 -0
  289. package/sidebar/sidebar-menu-item.d.ts +12 -0
  290. package/sidebar/sidebar-menu-item.js +20 -0
  291. package/sidebar/sidebar-menu.d.ts +14 -0
  292. package/sidebar/sidebar-menu.js +30 -0
  293. package/sidebar/sidebar-provider.d.ts +34 -0
  294. package/sidebar/sidebar-provider.js +157 -0
  295. package/sidebar/sidebar-separator.d.ts +12 -0
  296. package/sidebar/sidebar-separator.js +24 -0
  297. package/sidebar/sidebar-trigger.d.ts +16 -0
  298. package/sidebar/sidebar-trigger.js +50 -0
  299. package/sidebar/sidebar.d.ts +21 -0
  300. package/sidebar/sidebar.js +228 -0
  301. package/slider/index.d.ts +1 -0
  302. package/slider/index.js +1 -0
  303. package/slider/register.d.ts +1 -0
  304. package/slider/register.js +4 -0
  305. package/slider/slider.d.ts +37 -0
  306. package/slider/slider.js +268 -0
  307. package/spinner/index.d.ts +1 -0
  308. package/spinner/index.js +1 -0
  309. package/spinner/register.d.ts +1 -0
  310. package/spinner/register.js +4 -0
  311. package/spinner/spinner.d.ts +18 -0
  312. package/spinner/spinner.js +138 -0
  313. package/switch/index.d.ts +1 -0
  314. package/switch/index.js +1 -0
  315. package/switch/register.d.ts +1 -0
  316. package/switch/register.js +4 -0
  317. package/switch/switch.d.ts +29 -0
  318. package/switch/switch.js +201 -0
  319. package/tabs/index.d.ts +6 -0
  320. package/tabs/index.js +5 -0
  321. package/tabs/register.d.ts +1 -0
  322. package/tabs/register.js +10 -0
  323. package/tabs/tab.d.ts +16 -0
  324. package/tabs/tab.js +98 -0
  325. package/tabs/tabs-context.d.ts +8 -0
  326. package/tabs/tabs-context.js +2 -0
  327. package/tabs/tabs-indicator.d.ts +11 -0
  328. package/tabs/tabs-indicator.js +27 -0
  329. package/tabs/tabs-list.d.ts +17 -0
  330. package/tabs/tabs-list.js +85 -0
  331. package/tabs/tabs-panel.d.ts +18 -0
  332. package/tabs/tabs-panel.js +85 -0
  333. package/tabs/tabs.d.ts +24 -0
  334. package/tabs/tabs.js +111 -0
  335. package/textarea/index.d.ts +2 -0
  336. package/textarea/index.js +1 -0
  337. package/textarea/register.d.ts +1 -0
  338. package/textarea/register.js +4 -0
  339. package/textarea/textarea.d.ts +37 -0
  340. package/textarea/textarea.js +170 -0
  341. package/toggle/index.d.ts +3 -0
  342. package/toggle/index.js +2 -0
  343. package/toggle/register.d.ts +1 -0
  344. package/toggle/register.js +8 -0
  345. package/toggle/toggle-group-context.d.ts +9 -0
  346. package/toggle/toggle-group-context.js +2 -0
  347. package/toggle/toggle-group.d.ts +27 -0
  348. package/toggle/toggle-group.js +163 -0
  349. package/toggle/toggle.d.ts +25 -0
  350. package/toggle/toggle.js +124 -0
  351. package/toolbar/index.d.ts +1 -0
  352. package/toolbar/index.js +1 -0
  353. package/toolbar/register.d.ts +1 -0
  354. package/toolbar/register.js +4 -0
  355. package/toolbar/toolbar.d.ts +15 -0
  356. package/toolbar/toolbar.js +89 -0
  357. package/tooltip/index.d.ts +5 -0
  358. package/tooltip/index.js +3 -0
  359. package/tooltip/register.d.ts +1 -0
  360. package/tooltip/register.js +12 -0
  361. package/tooltip/tooltip-context.d.ts +17 -0
  362. package/tooltip/tooltip-context.js +3 -0
  363. package/tooltip/tooltip-popup.d.ts +16 -0
  364. package/tooltip/tooltip-popup.js +162 -0
  365. package/tooltip/tooltip-trigger.d.ts +15 -0
  366. package/tooltip/tooltip-trigger.js +110 -0
  367. package/tooltip/tooltip.d.ts +36 -0
  368. package/tooltip/tooltip.js +176 -0
  369. package/trunc/index.d.ts +1 -0
  370. package/trunc/index.js +1 -0
  371. package/trunc/register.d.ts +1 -0
  372. package/trunc/register.js +4 -0
  373. package/trunc/trunc.d.ts +19 -0
  374. package/trunc/trunc.js +68 -0
  375. package/vstack/index.d.ts +1 -0
  376. package/vstack/index.js +1 -0
  377. package/vstack/register.d.ts +1 -0
  378. package/vstack/register.js +4 -0
  379. package/vstack/vstack.d.ts +17 -0
  380. package/vstack/vstack.js +83 -0
@@ -0,0 +1,46 @@
1
+ /** Ported from original DUI: deep-future-app/app/client/components/dui/combobox */
2
+ import { LitElement, type TemplateResult } from "lit";
3
+ export type SelectOption = {
4
+ label: string;
5
+ value: string;
6
+ };
7
+ export type ComboboxValueChangeDetail = {
8
+ value: string;
9
+ option: SelectOption;
10
+ };
11
+ export type ComboboxValuesChangeDetail = {
12
+ value: string;
13
+ selected: boolean;
14
+ values: Set<string>;
15
+ };
16
+ export declare const valueChangeEvent: (detail: ComboboxValueChangeDetail) => CustomEvent<ComboboxValueChangeDetail>;
17
+ export declare const valuesChangeEvent: (detail: ComboboxValuesChangeDetail) => CustomEvent<ComboboxValuesChangeDetail>;
18
+ /**
19
+ * `<dui-combobox>` — A searchable dropdown for selecting from a list of options.
20
+ * Supports single-select and multi-select (chip) modes.
21
+ *
22
+ * @fires value-change - Single-select: fired when selection changes.
23
+ * Detail: { value: string, option: SelectOption }
24
+ * @fires values-change - Multi-select: fired when a value is toggled.
25
+ * Detail: { value: string, selected: boolean, values: Set<string> }
26
+ */
27
+ export declare class DuiCombobox extends LitElement {
28
+ #private;
29
+ static tagName: "dui-combobox";
30
+ static styles: import("lit").CSSResult[];
31
+ /** The available options. */
32
+ accessor options: SelectOption[];
33
+ /** Currently selected value (single-select mode). */
34
+ accessor value: string;
35
+ /** Currently selected values (multi-select mode). */
36
+ accessor values: Set<string>;
37
+ /** Enable multi-select mode with chips. */
38
+ accessor multiple: boolean;
39
+ /** Placeholder text for the input. */
40
+ accessor placeholder: string;
41
+ /** Whether the combobox is disabled. */
42
+ accessor disabled: boolean;
43
+ /** Name for form submission. */
44
+ accessor name: string;
45
+ render(): TemplateResult;
46
+ }
@@ -0,0 +1,524 @@
1
+ /** Ported from original DUI: deep-future-app/app/client/components/dui/combobox */
2
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ };
8
+ import { css, html, LitElement, nothing } from "lit";
9
+ import { property } from "lit/decorators.js";
10
+ import { repeat } from "lit/directives/repeat.js";
11
+ import { live } from "lit/directives/live.js";
12
+ import { base } from "@deepfuture/dui-core/base";
13
+ import { customEvent } from "@deepfuture/dui-core/event";
14
+ import { FloatingPortalController } from "@deepfuture/dui-core/floating-portal-controller";
15
+ export const valueChangeEvent = customEvent("value-change", { bubbles: true, composed: true });
16
+ export const valuesChangeEvent = customEvent("values-change", { bubbles: true, composed: true });
17
+ const hostStyles = css `
18
+ :host {
19
+ display: block;
20
+ }
21
+ `;
22
+ const componentStyles = css `
23
+ /* ---- Input area (structural) ---- */
24
+
25
+ .Chips {
26
+ position: relative;
27
+ box-sizing: border-box;
28
+ display: flex;
29
+ flex-wrap: wrap;
30
+ align-items: center;
31
+ width: 100%;
32
+ cursor: text;
33
+ }
34
+
35
+ .Chips[data-disabled] {
36
+ cursor: not-allowed;
37
+ }
38
+
39
+ .InputWrapper {
40
+ position: relative;
41
+ display: flex;
42
+ align-items: center;
43
+ width: 100%;
44
+ }
45
+
46
+ .Input {
47
+ box-sizing: border-box;
48
+ border: none;
49
+ outline: none;
50
+ background: transparent;
51
+ padding: 0;
52
+ min-width: 4rem;
53
+ flex: 1;
54
+ }
55
+
56
+ .Input:disabled {
57
+ cursor: not-allowed;
58
+ }
59
+
60
+ .Arrow {
61
+ position: absolute;
62
+ pointer-events: none;
63
+ flex-shrink: 0;
64
+ }
65
+
66
+ .Chip {
67
+ display: inline-flex;
68
+ align-items: center;
69
+ cursor: default;
70
+ max-width: 100%;
71
+ overflow: hidden;
72
+ }
73
+
74
+ .ChipLabel {
75
+ overflow: hidden;
76
+ text-overflow: ellipsis;
77
+ white-space: nowrap;
78
+ }
79
+
80
+ .ChipRemove {
81
+ display: inline-flex;
82
+ align-items: center;
83
+ justify-content: center;
84
+ border: none;
85
+ background: none;
86
+ cursor: pointer;
87
+ flex-shrink: 0;
88
+ }
89
+ `;
90
+ /** Styles injected into the portal positioner. */
91
+ const portalPopupStyles = [
92
+ css `
93
+ .Popup {
94
+ background: var(--popover);
95
+ border: var(--border-width-thin) solid var(--border);
96
+ border-radius: var(--radius-md);
97
+ box-shadow: var(--shadow-md);
98
+ opacity: 1;
99
+ transition-property: opacity, transform;
100
+ transition-duration: var(--duration-fast);
101
+ transition-timing-function: var(--ease-out-3);
102
+ transform: translateY(0);
103
+ pointer-events: auto;
104
+ }
105
+
106
+ .Popup[data-starting-style],
107
+ .Popup[data-ending-style] {
108
+ opacity: 0;
109
+ transform: translateY(calc(var(--space-1) * -1));
110
+ }
111
+
112
+ dui-scroll-area {
113
+ max-height: 240px;
114
+ height: auto;
115
+ }
116
+
117
+ .List {
118
+ padding: var(--space-1);
119
+ }
120
+
121
+ /* ---- Items ---- */
122
+
123
+ .Item {
124
+ display: flex;
125
+ align-items: center;
126
+ gap: var(--space-2);
127
+ padding: var(--space-2) var(--space-2) var(--space-2) var(--space-3);
128
+ border-radius: var(--radius-sm);
129
+ font-size: var(--font-size-sm);
130
+ font-family: var(--font-sans);
131
+ color: var(--popover-foreground);
132
+ cursor: pointer;
133
+ }
134
+
135
+ .Item:hover,
136
+ .Item[data-highlighted] {
137
+ background: var(--secondary);
138
+ color: var(--foreground);
139
+ }
140
+
141
+ .ItemIndicator {
142
+ --icon-size: var(--space-3_5);
143
+ flex-shrink: 0;
144
+ display: flex;
145
+ align-items: center;
146
+ justify-content: center;
147
+ }
148
+
149
+ .ItemText {
150
+ flex: 1;
151
+ overflow: hidden;
152
+ text-overflow: ellipsis;
153
+ white-space: nowrap;
154
+ }
155
+
156
+ /* ---- Empty ---- */
157
+
158
+ .Empty {
159
+ padding: var(--space-3) var(--space-3);
160
+ font-size: var(--font-size-sm);
161
+ color: var(--muted-foreground);
162
+ text-align: center;
163
+ }
164
+ `,
165
+ ];
166
+ /**
167
+ * `<dui-combobox>` — A searchable dropdown for selecting from a list of options.
168
+ * Supports single-select and multi-select (chip) modes.
169
+ *
170
+ * @fires value-change - Single-select: fired when selection changes.
171
+ * Detail: { value: string, option: SelectOption }
172
+ * @fires values-change - Multi-select: fired when a value is toggled.
173
+ * Detail: { value: string, selected: boolean, values: Set<string> }
174
+ */
175
+ export class DuiCombobox extends LitElement {
176
+ static { this.tagName = "dui-combobox"; }
177
+ static { this.styles = [base, hostStyles, componentStyles]; }
178
+ #options_accessor_storage = [];
179
+ /** The available options. */
180
+ get options() { return this.#options_accessor_storage; }
181
+ set options(value) { this.#options_accessor_storage = value; }
182
+ #value_accessor_storage = "";
183
+ /** Currently selected value (single-select mode). */
184
+ get value() { return this.#value_accessor_storage; }
185
+ set value(value) { this.#value_accessor_storage = value; }
186
+ #values_accessor_storage = new Set();
187
+ /** Currently selected values (multi-select mode). */
188
+ get values() { return this.#values_accessor_storage; }
189
+ set values(value) { this.#values_accessor_storage = value; }
190
+ #multiple_accessor_storage = false;
191
+ /** Enable multi-select mode with chips. */
192
+ get multiple() { return this.#multiple_accessor_storage; }
193
+ set multiple(value) { this.#multiple_accessor_storage = value; }
194
+ #placeholder_accessor_storage = "Search...";
195
+ /** Placeholder text for the input. */
196
+ get placeholder() { return this.#placeholder_accessor_storage; }
197
+ set placeholder(value) { this.#placeholder_accessor_storage = value; }
198
+ #disabled_accessor_storage = false;
199
+ /** Whether the combobox is disabled. */
200
+ get disabled() { return this.#disabled_accessor_storage; }
201
+ set disabled(value) { this.#disabled_accessor_storage = value; }
202
+ #name_accessor_storage = "";
203
+ /** Name for form submission. */
204
+ get name() { return this.#name_accessor_storage; }
205
+ set name(value) { this.#name_accessor_storage = value; }
206
+ #highlightedIndex_accessor_storage = -1;
207
+ get #highlightedIndex() { return this.#highlightedIndex_accessor_storage; }
208
+ set #highlightedIndex(value) { this.#highlightedIndex_accessor_storage = value; }
209
+ #inputValue_accessor_storage = "";
210
+ get #inputValue() { return this.#inputValue_accessor_storage; }
211
+ set #inputValue(value) { this.#inputValue_accessor_storage = value; }
212
+ #popup = new FloatingPortalController(this, {
213
+ getAnchor: () => this.multiple
214
+ ? this.shadowRoot?.querySelector(".Chips")
215
+ : this.shadowRoot?.querySelector(".InputWrapper"),
216
+ styles: portalPopupStyles,
217
+ onOpen: () => {
218
+ this.#highlightedIndex = -1;
219
+ if (!this.multiple) {
220
+ this.#inputValue = "";
221
+ const input = this.shadowRoot?.querySelector(".Input");
222
+ if (input)
223
+ input.value = "";
224
+ }
225
+ },
226
+ onClose: () => {
227
+ this.#highlightedIndex = -1;
228
+ if (!this.multiple) {
229
+ const selected = this.options.find((o) => o.value === this.value);
230
+ this.#inputValue = selected?.label ?? "";
231
+ }
232
+ },
233
+ renderPopup: (portal) => {
234
+ const filtered = this.#filteredOptions;
235
+ const isEmpty = filtered.length === 0;
236
+ return html `
237
+ <div
238
+ class="Popup"
239
+ ?data-starting-style="${portal.isStarting}"
240
+ ?data-ending-style="${portal.isEnding}"
241
+ >
242
+ <dui-scroll-area>
243
+ <div
244
+ class="List"
245
+ id="${this.#listId}"
246
+ role="listbox"
247
+ aria-labelledby="${this.#inputId}"
248
+ ?data-empty="${isEmpty}"
249
+ @mousedown="${this.#onListMouseDown}"
250
+ @mousemove="${this.#onListMouseMove}"
251
+ >
252
+ ${repeat(filtered, (option) => option.value, this.#renderItem)}
253
+ ${isEmpty ? html ` <div class="Empty">No results</div> ` : nothing}
254
+ </div>
255
+ </dui-scroll-area>
256
+ </div>
257
+ `;
258
+ },
259
+ });
260
+ #inputId = `combobox-input-${crypto.randomUUID().slice(0, 8)}`;
261
+ #listId = `combobox-list-${crypto.randomUUID().slice(0, 8)}`;
262
+ /** Filtered options based on current input text. */
263
+ get #filteredOptions() {
264
+ const query = this.#inputValue.toLowerCase();
265
+ const opts = this.options;
266
+ if (!query)
267
+ return opts;
268
+ return opts.filter((opt) => opt.label.toLowerCase().includes(query));
269
+ }
270
+ // ---- Input handling ----
271
+ #onInput = (event) => {
272
+ const target = event.target;
273
+ this.#inputValue = target.value;
274
+ if (!this.#popup.isOpen) {
275
+ if (!this.disabled)
276
+ this.#popup.open();
277
+ }
278
+ this.#highlightedIndex = -1;
279
+ };
280
+ #onInputFocus = () => {
281
+ if (!this.#popup.isOpen && !this.disabled) {
282
+ this.#popup.open();
283
+ }
284
+ };
285
+ #onInputKeyDown = (event) => {
286
+ const filtered = this.#filteredOptions;
287
+ switch (event.key) {
288
+ case "ArrowDown":
289
+ event.preventDefault();
290
+ if (!this.#popup.isOpen) {
291
+ if (!this.disabled)
292
+ this.#popup.open();
293
+ }
294
+ else {
295
+ this.#highlightedIndex = Math.min(this.#highlightedIndex + 1, filtered.length - 1);
296
+ }
297
+ break;
298
+ case "ArrowUp":
299
+ event.preventDefault();
300
+ if (!this.#popup.isOpen) {
301
+ if (!this.disabled)
302
+ this.#popup.open();
303
+ }
304
+ else {
305
+ this.#highlightedIndex = Math.max(this.#highlightedIndex - 1, 0);
306
+ }
307
+ break;
308
+ case "Enter": {
309
+ event.preventDefault();
310
+ if (this.#popup.isOpen) {
311
+ const index = this.#highlightedIndex >= 0 ? this.#highlightedIndex : 0;
312
+ const option = filtered[index];
313
+ if (option) {
314
+ this.#selectOption(option);
315
+ }
316
+ }
317
+ else if (!this.disabled) {
318
+ this.#popup.open();
319
+ }
320
+ break;
321
+ }
322
+ case "Escape":
323
+ if (this.#popup.isOpen) {
324
+ event.preventDefault();
325
+ this.#inputValue = "";
326
+ this.#popup.close();
327
+ }
328
+ break;
329
+ case "Tab":
330
+ if (this.#popup.isOpen) {
331
+ this.#popup.close();
332
+ }
333
+ break;
334
+ case "Home":
335
+ if (this.#popup.isOpen) {
336
+ event.preventDefault();
337
+ this.#highlightedIndex = 0;
338
+ }
339
+ break;
340
+ case "End":
341
+ if (this.#popup.isOpen) {
342
+ event.preventDefault();
343
+ this.#highlightedIndex = filtered.length - 1;
344
+ }
345
+ break;
346
+ case "Backspace":
347
+ if (this.multiple && this.#inputValue === "" && this.values.size > 0) {
348
+ const lastValue = Array.from(this.values).at(-1);
349
+ if (lastValue) {
350
+ this.#removeValue(lastValue);
351
+ }
352
+ }
353
+ break;
354
+ }
355
+ };
356
+ // ---- Selection ----
357
+ #selectOption(option) {
358
+ if (this.multiple) {
359
+ const newValues = new Set(this.values);
360
+ const selected = !newValues.has(option.value);
361
+ if (selected) {
362
+ newValues.add(option.value);
363
+ }
364
+ else {
365
+ newValues.delete(option.value);
366
+ }
367
+ this.values = newValues;
368
+ this.#inputValue = "";
369
+ this.#highlightedIndex = -1;
370
+ this.dispatchEvent(valuesChangeEvent({
371
+ value: option.value,
372
+ selected,
373
+ values: newValues,
374
+ }));
375
+ const input = this.shadowRoot?.querySelector(".Input");
376
+ input?.focus();
377
+ }
378
+ else {
379
+ this.value = option.value;
380
+ this.#inputValue = option.label;
381
+ this.dispatchEvent(valueChangeEvent({ value: option.value, option }));
382
+ this.#popup.close();
383
+ }
384
+ }
385
+ #removeValue(value) {
386
+ const newValues = new Set(this.values);
387
+ newValues.delete(value);
388
+ this.values = newValues;
389
+ this.dispatchEvent(valuesChangeEvent({ value, selected: false, values: newValues }));
390
+ }
391
+ #onItemClick = (option) => {
392
+ this.#selectOption(option);
393
+ };
394
+ #onListMouseDown = (event) => {
395
+ event.preventDefault();
396
+ };
397
+ #onListMouseMove = () => {
398
+ if (this.#highlightedIndex !== -1) {
399
+ this.#highlightedIndex = -1;
400
+ }
401
+ };
402
+ #onChipsClick = () => {
403
+ const input = this.shadowRoot?.querySelector(".Input");
404
+ input?.focus();
405
+ };
406
+ // ---- Render ----
407
+ #renderChip = (value) => {
408
+ const option = this.options.find((o) => o.value === value);
409
+ const label = option?.label ?? value;
410
+ return html `
411
+ <span class="Chip">
412
+ <span class="ChipLabel">${label}</span>
413
+ <button
414
+ class="ChipRemove"
415
+ type="button"
416
+ tabindex="-1"
417
+ @mousedown="${(e) => e.preventDefault()}"
418
+ @click="${(e) => {
419
+ e.stopPropagation();
420
+ this.#removeValue(value);
421
+ }}"
422
+ >
423
+ <dui-icon><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M18 6 6 18"/><path d="m6 6 12 12"/></svg></dui-icon>
424
+ </button>
425
+ </span>
426
+ `;
427
+ };
428
+ #renderItem = (option, index) => {
429
+ const isSelected = this.multiple
430
+ ? this.values.has(option.value)
431
+ : option.value === this.value;
432
+ const isHighlighted = index === this.#highlightedIndex;
433
+ return html `
434
+ <div
435
+ class="Item"
436
+ role="option"
437
+ id="${this.#listId}-option-${index}"
438
+ aria-selected="${isSelected}"
439
+ ?data-selected="${isSelected}"
440
+ ?data-highlighted="${isHighlighted}"
441
+ @click="${() => this.#onItemClick(option)}"
442
+ >
443
+ <span class="ItemText">${option.label}</span>
444
+ <span class="ItemIndicator">
445
+ ${isSelected ? html `<dui-icon><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M20 6 9 17l-5-5"/></svg></dui-icon>` : nothing}
446
+ </span>
447
+ </div>
448
+ `;
449
+ };
450
+ render() {
451
+ const inputHtml = html `
452
+ <input
453
+ class="Input"
454
+ id="${this.#inputId}"
455
+ type="text"
456
+ role="combobox"
457
+ autocomplete="off"
458
+ aria-haspopup="listbox"
459
+ aria-expanded="${this.#popup.isOpen}"
460
+ aria-controls="${this.#listId}"
461
+ aria-activedescendant="${this.#highlightedIndex >= 0
462
+ ? `${this.#listId}-option-${this.#highlightedIndex}`
463
+ : nothing}"
464
+ .value="${live(this.#inputValue)}"
465
+ .placeholder="${this.placeholder}"
466
+ ?disabled="${this.disabled}"
467
+ @input="${this.#onInput}"
468
+ @focus="${this.#onInputFocus}"
469
+ @keydown="${this.#onInputKeyDown}"
470
+ />
471
+ `;
472
+ if (this.multiple) {
473
+ return html `
474
+ <div
475
+ class="Chips"
476
+ part="chips"
477
+ ?data-disabled="${this.disabled}"
478
+ @click="${this.#onChipsClick}"
479
+ >
480
+ ${repeat(Array.from(this.values), (v) => v, this.#renderChip)}
481
+ ${inputHtml}
482
+ <dui-icon class="Arrow"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="m6 9 6 6 6-6"/></svg></dui-icon>
483
+ </div>
484
+ ${this.name
485
+ ? repeat(Array.from(this.values), (v) => v, (v) => html `
486
+ <input type="hidden" name="${this.name}" .value="${v}" />
487
+ `)
488
+ : nothing}
489
+ `;
490
+ }
491
+ return html `
492
+ <div class="InputWrapper" part="input-wrapper">
493
+ ${inputHtml}
494
+ <dui-icon class="Arrow"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="m6 9 6 6 6-6"/></svg></dui-icon>
495
+ </div>
496
+ ${this.name
497
+ ? html `
498
+ <input type="hidden" name="${this.name}" .value="${this.value}" />
499
+ `
500
+ : nothing}
501
+ `;
502
+ }
503
+ }
504
+ __decorate([
505
+ property({ attribute: false })
506
+ ], DuiCombobox.prototype, "options", null);
507
+ __decorate([
508
+ property({ type: String })
509
+ ], DuiCombobox.prototype, "value", null);
510
+ __decorate([
511
+ property({ attribute: false })
512
+ ], DuiCombobox.prototype, "values", null);
513
+ __decorate([
514
+ property({ type: Boolean, reflect: true })
515
+ ], DuiCombobox.prototype, "multiple", null);
516
+ __decorate([
517
+ property({ type: String })
518
+ ], DuiCombobox.prototype, "placeholder", null);
519
+ __decorate([
520
+ property({ type: Boolean, reflect: true })
521
+ ], DuiCombobox.prototype, "disabled", null);
522
+ __decorate([
523
+ property({ type: String })
524
+ ], DuiCombobox.prototype, "name", null);
@@ -0,0 +1,2 @@
1
+ export { DuiCombobox, valueChangeEvent, valuesChangeEvent, } from "./combobox.js";
2
+ export type { SelectOption, ComboboxValueChangeDetail, ComboboxValuesChangeDetail, } from "./combobox.js";
@@ -0,0 +1 @@
1
+ export { DuiCombobox, valueChangeEvent, valuesChangeEvent, } from "./combobox.js";
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,4 @@
1
+ import { DuiCombobox } from "./combobox.js";
2
+ if (!customElements.get(DuiCombobox.tagName)) {
3
+ customElements.define(DuiCombobox.tagName, DuiCombobox);
4
+ }
@@ -0,0 +1,30 @@
1
+ /** Ported from original DUI: deep-future-app/app/client/components/dui/command */
2
+ export type CommandItemEntry = {
3
+ readonly id: string;
4
+ readonly value: string;
5
+ readonly keywords: readonly string[];
6
+ readonly textContent: string;
7
+ readonly disabled: boolean;
8
+ readonly groupId: string | undefined;
9
+ };
10
+ export type CommandContext = {
11
+ readonly search: string;
12
+ readonly selectedItemId: string | undefined;
13
+ readonly listId: string;
14
+ readonly loop: boolean;
15
+ readonly shouldFilter: boolean;
16
+ readonly getScore: (itemId: string) => number;
17
+ readonly getVisibleCount: () => number;
18
+ readonly getGroupVisibleCount: (groupId: string) => number;
19
+ readonly registerItem: (entry: CommandItemEntry) => void;
20
+ readonly unregisterItem: (id: string) => void;
21
+ readonly updateItem: (entry: CommandItemEntry) => void;
22
+ readonly registerGroup: (groupId: string) => void;
23
+ readonly unregisterGroup: (groupId: string) => void;
24
+ readonly setSearch: (value: string) => void;
25
+ readonly selectItem: (id: string) => void;
26
+ readonly handleItemSelect: (value: string) => void;
27
+ };
28
+ export declare const commandContext: {
29
+ __context__: CommandContext;
30
+ };
@@ -0,0 +1,3 @@
1
+ /** Ported from original DUI: deep-future-app/app/client/components/dui/command */
2
+ import { createContext } from "@lit/context";
3
+ export const commandContext = createContext(Symbol("dui-command"));
@@ -0,0 +1,10 @@
1
+ /** Ported from original DUI: deep-future-app/app/client/components/dui/command */
2
+ import { LitElement, type TemplateResult } from "lit";
3
+ import { type CommandContext } from "./command-context.js";
4
+ export declare class DuiCommandEmpty extends LitElement {
5
+ static tagName: "dui-command-empty";
6
+ static styles: import("lit").CSSResult[];
7
+ accessor _ctx: CommandContext;
8
+ willUpdate(): void;
9
+ render(): TemplateResult;
10
+ }
@@ -0,0 +1,50 @@
1
+ /** Ported from original DUI: deep-future-app/app/client/components/dui/command */
2
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ };
8
+ import { css, html, LitElement } from "lit";
9
+ import { consume } from "@lit/context";
10
+ import { base } from "@deepfuture/dui-core/base";
11
+ import { commandContext } from "./command-context.js";
12
+ const styles = css `
13
+ :host {
14
+ display: block;
15
+ }
16
+
17
+ :host([data-hidden]) {
18
+ display: none;
19
+ }
20
+
21
+ .Empty {
22
+ text-align: center;
23
+ }
24
+ `;
25
+ export class DuiCommandEmpty extends LitElement {
26
+ static { this.tagName = "dui-command-empty"; }
27
+ static { this.styles = [base, styles]; }
28
+ #_ctx_accessor_storage;
29
+ get _ctx() { return this.#_ctx_accessor_storage; }
30
+ set _ctx(value) { this.#_ctx_accessor_storage = value; }
31
+ willUpdate() {
32
+ const shouldShow = this._ctx?.search !== "" && this._ctx?.getVisibleCount() === 0;
33
+ if (shouldShow) {
34
+ this.removeAttribute("data-hidden");
35
+ }
36
+ else {
37
+ this.setAttribute("data-hidden", "");
38
+ }
39
+ }
40
+ render() {
41
+ return html `
42
+ <div class="Empty" role="status">
43
+ <slot></slot>
44
+ </div>
45
+ `;
46
+ }
47
+ }
48
+ __decorate([
49
+ consume({ context: commandContext, subscribe: true })
50
+ ], DuiCommandEmpty.prototype, "_ctx", null);