@torpor/ui 0.3.7 → 1.0.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 (346) hide show
  1. package/README.md +83 -7
  2. package/dist/Accordion/Accordion.torp +43 -165
  3. package/dist/Accordion/AccordionContent.torp +6 -6
  4. package/dist/Accordion/AccordionHeader.torp +7 -11
  5. package/dist/Accordion/AccordionItem.torp +24 -24
  6. package/dist/Accordion/AccordionTrigger.torp +17 -8
  7. package/dist/Accordion/AccordionTypes.ts +6 -6
  8. package/dist/Accordion/index.d.ts +23 -25
  9. package/dist/Accordion/index.js +6 -22
  10. package/dist/Breadcrumb/Breadcrumb.torp +12 -10
  11. package/dist/Breadcrumb/BreadcrumbItem.torp +6 -6
  12. package/dist/Breadcrumb/BreadcrumbList.torp +21 -0
  13. package/dist/Breadcrumb/BreadcrumbSeparator.torp +4 -4
  14. package/dist/Breadcrumb/index.d.ts +39 -15
  15. package/dist/Breadcrumb/index.js +5 -14
  16. package/dist/Calendar/Calendar.torp +163 -156
  17. package/dist/Calendar/CalendarDay.torp +91 -45
  18. package/dist/Calendar/CalendarDayHeader.torp +36 -0
  19. package/dist/Calendar/CalendarGrid.torp +104 -0
  20. package/dist/Calendar/CalendarGridHeader.torp +43 -0
  21. package/dist/Calendar/CalendarHeader.torp +48 -0
  22. package/dist/Calendar/CalendarHeaderTrigger.torp +54 -0
  23. package/dist/Calendar/CalendarTypes.ts +25 -4
  24. package/dist/Calendar/buildDays.ts +54 -0
  25. package/dist/Calendar/index.d.ts +191 -5
  26. package/dist/Calendar/index.js +8 -10
  27. package/dist/Carousel/Carousel.torp +180 -0
  28. package/dist/Carousel/CarouselIndicators.torp +65 -0
  29. package/dist/Carousel/CarouselNext.torp +43 -0
  30. package/dist/Carousel/CarouselPrevious.torp +44 -0
  31. package/dist/Carousel/CarouselSlide.torp +57 -0
  32. package/dist/Carousel/CarouselTypes.ts +28 -0
  33. package/dist/Carousel/index.d.ts +147 -0
  34. package/dist/Carousel/index.js +6 -0
  35. package/dist/Charts/BarChart.torp +70 -0
  36. package/dist/Charts/Chart.torp +120 -0
  37. package/dist/Charts/ChartBars.torp +78 -0
  38. package/dist/Charts/ChartColumns.torp +66 -0
  39. package/dist/Charts/ChartGrid.torp +54 -0
  40. package/dist/Charts/ChartLines.torp +60 -0
  41. package/dist/Charts/ChartTypes.ts +25 -0
  42. package/dist/Charts/ChartXAxis.torp +83 -0
  43. package/dist/Charts/ChartYAxis.torp +105 -0
  44. package/dist/Charts/ColumnChart.torp +70 -0
  45. package/dist/{Chart → Charts}/GridLines.torp +7 -4
  46. package/dist/Charts/LineChart.torp +73 -0
  47. package/dist/{Chart → Charts}/PieChart.torp +14 -20
  48. package/dist/{Chart → Charts}/ScatterChart.torp +45 -38
  49. package/dist/{Chart → Charts}/SparkLine.torp +16 -19
  50. package/dist/{Chart → Charts}/XAxis.torp +18 -12
  51. package/dist/{Chart → Charts}/YAxis.torp +15 -9
  52. package/dist/Charts/index.d.ts +469 -0
  53. package/dist/Charts/index.js +17 -0
  54. package/dist/ColorPicker/ColorPalette.torp +154 -0
  55. package/dist/ColorPicker/ColorPicker.torp +157 -0
  56. package/dist/ColorPicker/index.d.ts +85 -0
  57. package/dist/ColorPicker/index.js +3 -0
  58. package/dist/ComboBox/ComboBox.torp +205 -0
  59. package/dist/ComboBox/ComboBoxContent.torp +112 -0
  60. package/dist/ComboBox/ComboBoxInput.torp +145 -0
  61. package/dist/ComboBox/ComboBoxTrigger.torp +49 -0
  62. package/dist/ComboBox/ComboBoxTypes.ts +39 -0
  63. package/dist/ComboBox/index.d.ts +152 -0
  64. package/dist/ComboBox/index.js +6 -0
  65. package/dist/CommandPalette/CommandPalette.torp +220 -0
  66. package/dist/CommandPalette/CommandTypes.ts +14 -0
  67. package/dist/CommandPalette/index.d.ts +45 -0
  68. package/dist/CommandPalette/index.js +2 -0
  69. package/dist/Contextual/Contextual.torp +39 -52
  70. package/dist/Contextual/ContextualContent.torp +29 -73
  71. package/dist/Contextual/ContextualHover.torp +112 -0
  72. package/dist/Contextual/ContextualTrigger.torp +31 -42
  73. package/dist/Contextual/ContextualTypes.ts +5 -18
  74. package/dist/Contextual/index.d.ts +44 -27
  75. package/dist/Contextual/index.js +5 -14
  76. package/dist/DataGrid/DataGrid.torp +496 -0
  77. package/dist/DataGrid/DataGridTypes.ts +25 -0
  78. package/dist/DataGrid/index.d.ts +90 -0
  79. package/dist/DataGrid/index.js +3 -0
  80. package/dist/DataGrid/sortRows.ts +32 -0
  81. package/dist/DatePicker/DatePicker.torp +222 -0
  82. package/dist/DatePicker/DatePickerHeader.torp +20 -0
  83. package/dist/DatePicker/index.d.ts +55 -0
  84. package/dist/DatePicker/index.js +2 -0
  85. package/dist/DateRangePicker/DateRangePicker.torp +311 -0
  86. package/dist/DateRangePicker/DateRangePickerDay.torp +137 -0
  87. package/dist/DateRangePicker/DateRangePickerTypes.ts +21 -0
  88. package/dist/DateRangePicker/index.d.ts +76 -0
  89. package/dist/DateRangePicker/index.js +3 -0
  90. package/dist/Dialog/Dialog.torp +33 -30
  91. package/dist/Dialog/DialogBody.torp +5 -9
  92. package/dist/Dialog/DialogButton.torp +14 -11
  93. package/dist/Dialog/DialogFooter.torp +3 -7
  94. package/dist/Dialog/DialogHeader.torp +6 -10
  95. package/dist/Dialog/DialogTypes.ts +2 -2
  96. package/dist/Dialog/index.d.ts +28 -26
  97. package/dist/Dialog/index.js +6 -22
  98. package/dist/Disclosure/Disclosure.torp +18 -18
  99. package/dist/Disclosure/DisclosureContent.torp +5 -6
  100. package/dist/Disclosure/DisclosureHeader.torp +7 -11
  101. package/dist/Disclosure/DisclosureTrigger.torp +4 -5
  102. package/dist/Disclosure/DisclosureTypes.ts +1 -1
  103. package/dist/Disclosure/index.d.ts +14 -16
  104. package/dist/Disclosure/index.js +5 -18
  105. package/dist/Drawer/Drawer.torp +21 -51
  106. package/dist/Drawer/DrawerContent.torp +67 -13
  107. package/dist/Drawer/DrawerOverlay.torp +4 -4
  108. package/dist/Drawer/DrawerTrigger.torp +16 -4
  109. package/dist/Drawer/DrawerTypes.ts +4 -1
  110. package/dist/Drawer/index.d.ts +16 -20
  111. package/dist/Drawer/index.js +5 -18
  112. package/dist/FocusGroup/FocusGroup.torp +70 -0
  113. package/dist/FocusGroup/FocusGroupButton.torp +59 -0
  114. package/dist/FocusGroup/FocusGroupTypes.ts +14 -0
  115. package/dist/FocusGroup/index.d.ts +44 -0
  116. package/dist/FocusGroup/index.js +3 -0
  117. package/dist/Form/CheckBox.torp +28 -20
  118. package/dist/Form/Field.torp +17 -17
  119. package/dist/Form/File.torp +31 -22
  120. package/dist/Form/FileDrop.torp +187 -0
  121. package/dist/Form/Form.torp +24 -22
  122. package/dist/Form/FormTypes.ts +2 -0
  123. package/dist/Form/FormValues.torp +37 -0
  124. package/dist/Form/Hidden.torp +4 -12
  125. package/dist/Form/Input.torp +38 -32
  126. package/dist/Form/Label.torp +3 -3
  127. package/dist/Form/Message.torp +13 -5
  128. package/dist/Form/MessageSummary.torp +39 -0
  129. package/dist/Form/Option.torp +11 -7
  130. package/dist/Form/Select.torp +32 -28
  131. package/dist/Form/TextArea.torp +35 -31
  132. package/dist/Form/Toggle.torp +109 -0
  133. package/dist/Form/index.d.ts +198 -77
  134. package/dist/Form/index.js +16 -46
  135. package/dist/ListBox/ListBox.torp +374 -0
  136. package/dist/ListBox/ListBoxItem.torp +131 -0
  137. package/dist/ListBox/ListBoxSeparator.torp +29 -0
  138. package/dist/ListBox/ListBoxTypes.ts +41 -0
  139. package/dist/ListBox/LoadedListBoxItems.torp +41 -0
  140. package/dist/ListBox/index.d.ts +136 -0
  141. package/dist/ListBox/index.js +4 -0
  142. package/dist/MaskedInput/MaskedInput.torp +143 -0
  143. package/dist/MaskedInput/index.d.ts +52 -0
  144. package/dist/MaskedInput/index.js +2 -0
  145. package/dist/Menu/Menu.torp +90 -70
  146. package/dist/Menu/MenuButton.torp +17 -10
  147. package/dist/Menu/MenuCheck.torp +22 -18
  148. package/dist/Menu/MenuGroup.torp +4 -4
  149. package/dist/Menu/MenuIndicator.torp +5 -13
  150. package/dist/Menu/MenuPopout.torp +20 -50
  151. package/dist/Menu/MenuPopoutContent.torp +15 -66
  152. package/dist/Menu/MenuPopoutTrigger.torp +19 -100
  153. package/dist/Menu/MenuRadio.torp +25 -26
  154. package/dist/Menu/MenuRadioGroup.torp +25 -68
  155. package/dist/Menu/MenuSeparator.torp +3 -2
  156. package/dist/Menu/MenuTypes.ts +12 -21
  157. package/dist/Menu/index.d.ts +45 -51
  158. package/dist/Menu/index.js +12 -46
  159. package/dist/MenuBar/MenuBar.torp +31 -83
  160. package/dist/MenuBar/MenuBarItem.torp +34 -55
  161. package/dist/MenuBar/MenuBarItemContent.torp +15 -101
  162. package/dist/MenuBar/MenuBarItemTrigger.torp +20 -55
  163. package/dist/MenuBar/MenuBarTypes.ts +13 -12
  164. package/dist/MenuBar/index.d.ts +17 -19
  165. package/dist/MenuBar/index.js +5 -18
  166. package/dist/Modal/Modal.torp +28 -48
  167. package/dist/Modal/ModalContent.torp +21 -44
  168. package/dist/Modal/ModalOverlay.torp +4 -4
  169. package/dist/Modal/ModalTrigger.torp +16 -32
  170. package/dist/Modal/ModalTypes.ts +6 -17
  171. package/dist/Modal/index.d.ts +17 -29
  172. package/dist/Modal/index.js +29 -28
  173. package/dist/Modal/index.js.map +1 -1
  174. package/dist/Modal/showPrompt.ts +2 -2
  175. package/dist/NavMenu/NavMenu.torp +22 -104
  176. package/dist/NavMenu/NavMenuButton.torp +10 -8
  177. package/dist/NavMenu/NavMenuElement.torp +6 -7
  178. package/dist/NavMenu/NavMenuGroup.torp +5 -5
  179. package/dist/NavMenu/NavMenuGroupHeader.torp +5 -8
  180. package/dist/NavMenu/NavMenuLink.torp +7 -10
  181. package/dist/NavMenu/NavMenuPopout.torp +16 -61
  182. package/dist/NavMenu/NavMenuPopoutContent.torp +14 -73
  183. package/dist/NavMenu/NavMenuPopoutTrigger.torp +47 -0
  184. package/dist/NavMenu/NavMenuSeparator.torp +3 -6
  185. package/dist/NavMenu/NavMenuTypes.ts +6 -15
  186. package/dist/NavMenu/index.d.ts +55 -55
  187. package/dist/NavMenu/index.js +11 -42
  188. package/dist/Notification/Notification.torp +12 -24
  189. package/dist/Notification/NotificationClose.torp +6 -3
  190. package/dist/Notification/NotificationContainer.torp +3 -7
  191. package/dist/Notification/NotificationContent.torp +3 -7
  192. package/dist/Notification/NotificationTypes.ts +1 -1
  193. package/dist/Notification/index.d.ts +15 -12
  194. package/dist/Notification/index.js +22 -32
  195. package/dist/Notification/index.js.map +1 -1
  196. package/dist/NumberInput/NumberInput.torp +255 -0
  197. package/dist/NumberInput/index.d.ts +44 -0
  198. package/dist/NumberInput/index.js +2 -0
  199. package/dist/Pagination/Pagination.torp +152 -0
  200. package/dist/Pagination/PaginationItem.torp +137 -0
  201. package/dist/Pagination/PaginationTypes.ts +22 -0
  202. package/dist/Pagination/buildPages.ts +61 -0
  203. package/dist/Pagination/index.d.ts +63 -0
  204. package/dist/Pagination/index.js +3 -0
  205. package/dist/Popover/Popover.torp +39 -52
  206. package/dist/Popover/PopoverContent.torp +27 -76
  207. package/dist/Popover/PopoverHover.torp +90 -0
  208. package/dist/Popover/PopoverTrigger.torp +17 -40
  209. package/dist/Popover/PopoverTypes.ts +5 -18
  210. package/dist/Popover/index.d.ts +40 -25
  211. package/dist/Popover/index.js +18 -18
  212. package/dist/Popover/index.js.map +1 -1
  213. package/dist/Progress/Progress.torp +88 -0
  214. package/dist/Progress/index.d.ts +37 -0
  215. package/dist/Progress/index.js +2 -0
  216. package/dist/Rating/Rating.torp +225 -0
  217. package/dist/Rating/index.d.ts +44 -0
  218. package/dist/Rating/index.js +2 -0
  219. package/dist/SegmentedControl/SegmentedControl.torp +233 -0
  220. package/dist/SegmentedControl/SegmentedControlTypes.ts +26 -0
  221. package/dist/SegmentedControl/SegmentedItem.torp +78 -0
  222. package/dist/SegmentedControl/index.d.ts +74 -0
  223. package/dist/SegmentedControl/index.js +3 -0
  224. package/dist/SelectBox/SelectBox.torp +190 -0
  225. package/dist/SelectBox/SelectBoxContent.torp +107 -0
  226. package/dist/SelectBox/SelectBoxTrigger.torp +141 -0
  227. package/dist/SelectBox/SelectBoxTypes.ts +33 -0
  228. package/dist/SelectBox/index.d.ts +112 -0
  229. package/dist/SelectBox/index.js +5 -0
  230. package/dist/Slider/Slider.torp +248 -0
  231. package/dist/Slider/index.d.ts +45 -0
  232. package/dist/Slider/index.js +2 -0
  233. package/dist/Splitter/Splitter.torp +156 -0
  234. package/dist/Splitter/SplitterHandle.torp +161 -0
  235. package/dist/Splitter/SplitterPane.torp +63 -0
  236. package/dist/Splitter/SplitterTypes.ts +31 -0
  237. package/dist/Splitter/index.d.ts +103 -0
  238. package/dist/Splitter/index.js +4 -0
  239. package/dist/Stepper/Stepper.torp +146 -0
  240. package/dist/Stepper/StepperMarker.torp +24 -0
  241. package/dist/Stepper/StepperNext.torp +44 -0
  242. package/dist/Stepper/StepperPrevious.torp +44 -0
  243. package/dist/Stepper/StepperStep.torp +90 -0
  244. package/dist/Stepper/StepperTypes.ts +30 -0
  245. package/dist/Stepper/index.d.ts +149 -0
  246. package/dist/Stepper/index.js +6 -0
  247. package/dist/TabGroup/TabContent.torp +6 -6
  248. package/dist/TabGroup/TabGroup.torp +97 -113
  249. package/dist/TabGroup/TabGroupTypes.ts +3 -3
  250. package/dist/TabGroup/TabHeader.torp +23 -19
  251. package/dist/TabGroup/TabList.torp +8 -21
  252. package/dist/TabGroup/TabTrigger.torp +6 -7
  253. package/dist/TabGroup/index.d.ts +26 -26
  254. package/dist/TabGroup/index.js +6 -22
  255. package/dist/TagInput/TagInput.torp +378 -0
  256. package/dist/TagInput/index.d.ts +48 -0
  257. package/dist/TagInput/index.js +2 -0
  258. package/dist/TimePicker/TimePicker.torp +462 -0
  259. package/dist/TimePicker/index.d.ts +53 -0
  260. package/dist/TimePicker/index.js +2 -0
  261. package/dist/ToolBar/ToolBar.torp +117 -0
  262. package/dist/ToolBar/ToolBarButton.torp +56 -0
  263. package/dist/ToolBar/ToolBarElement.torp +51 -0
  264. package/dist/ToolBar/ToolBarPopout.torp +45 -0
  265. package/dist/ToolBar/ToolBarPopoutContent.torp +34 -0
  266. package/dist/ToolBar/ToolBarPopoutTrigger.torp +47 -0
  267. package/dist/ToolBar/ToolBarSeparator.torp +21 -0
  268. package/dist/ToolBar/ToolBarTypes.ts +28 -0
  269. package/dist/ToolBar/index.d.ts +210 -0
  270. package/dist/ToolBar/index.js +8 -0
  271. package/dist/Tree/Tree.torp +395 -0
  272. package/dist/Tree/TreeItem.torp +176 -0
  273. package/dist/Tree/TreeItemChildren.torp +60 -0
  274. package/dist/Tree/TreeItemContent.torp +46 -0
  275. package/dist/Tree/TreeItemLabel.torp +94 -0
  276. package/dist/Tree/TreeItemTrigger.torp +78 -0
  277. package/dist/Tree/TreeLoadedChildren.torp +122 -0
  278. package/dist/Tree/TreeTypes.ts +63 -0
  279. package/dist/Tree/index.d.ts +262 -0
  280. package/dist/Tree/index.js +7 -0
  281. package/dist/icons/ChevronDoubleLeft.torp +19 -0
  282. package/dist/icons/ChevronDoubleRight.torp +19 -0
  283. package/dist/icons/index.d.ts +61 -1
  284. package/dist/icons/index.js +17 -58
  285. package/dist/loader-DEeG5vFY.js +44 -0
  286. package/dist/loader-DEeG5vFY.js.map +1 -0
  287. package/dist/motion/index.d.ts +12 -8
  288. package/dist/motion/index.d.ts.map +1 -0
  289. package/dist/motion/index.js +72 -88
  290. package/dist/motion/index.js.map +1 -1
  291. package/dist/mount/draggable.ts +63 -0
  292. package/dist/mount/dropTarget.ts +108 -0
  293. package/dist/mount/hoverTrigger.ts +1 -1
  294. package/dist/utils/$handle.ts +23 -0
  295. package/dist/utils/LoadedItems.torp +47 -0
  296. package/dist/utils/PopoutClickTrigger.torp +99 -0
  297. package/dist/utils/PopoutTypes.ts +82 -0
  298. package/dist/utils/SubmenuPopout.torp +89 -0
  299. package/dist/utils/SubmenuPopoutContent.torp +87 -0
  300. package/dist/utils/SubmenuPopoutTrigger.torp +160 -0
  301. package/dist/utils/chartColors.ts +13 -13
  302. package/dist/utils/chartLayout.ts +143 -0
  303. package/dist/utils/chartUtils.ts +1 -1
  304. package/dist/utils/colorUtils.ts +103 -0
  305. package/dist/utils/createItemGroup.ts +152 -0
  306. package/dist/utils/dateUtils.ts +8 -7
  307. package/dist/utils/documentEvents.ts +4 -4
  308. package/dist/utils/dragState.ts +86 -0
  309. package/dist/utils/focusGroup.ts +204 -0
  310. package/dist/utils/focusItem.ts +44 -0
  311. package/dist/utils/formField.ts +70 -0
  312. package/dist/utils/hoverOpen.ts +50 -0
  313. package/dist/utils/hoverReveal.ts +194 -0
  314. package/dist/utils/loader.ts +113 -0
  315. package/dist/utils/maskUtils.ts +98 -0
  316. package/dist/utils/popoutContent.ts +137 -0
  317. package/dist/utils/reorderList.ts +52 -0
  318. package/package.json +116 -25
  319. package/dist/Accordion/index.js.map +0 -1
  320. package/dist/Breadcrumb/index.js.map +0 -1
  321. package/dist/Calendar/index.js.map +0 -1
  322. package/dist/Chart/BarChart.torp +0 -159
  323. package/dist/Chart/LineChart.torp +0 -196
  324. package/dist/Chart/index.d.ts +0 -220
  325. package/dist/Chart/index.js +0 -34
  326. package/dist/Chart/index.js.map +0 -1
  327. package/dist/Contextual/index.js.map +0 -1
  328. package/dist/Dialog/index.js.map +0 -1
  329. package/dist/Disclosure/index.js.map +0 -1
  330. package/dist/Drawer/index.js.map +0 -1
  331. package/dist/Form/index.js.map +0 -1
  332. package/dist/Menu/index.js.map +0 -1
  333. package/dist/MenuBar/index.js.map +0 -1
  334. package/dist/NavMenu/NavMenuPopoutButton.torp +0 -129
  335. package/dist/NavMenu/index.js.map +0 -1
  336. package/dist/TabGroup/index.js.map +0 -1
  337. package/dist/icons/index.js.map +0 -1
  338. package/dist/index.d.ts +0 -19
  339. package/dist/metafile-esm.json +0 -1
  340. package/dist/motion/fade.ts +0 -16
  341. package/dist/motion/grow.ts +0 -23
  342. package/dist/motion/measure.ts +0 -28
  343. package/dist/motion/slide.ts +0 -45
  344. package/dist/mount/index.d.ts +0 -2
  345. package/dist/utils/index.d.ts +0 -2
  346. /package/dist/{Chart → Charts}/DataSeries.ts +0 -0
