@salt-ds/lab 1.0.0-alpha.44 → 1.0.0-alpha.46

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.
Files changed (106) hide show
  1. package/css/salt-lab.css +32 -84
  2. package/dist-cjs/calendar/internal/CalendarDay.js +5 -1
  3. package/dist-cjs/calendar/internal/CalendarDay.js.map +1 -1
  4. package/dist-cjs/calendar/internal/CalendarNavigation.js +2 -6
  5. package/dist-cjs/calendar/internal/CalendarNavigation.js.map +1 -1
  6. package/dist-cjs/calendar/useCalendar.js +4 -4
  7. package/dist-cjs/calendar/useCalendar.js.map +1 -1
  8. package/dist-cjs/calendar/useSelection.js +4 -0
  9. package/dist-cjs/calendar/useSelection.js.map +1 -1
  10. package/dist-cjs/contact-details/ContactPrimaryInfo.js.map +1 -1
  11. package/dist-cjs/date-input/DateInput.css.js +1 -1
  12. package/dist-cjs/date-input/DateInput.js +179 -52
  13. package/dist-cjs/date-input/DateInput.js.map +1 -1
  14. package/dist-cjs/date-picker/DatePicker.js +168 -0
  15. package/dist-cjs/date-picker/DatePicker.js.map +1 -0
  16. package/dist-cjs/date-picker/DatePickerContext.js +34 -0
  17. package/dist-cjs/date-picker/DatePickerContext.js.map +1 -0
  18. package/dist-cjs/date-picker/DatePickerPanel.css.js +6 -0
  19. package/dist-cjs/date-picker/DatePickerPanel.css.js.map +1 -0
  20. package/dist-cjs/date-picker/DatePickerPanel.js +139 -0
  21. package/dist-cjs/date-picker/DatePickerPanel.js.map +1 -0
  22. package/dist-cjs/index.js +3 -0
  23. package/dist-cjs/index.js.map +1 -1
  24. package/dist-cjs/stepped-tracker/TrackerStep/TrackerStep.css.js +1 -1
  25. package/dist-cjs/stepper-input/StepperInput.css.js +1 -1
  26. package/dist-cjs/stepper-input/StepperInput.js +25 -74
  27. package/dist-cjs/stepper-input/StepperInput.js.map +1 -1
  28. package/dist-cjs/stepper-input/useStepperInput.js +19 -63
  29. package/dist-cjs/stepper-input/useStepperInput.js.map +1 -1
  30. package/dist-es/calendar/internal/CalendarDay.js +5 -1
  31. package/dist-es/calendar/internal/CalendarDay.js.map +1 -1
  32. package/dist-es/calendar/internal/CalendarNavigation.js +3 -7
  33. package/dist-es/calendar/internal/CalendarNavigation.js.map +1 -1
  34. package/dist-es/calendar/useCalendar.js +5 -5
  35. package/dist-es/calendar/useCalendar.js.map +1 -1
  36. package/dist-es/calendar/useSelection.js +4 -1
  37. package/dist-es/calendar/useSelection.js.map +1 -1
  38. package/dist-es/contact-details/ContactPrimaryInfo.js.map +1 -1
  39. package/dist-es/date-input/DateInput.css.js +1 -1
  40. package/dist-es/date-input/DateInput.js +183 -56
  41. package/dist-es/date-input/DateInput.js.map +1 -1
  42. package/dist-es/date-picker/DatePicker.js +164 -0
  43. package/dist-es/date-picker/DatePicker.js.map +1 -0
  44. package/dist-es/date-picker/DatePickerContext.js +29 -0
  45. package/dist-es/date-picker/DatePickerContext.js.map +1 -0
  46. package/dist-es/date-picker/DatePickerPanel.css.js +4 -0
  47. package/dist-es/date-picker/DatePickerPanel.css.js.map +1 -0
  48. package/dist-es/date-picker/DatePickerPanel.js +135 -0
  49. package/dist-es/date-picker/DatePickerPanel.js.map +1 -0
  50. package/dist-es/index.js +2 -1
  51. package/dist-es/index.js.map +1 -1
  52. package/dist-es/stepped-tracker/TrackerStep/TrackerStep.css.js +1 -1
  53. package/dist-es/stepper-input/StepperInput.css.js +1 -1
  54. package/dist-es/stepper-input/StepperInput.js +27 -76
  55. package/dist-es/stepper-input/StepperInput.js.map +1 -1
  56. package/dist-es/stepper-input/useStepperInput.js +19 -63
  57. package/dist-es/stepper-input/useStepperInput.js.map +1 -1
  58. package/dist-types/breadcrumbs/internal/BreadcrumbsCollapsed.d.ts +1 -1
  59. package/dist-types/breadcrumbs/internal/BreadcrumbsSeparator.d.ts +1 -1
  60. package/dist-types/button-bar/internal/DescendantContext.d.ts +1 -1
  61. package/dist-types/calendar/useSelection.d.ts +1 -0
  62. package/dist-types/combo-box-deprecated/internal/MultiSelectComboBox.d.ts +1 -1
  63. package/dist-types/combo-box-deprecated/internal/useComboBox.d.ts +54 -60
  64. package/dist-types/combo-box-deprecated/internal/useMultiSelectComboBox.d.ts +165 -182
  65. package/dist-types/common-hooks/collectionProvider.d.ts +1 -1
  66. package/dist-types/contact-details/MailLinkComponent.d.ts +1 -1
  67. package/dist-types/date-input/DateInput.d.ts +29 -7
  68. package/dist-types/date-picker/DatePicker.d.ts +70 -0
  69. package/dist-types/date-picker/DatePickerContext.d.ts +21 -0
  70. package/dist-types/date-picker/DatePickerPanel.d.ts +12 -0
  71. package/dist-types/date-picker/index.d.ts +1 -0
  72. package/dist-types/form-field-legacy/FormActivationIndicator.d.ts +1 -1
  73. package/dist-types/form-field-legacy/FormHelperText.d.ts +1 -1
  74. package/dist-types/form-field-legacy/FormLabel.d.ts +1 -1
  75. package/dist-types/form-field-legacy/NecessityIndicator.d.ts +1 -1
  76. package/dist-types/form-field-legacy/StatusIndicator.d.ts +1 -1
  77. package/dist-types/index.d.ts +1 -0
  78. package/dist-types/list-deprecated/internal/DescendantContext.d.ts +1 -1
  79. package/dist-types/list-deprecated/internal/Highlighter.d.ts +1 -1
  80. package/dist-types/query-input/internal/CategoryList.d.ts +1 -1
  81. package/dist-types/query-input/internal/SearchList.d.ts +1 -1
  82. package/dist-types/query-input/internal/ValueList.d.ts +1 -1
  83. package/dist-types/query-input/internal/ValueSelector.d.ts +1 -1
  84. package/dist-types/responsive/overflowUtils.d.ts +1 -1
  85. package/dist-types/slider/internal/SliderMarkLabels.d.ts +1 -1
  86. package/dist-types/slider/internal/SliderRail.d.ts +1 -1
  87. package/dist-types/slider/internal/SliderRailMarks.d.ts +1 -1
  88. package/dist-types/slider/internal/SliderSelection.d.ts +1 -1
  89. package/dist-types/stepped-tracker/SteppedTrackerContext.d.ts +2 -2
  90. package/dist-types/stepped-tracker/TrackerConnector/TrackerConnector.d.ts +1 -1
  91. package/dist-types/stepper-input/StepperInput.d.ts +43 -12
  92. package/dist-types/stepper-input/useStepperInput.d.ts +7 -293
  93. package/dist-types/tabs/TabActivationIndicator.d.ts +1 -1
  94. package/dist-types/toolbar/Tooltray.d.ts +1 -1
  95. package/dist-types/tree/TreeNode.d.ts +1 -1
  96. package/package.json +3 -3
  97. package/dist-cjs/stepper-input/internal/useActivationIndicatorPosition.js +0 -38
  98. package/dist-cjs/stepper-input/internal/useActivationIndicatorPosition.js.map +0 -1
  99. package/dist-cjs/stepper-input/internal/useDynamicAriaLabel.js +0 -76
  100. package/dist-cjs/stepper-input/internal/useDynamicAriaLabel.js.map +0 -1
  101. package/dist-es/stepper-input/internal/useActivationIndicatorPosition.js +0 -34
  102. package/dist-es/stepper-input/internal/useActivationIndicatorPosition.js.map +0 -1
  103. package/dist-es/stepper-input/internal/useDynamicAriaLabel.js +0 -72
  104. package/dist-es/stepper-input/internal/useDynamicAriaLabel.js.map +0 -1
  105. package/dist-types/stepper-input/internal/useActivationIndicatorPosition.d.ts +0 -2
  106. package/dist-types/stepper-input/internal/useDynamicAriaLabel.d.ts +0 -3
