@torpor/ui 0.3.7 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +83 -7
- package/dist/Accordion/Accordion.torp +43 -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 +6 -6
- 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 +25 -4
- 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 +70 -0
- 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/{Chart → Charts}/GridLines.torp +7 -4
- package/dist/Charts/LineChart.torp +73 -0
- package/dist/{Chart → Charts}/PieChart.torp +14 -20
- package/dist/{Chart → Charts}/ScatterChart.torp +45 -38
- package/dist/{Chart → Charts}/SparkLine.torp +16 -19
- package/dist/{Chart → Charts}/XAxis.torp +18 -12
- package/dist/{Chart → Charts}/YAxis.torp +15 -9
- package/dist/Charts/index.d.ts +469 -0
- package/dist/Charts/index.js +17 -0
- 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 +39 -52
- 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 +5 -18
- 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 +33 -30
- package/dist/Dialog/DialogBody.torp +5 -9
- package/dist/Dialog/DialogButton.torp +14 -11
- package/dist/Dialog/DialogFooter.torp +3 -7
- package/dist/Dialog/DialogHeader.torp +6 -10
- package/dist/Dialog/DialogTypes.ts +2 -2
- package/dist/Dialog/index.d.ts +28 -26
- 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/DisclosureTypes.ts +1 -1
- package/dist/Disclosure/index.d.ts +14 -16
- package/dist/Disclosure/index.js +5 -18
- package/dist/Drawer/Drawer.torp +21 -51
- 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 +4 -1
- 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 +28 -20
- 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 +39 -0
- 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 +198 -77
- package/dist/Form/index.js +16 -46
- package/dist/ListBox/ListBox.torp +374 -0
- package/dist/ListBox/ListBoxItem.torp +131 -0
- package/dist/ListBox/ListBoxSeparator.torp +29 -0
- package/dist/ListBox/ListBoxTypes.ts +41 -0
- package/dist/ListBox/LoadedListBoxItems.torp +41 -0
- package/dist/ListBox/index.d.ts +136 -0
- package/dist/ListBox/index.js +4 -0
- 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 +90 -70
- 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 +12 -21
- 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 +34 -55
- package/dist/MenuBar/MenuBarItemContent.torp +15 -101
- package/dist/MenuBar/MenuBarItemTrigger.torp +20 -55
- package/dist/MenuBar/MenuBarTypes.ts +13 -12
- package/dist/MenuBar/index.d.ts +17 -19
- package/dist/MenuBar/index.js +5 -18
- package/dist/Modal/Modal.torp +28 -48
- 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 +6 -17
- 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 -104
- package/dist/NavMenu/NavMenuButton.torp +10 -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 +16 -61
- package/dist/NavMenu/NavMenuPopoutContent.torp +14 -73
- package/dist/NavMenu/NavMenuPopoutTrigger.torp +47 -0
- package/dist/NavMenu/NavMenuSeparator.torp +3 -6
- package/dist/NavMenu/NavMenuTypes.ts +6 -15
- package/dist/NavMenu/index.d.ts +55 -55
- 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 +152 -0
- package/dist/Pagination/PaginationItem.torp +137 -0
- package/dist/Pagination/PaginationTypes.ts +22 -0
- package/dist/Pagination/buildPages.ts +61 -0
- package/dist/Pagination/index.d.ts +63 -0
- package/dist/Pagination/index.js +3 -0
- package/dist/Popover/Popover.torp +39 -52
- 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 +5 -18
- 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 +190 -0
- package/dist/SelectBox/SelectBoxContent.torp +107 -0
- package/dist/SelectBox/SelectBoxTrigger.torp +141 -0
- package/dist/SelectBox/SelectBoxTypes.ts +33 -0
- package/dist/SelectBox/index.d.ts +112 -0
- package/dist/SelectBox/index.js +5 -0
- 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 +3 -3
- 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 +117 -0
- package/dist/ToolBar/ToolBarButton.torp +56 -0
- package/dist/ToolBar/ToolBarElement.torp +51 -0
- package/dist/ToolBar/ToolBarPopout.torp +45 -0
- package/dist/ToolBar/ToolBarPopoutContent.torp +34 -0
- package/dist/ToolBar/ToolBarPopoutTrigger.torp +47 -0
- package/dist/ToolBar/ToolBarSeparator.torp +21 -0
- package/dist/ToolBar/ToolBarTypes.ts +28 -0
- package/dist/ToolBar/index.d.ts +210 -0
- package/dist/ToolBar/index.js +8 -0
- 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 +82 -0
- 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/chartUtils.ts +1 -1
- 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 +116 -25
- 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/Chart/BarChart.torp +0 -159
- package/dist/Chart/LineChart.torp +0 -196
- package/dist/Chart/index.d.ts +0 -220
- package/dist/Chart/index.js +0 -34
- package/dist/Chart/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/Menu/index.js.map +0 -1
- package/dist/MenuBar/index.js.map +0 -1
- package/dist/NavMenu/NavMenuPopoutButton.torp +0 -129
- package/dist/NavMenu/index.js.map +0 -1
- package/dist/TabGroup/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/{Chart → Charts}/DataSeries.ts +0 -0
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Masked input plumbing: masks are strings where token characters accept
|
|
3
|
+
* user input and everything else is a literal.
|
|
4
|
+
*
|
|
5
|
+
* - `9` -- digit (0-9)
|
|
6
|
+
* - `L` -- letter (a-z, case preserved)
|
|
7
|
+
* - `a` -- alphanumeric
|
|
8
|
+
* - `\x` -- the literal character x
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
export interface MaskToken {
|
|
12
|
+
/** Literal characters render as-is; tokens accept input */
|
|
13
|
+
literal: boolean;
|
|
14
|
+
char: string;
|
|
15
|
+
pattern?: RegExp;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/** Splits a mask into literal/token parts */
|
|
19
|
+
export function parseMask(mask: string): MaskToken[] {
|
|
20
|
+
const tokens: MaskToken[] = [];
|
|
21
|
+
for (let i = 0; i < mask.length; i++) {
|
|
22
|
+
const char = mask[i];
|
|
23
|
+
if (char === "\\" && i + 1 < mask.length) {
|
|
24
|
+
tokens.push({ literal: true, char: mask[i + 1] });
|
|
25
|
+
i++;
|
|
26
|
+
continue;
|
|
27
|
+
}
|
|
28
|
+
switch (char) {
|
|
29
|
+
case "9":
|
|
30
|
+
tokens.push({ literal: false, char, pattern: /[0-9]/ });
|
|
31
|
+
break;
|
|
32
|
+
case "L":
|
|
33
|
+
tokens.push({ literal: false, char, pattern: /[A-Za-z]/ });
|
|
34
|
+
break;
|
|
35
|
+
case "a":
|
|
36
|
+
tokens.push({ literal: false, char, pattern: /[A-Za-z0-9]/ });
|
|
37
|
+
break;
|
|
38
|
+
default:
|
|
39
|
+
tokens.push({ literal: true, char });
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
return tokens;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/** The characters a mask can hold, ignoring literals */
|
|
46
|
+
export function tokenCount(tokens: MaskToken[]): number {
|
|
47
|
+
return tokens.filter((t) => !t.literal).length;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Walks user-entered text against the mask, keeping only characters that
|
|
52
|
+
* fit the remaining slots. Typing ahead of literals works because missing
|
|
53
|
+
* literals are skipped, so `5551234` formats like `(555) 123-4`.
|
|
54
|
+
*/
|
|
55
|
+
export function extractRaw(tokens: MaskToken[], text: string): string {
|
|
56
|
+
let result = "";
|
|
57
|
+
let ti = 0;
|
|
58
|
+
|
|
59
|
+
for (const ch of text) {
|
|
60
|
+
if (ti >= tokens.length) break;
|
|
61
|
+
|
|
62
|
+
// Skip forward to the first token this character satisfies
|
|
63
|
+
while (ti < tokens.length && tokens[ti].literal && tokens[ti].char !== ch) {
|
|
64
|
+
ti++;
|
|
65
|
+
}
|
|
66
|
+
const token = tokens[ti];
|
|
67
|
+
if (!token) break;
|
|
68
|
+
|
|
69
|
+
if (token.literal) {
|
|
70
|
+
// The user typed the literal itself
|
|
71
|
+
ti++;
|
|
72
|
+
continue;
|
|
73
|
+
}
|
|
74
|
+
if (!token.pattern!.test(ch)) continue;
|
|
75
|
+
|
|
76
|
+
result += ch;
|
|
77
|
+
ti++;
|
|
78
|
+
}
|
|
79
|
+
return result;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/** Builds the displayed text from raw input characters */
|
|
83
|
+
export function formatMask(tokens: MaskToken[], raw: string): string {
|
|
84
|
+
let result = "";
|
|
85
|
+
let index = 0;
|
|
86
|
+
let lastFilledEnd = 0;
|
|
87
|
+
|
|
88
|
+
for (let i = 0; i < tokens.length && index < raw.length; i++) {
|
|
89
|
+
const token = tokens[i];
|
|
90
|
+
if (token.literal) {
|
|
91
|
+
result += token.char;
|
|
92
|
+
continue;
|
|
93
|
+
}
|
|
94
|
+
result += raw[index++];
|
|
95
|
+
lastFilledEnd = result.length;
|
|
96
|
+
}
|
|
97
|
+
return result.slice(0, lastFilledEnd);
|
|
98
|
+
}
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
import { addDocumentEvent, removeDocumentEvent } from "./documentEvents";
|
|
2
|
+
import getScrollParent from "./getScrollParent";
|
|
3
|
+
import setPopoverPosition from "./setPopoverPosition";
|
|
4
|
+
|
|
5
|
+
export interface PopoutContentOptions {
|
|
6
|
+
/** Resolves the element to position the content against */
|
|
7
|
+
getAnchor: () => HTMLElement | undefined;
|
|
8
|
+
/** Resolves the content element */
|
|
9
|
+
getContent: () => HTMLElement | undefined;
|
|
10
|
+
/** Closes the popout (e.g. by setting visible to false) */
|
|
11
|
+
close: (e: MouseEvent | KeyboardEvent) => void;
|
|
12
|
+
/** Where to show the content, relative to the anchor */
|
|
13
|
+
side?: "top" | "right" | "bottom" | "left";
|
|
14
|
+
/** How to align the content, relative to the anchor */
|
|
15
|
+
alignment?: "start" | "center" | "end";
|
|
16
|
+
/** Custom positioning, as an alternative to side/alignment */
|
|
17
|
+
position?: () => void;
|
|
18
|
+
/** Whether pressing Escape closes the popout */
|
|
19
|
+
closeOnEscape?: boolean;
|
|
20
|
+
/** Only close on Escape when the focus is inside the content */
|
|
21
|
+
escapeOnlyWhenFocused?: boolean;
|
|
22
|
+
/** Ignore clicks on the anchor element when closing on outside clicks */
|
|
23
|
+
ignoreAnchorClicks?: boolean;
|
|
24
|
+
/** Called after the content is shown, to set focus for accessibility */
|
|
25
|
+
focusFirstElement?: () => void;
|
|
26
|
+
/** Focus the anchor element after hiding */
|
|
27
|
+
refocusAnchorOnHide?: boolean;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Shared show/hide machinery for popout content components: outside click
|
|
32
|
+
* handling, Escape handling, repositioning on scroll/resize and focus
|
|
33
|
+
* management.
|
|
34
|
+
*
|
|
35
|
+
* HACK: Because the popout could be shown with a click, we need to wait for
|
|
36
|
+
* another mousedown before we close on click. Otherwise the click that opened
|
|
37
|
+
* the popout immediately bubbles to the document and closes it again.
|
|
38
|
+
*/
|
|
39
|
+
export function createPopoutContent(options: PopoutContentOptions): {
|
|
40
|
+
show: () => void;
|
|
41
|
+
hide: () => void;
|
|
42
|
+
} {
|
|
43
|
+
let shown = false;
|
|
44
|
+
let closeOnClick = false;
|
|
45
|
+
|
|
46
|
+
function setPosition() {
|
|
47
|
+
const anchor = options.getAnchor();
|
|
48
|
+
const content = options.getContent();
|
|
49
|
+
if (!anchor || !content) return;
|
|
50
|
+
|
|
51
|
+
if (options.position) {
|
|
52
|
+
options.position();
|
|
53
|
+
} else {
|
|
54
|
+
setPopoverPosition(anchor, content, options.side ?? "bottom", options.alignment ?? "start");
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
function handleDocumentMouseDown() {
|
|
59
|
+
closeOnClick = true;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
function handleDocumentClick(e: MouseEvent) {
|
|
63
|
+
const content = options.getContent();
|
|
64
|
+
const anchor = options.getAnchor();
|
|
65
|
+
if (!closeOnClick || !content || content.contains(e.target as HTMLElement)) {
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
if (options.ignoreAnchorClicks && anchor?.contains(e.target as HTMLElement)) {
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
|
+
e.preventDefault();
|
|
72
|
+
options.close(e);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
function handleDocumentKeyDown(e: KeyboardEvent) {
|
|
76
|
+
if (e.key !== "Escape") return;
|
|
77
|
+
const content = options.getContent();
|
|
78
|
+
if (options.escapeOnlyWhenFocused && content && !content.contains(e.target as Node)) {
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
81
|
+
e.preventDefault();
|
|
82
|
+
options.close(e);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
function show() {
|
|
86
|
+
shown = true;
|
|
87
|
+
|
|
88
|
+
closeOnClick = false;
|
|
89
|
+
addDocumentEvent("mousedown", handleDocumentMouseDown);
|
|
90
|
+
addDocumentEvent("click", handleDocumentClick);
|
|
91
|
+
if (options.closeOnEscape) {
|
|
92
|
+
addDocumentEvent("keydown", handleDocumentKeyDown);
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
// Set the position and listen for window resize and scroll to reset the position
|
|
96
|
+
setPosition();
|
|
97
|
+
addEventListener("resize", setPosition);
|
|
98
|
+
const anchor = options.getAnchor();
|
|
99
|
+
if (anchor) {
|
|
100
|
+
getScrollParent(anchor).addEventListener("scroll", setPosition);
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
options.focusFirstElement?.();
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
function hide() {
|
|
107
|
+
if (!shown) return;
|
|
108
|
+
shown = false;
|
|
109
|
+
|
|
110
|
+
removeDocumentEvent("mousedown", handleDocumentMouseDown);
|
|
111
|
+
removeDocumentEvent("click", handleDocumentClick);
|
|
112
|
+
removeDocumentEvent("keydown", handleDocumentKeyDown);
|
|
113
|
+
removeEventListener("resize", setPosition);
|
|
114
|
+
const anchor = options.getAnchor();
|
|
115
|
+
if (anchor) {
|
|
116
|
+
getScrollParent(anchor).removeEventListener("scroll", setPosition);
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
// Focus the anchor element again, per the WAI guidelines, unless focus
|
|
120
|
+
// has already moved elsewhere (e.g. to an adjacent menubar item's menu).
|
|
121
|
+
// If the focused element was removed with the content, focus has fallen
|
|
122
|
+
// back to the body, and the anchor is focused again
|
|
123
|
+
if (options.refocusAnchorOnHide) {
|
|
124
|
+
const content = options.getContent();
|
|
125
|
+
if (
|
|
126
|
+
!content ||
|
|
127
|
+
content.contains(document.activeElement) ||
|
|
128
|
+
document.activeElement === document.body
|
|
129
|
+
) {
|
|
130
|
+
const el = options.getAnchor();
|
|
131
|
+
el?.focus?.();
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
return { show, hide };
|
|
137
|
+
}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pure helpers for reorderable collections, used by list and tree drag &
|
|
3
|
+
* drop. Geometry-free on purpose: components measure their own slots with
|
|
4
|
+
* slotIndex and combine the result with these.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
/** Moves an item to a final index; out-of-range targets are clamped */
|
|
8
|
+
export function moveItem<T>(items: T[], from: number, to: number): T[] {
|
|
9
|
+
const next = items.slice();
|
|
10
|
+
if (from < 0 || from >= next.length) return next;
|
|
11
|
+
const clamped = Math.min(next.length - 1, Math.max(0, to));
|
|
12
|
+
const [item] = next.splice(from, 1);
|
|
13
|
+
next.splice(clamped, 0, item);
|
|
14
|
+
return next;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Moves an item to sit at the slot `insertAt` occupied *before* the move --
|
|
19
|
+
* i.e. `insertAt` indexes into the original order, which is what pointer
|
|
20
|
+
* math produces (dropped before item N). Handles the index shift caused by
|
|
21
|
+
* removing the dragged element.
|
|
22
|
+
*/
|
|
23
|
+
export function moveToSlot<T>(items: T[], from: number, insertAt: number): T[] {
|
|
24
|
+
let to = insertAt;
|
|
25
|
+
if (from < insertAt) {
|
|
26
|
+
to = insertAt - 1;
|
|
27
|
+
}
|
|
28
|
+
return moveItem(items, from, to);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Finds which slot a pointer sits in along an axis: the index of the first
|
|
33
|
+
* element whose midpoint the point has passed (or elements.length when past
|
|
34
|
+
* all of them). `elements` must already be in display order.
|
|
35
|
+
*
|
|
36
|
+
* ```
|
|
37
|
+
* const insert = slotIndex([...list.children], "y", e.clientY);
|
|
38
|
+
* list.set(items => moveToSlot(items, dragFrom, insert));
|
|
39
|
+
* ```
|
|
40
|
+
*/
|
|
41
|
+
export function slotIndex(
|
|
42
|
+
elements: { getBoundingClientRect(): DOMRect }[],
|
|
43
|
+
axis: "x" | "y",
|
|
44
|
+
point: number,
|
|
45
|
+
): number {
|
|
46
|
+
for (let i = 0; i < elements.length; i++) {
|
|
47
|
+
const rect = elements[i].getBoundingClientRect();
|
|
48
|
+
const mid = axis === "x" ? rect.left + rect.width / 2 : rect.top + rect.height / 2;
|
|
49
|
+
if (point < mid) return i;
|
|
50
|
+
}
|
|
51
|
+
return elements.length;
|
|
52
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@torpor/ui",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "1.0.0",
|
|
4
4
|
"description": "Accessible, unstyled components for use in your Torpor front-end",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"exports": {
|
|
@@ -16,14 +16,42 @@
|
|
|
16
16
|
"types": "./dist/Calendar/index.d.ts",
|
|
17
17
|
"import": "./dist/Calendar/index.js"
|
|
18
18
|
},
|
|
19
|
-
"./
|
|
20
|
-
"types": "./dist/
|
|
21
|
-
"import": "./dist/
|
|
19
|
+
"./Carousel": {
|
|
20
|
+
"types": "./dist/Carousel/index.d.ts",
|
|
21
|
+
"import": "./dist/Carousel/index.js"
|
|
22
|
+
},
|
|
23
|
+
"./Charts": {
|
|
24
|
+
"types": "./dist/Charts/index.d.ts",
|
|
25
|
+
"import": "./dist/Charts/index.js"
|
|
26
|
+
},
|
|
27
|
+
"./CommandPalette": {
|
|
28
|
+
"types": "./dist/CommandPalette/index.d.ts",
|
|
29
|
+
"import": "./dist/CommandPalette/index.js"
|
|
30
|
+
},
|
|
31
|
+
"./ColorPicker": {
|
|
32
|
+
"types": "./dist/ColorPicker/index.d.ts",
|
|
33
|
+
"import": "./dist/ColorPicker/index.js"
|
|
34
|
+
},
|
|
35
|
+
"./ComboBox": {
|
|
36
|
+
"types": "./dist/ComboBox/index.d.ts",
|
|
37
|
+
"import": "./dist/ComboBox/index.js"
|
|
22
38
|
},
|
|
23
39
|
"./Contextual": {
|
|
24
40
|
"types": "./dist/Contextual/index.d.ts",
|
|
25
41
|
"import": "./dist/Contextual/index.js"
|
|
26
42
|
},
|
|
43
|
+
"./DataGrid": {
|
|
44
|
+
"types": "./dist/DataGrid/index.d.ts",
|
|
45
|
+
"import": "./dist/DataGrid/index.js"
|
|
46
|
+
},
|
|
47
|
+
"./DatePicker": {
|
|
48
|
+
"types": "./dist/DatePicker/index.d.ts",
|
|
49
|
+
"import": "./dist/DatePicker/index.js"
|
|
50
|
+
},
|
|
51
|
+
"./DateRangePicker": {
|
|
52
|
+
"types": "./dist/DateRangePicker/index.d.ts",
|
|
53
|
+
"import": "./dist/DateRangePicker/index.js"
|
|
54
|
+
},
|
|
27
55
|
"./Dialog": {
|
|
28
56
|
"types": "./dist/Dialog/index.d.ts",
|
|
29
57
|
"import": "./dist/Dialog/index.js"
|
|
@@ -36,10 +64,18 @@
|
|
|
36
64
|
"types": "./dist/Drawer/index.d.ts",
|
|
37
65
|
"import": "./dist/Drawer/index.js"
|
|
38
66
|
},
|
|
67
|
+
"./FocusGroup": {
|
|
68
|
+
"types": "./dist/FocusGroup/index.d.ts",
|
|
69
|
+
"import": "./dist/FocusGroup/index.js"
|
|
70
|
+
},
|
|
39
71
|
"./Form": {
|
|
40
72
|
"types": "./dist/Form/index.d.ts",
|
|
41
73
|
"import": "./dist/Form/index.js"
|
|
42
74
|
},
|
|
75
|
+
"./ListBox": {
|
|
76
|
+
"types": "./dist/ListBox/index.d.ts",
|
|
77
|
+
"import": "./dist/ListBox/index.js"
|
|
78
|
+
},
|
|
43
79
|
"./Menu": {
|
|
44
80
|
"types": "./dist/Menu/index.d.ts",
|
|
45
81
|
"import": "./dist/Menu/index.js"
|
|
@@ -52,22 +88,78 @@
|
|
|
52
88
|
"types": "./dist/Modal/index.d.ts",
|
|
53
89
|
"import": "./dist/Modal/index.js"
|
|
54
90
|
},
|
|
91
|
+
"./NumberInput": {
|
|
92
|
+
"types": "./dist/NumberInput/index.d.ts",
|
|
93
|
+
"import": "./dist/NumberInput/index.js"
|
|
94
|
+
},
|
|
55
95
|
"./NavMenu": {
|
|
56
96
|
"types": "./dist/NavMenu/index.d.ts",
|
|
57
97
|
"import": "./dist/NavMenu/index.js"
|
|
58
98
|
},
|
|
99
|
+
"./MaskedInput": {
|
|
100
|
+
"types": "./dist/MaskedInput/index.d.ts",
|
|
101
|
+
"import": "./dist/MaskedInput/index.js"
|
|
102
|
+
},
|
|
59
103
|
"./Notification": {
|
|
60
104
|
"types": "./dist/Notification/index.d.ts",
|
|
61
105
|
"import": "./dist/Notification/index.js"
|
|
62
106
|
},
|
|
107
|
+
"./Pagination": {
|
|
108
|
+
"types": "./dist/Pagination/index.d.ts",
|
|
109
|
+
"import": "./dist/Pagination/index.js"
|
|
110
|
+
},
|
|
111
|
+
"./Progress": {
|
|
112
|
+
"types": "./dist/Progress/index.d.ts",
|
|
113
|
+
"import": "./dist/Progress/index.js"
|
|
114
|
+
},
|
|
63
115
|
"./Popover": {
|
|
64
116
|
"types": "./dist/Popover/index.d.ts",
|
|
65
117
|
"import": "./dist/Popover/index.js"
|
|
66
118
|
},
|
|
119
|
+
"./Rating": {
|
|
120
|
+
"types": "./dist/Rating/index.d.ts",
|
|
121
|
+
"import": "./dist/Rating/index.js"
|
|
122
|
+
},
|
|
123
|
+
"./SelectBox": {
|
|
124
|
+
"types": "./dist/SelectBox/index.d.ts",
|
|
125
|
+
"import": "./dist/SelectBox/index.js"
|
|
126
|
+
},
|
|
127
|
+
"./SegmentedControl": {
|
|
128
|
+
"types": "./dist/SegmentedControl/index.d.ts",
|
|
129
|
+
"import": "./dist/SegmentedControl/index.js"
|
|
130
|
+
},
|
|
131
|
+
"./Slider": {
|
|
132
|
+
"types": "./dist/Slider/index.d.ts",
|
|
133
|
+
"import": "./dist/Slider/index.js"
|
|
134
|
+
},
|
|
135
|
+
"./Splitter": {
|
|
136
|
+
"types": "./dist/Splitter/index.d.ts",
|
|
137
|
+
"import": "./dist/Splitter/index.js"
|
|
138
|
+
},
|
|
139
|
+
"./Stepper": {
|
|
140
|
+
"types": "./dist/Stepper/index.d.ts",
|
|
141
|
+
"import": "./dist/Stepper/index.js"
|
|
142
|
+
},
|
|
67
143
|
"./TabGroup": {
|
|
68
144
|
"types": "./dist/TabGroup/index.d.ts",
|
|
69
145
|
"import": "./dist/TabGroup/index.js"
|
|
70
146
|
},
|
|
147
|
+
"./TagInput": {
|
|
148
|
+
"types": "./dist/TagInput/index.d.ts",
|
|
149
|
+
"import": "./dist/TagInput/index.js"
|
|
150
|
+
},
|
|
151
|
+
"./Tree": {
|
|
152
|
+
"types": "./dist/Tree/index.d.ts",
|
|
153
|
+
"import": "./dist/Tree/index.js"
|
|
154
|
+
},
|
|
155
|
+
"./ToolBar": {
|
|
156
|
+
"types": "./dist/ToolBar/index.d.ts",
|
|
157
|
+
"import": "./dist/ToolBar/index.js"
|
|
158
|
+
},
|
|
159
|
+
"./TimePicker": {
|
|
160
|
+
"types": "./dist/TimePicker/index.d.ts",
|
|
161
|
+
"import": "./dist/TimePicker/index.js"
|
|
162
|
+
},
|
|
71
163
|
"./icons": {
|
|
72
164
|
"types": "./dist/icons/index.d.ts",
|
|
73
165
|
"import": "./dist/icons/index.js"
|
|
@@ -87,31 +179,30 @@
|
|
|
87
179
|
"author": "",
|
|
88
180
|
"license": "ISC",
|
|
89
181
|
"dependencies": {
|
|
90
|
-
"@torpor/
|
|
91
|
-
"@torpor/
|
|
182
|
+
"@torpor/unplugin": "^1.0.0",
|
|
183
|
+
"@torpor/view": "^1.0.0"
|
|
92
184
|
},
|
|
93
185
|
"devDependencies": {
|
|
94
186
|
"@testing-library/dom": "^10.4.1",
|
|
95
|
-
"@testing-library/jest-dom": "^
|
|
96
|
-
"@testing-library/user-event": "^14.6.
|
|
97
|
-
"@
|
|
98
|
-
"@types/
|
|
99
|
-
"@
|
|
100
|
-
"
|
|
101
|
-
"
|
|
102
|
-
"
|
|
103
|
-
"
|
|
104
|
-
"
|
|
105
|
-
"
|
|
106
|
-
"
|
|
107
|
-
"
|
|
108
|
-
"
|
|
109
|
-
"zod": "^4.1.12"
|
|
187
|
+
"@testing-library/jest-dom": "^7.0.0",
|
|
188
|
+
"@testing-library/user-event": "^14.6.3",
|
|
189
|
+
"@types/jsdom": "^28.0.3",
|
|
190
|
+
"@types/node": "^26.1.2",
|
|
191
|
+
"@typescript/native-preview": "7.0.0-dev.20260707.2",
|
|
192
|
+
"chalk": "^6.0.0",
|
|
193
|
+
"jsdom": "^30.0.1",
|
|
194
|
+
"tsx": "^4.23.5",
|
|
195
|
+
"typescript": "^7.0.2",
|
|
196
|
+
"vite": "npm:@voidzero-dev/vite-plus-core@0.2.7",
|
|
197
|
+
"vite-plus": "0.2.7",
|
|
198
|
+
"zod": "^4.4.3",
|
|
199
|
+
"@torpor/prettier": "^1.0.0",
|
|
200
|
+
"@torpor/check": "^1.0.0"
|
|
110
201
|
},
|
|
111
202
|
"scripts": {
|
|
112
|
-
"build": "tsgo --noEmit &&
|
|
113
|
-
"
|
|
114
|
-
"
|
|
115
|
-
"
|
|
203
|
+
"build": "tsgo --noEmit && vp pack",
|
|
204
|
+
"check": "torp-check && pnpm dlx oxlint --type-aware",
|
|
205
|
+
"test": "vp test",
|
|
206
|
+
"format": "vp fmt ."
|
|
116
207
|
}
|
|
117
208
|
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
|
package/dist/Chart/BarChart.torp
DELETED
|
@@ -1,159 +0,0 @@
|
|
|
1
|
-
import type { ClassValue, StyleValue } from "@torpor/view";
|
|
2
|
-
import XAxis from "./XAxis.torp";
|
|
3
|
-
import YAxis from "./YAxis.torp";
|
|
4
|
-
import GridLines from "./GridLines.torp";
|
|
5
|
-
import {
|
|
6
|
-
calculateMaxValue,
|
|
7
|
-
calculateStepValue,
|
|
8
|
-
calculateStepLabels,
|
|
9
|
-
calculateItemWidth,
|
|
10
|
-
calculateValueHeight,
|
|
11
|
-
calculateChartBottom,
|
|
12
|
-
calculateChartLeft
|
|
13
|
-
} from "../utils/chartUtils";
|
|
14
|
-
import { chartColors } from "../utils/chartColors";
|
|
15
|
-
|
|
16
|
-
import type DataSeries from "./DataSeries";
|
|
17
|
-
|
|
18
|
-
interface BarChartProps {
|
|
19
|
-
/** An ID for the root element */
|
|
20
|
-
id?: string;
|
|
21
|
-
/** Classes for the root element */
|
|
22
|
-
class?: ClassValue,
|
|
23
|
-
/** Styles for the root element */
|
|
24
|
-
style?: StyleValue,
|
|
25
|
-
series: DataSeries[],
|
|
26
|
-
height?: number,
|
|
27
|
-
width?: number,
|
|
28
|
-
xLabel?: string,
|
|
29
|
-
yLabel?: string,
|
|
30
|
-
maxValue?: number,
|
|
31
|
-
stepCount?: number,
|
|
32
|
-
stepValue?: number,
|
|
33
|
-
hideXAxis?: boolean,
|
|
34
|
-
hideYAxis?: boolean,
|
|
35
|
-
showHLines?: boolean,
|
|
36
|
-
showVLines?: boolean,
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
export default function BarChart($props: BarChartProps) {
|
|
40
|
-
const defaultHeight = 200;
|
|
41
|
-
const defaultWidth = 400;
|
|
42
|
-
|
|
43
|
-
let container: HTMLElement;
|
|
44
|
-
let measurer: SVGTextElement;
|
|
45
|
-
|
|
46
|
-
let $state = $watch({
|
|
47
|
-
textWidth: 0,
|
|
48
|
-
textHeight: 0,
|
|
49
|
-
get labels() {
|
|
50
|
-
return $props.series.map((s) => s.name);
|
|
51
|
-
},
|
|
52
|
-
get calculatedHeight() {
|
|
53
|
-
return $props.height || defaultHeight;
|
|
54
|
-
},
|
|
55
|
-
get calculatedWidth() {
|
|
56
|
-
return $props.width || container?.clientWidth || defaultWidth;
|
|
57
|
-
},
|
|
58
|
-
get maxValue () {
|
|
59
|
-
return $props.maxValue || calculateMaxValue($props.series);
|
|
60
|
-
},
|
|
61
|
-
get calculatedStepValue() {
|
|
62
|
-
return $props.stepValue || calculateStepValue($state.maxValue, $props.stepCount);
|
|
63
|
-
},
|
|
64
|
-
get stepLabels() {
|
|
65
|
-
return calculateStepLabels($props.stepCount || 2, $state.calculatedStepValue);
|
|
66
|
-
},
|
|
67
|
-
get itemWidth() {
|
|
68
|
-
return calculateItemWidth($state.calculatedWidth, $state.chartLeft, $state.labels);
|
|
69
|
-
},
|
|
70
|
-
get valueHeight() {
|
|
71
|
-
return calculateValueHeight($state.chartBottom, $state.textHeight, $state.calculatedStepValue, $props.stepCount || 2);
|
|
72
|
-
},
|
|
73
|
-
get chartBottom() {
|
|
74
|
-
return calculateChartBottom($props.xLabel ?? "", $state.calculatedHeight, $state.textHeight);
|
|
75
|
-
},
|
|
76
|
-
get chartLeft() {
|
|
77
|
-
return calculateChartLeft($state.stepLabels, $props.yLabel ?? "", $state.textHeight, $state.textWidth);
|
|
78
|
-
}
|
|
79
|
-
});
|
|
80
|
-
|
|
81
|
-
$mount(() => {
|
|
82
|
-
// HACK: Wait until the measurer is really available
|
|
83
|
-
setTimeout(() => {
|
|
84
|
-
const bbox = measurer.getBBox();
|
|
85
|
-
$state.textWidth = bbox.width;
|
|
86
|
-
$state.textHeight = bbox.height * 1.5;
|
|
87
|
-
measurer.remove();
|
|
88
|
-
}, 1);
|
|
89
|
-
});
|
|
90
|
-
|
|
91
|
-
@render {
|
|
92
|
-
<div
|
|
93
|
-
{$props?.id}
|
|
94
|
-
class={["torp-bar-chart", $props?.class]}
|
|
95
|
-
{$props?.style}
|
|
96
|
-
&ref={container}
|
|
97
|
-
>
|
|
98
|
-
<svg version="1.1" width={$state.calculatedWidth} height={$state.calculatedHeight} xmlns="http://www.w3.org/2000/svg">
|
|
99
|
-
<g>
|
|
100
|
-
<text &ref={measurer} x="-999" y="-999">8</text>
|
|
101
|
-
|
|
102
|
-
@if ($state.textWidth && $state.textHeight) {
|
|
103
|
-
<XAxis
|
|
104
|
-
showAxis={!$props.hideXAxis}
|
|
105
|
-
height={$state.calculatedHeight}
|
|
106
|
-
width={$state.calculatedWidth}
|
|
107
|
-
{$state.itemWidth}
|
|
108
|
-
{$state.textHeight}
|
|
109
|
-
xLabel={$props.xLabel ?? ""}
|
|
110
|
-
stepLabels={[]}
|
|
111
|
-
stepValue={0}
|
|
112
|
-
{$state.labels}
|
|
113
|
-
{$state.chartLeft}
|
|
114
|
-
{$state.chartBottom}
|
|
115
|
-
/>
|
|
116
|
-
<YAxis
|
|
117
|
-
showAxis={!$props.hideYAxis}
|
|
118
|
-
{$state.valueHeight}
|
|
119
|
-
{$state.textHeight}
|
|
120
|
-
yLabel={$props.yLabel ?? ""}
|
|
121
|
-
{$state.stepLabels}
|
|
122
|
-
stepValue={$state.calculatedStepValue}
|
|
123
|
-
{$state.chartLeft}
|
|
124
|
-
{$state.chartBottom}
|
|
125
|
-
/>
|
|
126
|
-
<GridLines
|
|
127
|
-
{$props.showHLines}
|
|
128
|
-
{$props.showVLines}
|
|
129
|
-
width={$state.calculatedWidth}
|
|
130
|
-
{$state.labels}
|
|
131
|
-
xStepValue={0}
|
|
132
|
-
xStepLabels={[]}
|
|
133
|
-
yStepValue={$state.calculatedStepValue}
|
|
134
|
-
yStepLabels={$state.stepLabels}
|
|
135
|
-
{$state.itemWidth}
|
|
136
|
-
{$state.valueHeight}
|
|
137
|
-
{$state.chartLeft}
|
|
138
|
-
{$state.chartBottom}
|
|
139
|
-
type="bar"
|
|
140
|
-
/>
|
|
141
|
-
@for (let [i, series] of $props.series.entries()) {
|
|
142
|
-
<rect
|
|
143
|
-
x={$state.chartLeft +
|
|
144
|
-
i * $state.itemWidth +
|
|
145
|
-
$state.itemWidth / 4}
|
|
146
|
-
y={$state.chartBottom - Math.max(1, series.data[0] * $state.valueHeight)}
|
|
147
|
-
width={Math.max(1, $state.itemWidth / 2)}
|
|
148
|
-
height={Math.max(1, series.data[0] * $state.valueHeight)}
|
|
149
|
-
fill={series.color || chartColors[i % chartColors.length]}
|
|
150
|
-
>
|
|
151
|
-
<title>{`${[series.name, series.data[0]].filter(Boolean).join("\n")}`}</title>
|
|
152
|
-
</rect>
|
|
153
|
-
}
|
|
154
|
-
}
|
|
155
|
-
</g>
|
|
156
|
-
</svg>
|
|
157
|
-
</div>
|
|
158
|
-
}
|
|
159
|
-
}
|