@@ -0,0 +1,190 @@
1
+ import type { Bindable, ClassValue, StyleValue } from "@torpor/view";
2
+ import $handle from "../utils/$handle";
3
+ import {
4
+ type FieldContext,
5
+ FieldContextName,
6
+ type FormContext,
7
+ FormContextName,
8
+ } from "../Form/FormTypes";
9
+ import FormValues from "../Form/FormValues.torp";
10
+ import { type LoadResult, type Loader, createItemLoader } from "../utils/loader";
11
+ import { type PopoutContext, PopoutContextName } from "../utils/PopoutTypes";
12
+ import createFormField from "../utils/formField";
13
+ import { type SelectBoxContext, SelectBoxContextName, type SelectBoxState } from "./SelectBoxTypes";
14
+
15
+ interface SelectBoxProps {
16
+ /** An ID for the root element */
17
+ id?: string;
18
+ /** Classes for the root element */
19
+ class?: ClassValue;
20
+ /** Styles for the root element */
21
+ style?: StyleValue;
22
+ /** The name of the input's form data field */
23
+ name?: string;
24
+ /** The data value selected by the user, or an array of values if multiple is set */
25
+ value: Bindable<any>;
26
+ /** Whether multiple values can be selected at the same time */
27
+ multiple?: boolean;
28
+ /**
29
+ * Reads options from the network (or anywhere async) when the box is
30
+ * shown. When set and no content is slotted in, the options are rendered
31
+ * automatically.
32
+ */
33
+ load?: Loader;
34
+ /** Called after each successful load with the normalized result */
35
+ onload?: (result: LoadResult) => void;
36
+ /** Extracts the display text for a loaded item (defaults to `label ?? text ?? item`) */
37
+ getItemLabel?: (item: any) => any;
38
+ /** Extracts the value for a loaded item (defaults to `value ?? id`) */
39
+ getItemValue?: (item: any) => any;
40
+ /** Text to display when the input value is empty */
41
+ placeholder?: string;
42
+ ///** Whether the input's value is required */
43
+ //required?: boolean,
44
+ /** Whether the popout is visible; only bind this to control it from outside */
45
+ visible?: Bindable<boolean | undefined>;
46
+ /** Raised when the value has changed */
47
+ onchange?: (value: any) => void;
48
+ /** Raised when the popout has opened */
49
+ onopen?: () => void;
50
+ /** Raised when the popout has closed */
51
+ onclose?: (result: any) => void;
52
+ }
53
+
54
+ /**
55
+ * An input box for selecting a value from a popout ListBox or Dialog.
56
+ *
57
+ * See [the WAI ARIA guidelines for ComboBoxes](https://www.w3.org/WAI/ARIA/apg/patterns/combobox/).
58
+ *
59
+ * The structure of a SelectBox is:
60
+ *
61
+ * ```
62
+ * <SelectBox>
63
+ * <SelectBoxTrigger />
64
+ * <SelectBoxContent />
65
+ * </SelectBox>
66
+ * ```
67
+ */
68
+ export default function SelectBox($props: SelectBoxProps | undefined) {
69
+ // Wire up the enclosing Form and Field, if any
70
+ const form = createFormField(
71
+ $props?.name,
72
+ $context[FormContextName] as FormContext | undefined,
73
+ $context[FieldContextName] as FieldContext | undefined,
74
+ );
75
+
76
+ let $state: SelectBoxState = $watch({
77
+ visible: false,
78
+ value: $props?.value,
79
+ contentId: undefined,
80
+ triggerId: undefined,
81
+ contentRole: undefined,
82
+ });
83
+
84
+ $bind($state, $props, "visible", "value");
85
+
86
+ if ($props?.load !== undefined && typeof $props.load !== "function") {
87
+ throw new Error("SelectBox: `load` must be a function");
88
+ }
89
+ const hasLoader = typeof $props?.load === "function";
90
+
91
+ // Load options from the network (lazily, on first read)
92
+ const $load = hasLoader
93
+ ? createItemLoader({
94
+ load: $props!.load!,
95
+ getRequest: () => ({}),
96
+ onload: (r) => $props?.onload?.(r),
97
+ })
98
+ : undefined;
99
+
100
+ let result: any;
101
+
102
+ // Set the context to pass down to items
103
+ let context: SelectBoxContext = {
104
+ handleButton,
105
+ handleClickOutside,
106
+ get placeholder() {
107
+ return $props?.placeholder;
108
+ },
109
+ get multiple() {
110
+ return $props?.multiple === true;
111
+ },
112
+ inField: () => form.inField,
113
+ valid: () => form.valid,
114
+ messageId: () => form.messageId,
115
+ handleBlur: () => form.handleBlur(),
116
+ state: $state,
117
+ getLoadedItems: $load ? () => $load.items : undefined,
118
+ getItemLabel: $props?.getItemLabel,
119
+ getItemValue: $props?.getItemValue,
120
+ };
121
+ $context[SelectBoxContextName] = context;
122
+
123
+ // Set the context to pass down to items
124
+ let popoutContext: PopoutContext = context;
125
+ $context[PopoutContextName] = popoutContext;
126
+
127
+ // Dispatch the change event when the value changes
128
+ $handle((first) => {
129
+ const value = $state.value;
130
+ if (!first) {
131
+ form.handleInput();
132
+ $props?.onchange?.(value);
133
+ }
134
+ });
135
+
136
+ // Dispatch the open/close events when the popout is opened or closed
137
+ $handle((first) => {
138
+ const visible = $state.visible;
139
+ if (first) return;
140
+ if (visible) {
141
+ $props?.onopen?.();
142
+ } else {
143
+ $props?.onclose?.(result);
144
+ }
145
+ });
146
+
147
+ function handleButton(type: "confirm" | "cancel" | undefined, value?: any) {
148
+ // Get the button's result
149
+ switch (type) {
150
+ case "confirm": {
151
+ result = value ?? true;
152
+ break;
153
+ }
154
+ case "cancel": {
155
+ result = value ?? false;
156
+ break;
157
+ }
158
+ default: {
159
+ result = value;
160
+ break;
161
+ }
162
+ }
163
+
164
+ // Update the value
165
+ if (type !== "cancel") {
166
+ $state.value = result;
167
+ }
168
+
169
+ // Hide the popout and focus the button
170
+ if (type === "confirm" || type === "cancel") {
171
+ $state.visible = false;
172
+ if (context.focusTrigger) {
173
+ context.focusTrigger();
174
+ }
175
+ }
176
+ }
177
+
178
+ function handleClickOutside(e: MouseEvent | KeyboardEvent) {
179
+ e.preventDefault();
180
+ $state.visible = false;
181
+ }
182
+
183
+ @render {
184
+ <div {$props?.id} class={["torp-select-box", $props?.class]} {$props?.style}>
185
+ <slot />
186
+ </div>
187
+
188
+ <FormValues name={form.name} value={$state.value} />
189
+ }
190
+ }
@@ -0,0 +1,107 @@
1
+ import type { ClassValue, StyleValue } from "@torpor/view";
2
+ import { addDocumentEvent, removeDocumentEvent } from "../utils/documentEvents";
3
+ import LoadedItems from "../utils/LoadedItems.torp";
4
+ import { type SelectBoxContext, SelectBoxContextName } from "./SelectBoxTypes";
5
+
6
+ interface SelectBoxContentProps {
7
+ /** An ID for the root element */
8
+ id?: string;
9
+ /** Classes for the root element */
10
+ class?: ClassValue;
11
+ /** Styles for the root element */
12
+ style?: StyleValue;
13
+ }
14
+
15
+ /**
16
+ * The content that is displayed for a SelectBox when it is open, displayed
17
+ * alongside an element.
18
+ */
19
+ export default function SelectBoxContent($props: SelectBoxContentProps | undefined) {
20
+ let div: HTMLDivElement;
21
+ let shown = false;
22
+ let closeOnClick = false;
23
+
24
+ // Get stuff out of the SelectBoxContext
25
+ const context = $context[SelectBoxContextName] as SelectBoxContext;
26
+ if (!context) {
27
+ throw new Error("SelectBoxContent must be contained within a SelectBox");
28
+ }
29
+ let $state = context.state;
30
+
31
+ $run(() => {
32
+ if (!$state.visible) {
33
+ hide();
34
+ }
35
+ });
36
+
37
+ function show(_: HTMLElement) {
38
+ shown = true;
39
+
40
+ // HACK: Because this SelectBox could be shown with a click, we need to wait for another mousedown
41
+ // before we close on click. Otherwise the click immediately bubbles to the document
42
+ closeOnClick = false;
43
+ addDocumentEvent("mousedown", handleDocumentMouseDown);
44
+ addDocumentEvent("click", handleDocumentClick);
45
+ }
46
+
47
+ function hide() {
48
+ if (!shown) return;
49
+
50
+ removeDocumentEvent("mousedown", handleDocumentMouseDown);
51
+ removeDocumentEvent("click", handleDocumentClick);
52
+ }
53
+
54
+ function handleDocumentMouseDown() {
55
+ closeOnClick = true;
56
+ }
57
+
58
+ function handleDocumentClick(e: MouseEvent) {
59
+ if (closeOnClick && div && !div.contains(e.target as HTMLElement)) {
60
+ e.preventDefault();
61
+ context.handleClickOutside!(e);
62
+ }
63
+ }
64
+
65
+ // HACK: We need to keep the items in the document so that we can search through them
66
+ @render {
67
+ @//if ($state.visible) {
68
+ <div
69
+ {$props?.id}
70
+ class={["torp-select-box-content", $props?.class, $state.visible ? undefined : "hidden"]}
71
+ {$props?.style}
72
+ aria-hidden={$state.visible ? undefined : "true"}
73
+ &ref={div}
74
+ onmount={show}
75
+ >
76
+ <slot>
77
+ @if (context.getLoadedItems) {
78
+ @// Options loaded from a network loader, rendered automatically
79
+ @try {
80
+ @await {
81
+ <LoadedItems
82
+ items={context.getLoadedItems!()}
83
+ value={$state.value}
84
+ multiple={context.multiple}
85
+ getItemLabel={context.getItemLabel}
86
+ getItemValue={context.getItemValue}
87
+ />
88
+ } with {
89
+ <span class="torp-select-box-loading">Loading…</span>
90
+ }
91
+ } catch (err) {
92
+ <span class="torp-select-box-error" role="alert">
93
+ {err instanceof Error ? err.message : String(err)}
94
+ </span>
95
+ }
96
+ }
97
+ </slot>
98
+ </div>
99
+ @//}
100
+ }
101
+
102
+ @style {
103
+ .torp-select-box-content.hidden {
104
+ display: none;
105
+ }
106
+ }
107
+ }
@@ -0,0 +1,141 @@
1
+ import type { ClassValue, StyleValue } from "@torpor/view";
2
+ import getId from "../utils/getId";
3
+ import { type SelectBoxContext, SelectBoxContextName } from "./SelectBoxTypes";
4
+
5
+ interface SelectBoxTriggerProps {
6
+ /** An ID for the root element */
7
+ id?: string;
8
+ /** Classes for the root element */
9
+ class?: ClassValue;
10
+ /** Styles for the root element */
11
+ style?: StyleValue;
12
+ /** An ARIA label for describing the trigger to screen readers when there is no associated label element */
13
+ ariaLabel?: string;
14
+ }
15
+
16
+ /**
17
+ * The input that causes a SelectBox to appear or disappear.
18
+ */
19
+ export default function SelectBoxTrigger($props: SelectBoxTriggerProps | undefined) {
20
+ let defaultId = getId();
21
+ let button: HTMLButtonElement;
22
+
23
+ // Get stuff out of the SelectBoxContext
24
+ const context = $context[SelectBoxContextName] as SelectBoxContext;
25
+ if (!context) {
26
+ throw new Error("SelectBoxTrigger must be contained within a SelectBox");
27
+ }
28
+ let $state = context.state;
29
+ context.focusTrigger = focusTrigger;
30
+
31
+ // Set the trigger ID so that it can be used with aria-labelledby
32
+ $state.triggerId = $props?.id ?? defaultId;
33
+
34
+ function focusTrigger() {
35
+ button.focus();
36
+ }
37
+
38
+ function displayValue(): string | undefined {
39
+ const value = $state.value;
40
+ if (value === undefined || value === null || value === "") {
41
+ return undefined;
42
+ }
43
+ return Array.isArray(value) ? (value as any[]).join(", ") : String(value);
44
+ }
45
+
46
+ function handleClick() {
47
+ $state.visible = !$state.visible;
48
+ if (!$state.visible) {
49
+ context.searchText = "";
50
+ }
51
+ }
52
+
53
+ function handleKey(e: KeyboardEvent) {
54
+ switch (e.key) {
55
+ case "ArrowDown": {
56
+ e.preventDefault();
57
+ $state.visible = true;
58
+ if (context.focusFirstElement) {
59
+ context.focusFirstElement();
60
+ }
61
+ break;
62
+ }
63
+ case "ArrowUp": {
64
+ e.preventDefault();
65
+ $state.visible = true;
66
+ if (context.focusLastElement) {
67
+ context.focusLastElement();
68
+ }
69
+ break;
70
+ }
71
+ case "Escape": {
72
+ if ($state.visible) {
73
+ e.preventDefault();
74
+ // NOTE: This may be too much of a departure from standards
75
+ if (context.searchText !== undefined && context.searchText !== "") {
76
+ context.searchText = "";
77
+ } else {
78
+ $state.visible = false;
79
+ }
80
+ }
81
+ break;
82
+ }
83
+ case "Backspace": {
84
+ if (context.searchText && context.searchItems) {
85
+ e.preventDefault();
86
+ const shorten = (str: string) => str.substring(0, str.length - 1);
87
+ context.searchText = shorten(context.searchText!);
88
+ if (context.searchText.length > 0) {
89
+ const found = context.searchItems(context.searchText);
90
+ if (found) {
91
+ found.setFocused();
92
+ }
93
+ }
94
+ }
95
+ break;
96
+ }
97
+ default: {
98
+ // TODO: Handle unicode
99
+ if (e.key.length === 1 && context.searchItems) {
100
+ e.preventDefault();
101
+ context.searchText ??= "";
102
+ context.searchText += e.key;
103
+ const found = context.searchItems(context.searchText);
104
+ if (found !== undefined) {
105
+ $state.visible = true;
106
+ found.setFocused();
107
+ }
108
+ }
109
+ }
110
+ }
111
+ }
112
+
113
+ @render {
114
+ <button
115
+ type="button"
116
+ role="combobox"
117
+ id={$props?.id ?? defaultId}
118
+ class={["torp-select-box-trigger", $props?.class]}
119
+ {$props?.style}
120
+ aria-controls={$state.contentId}
121
+ aria-haspopup={$state.contentRole}
122
+ aria-expanded={$state.visible ? "true" : "false"}
123
+ aria-label={$props?.ariaLabel}
124
+ data-valid={context.valid?.() ? "valid" : "invalid"}
125
+ aria-describedby={context.messageId?.()}
126
+ aria-invalid={context.inField?.() && !context.valid?.() ? "true" : undefined}
127
+ onblur={() => context.handleBlur?.()}
128
+ onclick={handleClick}
129
+ onkeydown={handleKey}
130
+ &ref={button}
131
+ >
132
+ <slot>
133
+ @if (displayValue()) {
134
+ <span>{displayValue()}</span>
135
+ } @else {
136
+ <span>{context.placeholder || "-"}</span>
137
+ }
138
+ </slot>
139
+ </button>
140
+ }
141
+ }
@@ -0,0 +1,33 @@
1
+ import { type PopoutContext, type PopoutState } from "../utils/PopoutTypes";
2
+ import { type LoadResult, type Loader } from "../utils/loader";
3
+
4
+ export const SelectBoxContextName: unique symbol = Symbol.for("torp.SelectBox");
5
+
6
+ /** The shared context for SelectBox components */
7
+ export interface SelectBoxContext extends PopoutContext {
8
+ placeholder?: string;
9
+ multiple?: boolean;
10
+ state: SelectBoxState;
11
+ focusTrigger?: () => void;
12
+ /** Whether the component is contained within a Form Field */
13
+ inField?: () => boolean;
14
+ /** Whether the Field's value is valid, for data-valid / aria-invalid */
15
+ valid?: () => boolean;
16
+ /** The ID of the Field's Message component, for aria-describedby */
17
+ messageId?: () => string | undefined;
18
+ /** Called by the trigger when it loses focus, to run Field validation */
19
+ handleBlur?: () => void;
20
+ /** Returns the items loaded from the network loader, when one is set */
21
+ getLoadedItems?: () => any[];
22
+ /** Extracts the display text for a loaded item */
23
+ getItemLabel?: (item: any) => any;
24
+ /** Extracts the value for a loaded item */
25
+ getItemValue?: (item: any) => any;
26
+ }
27
+
28
+ export interface SelectBoxState extends PopoutState {
29
+ value: any;
30
+ name?: string;
31
+ }
32
+
33
+ export type { LoadResult, Loader };
@@ -0,0 +1,112 @@
1
+ import { type SlotRender } from "@torpor/view";
2
+
3
+
4
+ interface SelectBoxProps {
5
+ /** An ID for the root element */
6
+ id?: string;
7
+ /** Classes for the root element */
8
+ class?: ClassValue;
9
+ /** Styles for the root element */
10
+ style?: StyleValue;
11
+ /** The name of the input's form data field */
12
+ name?: string;
13
+ /** The data value selected by the user, or an array of values if multiple is set */
14
+ value: Bindable<any>;
15
+ /** Whether multiple values can be selected at the same time */
16
+ multiple?: boolean;
17
+ /**
18
+ * Reads options from the network (or anywhere async) when the box is
19
+ * shown. When set and no content is slotted in, the options are rendered
20
+ * automatically.
21
+ */
22
+ load?: Loader;
23
+ /** Called after each successful load with the normalized result */
24
+ onload?: (result: LoadResult) => void;
25
+ /** Extracts the display text for a loaded item (defaults to `label ?? text ?? item`) */
26
+ getItemLabel?: (item: any) => any;
27
+ /** Extracts the value for a loaded item (defaults to `value ?? id`) */
28
+ getItemValue?: (item: any) => any;
29
+ /** Text to display when the input value is empty */
30
+ placeholder?: string;
31
+ ///** Whether the input's value is required */
32
+ //required?: boolean,
33
+ /** Whether the popout is visible; only bind this to control it from outside */
34
+ visible?: Bindable<boolean | undefined>;
35
+ /** Raised when the value has changed */
36
+ onchange?: (value: any) => void;
37
+ /** Raised when the popout has opened */
38
+ onopen?: () => void;
39
+ /** Raised when the popout has closed */
40
+ onclose?: (result: any) => void;
41
+ }
42
+
43
+ /**
44
+ * An input box for selecting a value from a popout ListBox or Dialog.
45
+ *
46
+ * See [the WAI ARIA guidelines for ComboBoxes](https://www.w3.org/WAI/ARIA/apg/patterns/combobox/).
47
+ *
48
+ * The structure of a SelectBox is:
49
+ *
50
+ * ```
51
+ * <SelectBox>
52
+ * <SelectBoxTrigger />
53
+ * <SelectBoxContent />
54
+ * </SelectBox>
55
+ * ```
56
+ */
57
+ declare function SelectBox(
58
+ $parent: ParentNode,
59
+ $anchor: Node | null,
60
+ $props: SelectBoxProps | undefined,
61
+ $context?: Record<PropertyKey, any>,
62
+ $slots?: Record<string, SlotRender>,
63
+ ): void;
64
+
65
+
66
+
67
+ interface SelectBoxContentProps {
68
+ /** An ID for the root element */
69
+ id?: string;
70
+ /** Classes for the root element */
71
+ class?: ClassValue;
72
+ /** Styles for the root element */
73
+ style?: StyleValue;
74
+ }
75
+
76
+ /**
77
+ * The content that is displayed for a SelectBox when it is open, displayed
78
+ * alongside an element.
79
+ */
80
+ declare function SelectBoxContent(
81
+ $parent: ParentNode,
82
+ $anchor: Node | null,
83
+ $props: SelectBoxContentProps | undefined,
84
+ $context?: Record<PropertyKey, any>,
85
+ $slots?: Record<string, SlotRender>,
86
+ ): void;
87
+
88
+
89
+
90
+ interface SelectBoxTriggerProps {
91
+ /** An ID for the root element */
92
+ id?: string;
93
+ /** Classes for the root element */
94
+ class?: ClassValue;
95
+ /** Styles for the root element */
96
+ style?: StyleValue;
97
+ /** An ARIA label for describing the trigger to screen readers when there is no associated label element */
98
+ ariaLabel?: string;
99
+ }
100
+
101
+ /**
102
+ * The input that causes a SelectBox to appear or disappear.
103
+ */
104
+ declare function SelectBoxTrigger(
105
+ $parent: ParentNode,
106
+ $anchor: Node | null,
107
+ $props: SelectBoxTriggerProps | undefined,
108
+ $context?: Record<PropertyKey, any>,
109
+ $slots?: Record<string, SlotRender>,
110
+ ): void;
111
+
112
+ export { SelectBox, SelectBoxContent, SelectBoxTrigger };
@@ -0,0 +1,5 @@
1
+ import { n as normalizeLoadResult, t as createItemLoader } from "../loader-DEeG5vFY.js";
2
+ import SelectBox from "./SelectBox.torp";
3
+ import SelectBoxContent from "./SelectBoxContent.torp";
4
+ import SelectBoxTrigger from "./SelectBoxTrigger.torp";
5
+ export { SelectBox, SelectBoxContent, SelectBoxTrigger, createItemLoader, normalizeLoadResult };