@@ -0,0 +1,135 @@
1
+ import { jsx, jsxs } from 'react/jsx-runtime';
2
+ import { forwardRef, useState, useEffect } from 'react';
3
+ import { makePrefixer, useFloatingComponent, useFormFieldProps, StackLayout, FlexItem, FormFieldHelperText, FlexLayout, FormFieldContext } from '@salt-ds/core';
4
+ import { clsx } from 'clsx';
5
+ import { useDatePickerContext } from './DatePickerContext.js';
6
+ import css_248z from './DatePickerPanel.css.js';
7
+ import { useWindow } from '@salt-ds/window';
8
+ import { useComponentCssInjection } from '@salt-ds/styles';
9
+ import { Calendar } from '../calendar/Calendar.js';
10
+ import { endOfMonth, startOfMonth } from '@internationalized/date';
11
+ import '../calendar/internal/CalendarContext.js';
12
+ import '../calendar/internal/utils.js';
13
+ import '../calendar/useSelection.js';
14
+
15
+ const withBaseName = makePrefixer("saltDatePickerPanel");
16
+ const DatePickerPanel = forwardRef(
17
+ function DatePickerPanel2(props, ref) {
18
+ var _a;
19
+ const { className, onSelect, helperText, CalendarProps: CalendarProps2, ...rest } = props;
20
+ const targetWindow = useWindow();
21
+ useComponentCssInjection({
22
+ testId: "salt-date-picker-panel",
23
+ css: css_248z,
24
+ window: targetWindow
25
+ });
26
+ const { Component: FloatingComponent } = useFloatingComponent();
27
+ const [hoveredDate, setHoveredDate] = useState(null);
28
+ const {
29
+ openState,
30
+ startDate,
31
+ setStartDate,
32
+ startVisibleMonth,
33
+ setStartVisibleMonth,
34
+ endDate,
35
+ setEndDate,
36
+ endVisibleMonth,
37
+ setEndVisibleMonth,
38
+ setOpen,
39
+ selectionVariant,
40
+ context,
41
+ getPanelPosition
42
+ } = useDatePickerContext();
43
+ const { a11yProps } = useFormFieldProps();
44
+ const setRangeDate = (event, newDate) => {
45
+ setStartDate(newDate.startDate);
46
+ setEndDate(newDate.endDate);
47
+ onSelect == null ? void 0 : onSelect(event, newDate);
48
+ if (newDate.startDate && newDate.endDate) {
49
+ setOpen(false);
50
+ }
51
+ };
52
+ const setSingleDate = (event, newDate) => {
53
+ setStartDate(newDate);
54
+ onSelect == null ? void 0 : onSelect(event, newDate);
55
+ setOpen(false);
56
+ };
57
+ const handleHoveredDateChange = (_, newHoveredDate) => {
58
+ setHoveredDate(newHoveredDate);
59
+ };
60
+ useEffect(() => {
61
+ if (startDate) {
62
+ setStartVisibleMonth(startDate);
63
+ setEndVisibleMonth(startDate.add({ months: 1 }));
64
+ }
65
+ }, [startDate]);
66
+ const isRangePicker = selectionVariant === "range";
67
+ const firstCalendarProps = isRangePicker ? {
68
+ selectionVariant: "range",
69
+ hoveredDate: startDate && hoveredDate && hoveredDate.compare(endOfMonth(startDate)) > 0 ? endOfMonth(startDate) : hoveredDate,
70
+ onHoveredDateChange: handleHoveredDateChange,
71
+ selectedDate: { startDate, endDate },
72
+ onSelectedDateChange: setRangeDate,
73
+ maxDate: startDate && endOfMonth(startDate),
74
+ hideOutOfRangeDates: true
75
+ } : {
76
+ selectionVariant: "default",
77
+ selectedDate: startDate,
78
+ onSelectedDateChange: setSingleDate
79
+ };
80
+ return /* @__PURE__ */ jsx(FloatingComponent, {
81
+ open: openState,
82
+ className: clsx(withBaseName(), className),
83
+ "aria-modal": "true",
84
+ ref,
85
+ focusManagerProps: context ? {
86
+ context,
87
+ initialFocus: 4
88
+ } : void 0,
89
+ ...getPanelPosition(),
90
+ ...a11yProps,
91
+ ...rest,
92
+ children: /* @__PURE__ */ jsxs(StackLayout, {
93
+ separators: true,
94
+ gap: 0,
95
+ className: withBaseName("container"),
96
+ children: [
97
+ helperText && /* @__PURE__ */ jsx(FlexItem, {
98
+ className: withBaseName("header"),
99
+ children: /* @__PURE__ */ jsx(FormFieldHelperText, {
100
+ children: helperText
101
+ })
102
+ }),
103
+ /* @__PURE__ */ jsx(FlexLayout, {
104
+ children: /* @__PURE__ */ jsxs(FormFieldContext.Provider, {
105
+ value: {},
106
+ children: [
107
+ /* @__PURE__ */ jsx(Calendar, {
108
+ visibleMonth: startVisibleMonth,
109
+ onVisibleMonthChange: (_, month) => setStartVisibleMonth(month),
110
+ ...firstCalendarProps,
111
+ ...CalendarProps2
112
+ }),
113
+ isRangePicker && /* @__PURE__ */ jsx(Calendar, {
114
+ selectionVariant: "range",
115
+ hoveredDate,
116
+ onHoveredDateChange: handleHoveredDateChange,
117
+ selectedDate: { startDate, endDate },
118
+ onSelectedDateChange: setRangeDate,
119
+ visibleMonth: endVisibleMonth,
120
+ onVisibleMonthChange: (_, month) => setEndVisibleMonth(month),
121
+ hideOutOfRangeDates: true,
122
+ minDate: startDate ? (_a = startOfMonth(startDate)) == null ? void 0 : _a.add({ months: 1 }) : void 0,
123
+ ...CalendarProps2
124
+ })
125
+ ]
126
+ })
127
+ })
128
+ ]
129
+ })
130
+ });
131
+ }
132
+ );
133
+
134
+ export { DatePickerPanel };
135
+ //# sourceMappingURL=DatePickerPanel.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DatePickerPanel.js","sources":["../src/date-picker/DatePickerPanel.tsx"],"sourcesContent":["import {\n ComponentPropsWithoutRef,\n forwardRef,\n SyntheticEvent,\n useEffect,\n useState,\n} from \"react\";\nimport {\n FlexItem,\n FlexLayout,\n FormFieldHelperText,\n makePrefixer,\n StackLayout,\n useFloatingComponent,\n useFormFieldProps,\n FormFieldContext,\n FormFieldContextValue,\n} from \"@salt-ds/core\";\nimport { clsx } from \"clsx\";\nimport { useDatePickerContext } from \"./DatePickerContext\";\nimport dateInputPanelCss from \"./DatePickerPanel.css\";\nimport { useWindow } from \"@salt-ds/window\";\nimport { useComponentCssInjection } from \"@salt-ds/styles\";\nimport {\n Calendar,\n CalendarProps,\n UseRangeSelectionCalendarProps,\n UseSingleSelectionCalendarProps,\n} from \"../calendar\";\nimport { DateValue, endOfMonth, startOfMonth } from \"@internationalized/date\";\n\nexport interface DatePickerPanelProps extends ComponentPropsWithoutRef<\"div\"> {\n onSelect?: (\n event: SyntheticEvent,\n selectedDate?: DateValue | { startDate?: DateValue; endDate?: DateValue }\n ) => void;\n helperText?: string;\n CalendarProps?: Partial<\n Omit<\n CalendarProps,\n | \"selectionVariant\"\n | \"selectedDate\"\n | \"defaultSelectedDate\"\n | \"onSelectedDateChange\"\n >\n >;\n}\n\nconst withBaseName = makePrefixer(\"saltDatePickerPanel\");\n\nexport const DatePickerPanel = forwardRef<HTMLDivElement, DatePickerPanelProps>(\n function DatePickerPanel(props, ref) {\n const { className, onSelect, helperText, CalendarProps, ...rest } = props;\n\n const targetWindow = useWindow();\n useComponentCssInjection({\n testId: \"salt-date-picker-panel\",\n css: dateInputPanelCss,\n window: targetWindow,\n });\n\n const { Component: FloatingComponent } = useFloatingComponent();\n const [hoveredDate, setHoveredDate] = useState<DateValue | null>(null);\n\n const {\n openState,\n startDate,\n setStartDate,\n startVisibleMonth,\n setStartVisibleMonth,\n endDate,\n setEndDate,\n endVisibleMonth,\n setEndVisibleMonth,\n setOpen,\n selectionVariant,\n context,\n getPanelPosition,\n } = useDatePickerContext();\n\n const { a11yProps } = useFormFieldProps();\n\n const setRangeDate: UseRangeSelectionCalendarProps[\"onSelectedDateChange\"] =\n (event, newDate) => {\n setStartDate(newDate.startDate);\n setEndDate(newDate.endDate);\n onSelect?.(event, newDate);\n if (newDate.startDate && newDate.endDate) {\n setOpen(false);\n }\n };\n const setSingleDate: UseSingleSelectionCalendarProps[\"onSelectedDateChange\"] =\n (event, newDate) => {\n setStartDate(newDate);\n onSelect?.(event, newDate);\n setOpen(false);\n };\n const handleHoveredDateChange: CalendarProps[\"onHoveredDateChange\"] = (\n _,\n newHoveredDate\n ) => {\n setHoveredDate(newHoveredDate);\n };\n useEffect(() => {\n if (startDate) {\n setStartVisibleMonth(startDate);\n setEndVisibleMonth(startDate.add({ months: 1 }));\n }\n }, [startDate]);\n\n const isRangePicker = selectionVariant === \"range\";\n const firstCalendarProps: CalendarProps = isRangePicker\n ? {\n selectionVariant: \"range\",\n hoveredDate:\n startDate &&\n hoveredDate &&\n hoveredDate.compare(endOfMonth(startDate)) > 0\n ? endOfMonth(startDate)\n : hoveredDate,\n onHoveredDateChange: handleHoveredDateChange,\n selectedDate: { startDate, endDate },\n onSelectedDateChange: setRangeDate,\n maxDate: startDate && endOfMonth(startDate),\n hideOutOfRangeDates: true,\n }\n : {\n selectionVariant: \"default\",\n selectedDate: startDate,\n onSelectedDateChange: setSingleDate,\n };\n return (\n <FloatingComponent\n open={openState}\n className={clsx(withBaseName(), className)}\n aria-modal=\"true\"\n ref={ref}\n focusManagerProps={\n context\n ? {\n context: context,\n initialFocus: 4,\n }\n : undefined\n }\n {...getPanelPosition()}\n {...a11yProps}\n {...rest}\n >\n <StackLayout separators gap={0} className={withBaseName(\"container\")}>\n {helperText && (\n <FlexItem className={withBaseName(\"header\")}>\n <FormFieldHelperText>{helperText}</FormFieldHelperText>\n </FlexItem>\n )}\n <FlexLayout>\n {/* Avoid Dropdowns in Calendar inheriting the FormField's state */}\n <FormFieldContext.Provider value={{} as FormFieldContextValue}>\n <Calendar\n visibleMonth={startVisibleMonth}\n onVisibleMonthChange={(_, month) => setStartVisibleMonth(month)}\n {...firstCalendarProps}\n {...CalendarProps}\n />\n {isRangePicker && (\n <Calendar\n selectionVariant=\"range\"\n hoveredDate={hoveredDate}\n onHoveredDateChange={handleHoveredDateChange}\n selectedDate={{ startDate, endDate }}\n onSelectedDateChange={setRangeDate}\n visibleMonth={endVisibleMonth}\n onVisibleMonthChange={(_, month) => setEndVisibleMonth(month)}\n hideOutOfRangeDates\n minDate={\n startDate\n ? startOfMonth(startDate)?.add({ months: 1 })\n : undefined\n }\n {...CalendarProps}\n />\n )}\n </FormFieldContext.Provider>\n </FlexLayout>\n </StackLayout>\n </FloatingComponent>\n );\n }\n);\n"],"names":["DatePickerPanel","CalendarProps","dateInputPanelCss"],"mappings":";;;;;;;;;;;;;;AAgDA,MAAM,YAAA,GAAe,aAAa,qBAAqB,CAAA,CAAA;AAEhD,MAAM,eAAkB,GAAA,UAAA;AAAA,EAC7B,SAASA,gBAAgB,CAAA,KAAA,EAAO,GAAK,EAAA;AAnDvC,IAAA,IAAA,EAAA,CAAA;AAoDI,IAAA,MAAM,EAAE,SAAW,EAAA,QAAA,EAAU,YAAY,aAAAC,EAAAA,cAAAA,EAAAA,GAAkB,MAAS,GAAA,KAAA,CAAA;AAEpE,IAAA,MAAM,eAAe,SAAU,EAAA,CAAA;AAC/B,IAAyB,wBAAA,CAAA;AAAA,MACvB,MAAQ,EAAA,wBAAA;AAAA,MACR,GAAK,EAAAC,QAAA;AAAA,MACL,MAAQ,EAAA,YAAA;AAAA,KACT,CAAA,CAAA;AAED,IAAA,MAAM,EAAE,SAAA,EAAW,iBAAkB,EAAA,GAAI,oBAAqB,EAAA,CAAA;AAC9D,IAAA,MAAM,CAAC,WAAA,EAAa,cAAc,CAAA,GAAI,SAA2B,IAAI,CAAA,CAAA;AAErE,IAAM,MAAA;AAAA,MACJ,SAAA;AAAA,MACA,SAAA;AAAA,MACA,YAAA;AAAA,MACA,iBAAA;AAAA,MACA,oBAAA;AAAA,MACA,OAAA;AAAA,MACA,UAAA;AAAA,MACA,eAAA;AAAA,MACA,kBAAA;AAAA,MACA,OAAA;AAAA,MACA,gBAAA;AAAA,MACA,OAAA;AAAA,MACA,gBAAA;AAAA,QACE,oBAAqB,EAAA,CAAA;AAEzB,IAAM,MAAA,EAAE,SAAU,EAAA,GAAI,iBAAkB,EAAA,CAAA;AAExC,IAAM,MAAA,YAAA,GACJ,CAAC,KAAA,EAAO,OAAY,KAAA;AAClB,MAAA,YAAA,CAAa,QAAQ,SAAS,CAAA,CAAA;AAC9B,MAAA,UAAA,CAAW,QAAQ,OAAO,CAAA,CAAA;AAC1B,MAAA,QAAA,IAAA,IAAA,GAAA,KAAA,CAAA,GAAA,QAAA,CAAW,KAAO,EAAA,OAAA,CAAA,CAAA;AAClB,MAAI,IAAA,OAAA,CAAQ,SAAa,IAAA,OAAA,CAAQ,OAAS,EAAA;AACxC,QAAA,OAAA,CAAQ,KAAK,CAAA,CAAA;AAAA,OACf;AAAA,KACF,CAAA;AACF,IAAM,MAAA,aAAA,GACJ,CAAC,KAAA,EAAO,OAAY,KAAA;AAClB,MAAA,YAAA,CAAa,OAAO,CAAA,CAAA;AACpB,MAAA,QAAA,IAAA,IAAA,GAAA,KAAA,CAAA,GAAA,QAAA,CAAW,KAAO,EAAA,OAAA,CAAA,CAAA;AAClB,MAAA,OAAA,CAAQ,KAAK,CAAA,CAAA;AAAA,KACf,CAAA;AACF,IAAM,MAAA,uBAAA,GAAgE,CACpE,CAAA,EACA,cACG,KAAA;AACH,MAAA,cAAA,CAAe,cAAc,CAAA,CAAA;AAAA,KAC/B,CAAA;AACA,IAAA,SAAA,CAAU,MAAM;AACd,MAAA,IAAI,SAAW,EAAA;AACb,QAAA,oBAAA,CAAqB,SAAS,CAAA,CAAA;AAC9B,QAAA,kBAAA,CAAmB,UAAU,GAAI,CAAA,EAAE,MAAQ,EAAA,CAAA,EAAG,CAAC,CAAA,CAAA;AAAA,OACjD;AAAA,KACF,EAAG,CAAC,SAAS,CAAC,CAAA,CAAA;AAEd,IAAA,MAAM,gBAAgB,gBAAqB,KAAA,OAAA,CAAA;AAC3C,IAAA,MAAM,qBAAoC,aACtC,GAAA;AAAA,MACE,gBAAkB,EAAA,OAAA;AAAA,MAClB,WACE,EAAA,SAAA,IACA,WACA,IAAA,WAAA,CAAY,OAAQ,CAAA,UAAA,CAAW,SAAS,CAAC,CAAI,GAAA,CAAA,GACzC,UAAW,CAAA,SAAS,CACpB,GAAA,WAAA;AAAA,MACN,mBAAqB,EAAA,uBAAA;AAAA,MACrB,YAAA,EAAc,EAAE,SAAA,EAAW,OAAQ,EAAA;AAAA,MACnC,oBAAsB,EAAA,YAAA;AAAA,MACtB,OAAA,EAAS,SAAa,IAAA,UAAA,CAAW,SAAS,CAAA;AAAA,MAC1C,mBAAqB,EAAA,IAAA;AAAA,KAEvB,GAAA;AAAA,MACE,gBAAkB,EAAA,SAAA;AAAA,MAClB,YAAc,EAAA,SAAA;AAAA,MACd,oBAAsB,EAAA,aAAA;AAAA,KACxB,CAAA;AACJ,IAAA,uBACG,GAAA,CAAA,iBAAA,EAAA;AAAA,MACC,IAAM,EAAA,SAAA;AAAA,MACN,SAAW,EAAA,IAAA,CAAK,YAAa,EAAA,EAAG,SAAS,CAAA;AAAA,MACzC,YAAW,EAAA,MAAA;AAAA,MACX,GAAA;AAAA,MACA,mBACE,OACI,GAAA;AAAA,QACE,OAAA;AAAA,QACA,YAAc,EAAA,CAAA;AAAA,OAEhB,GAAA,KAAA,CAAA;AAAA,MAEL,GAAG,gBAAiB,EAAA;AAAA,MACpB,GAAG,SAAA;AAAA,MACH,GAAG,IAAA;AAAA,MAEJ,QAAC,kBAAA,IAAA,CAAA,WAAA,EAAA;AAAA,QAAY,UAAU,EAAA,IAAA;AAAA,QAAC,GAAK,EAAA,CAAA;AAAA,QAAG,SAAA,EAAW,aAAa,WAAW,CAAA;AAAA,QAChE,QAAA,EAAA;AAAA,UAAA,UAAA,oBACE,GAAA,CAAA,QAAA,EAAA;AAAA,YAAS,SAAA,EAAW,aAAa,QAAQ,CAAA;AAAA,YACxC,QAAC,kBAAA,GAAA,CAAA,mBAAA,EAAA;AAAA,cAAqB,QAAA,EAAA,UAAA;AAAA,aAAW,CAAA;AAAA,WACnC,CAAA;AAAA,0BAED,GAAA,CAAA,UAAA,EAAA;AAAA,YAEC,QAAA,kBAAA,IAAA,CAAC,iBAAiB,QAAjB,EAAA;AAAA,cAA0B,OAAO,EAAC;AAAA,cACjC,QAAA,EAAA;AAAA,gCAAC,GAAA,CAAA,QAAA,EAAA;AAAA,kBACC,YAAc,EAAA,iBAAA;AAAA,kBACd,oBAAsB,EAAA,CAAC,CAAG,EAAA,KAAA,KAAU,qBAAqB,KAAK,CAAA;AAAA,kBAC7D,GAAG,kBAAA;AAAA,kBACH,GAAGD,cAAAA;AAAA,iBACN,CAAA;AAAA,gBACC,iCACE,GAAA,CAAA,QAAA,EAAA;AAAA,kBACC,gBAAiB,EAAA,OAAA;AAAA,kBACjB,WAAA;AAAA,kBACA,mBAAqB,EAAA,uBAAA;AAAA,kBACrB,YAAA,EAAc,EAAE,SAAA,EAAW,OAAQ,EAAA;AAAA,kBACnC,oBAAsB,EAAA,YAAA;AAAA,kBACtB,YAAc,EAAA,eAAA;AAAA,kBACd,oBAAsB,EAAA,CAAC,CAAG,EAAA,KAAA,KAAU,mBAAmB,KAAK,CAAA;AAAA,kBAC5D,mBAAmB,EAAA,IAAA;AAAA,kBACnB,OAAA,EACE,SACI,GAAA,CAAA,EAAA,GAAA,YAAA,CAAa,SAAS,CAAA,KAAtB,mBAAyB,GAAI,CAAA,EAAE,MAAQ,EAAA,CAAA,EACvC,CAAA,GAAA,KAAA,CAAA;AAAA,kBAEL,GAAGA,cAAAA;AAAA,iBACN,CAAA;AAAA,eAAA;AAAA,aAEJ,CAAA;AAAA,WACF,CAAA;AAAA,SAAA;AAAA,OACF,CAAA;AAAA,KACF,CAAA,CAAA;AAAA,GAEJ;AACF;;;;"}
package/dist-es/index.js CHANGED
@@ -27,7 +27,7 @@ export { OrderedButton } from './button-bar/OrderedButton.js';
27
27
  export { Calendar } from './calendar/Calendar.js';
