@torpor/ui 0.4.0 → 1.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.
- 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 +85 -0
- package/dist/Charts/ChartYAxis.torp +107 -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 +14 -11
- package/dist/Charts/YAxis.torp +10 -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 +120 -0
- package/dist/ComboBox/ComboBoxInput.torp +161 -0
- package/dist/ComboBox/ComboBoxTrigger.torp +49 -0
- package/dist/ComboBox/ComboBoxTypes.ts +39 -0
- package/dist/ComboBox/index.d.ts +154 -0
- package/dist/ComboBox/index.js +6 -0
- package/dist/CommandPalette/CommandPalette.torp +223 -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 +315 -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 +70 -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 +49 -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 +245 -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 +70 -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
package/dist/motion/index.js
CHANGED
|
@@ -1,97 +1,79 @@
|
|
|
1
|
-
|
|
1
|
+
//#region src/motion/fade.ts
|
|
2
2
|
function fade(_el, options) {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
{
|
|
8
|
-
opacity: 1
|
|
9
|
-
}
|
|
10
|
-
];
|
|
11
|
-
return { keyframes, options };
|
|
3
|
+
return {
|
|
4
|
+
keyframes: [{ opacity: 0 }, { opacity: 1 }],
|
|
5
|
+
options
|
|
6
|
+
};
|
|
12
7
|
}
|
|
13
|
-
|
|
14
|
-
|
|
8
|
+
//#endregion
|
|
9
|
+
//#region src/motion/measure.ts
|
|
10
|
+
/**
|
|
11
|
+
* Measures an element before it is added to the DOM
|
|
12
|
+
* @param el The element to measure
|
|
13
|
+
* @param fn The function to use to get the desired measurement (e.g. el.offsetHeight)
|
|
14
|
+
*/
|
|
15
15
|
function measure(el, fn) {
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
}
|
|
30
|
-
return result;
|
|
16
|
+
let oldVisibility = el.style.visibility;
|
|
17
|
+
let oldPosition = el.style.position;
|
|
18
|
+
let oldParent = el.parentNode;
|
|
19
|
+
let oldBefore = el.nextSibling;
|
|
20
|
+
el.style.visibility = "hidden";
|
|
21
|
+
el.style.position = "absolute";
|
|
22
|
+
document.body.appendChild(el);
|
|
23
|
+
let result = fn(el);
|
|
24
|
+
el.parentNode.removeChild(el);
|
|
25
|
+
el.style.visibility = oldVisibility;
|
|
26
|
+
el.style.position = oldPosition;
|
|
27
|
+
if (oldParent !== null) oldParent.insertBefore(el, oldBefore);
|
|
28
|
+
return result;
|
|
31
29
|
}
|
|
32
|
-
|
|
33
|
-
|
|
30
|
+
//#endregion
|
|
31
|
+
//#region src/motion/grow.ts
|
|
34
32
|
function grow(el, options) {
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
height: height + "px"
|
|
47
|
-
}
|
|
48
|
-
];
|
|
49
|
-
return { keyframes, options };
|
|
33
|
+
return {
|
|
34
|
+
keyframes: [{
|
|
35
|
+
height: "0px",
|
|
36
|
+
overflow: "hidden",
|
|
37
|
+
paddingTop: "0px",
|
|
38
|
+
paddingBottom: "0px",
|
|
39
|
+
marginTop: "0px",
|
|
40
|
+
marginBottom: "0px"
|
|
41
|
+
}, { height: measure(el, (el) => el.clientHeight) + "px" }],
|
|
42
|
+
options
|
|
43
|
+
};
|
|
50
44
|
}
|
|
51
|
-
|
|
52
|
-
|
|
45
|
+
//#endregion
|
|
46
|
+
//#region src/motion/slide.ts
|
|
53
47
|
function slide(el, options) {
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
el.style.bottom = "0px";
|
|
82
|
-
const height = measure(el, (el2) => el2.offsetHeight);
|
|
83
|
-
const keyframes = [
|
|
84
|
-
{ transform: `translateY(${height}px)` },
|
|
85
|
-
{ transform: "translateY(0px)" }
|
|
86
|
-
];
|
|
87
|
-
return { keyframes, options };
|
|
88
|
-
}
|
|
89
|
-
}
|
|
48
|
+
el.style.position = "fixed";
|
|
49
|
+
switch (options?.side ?? "left") {
|
|
50
|
+
case "left":
|
|
51
|
+
el.style.left = "0px";
|
|
52
|
+
return {
|
|
53
|
+
keyframes: [{ transform: `translateX(-${measure(el, (el) => el.offsetWidth)}px)` }, { transform: "translateX(0px)" }],
|
|
54
|
+
options
|
|
55
|
+
};
|
|
56
|
+
case "top":
|
|
57
|
+
el.style.top = "0px";
|
|
58
|
+
return {
|
|
59
|
+
keyframes: [{ transform: `translateY(-${measure(el, (el) => el.offsetHeight)}px)` }, { transform: "translateY(0px)" }],
|
|
60
|
+
options
|
|
61
|
+
};
|
|
62
|
+
case "right":
|
|
63
|
+
el.style.right = "0px";
|
|
64
|
+
return {
|
|
65
|
+
keyframes: [{ transform: `translateX(${measure(el, (el) => el.offsetWidth)}px)` }, { transform: "translateX(0px)" }],
|
|
66
|
+
options
|
|
67
|
+
};
|
|
68
|
+
case "bottom":
|
|
69
|
+
el.style.bottom = "0px";
|
|
70
|
+
return {
|
|
71
|
+
keyframes: [{ transform: `translateY(${measure(el, (el) => el.offsetHeight)}px)` }, { transform: "translateY(0px)" }],
|
|
72
|
+
options
|
|
73
|
+
};
|
|
74
|
+
}
|
|
90
75
|
}
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
measure,
|
|
95
|
-
slide
|
|
96
|
-
};
|
|
76
|
+
//#endregion
|
|
77
|
+
export { fade, grow, measure, slide };
|
|
78
|
+
|
|
97
79
|
//# sourceMappingURL=index.js.map
|
package/dist/motion/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/motion/fade.ts","../../src/motion/measure.ts","../../src/motion/grow.ts","../../src/motion/slide.ts"],"sourcesContent":["import { type Animation } from \"@torpor/view\";\n\nexport default function fade(\n\t_el: HTMLElement,\n\toptions?: number | KeyframeAnimationOptions,\n): Animation {\n\tconst keyframes = [\n\t\t{\n\t\t\topacity: 0,\n\t\t},\n\t\t{\n\t\t\topacity: 1,\n\t\t},\n\t];\n\treturn { keyframes, options };\n}\n","/**\n * Measures an element before it is added to the DOM\n * @param el The element to measure\n * @param fn The function to use to get the desired measurement (e.g. el.offsetHeight)\n */\nexport default function measure(el: HTMLElement, fn: (
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../../src/motion/fade.ts","../../src/motion/measure.ts","../../src/motion/grow.ts","../../src/motion/slide.ts"],"sourcesContent":["import { type Animation } from \"@torpor/view\";\n\nexport default function fade(\n\t_el: HTMLElement,\n\toptions?: number | KeyframeAnimationOptions,\n): Animation {\n\tconst keyframes = [\n\t\t{\n\t\t\topacity: 0,\n\t\t},\n\t\t{\n\t\t\topacity: 1,\n\t\t},\n\t];\n\treturn { keyframes, options };\n}\n","/**\n * Measures an element before it is added to the DOM\n * @param el The element to measure\n * @param fn The function to use to get the desired measurement (e.g. el.offsetHeight)\n */\nexport default function measure(el: HTMLElement, fn: (_el: HTMLElement) => number): number {\n\t// From https://stackoverflow.com/a/46707458\n\tlet oldVisibility = el.style.visibility;\n\tlet oldPosition = el.style.position;\n\n\tlet oldParent = el.parentNode;\n\tlet oldBefore = el.nextSibling;\n\n\tel.style.visibility = \"hidden\";\n\tel.style.position = \"absolute\";\n\n\tdocument.body.appendChild(el);\n\tlet result = fn(el);\n\tel.parentNode!.removeChild(el);\n\n\t// Restore the styles unconditionally: transition functions call this with\n\t// a newly created element that isn't attached yet (oldParent is null), and\n\t// leaving the measuring styles on it would render it invisible\n\tel.style.visibility = oldVisibility;\n\tel.style.position = oldPosition;\n\n\tif (oldParent !== null) {\n\t\toldParent.insertBefore(el, oldBefore);\n\t}\n\n\treturn result;\n}\n","import { type Animation } from \"@torpor/view\";\nimport measure from \"./measure\";\n\nexport default function grow(\n\tel: HTMLElement,\n\toptions?: number | KeyframeAnimationOptions,\n): Animation {\n\tconst height = measure(el, (el) => el.clientHeight);\n\tconst keyframes = [\n\t\t{\n\t\t\theight: \"0px\",\n\t\t\toverflow: \"hidden\",\n\t\t\tpaddingTop: \"0px\",\n\t\t\tpaddingBottom: \"0px\",\n\t\t\tmarginTop: \"0px\",\n\t\t\tmarginBottom: \"0px\",\n\t\t},\n\t\t{\n\t\t\theight: height + \"px\",\n\t\t},\n\t];\n\treturn { keyframes, options };\n}\n","import { type Animation } from \"@torpor/view\";\nimport measure from \"./measure\";\n\ninterface Options extends KeyframeAnimationOptions {\n\tside: \"left\" | \"right\" | \"top\" | \"bottom\";\n}\n\nexport default function slide(el: HTMLElement, options?: Options): Animation {\n\tel.style.position = \"fixed\";\n\tswitch (options?.side ?? \"left\") {\n\t\tcase \"left\": {\n\t\t\tel.style.left = \"0px\";\n\t\t\tconst width = measure(el, (el) => el.offsetWidth);\n\t\t\tconst keyframes = [\n\t\t\t\t{ transform: `translateX(-${width}px)` },\n\t\t\t\t{ transform: \"translateX(0px)\" },\n\t\t\t];\n\t\t\treturn { keyframes, options };\n\t\t}\n\t\tcase \"top\": {\n\t\t\tel.style.top = \"0px\";\n\t\t\tconst height = measure(el, (el) => el.offsetHeight);\n\t\t\tconst keyframes = [\n\t\t\t\t{ transform: `translateY(-${height}px)` },\n\t\t\t\t{ transform: \"translateY(0px)\" },\n\t\t\t];\n\t\t\treturn { keyframes, options };\n\t\t}\n\t\tcase \"right\": {\n\t\t\tel.style.right = \"0px\";\n\t\t\tconst width = measure(el, (el) => el.offsetWidth);\n\t\t\tconst keyframes = [{ transform: `translateX(${width}px)` }, { transform: \"translateX(0px)\" }];\n\t\t\treturn { keyframes, options };\n\t\t}\n\t\tcase \"bottom\": {\n\t\t\tel.style.bottom = \"0px\";\n\t\t\tconst height = measure(el, (el) => el.offsetHeight);\n\t\t\tconst keyframes = [\n\t\t\t\t{ transform: `translateY(${height}px)` },\n\t\t\t\t{ transform: \"translateY(0px)\" },\n\t\t\t];\n\t\t\treturn { keyframes, options };\n\t\t}\n\t}\n}\n"],"mappings":";AAEA,SAAwB,KACvB,KACA,SACY;CASZ,OAAO;EAAE,WAAA,CAPR,EACC,SAAS,EACV,GACA,EACC,SAAS,EACV,CAEgB;EAAG;CAAQ;AAC7B;;;;;;;;ACVA,SAAwB,QAAQ,IAAiB,IAA0C;CAE1F,IAAI,gBAAgB,GAAG,MAAM;CAC7B,IAAI,cAAc,GAAG,MAAM;CAE3B,IAAI,YAAY,GAAG;CACnB,IAAI,YAAY,GAAG;CAEnB,GAAG,MAAM,aAAa;CACtB,GAAG,MAAM,WAAW;CAEpB,SAAS,KAAK,YAAY,EAAE;CAC5B,IAAI,SAAS,GAAG,EAAE;CAClB,GAAG,WAAY,YAAY,EAAE;CAK7B,GAAG,MAAM,aAAa;CACtB,GAAG,MAAM,WAAW;CAEpB,IAAI,cAAc,MACjB,UAAU,aAAa,IAAI,SAAS;CAGrC,OAAO;AACR;;;AC5BA,SAAwB,KACvB,IACA,SACY;CAeZ,OAAO;EAAE,WAAA,CAZR;GACC,QAAQ;GACR,UAAU;GACV,YAAY;GACZ,eAAe;GACf,WAAW;GACX,cAAc;EACf,GACA,EACC,QAXa,QAAQ,KAAK,OAAO,GAAG,YAWvB,IAAI,KAClB,CAEgB;EAAG;CAAQ;AAC7B;;;ACfA,SAAwB,MAAM,IAAiB,SAA8B;CAC5E,GAAG,MAAM,WAAW;CACpB,QAAQ,SAAS,QAAQ,QAAzB;EACC,KAAK;GACJ,GAAG,MAAM,OAAO;GAMhB,OAAO;IAAE,WAAA,CAHR,EAAE,WAAW,eAFA,QAAQ,KAAK,OAAO,GAAG,WAEJ,EAAE,KAAK,GACvC,EAAE,WAAW,kBAAkB,CAEf;IAAG;GAAQ;EAE7B,KAAK;GACJ,GAAG,MAAM,MAAM;GAMf,OAAO;IAAE,WAAA,CAHR,EAAE,WAAW,eAFC,QAAQ,KAAK,OAAO,GAAG,YAEJ,EAAE,KAAK,GACxC,EAAE,WAAW,kBAAkB,CAEf;IAAG;GAAQ;EAE7B,KAAK;GACJ,GAAG,MAAM,QAAQ;GAGjB,OAAO;IAAE,WAAA,CADU,EAAE,WAAW,cADlB,QAAQ,KAAK,OAAO,GAAG,WACa,EAAE,KAAK,GAAG,EAAE,WAAW,kBAAkB,CAC1E;IAAG;GAAQ;EAE7B,KAAK;GACJ,GAAG,MAAM,SAAS;GAMlB,OAAO;IAAE,WAAA,CAHR,EAAE,WAAW,cAFC,QAAQ,KAAK,OAAO,GAAG,YAEL,EAAE,KAAK,GACvC,EAAE,WAAW,kBAAkB,CAEf;IAAG;GAAQ;CAE9B;AACD"}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { beginDrag, endDrag, writeDragType } from "../utils/dragState";
|
|
2
|
+
|
|
3
|
+
interface DraggableOptions {
|
|
4
|
+
/** High-level kind for drop targets to filter on */
|
|
5
|
+
kind?: string;
|
|
6
|
+
/** Payload handed to the drop target that receives this drag */
|
|
7
|
+
data?: any;
|
|
8
|
+
/**
|
|
9
|
+
* Called when a drag starts; returning false cancels the drag entirely
|
|
10
|
+
* (useful for drags-in-progress controls, readonly flags etc)
|
|
11
|
+
*/
|
|
12
|
+
onstart?: (e: DragEvent) => boolean | void;
|
|
13
|
+
/** Called when the drag finishes, whether it was dropped or cancelled */
|
|
14
|
+
onend?: (e: DragEvent) => void;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Makes an element draggable via the native HTML5 drag & drop API.
|
|
19
|
+
*
|
|
20
|
+
* ```
|
|
21
|
+
* <li onmount={(el) => draggable(el, { kind: "list-item", data: item })}>
|
|
22
|
+
* ```
|
|
23
|
+
*
|
|
24
|
+
* Pairs with dropTarget, which receives `{ kind, data }` for accepted
|
|
25
|
+
* drops. The tracked drag is always cleaned up on dragend, so handlers
|
|
26
|
+
* don't leak between drags.
|
|
27
|
+
*/
|
|
28
|
+
export default function draggable(node: HTMLElement, options: DraggableOptions): () => void {
|
|
29
|
+
let started = false;
|
|
30
|
+
|
|
31
|
+
function handleStart(e: DragEvent) {
|
|
32
|
+
if (options.onstart?.(e) === false) {
|
|
33
|
+
e.preventDefault();
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
const info = beginDrag(options.kind ?? "", options.data);
|
|
37
|
+
writeDragType(e, info.id);
|
|
38
|
+
if (e.dataTransfer) {
|
|
39
|
+
e.dataTransfer.effectAllowed = "move";
|
|
40
|
+
}
|
|
41
|
+
started = true;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
function handleEnd(e: DragEvent) {
|
|
45
|
+
if (started) {
|
|
46
|
+
started = false;
|
|
47
|
+
endDrag();
|
|
48
|
+
options.onend?.(e);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
node.addEventListener("dragstart", handleStart);
|
|
53
|
+
node.addEventListener("dragend", handleEnd);
|
|
54
|
+
|
|
55
|
+
return () => {
|
|
56
|
+
node.removeEventListener("dragstart", handleStart);
|
|
57
|
+
node.removeEventListener("dragend", handleEnd);
|
|
58
|
+
if (started) {
|
|
59
|
+
started = false;
|
|
60
|
+
endDrag();
|
|
61
|
+
}
|
|
62
|
+
};
|
|
63
|
+
}
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import { type DragInfo, resolveDrag } from "../utils/dragState";
|
|
2
|
+
|
|
3
|
+
interface DropTargetOptions {
|
|
4
|
+
/** Filters incoming drags; only accepted kinds receive over/drop calls */
|
|
5
|
+
accepts?: (info: DragInfo) => boolean;
|
|
6
|
+
/** The cursor effect shown while hovering (default "move") */
|
|
7
|
+
effect?: "move" | "copy" | "link";
|
|
8
|
+
/** Called continuously while an accepted drag hovers the target */
|
|
9
|
+
onover?: (info: DragInfo, e: DragEvent) => void;
|
|
10
|
+
/** Called once when hovering starts */
|
|
11
|
+
onenter?: (info: DragInfo, e: DragEvent) => void;
|
|
12
|
+
/** Called once when hovering ends */
|
|
13
|
+
onleave?: () => void;
|
|
14
|
+
/** Called when an accepted drag is dropped; returning false rejects it */
|
|
15
|
+
ondrop?: (info: DragInfo, e: DragEvent) => boolean | void;
|
|
16
|
+
/** Class applied while an accepted drag hovers the target */
|
|
17
|
+
dragClass?: string;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Turns an element into a drop target for native HTML5 drags.
|
|
22
|
+
*
|
|
23
|
+
* ```
|
|
24
|
+
* <div
|
|
25
|
+
* class="panel"
|
|
26
|
+
* onmount={(el) =>
|
|
27
|
+
* dropTarget(el, {
|
|
28
|
+
* accepts: (info) => info.kind === "list-item",
|
|
29
|
+
* dragClass: "dropping",
|
|
30
|
+
* ondrop: (info) => addItem(info.data),
|
|
31
|
+
* })
|
|
32
|
+
* }
|
|
33
|
+
* />
|
|
34
|
+
* ```
|
|
35
|
+
*
|
|
36
|
+
* Handles the tedious parts of the platform API -- preventing the browser's
|
|
37
|
+
* default navigation, resolving the tracked drag, effect negotiation --
|
|
38
|
+
* so components only express what they accept and what happens on drop.
|
|
39
|
+
*/
|
|
40
|
+
export default function dropTarget(node: HTMLElement, options: DropTargetOptions): () => void {
|
|
41
|
+
let hoverClassApplied = false;
|
|
42
|
+
|
|
43
|
+
function accepts(info: DragInfo | undefined): info is DragInfo {
|
|
44
|
+
return !!info && (!options.accepts || options.accepts(info));
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
function applyHover() {
|
|
48
|
+
if (!hoverClassApplied && options.dragClass) {
|
|
49
|
+
hoverClassApplied = true;
|
|
50
|
+
node.classList.add(options.dragClass);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
function removeHover() {
|
|
55
|
+
if (hoverClassApplied) {
|
|
56
|
+
hoverClassApplied = false;
|
|
57
|
+
node.classList.remove(options.dragClass!);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
function handleOver(e: DragEvent) {
|
|
62
|
+
const info = resolveDrag(e);
|
|
63
|
+
if (!accepts(info)) return;
|
|
64
|
+
|
|
65
|
+
e.preventDefault();
|
|
66
|
+
if (e.dataTransfer) {
|
|
67
|
+
e.dataTransfer.dropEffect = options.effect ?? "move";
|
|
68
|
+
}
|
|
69
|
+
applyHover();
|
|
70
|
+
options.onover?.(info!, e);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
function handleEnter(e: DragEvent) {
|
|
74
|
+
const info = resolveDrag(e);
|
|
75
|
+
if (!accepts(info)) return;
|
|
76
|
+
applyHover();
|
|
77
|
+
options.onenter?.(info!, e);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
function handleLeave(e: DragEvent) {
|
|
81
|
+
const related = e.relatedTarget as Node | null;
|
|
82
|
+
if (related && node.contains(related)) return;
|
|
83
|
+
removeHover();
|
|
84
|
+
options.onleave?.();
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
function handleDrop(e: DragEvent) {
|
|
88
|
+
e.preventDefault();
|
|
89
|
+
removeHover();
|
|
90
|
+
|
|
91
|
+
const info = resolveDrag(e);
|
|
92
|
+
if (!accepts(info)) return;
|
|
93
|
+
options.ondrop?.(info!, e);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
node.addEventListener("dragover", handleOver);
|
|
97
|
+
node.addEventListener("dragenter", handleEnter);
|
|
98
|
+
node.addEventListener("dragleave", handleLeave);
|
|
99
|
+
node.addEventListener("drop", handleDrop);
|
|
100
|
+
|
|
101
|
+
return () => {
|
|
102
|
+
removeHover();
|
|
103
|
+
node.removeEventListener("dragover", handleOver);
|
|
104
|
+
node.removeEventListener("dragenter", handleEnter);
|
|
105
|
+
node.removeEventListener("dragleave", handleLeave);
|
|
106
|
+
node.removeEventListener("drop", handleDrop);
|
|
107
|
+
};
|
|
108
|
+
}
|
|
@@ -10,7 +10,7 @@ export default function hoverTrigger(node: HTMLElement, options: HoverTriggerOpt
|
|
|
10
10
|
const hoverDelay = options.hoverDelay || 1000;
|
|
11
11
|
const touchDelay = options.touchDelay || 1000;
|
|
12
12
|
|
|
13
|
-
let interval:
|
|
13
|
+
let interval: ReturnType<typeof setTimeout> | undefined;
|
|
14
14
|
|
|
15
15
|
// Add click event handlers to the node
|
|
16
16
|
node.addEventListener("mouseenter", handleMouseEnter);
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { $run } from "@torpor/view";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Runs a function once on subscription and re-runs it whenever any reactive
|
|
5
|
+
* state it read changes. The callback receives a `first` flag that is `true`
|
|
6
|
+
* on the initial run and `false` on every subsequent (change-driven) run, so
|
|
7
|
+
* callers can distinguish setup from "react to a change" without maintaining
|
|
8
|
+
* their own `firstChange` flag.
|
|
9
|
+
*
|
|
10
|
+
* This is a small helper over `$run` kept in @torpor/ui for its components;
|
|
11
|
+
* library authors can copy it if they need the same pattern.
|
|
12
|
+
*
|
|
13
|
+
* @param fn The function to run, receiving a `first` flag. May return a
|
|
14
|
+
* cleanup function.
|
|
15
|
+
*/
|
|
16
|
+
export default function $handle(fn: (first: boolean) => void | (() => void)): void {
|
|
17
|
+
let firstRun = true;
|
|
18
|
+
$run(() => {
|
|
19
|
+
const first = firstRun;
|
|
20
|
+
firstRun = false;
|
|
21
|
+
return fn(first);
|
|
22
|
+
});
|
|
23
|
+
}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { ListBox, ListBoxItem } from "../ListBox/index";
|
|
2
|
+
|
|
3
|
+
interface LoadedItemsProps {
|
|
4
|
+
/** The items to render */
|
|
5
|
+
items: any[];
|
|
6
|
+
/** The selected value(s), bound through to the internal ListBox */
|
|
7
|
+
value: any;
|
|
8
|
+
/** Whether multiple items can be selected */
|
|
9
|
+
multiple?: boolean;
|
|
10
|
+
/** Extracts the display text for an item (defaults to label ?? text ?? item) */
|
|
11
|
+
getItemLabel?: (item: any) => any;
|
|
12
|
+
/** Extracts the value for an item (defaults to value ?? id) */
|
|
13
|
+
getItemValue?: (item: any) => any;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
function defaultLabel(item: any): string {
|
|
17
|
+
const label = item?.label ?? item?.text ?? item;
|
|
18
|
+
return typeof label === "string" ? label : String(label);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
function defaultValue(item: any): any {
|
|
22
|
+
return item?.value ?? item?.id;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* The internally rendered list of options for components that load their
|
|
27
|
+
* items from a network loader (ComboBox auto-complete etc). Used as the
|
|
28
|
+
* fallback content when a consumer doesn't slot their own ListBox.
|
|
29
|
+
*/
|
|
30
|
+
export default function LoadedItems($props: LoadedItemsProps) {
|
|
31
|
+
const getLabel = $props.getItemLabel ?? defaultLabel;
|
|
32
|
+
const getValue = $props.getItemValue ?? defaultValue;
|
|
33
|
+
|
|
34
|
+
@render {
|
|
35
|
+
<ListBox type={$props.multiple ? "multiple" : "single"} value={$props.value}>
|
|
36
|
+
@for (let item of $props.items) {
|
|
37
|
+
@key = getValue(item)
|
|
38
|
+
<ListBoxItem value={getValue(item)}>
|
|
39
|
+
{getLabel(item)}
|
|
40
|
+
</ListBoxItem>
|
|
41
|
+
}
|
|
42
|
+
</ListBox>
|
|
43
|
+
@if ($props.items.length === 0) {
|
|
44
|
+
<span class="torp-loaded-items-empty">No results.</span>
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
}
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
import type { ClassValue, StyleValue } from "@torpor/view";
|
|
2
|
+
import getId from "./getId";
|
|
3
|
+
import { type PopoutContext } from "./PopoutTypes";
|
|
4
|
+
|
|
5
|
+
interface PopoutClickTriggerProps {
|
|
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
|
+
/** The element to render: a button, or a div for right-click regions */
|
|
13
|
+
tag?: "button" | "div";
|
|
14
|
+
/** The event that activates the popout */
|
|
15
|
+
event?: "click" | "contextmenu";
|
|
16
|
+
/** The containing popout's context (the family-specific one, not PopoutContext) */
|
|
17
|
+
context: PopoutContext;
|
|
18
|
+
/**
|
|
19
|
+
* Called with the activating event before visibility is toggled, for
|
|
20
|
+
* triggers that track a position (right-click coordinates etc)
|
|
21
|
+
*/
|
|
22
|
+
onactivate?: (node: HTMLElement, e: MouseEvent) => void;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* The shared primitive behind PopoverTrigger, ContextualTrigger and
|
|
27
|
+
* ModalTrigger: it publishes the trigger id, renders the standard trigger
|
|
28
|
+
* attributes (aria-haspopup / aria-expanded / aria-controls), anchors the
|
|
29
|
+
* popout to itself and toggles visibility on the configured event.
|
|
30
|
+
*
|
|
31
|
+
* Hover activation deliberately lives in PopoverHover / ContextualHover,
|
|
32
|
+
* whose open/close semantics (intent delay, exit grace) differ enough from
|
|
33
|
+
* a press to warrant their own component.
|
|
34
|
+
*/
|
|
35
|
+
export default function PopoutClickTrigger($props?: PopoutClickTriggerProps) {
|
|
36
|
+
let defaultId = getId();
|
|
37
|
+
|
|
38
|
+
const context = $props!.context;
|
|
39
|
+
const $state = context.state;
|
|
40
|
+
|
|
41
|
+
// Set the trigger ID so that it can be used with aria-labelledby
|
|
42
|
+
$state.triggerId = $props?.id ?? defaultId;
|
|
43
|
+
|
|
44
|
+
const tag = $props?.tag ?? "button";
|
|
45
|
+
const event = $props?.event ?? "click";
|
|
46
|
+
|
|
47
|
+
function handleEvent(node: HTMLElement, e: MouseEvent) {
|
|
48
|
+
if (event === "contextmenu") {
|
|
49
|
+
e.preventDefault();
|
|
50
|
+
}
|
|
51
|
+
$props?.onactivate?.(node, e);
|
|
52
|
+
$state.visible = !$state.visible;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
function handleClick(e: MouseEvent) {
|
|
56
|
+
if (event !== "click") return;
|
|
57
|
+
handleEvent(e.currentTarget as HTMLElement, e);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
function handleContextMenu(e: MouseEvent) {
|
|
61
|
+
if (event !== "contextmenu") return;
|
|
62
|
+
handleEvent(e.currentTarget as HTMLElement, e);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
function handleMount(el: HTMLElement) {
|
|
66
|
+
context.anchorElement = el;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
@render {
|
|
70
|
+
@if (tag === "button") {
|
|
71
|
+
<button
|
|
72
|
+
type="button"
|
|
73
|
+
id={$props?.id ?? defaultId}
|
|
74
|
+
class={["torp-popout-trigger", $props?.class]}
|
|
75
|
+
{$props?.style}
|
|
76
|
+
aria-haspopup={$state.contentRole ?? "true"}
|
|
77
|
+
aria-expanded={$state.visible ? "true" : "false"}
|
|
78
|
+
aria-controls={$state.contentId}
|
|
79
|
+
onclick={handleClick}
|
|
80
|
+
onmount={handleMount}
|
|
81
|
+
>
|
|
82
|
+
<slot />
|
|
83
|
+
</button>
|
|
84
|
+
} else {
|
|
85
|
+
<div
|
|
86
|
+
id={$props?.id ?? defaultId}
|
|
87
|
+
class={["torp-popout-trigger", $props?.class]}
|
|
88
|
+
{$props?.style}
|
|
89
|
+
aria-haspopup={$state.contentRole ?? "true"}
|
|
90
|
+
aria-expanded={$state.visible ? "true" : "false"}
|
|
91
|
+
aria-controls={$state.contentId}
|
|
92
|
+
oncontextmenu={handleContextMenu}
|
|
93
|
+
onmount={handleMount}
|
|
94
|
+
>
|
|
95
|
+
<slot />
|
|
96
|
+
</div>
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
}
|
|
@@ -3,30 +3,77 @@ export const PopoutContextName: unique symbol = Symbol.for("torp.Popout");
|
|
|
3
3
|
// TODO: Use this type in more places
|
|
4
4
|
export type HandleButtonPress = (type: "confirm" | "cancel" | undefined, value?: any) => void;
|
|
5
5
|
|
|
6
|
+
/**
|
|
7
|
+
* The shared focus API for popout-style contexts: content can focus its
|
|
8
|
+
* first/last item after being shown.
|
|
9
|
+
*
|
|
10
|
+
* HACK: Deferring the focus call is necessary because if we focus the first
|
|
11
|
+
* element e.g. in a Dialog's onMount, it will scroll the page to the focused
|
|
12
|
+
* element and mess up our careful positioning. We need to be able to manually
|
|
13
|
+
* set the order to
|
|
14
|
+
* 1. set visible (so we have an element with content)
|
|
15
|
+
* 2. set position (so the element is in the right place)
|
|
16
|
+
* 3. set focus (for accessibility)
|
|
17
|
+
* There may be a more elegant way to accomplish this!
|
|
18
|
+
*/
|
|
19
|
+
export interface FocusApi {
|
|
20
|
+
focusFirstElement?: () => void;
|
|
21
|
+
focusLastElement?: () => void;
|
|
22
|
+
}
|
|
23
|
+
|
|
6
24
|
/** The shared context for popout components */
|
|
7
|
-
export interface PopoutContext {
|
|
25
|
+
export interface PopoutContext extends FocusApi {
|
|
8
26
|
handleButton: HandleButtonPress;
|
|
9
27
|
// HACK: We need to be able to let children (i.e. Dialogs) override the click outside functionality
|
|
10
28
|
// There may be a more elegant way to accomplish this too
|
|
11
|
-
handleClickOutside?: (e: MouseEvent) => void;
|
|
29
|
+
handleClickOutside?: (e: MouseEvent | KeyboardEvent) => void;
|
|
12
30
|
state: PopoutState;
|
|
13
31
|
//modal: boolean;
|
|
14
32
|
anchorElement?: HTMLElement;
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Called from menu content when an arrow key should move to an adjacent item
|
|
36
|
+
* in a containing MenuBar, opening its menu. Only set by MenuBarItem.
|
|
37
|
+
*/
|
|
38
|
+
navigateMenuBar?: (target: "previous" | "next") => void;
|
|
39
|
+
|
|
40
|
+
markElement?: (id: string) => void;
|
|
41
|
+
selectMarkedElement?: () => void;
|
|
42
|
+
searchText?: string;
|
|
43
|
+
searchItems?: (searchText: string) => { id: string; setFocused: () => void } | undefined;
|
|
24
44
|
}
|
|
25
45
|
|
|
26
46
|
export interface PopoutState {
|
|
27
47
|
visible: boolean;
|
|
28
|
-
//position: Point;
|
|
29
48
|
contentId?: string;
|
|
49
|
+
triggerId?: string;
|
|
50
|
+
/**
|
|
51
|
+
* The role of this popout's content ("menu", "listbox", "tree", "grid" or
|
|
52
|
+
* "dialog"), set by the content component so that triggers can use it for
|
|
53
|
+
* their aria-haspopup attribute.
|
|
54
|
+
*/
|
|
55
|
+
contentRole?: string;
|
|
56
|
+
/** Whether the popout is modal (e.g. it has an overlay) */
|
|
57
|
+
modal?: boolean;
|
|
58
|
+
/** The ID of the active descendant element, for aria-activedescendant */
|
|
59
|
+
activeDescendant?: string;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* The state that a submenu trigger registers with its containing group
|
|
64
|
+
* (Menu, MenuBar, ToolBar or NavMenu). Passed to `registerItem`; the group
|
|
65
|
+
* assigns `index`, and the trigger assigns `text` from its label on mount.
|
|
66
|
+
*/
|
|
67
|
+
export interface SubmenuItemState {
|
|
68
|
+
/** Assigned by the group on registration */
|
|
69
|
+
index?: number;
|
|
70
|
+
/** The item's label, set from its text content on mount; used for type-ahead */
|
|
71
|
+
text?: string;
|
|
72
|
+
setFocused: () => void;
|
|
73
|
+
/** Shows or hides the item's submenu */
|
|
74
|
+
setVisible?: (visible: boolean) => void;
|
|
75
|
+
/** Whether the item is disabled; disabled items are skipped by keyboard navigation */
|
|
76
|
+
disabled?: boolean;
|
|
30
77
|
}
|
|
31
78
|
|
|
32
79
|
export interface Point {
|