@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,255 @@
|
|
|
1
|
+
import type { Bindable, ClassValue, StyleValue } from "@torpor/view";
|
|
2
|
+
import $handle from "../utils/$handle";
|
|
3
|
+
import {
|
|
4
|
+
type FieldContext,
|
|
5
|
+
FieldContextName,
|
|
6
|
+
type FormContext,
|
|
7
|
+
FormContextName,
|
|
8
|
+
} from "../Form/FormTypes";
|
|
9
|
+
import FormValues from "../Form/FormValues.torp";
|
|
10
|
+
import createFormField from "../utils/formField";
|
|
11
|
+
|
|
12
|
+
interface NumberInputProps {
|
|
13
|
+
/** An ID for the root element */
|
|
14
|
+
id?: string;
|
|
15
|
+
/** Classes for the root element */
|
|
16
|
+
class?: ClassValue;
|
|
17
|
+
/** Styles for the root element */
|
|
18
|
+
style?: StyleValue;
|
|
19
|
+
/** The current value of the input; null if the field is empty */
|
|
20
|
+
value?: Bindable<number | null>;
|
|
21
|
+
/** The minimum allowed value */
|
|
22
|
+
min?: number;
|
|
23
|
+
/** The maximum allowed value */
|
|
24
|
+
max?: number;
|
|
25
|
+
/** The amount by which the value is increased or decreased (default 1) */
|
|
26
|
+
step?: number;
|
|
27
|
+
/** If set to true, the user cannot interact with this input */
|
|
28
|
+
disabled?: boolean;
|
|
29
|
+
/** An accessible name for the input */
|
|
30
|
+
ariaLabel?: string;
|
|
31
|
+
/** The name of the component's form data field */
|
|
32
|
+
name?: string;
|
|
33
|
+
/** Raised when the value has changed */
|
|
34
|
+
onchange?: (value: number | null) => void;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* An input where the user enters or steps a number between minimum and
|
|
39
|
+
* maximum values, by typing, by pressing the arrow keys, or by pressing the
|
|
40
|
+
* Home, End, PageUp or PageDown keys.
|
|
41
|
+
*
|
|
42
|
+
* See [the WAI ARIA guidelines for Spin Buttons](https://www.w3.org/WAI/ARIA/apg/patterns/spinbutton/).
|
|
43
|
+
*/
|
|
44
|
+
export default function NumberInput($props: NumberInputProps | undefined) {
|
|
45
|
+
let input: HTMLInputElement;
|
|
46
|
+
|
|
47
|
+
// Wire up the enclosing Form and Field, if any
|
|
48
|
+
const form = createFormField(
|
|
49
|
+
$props?.name,
|
|
50
|
+
$context[FormContextName] as FormContext | undefined,
|
|
51
|
+
$context[FieldContextName] as FieldContext | undefined,
|
|
52
|
+
);
|
|
53
|
+
|
|
54
|
+
function getMin(): number | undefined {
|
|
55
|
+
return $props?.min;
|
|
56
|
+
}
|
|
57
|
+
function getMax(): number | undefined {
|
|
58
|
+
return $props?.max;
|
|
59
|
+
}
|
|
60
|
+
function getStep(): number {
|
|
61
|
+
const step = $props?.step ?? 1;
|
|
62
|
+
return step > 0 ? step : 1;
|
|
63
|
+
}
|
|
64
|
+
function getDisabled(): boolean {
|
|
65
|
+
return $props?.disabled === true;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
// The number of decimal places implied by the step, e.g. 0.25 -> 2
|
|
69
|
+
function getPrecision(): number {
|
|
70
|
+
const text = String(getStep());
|
|
71
|
+
const dot = text.indexOf(".");
|
|
72
|
+
return dot === -1 ? 0 : text.length - dot - 1;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
let $state = $watch({
|
|
76
|
+
value: null as number | null,
|
|
77
|
+
text: "",
|
|
78
|
+
editing: false,
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
$bind($state, $props, "value");
|
|
82
|
+
|
|
83
|
+
// Keep the stored value clamped, so that out-of-range initial values
|
|
84
|
+
// don't later surface as user changes
|
|
85
|
+
$run(() => {
|
|
86
|
+
const clamped = clamp($state.value);
|
|
87
|
+
if (clamped !== $state.value) {
|
|
88
|
+
$state.value = clamped;
|
|
89
|
+
}
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
// The text tracks the value, unless the user is typing
|
|
93
|
+
$run(() => {
|
|
94
|
+
if (!$state.editing) {
|
|
95
|
+
$state.text = $state.value == null ? "" : String($state.value);
|
|
96
|
+
}
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
// Keep the input's value in sync with the text; typing sets the property
|
|
100
|
+
// directly, so an attribute alone would not update it
|
|
101
|
+
function syncInput() {
|
|
102
|
+
if (input && !$state.editing && input.value !== $state.text) {
|
|
103
|
+
input.value = $state.text;
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
$run(() => {
|
|
107
|
+
const text = $state.text;
|
|
108
|
+
const editing = $state.editing;
|
|
109
|
+
if (input && !editing && input.value !== text) {
|
|
110
|
+
input.value = text;
|
|
111
|
+
}
|
|
112
|
+
});
|
|
113
|
+
$onmount(() => syncInput());
|
|
114
|
+
|
|
115
|
+
// Dispatch the change event when a committed value changes
|
|
116
|
+
$handle((first) => {
|
|
117
|
+
const value = $state.value;
|
|
118
|
+
if (!first && !$state.editing) $props?.onchange?.(value);
|
|
119
|
+
});
|
|
120
|
+
|
|
121
|
+
function clamp(value: number | null): number | null {
|
|
122
|
+
if (value == null) return null;
|
|
123
|
+
let result = value;
|
|
124
|
+
if (getMin() != null) result = Math.max(getMin()!, result);
|
|
125
|
+
if (getMax() != null) result = Math.min(getMax()!, result);
|
|
126
|
+
return round(result);
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
function round(value: number): number {
|
|
130
|
+
const precision = getPrecision();
|
|
131
|
+
return precision ? Number(value.toFixed(precision)) : value;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
function parse(text: string): number | null {
|
|
135
|
+
const trimmed = text.trim();
|
|
136
|
+
if (trimmed === "") return null;
|
|
137
|
+
const parsed = Number(trimmed);
|
|
138
|
+
return Number.isFinite(parsed) ? parsed : null;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
function setValue(value: number | null) {
|
|
142
|
+
const next = clamp(value);
|
|
143
|
+
$state.editing = false;
|
|
144
|
+
if (next !== $state.value) {
|
|
145
|
+
$state.value = next;
|
|
146
|
+
form.handleInput();
|
|
147
|
+
}
|
|
148
|
+
// The text always matches what was committed
|
|
149
|
+
$state.text = next == null ? "" : String(next);
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
function stepValue(delta: number) {
|
|
153
|
+
if (getDisabled()) return;
|
|
154
|
+
const base = $state.value ?? 0;
|
|
155
|
+
setValue(base + delta);
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
function handleInput(e: Event) {
|
|
159
|
+
const el = e.currentTarget as HTMLInputElement;
|
|
160
|
+
$state.editing = true;
|
|
161
|
+
$state.text = el.value;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
// Typing commits on blur or Enter; invalid text reverts
|
|
165
|
+
function commit() {
|
|
166
|
+
const text = $state.text;
|
|
167
|
+
$state.editing = false;
|
|
168
|
+
const parsed = parse(text);
|
|
169
|
+
if (parsed == null && text.trim() !== "") {
|
|
170
|
+
// Not a number: revert to the last committed value
|
|
171
|
+
$state.text = $state.value == null ? "" : String($state.value);
|
|
172
|
+
return;
|
|
173
|
+
}
|
|
174
|
+
setValue(parsed);
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
function handleBlur() {
|
|
178
|
+
commit();
|
|
179
|
+
form.handleBlur();
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
function handleKey(e: KeyboardEvent) {
|
|
183
|
+
if (getDisabled()) return;
|
|
184
|
+
|
|
185
|
+
switch (e.key) {
|
|
186
|
+
case "ArrowUp": {
|
|
187
|
+
e.preventDefault();
|
|
188
|
+
stepValue(getStep());
|
|
189
|
+
break;
|
|
190
|
+
}
|
|
191
|
+
case "ArrowDown": {
|
|
192
|
+
e.preventDefault();
|
|
193
|
+
stepValue(-getStep());
|
|
194
|
+
break;
|
|
195
|
+
}
|
|
196
|
+
case "PageUp": {
|
|
197
|
+
e.preventDefault();
|
|
198
|
+
stepValue(getStep() * 10);
|
|
199
|
+
break;
|
|
200
|
+
}
|
|
201
|
+
case "PageDown": {
|
|
202
|
+
e.preventDefault();
|
|
203
|
+
stepValue(-getStep() * 10);
|
|
204
|
+
break;
|
|
205
|
+
}
|
|
206
|
+
case "Home": {
|
|
207
|
+
if (getMin() != null) {
|
|
208
|
+
e.preventDefault();
|
|
209
|
+
setValue(getMin()!);
|
|
210
|
+
}
|
|
211
|
+
break;
|
|
212
|
+
}
|
|
213
|
+
case "End": {
|
|
214
|
+
if (getMax() != null) {
|
|
215
|
+
e.preventDefault();
|
|
216
|
+
setValue(getMax()!);
|
|
217
|
+
}
|
|
218
|
+
break;
|
|
219
|
+
}
|
|
220
|
+
case "Enter": {
|
|
221
|
+
e.preventDefault();
|
|
222
|
+
commit();
|
|
223
|
+
break;
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
@render {
|
|
229
|
+
<input
|
|
230
|
+
id={$props?.id}
|
|
231
|
+
class={["torp-number-input", $props?.class]}
|
|
232
|
+
{$props?.style}
|
|
233
|
+
type="text"
|
|
234
|
+
inputmode="decimal"
|
|
235
|
+
role="spinbutton"
|
|
236
|
+
value={$state.text}
|
|
237
|
+
&ref={input}
|
|
238
|
+
tabindex={getDisabled() ? -1 : 0}
|
|
239
|
+
aria-label={$props?.ariaLabel}
|
|
240
|
+
aria-valuemin={getMin()}
|
|
241
|
+
aria-valuemax={getMax()}
|
|
242
|
+
aria-valuenow={$state.value == null ? undefined : $state.value}
|
|
243
|
+
aria-disabled={getDisabled() ? "true" : undefined}
|
|
244
|
+
data-valid={form.valid ? "valid" : "invalid"}
|
|
245
|
+
aria-describedby={form.messageId}
|
|
246
|
+
aria-invalid={form.inField && !form.valid ? "true" : undefined}
|
|
247
|
+
disabled={getDisabled()}
|
|
248
|
+
oninput={handleInput}
|
|
249
|
+
onblur={handleBlur}
|
|
250
|
+
onkeydown={handleKey}
|
|
251
|
+
/>
|
|
252
|
+
|
|
253
|
+
<FormValues name={form.name} value={$state.value} />
|
|
254
|
+
}
|
|
255
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { type SlotRender } from "@torpor/view";
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
interface NumberInputProps {
|
|
5
|
+
/** An ID for the root element */
|
|
6
|
+
id?: string;
|
|
7
|
+
/** Classes for the root element */
|
|
8
|
+
class?: ClassValue;
|
|
9
|
+
/** Styles for the root element */
|
|
10
|
+
style?: StyleValue;
|
|
11
|
+
/** The current value of the input; null if the field is empty */
|
|
12
|
+
value?: Bindable<number | null>;
|
|
13
|
+
/** The minimum allowed value */
|
|
14
|
+
min?: number;
|
|
15
|
+
/** The maximum allowed value */
|
|
16
|
+
max?: number;
|
|
17
|
+
/** The amount by which the value is increased or decreased (default 1) */
|
|
18
|
+
step?: number;
|
|
19
|
+
/** If set to true, the user cannot interact with this input */
|
|
20
|
+
disabled?: boolean;
|
|
21
|
+
/** An accessible name for the input */
|
|
22
|
+
ariaLabel?: string;
|
|
23
|
+
/** The name of the component's form data field */
|
|
24
|
+
name?: string;
|
|
25
|
+
/** Raised when the value has changed */
|
|
26
|
+
onchange?: (value: number | null) => void;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* An input where the user enters or steps a number between minimum and
|
|
31
|
+
* maximum values, by typing, by pressing the arrow keys, or by pressing the
|
|
32
|
+
* Home, End, PageUp or PageDown keys.
|
|
33
|
+
*
|
|
34
|
+
* See [the WAI ARIA guidelines for Spin Buttons](https://www.w3.org/WAI/ARIA/apg/patterns/spinbutton/).
|
|
35
|
+
*/
|
|
36
|
+
declare function NumberInput(
|
|
37
|
+
$parent: ParentNode,
|
|
38
|
+
$anchor: Node | null,
|
|
39
|
+
$props: NumberInputProps | undefined,
|
|
40
|
+
$context?: Record<PropertyKey, any>,
|
|
41
|
+
$slots?: Record<string, SlotRender>,
|
|
42
|
+
): void;
|
|
43
|
+
|
|
44
|
+
export { NumberInput };
|
|
@@ -1,27 +1,43 @@
|
|
|
1
1
|
import type { ClassValue, StyleValue } from "@torpor/view";
|
|
2
|
-
import {
|
|
2
|
+
import {
|
|
3
|
+
type ItemState,
|
|
4
|
+
type PageNumber,
|
|
5
|
+
type PaginationContext,
|
|
6
|
+
PaginationContextName,
|
|
7
|
+
} from "./PaginationTypes";
|
|
8
|
+
import buildPages from "./buildPages";
|
|
3
9
|
|
|
4
10
|
interface PaginationProps {
|
|
5
11
|
/** An ID for the root element */
|
|
6
12
|
id?: string;
|
|
7
13
|
/** Classes for the root element */
|
|
8
|
-
class?: ClassValue
|
|
14
|
+
class?: ClassValue;
|
|
9
15
|
/** Styles for the root element */
|
|
10
|
-
style?: StyleValue
|
|
16
|
+
style?: StyleValue;
|
|
11
17
|
/** The total number of pages (or items if the page size is greater than 1) */
|
|
12
|
-
count: number
|
|
13
|
-
/** The active page
|
|
14
|
-
|
|
18
|
+
count: number;
|
|
19
|
+
/** The active page */
|
|
20
|
+
page: number;
|
|
21
|
+
/** The number of items on each page **/
|
|
22
|
+
pageSize?: number;
|
|
23
|
+
/** The maximum number of pages to display (gaps will be indicated with ellipses) **/
|
|
24
|
+
maxPages?: number;
|
|
25
|
+
/** Accessible label for the pagination navigation */
|
|
26
|
+
"aria-label"?: string;
|
|
27
|
+
/** Called when a user wants to jump to a specific page (e.g., via ellipsis) */
|
|
28
|
+
onjump?: (targetPage: number, jumpTo: (page: number) => void) => void;
|
|
15
29
|
}
|
|
16
30
|
|
|
17
31
|
/**
|
|
18
32
|
* Buttons with page numbers that can be used to move between pages.
|
|
19
33
|
*/
|
|
20
34
|
export default function Pagination($props: PaginationProps) {
|
|
21
|
-
|
|
35
|
+
let $state = $watch({
|
|
36
|
+
get pages() {
|
|
37
|
+
return buildPages($props.count, $props.page, $props.pageSize, $props.maxPages);
|
|
38
|
+
},
|
|
39
|
+
});
|
|
22
40
|
|
|
23
|
-
// TODO: Do we actually need ItemStates when we're creating the item collection ourselves??
|
|
24
|
-
// A collection containing the active state and some functions for each item
|
|
25
41
|
let itemStates: ItemState[] = [];
|
|
26
42
|
|
|
27
43
|
// Put stuff into a PaginationContext
|
|
@@ -29,23 +45,16 @@ export default function Pagination($props: PaginationProps) {
|
|
|
29
45
|
registerItem,
|
|
30
46
|
removeItem,
|
|
31
47
|
toggleItem,
|
|
32
|
-
handleItemKey
|
|
48
|
+
handleItemKey,
|
|
49
|
+
jumpToPage: (page: number) => {
|
|
50
|
+
$props.page = Math.max(1, Math.min($props.count, page));
|
|
51
|
+
},
|
|
33
52
|
};
|
|
34
53
|
$context[PaginationContextName] = context;
|
|
35
54
|
|
|
36
|
-
function registerItem(
|
|
37
|
-
target: PageNumber,
|
|
38
|
-
setActive: (value: boolean) => void,
|
|
39
|
-
setFocused: () => void
|
|
40
|
-
) {
|
|
55
|
+
function registerItem(item: ItemState) {
|
|
41
56
|
// Add the item's state to the array
|
|
42
|
-
|
|
43
|
-
target,
|
|
44
|
-
active: false,
|
|
45
|
-
setActive,
|
|
46
|
-
setFocused
|
|
47
|
-
};
|
|
48
|
-
itemStates.push(newItemState);
|
|
57
|
+
itemStates.push(item);
|
|
49
58
|
}
|
|
50
59
|
|
|
51
60
|
function removeItem(target: PageNumber) {
|
|
@@ -59,31 +68,30 @@ export default function Pagination($props: PaginationProps) {
|
|
|
59
68
|
function toggleItem(target: PageNumber) {
|
|
60
69
|
switch (target) {
|
|
61
70
|
case "start": {
|
|
62
|
-
$props.
|
|
71
|
+
$props.page = 1;
|
|
63
72
|
break;
|
|
64
73
|
}
|
|
65
74
|
case "previous": {
|
|
66
|
-
$props.
|
|
75
|
+
$props.page = Math.max(1, $props.page - 1);
|
|
67
76
|
break;
|
|
68
77
|
}
|
|
69
78
|
case "next": {
|
|
70
|
-
$props.
|
|
79
|
+
$props.page = Math.min($props.count, $props.page + 1);
|
|
71
80
|
break;
|
|
72
81
|
}
|
|
73
82
|
case "end": {
|
|
74
|
-
$props.
|
|
83
|
+
$props.page = $props.count;
|
|
75
84
|
break;
|
|
76
85
|
}
|
|
77
86
|
case "startgap":
|
|
78
87
|
case "endgap": {
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
$props.number = parseInt(input);
|
|
88
|
+
if ($props.onjump) {
|
|
89
|
+
$props.onjump($props.page, context.jumpToPage);
|
|
82
90
|
}
|
|
83
91
|
break;
|
|
84
92
|
}
|
|
85
93
|
default: {
|
|
86
|
-
$props.
|
|
94
|
+
$props.page = target;
|
|
87
95
|
}
|
|
88
96
|
}
|
|
89
97
|
|
|
@@ -102,15 +110,12 @@ export default function Pagination($props: PaginationProps) {
|
|
|
102
110
|
}
|
|
103
111
|
|
|
104
112
|
function handleItemKey(e: KeyboardEvent) {
|
|
105
|
-
// TODO: Actually just change focus??
|
|
106
113
|
switch (e.key) {
|
|
107
|
-
case "Left":
|
|
108
114
|
case "ArrowLeft": {
|
|
109
115
|
toggleItem("previous");
|
|
110
116
|
e.preventDefault();
|
|
111
117
|
break;
|
|
112
118
|
}
|
|
113
|
-
case "Right":
|
|
114
119
|
case "ArrowRight": {
|
|
115
120
|
toggleItem("next");
|
|
116
121
|
e.preventDefault();
|
|
@@ -135,10 +140,12 @@ export default function Pagination($props: PaginationProps) {
|
|
|
135
140
|
{$props?.id}
|
|
136
141
|
class={["torp-pagination", $props?.class]}
|
|
137
142
|
{$props?.style}
|
|
143
|
+
role="navigation"
|
|
144
|
+
aria-label={$props["aria-label"] ?? "Pagination"}
|
|
138
145
|
tabindex="0"
|
|
139
146
|
onfocus={handleFocus}
|
|
140
147
|
>
|
|
141
|
-
<slot />
|
|
148
|
+
<slot {$state.pages} />
|
|
142
149
|
</div>
|
|
143
150
|
}
|
|
144
151
|
}
|
|
@@ -1,20 +1,26 @@
|
|
|
1
1
|
import type { ClassValue, StyleValue } from "@torpor/view";
|
|
2
|
-
import
|
|
2
|
+
import ChevronDoubleLeft from "../icons/ChevronDoubleLeft.torp";
|
|
3
|
+
import ChevronDoubleRight from "../icons/ChevronDoubleRight.torp";
|
|
4
|
+
import ChevronLeft from "../icons/ChevronLeft.torp";
|
|
5
|
+
import ChevronRight from "../icons/ChevronRight.torp";
|
|
6
|
+
import { type PageNumber, type PaginationContext, PaginationContextName } from "./PaginationTypes";
|
|
3
7
|
|
|
4
8
|
interface PaginationItemProps {
|
|
5
9
|
/** An ID for the root element */
|
|
6
10
|
id?: string;
|
|
7
11
|
/** Classes for the root element */
|
|
8
|
-
class?: ClassValue
|
|
12
|
+
class?: ClassValue;
|
|
9
13
|
/** Styles for the root element */
|
|
10
|
-
style?: StyleValue
|
|
14
|
+
style?: StyleValue;
|
|
11
15
|
/** The page for the button */
|
|
12
16
|
page: PageNumber;
|
|
13
17
|
/** Whether this is the active item */
|
|
14
18
|
active?: boolean;
|
|
19
|
+
/** Whether this item is disabled */
|
|
20
|
+
disabled?: boolean;
|
|
15
21
|
/** Raised when this item is made active */
|
|
16
|
-
|
|
17
|
-
}
|
|
22
|
+
onchange?: (active: boolean) => void;
|
|
23
|
+
}
|
|
18
24
|
|
|
19
25
|
export default function PaginationItem($props: PaginationItemProps) {
|
|
20
26
|
let button: HTMLButtonElement;
|
|
@@ -24,10 +30,28 @@ export default function PaginationItem($props: PaginationItemProps) {
|
|
|
24
30
|
if (!context) {
|
|
25
31
|
throw new Error("PaginationItem must be contained within a Pagination");
|
|
26
32
|
}
|
|
27
|
-
const { registerItem,
|
|
33
|
+
const { registerItem, removeItem, toggleItem, handleItemKey } = context;
|
|
28
34
|
|
|
29
35
|
// Register this item with the parent Pagination, which will handle setting this item's focus on keyboard events
|
|
30
|
-
registerItem($props.page, setActive, setFocused);
|
|
36
|
+
registerItem({ target: $props.page, active: false, setActive, setFocused });
|
|
37
|
+
|
|
38
|
+
$run(() => {
|
|
39
|
+
return () => {
|
|
40
|
+
removeItem($props.page);
|
|
41
|
+
};
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
// Call onchange when the active state changes
|
|
45
|
+
let prevActive = $props.active ?? false;
|
|
46
|
+
$run(() => {
|
|
47
|
+
const active = $props.active ?? false;
|
|
48
|
+
if (active !== prevActive) {
|
|
49
|
+
prevActive = active;
|
|
50
|
+
if ($props?.onchange) {
|
|
51
|
+
$props.onchange(active);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
});
|
|
31
55
|
|
|
32
56
|
// This function is called by the parent Pagination to set this item's active value
|
|
33
57
|
function setActive(value: boolean) {
|
|
@@ -36,8 +60,8 @@ export default function PaginationItem($props: PaginationItemProps) {
|
|
|
36
60
|
|
|
37
61
|
/** Raised when this item is made active */
|
|
38
62
|
//dispatch("toggle", value);
|
|
39
|
-
|
|
40
|
-
$props.
|
|
63
|
+
if ($props?.onchange) {
|
|
64
|
+
$props.onchange(value);
|
|
41
65
|
}
|
|
42
66
|
}
|
|
43
67
|
}
|
|
@@ -64,6 +88,9 @@ export default function PaginationItem($props: PaginationItemProps) {
|
|
|
64
88
|
{$props?.id}
|
|
65
89
|
class={["torp-pagination-item", $props?.class]}
|
|
66
90
|
{$props?.style}
|
|
91
|
+
role="button"
|
|
92
|
+
aria-current="page"
|
|
93
|
+
aria-label={`Page ${$props.page}`}
|
|
67
94
|
data-state={$props.active ? "active" : "inactive"}
|
|
68
95
|
>
|
|
69
96
|
{$props.page}
|
|
@@ -73,6 +100,16 @@ export default function PaginationItem($props: PaginationItemProps) {
|
|
|
73
100
|
type="button"
|
|
74
101
|
{$props?.id}
|
|
75
102
|
class={["torp-pagination-item", $props?.class]}
|
|
103
|
+
{$props?.disabled}
|
|
104
|
+
aria-label={
|
|
105
|
+
$props.page === "start" ? "First page" :
|
|
106
|
+
$props.page === "previous" ? "Previous page" :
|
|
107
|
+
$props.page === "next" ? "Next page" :
|
|
108
|
+
$props.page === "end" ? "Last page" :
|
|
109
|
+
$props.page === "startgap" || $props.page === "endgap" ? "More pages" :
|
|
110
|
+
`Page ${$props.page}`
|
|
111
|
+
}
|
|
112
|
+
aria-disabled={$props.disabled ? "true" : undefined}
|
|
76
113
|
data-type={$props.page}
|
|
77
114
|
data-state={$props.active ? "active" : "inactive"}
|
|
78
115
|
&ref={button}
|
|
@@ -81,13 +118,13 @@ export default function PaginationItem($props: PaginationItemProps) {
|
|
|
81
118
|
>
|
|
82
119
|
<slot>
|
|
83
120
|
@if ($props.page === "start") {
|
|
84
|
-
<
|
|
121
|
+
<ChevronDoubleLeft />
|
|
85
122
|
} else if ($props.page === "previous") {
|
|
86
|
-
<
|
|
123
|
+
<ChevronLeft />
|
|
87
124
|
} else if ($props.page === "next") {
|
|
88
|
-
<
|
|
125
|
+
<ChevronRight />
|
|
89
126
|
} else if ($props.page === "end") {
|
|
90
|
-
<
|
|
127
|
+
<ChevronDoubleRight />
|
|
91
128
|
} else if ($props.page === "startgap" || $props.page === "endgap") {
|
|
92
129
|
<span>…</span>
|
|
93
130
|
} else {
|
|
@@ -2,17 +2,14 @@ export const PaginationContextName: unique symbol = Symbol.for("torp.Pagination"
|
|
|
2
2
|
|
|
3
3
|
export interface PaginationContext {
|
|
4
4
|
// The registerItem function is called from each SeriesItem to register itself and its
|
|
5
|
-
//
|
|
6
|
-
registerItem: (
|
|
7
|
-
target: PageNumber,
|
|
8
|
-
setActive: (value: boolean) => void,
|
|
9
|
-
setFocused: () => void,
|
|
10
|
-
) => void;
|
|
5
|
+
// state with this component
|
|
6
|
+
registerItem: (item: ItemState) => void;
|
|
11
7
|
// The removeItem function is called from a SeriesItem when it has been unloaded so that we
|
|
12
8
|
// can remove it from the itemStates array
|
|
13
9
|
removeItem: (target: PageNumber) => void;
|
|
14
10
|
toggleItem: (target: PageNumber) => void;
|
|
15
11
|
handleItemKey: (e: KeyboardEvent) => void;
|
|
12
|
+
jumpToPage: (page: number) => void;
|
|
16
13
|
}
|
|
17
14
|
|
|
18
15
|
export interface ItemState {
|
|
@@ -4,13 +4,13 @@ import { type PageNumber } from "./PaginationTypes";
|
|
|
4
4
|
* Builds the pages that should be displayed for pagination.
|
|
5
5
|
*
|
|
6
6
|
* @param count The total number of pages (or items if the page size is greater than 1)
|
|
7
|
-
* @param
|
|
7
|
+
* @param page The active page
|
|
8
8
|
* @param pageSize The number of items on each page
|
|
9
9
|
* @param maxPages The maximum number of pages to display (gaps will be indicated with ellipses)
|
|
10
10
|
*/
|
|
11
11
|
export default function buildPages(
|
|
12
12
|
count: number,
|
|
13
|
-
|
|
13
|
+
page: number,
|
|
14
14
|
pageSize: number = 1,
|
|
15
15
|
maxPages: number = 9,
|
|
16
16
|
): PageNumber[] {
|
|
@@ -18,7 +18,7 @@ export default function buildPages(
|
|
|
18
18
|
const pageCount = Math.ceil(count / pageSize);
|
|
19
19
|
|
|
20
20
|
if (pageCount <= maxPages) {
|
|
21
|
-
// There
|
|
21
|
+
// There's no need for ellipses, just return the numbers
|
|
22
22
|
return Array.from({ length: pageCount })
|
|
23
23
|
.fill(0)
|
|
24
24
|
.map((_, i) => i + 1);
|
|
@@ -26,8 +26,8 @@ export default function buildPages(
|
|
|
26
26
|
// Get the start and end around the current page number
|
|
27
27
|
// Use floor and ceil in case there is an even number of pages (e.g. if
|
|
28
28
|
// maxPages is 8, there will be 3 numbers at the start and 4 at the end)
|
|
29
|
-
let start =
|
|
30
|
-
let end =
|
|
29
|
+
let start = page - Math.floor((maxPages - 1) / 2);
|
|
30
|
+
let end = page + Math.ceil((maxPages - 1) / 2);
|
|
31
31
|
if (start < 1) {
|
|
32
32
|
end += Math.abs(start) + 1;
|
|
33
33
|
start = 1;
|
|
@@ -44,12 +44,16 @@ export default function buildPages(
|
|
|
44
44
|
// Replace numbers at the start and end with ellipses if necessary
|
|
45
45
|
if (numbers[0] !== 1) {
|
|
46
46
|
numbers[0] = 1;
|
|
47
|
+
//if (numbers.length > 1) {
|
|
47
48
|
numbers[1] = "startgap";
|
|
49
|
+
//}
|
|
48
50
|
}
|
|
49
51
|
const l = numbers.length;
|
|
50
52
|
if (numbers[l - 1] !== pageCount) {
|
|
51
53
|
numbers[l - 1] = pageCount;
|
|
54
|
+
//if (l > 2) {
|
|
52
55
|
numbers[l - 2] = "endgap";
|
|
56
|
+
//}
|
|
53
57
|
}
|
|
54
58
|
|
|
55
59
|
return numbers;
|
|
@@ -5,13 +5,21 @@ interface PaginationProps {
|
|
|
5
5
|
/** An ID for the root element */
|
|
6
6
|
id?: string;
|
|
7
7
|
/** Classes for the root element */
|
|
8
|
-
class?: ClassValue
|
|
8
|
+
class?: ClassValue;
|
|
9
9
|
/** Styles for the root element */
|
|
10
|
-
style?: StyleValue
|
|
10
|
+
style?: StyleValue;
|
|
11
11
|
/** The total number of pages (or items if the page size is greater than 1) */
|
|
12
|
-
count: number
|
|
13
|
-
/** The active page
|
|
14
|
-
|
|
12
|
+
count: number;
|
|
13
|
+
/** The active page */
|
|
14
|
+
page: number;
|
|
15
|
+
/** The number of items on each page **/
|
|
16
|
+
pageSize?: number;
|
|
17
|
+
/** The maximum number of pages to display (gaps will be indicated with ellipses) **/
|
|
18
|
+
maxPages?: number;
|
|
19
|
+
/** Accessible label for the pagination navigation */
|
|
20
|
+
"aria-label"?: string;
|
|
21
|
+
/** Called when a user wants to jump to a specific page (e.g., via ellipsis) */
|
|
22
|
+
onjump?: (targetPage: number, jumpTo: (page: number) => void) => void;
|
|
15
23
|
}
|
|
16
24
|
|
|
17
25
|
/**
|
|
@@ -31,15 +39,17 @@ interface PaginationItemProps {
|
|
|
31
39
|
/** An ID for the root element */
|
|
32
40
|
id?: string;
|
|
33
41
|
/** Classes for the root element */
|
|
34
|
-
class?: ClassValue
|
|
42
|
+
class?: ClassValue;
|
|
35
43
|
/** Styles for the root element */
|
|
36
|
-
style?: StyleValue
|
|
44
|
+
style?: StyleValue;
|
|
37
45
|
/** The page for the button */
|
|
38
46
|
page: PageNumber;
|
|
39
47
|
/** Whether this is the active item */
|
|
40
48
|
active?: boolean;
|
|
49
|
+
/** Whether this item is disabled */
|
|
50
|
+
disabled?: boolean;
|
|
41
51
|
/** Raised when this item is made active */
|
|
42
|
-
|
|
52
|
+
onchange?: (active: boolean) => void;
|
|
43
53
|
}
|
|
44
54
|
|
|
45
55
|
declare function PaginationItem(
|
|
@@ -50,4 +60,4 @@ declare function PaginationItem(
|
|
|
50
60
|
$slots?: Record<string, SlotRender>,
|
|
51
61
|
): void;
|
|
52
62
|
|
|
53
|
-
export { Pagination, PaginationItem };
|
|
63
|
+
export { Pagination, PaginationItem };
|