28
28
  export { useCalendarDay } from './calendar/useCalendarDay.js';
29
29
  export { useCalendar } from './calendar/useCalendar.js';
30
- export { isRangeOrOffsetSelectionValue, useSelectionCalendar, useSelectionDay } from './calendar/useSelection.js';
30
+ export { isRangeOrOffsetSelectionValue, isRangeOrOffsetSelectionWithStartDate, useSelectionCalendar, useSelectionDay } from './calendar/useSelection.js';
31
31
  export { Carousel } from './carousel/Carousel.js';
32
32
  export { CarouselSlide } from './carousel/CarouselSlide.js';
33
33
  export { CascadingMenu } from './cascading-menu/CascadingMenu.js';
@@ -55,6 +55,7 @@ export { ContactFavoriteToggle } from './contact-details/ContactFavoriteToggle.j
55
55
  export { MailLinkComponent } from './contact-details/MailLinkComponent.js';
56
56
  export { ContentStatus } from './content-status/ContentStatus.js';
57
57
  export { DateInput } from './date-input/DateInput.js';
58
+ export { DatePicker } from './date-picker/DatePicker.js';
58
59
  export { DeckItem } from './deck-item/DeckItem.js';
59
60
  export { DeckLayout } from './deck-layout/DeckLayout.js';
