@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
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import type { Bindable, ClassValue, StyleValue } from "@torpor/view";
|
|
2
|
+
import $handle from "./$handle";
|
|
3
|
+
import { type PopoutContext, type PopoutState, PopoutContextName } from "./PopoutTypes";
|
|
4
|
+
|
|
5
|
+
interface SubmenuPopoutProps {
|
|
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
|
+
/** Whether the popout is visible */
|
|
13
|
+
visible: Bindable<boolean | undefined>;
|
|
14
|
+
/** Raised when the popout has opened */
|
|
15
|
+
onopen?: () => void;
|
|
16
|
+
/** Raised when the popout has closed */
|
|
17
|
+
onclose?: (result: any) => void;
|
|
18
|
+
/** The popout's state, supplied when the containing component needs access to it */
|
|
19
|
+
state?: PopoutState;
|
|
20
|
+
/** Extra values published through the popout context, e.g. handleButton */
|
|
21
|
+
context?: Partial<PopoutContext>;
|
|
22
|
+
/** Whether the popout closes when the pointer leaves it (default true) */
|
|
23
|
+
closeOnMouseLeave?: boolean;
|
|
24
|
+
/** The role of the popout's content, published so that triggers can use it for aria-haspopup */
|
|
25
|
+
contentRole?: string;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* The shared primitive behind MenuPopout, MenuBarItem, ToolBarPopout and
|
|
30
|
+
* NavMenuPopout: it owns the popout's state, publishes the popout context for
|
|
31
|
+
* its trigger and content, and raises open/close events. The component
|
|
32
|
+
* wrappers supply their group's behaviour through props.
|
|
33
|
+
*
|
|
34
|
+
* The structure of a submenu popout is:
|
|
35
|
+
*
|
|
36
|
+
* ```
|
|
37
|
+
* <XPopout>
|
|
38
|
+
* <XPopoutTrigger /> (optional)
|
|
39
|
+
* <XPopoutContent />
|
|
40
|
+
* </XPopout>
|
|
41
|
+
* ```
|
|
42
|
+
*/
|
|
43
|
+
export default function SubmenuPopout($props: SubmenuPopoutProps | undefined) {
|
|
44
|
+
let $state: PopoutState = $props?.state ?? $watch({
|
|
45
|
+
visible: false,
|
|
46
|
+
contentId: undefined,
|
|
47
|
+
triggerId: undefined,
|
|
48
|
+
contentRole: $props?.contentRole,
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
$bind($state, $props, "visible");
|
|
52
|
+
|
|
53
|
+
let result: any;
|
|
54
|
+
|
|
55
|
+
// Set the context to pass down to the trigger and content
|
|
56
|
+
let context: PopoutContext = {
|
|
57
|
+
handleButton: () => {},
|
|
58
|
+
...$props?.context,
|
|
59
|
+
state: $state,
|
|
60
|
+
};
|
|
61
|
+
$context[PopoutContextName] = context;
|
|
62
|
+
|
|
63
|
+
$handle((first) => {
|
|
64
|
+
const visible = $state.visible;
|
|
65
|
+
if (first) return;
|
|
66
|
+
if (visible) {
|
|
67
|
+
$props?.onopen?.();
|
|
68
|
+
} else {
|
|
69
|
+
$props?.onclose?.(result);
|
|
70
|
+
}
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
function handleMouseLeave() {
|
|
74
|
+
if ($props?.closeOnMouseLeave !== false) {
|
|
75
|
+
$state.visible = false;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
@render {
|
|
80
|
+
<div
|
|
81
|
+
{$props?.id}
|
|
82
|
+
class={$props?.class}
|
|
83
|
+
{$props?.style}
|
|
84
|
+
onmouseleave={handleMouseLeave}
|
|
85
|
+
>
|
|
86
|
+
<slot />
|
|
87
|
+
</div>
|
|
88
|
+
}
|
|
89
|
+
}
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import type { ClassValue, StyleValue } from "@torpor/view";
|
|
2
|
+
import getId from "./getId";
|
|
3
|
+
import { createPopoutContent } from "./popoutContent";
|
|
4
|
+
import { type PopoutContext, PopoutContextName } from "./PopoutTypes";
|
|
5
|
+
|
|
6
|
+
interface SubmenuPopoutContentProps {
|
|
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
|
+
/** Where the popout will be shown, relative to the popout button */
|
|
14
|
+
side?: "top" | "right" | "bottom" | "left";
|
|
15
|
+
/** How the popout will be aligned, relative to the popout button */
|
|
16
|
+
alignment?: "start" | "center" | "end";
|
|
17
|
+
/** Whether pressing Escape closes the popout (default true) */
|
|
18
|
+
closeOnEscape?: boolean;
|
|
19
|
+
/** Only close on Escape when the focus is inside the content */
|
|
20
|
+
escapeOnlyWhenFocused?: boolean;
|
|
21
|
+
/** The ARIA role of the content element, e.g. "menu" */
|
|
22
|
+
role?: string;
|
|
23
|
+
/**
|
|
24
|
+
* The role of the popout's content, published so that triggers can use it
|
|
25
|
+
* for aria-haspopup
|
|
26
|
+
*/
|
|
27
|
+
contentRole?: string;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* The shared primitive behind MenuPopoutContent, MenuBarItemContent,
|
|
32
|
+
* ToolBarPopoutContent and NavMenuPopoutContent: it positions the content
|
|
33
|
+
* against the trigger, handles outside clicks, Escape and focus, and renders
|
|
34
|
+
* the content when the popout is visible.
|
|
35
|
+
*/
|
|
36
|
+
export default function SubmenuPopoutContent($props: SubmenuPopoutContentProps | undefined) {
|
|
37
|
+
const defaultId = getId();
|
|
38
|
+
|
|
39
|
+
// Get stuff out of the PopoutContext
|
|
40
|
+
const popoutContext = $context[PopoutContextName] as PopoutContext;
|
|
41
|
+
if (!popoutContext) {
|
|
42
|
+
throw new Error("SubmenuPopoutContent must be contained within a SubmenuPopout");
|
|
43
|
+
}
|
|
44
|
+
let $state = popoutContext.state;
|
|
45
|
+
|
|
46
|
+
// Set the content ID so that triggers can use it with aria-controls
|
|
47
|
+
$state.contentId = $props?.id ?? defaultId;
|
|
48
|
+
|
|
49
|
+
// Set the content role so that triggers can use it with aria-haspopup
|
|
50
|
+
$state.contentRole = $props?.contentRole ?? $state.contentRole;
|
|
51
|
+
|
|
52
|
+
const popout = createPopoutContent({
|
|
53
|
+
getAnchor: () => popoutContext.anchorElement,
|
|
54
|
+
getContent: () => div,
|
|
55
|
+
close: () => ($state.visible = false),
|
|
56
|
+
side: $props?.side ?? "bottom",
|
|
57
|
+
alignment: $props?.alignment ?? "start",
|
|
58
|
+
closeOnEscape: $props?.closeOnEscape ?? true,
|
|
59
|
+
escapeOnlyWhenFocused: $props?.escapeOnlyWhenFocused,
|
|
60
|
+
focusFirstElement: () => popoutContext.focusFirstElement?.(),
|
|
61
|
+
refocusAnchorOnHide: true,
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
let div: HTMLDivElement;
|
|
65
|
+
|
|
66
|
+
$run(() => {
|
|
67
|
+
if (!$state.visible) {
|
|
68
|
+
popout.hide();
|
|
69
|
+
}
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
@render {
|
|
73
|
+
@if ($state.visible) {
|
|
74
|
+
<div
|
|
75
|
+
id={$props?.id ?? defaultId}
|
|
76
|
+
class={$props?.class}
|
|
77
|
+
{$props?.style}
|
|
78
|
+
role={$props?.role}
|
|
79
|
+
aria-labelledby={$props?.role ? $state.triggerId : undefined}
|
|
80
|
+
&ref={div}
|
|
81
|
+
onmount={(_el) => popout.show()}
|
|
82
|
+
>
|
|
83
|
+
<slot />
|
|
84
|
+
</div>
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
}
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
import type { ClassValue, StyleValue } from "@torpor/view";
|
|
2
|
+
import getId from "./getId";
|
|
3
|
+
import { createHoverOpen } from "./hoverOpen";
|
|
4
|
+
import {
|
|
5
|
+
type PopoutContext,
|
|
6
|
+
PopoutContextName,
|
|
7
|
+
type SubmenuItemState,
|
|
8
|
+
} from "./PopoutTypes";
|
|
9
|
+
|
|
10
|
+
interface SubmenuPopoutTriggerProps {
|
|
11
|
+
/** An ID for the root element */
|
|
12
|
+
id?: string;
|
|
13
|
+
/** Classes for the root element */
|
|
14
|
+
class?: ClassValue;
|
|
15
|
+
/** Styles for the root element */
|
|
16
|
+
style?: StyleValue;
|
|
17
|
+
/** The delay before showing the popout on hover, in milliseconds (default 500; 0 opens immediately) */
|
|
18
|
+
hoverDelay?: number;
|
|
19
|
+
/** Whether this button is disabled */
|
|
20
|
+
disabled?: boolean;
|
|
21
|
+
/** The ARIA role of the trigger */
|
|
22
|
+
role?: string;
|
|
23
|
+
/** The element's tabindex, if it should not take focus via tabbing */
|
|
24
|
+
tabindex?: string;
|
|
25
|
+
/** The key that opens the popout */
|
|
26
|
+
openKey?: string;
|
|
27
|
+
/** The containing group's registration function */
|
|
28
|
+
registerItem: (item: SubmenuItemState) => { index: number };
|
|
29
|
+
/** Called with the registration index, for wrappers that need it elsewhere */
|
|
30
|
+
onRegister?: (index: number) => void;
|
|
31
|
+
/** The containing group's key handler, called for keys other than openKey */
|
|
32
|
+
handleItemKey: (e: KeyboardEvent) => void;
|
|
33
|
+
/** The containing group's focus handler */
|
|
34
|
+
handleItemFocus: (index: number) => void;
|
|
35
|
+
/**
|
|
36
|
+
* Replaces how the popout is shown/hidden, which by default writes the
|
|
37
|
+
* popout's visible state; also registered with the group
|
|
38
|
+
*/
|
|
39
|
+
setVisible?: (visible: boolean) => void;
|
|
40
|
+
/**
|
|
41
|
+
* Called with the registration index when the trigger is activated by
|
|
42
|
+
* clicking or with openKey, before the popout is shown
|
|
43
|
+
*/
|
|
44
|
+
onActivate?: (index: number) => void;
|
|
45
|
+
/** Replaces the default toggle behaviour when the trigger is clicked */
|
|
46
|
+
onclick?: () => void;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* The shared primitive behind MenuPopoutTrigger, MenuBarItemTrigger,
|
|
51
|
+
* ToolBarPopoutTrigger and NavMenuPopoutTrigger: it registers itself with the
|
|
52
|
+
* containing group, opens the popout on hover, on click or with the group's
|
|
53
|
+
* open key, and renders the standard trigger attributes.
|
|
54
|
+
*/
|
|
55
|
+
export default function SubmenuPopoutTrigger($props: SubmenuPopoutTriggerProps | undefined) {
|
|
56
|
+
let defaultId = getId();
|
|
57
|
+
|
|
58
|
+
let button: HTMLButtonElement;
|
|
59
|
+
|
|
60
|
+
// Get stuff out of the PopoutContext
|
|
61
|
+
const popoutContext = $context[PopoutContextName] as PopoutContext;
|
|
62
|
+
if (!popoutContext) {
|
|
63
|
+
throw new Error("SubmenuPopoutTrigger must be contained within a SubmenuPopout");
|
|
64
|
+
}
|
|
65
|
+
const { state: $state } = popoutContext;
|
|
66
|
+
|
|
67
|
+
// Set the trigger ID so that it can be used with aria-labelledby
|
|
68
|
+
$state.triggerId = $props?.id ?? defaultId;
|
|
69
|
+
|
|
70
|
+
function setVisible(visible: boolean) {
|
|
71
|
+
if ($props?.setVisible) {
|
|
72
|
+
$props.setVisible(visible);
|
|
73
|
+
} else {
|
|
74
|
+
$state.visible = visible;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
// Register this item with the containing group and store the index
|
|
79
|
+
const item: SubmenuItemState = { setFocused, setVisible, disabled: $props?.disabled };
|
|
80
|
+
const { index } = $props!.registerItem(item);
|
|
81
|
+
$props?.onRegister?.(index);
|
|
82
|
+
|
|
83
|
+
function setFocused() {
|
|
84
|
+
button.focus();
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
// Store the anchor element, and the item's label for type-ahead
|
|
88
|
+
function handleMount(el: HTMLButtonElement) {
|
|
89
|
+
popoutContext.anchorElement = el;
|
|
90
|
+
item.text = el.textContent.trim();
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
function activate() {
|
|
94
|
+
$props?.onActivate?.(index);
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
function handleClick() {
|
|
98
|
+
if ($props?.onclick) {
|
|
99
|
+
$props.onclick();
|
|
100
|
+
return;
|
|
101
|
+
}
|
|
102
|
+
activate();
|
|
103
|
+
setVisible(!$state.visible);
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
function handleKey(e: KeyboardEvent) {
|
|
107
|
+
if (e.key === $props?.openKey) {
|
|
108
|
+
// TODO: This should be based on what side the menu shows on
|
|
109
|
+
e.preventDefault();
|
|
110
|
+
activate();
|
|
111
|
+
setVisible(true);
|
|
112
|
+
} else {
|
|
113
|
+
$props!.handleItemKey(e);
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
const hoverDelay = $props?.hoverDelay ?? 500;
|
|
118
|
+
const hoverOpen = createHoverOpen(
|
|
119
|
+
() => setVisible(true),
|
|
120
|
+
() => $props?.disabled ?? false,
|
|
121
|
+
hoverDelay,
|
|
122
|
+
);
|
|
123
|
+
|
|
124
|
+
function handleMouseEnter() {
|
|
125
|
+
// Open immediately when there is no hover delay, as menubar items do
|
|
126
|
+
if (hoverDelay <= 0) {
|
|
127
|
+
if (!$props?.disabled) {
|
|
128
|
+
setVisible(true);
|
|
129
|
+
}
|
|
130
|
+
} else {
|
|
131
|
+
hoverOpen.handleMouseEnter();
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
@render {
|
|
136
|
+
<button
|
|
137
|
+
id={$props?.id ?? defaultId}
|
|
138
|
+
class={$props?.class}
|
|
139
|
+
{$props?.style}
|
|
140
|
+
type="button"
|
|
141
|
+
{$props?.disabled}
|
|
142
|
+
role={$props?.role}
|
|
143
|
+
tabindex={$props?.tabindex}
|
|
144
|
+
aria-haspopup={$state.contentRole ?? "true"}
|
|
145
|
+
aria-expanded={$state.visible ? "true" : "false"}
|
|
146
|
+
aria-controls={$state.contentId}
|
|
147
|
+
aria-disabled={$props?.disabled ? "true" : undefined}
|
|
148
|
+
onkeydown={handleKey}
|
|
149
|
+
onclick={handleClick}
|
|
150
|
+
onfocus={() => $props!.handleItemFocus(index)}
|
|
151
|
+
onmouseenter={handleMouseEnter}
|
|
152
|
+
onmouseleave={hoverOpen.handleMouseLeave}
|
|
153
|
+
onmousemove={hoverOpen.handleMouseMove}
|
|
154
|
+
&ref={button}
|
|
155
|
+
onmount={handleMount}
|
|
156
|
+
>
|
|
157
|
+
<slot />
|
|
158
|
+
</button>
|
|
159
|
+
}
|
|
160
|
+
}
|
|
@@ -2,16 +2,16 @@
|
|
|
2
2
|
* Colors that can be used in charts, from http://colorbrewer2.org/
|
|
3
3
|
*/
|
|
4
4
|
export const chartColors = [
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
];
|
|
5
|
+
"#A6CEE3",
|
|
6
|
+
"#B2DF8A",
|
|
7
|
+
"#FB9A99",
|
|
8
|
+
"#FDBF6F",
|
|
9
|
+
"#CAB2D6",
|
|
10
|
+
"#FFFF99",
|
|
11
|
+
"#1F78B4",
|
|
12
|
+
"#33A02C",
|
|
13
|
+
"#E31A1C",
|
|
14
|
+
"#FF7F00",
|
|
15
|
+
"#6A3D9A",
|
|
16
|
+
"#B15928",
|
|
17
|
+
] as const;
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
import { $watch } from "@torpor/view";
|
|
2
|
+
import type DataSeries from "../Charts/DataSeries";
|
|
3
|
+
import {
|
|
4
|
+
calculateChartBottom,
|
|
5
|
+
calculateChartLeft,
|
|
6
|
+
calculateItemWidth,
|
|
7
|
+
calculateMaxValue,
|
|
8
|
+
calculateStepLabels,
|
|
9
|
+
calculateStepValue,
|
|
10
|
+
calculateValueHeight,
|
|
11
|
+
} from "./chartUtils";
|
|
12
|
+
|
|
13
|
+
export interface ChartLayoutOptions {
|
|
14
|
+
/** The named series to lay out */
|
|
15
|
+
series: () => DataSeries[];
|
|
16
|
+
/** Fixed height, if any (default 200 or the container's client height) */
|
|
17
|
+
height?: () => number | undefined;
|
|
18
|
+
/** Fixed width, if any (default 400 or the container's client width) */
|
|
19
|
+
width?: () => number | undefined;
|
|
20
|
+
/** Label under the x axis */
|
|
21
|
+
xLabel?: () => string | undefined;
|
|
22
|
+
/** Label beside the y axis */
|
|
23
|
+
yLabel?: () => string | undefined;
|
|
24
|
+
/** The value at the top of the chart, instead of the series' maximum */
|
|
25
|
+
maxValue?: () => number | undefined;
|
|
26
|
+
/** The number of steps between 0 and the maximum value (default 2) */
|
|
27
|
+
stepCount?: () => number | undefined;
|
|
28
|
+
/** The size of each step, instead of being calculated */
|
|
29
|
+
stepValue?: () => number | undefined;
|
|
30
|
+
/** The container element, used to measure responsive widths */
|
|
31
|
+
getContainer?: () => HTMLElement | undefined;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* The shared layout scaffold behind the cartesian charts (Bar, Column,
|
|
36
|
+
* Line): measures the chart's text so labels can be sized, and calculates
|
|
37
|
+
* the plot geometry -- maximum value, step sizes, slot widths and the
|
|
38
|
+
* left/bottom margins -- reactively from the series and axis props.
|
|
39
|
+
*
|
|
40
|
+
* Charts render only their own marks; call `measure` from `$onmount` with the
|
|
41
|
+
* hidden `<text>` element they render for that purpose.
|
|
42
|
+
*
|
|
43
|
+
* ```
|
|
44
|
+
* let $layout = createChartLayout({
|
|
45
|
+
* series: () => $props.series,
|
|
46
|
+
* getContainer: () => container,
|
|
47
|
+
* });
|
|
48
|
+
* $onmount(() => setTimeout(() => measure($layout, measurer), 1));
|
|
49
|
+
* ```
|
|
50
|
+
*/
|
|
51
|
+
export interface ChartLayout {
|
|
52
|
+
/** The width of the chart's text, measured from the measurer element */
|
|
53
|
+
textWidth: number;
|
|
54
|
+
/** The height of the chart's text (1.5x the measurer's box) */
|
|
55
|
+
textHeight: number;
|
|
56
|
+
/** The series names, rendered along the x axis */
|
|
57
|
+
readonly labels: string[];
|
|
58
|
+
readonly calculatedHeight: number;
|
|
59
|
+
readonly calculatedWidth: number;
|
|
60
|
+
/** The largest value across all series, unless overridden */
|
|
61
|
+
readonly maxValue: number;
|
|
62
|
+
/** The size of one y axis step */
|
|
63
|
+
readonly stepValue: number;
|
|
64
|
+
/** The labels for each step, 0 through max */
|
|
65
|
+
readonly stepLabels: number[];
|
|
66
|
+
/** The width of one category slot */
|
|
67
|
+
readonly itemWidth: number;
|
|
68
|
+
/** The pixel height of one unit of value */
|
|
69
|
+
readonly valueHeight: number;
|
|
70
|
+
/** The bottom edge of the plot area */
|
|
71
|
+
readonly chartBottom: number;
|
|
72
|
+
/** The left edge of the plot area */
|
|
73
|
+
readonly chartLeft: number;
|
|
74
|
+
setTextSize(width: number, height: number): void;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
export function createChartLayout(options: ChartLayoutOptions): ChartLayout {
|
|
78
|
+
const defaultHeight = 200;
|
|
79
|
+
const defaultWidth = 400;
|
|
80
|
+
const getStepCount = () => options.stepCount?.() ?? 2;
|
|
81
|
+
|
|
82
|
+
return $watch({
|
|
83
|
+
textWidth: 0,
|
|
84
|
+
textHeight: 0,
|
|
85
|
+
|
|
86
|
+
get labels() {
|
|
87
|
+
return options.series().map((s) => s.name);
|
|
88
|
+
},
|
|
89
|
+
get calculatedHeight() {
|
|
90
|
+
return options.height?.() || defaultHeight;
|
|
91
|
+
},
|
|
92
|
+
get calculatedWidth() {
|
|
93
|
+
return options.width?.() || options.getContainer?.()?.clientWidth || defaultWidth;
|
|
94
|
+
},
|
|
95
|
+
get maxValue() {
|
|
96
|
+
return options.maxValue?.() || calculateMaxValue(options.series());
|
|
97
|
+
},
|
|
98
|
+
get stepValue() {
|
|
99
|
+
return options.stepValue?.() || calculateStepValue(this.maxValue, options.stepCount?.());
|
|
100
|
+
},
|
|
101
|
+
get stepLabels() {
|
|
102
|
+
return calculateStepLabels(getStepCount(), this.stepValue);
|
|
103
|
+
},
|
|
104
|
+
get itemWidth() {
|
|
105
|
+
return calculateItemWidth(this.calculatedWidth, this.chartLeft, this.labels);
|
|
106
|
+
},
|
|
107
|
+
get valueHeight() {
|
|
108
|
+
return calculateValueHeight(
|
|
109
|
+
this.chartBottom,
|
|
110
|
+
this.textHeight,
|
|
111
|
+
this.stepValue,
|
|
112
|
+
getStepCount(),
|
|
113
|
+
);
|
|
114
|
+
},
|
|
115
|
+
get chartBottom() {
|
|
116
|
+
return calculateChartBottom(options.xLabel?.() ?? "", this.calculatedHeight, this.textHeight);
|
|
117
|
+
},
|
|
118
|
+
get chartLeft() {
|
|
119
|
+
return calculateChartLeft(
|
|
120
|
+
this.stepLabels,
|
|
121
|
+
options.yLabel?.() ?? "",
|
|
122
|
+
this.textHeight,
|
|
123
|
+
this.textWidth,
|
|
124
|
+
);
|
|
125
|
+
},
|
|
126
|
+
|
|
127
|
+
setTextSize(width: number, height: number) {
|
|
128
|
+
this.textWidth = width;
|
|
129
|
+
this.textHeight = height * 1.5;
|
|
130
|
+
},
|
|
131
|
+
});
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
/**
|
|
135
|
+
* Reads the size of a hidden measurer `<text>` element into the layout
|
|
136
|
+
* state and removes it. Call once the element is in the document (from
|
|
137
|
+
* `$onmount`, deferred a tick).
|
|
138
|
+
*/
|
|
139
|
+
export function measureChartText(layout: ChartLayout, measurer: SVGTextElement): void {
|
|
140
|
+
const bbox = measurer.getBBox();
|
|
141
|
+
layout.setTextSize(bbox.width, bbox.height);
|
|
142
|
+
measurer.remove();
|
|
143
|
+
}
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
/** Converts between color representations used by the picker components */
|
|
2
|
+
|
|
3
|
+
export interface Rgb {
|
|
4
|
+
r: number;
|
|
5
|
+
g: number;
|
|
6
|
+
b: number;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
/** Parses "#rgb", "#rrggbb" or "rrggbb"; returns undefined when invalid */
|
|
10
|
+
export function parseHex(text: string | undefined | null): string | undefined {
|
|
11
|
+
if (!text) return undefined;
|
|
12
|
+
let value = text.trim().replace(/^#/, "");
|
|
13
|
+
if (value.length === 3) {
|
|
14
|
+
value = value
|
|
15
|
+
.split("")
|
|
16
|
+
.map((c) => c + c)
|
|
17
|
+
.join("");
|
|
18
|
+
}
|
|
19
|
+
if (!/^[0-9a-fA-F]{6}$/.test(value)) return undefined;
|
|
20
|
+
return "#" + value.toLowerCase();
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export function hexToRgb(hex: string): Rgb {
|
|
24
|
+
const value = parseHex(hex) ?? "#000000";
|
|
25
|
+
return {
|
|
26
|
+
r: parseInt(value.slice(1, 3), 16),
|
|
27
|
+
g: parseInt(value.slice(3, 5), 16),
|
|
28
|
+
b: parseInt(value.slice(5, 7), 16),
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
function toHexPart(n: number): string {
|
|
33
|
+
const clamped = Math.min(255, Math.max(0, Math.round(n)));
|
|
34
|
+
return clamped.toString(16).padStart(2, "0");
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export function rgbToHex({ r, g, b }: Rgb): string {
|
|
38
|
+
return `#${toHexPart(r)}${toHexPart(g)}${toHexPart(b)}`;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/** Blends two colors; amount 0 returns a, 1 returns b */
|
|
42
|
+
export function mix(a: string, b: string, amount: number): string {
|
|
43
|
+
const ca = hexToRgb(a);
|
|
44
|
+
const cb = hexToRgb(b);
|
|
45
|
+
const t = Math.min(1, Math.max(0, amount));
|
|
46
|
+
return rgbToHex({
|
|
47
|
+
r: ca.r + (cb.r - ca.r) * t,
|
|
48
|
+
g: ca.g + (cb.g - ca.g) * t,
|
|
49
|
+
b: ca.b + (cb.b - ca.b) * t,
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/** Perceptual lightness in [0..1], for choosing readable text on swatches */
|
|
54
|
+
export function luminance(hex: string): number {
|
|
55
|
+
const { r, g, b } = hexToRgb(hex);
|
|
56
|
+
return (0.2126 * r + 0.7152 * g + 0.0722 * b) / 255;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/** A default palette, roughly ordered light to dark */
|
|
60
|
+
export const defaultPalette: string[] = [
|
|
61
|
+
"#FFFFFF",
|
|
62
|
+
"#F5F5F5",
|
|
63
|
+
"#D9D9D9",
|
|
64
|
+
"#BFBFBF",
|
|
65
|
+
"#8C8C8C",
|
|
66
|
+
"#595959",
|
|
67
|
+
"#404040",
|
|
68
|
+
"#262626",
|
|
69
|
+
"#0F0F0F",
|
|
70
|
+
"#000000",
|
|
71
|
+
"#FFE4E1",
|
|
72
|
+
"#FFC0CB",
|
|
73
|
+
"#FF7F7F",
|
|
74
|
+
"#FF4040",
|
|
75
|
+
"#E60000",
|
|
76
|
+
"#A61C00",
|
|
77
|
+
"#FFEDCC",
|
|
78
|
+
"#FFD59E",
|
|
79
|
+
"#FFAA33",
|
|
80
|
+
"#E67E00",
|
|
81
|
+
"#B35900",
|
|
82
|
+
"#FFF9C4",
|
|
83
|
+
"#FFF176",
|
|
84
|
+
"#FFEB3B",
|
|
85
|
+
"#FBC02D",
|
|
86
|
+
"#F9A825",
|
|
87
|
+
"#827717",
|
|
88
|
+
"#E8F5E9",
|
|
89
|
+
"#A5D6A7",
|
|
90
|
+
"#66BB6A",
|
|
91
|
+
"#2E7D32",
|
|
92
|
+
"#1B5E20",
|
|
93
|
+
"#0D47A1",
|
|
94
|
+
"#1565C0",
|
|
95
|
+
"#1E88E5",
|
|
96
|
+
"#42A5F5",
|
|
97
|
+
"#90CAF9",
|
|
98
|
+
"#E1BEE7",
|
|
99
|
+
"#CE93D8",
|
|
100
|
+
"#AB47BC",
|
|
101
|
+
"#8E24AA",
|
|
102
|
+
"#4A148C",
|
|
103
|
+
];
|