@torpor/ui 0.4.0 → 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.
- package/README.md +83 -7
- package/dist/Accordion/Accordion.torp +42 -165
- package/dist/Accordion/AccordionContent.torp +6 -6
- package/dist/Accordion/AccordionHeader.torp +7 -11
- package/dist/Accordion/AccordionItem.torp +24 -24
- package/dist/Accordion/AccordionTrigger.torp +17 -8
- package/dist/Accordion/AccordionTypes.ts +1 -1
- package/dist/Accordion/index.d.ts +23 -25
- package/dist/Accordion/index.js +6 -22
- package/dist/Breadcrumb/Breadcrumb.torp +12 -10
- package/dist/Breadcrumb/BreadcrumbItem.torp +6 -6
- package/dist/Breadcrumb/BreadcrumbList.torp +21 -0
- package/dist/Breadcrumb/BreadcrumbSeparator.torp +4 -4
- package/dist/Breadcrumb/index.d.ts +39 -15
- package/dist/Breadcrumb/index.js +5 -14
- package/dist/Calendar/Calendar.torp +163 -156
- package/dist/Calendar/CalendarDay.torp +91 -45
- package/dist/Calendar/CalendarDayHeader.torp +36 -0
- package/dist/Calendar/CalendarGrid.torp +104 -0
- package/dist/Calendar/CalendarGridHeader.torp +43 -0
- package/dist/Calendar/CalendarHeader.torp +48 -0
- package/dist/Calendar/CalendarHeaderTrigger.torp +54 -0
- package/dist/Calendar/CalendarTypes.ts +24 -3
- package/dist/Calendar/buildDays.ts +54 -0
- package/dist/Calendar/index.d.ts +191 -5
- package/dist/Calendar/index.js +8 -10
- package/dist/Carousel/Carousel.torp +180 -0
- package/dist/Carousel/CarouselIndicators.torp +65 -0
- package/dist/Carousel/CarouselNext.torp +43 -0
- package/dist/Carousel/CarouselPrevious.torp +44 -0
- package/dist/Carousel/CarouselSlide.torp +57 -0
- package/dist/Carousel/CarouselTypes.ts +28 -0
- package/dist/Carousel/index.d.ts +147 -0
- package/dist/Carousel/index.js +6 -0
- package/dist/Charts/BarChart.torp +55 -144
- package/dist/Charts/Chart.torp +120 -0
- package/dist/Charts/ChartBars.torp +78 -0
- package/dist/Charts/ChartColumns.torp +66 -0
- package/dist/Charts/ChartGrid.torp +54 -0
- package/dist/Charts/ChartLines.torp +60 -0
- package/dist/Charts/ChartTypes.ts +25 -0
- package/dist/Charts/ChartXAxis.torp +83 -0
- package/dist/Charts/ChartYAxis.torp +105 -0
- package/dist/Charts/ColumnChart.torp +70 -0
- package/dist/Charts/GridLines.torp +4 -4
- package/dist/Charts/LineChart.torp +55 -178
- package/dist/Charts/PieChart.torp +14 -20
- package/dist/Charts/ScatterChart.torp +45 -38
- package/dist/Charts/SparkLine.torp +16 -19
- package/dist/Charts/XAxis.torp +11 -11
- package/dist/Charts/YAxis.torp +8 -8
- package/dist/Charts/index.d.ts +328 -79
- package/dist/Charts/index.js +17 -34
- package/dist/ColorPicker/ColorPalette.torp +154 -0
- package/dist/ColorPicker/ColorPicker.torp +157 -0
- package/dist/ColorPicker/index.d.ts +85 -0
- package/dist/ColorPicker/index.js +3 -0
- package/dist/ComboBox/ComboBox.torp +205 -0
- package/dist/ComboBox/ComboBoxContent.torp +112 -0
- package/dist/ComboBox/ComboBoxInput.torp +145 -0
- package/dist/ComboBox/ComboBoxTrigger.torp +49 -0
- package/dist/ComboBox/ComboBoxTypes.ts +39 -0
- package/dist/ComboBox/index.d.ts +152 -0
- package/dist/ComboBox/index.js +6 -0
- package/dist/CommandPalette/CommandPalette.torp +220 -0
- package/dist/CommandPalette/CommandTypes.ts +14 -0
- package/dist/CommandPalette/index.d.ts +45 -0
- package/dist/CommandPalette/index.js +2 -0
- package/dist/Contextual/Contextual.torp +32 -50
- package/dist/Contextual/ContextualContent.torp +29 -73
- package/dist/Contextual/ContextualHover.torp +112 -0
- package/dist/Contextual/ContextualTrigger.torp +31 -42
- package/dist/Contextual/ContextualTypes.ts +4 -17
- package/dist/Contextual/index.d.ts +44 -27
- package/dist/Contextual/index.js +5 -14
- package/dist/DataGrid/DataGrid.torp +496 -0
- package/dist/DataGrid/DataGridTypes.ts +25 -0
- package/dist/DataGrid/index.d.ts +90 -0
- package/dist/DataGrid/index.js +3 -0
- package/dist/DataGrid/sortRows.ts +32 -0
- package/dist/DatePicker/DatePicker.torp +222 -0
- package/dist/DatePicker/DatePickerHeader.torp +20 -0
- package/dist/DatePicker/index.d.ts +55 -0
- package/dist/DatePicker/index.js +2 -0
- package/dist/DateRangePicker/DateRangePicker.torp +311 -0
- package/dist/DateRangePicker/DateRangePickerDay.torp +137 -0
- package/dist/DateRangePicker/DateRangePickerTypes.ts +21 -0
- package/dist/DateRangePicker/index.d.ts +76 -0
- package/dist/DateRangePicker/index.js +3 -0
- package/dist/Dialog/Dialog.torp +24 -17
- package/dist/Dialog/DialogBody.torp +5 -9
- package/dist/Dialog/DialogButton.torp +12 -12
- package/dist/Dialog/DialogFooter.torp +3 -7
- package/dist/Dialog/DialogHeader.torp +6 -10
- package/dist/Dialog/index.d.ts +27 -27
- package/dist/Dialog/index.js +6 -22
- package/dist/Disclosure/Disclosure.torp +18 -18
- package/dist/Disclosure/DisclosureContent.torp +5 -6
- package/dist/Disclosure/DisclosureHeader.torp +7 -11
- package/dist/Disclosure/DisclosureTrigger.torp +4 -5
- package/dist/Disclosure/index.d.ts +14 -16
- package/dist/Disclosure/index.js +5 -18
- package/dist/Drawer/Drawer.torp +19 -49
- package/dist/Drawer/DrawerContent.torp +67 -13
- package/dist/Drawer/DrawerOverlay.torp +4 -4
- package/dist/Drawer/DrawerTrigger.torp +16 -4
- package/dist/Drawer/DrawerTypes.ts +3 -0
- package/dist/Drawer/index.d.ts +16 -20
- package/dist/Drawer/index.js +5 -18
- package/dist/FocusGroup/FocusGroup.torp +70 -0
- package/dist/FocusGroup/FocusGroupButton.torp +59 -0
- package/dist/FocusGroup/FocusGroupTypes.ts +14 -0
- package/dist/FocusGroup/index.d.ts +44 -0
- package/dist/FocusGroup/index.js +3 -0
- package/dist/Form/CheckBox.torp +27 -18
- package/dist/Form/Field.torp +17 -17
- package/dist/Form/File.torp +31 -22
- package/dist/Form/FileDrop.torp +187 -0
- package/dist/Form/Form.torp +24 -22
- package/dist/Form/FormTypes.ts +2 -0
- package/dist/Form/FormValues.torp +37 -0
- package/dist/Form/Hidden.torp +4 -12
- package/dist/Form/Input.torp +38 -32
- package/dist/Form/Label.torp +3 -3
- package/dist/Form/Message.torp +13 -5
- package/dist/Form/MessageSummary.torp +5 -4
- package/dist/Form/Option.torp +11 -7
- package/dist/Form/Select.torp +32 -28
- package/dist/Form/TextArea.torp +35 -31
- package/dist/Form/Toggle.torp +109 -0
- package/dist/Form/index.d.ts +178 -79
- package/dist/Form/index.js +16 -50
- package/dist/ListBox/ListBox.torp +253 -150
- package/dist/ListBox/ListBoxItem.torp +54 -30
- package/dist/ListBox/ListBoxSeparator.torp +5 -2
- package/dist/ListBox/ListBoxTypes.ts +23 -5
- package/dist/ListBox/LoadedListBoxItems.torp +41 -0
- package/dist/ListBox/index.d.ts +56 -17
- package/dist/ListBox/index.js +4 -14
- package/dist/MaskedInput/MaskedInput.torp +143 -0
- package/dist/MaskedInput/index.d.ts +52 -0
- package/dist/MaskedInput/index.js +2 -0
- package/dist/Menu/Menu.torp +86 -71
- package/dist/Menu/MenuButton.torp +17 -10
- package/dist/Menu/MenuCheck.torp +22 -18
- package/dist/Menu/MenuGroup.torp +4 -4
- package/dist/Menu/MenuIndicator.torp +5 -13
- package/dist/Menu/MenuPopout.torp +20 -50
- package/dist/Menu/MenuPopoutContent.torp +15 -66
- package/dist/Menu/MenuPopoutTrigger.torp +19 -100
- package/dist/Menu/MenuRadio.torp +25 -26
- package/dist/Menu/MenuRadioGroup.torp +25 -68
- package/dist/Menu/MenuSeparator.torp +3 -2
- package/dist/Menu/MenuTypes.ts +9 -19
- package/dist/Menu/index.d.ts +45 -51
- package/dist/Menu/index.js +12 -46
- package/dist/MenuBar/MenuBar.torp +31 -83
- package/dist/MenuBar/MenuBarItem.torp +33 -51
- package/dist/MenuBar/MenuBarItemContent.torp +15 -101
- package/dist/MenuBar/MenuBarItemTrigger.torp +20 -55
- package/dist/MenuBar/MenuBarTypes.ts +11 -10
- package/dist/MenuBar/index.d.ts +17 -19
- package/dist/MenuBar/index.js +5 -18
- package/dist/Modal/Modal.torp +22 -47
- package/dist/Modal/ModalContent.torp +21 -44
- package/dist/Modal/ModalOverlay.torp +4 -4
- package/dist/Modal/ModalTrigger.torp +16 -32
- package/dist/Modal/ModalTypes.ts +5 -16
- package/dist/Modal/index.d.ts +17 -29
- package/dist/Modal/index.js +29 -28
- package/dist/Modal/index.js.map +1 -1
- package/dist/Modal/showPrompt.ts +2 -2
- package/dist/NavMenu/NavMenu.torp +22 -111
- package/dist/NavMenu/NavMenuButton.torp +7 -8
- package/dist/NavMenu/NavMenuElement.torp +6 -7
- package/dist/NavMenu/NavMenuGroup.torp +5 -5
- package/dist/NavMenu/NavMenuGroupHeader.torp +5 -8
- package/dist/NavMenu/NavMenuLink.torp +7 -10
- package/dist/NavMenu/NavMenuPopout.torp +15 -60
- package/dist/NavMenu/NavMenuPopoutContent.torp +14 -73
- package/dist/NavMenu/NavMenuPopoutTrigger.torp +17 -99
- package/dist/NavMenu/NavMenuSeparator.torp +3 -7
- package/dist/NavMenu/NavMenuTypes.ts +4 -14
- package/dist/NavMenu/index.d.ts +40 -44
- package/dist/NavMenu/index.js +11 -42
- package/dist/Notification/Notification.torp +12 -24
- package/dist/Notification/NotificationClose.torp +6 -3
- package/dist/Notification/NotificationContainer.torp +3 -7
- package/dist/Notification/NotificationContent.torp +3 -7
- package/dist/Notification/NotificationTypes.ts +1 -1
- package/dist/Notification/index.d.ts +15 -12
- package/dist/Notification/index.js +22 -32
- package/dist/Notification/index.js.map +1 -1
- package/dist/NumberInput/NumberInput.torp +255 -0
- package/dist/NumberInput/index.d.ts +44 -0
- package/dist/NumberInput/index.js +2 -0
- package/dist/Pagination/Pagination.torp +41 -34
- package/dist/Pagination/PaginationItem.torp +50 -13
- package/dist/Pagination/PaginationTypes.ts +3 -6
- package/dist/Pagination/buildPages.ts +9 -5
- package/dist/Pagination/index.d.ts +19 -9
- package/dist/Pagination/index.js +3 -40
- package/dist/Popover/Popover.torp +32 -50
- package/dist/Popover/PopoverContent.torp +27 -76
- package/dist/Popover/PopoverHover.torp +90 -0
- package/dist/Popover/PopoverTrigger.torp +17 -40
- package/dist/Popover/PopoverTypes.ts +4 -17
- package/dist/Popover/index.d.ts +40 -25
- package/dist/Popover/index.js +18 -18
- package/dist/Popover/index.js.map +1 -1
- package/dist/Progress/Progress.torp +88 -0
- package/dist/Progress/index.d.ts +37 -0
- package/dist/Progress/index.js +2 -0
- package/dist/Rating/Rating.torp +225 -0
- package/dist/Rating/index.d.ts +44 -0
- package/dist/Rating/index.js +2 -0
- package/dist/SegmentedControl/SegmentedControl.torp +233 -0
- package/dist/SegmentedControl/SegmentedControlTypes.ts +26 -0
- package/dist/SegmentedControl/SegmentedItem.torp +78 -0
- package/dist/SegmentedControl/index.d.ts +74 -0
- package/dist/SegmentedControl/index.js +3 -0
- package/dist/SelectBox/SelectBox.torp +107 -53
- package/dist/SelectBox/SelectBoxContent.torp +45 -19
- package/dist/SelectBox/SelectBoxTrigger.torp +108 -8
- package/dist/SelectBox/SelectBoxTypes.ts +26 -11
- package/dist/SelectBox/index.d.ts +39 -54
- package/dist/SelectBox/index.js +5 -18
- package/dist/Slider/Slider.torp +248 -0
- package/dist/Slider/index.d.ts +45 -0
- package/dist/Slider/index.js +2 -0
- package/dist/Splitter/Splitter.torp +156 -0
- package/dist/Splitter/SplitterHandle.torp +161 -0
- package/dist/Splitter/SplitterPane.torp +63 -0
- package/dist/Splitter/SplitterTypes.ts +31 -0
- package/dist/Splitter/index.d.ts +103 -0
- package/dist/Splitter/index.js +4 -0
- package/dist/Stepper/Stepper.torp +146 -0
- package/dist/Stepper/StepperMarker.torp +24 -0
- package/dist/Stepper/StepperNext.torp +44 -0
- package/dist/Stepper/StepperPrevious.torp +44 -0
- package/dist/Stepper/StepperStep.torp +90 -0
- package/dist/Stepper/StepperTypes.ts +30 -0
- package/dist/Stepper/index.d.ts +149 -0
- package/dist/Stepper/index.js +6 -0
- package/dist/TabGroup/TabContent.torp +6 -6
- package/dist/TabGroup/TabGroup.torp +97 -113
- package/dist/TabGroup/TabGroupTypes.ts +1 -1
- package/dist/TabGroup/TabHeader.torp +23 -19
- package/dist/TabGroup/TabList.torp +8 -21
- package/dist/TabGroup/TabTrigger.torp +6 -7
- package/dist/TabGroup/index.d.ts +26 -26
- package/dist/TabGroup/index.js +6 -22
- package/dist/TagInput/TagInput.torp +378 -0
- package/dist/TagInput/index.d.ts +48 -0
- package/dist/TagInput/index.js +2 -0
- package/dist/TimePicker/TimePicker.torp +462 -0
- package/dist/TimePicker/index.d.ts +53 -0
- package/dist/TimePicker/index.js +2 -0
- package/dist/ToolBar/ToolBar.torp +29 -110
- package/dist/ToolBar/ToolBarButton.torp +7 -8
- package/dist/ToolBar/ToolBarElement.torp +7 -11
- package/dist/ToolBar/ToolBarPopout.torp +16 -68
- package/dist/ToolBar/ToolBarPopoutContent.torp +15 -73
- package/dist/ToolBar/ToolBarPopoutTrigger.torp +19 -110
- package/dist/ToolBar/ToolBarSeparator.torp +3 -7
- package/dist/ToolBar/ToolBarTypes.ts +7 -14
- package/dist/ToolBar/index.d.ts +30 -32
- package/dist/ToolBar/index.js +8 -30
- package/dist/Tree/Tree.torp +395 -0
- package/dist/Tree/TreeItem.torp +176 -0
- package/dist/Tree/TreeItemChildren.torp +60 -0
- package/dist/Tree/TreeItemContent.torp +46 -0
- package/dist/Tree/TreeItemLabel.torp +94 -0
- package/dist/Tree/TreeItemTrigger.torp +78 -0
- package/dist/Tree/TreeLoadedChildren.torp +122 -0
- package/dist/Tree/TreeTypes.ts +63 -0
- package/dist/Tree/index.d.ts +262 -0
- package/dist/Tree/index.js +7 -0
- package/dist/icons/ChevronDoubleLeft.torp +19 -0
- package/dist/icons/ChevronDoubleRight.torp +19 -0
- package/dist/icons/index.d.ts +61 -1
- package/dist/icons/index.js +17 -58
- package/dist/loader-DEeG5vFY.js +44 -0
- package/dist/loader-DEeG5vFY.js.map +1 -0
- package/dist/motion/index.d.ts +12 -8
- package/dist/motion/index.d.ts.map +1 -0
- package/dist/motion/index.js +72 -88
- package/dist/motion/index.js.map +1 -1
- package/dist/mount/draggable.ts +63 -0
- package/dist/mount/dropTarget.ts +108 -0
- package/dist/mount/hoverTrigger.ts +1 -1
- package/dist/utils/$handle.ts +23 -0
- package/dist/utils/LoadedItems.torp +47 -0
- package/dist/utils/PopoutClickTrigger.torp +99 -0
- package/dist/utils/PopoutTypes.ts +59 -12
- package/dist/utils/SubmenuPopout.torp +89 -0
- package/dist/utils/SubmenuPopoutContent.torp +87 -0
- package/dist/utils/SubmenuPopoutTrigger.torp +160 -0
- package/dist/utils/chartColors.ts +13 -13
- package/dist/utils/chartLayout.ts +143 -0
- package/dist/utils/colorUtils.ts +103 -0
- package/dist/utils/createItemGroup.ts +152 -0
- package/dist/utils/dateUtils.ts +8 -7
- package/dist/utils/documentEvents.ts +4 -4
- package/dist/utils/dragState.ts +86 -0
- package/dist/utils/focusGroup.ts +204 -0
- package/dist/utils/focusItem.ts +44 -0
- package/dist/utils/formField.ts +70 -0
- package/dist/utils/hoverOpen.ts +50 -0
- package/dist/utils/hoverReveal.ts +194 -0
- package/dist/utils/loader.ts +113 -0
- package/dist/utils/maskUtils.ts +98 -0
- package/dist/utils/popoutContent.ts +137 -0
- package/dist/utils/reorderList.ts +52 -0
- package/package.json +97 -22
- package/dist/Accordion/index.js.map +0 -1
- package/dist/Breadcrumb/index.js.map +0 -1
- package/dist/Calendar/index.js.map +0 -1
- package/dist/Charts/index.js.map +0 -1
- package/dist/Contextual/index.js.map +0 -1
- package/dist/Dialog/index.js.map +0 -1
- package/dist/Disclosure/index.js.map +0 -1
- package/dist/Drawer/index.js.map +0 -1
- package/dist/Form/index.js.map +0 -1
- package/dist/ListBox/index.js.map +0 -1
- package/dist/Menu/index.js.map +0 -1
- package/dist/MenuBar/index.js.map +0 -1
- package/dist/NavMenu/index.js.map +0 -1
- package/dist/Pagination/index.js.map +0 -1
- package/dist/SelectBox/SelectBoxInput.torp +0 -95
- package/dist/SelectBox/index.js.map +0 -1
- package/dist/TabGroup/index.js.map +0 -1
- package/dist/ToolBar/index.js.map +0 -1
- package/dist/icons/index.js.map +0 -1
- package/dist/index.d.ts +0 -19
- package/dist/metafile-esm.json +0 -1
- package/dist/motion/fade.ts +0 -16
- package/dist/motion/grow.ts +0 -23
- package/dist/motion/measure.ts +0 -28
- package/dist/motion/slide.ts +0 -45
- package/dist/mount/index.d.ts +0 -2
- package/dist/utils/index.d.ts +0 -2
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import type { ClassValue, StyleValue } from "@torpor/view";
|
|
2
|
+
import { type SegmentedControlContext, SegmentedControlContextName } from "./SegmentedControlTypes";
|
|
3
|
+
|
|
4
|
+
interface SegmentedItemProps {
|
|
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 index of this item */
|
|
12
|
+
index?: number;
|
|
13
|
+
/** The value for this item */
|
|
14
|
+
value?: string;
|
|
15
|
+
/** If set to true, the user cannot interact with this item */
|
|
16
|
+
disabled?: boolean;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* A segment in a SegmentedControl, one of which is always active.
|
|
21
|
+
*/
|
|
22
|
+
export default function SegmentedItem($props: SegmentedItemProps | undefined) {
|
|
23
|
+
let button: HTMLButtonElement;
|
|
24
|
+
|
|
25
|
+
// Get stuff out of the SegmentedControl context
|
|
26
|
+
const context = $context[SegmentedControlContextName] as SegmentedControlContext;
|
|
27
|
+
if (!context) {
|
|
28
|
+
throw new Error("SegmentedItem must be contained within a SegmentedControl");
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
// Register this item with the parent SegmentedControl
|
|
32
|
+
let $state = context.registerItem($props?.index, $props?.value, $props?.disabled);
|
|
33
|
+
|
|
34
|
+
$run(() => {
|
|
35
|
+
return () => {
|
|
36
|
+
context.removeItem($state.index);
|
|
37
|
+
};
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
// This function is called by the parent SegmentedControl to focus this item
|
|
41
|
+
function setFocused() {
|
|
42
|
+
button.focus();
|
|
43
|
+
}
|
|
44
|
+
$state.setFocused = setFocused;
|
|
45
|
+
|
|
46
|
+
function getDisabled(): boolean {
|
|
47
|
+
return $state.disabled || $state.parentDisabled;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
function handleClick() {
|
|
51
|
+
if (getDisabled()) return;
|
|
52
|
+
context.triggerItem($state.value);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
function handleKey(e: KeyboardEvent) {
|
|
56
|
+
if (getDisabled()) return;
|
|
57
|
+
context.handleItemKey($state.index, e);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
@render {
|
|
61
|
+
<button
|
|
62
|
+
type="button"
|
|
63
|
+
{$props?.id}
|
|
64
|
+
class={["torp-segmented-item", $props?.class]}
|
|
65
|
+
{$props?.style}
|
|
66
|
+
role="radio"
|
|
67
|
+
tabindex={$state.active ? 0 : -1}
|
|
68
|
+
aria-checked={$state.active ? "true" : "false"}
|
|
69
|
+
aria-disabled={getDisabled() ? "true" : undefined}
|
|
70
|
+
data-state={$state.active ? "active" : "inactive"}
|
|
71
|
+
onclick={handleClick}
|
|
72
|
+
onkeydown={handleKey}
|
|
73
|
+
&ref={button}
|
|
74
|
+
>
|
|
75
|
+
<slot />
|
|
76
|
+
</button>
|
|
77
|
+
}
|
|
78
|
+
}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import { type SlotRender } from "@torpor/view";
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
interface SegmentedControlProps {
|
|
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 value of the active segment */
|
|
12
|
+
value?: Bindable<string | undefined>;
|
|
13
|
+
/** If set to true, the user cannot interact with any segments */
|
|
14
|
+
disabled?: boolean;
|
|
15
|
+
/** An accessible name for the control */
|
|
16
|
+
ariaLabel?: string;
|
|
17
|
+
/** The name of the component's form data field */
|
|
18
|
+
name?: string;
|
|
19
|
+
/** Raised when the active segment has changed */
|
|
20
|
+
onchange?: (value: string) => void;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* A compact group of segments, of which exactly one is active. The user moves
|
|
25
|
+
* between segments with the arrow keys, or selects one directly.
|
|
26
|
+
*
|
|
27
|
+
* See [the WAI ARIA guidelines for Radio Groups](https://www.w3.org/WAI/ARIA/apg/patterns/radiogroup/).
|
|
28
|
+
*
|
|
29
|
+
* The structure of a SegmentedControl is:
|
|
30
|
+
*
|
|
31
|
+
* ```
|
|
32
|
+
* <SegmentedControl ariaLabel="View">
|
|
33
|
+
* <SegmentedItem value="day">Day</SegmentedItem>
|
|
34
|
+
* <SegmentedItem value="week">Week</SegmentedItem>
|
|
35
|
+
* </SegmentedControl>
|
|
36
|
+
* ```
|
|
37
|
+
*/
|
|
38
|
+
declare function SegmentedControl(
|
|
39
|
+
$parent: ParentNode,
|
|
40
|
+
$anchor: Node | null,
|
|
41
|
+
$props: SegmentedControlProps | undefined,
|
|
42
|
+
$context?: Record<PropertyKey, any>,
|
|
43
|
+
$slots?: Record<string, SlotRender>,
|
|
44
|
+
): void;
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
interface SegmentedItemProps {
|
|
49
|
+
/** An ID for the root element */
|
|
50
|
+
id?: string;
|
|
51
|
+
/** Classes for the root element */
|
|
52
|
+
class?: ClassValue;
|
|
53
|
+
/** Styles for the root element */
|
|
54
|
+
style?: StyleValue;
|
|
55
|
+
/** The index of this item */
|
|
56
|
+
index?: number;
|
|
57
|
+
/** The value for this item */
|
|
58
|
+
value?: string;
|
|
59
|
+
/** If set to true, the user cannot interact with this item */
|
|
60
|
+
disabled?: boolean;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* A segment in a SegmentedControl, one of which is always active.
|
|
65
|
+
*/
|
|
66
|
+
declare function SegmentedItem(
|
|
67
|
+
$parent: ParentNode,
|
|
68
|
+
$anchor: Node | null,
|
|
69
|
+
$props: SegmentedItemProps | undefined,
|
|
70
|
+
$context?: Record<PropertyKey, any>,
|
|
71
|
+
$slots?: Record<string, SlotRender>,
|
|
72
|
+
): void;
|
|
73
|
+
|
|
74
|
+
export { SegmentedControl, SegmentedItem };
|
|
@@ -1,26 +1,54 @@
|
|
|
1
|
-
import type { ClassValue, StyleValue } from "@torpor/view";
|
|
2
|
-
import
|
|
3
|
-
import {
|
|
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";
|
|
4
14
|
|
|
5
15
|
interface SelectBoxProps {
|
|
6
16
|
/** An ID for the root element */
|
|
7
17
|
id?: string;
|
|
8
18
|
/** Classes for the root element */
|
|
9
|
-
class?: ClassValue
|
|
19
|
+
class?: ClassValue;
|
|
10
20
|
/** Styles for the root element */
|
|
11
|
-
style?: StyleValue
|
|
12
|
-
/** The
|
|
13
|
-
|
|
14
|
-
/**
|
|
15
|
-
|
|
16
|
-
/**
|
|
17
|
-
|
|
18
|
-
/**
|
|
19
|
-
|
|
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;
|
|
20
48
|
/** Raised when the popout has opened */
|
|
21
|
-
onopen?: () => void
|
|
49
|
+
onopen?: () => void;
|
|
22
50
|
/** Raised when the popout has closed */
|
|
23
|
-
onclose?: (result: any) => void
|
|
51
|
+
onclose?: (result: any) => void;
|
|
24
52
|
}
|
|
25
53
|
|
|
26
54
|
/**
|
|
@@ -32,28 +60,42 @@ interface SelectBoxProps {
|
|
|
32
60
|
*
|
|
33
61
|
* ```
|
|
34
62
|
* <SelectBox>
|
|
35
|
-
* <
|
|
36
|
-
* <SelectBoxTrigger /> (optional)
|
|
63
|
+
* <SelectBoxTrigger />
|
|
37
64
|
* <SelectBoxContent />
|
|
38
65
|
* </SelectBox>
|
|
39
66
|
* ```
|
|
40
67
|
*/
|
|
41
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
|
+
|
|
42
76
|
let $state: SelectBoxState = $watch({
|
|
43
77
|
visible: false,
|
|
44
78
|
value: $props?.value,
|
|
79
|
+
contentId: undefined,
|
|
80
|
+
triggerId: undefined,
|
|
81
|
+
contentRole: undefined,
|
|
45
82
|
});
|
|
46
83
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
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;
|
|
57
99
|
|
|
58
100
|
let result: any;
|
|
59
101
|
|
|
@@ -61,7 +103,20 @@ export default function SelectBox($props: SelectBoxProps | undefined) {
|
|
|
61
103
|
let context: SelectBoxContext = {
|
|
62
104
|
handleButton,
|
|
63
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(),
|
|
64
116
|
state: $state,
|
|
117
|
+
getLoadedItems: $load ? () => $load.items : undefined,
|
|
118
|
+
getItemLabel: $props?.getItemLabel,
|
|
119
|
+
getItemValue: $props?.getItemValue,
|
|
65
120
|
};
|
|
66
121
|
$context[SelectBoxContextName] = context;
|
|
67
122
|
|
|
@@ -69,22 +124,23 @@ export default function SelectBox($props: SelectBoxProps | undefined) {
|
|
|
69
124
|
let popoutContext: PopoutContext = context;
|
|
70
125
|
$context[PopoutContextName] = popoutContext;
|
|
71
126
|
|
|
72
|
-
// Dispatch the
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
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) => {
|
|
78
138
|
const visible = $state.visible;
|
|
79
|
-
if (
|
|
80
|
-
|
|
139
|
+
if (first) return;
|
|
140
|
+
if (visible) {
|
|
141
|
+
$props?.onopen?.();
|
|
81
142
|
} else {
|
|
82
|
-
|
|
83
|
-
if (visible) {
|
|
84
|
-
if (onopen) onopen()
|
|
85
|
-
} else {
|
|
86
|
-
if (onclose) onclose(result);
|
|
87
|
-
}
|
|
143
|
+
$props?.onclose?.(result);
|
|
88
144
|
}
|
|
89
145
|
});
|
|
90
146
|
|
|
@@ -110,27 +166,25 @@ export default function SelectBox($props: SelectBoxProps | undefined) {
|
|
|
110
166
|
$state.value = result;
|
|
111
167
|
}
|
|
112
168
|
|
|
113
|
-
// Hide the popout
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
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
|
+
}
|
|
119
175
|
}
|
|
120
176
|
}
|
|
121
177
|
|
|
122
|
-
function handleClickOutside(e: MouseEvent) {
|
|
178
|
+
function handleClickOutside(e: MouseEvent | KeyboardEvent) {
|
|
123
179
|
e.preventDefault();
|
|
124
180
|
$state.visible = false;
|
|
125
181
|
}
|
|
126
182
|
|
|
127
183
|
@render {
|
|
128
|
-
<div
|
|
129
|
-
{$props?.id}
|
|
130
|
-
class={["torp-select-box", $props?.class]}
|
|
131
|
-
{$props?.style}
|
|
132
|
-
>
|
|
184
|
+
<div {$props?.id} class={["torp-select-box", $props?.class]} {$props?.style}>
|
|
133
185
|
<slot />
|
|
134
186
|
</div>
|
|
187
|
+
|
|
188
|
+
<FormValues name={form.name} value={$state.value} />
|
|
135
189
|
}
|
|
136
190
|
}
|
|
@@ -1,14 +1,15 @@
|
|
|
1
1
|
import type { ClassValue, StyleValue } from "@torpor/view";
|
|
2
2
|
import { addDocumentEvent, removeDocumentEvent } from "../utils/documentEvents";
|
|
3
|
-
import
|
|
3
|
+
import LoadedItems from "../utils/LoadedItems.torp";
|
|
4
|
+
import { type SelectBoxContext, SelectBoxContextName } from "./SelectBoxTypes";
|
|
4
5
|
|
|
5
6
|
interface SelectBoxContentProps {
|
|
6
7
|
/** An ID for the root element */
|
|
7
8
|
id?: string;
|
|
8
9
|
/** Classes for the root element */
|
|
9
|
-
class?: ClassValue
|
|
10
|
+
class?: ClassValue;
|
|
10
11
|
/** Styles for the root element */
|
|
11
|
-
style?: StyleValue
|
|
12
|
+
style?: StyleValue;
|
|
12
13
|
}
|
|
13
14
|
|
|
14
15
|
/**
|
|
@@ -33,7 +34,7 @@ export default function SelectBoxContent($props: SelectBoxContentProps | undefin
|
|
|
33
34
|
}
|
|
34
35
|
});
|
|
35
36
|
|
|
36
|
-
function show() {
|
|
37
|
+
function show(_: HTMLElement) {
|
|
37
38
|
shown = true;
|
|
38
39
|
|
|
39
40
|
// HACK: Because this SelectBox could be shown with a click, we need to wait for another mousedown
|
|
@@ -55,27 +56,52 @@ export default function SelectBoxContent($props: SelectBoxContentProps | undefin
|
|
|
55
56
|
}
|
|
56
57
|
|
|
57
58
|
function handleDocumentClick(e: MouseEvent) {
|
|
58
|
-
if (
|
|
59
|
-
closeOnClick &&
|
|
60
|
-
div &&
|
|
61
|
-
!div.contains(e.target as HTMLElement)
|
|
62
|
-
) {
|
|
59
|
+
if (closeOnClick && div && !div.contains(e.target as HTMLElement)) {
|
|
63
60
|
e.preventDefault();
|
|
64
61
|
context.handleClickOutside!(e);
|
|
65
62
|
}
|
|
66
63
|
}
|
|
67
64
|
|
|
65
|
+
// HACK: We need to keep the items in the document so that we can search through them
|
|
68
66
|
@render {
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
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;
|
|
79
105
|
}
|
|
80
106
|
}
|
|
81
107
|
}
|
|
@@ -1,41 +1,141 @@
|
|
|
1
1
|
import type { ClassValue, StyleValue } from "@torpor/view";
|
|
2
|
-
import
|
|
2
|
+
import getId from "../utils/getId";
|
|
3
|
+
import { type SelectBoxContext, SelectBoxContextName } from "./SelectBoxTypes";
|
|
3
4
|
|
|
4
5
|
interface SelectBoxTriggerProps {
|
|
5
6
|
/** An ID for the root element */
|
|
6
7
|
id?: string;
|
|
7
8
|
/** Classes for the root element */
|
|
8
|
-
class?: ClassValue
|
|
9
|
+
class?: ClassValue;
|
|
9
10
|
/** Styles for the root element */
|
|
10
|
-
style?: StyleValue
|
|
11
|
+
style?: StyleValue;
|
|
12
|
+
/** An ARIA label for describing the trigger to screen readers when there is no associated label element */
|
|
13
|
+
ariaLabel?: string;
|
|
11
14
|
}
|
|
12
15
|
|
|
13
16
|
/**
|
|
14
|
-
* The
|
|
17
|
+
* The input that causes a SelectBox to appear or disappear.
|
|
15
18
|
*/
|
|
16
19
|
export default function SelectBoxTrigger($props: SelectBoxTriggerProps | undefined) {
|
|
20
|
+
let defaultId = getId();
|
|
21
|
+
let button: HTMLButtonElement;
|
|
22
|
+
|
|
17
23
|
// Get stuff out of the SelectBoxContext
|
|
18
24
|
const context = $context[SelectBoxContextName] as SelectBoxContext;
|
|
19
25
|
if (!context) {
|
|
20
26
|
throw new Error("SelectBoxTrigger must be contained within a SelectBox");
|
|
21
27
|
}
|
|
22
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
|
+
}
|
|
23
45
|
|
|
24
46
|
function handleClick() {
|
|
25
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
|
+
}
|
|
26
111
|
}
|
|
27
112
|
|
|
28
113
|
@render {
|
|
29
114
|
<button
|
|
30
115
|
type="button"
|
|
31
|
-
|
|
116
|
+
role="combobox"
|
|
117
|
+
id={$props?.id ?? defaultId}
|
|
32
118
|
class={["torp-select-box-trigger", $props?.class]}
|
|
33
119
|
{$props?.style}
|
|
34
|
-
|
|
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?.()}
|
|
35
128
|
onclick={handleClick}
|
|
36
|
-
|
|
129
|
+
onkeydown={handleKey}
|
|
130
|
+
&ref={button}
|
|
37
131
|
>
|
|
38
|
-
<slot
|
|
132
|
+
<slot>
|
|
133
|
+
@if (displayValue()) {
|
|
134
|
+
<span>{displayValue()}</span>
|
|
135
|
+
} @else {
|
|
136
|
+
<span>{context.placeholder || "-"}</span>
|
|
137
|
+
}
|
|
138
|
+
</slot>
|
|
39
139
|
</button>
|
|
40
140
|
}
|
|
41
141
|
}
|
|
@@ -1,18 +1,33 @@
|
|
|
1
|
+
import { type PopoutContext, type PopoutState } from "../utils/PopoutTypes";
|
|
2
|
+
import { type LoadResult, type Loader } from "../utils/loader";
|
|
3
|
+
|
|
1
4
|
export const SelectBoxContextName: unique symbol = Symbol.for("torp.SelectBox");
|
|
2
5
|
|
|
3
|
-
/** The shared context for
|
|
4
|
-
export interface SelectBoxContext {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
// There may be a more elegant way to accomplish this too
|
|
8
|
-
handleClickOutside?: (e: MouseEvent) => void;
|
|
6
|
+
/** The shared context for SelectBox components */
|
|
7
|
+
export interface SelectBoxContext extends PopoutContext {
|
|
8
|
+
placeholder?: string;
|
|
9
|
+
multiple?: boolean;
|
|
9
10
|
state: SelectBoxState;
|
|
10
|
-
|
|
11
|
-
|
|
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;
|
|
12
26
|
}
|
|
13
27
|
|
|
14
|
-
export interface SelectBoxState {
|
|
15
|
-
visible: boolean;
|
|
28
|
+
export interface SelectBoxState extends PopoutState {
|
|
16
29
|
value: any;
|
|
17
|
-
|
|
30
|
+
name?: string;
|
|
18
31
|
}
|
|
32
|
+
|
|
33
|
+
export type { LoadResult, Loader };
|