60
61
  export { DropdownBase } from './dropdown/DropdownBase.js';
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
@@ -1,4 +1,4 @@
1
- var css_248z = ".saltTrackerStep {\n --trackerStep-icon-color-active: var(--saltTrackerStep-icon-color-active, var(--salt-status-info-foreground));\n --trackerStep-icon-color-completed: var(--saltTrackerStep-icon-color-completed, var(--salt-status-success-foreground));\n\n --trackerStep-icon-color: var(--saltTrackerStep-icon-color, var(--salt-status-static-foreground));\n\n --saltIcon-color: var(--trackerStep-icon-color);\n /* We redefine Icon Size so we can use it in calc functions in the trackerConnector */\n --saltIcon-size: var(--saltTrackerStep-icon-size, max(var(--salt-size-icon), 12px));\n}\n\n.saltTrackerStep {\n margin: 0;\n text-indent: 0;\n list-style-type: none;\n flex: 1;\n position: relative;\n display: flex;\n align-items: center;\n width: var(--saltTrackerStep-width, 100%);\n gap: var(--salt-spacing-50);\n color: var(--salt-content-primary-foreground);\n font-size: var(--salt-text-label-fontSize);\n line-height: var(--salt-text-label-lineHeight);\n}\n\n.saltSteppedTracker.saltSteppedTracker-horizontal .saltTrackerStep {\n flex-direction: column;\n padding: 0 var(--salt-spacing-25);\n}\n\n.saltSteppedTracker.saltSteppedTracker-vertical .saltTrackerStep {\n flex-direction: row;\n min-height: calc(var(--salt-size-base) * 2);\n width: 100%;\n}\n\n/* Pseudo-class applied to the root element on focus */\n.saltTrackerStep:focus-visible {\n outline-style: var(--salt-focused-outlineStyle);\n outline-width: var(--salt-focused-outlineWidth);\n outline-color: var(--salt-focused-outlineColor);\n outline-offset: var(--salt-focused-outlineOffset);\n}\n\n.saltTrackerStep .saltTrackerStep-body {\n width: 100%;\n display: flex;\n align-items: center;\n flex-direction: column;\n}\n\n.saltTrackerStep.saltTrackerStep-active {\n --trackerStep-icon-color: var(--trackerStep-icon-color-active);\n}\n\n.saltTrackerStep.saltTrackerStep-completed {\n --trackerStep-icon-color: var(--trackerStep-icon-color-completed);\n}\n";
1
+ var css_248z = ".saltTrackerStep {\n --trackerStep-icon-color-active: var(--saltTrackerStep-icon-color-active, var(--salt-status-info-foreground-decorative));\n --trackerStep-icon-color-completed: var(--saltTrackerStep-icon-color-completed, var(--salt-status-success-foreground-decorative));\n\n --trackerStep-icon-color: var(--saltTrackerStep-icon-color, var(--salt-status-static-foreground));\n\n --saltIcon-color: var(--trackerStep-icon-color);\n /* We redefine Icon Size so we can use it in calc functions in the trackerConnector */\n --saltIcon-size: var(--saltTrackerStep-icon-size, max(var(--salt-size-icon), 12px));\n}\n\n.saltTrackerStep {\n margin: 0;\n text-indent: 0;\n list-style-type: none;\n flex: 1;\n position: relative;\n display: flex;\n align-items: center;\n width: var(--saltTrackerStep-width, 100%);\n gap: var(--salt-spacing-50);\n color: var(--salt-content-primary-foreground);\n font-size: var(--salt-text-label-fontSize);\n line-height: var(--salt-text-label-lineHeight);\n}\n\n.saltSteppedTracker.saltSteppedTracker-horizontal .saltTrackerStep {\n flex-direction: column;\n padding: 0 var(--salt-spacing-25);\n}\n\n.saltSteppedTracker.saltSteppedTracker-vertical .saltTrackerStep {\n flex-direction: row;\n min-height: calc(var(--salt-size-base) * 2);\n width: 100%;\n}\n\n/* Pseudo-class applied to the root element on focus */\n.saltTrackerStep:focus-visible {\n outline-style: var(--salt-focused-outlineStyle);\n outline-width: var(--salt-focused-outlineWidth);\n outline-color: var(--salt-focused-outlineColor);\n outline-offset: var(--salt-focused-outlineOffset);\n}\n\n.saltTrackerStep .saltTrackerStep-body {\n width: 100%;\n display: flex;\n align-items: center;\n flex-direction: column;\n}\n\n.saltTrackerStep.saltTrackerStep-active {\n --trackerStep-icon-color: var(--trackerStep-icon-color-active);\n}\n\n.saltTrackerStep.saltTrackerStep-completed {\n --trackerStep-icon-color: var(--trackerStep-icon-color-completed);\n}\n";
2
2
 
3
3
  export { css_248z as default };
4
4
  //# sourceMappingURL=TrackerStep.css.js.map
@@ -1,4 +1,4 @@
1
- var css_248z = ".salt-density-medium {\n --stepperInput-adornment-container-top: -2px;\n --stepperInput-button-height: 12px;\n --stepperInput-button-margin: 2px;\n --stepperInput-button-width: 24px;\n --stepperInput-input-maxHeight: 28px;\n --stepperInput-secondary-button-height: 26px;\n --stepperInput-secondary-button-width: 26px;\n --stepperInput-secondary-button-marginRight: 2px;\n}\n\n.salt-density-touch {\n --stepperInput-adornment-container-top: 0;\n --stepperInput-button-height: 16px;\n --stepperInput-button-margin: 4px;\n --stepperInput-button-width: 36px;\n --stepperInput-secondary-button-height: 36px;\n --stepperInput-secondary-button-width: 36px;\n --stepperInput-secondary-button-marginRight: 4px;\n}\n\n.salt-density-low {\n --stepperInput-adornment-container-top: 0;\n --stepperInput-button-height: 12px;\n --stepperInput-button-margin: 4px;\n --stepperInput-button-width: 28px;\n --stepperInput-secondary-button-height: 28px;\n --stepperInput-secondary-button-width: 28px;\n --stepperInput-secondary-button-marginRight: 4px;\n}\n\n.salt-density-high {\n --stepperInput-adornment-container-top: -2px;\n --stepperInput-button-height: 8px;\n --stepperInput-button-margin: 2px;\n --stepperInput-button-width: 16px;\n --stepperInput-input-maxHeight: 20px;\n --stepperInput-secondary-button-height: 18px;\n --stepperInput-secondary-button-width: 18px;\n --stepperInput-secondary-button-marginRight: 2px;\n}\n\n/* Styles applied to adornment container */\n.saltStepperInput-adornmentContainer {\n display: flex;\n position: relative;\n top: var(--saltStepperInput-adornment-container-top, var(--stepperInput-adornment-container-top));\n}\n\n/* Styles applied to refresh button */\n.saltStepperInput-secondaryButton {\n --saltButton-height: var(--stepperInput-secondary-button-height);\n --saltButton-margin: var(--stepperInput-button-margin) var(--stepperInput-secondary-button-marginRight) var(--stepperInput-button-margin) var(--stepperInput-button-margin);\n --saltButton-width: var(--stepperInput-secondary-button-width);\n}\n\n.saltStepperInput-hideSecondaryButton {\n visibility: hidden;\n}\n\n/* Styles applied to stepper buttons container */\n.saltStepperInput-buttonContainer {\n display: flex;\n flex-direction: column;\n justify-content: center;\n}\n\n/* Styles applied to stepper buttons */\n.saltStepperInput-stepperButton {\n --saltButton-height: var(--stepperInput-button-height);\n --saltButton-margin: var(--stepperInput-button-margin);\n --saltButton-width: var(--stepperInput-button-width);\n}\n\n/* Styles applied to increment button */\n.saltStepperInput-increment {\n}\n\n/* Styles applied to decrement button */\n.saltStepperInput-decrement {\n --saltButton-margin: 0 var(--stepperInput-button-margin) var(--stepperInput-button-margin) var(--stepperInput-button-margin);\n}\n\n/* Styles applied to stepper button icon */\n.saltStepperInput-stepperButtonIcon {\n}\n\n/* Styles applied to input component */\n.saltStepperInput-input {\n max-height: var(--saltStepperInput-maxHeight, unset);\n}\n";
1
+ var css_248z = "/* Styles applied to stepper container */\n.saltStepperInput {\n align-items: center;\n display: flex;\n flex-direction: row;\n gap: var(--salt-spacing-50);\n}\n\n/* Styles applied to stepper buttons container */\n.saltStepperInput-buttonContainer {\n display: flex;\n flex-direction: column;\n gap: var(--salt-spacing-50);\n}\n\n/* Styles applied to stepper buttons */\n.saltStepperInput-stepperButton {\n --saltButton-height: calc((var(--salt-size-base) - var(--salt-spacing-50)) * 0.5);\n --saltButton-width: var(--salt-size-base);\n}\n";
2
2
 
3
3
  export { css_248z as default };
4
4
  //# sourceMappingURL=StepperInput.css.js.map
@@ -1,13 +1,10 @@
1
1
  import { jsxs, jsx } from 'react/jsx-runtime';
2
2
  import { clsx } from 'clsx';
3
3
  import { forwardRef, useRef } from 'react';
4
- import { makePrefixer, Button } from '@salt-ds/core';
4
+ import { makePrefixer, Input, Button } from '@salt-ds/core';
5
5
  import { useComponentCssInjection } from '@salt-ds/styles';
6
6
  import { useWindow } from '@salt-ds/window';
7
- import { RefreshIcon, TriangleUpIcon, TriangleDownIcon } from '@salt-ds/icons';
8
- import { InputLegacy } from '../input-legacy/InputLegacy.js';
9
- import '../input-legacy/StaticInputAdornment.js';
10
- import { useActivationIndicatorPosition } from './internal/useActivationIndicatorPosition.js';
7
+ import { TriangleUpIcon, TriangleDownIcon } from '@salt-ds/icons';
11
8
  import { useStepperInput } from './useStepperInput.js';
12
9
  import css_248z from './StepperInput.css.js';
13
10
 
@@ -15,11 +12,13 @@ const withBaseName = makePrefixer("saltStepperInput");
15
12
  const StepperInput = forwardRef(
16
13
  function StepperInput2(props, ref) {
17
14
  const {
18
- ButtonProps: ButtonPropsProp,
19
- InputProps: InputPropsProp,
20
- textAlign = "left",
21
15
  className,
22
- showRefreshButton = false
16
+ hideButtons,
17
+ onBlur,
18
+ onChange,
19
+ onFocus,
20
+ readOnly,
21
+ ...rest
23
22
  } = props;
24
23
  const targetWindow = useWindow();
25
24
  useComponentCssInjection({
@@ -27,90 +26,42 @@ const StepperInput = forwardRef(
27
26
  css: css_248z,
28
27
  window: targetWindow
29
28
  });
30
- const adornmentRef = useRef(null);
31
29
  const inputRef = useRef(null);
32
- const {
33
- decrementButtonDown,
34
- getButtonIcon,
35
- getButtonProps,
36
- getInputProps,
37
- incrementButtonDown,
38
- isAtMax,
39
- isAtMin,
40
- refreshCurrentValue,
41
- stepperDirection,
42
- valuesHaveDiverged
43
- } = useStepperInput(props, inputRef);
44
- useActivationIndicatorPosition(
45
- adornmentRef,
46
- valuesHaveDiverged() || showRefreshButton
47
- );
48
- const endAdornment = /* @__PURE__ */ jsxs("div", {
49
- className: withBaseName("adornmentContainer"),
50
- ref: adornmentRef,
30
+ const { getButtonProps, getInputProps } = useStepperInput(props, inputRef);
31
+ return /* @__PURE__ */ jsxs("div", {
32
+ className: clsx(withBaseName(), className),
33
+ ref,
51
34
  children: [
52
- /* @__PURE__ */ jsx(Button, {
53
- "aria-label": "Refresh default value",
54
- className: clsx(withBaseName("secondaryButton"), {
55
- [withBaseName("hideSecondaryButton")]: !(showRefreshButton || valuesHaveDiverged())
56
- }),
57
- onClick: refreshCurrentValue,
58
- variant: "secondary",
59
- children: /* @__PURE__ */ jsx(RefreshIcon, {
60
- "aria-label": "refresh"
61
- })
35
+ /* @__PURE__ */ jsx(Input, {
36
+ onBlur,
37
+ onFocus,
38
+ ref: inputRef,
39
+ readOnly,
40
+ ...getInputProps(rest)
62
41
  }),
63
- /* @__PURE__ */ jsxs("div", {
42
+ !hideButtons && !readOnly && /* @__PURE__ */ jsxs("div", {
64
43
  className: withBaseName("buttonContainer"),
65
44
  children: [
66
45
  /* @__PURE__ */ jsx(Button, {
67
- className: clsx(
68
- withBaseName("stepperButton"),
69
- withBaseName("increment"),
70
- {
71
- active: incrementButtonDown
72
- }
73
- ),
74
- disabled: isAtMax(),
75
- ...getButtonProps(stepperDirection.INCREMENT, ButtonPropsProp),
46
+ "aria-label": "increment value",
47
+ className: withBaseName("stepperButton"),
48
+ ...getButtonProps("increment"),
76
49
  children: /* @__PURE__ */ jsx(TriangleUpIcon, {
77
- className: withBaseName("stepperButtonIcon"),
78
- "aria-label": getButtonIcon(stepperDirection.INCREMENT)
50
+ "aria-hidden": true
79
51
  })
80
52
  }),
81
53
  /* @__PURE__ */ jsx(Button, {
82
- className: clsx(
83
- withBaseName("stepperButton"),
84
- withBaseName("decrement"),
85
- {
86
- active: decrementButtonDown
87
- }
88
- ),
89
- disabled: isAtMin(),
90
- ...getButtonProps(stepperDirection.DECREMENT, ButtonPropsProp),
54
+ "aria-label": "decrement value",
55
+ className: withBaseName("stepperButton"),
56
+ ...getButtonProps("decrement"),
91
57
  children: /* @__PURE__ */ jsx(TriangleDownIcon, {
92
- className: withBaseName("stepperButtonIcon"),
93
- "aria-label": getButtonIcon(stepperDirection.DECREMENT)
58
+ "aria-hidden": true
94
59
  })
95
60
  })
96
61
  ]
97
62
  })
98
63
  ]
99
64
  });
100
- return /* @__PURE__ */ jsx("div", {
101
- className: clsx(withBaseName(), className),
102
- onBlur: props.onBlur,
103
- onFocus: props.onFocus,
104
- ref,
105
- children: /* @__PURE__ */ jsx(InputLegacy, {
106
- className: withBaseName("input"),
107
- endAdornment,
108
- highlightOnFocus: true,
109
- ref: inputRef,
110
- textAlign,
111
- ...getInputProps(InputPropsProp)
112
- })
113
- });
114
65
  }
115
66
  );
116
67
 
@@ -1 +1 @@
1
- {"version":3,"file":"StepperInput.js","sources":["../src/stepper-input/StepperInput.tsx"],"sourcesContent":["import { clsx } from \"clsx\";\nimport React, { forwardRef, ReactNode, useRef } from \"react\";\nimport { Button, ButtonProps, makePrefixer } from \"@salt-ds/core\";\nimport { useComponentCssInjection } from \"@salt-ds/styles\";\nimport { useWindow } from \"@salt-ds/window\";\nimport { RefreshIcon, TriangleDownIcon, TriangleUpIcon } from \"@salt-ds/icons\";\nimport {\n InputLegacy as Input,\n InputLegacyProps as InputProps,\n} from \"../input-legacy\";\nimport { useActivationIndicatorPosition } from \"./internal/useActivationIndicatorPosition\";\nimport { useStepperInput } from \"./useStepperInput\";\n\nimport stepperInputCss from \"./StepperInput.css\";\n\nconst withBaseName = makePrefixer(\"saltStepperInput\");\n\nexport interface StepperInputProps {\n ButtonProps?: Partial<ButtonProps>;\n InputProps?: Partial<InputProps>;\n block?: number;\n className?: string;\n decimalPlaces?: number;\n defaultValue?: number;\n liveValue?: number;\n max?: number;\n min?: number;\n onBlur?: (event: React.FocusEvent<HTMLDivElement>) => void;\n onFocus?: (event: React.FocusEvent<HTMLDivElement>) => void;\n onChange?: (changedValue: number | string) => void;\n showRefreshButton?: boolean;\n step?: number;\n textAlign?: \"center\" | \"left\" | \"right\";\n value?: number | string;\n}\n\nexport const StepperInput = forwardRef<HTMLDivElement, StepperInputProps>(\n function StepperInput(props, ref) {\n const {\n ButtonProps: ButtonPropsProp,\n InputProps: InputPropsProp,\n textAlign = \"left\",\n className,\n showRefreshButton = false,\n } = props;\n\n const targetWindow = useWindow();\n useComponentCssInjection({\n testId: \"salt-stepper-input\",\n css: stepperInputCss,\n window: targetWindow,\n });\n\n const adornmentRef = useRef<HTMLDivElement | null>(null);\n const inputRef = useRef<HTMLInputElement | null>(null);\n\n const {\n decrementButtonDown,\n getButtonIcon,\n getButtonProps,\n getInputProps,\n incrementButtonDown,\n isAtMax,\n isAtMin,\n refreshCurrentValue,\n stepperDirection,\n valuesHaveDiverged,\n } = useStepperInput(props, inputRef);\n\n useActivationIndicatorPosition(\n adornmentRef,\n valuesHaveDiverged() || showRefreshButton\n );\n\n const endAdornment: ReactNode = (\n <div className={withBaseName(\"adornmentContainer\")} ref={adornmentRef}>\n <Button\n aria-label=\"Refresh default value\"\n className={clsx(withBaseName(\"secondaryButton\"), {\n // Refresh button is always rendered and has its visibility toggled to\n // avoid component width changing.\n [withBaseName(\"hideSecondaryButton\")]: !(\n showRefreshButton || valuesHaveDiverged()\n ),\n })}\n onClick={refreshCurrentValue}\n variant=\"secondary\"\n >\n <RefreshIcon aria-label=\"refresh\" />\n </Button>\n <div className={withBaseName(\"buttonContainer\")}>\n <Button\n className={clsx(\n withBaseName(\"stepperButton\"),\n withBaseName(\"increment\"),\n {\n active: incrementButtonDown,\n }\n )}\n disabled={isAtMax()}\n {...getButtonProps(stepperDirection.INCREMENT, ButtonPropsProp)}\n >\n <TriangleUpIcon\n className={withBaseName(\"stepperButtonIcon\")}\n aria-label={getButtonIcon(stepperDirection.INCREMENT)}\n />\n </Button>\n <Button\n className={clsx(\n withBaseName(\"stepperButton\"),\n withBaseName(\"decrement\"),\n {\n active: decrementButtonDown,\n }\n )}\n disabled={isAtMin()}\n {...getButtonProps(stepperDirection.DECREMENT, ButtonPropsProp)}\n >\n <TriangleDownIcon\n className={withBaseName(\"stepperButtonIcon\")}\n aria-label={getButtonIcon(stepperDirection.DECREMENT)}\n />\n </Button>\n </div>\n </div>\n );\n\n return (\n <div\n className={clsx(withBaseName(), className)}\n onBlur={props.onBlur}\n onFocus={props.onFocus}\n ref={ref}\n >\n <Input\n className={withBaseName(\"input\")}\n endAdornment={endAdornment}\n highlightOnFocus\n ref={inputRef}\n textAlign={textAlign}\n {...getInputProps(InputPropsProp)}\n />\n </div>\n );\n }\n);\n"],"names":["StepperInput","stepperInputCss","Input"],"mappings":"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"}
1
+ {"version":3,"file":"StepperInput.js","sources":["../src/stepper-input/StepperInput.tsx"],"sourcesContent":["import { clsx } from \"clsx\";\nimport { FocusEventHandler, forwardRef, useRef } from \"react\";\nimport { Button, makePrefixer, Input, InputProps } from \"@salt-ds/core\";\nimport { useComponentCssInjection } from \"@salt-ds/styles\";\nimport { useWindow } from \"@salt-ds/window\";\nimport { TriangleDownIcon, TriangleUpIcon } from \"@salt-ds/icons\";\nimport { useStepperInput } from \"./useStepperInput\";\n\nimport stepperInputCss from \"./StepperInput.css\";\n\nconst withBaseName = makePrefixer(\"saltStepperInput\");\n\nexport interface StepperInputProps\n extends Omit<InputProps, \"onChange\" | \"emptyReadOnlyMarker\"> {\n /**\n * A multiplier applied to the `step` when the value is incremented or decremented using the PageDown/PageUp keys.\n */\n block?: number;\n /**\n * The number of decimal places to display.\n */\n decimalPlaces?: number;\n /**\n * Sets the initial default value of the component.\n */\n defaultValue?: number;\n /**\n * The maximum value that can be selected.\n */\n max?: number;\n /**\n * The minimum value that can be selected.\n */\n min?: number;\n /**\n * Whether to hide the stepper buttons. Defaults to `false`.\n */\n hideButtons?: boolean;\n /**\n * Callback when stepper input loses focus.\n */\n onBlur?: FocusEventHandler<HTMLInputElement>;\n /**\n * Callback when stepper input value is changed.\n */\n onChange?: (changedValue: number | string) => void;\n /**\n * Callback when stepper input gains focus.\n */\n onFocus?: FocusEventHandler<HTMLInputElement>;\n /**\n * The amount to increment or decrement the value by when using the stepper buttons or Up Arrow and Down Arrow keys.\n */\n step?: number;\n /**\n * Determines the text alignment of the display value.\n */\n textAlign?: \"center\" | \"left\" | \"right\";\n /**\n * The value of the stepper input. The component will be controlled if this prop is provided.\n */\n value?: number | string;\n}\n\nexport const StepperInput = forwardRef<HTMLDivElement, StepperInputProps>(\n function StepperInput(props, ref) {\n const {\n className,\n hideButtons,\n onBlur,\n onChange,\n onFocus,\n readOnly,\n ...rest\n } = props;\n\n const targetWindow = useWindow();\n useComponentCssInjection({\n testId: \"salt-stepper-input\",\n css: stepperInputCss,\n window: targetWindow,\n });\n\n const inputRef = useRef<HTMLInputElement | null>(null);\n\n const { getButtonProps, getInputProps } = useStepperInput(props, inputRef);\n\n return (\n <div className={clsx(withBaseName(), className)} ref={ref}>\n <Input\n onBlur={onBlur}\n onFocus={onFocus}\n ref={inputRef}\n readOnly={readOnly}\n {...getInputProps(rest)}\n />\n {!hideButtons && !readOnly && (\n <div className={withBaseName(\"buttonContainer\")}>\n <Button\n aria-label=\"increment value\"\n className={withBaseName(\"stepperButton\")}\n {...getButtonProps(\"increment\")}\n >\n <TriangleUpIcon aria-hidden />\n </Button>\n <Button\n aria-label=\"decrement value\"\n className={withBaseName(\"stepperButton\")}\n {...getButtonProps(\"decrement\")}\n >\n <TriangleDownIcon aria-hidden />\n </Button>\n </div>\n )}\n </div>\n );\n }\n);\n"],"names":["StepperInput","stepperInputCss"],"mappings":";;;;;;;;;;AAUA,MAAM,YAAA,GAAe,aAAa,kBAAkB,CAAA,CAAA;AAsD7C,MAAM,YAAe,GAAA,UAAA;AAAA,EAC1B,SAASA,aAAa,CAAA,KAAA,EAAO,GAAK,EAAA;AAChC,IAAM,MAAA;AAAA,MACJ,SAAA;AAAA,MACA,WAAA;AAAA,MACA,MAAA;AAAA,MACA,QAAA;AAAA,MACA,OAAA;AAAA,MACA,QAAA;AAAA,MACG,GAAA,IAAA;AAAA,KACD,GAAA,KAAA,CAAA;AAEJ,IAAA,MAAM,eAAe,SAAU,EAAA,CAAA;AAC/B,IAAyB,wBAAA,CAAA;AAAA,MACvB,MAAQ,EAAA,oBAAA;AAAA,MACR,GAAK,EAAAC,QAAA;AAAA,MACL,MAAQ,EAAA,YAAA;AAAA,KACT,CAAA,CAAA;AAED,IAAM,MAAA,QAAA,GAAW,OAAgC,IAAI,CAAA,CAAA;AAErD,IAAA,MAAM,EAAE,cAAgB,EAAA,aAAA,EAAkB,GAAA,eAAA,CAAgB,OAAO,QAAQ,CAAA,CAAA;AAEzE,IAAA,uBACG,IAAA,CAAA,KAAA,EAAA;AAAA,MAAI,SAAW,EAAA,IAAA,CAAK,YAAa,EAAA,EAAG,SAAS,CAAA;AAAA,MAAG,GAAA;AAAA,MAC/C,QAAA,EAAA;AAAA,wBAAC,GAAA,CAAA,KAAA,EAAA;AAAA,UACC,MAAA;AAAA,UACA,OAAA;AAAA,UACA,GAAK,EAAA,QAAA;AAAA,UACL,QAAA;AAAA,UACC,GAAG,cAAc,IAAI,CAAA;AAAA,SACxB,CAAA;AAAA,QACC,CAAC,WAAA,IAAe,CAAC,QAAA,oBACf,IAAA,CAAA,KAAA,EAAA;AAAA,UAAI,SAAA,EAAW,aAAa,iBAAiB,CAAA;AAAA,UAC5C,QAAA,EAAA;AAAA,4BAAC,GAAA,CAAA,MAAA,EAAA;AAAA,cACC,YAAW,EAAA,iBAAA;AAAA,cACX,SAAA,EAAW,aAAa,eAAe,CAAA;AAAA,cACtC,GAAG,eAAe,WAAW,CAAA;AAAA,cAE9B,QAAC,kBAAA,GAAA,CAAA,cAAA,EAAA;AAAA,gBAAe,aAAW,EAAA,IAAA;AAAA,eAAC,CAAA;AAAA,aAC9B,CAAA;AAAA,4BACC,GAAA,CAAA,MAAA,EAAA;AAAA,cACC,YAAW,EAAA,iBAAA;AAAA,cACX,SAAA,EAAW,aAAa,eAAe,CAAA;AAAA,cACtC,GAAG,eAAe,WAAW,CAAA;AAAA,cAE9B,QAAC,kBAAA,GAAA,CAAA,gBAAA,EAAA;AAAA,gBAAiB,aAAW,EAAA,IAAA;AAAA,eAAC,CAAA;AAAA,aAChC,CAAA;AAAA,WAAA;AAAA,SACF,CAAA;AAAA,OAAA;AAAA,KAEJ,CAAA,CAAA;AAAA,GAEJ;AACF;;;;"}
@@ -1,11 +1,6 @@
1
1
  import { useControlled, useId } from '@salt-ds/core';
2
- import { useDynamicAriaLabel } from './internal/useDynamicAriaLabel.js';
3
2
  import { useSpinner } from './internal/useSpinner.js';
4
3
 
5
- const stepperDirection = {
6
- INCREMENT: "increment",
7
- DECREMENT: "decrement"
8
- };
9
4
  const ACCEPT_INPUT = /^[-+]?[0-9]*\.?([0-9]+)?/g;
10
5
  const callAll = (...fns) => (...args) => fns.forEach((fn) => fn && fn(...args));
11
6
  const toFixedDecimalPlaces = (inputNumber, decimalPlaces) => inputNumber.toFixed(decimalPlaces);
@@ -19,27 +14,25 @@ const toFloat = (inputValue) => {
19
14
  return 0;
20
15
  return parseFloat(inputValue.toString());
21
16
  };
22
- const santizedInput = (numberString) => (numberString.match(ACCEPT_INPUT) || []).join("");
23
- const getButtonIcon = (type) => type === stepperDirection.INCREMENT ? "triangle-up" : "triangle-down";
17
+ const sanitizedInput = (numberString) => (numberString.match(ACCEPT_INPUT) || []).join("");
24
18
  const useStepperInput = (props, inputRef) => {
25
19
  const {
26
20
  block = 10,
27
21
  decimalPlaces = 0,
28
22
  defaultValue = 0,
29
- liveValue,
23
+ id: idProp,
30
24
  max = Number.MAX_SAFE_INTEGER,
31
25
  min = Number.MIN_SAFE_INTEGER,
32
26
  onChange,
33
27
  step = 1,
34
- value,
35
- InputProps: inputPropsProp = {}
28
+ value
36
29
  } = props;
37
30
  const [currentValue, setCurrentValue, isControlled] = useControlled({
38
31
  controlled: value,
39
32
  default: toFixedDecimalPlaces(defaultValue, decimalPlaces),
40
33
  name: "stepper-input"
41
34
  });
42
- const inputId = useId(inputPropsProp.id);
35
+ const inputId = useId(idProp);
43
36
  const isOutOfRange = () => {
44
37
  if (currentValue === void 0)
45
38
  return true;
@@ -55,18 +48,6 @@ const useStepperInput = (props, inputRef) => {
55
48
  return true;
56
49
  return toFloat(currentValue) <= min || min === 0 && currentValue === "";
57
50
  };
58
- const valuesHaveDiverged = () => {
59
- if (liveValue === void 0 || currentValue === void 0)
60
- return false;
61
- return toFloat(toFixedDecimalPlaces(liveValue, decimalPlaces)) !== toFloat(currentValue);
62
- };
63
- const { setHasAnnounced } = useDynamicAriaLabel(
64
- ", value out of date",
65
- liveValue !== void 0,
66
- inputRef,
67
- currentValue,
68
- valuesHaveDiverged
69
- );
70
51
  const decrement = () => {
71
52
  if (currentValue === void 0 || isAtMin())
72
53
  return;
@@ -100,6 +81,8 @@ const useStepperInput = (props, inputRef) => {
100
81
  setNextValue(nextValue);
101
82
  };
102
83
  const setNextValue = (modifiedValue) => {
84
+ if (props.readOnly)
85
+ return;
103
86
  let nextValue = modifiedValue;
104
87
  if (nextValue < min)
105
88
  nextValue = min;
@@ -133,16 +116,13 @@ const useStepperInput = (props, inputRef) => {
133
116
  onChange(roundedValue);
134
117
  }
135
118
  };
136
- const handleInputFocus = () => {
137
- setHasAnnounced(false);
138
- };
139
119
  const handleInputChange = (event) => {
140
- const changedValue = event.currentTarget.value;
120
+ const changedValue = event.target.value;
141
121
  if (!isControlled) {
142
- setCurrentValue(santizedInput(changedValue));
122
+ setCurrentValue(sanitizedInput(changedValue));
143
123
  }
144
124
  if (onChange) {
145
- onChange(santizedInput(changedValue));
125
+ onChange(sanitizedInput(changedValue));
146
126
  }
147
127
  };
148
128
  const handleInputKeyDown = (event) => {
@@ -155,40 +135,21 @@ const useStepperInput = (props, inputRef) => {
155
135
  event.key === "PageUp" ? incrementSpinnerBlock() : decrementSpinnerBlock();
156
136
  }
157
137
  };
158
- const handleButtonMouseDown = (event, type = stepperDirection.INCREMENT) => {
138
+ const handleButtonMouseDown = (event, direction) => {
159
139
  if (event.nativeEvent.button !== 0)
160
140
  return;
161
- type === stepperDirection.INCREMENT ? incrementSpinner() : decrementSpinner();
141
+ direction === "increment" ? incrementSpinner() : decrementSpinner();
162
142
  };
163
143
  const handleButtonMouseUp = () => {
164
144
  var _a;
165
145
  return (_a = inputRef.current) == null ? void 0 : _a.focus();
166
146
  };
167
- const refreshCurrentValue = () => {
168
- var _a;
169
- const refreshedcurrentValue = liveValue !== void 0 ? liveValue : defaultValue;
170
- if (refreshedcurrentValue === void 0)
171
- return;
172
- setCurrentValue(
173
- toFixedDecimalPlaces(toFloat(refreshedcurrentValue), decimalPlaces)
174
- );
175
- (_a = inputRef.current) == null ? void 0 : _a.focus();
176
- if (onChange) {
177
- onChange(
178
- toFixedDecimalPlaces(toFloat(refreshedcurrentValue), decimalPlaces)
179
- );
180
- }
181
- };
182
- const getButtonProps = (type = stepperDirection.INCREMENT, buttonPropsProp = {}) => ({
147
+ const getButtonProps = (direction) => ({
183
148
  "aria-hidden": true,
184
- "data-testid": `${type}-button`,
149
+ disabled: props.disabled || (direction === "increment" ? isAtMax() : isAtMin()),
185
150
  tabIndex: -1,
186
- ...buttonPropsProp,
187
- onMouseDown: callAll(
188
- (event) => handleButtonMouseDown(event, type),
189
- buttonPropsProp.onMouseDown
190
- ),
191
- onMouseUp: callAll(() => handleButtonMouseUp(), buttonPropsProp.onMouseUp)
151
+ onMouseDown: (event) => handleButtonMouseDown(event, direction),
152
+ onMouseUp: handleButtonMouseUp
192
153
  });
193
154
  const getInputProps = (inputProps = {}) => {
194
155
  if (currentValue === void 0)
@@ -208,22 +169,17 @@ const useStepperInput = (props, inputRef) => {
208
169
  },
209
170
  onBlur: callAll(inputProps.onBlur, handleInputBlur),
210
171
  onChange: callAll(inputProps.onChange, handleInputChange),
211
- onFocus: callAll(inputProps.onFocus, handleInputFocus),
212
- onKeyDown: callAll(inputProps.onKeyPress, handleInputKeyDown),
172
+ onFocus: inputProps.onFocus,
173
+ onKeyDown: callAll(inputProps.onKeyDown, handleInputKeyDown),
174
+ textAlign: inputProps.textAlign,
213
175
  value: String(currentValue)
214
176
  };
215
177
  };
216
178
  return {
217
179
  decrementButtonDown: arrowDownButtonDown || pgDnButtonDown,
218
- getButtonIcon,
219
180
  getButtonProps,
220
181
  getInputProps,
221
- incrementButtonDown: arrowUpButtonDown || pgUpButtonDown,
222
- isAtMax,
223
- isAtMin,
224
- refreshCurrentValue,
225
- stepperDirection,
226
- valuesHaveDiverged
182
+ incrementButtonDown: arrowUpButtonDown || pgUpButtonDown
227
183
  };
228
184
  };
229
185
 
@@ -1 +1 @@
1
- {"version":3,"file":"useStepperInput.js","sources":["../src/stepper-input/useStepperInput.ts"],"sourcesContent":["import { KeyboardEvent, MouseEvent, MutableRefObject } from \"react\";\nimport { ButtonProps, useControlled, useId } from \"@salt-ds/core\";\nimport { InputLegacyProps as InputProps } from \"../input-legacy\";\nimport { useDynamicAriaLabel } from \"./internal/useDynamicAriaLabel\";\nimport { useSpinner } from \"./internal/useSpinner\";\nimport { StepperInputProps } from \"./StepperInput\";\n\ntype Direction = \"decrement\" | \"increment\";\n\nconst stepperDirection = {\n INCREMENT: \"increment\" as Direction,\n DECREMENT: \"decrement\" as Direction,\n};\n\n// The input should only accept numbers, decimal points, and plus/minus symbols\nconst ACCEPT_INPUT = /^[-+]?[0-9]*\\.?([0-9]+)?/g;\n\nconst callAll =\n (...fns: any[]) =>\n (...args: any[]) =>\n fns.forEach((fn) => fn && fn(...args));\n\nconst toFixedDecimalPlaces = (inputNumber: number, decimalPlaces: number) =>\n inputNumber.toFixed(decimalPlaces);\n\nconst isAllowedNonNumeric = (inputCharacter: number | string) => {\n if (typeof inputCharacter === \"number\") return;\n return (\n (\"-+\".includes(inputCharacter) && inputCharacter.length === 1) ||\n inputCharacter === \"\"\n );\n};\n\nconst toFloat = (inputValue: number | string) => {\n // Plus, minus, and empty characters are treated as 0\n if (isAllowedNonNumeric(inputValue)) return 0;\n return parseFloat(inputValue.toString());\n};\n\nconst santizedInput = (numberString: string) =>\n (numberString.match(ACCEPT_INPUT) || []).join(\"\");\n\nconst getButtonIcon = (type: Direction) =>\n type === stepperDirection.INCREMENT ? \"triangle-up\" : \"triangle-down\";\n\nexport const useStepperInput = (\n props: StepperInputProps,\n inputRef: MutableRefObject<HTMLInputElement | null>\n) => {\n const {\n block = 10,\n decimalPlaces = 0,\n defaultValue = 0,\n liveValue,\n max = Number.MAX_SAFE_INTEGER,\n min = Number.MIN_SAFE_INTEGER,\n onChange,\n step = 1,\n value,\n InputProps: inputPropsProp = {},\n } = props;\n\n const [currentValue, setCurrentValue, isControlled] = useControlled({\n controlled: value,\n default: toFixedDecimalPlaces(defaultValue, decimalPlaces),\n name: \"stepper-input\",\n });\n const inputId = useId(inputPropsProp.id);\n\n const isOutOfRange = () => {\n if (currentValue === undefined) return true;\n return toFloat(currentValue) > max || toFloat(currentValue) < min;\n };\n\n const isAtMax = () => {\n if (currentValue === undefined) return true;\n return toFloat(currentValue) >= max || (max === 0 && currentValue === \"\");\n };\n\n const isAtMin = () => {\n if (currentValue === undefined) return true;\n return toFloat(currentValue) <= min || (min === 0 && currentValue === \"\");\n };\n\n const valuesHaveDiverged = () => {\n if (liveValue === undefined || currentValue === undefined) return false;\n return (\n toFloat(toFixedDecimalPlaces(liveValue, decimalPlaces)) !==\n toFloat(currentValue)\n );\n };\n\n const { setHasAnnounced } = useDynamicAriaLabel(\n \", value out of date\",\n liveValue !== undefined,\n inputRef,\n currentValue,\n valuesHaveDiverged\n );\n\n const decrement = () => {\n if (currentValue === undefined || isAtMin()) return;\n let nextValue = currentValue === \"\" ? -step : toFloat(currentValue) - step;\n\n // Set value to `max` if it's currently out of range\n if (max !== undefined && isOutOfRange()) nextValue = max;\n\n setNextValue(nextValue);\n };\n\n const decrementBlock = () => {\n if (currentValue === undefined || isAtMin()) return;\n let nextValue =\n currentValue === \"\"\n ? block * -step\n : toFloat(currentValue) - step * block;\n\n // Set value to `max` if it's currently out of range\n if (max !== undefined && isOutOfRange()) nextValue = max;\n\n setNextValue(nextValue);\n };\n\n const increment = () => {\n if (currentValue === undefined || isAtMax()) return;\n let nextValue = currentValue === \"\" ? step : toFloat(currentValue) + step;\n\n // Set value to `min` if it's currently out of range\n if (min !== undefined && isOutOfRange()) nextValue = min;\n\n setNextValue(nextValue);\n };\n\n const incrementBlock = () => {\n if (currentValue === undefined || isAtMax()) return;\n let nextValue =\n currentValue === \"\" ? block * step : toFloat(currentValue) + step * block;\n\n // Set value to `min` if it's currently out of range\n if (min !== undefined && isOutOfRange()) nextValue = min;\n\n setNextValue(nextValue);\n };\n\n const setNextValue = (modifiedValue: number) => {\n let nextValue = modifiedValue;\n if (nextValue < min) nextValue = min;\n if (nextValue > max) nextValue = max;\n\n const roundedValue = toFixedDecimalPlaces(nextValue, decimalPlaces);\n if (isNaN(toFloat(roundedValue))) return;\n\n if (!isControlled) {\n setCurrentValue(roundedValue);\n }\n\n if (onChange) {\n onChange(roundedValue);\n }\n };\n\n const { activate: decrementSpinnerBlock, buttonDown: pgDnButtonDown } =\n useSpinner(decrementBlock, isAtMin());\n\n const { activate: decrementSpinner, buttonDown: arrowDownButtonDown } =\n useSpinner(decrement, isAtMin());\n\n const { activate: incrementSpinnerBlock, buttonDown: pgUpButtonDown } =\n useSpinner(incrementBlock, isAtMax());\n\n const { activate: incrementSpinner, buttonDown: arrowUpButtonDown } =\n useSpinner(increment, isAtMax());\n\n const handleInputBlur = () => {\n if (currentValue === undefined) return;\n\n const roundedValue = toFixedDecimalPlaces(\n toFloat(currentValue),\n decimalPlaces\n );\n\n if (\n currentValue !== \"\" &&\n !isAllowedNonNumeric(currentValue) &&\n !isControlled\n ) {\n setCurrentValue(roundedValue);\n }\n\n if (onChange) {\n onChange(roundedValue);\n }\n };\n\n const handleInputFocus = () => {\n setHasAnnounced(false);\n };\n\n const handleInputChange = (event: KeyboardEvent) => {\n const changedValue = (event.currentTarget as HTMLInputElement).value;\n\n if (!isControlled) {\n setCurrentValue(santizedInput(changedValue));\n }\n\n if (onChange) {\n onChange(santizedInput(changedValue));\n }\n };\n\n const handleInputKeyDown = (event: KeyboardEvent) => {\n if ([\"ArrowUp\", \"ArrowDown\"].includes(event.key)) {\n event.preventDefault();\n event.key === \"ArrowUp\" ? incrementSpinner() : decrementSpinner();\n }\n if ([\"PageUp\", \"PageDown\"].includes(event.key)) {\n event.preventDefault();\n event.key === \"PageUp\"\n ? incrementSpinnerBlock()\n : decrementSpinnerBlock();\n }\n };\n\n const handleButtonMouseDown = (\n event: MouseEvent<HTMLButtonElement>,\n type: Direction = stepperDirection.INCREMENT\n ) => {\n if (event.nativeEvent.button !== 0) return;\n type === stepperDirection.INCREMENT\n ? incrementSpinner()\n : decrementSpinner();\n };\n\n const handleButtonMouseUp = () => inputRef.current?.focus();\n\n const refreshCurrentValue = () => {\n const refreshedcurrentValue =\n liveValue !== undefined ? liveValue : defaultValue;\n if (refreshedcurrentValue === undefined) return;\n\n setCurrentValue(\n toFixedDecimalPlaces(toFloat(refreshedcurrentValue), decimalPlaces)\n );\n\n inputRef.current?.focus();\n\n if (onChange) {\n onChange(\n toFixedDecimalPlaces(toFloat(refreshedcurrentValue), decimalPlaces)\n );\n }\n };\n\n const getButtonProps = (\n type: Direction = stepperDirection.INCREMENT,\n buttonPropsProp: ButtonProps = {}\n ) => ({\n \"aria-hidden\": true,\n \"data-testid\": `${type}-button`,\n tabIndex: -1,\n ...buttonPropsProp,\n onMouseDown: callAll(\n (event: MouseEvent<HTMLButtonElement>) =>\n handleButtonMouseDown(event, type),\n buttonPropsProp.onMouseDown\n ),\n onMouseUp: callAll(() => handleButtonMouseUp(), buttonPropsProp.onMouseUp),\n });\n\n const getInputProps = (\n inputProps: InputProps = {}\n ): InputProps | undefined => {\n if (currentValue === undefined) return undefined;\n return {\n ...inputProps,\n inputProps: {\n role: \"spinbutton\",\n \"aria-invalid\": isOutOfRange(),\n \"aria-valuemax\": toFloat(toFixedDecimalPlaces(max, decimalPlaces)),\n \"aria-valuemin\": toFloat(toFixedDecimalPlaces(min, decimalPlaces)),\n \"aria-valuenow\": toFloat(\n toFixedDecimalPlaces(toFloat(currentValue), decimalPlaces)\n ),\n id: inputId,\n ...inputProps.inputProps,\n },\n onBlur: callAll(inputProps.onBlur, handleInputBlur),\n onChange: callAll(inputProps.onChange, handleInputChange),\n onFocus: callAll(inputProps.onFocus, handleInputFocus),\n onKeyDown: callAll(inputProps.onKeyPress, handleInputKeyDown),\n value: String(currentValue),\n };\n };\n\n return {\n decrementButtonDown: arrowDownButtonDown || pgDnButtonDown,\n getButtonIcon,\n getButtonProps,\n getInputProps,\n incrementButtonDown: arrowUpButtonDown || pgUpButtonDown,\n isAtMax,\n isAtMin,\n refreshCurrentValue,\n stepperDirection,\n valuesHaveDiverged,\n };\n};\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"useStepperInput.js","sources":["../src/stepper-input/useStepperInput.ts"],"sourcesContent":["import {\n ChangeEvent,\n KeyboardEvent,\n MouseEvent,\n MutableRefObject,\n} from \"react\";\nimport { useControlled, useId, InputProps } from \"@salt-ds/core\";\nimport { useSpinner } from \"./internal/useSpinner\";\nimport { StepperInputProps } from \"./StepperInput\";\n\n// The input should only accept numbers, decimal points, and plus/minus symbols\nconst ACCEPT_INPUT = /^[-+]?[0-9]*\\.?([0-9]+)?/g;\n\nconst callAll =\n (...fns: any[]) =>\n (...args: any[]) =>\n fns.forEach((fn) => fn && fn(...args));\n\nconst toFixedDecimalPlaces = (inputNumber: number, decimalPlaces: number) =>\n inputNumber.toFixed(decimalPlaces);\n\nconst isAllowedNonNumeric = (inputCharacter: number | string) => {\n if (typeof inputCharacter === \"number\") return;\n return (\n (\"-+\".includes(inputCharacter) && inputCharacter.length === 1) ||\n inputCharacter === \"\"\n );\n};\n\nconst toFloat = (inputValue: number | string) => {\n // Plus, minus, and empty characters are treated as 0\n if (isAllowedNonNumeric(inputValue)) return 0;\n return parseFloat(inputValue.toString());\n};\n\nconst sanitizedInput = (numberString: string) =>\n (numberString.match(ACCEPT_INPUT) || []).join(\"\");\n\nexport const useStepperInput = (\n props: StepperInputProps,\n inputRef: MutableRefObject<HTMLInputElement | null>\n) => {\n const {\n block = 10,\n decimalPlaces = 0,\n defaultValue = 0,\n id: idProp,\n max = Number.MAX_SAFE_INTEGER,\n min = Number.MIN_SAFE_INTEGER,\n onChange,\n step = 1,\n value,\n } = props;\n\n const [currentValue, setCurrentValue, isControlled] = useControlled({\n controlled: value,\n default: toFixedDecimalPlaces(defaultValue, decimalPlaces),\n name: \"stepper-input\",\n });\n const inputId = useId(idProp);\n\n const isOutOfRange = () => {\n if (currentValue === undefined) return true;\n return toFloat(currentValue) > max || toFloat(currentValue) < min;\n };\n\n const isAtMax = () => {\n if (currentValue === undefined) return true;\n return toFloat(currentValue) >= max || (max === 0 && currentValue === \"\");\n };\n\n const isAtMin = () => {\n if (currentValue === undefined) return true;\n return toFloat(currentValue) <= min || (min === 0 && currentValue === \"\");\n };\n\n const decrement = () => {\n if (currentValue === undefined || isAtMin()) return;\n let nextValue = currentValue === \"\" ? -step : toFloat(currentValue) - step;\n\n // Set value to `max` if it's currently out of range\n if (max !== undefined && isOutOfRange()) nextValue = max;\n\n setNextValue(nextValue);\n };\n\n const decrementBlock = () => {\n if (currentValue === undefined || isAtMin()) return;\n let nextValue =\n currentValue === \"\"\n ? block * -step\n : toFloat(currentValue) - step * block;\n\n // Set value to `max` if it's currently out of range\n if (max !== undefined && isOutOfRange()) nextValue = max;\n\n setNextValue(nextValue);\n };\n\n const increment = () => {\n if (currentValue === undefined || isAtMax()) return;\n let nextValue = currentValue === \"\" ? step : toFloat(currentValue) + step;\n\n // Set value to `min` if it's currently out of range\n if (min !== undefined && isOutOfRange()) nextValue = min;\n\n setNextValue(nextValue);\n };\n\n const incrementBlock = () => {\n if (currentValue === undefined || isAtMax()) return;\n let nextValue =\n currentValue === \"\" ? block * step : toFloat(currentValue) + step * block;\n\n // Set value to `min` if it's currently out of range\n if (min !== undefined && isOutOfRange()) nextValue = min;\n\n setNextValue(nextValue);\n };\n\n const setNextValue = (modifiedValue: number) => {\n if (props.readOnly) return;\n let nextValue = modifiedValue;\n if (nextValue < min) nextValue = min;\n if (nextValue > max) nextValue = max;\n\n const roundedValue = toFixedDecimalPlaces(nextValue, decimalPlaces);\n if (isNaN(toFloat(roundedValue))) return;\n\n if (!isControlled) {\n setCurrentValue(roundedValue);\n }\n\n if (onChange) {\n onChange(roundedValue);\n }\n };\n\n const { activate: decrementSpinnerBlock, buttonDown: pgDnButtonDown } =\n useSpinner(decrementBlock, isAtMin());\n\n const { activate: decrementSpinner, buttonDown: arrowDownButtonDown } =\n useSpinner(decrement, isAtMin());\n\n const { activate: incrementSpinnerBlock, buttonDown: pgUpButtonDown } =\n useSpinner(incrementBlock, isAtMax());\n\n const { activate: incrementSpinner, buttonDown: arrowUpButtonDown } =\n useSpinner(increment, isAtMax());\n\n const handleInputBlur = () => {\n if (currentValue === undefined) return;\n\n const roundedValue = toFixedDecimalPlaces(\n toFloat(currentValue),\n decimalPlaces\n );\n\n if (\n currentValue !== \"\" &&\n !isAllowedNonNumeric(currentValue) &&\n !isControlled\n ) {\n setCurrentValue(roundedValue);\n }\n\n if (onChange) {\n onChange(roundedValue);\n }\n };\n\n const handleInputChange = (event: ChangeEvent<HTMLInputElement>) => {\n const changedValue = event.target.value;\n\n if (!isControlled) {\n setCurrentValue(sanitizedInput(changedValue));\n }\n\n if (onChange) {\n onChange(sanitizedInput(changedValue));\n }\n };\n\n const handleInputKeyDown = (event: KeyboardEvent) => {\n if ([\"ArrowUp\", \"ArrowDown\"].includes(event.key)) {\n event.preventDefault();\n event.key === \"ArrowUp\" ? incrementSpinner() : decrementSpinner();\n }\n if ([\"PageUp\", \"PageDown\"].includes(event.key)) {\n event.preventDefault();\n event.key === \"PageUp\"\n ? incrementSpinnerBlock()\n : decrementSpinnerBlock();\n }\n };\n\n const handleButtonMouseDown = (\n event: MouseEvent<HTMLButtonElement>,\n direction: string\n ) => {\n if (event.nativeEvent.button !== 0) return;\n direction === \"increment\" ? incrementSpinner() : decrementSpinner();\n };\n\n const handleButtonMouseUp = () => inputRef.current?.focus();\n\n const getButtonProps = (direction: string) => ({\n \"aria-hidden\": true,\n disabled:\n props.disabled || (direction === \"increment\" ? isAtMax() : isAtMin()),\n tabIndex: -1,\n onMouseDown: (event: MouseEvent<HTMLButtonElement>) =>\n handleButtonMouseDown(event, direction),\n onMouseUp: handleButtonMouseUp,\n });\n\n const getInputProps = (\n inputProps: InputProps = {}\n ): InputProps | undefined => {\n if (currentValue === undefined) return undefined;\n return {\n ...inputProps,\n inputProps: {\n role: \"spinbutton\",\n \"aria-invalid\": isOutOfRange(),\n \"aria-valuemax\": toFloat(toFixedDecimalPlaces(max, decimalPlaces)),\n \"aria-valuemin\": toFloat(toFixedDecimalPlaces(min, decimalPlaces)),\n \"aria-valuenow\": toFloat(\n toFixedDecimalPlaces(toFloat(currentValue), decimalPlaces)\n ),\n id: inputId,\n ...inputProps.inputProps,\n },\n onBlur: callAll(inputProps.onBlur, handleInputBlur),\n onChange: callAll(inputProps.onChange, handleInputChange),\n onFocus: inputProps.onFocus,\n onKeyDown: callAll(inputProps.onKeyDown, handleInputKeyDown),\n textAlign: inputProps.textAlign,\n value: String(currentValue),\n };\n };\n\n return {\n decrementButtonDown: arrowDownButtonDown || pgDnButtonDown,\n getButtonProps,\n getInputProps,\n incrementButtonDown: arrowUpButtonDown || pgUpButtonDown,\n };\n};\n"],"names":[],"mappings":"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"}