@react-aria/spinbutton 3.7.0 → 3.7.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.
@@ -1 +1 @@
1
- {"mappings":";;AAsBA,gCAAiC,SAAQ,SAAS,EAAE,WAAW,MAAM,CAAC,EAAE,UAAU,MAAM,CAAC,EAAE,eAAe,MAAM,CAAC;IAC/G,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,IAAI,CAAC;IACzB,eAAe,CAAC,EAAE,MAAM,IAAI,CAAC;IAC7B,WAAW,CAAC,EAAE,MAAM,IAAI,CAAC;IACzB,eAAe,CAAC,EAAE,MAAM,IAAI,CAAC;IAC7B,gBAAgB,CAAC,EAAE,MAAM,IAAI,CAAC;IAC9B,gBAAgB,CAAC,EAAE,MAAM,IAAI,CAAA;CAC9B;AAED;IACE,eAAe,EAAE,aAAa,CAAC;IAC/B,oBAAoB,EAAE,eAAe,CAAC;IACtC,oBAAoB,EAAE,eAAe,CAAA;CACtC;AAED,8BACE,KAAK,EAAE,eAAe,GACrB,cAAc,CA0QhB","sources":["packages/@react-aria/spinbutton/src/packages/@react-aria/spinbutton/src/useSpinButton.ts","packages/@react-aria/spinbutton/src/packages/@react-aria/spinbutton/src/index.ts","packages/@react-aria/spinbutton/src/index.ts"],"sourcesContent":[null,null,"/*\n * Copyright 2020 Adobe. All rights reserved.\n * This file is licensed to you under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License. You may obtain a copy\n * of the License at http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under\n * the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\n * OF ANY KIND, either express or implied. See the License for the specific language\n * governing permissions and limitations under the License.\n */\nexport type {SpinButtonProps, SpinbuttonAria} from './useSpinButton';\nexport {useSpinButton} from './useSpinButton';\n"],"names":[],"version":3,"file":"types.d.ts.map"}
1
+ {"mappings":";;AAwBA,gCAAiC,SAAQ,SAAS,EAAE,WAAW,MAAM,CAAC,EAAE,UAAU,MAAM,CAAC,EAAE,eAAe,MAAM,CAAC;IAC/G,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,IAAI,CAAC;IACzB,eAAe,CAAC,EAAE,MAAM,IAAI,CAAC;IAC7B,WAAW,CAAC,EAAE,MAAM,IAAI,CAAC;IACzB,eAAe,CAAC,EAAE,MAAM,IAAI,CAAC;IAC7B,gBAAgB,CAAC,EAAE,MAAM,IAAI,CAAC;IAC9B,gBAAgB,CAAC,EAAE,MAAM,IAAI,CAAA;CAC9B;AAED;IACE,eAAe,EAAE,aAAa,CAAC;IAC/B,oBAAoB,EAAE,eAAe,CAAC;IACtC,oBAAoB,EAAE,eAAe,CAAA;CACtC;AAED,8BACE,KAAK,EAAE,eAAe,GACrB,cAAc,CA+PhB","sources":["packages/@react-aria/spinbutton/src/packages/@react-aria/spinbutton/src/useSpinButton.ts","packages/@react-aria/spinbutton/src/packages/@react-aria/spinbutton/src/index.ts","packages/@react-aria/spinbutton/src/index.ts"],"sourcesContent":[null,null,"/*\n * Copyright 2020 Adobe. All rights reserved.\n * This file is licensed to you under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License. You may obtain a copy\n * of the License at http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under\n * the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\n * OF ANY KIND, either express or implied. See the License for the specific language\n * governing permissions and limitations under the License.\n */\nexport type {SpinButtonProps, SpinbuttonAria} from './useSpinButton';\nexport {useSpinButton} from './useSpinButton';\n"],"names":[],"version":3,"file":"types.d.ts.map"}
@@ -29,6 +29,7 @@ $parcel$export(module.exports, "useSpinButton", () => $37bbd4c129023f61$export$e
29
29
 
30
30
 
31
31
 
32
+ const $37bbd4c129023f61$var$noop = ()=>{};
32
33
  function $37bbd4c129023f61$export$e908e06f4b8e3402(props) {
33
34
  const _async = (0, $2pZbw$react.useRef)(undefined);
34
35
  let { value: value, textValue: textValue, minValue: minValue, maxValue: maxValue, isDisabled: isDisabled, isReadOnly: isReadOnly, isRequired: isRequired, onIncrement: onIncrement, onIncrementPage: onIncrementPage, onDecrement: onDecrement, onDecrementPage: onDecrementPage, onDecrementToMin: onDecrementToMin, onIncrementToMax: onIncrementToMax } = props;
@@ -115,23 +116,31 @@ function $37bbd4c129023f61$export$e908e06f4b8e3402(props) {
115
116
  }, [
116
117
  clearAsync
117
118
  ]);
118
- const onIncrementPressStart = (0, $2pZbw$reactariautils.useEffectEvent)((initialStepDelay)=>{
119
+ const onIncrementEvent = (0, $2pZbw$reactariautils.useEffectEvent)(onIncrement !== null && onIncrement !== void 0 ? onIncrement : $37bbd4c129023f61$var$noop);
120
+ const onDecrementEvent = (0, $2pZbw$reactariautils.useEffectEvent)(onDecrement !== null && onDecrement !== void 0 ? onDecrement : $37bbd4c129023f61$var$noop);
121
+ const stepUpEvent = (0, $2pZbw$reactariautils.useEffectEvent)(()=>{
122
+ if (maxValue === undefined || isNaN(maxValue) || value === undefined || isNaN(value) || value < maxValue) {
123
+ onIncrementEvent();
124
+ onIncrementPressStartEvent(60);
125
+ }
126
+ });
127
+ const onIncrementPressStartEvent = (0, $2pZbw$reactariautils.useEffectEvent)((initialStepDelay)=>{
119
128
  clearAsyncEvent();
120
129
  isSpinning.current = true;
121
- onIncrement === null || onIncrement === void 0 ? void 0 : onIncrement();
122
130
  // Start spinning after initial delay
123
- _async.current = window.setTimeout(()=>{
124
- if (maxValue === undefined || isNaN(maxValue) || value === undefined || isNaN(value) || value < maxValue) onIncrementPressStart(60);
125
- }, initialStepDelay);
131
+ _async.current = window.setTimeout(stepUpEvent, initialStepDelay);
132
+ });
133
+ const stepDownEvent = (0, $2pZbw$reactariautils.useEffectEvent)(()=>{
134
+ if (minValue === undefined || isNaN(minValue) || value === undefined || isNaN(value) || value > minValue) {
135
+ onDecrementEvent();
136
+ onDecrementPressStartEvent(60);
137
+ }
126
138
  });
127
- const onDecrementPressStart = (0, $2pZbw$reactariautils.useEffectEvent)((initialStepDelay)=>{
139
+ const onDecrementPressStartEvent = (0, $2pZbw$reactariautils.useEffectEvent)((initialStepDelay)=>{
128
140
  clearAsyncEvent();
129
141
  isSpinning.current = true;
130
- onDecrement === null || onDecrement === void 0 ? void 0 : onDecrement();
131
142
  // Start spinning after initial delay
132
- _async.current = window.setTimeout(()=>{
133
- if (minValue === undefined || isNaN(minValue) || value === undefined || isNaN(value) || value > minValue) onDecrementPressStart(60);
134
- }, initialStepDelay);
143
+ _async.current = window.setTimeout(stepDownEvent, initialStepDelay);
135
144
  });
136
145
  let cancelContextMenu = (e)=>{
137
146
  e.preventDefault();
@@ -144,15 +153,15 @@ function $37bbd4c129023f61$export$e908e06f4b8e3402(props) {
144
153
  let isUp = (0, $2pZbw$react.useRef)(false);
145
154
  let [isIncrementPressed, setIsIncrementPressed] = (0, $2pZbw$react.useState)(null);
146
155
  (0, $2pZbw$react.useEffect)(()=>{
147
- if (isIncrementPressed === 'touch') onIncrementPressStart(60);
148
- else if (isIncrementPressed) onIncrementPressStart(400);
156
+ if (isIncrementPressed === 'touch') onIncrementPressStartEvent(600);
157
+ else if (isIncrementPressed) onIncrementPressStartEvent(400);
149
158
  }, [
150
159
  isIncrementPressed
151
160
  ]);
152
161
  let [isDecrementPressed, setIsDecrementPressed] = (0, $2pZbw$react.useState)(null);
153
162
  (0, $2pZbw$react.useEffect)(()=>{
154
- if (isDecrementPressed === 'touch') onDecrementPressStart(60);
155
- else if (isDecrementPressed) onDecrementPressStart(400);
163
+ if (isDecrementPressed === 'touch') onDecrementPressStartEvent(600);
164
+ else if (isDecrementPressed) onDecrementPressStartEvent(400);
156
165
  }, [
157
166
  isDecrementPressed
158
167
  ]);
@@ -172,32 +181,32 @@ function $37bbd4c129023f61$export$e908e06f4b8e3402(props) {
172
181
  },
173
182
  incrementButtonProps: {
174
183
  onPressStart: (e)=>{
175
- if (e.pointerType !== 'touch') setIsIncrementPressed('mouse');
176
- else {
177
- if (_async.current) clearAsync();
184
+ clearAsync();
185
+ if (e.pointerType !== 'touch') {
186
+ onIncrement === null || onIncrement === void 0 ? void 0 : onIncrement();
187
+ setIsIncrementPressed('mouse');
188
+ } else {
178
189
  addGlobalListener(window, 'pointercancel', onPointerCancel, {
179
190
  capture: true
180
191
  });
181
192
  isUp.current = false;
182
193
  // For touch users, don't trigger a decrement on press start, we'll wait for the press end to trigger it if
183
194
  // the control isn't spinning.
184
- _async.current = window.setTimeout(()=>{
185
- setIsIncrementPressed('touch');
186
- }, 600);
195
+ setIsIncrementPressed('touch');
187
196
  }
188
197
  addGlobalListener(window, 'contextmenu', cancelContextMenu);
189
198
  },
190
199
  onPressUp: (e)=>{
191
- if (e.pointerType === 'touch') isUp.current = true;
192
200
  clearAsync();
201
+ if (e.pointerType === 'touch') isUp.current = true;
193
202
  removeAllGlobalListeners();
194
203
  setIsIncrementPressed(null);
195
204
  },
196
205
  onPressEnd: (e)=>{
206
+ clearAsync();
197
207
  if (e.pointerType === 'touch') {
198
208
  if (!isSpinning.current && isUp.current) onIncrement === null || onIncrement === void 0 ? void 0 : onIncrement();
199
209
  }
200
- clearAsync();
201
210
  isUp.current = false;
202
211
  setIsIncrementPressed(null);
203
212
  },
@@ -206,31 +215,31 @@ function $37bbd4c129023f61$export$e908e06f4b8e3402(props) {
206
215
  },
207
216
  decrementButtonProps: {
208
217
  onPressStart: (e)=>{
209
- if (e.pointerType !== 'touch') setIsDecrementPressed('mouse');
210
- else {
211
- if (_async.current) clearAsync();
218
+ clearAsync();
219
+ if (e.pointerType !== 'touch') {
220
+ onDecrement === null || onDecrement === void 0 ? void 0 : onDecrement();
221
+ setIsDecrementPressed('mouse');
222
+ } else {
212
223
  addGlobalListener(window, 'pointercancel', onPointerCancel, {
213
224
  capture: true
214
225
  });
215
226
  isUp.current = false;
216
227
  // For touch users, don't trigger a decrement on press start, we'll wait for the press end to trigger it if
217
228
  // the control isn't spinning.
218
- _async.current = window.setTimeout(()=>{
219
- setIsDecrementPressed('touch');
220
- }, 600);
229
+ setIsDecrementPressed('touch');
221
230
  }
222
231
  },
223
232
  onPressUp: (e)=>{
224
- if (e.pointerType === 'touch') isUp.current = true;
225
233
  clearAsync();
234
+ if (e.pointerType === 'touch') isUp.current = true;
226
235
  removeAllGlobalListeners();
227
236
  setIsDecrementPressed(null);
228
237
  },
229
238
  onPressEnd: (e)=>{
239
+ clearAsync();
230
240
  if (e.pointerType === 'touch') {
231
241
  if (!isSpinning.current && isUp.current) onDecrement === null || onDecrement === void 0 ? void 0 : onDecrement();
232
242
  }
233
- clearAsync();
234
243
  isUp.current = false;
235
244
  setIsDecrementPressed(null);
236
245
  },
@@ -1 +1 @@
1
- {"mappings":"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","sources":["packages/@react-aria/spinbutton/src/useSpinButton.ts"],"sourcesContent":["/*\n * Copyright 2020 Adobe. All rights reserved.\n * This file is licensed to you under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License. You may obtain a copy\n * of the License at http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under\n * the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\n * OF ANY KIND, either express or implied. See the License for the specific language\n * governing permissions and limitations under the License.\n */\n\nimport {announce, clearAnnouncer} from '@react-aria/live-announcer';\nimport {AriaButtonProps} from '@react-types/button';\nimport {DOMAttributes, InputBase, RangeInputBase, Validation, ValueBase} from '@react-types/shared';\n// @ts-ignore\nimport intlMessages from '../intl/*.json';\nimport {useCallback, useEffect, useRef, useState} from 'react';\nimport {useEffectEvent, useGlobalListeners} from '@react-aria/utils';\nimport {useLocalizedStringFormatter} from '@react-aria/i18n';\n\n\nexport interface SpinButtonProps extends InputBase, Validation<number>, ValueBase<number>, RangeInputBase<number> {\n textValue?: string,\n onIncrement?: () => void,\n onIncrementPage?: () => void,\n onDecrement?: () => void,\n onDecrementPage?: () => void,\n onDecrementToMin?: () => void,\n onIncrementToMax?: () => void\n}\n\nexport interface SpinbuttonAria {\n spinButtonProps: DOMAttributes,\n incrementButtonProps: AriaButtonProps,\n decrementButtonProps: AriaButtonProps\n}\n\nexport function useSpinButton(\n props: SpinButtonProps\n): SpinbuttonAria {\n const _async = useRef<number>(undefined);\n let {\n value,\n textValue,\n minValue,\n maxValue,\n isDisabled,\n isReadOnly,\n isRequired,\n onIncrement,\n onIncrementPage,\n onDecrement,\n onDecrementPage,\n onDecrementToMin,\n onIncrementToMax\n } = props;\n const stringFormatter = useLocalizedStringFormatter(intlMessages, '@react-aria/spinbutton');\n\n let isSpinning = useRef(false);\n const clearAsync = useCallback(() => {\n clearTimeout(_async.current);\n isSpinning.current = false;\n }, []);\n const clearAsyncEvent = useEffectEvent(() => {\n clearAsync();\n });\n\n useEffect(() => {\n return () => clearAsyncEvent();\n }, []);\n\n let onKeyDown = (e) => {\n if (e.ctrlKey || e.metaKey || e.shiftKey || e.altKey || isReadOnly || e.nativeEvent.isComposing) {\n return;\n }\n\n switch (e.key) {\n case 'PageUp':\n if (onIncrementPage) {\n e.preventDefault();\n onIncrementPage?.();\n break;\n }\n // fallthrough!\n case 'ArrowUp':\n case 'Up':\n if (onIncrement) {\n e.preventDefault();\n onIncrement?.();\n }\n break;\n case 'PageDown':\n if (onDecrementPage) {\n e.preventDefault();\n onDecrementPage?.();\n break;\n }\n // fallthrough\n case 'ArrowDown':\n case 'Down':\n if (onDecrement) {\n e.preventDefault();\n onDecrement?.();\n }\n break;\n case 'Home':\n if (onDecrementToMin) {\n e.preventDefault();\n onDecrementToMin?.();\n }\n break;\n case 'End':\n if (onIncrementToMax) {\n e.preventDefault();\n onIncrementToMax?.();\n }\n break;\n }\n };\n\n let isFocused = useRef(false);\n let onFocus = () => {\n isFocused.current = true;\n };\n\n let onBlur = () => {\n isFocused.current = false;\n };\n\n // Replace Unicode hyphen-minus (U+002D) with minus sign (U+2212).\n // This ensures that macOS VoiceOver announces it as \"minus\" even with other characters between the minus sign\n // and the number (e.g. currency symbol). Otherwise it announces nothing because it assumes the character is a hyphen.\n // In addition, replace the empty string with the word \"Empty\" so that iOS VoiceOver does not read \"50%\" for an empty field.\n let ariaTextValue = textValue === '' ? stringFormatter.format('Empty') : (textValue || `${value}`).replace('-', '\\u2212');\n\n useEffect(() => {\n if (isFocused.current) {\n clearAnnouncer('assertive');\n announce(ariaTextValue, 'assertive');\n }\n }, [ariaTextValue]);\n\n // For touch users, if they move their finger like they're scrolling, we don't want to trigger a spin.\n let onPointerCancel = useCallback(() => {\n clearAsync();\n }, [clearAsync]);\n\n const onIncrementPressStart = useEffectEvent(\n (initialStepDelay: number) => {\n clearAsyncEvent();\n isSpinning.current = true;\n onIncrement?.();\n // Start spinning after initial delay\n _async.current = window.setTimeout(\n () => {\n if ((maxValue === undefined || isNaN(maxValue)) || (value === undefined || isNaN(value)) || value < maxValue) {\n onIncrementPressStart(60);\n }\n },\n initialStepDelay\n );\n }\n );\n\n const onDecrementPressStart = useEffectEvent(\n (initialStepDelay: number) => {\n clearAsyncEvent();\n isSpinning.current = true;\n onDecrement?.();\n // Start spinning after initial delay\n _async.current = window.setTimeout(\n () => {\n if ((minValue === undefined || isNaN(minValue)) || (value === undefined || isNaN(value)) || value > minValue) {\n onDecrementPressStart(60);\n }\n },\n initialStepDelay\n );\n }\n );\n\n let cancelContextMenu = (e) => {\n e.preventDefault();\n };\n\n let {addGlobalListener, removeAllGlobalListeners} = useGlobalListeners();\n\n // Tracks in touch if the press end event was preceded by a press up.\n // If it wasn't, then we know the finger left the button while still in contact with the screen.\n // This means that the user is trying to scroll or interact in some way that shouldn't trigger\n // an increment or decrement.\n let isUp = useRef(false);\n\n let [isIncrementPressed, setIsIncrementPressed] = useState<'touch' | 'mouse' | null>(null);\n useEffect(() => {\n if (isIncrementPressed === 'touch') {\n onIncrementPressStart(60);\n } else if (isIncrementPressed) {\n onIncrementPressStart(400);\n }\n }, [isIncrementPressed]);\n\n let [isDecrementPressed, setIsDecrementPressed] = useState<'touch' | 'mouse' | null>(null);\n useEffect(() => {\n if (isDecrementPressed === 'touch') {\n onDecrementPressStart(60);\n } else if (isDecrementPressed) {\n onDecrementPressStart(400);\n }\n }, [isDecrementPressed]);\n\n return {\n spinButtonProps: {\n role: 'spinbutton',\n 'aria-valuenow': value !== undefined && !isNaN(value) ? value : undefined,\n 'aria-valuetext': ariaTextValue,\n 'aria-valuemin': minValue,\n 'aria-valuemax': maxValue,\n 'aria-disabled': isDisabled || undefined,\n 'aria-readonly': isReadOnly || undefined,\n 'aria-required': isRequired || undefined,\n onKeyDown,\n onFocus,\n onBlur\n },\n incrementButtonProps: {\n onPressStart: (e) => {\n if (e.pointerType !== 'touch') {\n setIsIncrementPressed('mouse');\n } else {\n if (_async.current) {\n clearAsync();\n }\n\n addGlobalListener(window, 'pointercancel', onPointerCancel, {capture: true});\n isUp.current = false;\n // For touch users, don't trigger a decrement on press start, we'll wait for the press end to trigger it if\n // the control isn't spinning.\n _async.current = window.setTimeout(() => {\n setIsIncrementPressed('touch');\n }, 600);\n }\n addGlobalListener(window, 'contextmenu', cancelContextMenu);\n },\n onPressUp: (e) => {\n if (e.pointerType === 'touch') {\n isUp.current = true;\n }\n clearAsync();\n removeAllGlobalListeners();\n setIsIncrementPressed(null);\n },\n onPressEnd: (e) => {\n if (e.pointerType === 'touch') {\n if (!isSpinning.current && isUp.current) {\n onIncrement?.();\n }\n }\n clearAsync();\n isUp.current = false;\n setIsIncrementPressed(null);\n },\n onFocus,\n onBlur\n },\n decrementButtonProps: {\n onPressStart: (e) => {\n if (e.pointerType !== 'touch') {\n setIsDecrementPressed('mouse');\n } else {\n if (_async.current) {\n clearAsync();\n }\n\n addGlobalListener(window, 'pointercancel', onPointerCancel, {capture: true});\n isUp.current = false;\n // For touch users, don't trigger a decrement on press start, we'll wait for the press end to trigger it if\n // the control isn't spinning.\n _async.current = window.setTimeout(() => {\n setIsDecrementPressed('touch');\n }, 600);\n }\n },\n onPressUp: (e) => {\n if (e.pointerType === 'touch') {\n isUp.current = true;\n }\n clearAsync();\n removeAllGlobalListeners();\n setIsDecrementPressed(null);\n },\n onPressEnd: (e) => {\n if (e.pointerType === 'touch') {\n if (!isSpinning.current && isUp.current) {\n onDecrement?.();\n }\n }\n clearAsync();\n isUp.current = false;\n setIsDecrementPressed(null);\n },\n onFocus,\n onBlur\n }\n };\n}\n"],"names":[],"version":3,"file":"useSpinButton.main.js.map"}
1
+ {"mappings":"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","sources":["packages/@react-aria/spinbutton/src/useSpinButton.ts"],"sourcesContent":["/*\n * Copyright 2020 Adobe. All rights reserved.\n * This file is licensed to you under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License. You may obtain a copy\n * of the License at http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under\n * the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\n * OF ANY KIND, either express or implied. See the License for the specific language\n * governing permissions and limitations under the License.\n */\n\nimport {announce, clearAnnouncer} from '@react-aria/live-announcer';\nimport {AriaButtonProps} from '@react-types/button';\nimport {DOMAttributes, InputBase, RangeInputBase, Validation, ValueBase} from '@react-types/shared';\n// @ts-ignore\nimport intlMessages from '../intl/*.json';\nimport {useCallback, useEffect, useRef, useState} from 'react';\nimport {useEffectEvent, useGlobalListeners} from '@react-aria/utils';\nimport {useLocalizedStringFormatter} from '@react-aria/i18n';\n\n\nconst noop = () => {};\n\nexport interface SpinButtonProps extends InputBase, Validation<number>, ValueBase<number>, RangeInputBase<number> {\n textValue?: string,\n onIncrement?: () => void,\n onIncrementPage?: () => void,\n onDecrement?: () => void,\n onDecrementPage?: () => void,\n onDecrementToMin?: () => void,\n onIncrementToMax?: () => void\n}\n\nexport interface SpinbuttonAria {\n spinButtonProps: DOMAttributes,\n incrementButtonProps: AriaButtonProps,\n decrementButtonProps: AriaButtonProps\n}\n\nexport function useSpinButton(\n props: SpinButtonProps\n): SpinbuttonAria {\n const _async = useRef<number>(undefined);\n let {\n value,\n textValue,\n minValue,\n maxValue,\n isDisabled,\n isReadOnly,\n isRequired,\n onIncrement,\n onIncrementPage,\n onDecrement,\n onDecrementPage,\n onDecrementToMin,\n onIncrementToMax\n } = props;\n const stringFormatter = useLocalizedStringFormatter(intlMessages, '@react-aria/spinbutton');\n\n let isSpinning = useRef(false);\n const clearAsync = useCallback(() => {\n clearTimeout(_async.current);\n isSpinning.current = false;\n }, []);\n const clearAsyncEvent = useEffectEvent(() => {\n clearAsync();\n });\n\n useEffect(() => {\n return () => clearAsyncEvent();\n }, []);\n\n let onKeyDown = (e) => {\n if (e.ctrlKey || e.metaKey || e.shiftKey || e.altKey || isReadOnly || e.nativeEvent.isComposing) {\n return;\n }\n\n switch (e.key) {\n case 'PageUp':\n if (onIncrementPage) {\n e.preventDefault();\n onIncrementPage?.();\n break;\n }\n // fallthrough!\n case 'ArrowUp':\n case 'Up':\n if (onIncrement) {\n e.preventDefault();\n onIncrement?.();\n }\n break;\n case 'PageDown':\n if (onDecrementPage) {\n e.preventDefault();\n onDecrementPage?.();\n break;\n }\n // fallthrough\n case 'ArrowDown':\n case 'Down':\n if (onDecrement) {\n e.preventDefault();\n onDecrement?.();\n }\n break;\n case 'Home':\n if (onDecrementToMin) {\n e.preventDefault();\n onDecrementToMin?.();\n }\n break;\n case 'End':\n if (onIncrementToMax) {\n e.preventDefault();\n onIncrementToMax?.();\n }\n break;\n }\n };\n\n let isFocused = useRef(false);\n let onFocus = () => {\n isFocused.current = true;\n };\n\n let onBlur = () => {\n isFocused.current = false;\n };\n\n // Replace Unicode hyphen-minus (U+002D) with minus sign (U+2212).\n // This ensures that macOS VoiceOver announces it as \"minus\" even with other characters between the minus sign\n // and the number (e.g. currency symbol). Otherwise it announces nothing because it assumes the character is a hyphen.\n // In addition, replace the empty string with the word \"Empty\" so that iOS VoiceOver does not read \"50%\" for an empty field.\n let ariaTextValue = textValue === '' ? stringFormatter.format('Empty') : (textValue || `${value}`).replace('-', '\\u2212');\n\n useEffect(() => {\n if (isFocused.current) {\n clearAnnouncer('assertive');\n announce(ariaTextValue, 'assertive');\n }\n }, [ariaTextValue]);\n\n // For touch users, if they move their finger like they're scrolling, we don't want to trigger a spin.\n let onPointerCancel = useCallback(() => {\n clearAsync();\n }, [clearAsync]);\n\n const onIncrementEvent = useEffectEvent(onIncrement ?? noop);\n const onDecrementEvent = useEffectEvent(onDecrement ?? noop);\n\n const stepUpEvent = useEffectEvent(() => {\n if (maxValue === undefined || isNaN(maxValue) || value === undefined || isNaN(value) || value < maxValue) {\n onIncrementEvent();\n onIncrementPressStartEvent(60);\n }\n });\n\n const onIncrementPressStartEvent = useEffectEvent((initialStepDelay: number) => {\n clearAsyncEvent();\n isSpinning.current = true;\n // Start spinning after initial delay\n _async.current = window.setTimeout(stepUpEvent, initialStepDelay);\n });\n\n const stepDownEvent = useEffectEvent(() => {\n if (minValue === undefined || isNaN(minValue) || value === undefined || isNaN(value) || value > minValue) {\n onDecrementEvent();\n onDecrementPressStartEvent(60);\n }\n });\n\n const onDecrementPressStartEvent = useEffectEvent((initialStepDelay: number) => {\n clearAsyncEvent();\n isSpinning.current = true;\n // Start spinning after initial delay\n _async.current = window.setTimeout(stepDownEvent, initialStepDelay);\n });\n\n let cancelContextMenu = (e) => {\n e.preventDefault();\n };\n\n let {addGlobalListener, removeAllGlobalListeners} = useGlobalListeners();\n\n // Tracks in touch if the press end event was preceded by a press up.\n // If it wasn't, then we know the finger left the button while still in contact with the screen.\n // This means that the user is trying to scroll or interact in some way that shouldn't trigger\n // an increment or decrement.\n let isUp = useRef(false);\n\n let [isIncrementPressed, setIsIncrementPressed] = useState<'touch' | 'mouse' | null>(null);\n useEffect(() => {\n if (isIncrementPressed === 'touch') {\n onIncrementPressStartEvent(600);\n } else if (isIncrementPressed) {\n onIncrementPressStartEvent(400);\n }\n }, [isIncrementPressed]);\n\n let [isDecrementPressed, setIsDecrementPressed] = useState<'touch' | 'mouse' | null>(null);\n useEffect(() => {\n if (isDecrementPressed === 'touch') {\n onDecrementPressStartEvent(600);\n } else if (isDecrementPressed) {\n onDecrementPressStartEvent(400);\n }\n }, [isDecrementPressed]);\n\n return {\n spinButtonProps: {\n role: 'spinbutton',\n 'aria-valuenow': value !== undefined && !isNaN(value) ? value : undefined,\n 'aria-valuetext': ariaTextValue,\n 'aria-valuemin': minValue,\n 'aria-valuemax': maxValue,\n 'aria-disabled': isDisabled || undefined,\n 'aria-readonly': isReadOnly || undefined,\n 'aria-required': isRequired || undefined,\n onKeyDown,\n onFocus,\n onBlur\n },\n incrementButtonProps: {\n onPressStart: (e) => {\n clearAsync();\n if (e.pointerType !== 'touch') {\n onIncrement?.();\n setIsIncrementPressed('mouse');\n } else {\n addGlobalListener(window, 'pointercancel', onPointerCancel, {capture: true});\n isUp.current = false;\n // For touch users, don't trigger a decrement on press start, we'll wait for the press end to trigger it if\n // the control isn't spinning.\n setIsIncrementPressed('touch');\n }\n addGlobalListener(window, 'contextmenu', cancelContextMenu);\n },\n onPressUp: (e) => {\n clearAsync();\n if (e.pointerType === 'touch') {\n isUp.current = true;\n }\n removeAllGlobalListeners();\n setIsIncrementPressed(null);\n },\n onPressEnd: (e) => {\n clearAsync();\n if (e.pointerType === 'touch') {\n if (!isSpinning.current && isUp.current) {\n onIncrement?.();\n }\n }\n isUp.current = false;\n setIsIncrementPressed(null);\n },\n onFocus,\n onBlur\n },\n decrementButtonProps: {\n onPressStart: (e) => {\n clearAsync();\n if (e.pointerType !== 'touch') {\n onDecrement?.();\n setIsDecrementPressed('mouse');\n } else {\n addGlobalListener(window, 'pointercancel', onPointerCancel, {capture: true});\n isUp.current = false;\n // For touch users, don't trigger a decrement on press start, we'll wait for the press end to trigger it if\n // the control isn't spinning.\n setIsDecrementPressed('touch');\n }\n },\n onPressUp: (e) => {\n clearAsync();\n if (e.pointerType === 'touch') {\n isUp.current = true;\n }\n removeAllGlobalListeners();\n setIsDecrementPressed(null);\n },\n onPressEnd: (e) => {\n clearAsync();\n if (e.pointerType === 'touch') {\n if (!isSpinning.current && isUp.current) {\n onDecrement?.();\n }\n }\n isUp.current = false;\n setIsDecrementPressed(null);\n },\n onFocus,\n onBlur\n }\n };\n}\n"],"names":[],"version":3,"file":"useSpinButton.main.js.map"}
@@ -23,6 +23,7 @@ function $parcel$interopDefault(a) {
23
23
 
24
24
 
25
25
 
26
+ const $d2e8511e6f209edf$var$noop = ()=>{};
26
27
  function $d2e8511e6f209edf$export$e908e06f4b8e3402(props) {
27
28
  const _async = (0, $5rwhf$useRef)(undefined);
28
29
  let { value: value, textValue: textValue, minValue: minValue, maxValue: maxValue, isDisabled: isDisabled, isReadOnly: isReadOnly, isRequired: isRequired, onIncrement: onIncrement, onIncrementPage: onIncrementPage, onDecrement: onDecrement, onDecrementPage: onDecrementPage, onDecrementToMin: onDecrementToMin, onIncrementToMax: onIncrementToMax } = props;
@@ -109,23 +110,31 @@ function $d2e8511e6f209edf$export$e908e06f4b8e3402(props) {
109
110
  }, [
110
111
  clearAsync
111
112
  ]);
112
- const onIncrementPressStart = (0, $5rwhf$useEffectEvent)((initialStepDelay)=>{
113
+ const onIncrementEvent = (0, $5rwhf$useEffectEvent)(onIncrement !== null && onIncrement !== void 0 ? onIncrement : $d2e8511e6f209edf$var$noop);
114
+ const onDecrementEvent = (0, $5rwhf$useEffectEvent)(onDecrement !== null && onDecrement !== void 0 ? onDecrement : $d2e8511e6f209edf$var$noop);
115
+ const stepUpEvent = (0, $5rwhf$useEffectEvent)(()=>{
116
+ if (maxValue === undefined || isNaN(maxValue) || value === undefined || isNaN(value) || value < maxValue) {
117
+ onIncrementEvent();
118
+ onIncrementPressStartEvent(60);
119
+ }
120
+ });
121
+ const onIncrementPressStartEvent = (0, $5rwhf$useEffectEvent)((initialStepDelay)=>{
113
122
  clearAsyncEvent();
114
123
  isSpinning.current = true;
115
- onIncrement === null || onIncrement === void 0 ? void 0 : onIncrement();
116
124
  // Start spinning after initial delay
117
- _async.current = window.setTimeout(()=>{
118
- if (maxValue === undefined || isNaN(maxValue) || value === undefined || isNaN(value) || value < maxValue) onIncrementPressStart(60);
119
- }, initialStepDelay);
125
+ _async.current = window.setTimeout(stepUpEvent, initialStepDelay);
126
+ });
127
+ const stepDownEvent = (0, $5rwhf$useEffectEvent)(()=>{
128
+ if (minValue === undefined || isNaN(minValue) || value === undefined || isNaN(value) || value > minValue) {
129
+ onDecrementEvent();
130
+ onDecrementPressStartEvent(60);
131
+ }
120
132
  });
121
- const onDecrementPressStart = (0, $5rwhf$useEffectEvent)((initialStepDelay)=>{
133
+ const onDecrementPressStartEvent = (0, $5rwhf$useEffectEvent)((initialStepDelay)=>{
122
134
  clearAsyncEvent();
123
135
  isSpinning.current = true;
124
- onDecrement === null || onDecrement === void 0 ? void 0 : onDecrement();
125
136
  // Start spinning after initial delay
126
- _async.current = window.setTimeout(()=>{
127
- if (minValue === undefined || isNaN(minValue) || value === undefined || isNaN(value) || value > minValue) onDecrementPressStart(60);
128
- }, initialStepDelay);
137
+ _async.current = window.setTimeout(stepDownEvent, initialStepDelay);
129
138
  });
130
139
  let cancelContextMenu = (e)=>{
131
140
  e.preventDefault();
@@ -138,15 +147,15 @@ function $d2e8511e6f209edf$export$e908e06f4b8e3402(props) {
138
147
  let isUp = (0, $5rwhf$useRef)(false);
139
148
  let [isIncrementPressed, setIsIncrementPressed] = (0, $5rwhf$useState)(null);
140
149
  (0, $5rwhf$useEffect)(()=>{
141
- if (isIncrementPressed === 'touch') onIncrementPressStart(60);
142
- else if (isIncrementPressed) onIncrementPressStart(400);
150
+ if (isIncrementPressed === 'touch') onIncrementPressStartEvent(600);
151
+ else if (isIncrementPressed) onIncrementPressStartEvent(400);
143
152
  }, [
144
153
  isIncrementPressed
145
154
  ]);
146
155
  let [isDecrementPressed, setIsDecrementPressed] = (0, $5rwhf$useState)(null);
147
156
  (0, $5rwhf$useEffect)(()=>{
148
- if (isDecrementPressed === 'touch') onDecrementPressStart(60);
149
- else if (isDecrementPressed) onDecrementPressStart(400);
157
+ if (isDecrementPressed === 'touch') onDecrementPressStartEvent(600);
158
+ else if (isDecrementPressed) onDecrementPressStartEvent(400);
150
159
  }, [
151
160
  isDecrementPressed
152
161
  ]);
@@ -166,32 +175,32 @@ function $d2e8511e6f209edf$export$e908e06f4b8e3402(props) {
166
175
  },
167
176
  incrementButtonProps: {
168
177
  onPressStart: (e)=>{
169
- if (e.pointerType !== 'touch') setIsIncrementPressed('mouse');
170
- else {
171
- if (_async.current) clearAsync();
178
+ clearAsync();
179
+ if (e.pointerType !== 'touch') {
180
+ onIncrement === null || onIncrement === void 0 ? void 0 : onIncrement();
181
+ setIsIncrementPressed('mouse');
182
+ } else {
172
183
  addGlobalListener(window, 'pointercancel', onPointerCancel, {
173
184
  capture: true
174
185
  });
175
186
  isUp.current = false;
176
187
  // For touch users, don't trigger a decrement on press start, we'll wait for the press end to trigger it if
177
188
  // the control isn't spinning.
178
- _async.current = window.setTimeout(()=>{
179
- setIsIncrementPressed('touch');
180
- }, 600);
189
+ setIsIncrementPressed('touch');
181
190
  }
182
191
  addGlobalListener(window, 'contextmenu', cancelContextMenu);
183
192
  },
184
193
  onPressUp: (e)=>{
185
- if (e.pointerType === 'touch') isUp.current = true;
186
194
  clearAsync();
195
+ if (e.pointerType === 'touch') isUp.current = true;
187
196
  removeAllGlobalListeners();
188
197
  setIsIncrementPressed(null);
189
198
  },
190
199
  onPressEnd: (e)=>{
200
+ clearAsync();
191
201
  if (e.pointerType === 'touch') {
192
202
  if (!isSpinning.current && isUp.current) onIncrement === null || onIncrement === void 0 ? void 0 : onIncrement();
193
203
  }
194
- clearAsync();
195
204
  isUp.current = false;
196
205
  setIsIncrementPressed(null);
197
206
  },
@@ -200,31 +209,31 @@ function $d2e8511e6f209edf$export$e908e06f4b8e3402(props) {
200
209
  },
201
210
  decrementButtonProps: {
202
211
  onPressStart: (e)=>{
203
- if (e.pointerType !== 'touch') setIsDecrementPressed('mouse');
204
- else {
205
- if (_async.current) clearAsync();
212
+ clearAsync();
213
+ if (e.pointerType !== 'touch') {
214
+ onDecrement === null || onDecrement === void 0 ? void 0 : onDecrement();
215
+ setIsDecrementPressed('mouse');
216
+ } else {
206
217
  addGlobalListener(window, 'pointercancel', onPointerCancel, {
207
218
  capture: true
208
219
  });
209
220
  isUp.current = false;
210
221
  // For touch users, don't trigger a decrement on press start, we'll wait for the press end to trigger it if
211
222
  // the control isn't spinning.
212
- _async.current = window.setTimeout(()=>{
213
- setIsDecrementPressed('touch');
214
- }, 600);
223
+ setIsDecrementPressed('touch');
215
224
  }
216
225
  },
217
226
  onPressUp: (e)=>{
218
- if (e.pointerType === 'touch') isUp.current = true;
219
227
  clearAsync();
228
+ if (e.pointerType === 'touch') isUp.current = true;
220
229
  removeAllGlobalListeners();
221
230
  setIsDecrementPressed(null);
222
231
  },
223
232
  onPressEnd: (e)=>{
233
+ clearAsync();
224
234
  if (e.pointerType === 'touch') {
225
235
  if (!isSpinning.current && isUp.current) onDecrement === null || onDecrement === void 0 ? void 0 : onDecrement();
226
236
  }
227
- clearAsync();
228
237
  isUp.current = false;
229
238
  setIsDecrementPressed(null);
230
239
  },
@@ -23,6 +23,7 @@ function $parcel$interopDefault(a) {
23
23
 
24
24
 
25
25
 
26
+ const $d2e8511e6f209edf$var$noop = ()=>{};
26
27
  function $d2e8511e6f209edf$export$e908e06f4b8e3402(props) {
27
28
  const _async = (0, $5rwhf$useRef)(undefined);
28
29
  let { value: value, textValue: textValue, minValue: minValue, maxValue: maxValue, isDisabled: isDisabled, isReadOnly: isReadOnly, isRequired: isRequired, onIncrement: onIncrement, onIncrementPage: onIncrementPage, onDecrement: onDecrement, onDecrementPage: onDecrementPage, onDecrementToMin: onDecrementToMin, onIncrementToMax: onIncrementToMax } = props;
@@ -109,23 +110,31 @@ function $d2e8511e6f209edf$export$e908e06f4b8e3402(props) {
109
110
  }, [
110
111
  clearAsync
111
112
  ]);
112
- const onIncrementPressStart = (0, $5rwhf$useEffectEvent)((initialStepDelay)=>{
113
+ const onIncrementEvent = (0, $5rwhf$useEffectEvent)(onIncrement !== null && onIncrement !== void 0 ? onIncrement : $d2e8511e6f209edf$var$noop);
114
+ const onDecrementEvent = (0, $5rwhf$useEffectEvent)(onDecrement !== null && onDecrement !== void 0 ? onDecrement : $d2e8511e6f209edf$var$noop);
115
+ const stepUpEvent = (0, $5rwhf$useEffectEvent)(()=>{
116
+ if (maxValue === undefined || isNaN(maxValue) || value === undefined || isNaN(value) || value < maxValue) {
117
+ onIncrementEvent();
118
+ onIncrementPressStartEvent(60);
119
+ }
120
+ });
121
+ const onIncrementPressStartEvent = (0, $5rwhf$useEffectEvent)((initialStepDelay)=>{
113
122
  clearAsyncEvent();
114
123
  isSpinning.current = true;
115
- onIncrement === null || onIncrement === void 0 ? void 0 : onIncrement();
116
124
  // Start spinning after initial delay
117
- _async.current = window.setTimeout(()=>{
118
- if (maxValue === undefined || isNaN(maxValue) || value === undefined || isNaN(value) || value < maxValue) onIncrementPressStart(60);
119
- }, initialStepDelay);
125
+ _async.current = window.setTimeout(stepUpEvent, initialStepDelay);
126
+ });
127
+ const stepDownEvent = (0, $5rwhf$useEffectEvent)(()=>{
128
+ if (minValue === undefined || isNaN(minValue) || value === undefined || isNaN(value) || value > minValue) {
129
+ onDecrementEvent();
130
+ onDecrementPressStartEvent(60);
131
+ }
120
132
  });
121
- const onDecrementPressStart = (0, $5rwhf$useEffectEvent)((initialStepDelay)=>{
133
+ const onDecrementPressStartEvent = (0, $5rwhf$useEffectEvent)((initialStepDelay)=>{
122
134
  clearAsyncEvent();
123
135
  isSpinning.current = true;
124
- onDecrement === null || onDecrement === void 0 ? void 0 : onDecrement();
125
136
  // Start spinning after initial delay
126
- _async.current = window.setTimeout(()=>{
127
- if (minValue === undefined || isNaN(minValue) || value === undefined || isNaN(value) || value > minValue) onDecrementPressStart(60);
128
- }, initialStepDelay);
137
+ _async.current = window.setTimeout(stepDownEvent, initialStepDelay);
129
138
  });
130
139
  let cancelContextMenu = (e)=>{
131
140
  e.preventDefault();
@@ -138,15 +147,15 @@ function $d2e8511e6f209edf$export$e908e06f4b8e3402(props) {
138
147
  let isUp = (0, $5rwhf$useRef)(false);
139
148
  let [isIncrementPressed, setIsIncrementPressed] = (0, $5rwhf$useState)(null);
140
149
  (0, $5rwhf$useEffect)(()=>{
141
- if (isIncrementPressed === 'touch') onIncrementPressStart(60);
142
- else if (isIncrementPressed) onIncrementPressStart(400);
150
+ if (isIncrementPressed === 'touch') onIncrementPressStartEvent(600);
151
+ else if (isIncrementPressed) onIncrementPressStartEvent(400);
143
152
  }, [
144
153
  isIncrementPressed
145
154
  ]);
146
155
  let [isDecrementPressed, setIsDecrementPressed] = (0, $5rwhf$useState)(null);
147
156
  (0, $5rwhf$useEffect)(()=>{
148
- if (isDecrementPressed === 'touch') onDecrementPressStart(60);
149
- else if (isDecrementPressed) onDecrementPressStart(400);
157
+ if (isDecrementPressed === 'touch') onDecrementPressStartEvent(600);
158
+ else if (isDecrementPressed) onDecrementPressStartEvent(400);
150
159
  }, [
151
160
  isDecrementPressed
152
161
  ]);
@@ -166,32 +175,32 @@ function $d2e8511e6f209edf$export$e908e06f4b8e3402(props) {
166
175
  },
167
176
  incrementButtonProps: {
168
177
  onPressStart: (e)=>{
169
- if (e.pointerType !== 'touch') setIsIncrementPressed('mouse');
170
- else {
171
- if (_async.current) clearAsync();
178
+ clearAsync();
179
+ if (e.pointerType !== 'touch') {
180
+ onIncrement === null || onIncrement === void 0 ? void 0 : onIncrement();
181
+ setIsIncrementPressed('mouse');
182
+ } else {
172
183
  addGlobalListener(window, 'pointercancel', onPointerCancel, {
173
184
  capture: true
174
185
  });
175
186
  isUp.current = false;
176
187
  // For touch users, don't trigger a decrement on press start, we'll wait for the press end to trigger it if
177
188
  // the control isn't spinning.
178
- _async.current = window.setTimeout(()=>{
179
- setIsIncrementPressed('touch');
180
- }, 600);
189
+ setIsIncrementPressed('touch');
181
190
  }
182
191
  addGlobalListener(window, 'contextmenu', cancelContextMenu);
183
192
  },
184
193
  onPressUp: (e)=>{
185
- if (e.pointerType === 'touch') isUp.current = true;
186
194
  clearAsync();
195
+ if (e.pointerType === 'touch') isUp.current = true;
187
196
  removeAllGlobalListeners();
188
197
  setIsIncrementPressed(null);
189
198
  },
190
199
  onPressEnd: (e)=>{
200
+ clearAsync();
191
201
  if (e.pointerType === 'touch') {
192
202
  if (!isSpinning.current && isUp.current) onIncrement === null || onIncrement === void 0 ? void 0 : onIncrement();
193
203
  }
194
- clearAsync();
195
204
  isUp.current = false;
196
205
  setIsIncrementPressed(null);
197
206
  },
@@ -200,31 +209,31 @@ function $d2e8511e6f209edf$export$e908e06f4b8e3402(props) {
200
209
  },
201
210
  decrementButtonProps: {
202
211
  onPressStart: (e)=>{
203
- if (e.pointerType !== 'touch') setIsDecrementPressed('mouse');
204
- else {
205
- if (_async.current) clearAsync();
212
+ clearAsync();
213
+ if (e.pointerType !== 'touch') {
214
+ onDecrement === null || onDecrement === void 0 ? void 0 : onDecrement();
215
+ setIsDecrementPressed('mouse');
216
+ } else {
206
217
  addGlobalListener(window, 'pointercancel', onPointerCancel, {
207
218
  capture: true
208
219
  });
209
220
  isUp.current = false;
210
221
  // For touch users, don't trigger a decrement on press start, we'll wait for the press end to trigger it if
211
222
  // the control isn't spinning.
212
- _async.current = window.setTimeout(()=>{
213
- setIsDecrementPressed('touch');
214
- }, 600);
223
+ setIsDecrementPressed('touch');
215
224
  }
216
225
  },
217
226
  onPressUp: (e)=>{
218
- if (e.pointerType === 'touch') isUp.current = true;
219
227
  clearAsync();
228
+ if (e.pointerType === 'touch') isUp.current = true;
220
229
  removeAllGlobalListeners();
221
230
  setIsDecrementPressed(null);
222
231
  },
223
232
  onPressEnd: (e)=>{
233
+ clearAsync();
224
234
  if (e.pointerType === 'touch') {
225
235
  if (!isSpinning.current && isUp.current) onDecrement === null || onDecrement === void 0 ? void 0 : onDecrement();
226
236
  }
227
- clearAsync();
228
237
  isUp.current = false;
229
238
  setIsDecrementPressed(null);
230
239
  },
@@ -1 +1 @@
1
- {"mappings":"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","sources":["packages/@react-aria/spinbutton/src/useSpinButton.ts"],"sourcesContent":["/*\n * Copyright 2020 Adobe. All rights reserved.\n * This file is licensed to you under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License. You may obtain a copy\n * of the License at http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under\n * the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\n * OF ANY KIND, either express or implied. See the License for the specific language\n * governing permissions and limitations under the License.\n */\n\nimport {announce, clearAnnouncer} from '@react-aria/live-announcer';\nimport {AriaButtonProps} from '@react-types/button';\nimport {DOMAttributes, InputBase, RangeInputBase, Validation, ValueBase} from '@react-types/shared';\n// @ts-ignore\nimport intlMessages from '../intl/*.json';\nimport {useCallback, useEffect, useRef, useState} from 'react';\nimport {useEffectEvent, useGlobalListeners} from '@react-aria/utils';\nimport {useLocalizedStringFormatter} from '@react-aria/i18n';\n\n\nexport interface SpinButtonProps extends InputBase, Validation<number>, ValueBase<number>, RangeInputBase<number> {\n textValue?: string,\n onIncrement?: () => void,\n onIncrementPage?: () => void,\n onDecrement?: () => void,\n onDecrementPage?: () => void,\n onDecrementToMin?: () => void,\n onIncrementToMax?: () => void\n}\n\nexport interface SpinbuttonAria {\n spinButtonProps: DOMAttributes,\n incrementButtonProps: AriaButtonProps,\n decrementButtonProps: AriaButtonProps\n}\n\nexport function useSpinButton(\n props: SpinButtonProps\n): SpinbuttonAria {\n const _async = useRef<number>(undefined);\n let {\n value,\n textValue,\n minValue,\n maxValue,\n isDisabled,\n isReadOnly,\n isRequired,\n onIncrement,\n onIncrementPage,\n onDecrement,\n onDecrementPage,\n onDecrementToMin,\n onIncrementToMax\n } = props;\n const stringFormatter = useLocalizedStringFormatter(intlMessages, '@react-aria/spinbutton');\n\n let isSpinning = useRef(false);\n const clearAsync = useCallback(() => {\n clearTimeout(_async.current);\n isSpinning.current = false;\n }, []);\n const clearAsyncEvent = useEffectEvent(() => {\n clearAsync();\n });\n\n useEffect(() => {\n return () => clearAsyncEvent();\n }, []);\n\n let onKeyDown = (e) => {\n if (e.ctrlKey || e.metaKey || e.shiftKey || e.altKey || isReadOnly || e.nativeEvent.isComposing) {\n return;\n }\n\n switch (e.key) {\n case 'PageUp':\n if (onIncrementPage) {\n e.preventDefault();\n onIncrementPage?.();\n break;\n }\n // fallthrough!\n case 'ArrowUp':\n case 'Up':\n if (onIncrement) {\n e.preventDefault();\n onIncrement?.();\n }\n break;\n case 'PageDown':\n if (onDecrementPage) {\n e.preventDefault();\n onDecrementPage?.();\n break;\n }\n // fallthrough\n case 'ArrowDown':\n case 'Down':\n if (onDecrement) {\n e.preventDefault();\n onDecrement?.();\n }\n break;\n case 'Home':\n if (onDecrementToMin) {\n e.preventDefault();\n onDecrementToMin?.();\n }\n break;\n case 'End':\n if (onIncrementToMax) {\n e.preventDefault();\n onIncrementToMax?.();\n }\n break;\n }\n };\n\n let isFocused = useRef(false);\n let onFocus = () => {\n isFocused.current = true;\n };\n\n let onBlur = () => {\n isFocused.current = false;\n };\n\n // Replace Unicode hyphen-minus (U+002D) with minus sign (U+2212).\n // This ensures that macOS VoiceOver announces it as \"minus\" even with other characters between the minus sign\n // and the number (e.g. currency symbol). Otherwise it announces nothing because it assumes the character is a hyphen.\n // In addition, replace the empty string with the word \"Empty\" so that iOS VoiceOver does not read \"50%\" for an empty field.\n let ariaTextValue = textValue === '' ? stringFormatter.format('Empty') : (textValue || `${value}`).replace('-', '\\u2212');\n\n useEffect(() => {\n if (isFocused.current) {\n clearAnnouncer('assertive');\n announce(ariaTextValue, 'assertive');\n }\n }, [ariaTextValue]);\n\n // For touch users, if they move their finger like they're scrolling, we don't want to trigger a spin.\n let onPointerCancel = useCallback(() => {\n clearAsync();\n }, [clearAsync]);\n\n const onIncrementPressStart = useEffectEvent(\n (initialStepDelay: number) => {\n clearAsyncEvent();\n isSpinning.current = true;\n onIncrement?.();\n // Start spinning after initial delay\n _async.current = window.setTimeout(\n () => {\n if ((maxValue === undefined || isNaN(maxValue)) || (value === undefined || isNaN(value)) || value < maxValue) {\n onIncrementPressStart(60);\n }\n },\n initialStepDelay\n );\n }\n );\n\n const onDecrementPressStart = useEffectEvent(\n (initialStepDelay: number) => {\n clearAsyncEvent();\n isSpinning.current = true;\n onDecrement?.();\n // Start spinning after initial delay\n _async.current = window.setTimeout(\n () => {\n if ((minValue === undefined || isNaN(minValue)) || (value === undefined || isNaN(value)) || value > minValue) {\n onDecrementPressStart(60);\n }\n },\n initialStepDelay\n );\n }\n );\n\n let cancelContextMenu = (e) => {\n e.preventDefault();\n };\n\n let {addGlobalListener, removeAllGlobalListeners} = useGlobalListeners();\n\n // Tracks in touch if the press end event was preceded by a press up.\n // If it wasn't, then we know the finger left the button while still in contact with the screen.\n // This means that the user is trying to scroll or interact in some way that shouldn't trigger\n // an increment or decrement.\n let isUp = useRef(false);\n\n let [isIncrementPressed, setIsIncrementPressed] = useState<'touch' | 'mouse' | null>(null);\n useEffect(() => {\n if (isIncrementPressed === 'touch') {\n onIncrementPressStart(60);\n } else if (isIncrementPressed) {\n onIncrementPressStart(400);\n }\n }, [isIncrementPressed]);\n\n let [isDecrementPressed, setIsDecrementPressed] = useState<'touch' | 'mouse' | null>(null);\n useEffect(() => {\n if (isDecrementPressed === 'touch') {\n onDecrementPressStart(60);\n } else if (isDecrementPressed) {\n onDecrementPressStart(400);\n }\n }, [isDecrementPressed]);\n\n return {\n spinButtonProps: {\n role: 'spinbutton',\n 'aria-valuenow': value !== undefined && !isNaN(value) ? value : undefined,\n 'aria-valuetext': ariaTextValue,\n 'aria-valuemin': minValue,\n 'aria-valuemax': maxValue,\n 'aria-disabled': isDisabled || undefined,\n 'aria-readonly': isReadOnly || undefined,\n 'aria-required': isRequired || undefined,\n onKeyDown,\n onFocus,\n onBlur\n },\n incrementButtonProps: {\n onPressStart: (e) => {\n if (e.pointerType !== 'touch') {\n setIsIncrementPressed('mouse');\n } else {\n if (_async.current) {\n clearAsync();\n }\n\n addGlobalListener(window, 'pointercancel', onPointerCancel, {capture: true});\n isUp.current = false;\n // For touch users, don't trigger a decrement on press start, we'll wait for the press end to trigger it if\n // the control isn't spinning.\n _async.current = window.setTimeout(() => {\n setIsIncrementPressed('touch');\n }, 600);\n }\n addGlobalListener(window, 'contextmenu', cancelContextMenu);\n },\n onPressUp: (e) => {\n if (e.pointerType === 'touch') {\n isUp.current = true;\n }\n clearAsync();\n removeAllGlobalListeners();\n setIsIncrementPressed(null);\n },\n onPressEnd: (e) => {\n if (e.pointerType === 'touch') {\n if (!isSpinning.current && isUp.current) {\n onIncrement?.();\n }\n }\n clearAsync();\n isUp.current = false;\n setIsIncrementPressed(null);\n },\n onFocus,\n onBlur\n },\n decrementButtonProps: {\n onPressStart: (e) => {\n if (e.pointerType !== 'touch') {\n setIsDecrementPressed('mouse');\n } else {\n if (_async.current) {\n clearAsync();\n }\n\n addGlobalListener(window, 'pointercancel', onPointerCancel, {capture: true});\n isUp.current = false;\n // For touch users, don't trigger a decrement on press start, we'll wait for the press end to trigger it if\n // the control isn't spinning.\n _async.current = window.setTimeout(() => {\n setIsDecrementPressed('touch');\n }, 600);\n }\n },\n onPressUp: (e) => {\n if (e.pointerType === 'touch') {\n isUp.current = true;\n }\n clearAsync();\n removeAllGlobalListeners();\n setIsDecrementPressed(null);\n },\n onPressEnd: (e) => {\n if (e.pointerType === 'touch') {\n if (!isSpinning.current && isUp.current) {\n onDecrement?.();\n }\n }\n clearAsync();\n isUp.current = false;\n setIsDecrementPressed(null);\n },\n onFocus,\n onBlur\n }\n };\n}\n"],"names":[],"version":3,"file":"useSpinButton.module.js.map"}
1
+ {"mappings":";;;;;;;;;;AAAA;;;;;;;;;;CAUC;;;;;AAYD,MAAM,6BAAO,KAAO;AAkBb,SAAS,0CACd,KAAsB;IAEtB,MAAM,SAAS,CAAA,GAAA,aAAK,EAAU;IAC9B,IAAI,SACF,KAAK,aACL,SAAS,YACT,QAAQ,YACR,QAAQ,cACR,UAAU,cACV,UAAU,cACV,UAAU,eACV,WAAW,mBACX,eAAe,eACf,WAAW,mBACX,eAAe,oBACf,gBAAgB,oBAChB,gBAAgB,EACjB,GAAG;IACJ,MAAM,kBAAkB,CAAA,GAAA,kCAA0B,EAAE,CAAA,GAAA,oDAAW,GAAG;IAElE,IAAI,aAAa,CAAA,GAAA,aAAK,EAAE;IACxB,MAAM,aAAa,CAAA,GAAA,kBAAU,EAAE;QAC7B,aAAa,OAAO,OAAO;QAC3B,WAAW,OAAO,GAAG;IACvB,GAAG,EAAE;IACL,MAAM,kBAAkB,CAAA,GAAA,qBAAa,EAAE;QACrC;IACF;IAEA,CAAA,GAAA,gBAAQ,EAAE;QACR,OAAO,IAAM;IACf,GAAG,EAAE;IAEL,IAAI,YAAY,CAAC;QACf,IAAI,EAAE,OAAO,IAAI,EAAE,OAAO,IAAI,EAAE,QAAQ,IAAI,EAAE,MAAM,IAAI,cAAc,EAAE,WAAW,CAAC,WAAW,EAC7F;QAGF,OAAQ,EAAE,GAAG;YACX,KAAK;gBACH,IAAI,iBAAiB;oBACnB,EAAE,cAAc;oBAChB,4BAAA,sCAAA;oBACA;gBACF;YACF,eAAe;YACf,KAAK;YACL,KAAK;gBACH,IAAI,aAAa;oBACf,EAAE,cAAc;oBAChB,wBAAA,kCAAA;gBACF;gBACA;YACF,KAAK;gBACH,IAAI,iBAAiB;oBACnB,EAAE,cAAc;oBAChB,4BAAA,sCAAA;oBACA;gBACF;YACF,cAAc;YACd,KAAK;YACL,KAAK;gBACH,IAAI,aAAa;oBACf,EAAE,cAAc;oBAChB,wBAAA,kCAAA;gBACF;gBACA;YACF,KAAK;gBACH,IAAI,kBAAkB;oBACpB,EAAE,cAAc;oBAChB,6BAAA,uCAAA;gBACF;gBACA;YACF,KAAK;gBACH,IAAI,kBAAkB;oBACpB,EAAE,cAAc;oBAChB,6BAAA,uCAAA;gBACF;gBACA;QACJ;IACF;IAEA,IAAI,YAAY,CAAA,GAAA,aAAK,EAAE;IACvB,IAAI,UAAU;QACZ,UAAU,OAAO,GAAG;IACtB;IAEA,IAAI,SAAS;QACX,UAAU,OAAO,GAAG;IACtB;IAEA,kEAAkE;IAClE,8GAA8G;IAC9G,sHAAsH;IACtH,4HAA4H;IAC5H,IAAI,gBAAgB,cAAc,KAAK,gBAAgB,MAAM,CAAC,WAAW,AAAC,CAAA,aAAa,GAAG,OAAO,AAAD,EAAG,OAAO,CAAC,KAAK;IAEhH,CAAA,GAAA,gBAAQ,EAAE;QACR,IAAI,UAAU,OAAO,EAAE;YACrB,CAAA,GAAA,qBAAa,EAAE;YACf,CAAA,GAAA,eAAO,EAAE,eAAe;QAC1B;IACF,GAAG;QAAC;KAAc;IAElB,sGAAsG;IACtG,IAAI,kBAAkB,CAAA,GAAA,kBAAU,EAAE;QAChC;IACF,GAAG;QAAC;KAAW;IAEf,MAAM,mBAAmB,CAAA,GAAA,qBAAa,EAAE,wBAAA,yBAAA,cAAe;IACvD,MAAM,mBAAmB,CAAA,GAAA,qBAAa,EAAE,wBAAA,yBAAA,cAAe;IAEvD,MAAM,cAAc,CAAA,GAAA,qBAAa,EAAE;QACjC,IAAI,aAAa,aAAa,MAAM,aAAa,UAAU,aAAa,MAAM,UAAU,QAAQ,UAAU;YACxG;YACA,2BAA2B;QAC7B;IACF;IAEA,MAAM,6BAA6B,CAAA,GAAA,qBAAa,EAAE,CAAC;QACjD;QACA,WAAW,OAAO,GAAG;QACrB,qCAAqC;QACrC,OAAO,OAAO,GAAG,OAAO,UAAU,CAAC,aAAa;IAClD;IAEA,MAAM,gBAAgB,CAAA,GAAA,qBAAa,EAAE;QACnC,IAAI,aAAa,aAAa,MAAM,aAAa,UAAU,aAAa,MAAM,UAAU,QAAQ,UAAU;YACxG;YACA,2BAA2B;QAC7B;IACF;IAEA,MAAM,6BAA6B,CAAA,GAAA,qBAAa,EAAE,CAAC;QACjD;QACA,WAAW,OAAO,GAAG;QACrB,qCAAqC;QACrC,OAAO,OAAO,GAAG,OAAO,UAAU,CAAC,eAAe;IACpD;IAEA,IAAI,oBAAoB,CAAC;QACvB,EAAE,cAAc;IAClB;IAEA,IAAI,qBAAC,iBAAiB,4BAAE,wBAAwB,EAAC,GAAG,CAAA,GAAA,yBAAiB;IAErE,qEAAqE;IACrE,gGAAgG;IAChG,8FAA8F;IAC9F,6BAA6B;IAC7B,IAAI,OAAO,CAAA,GAAA,aAAK,EAAE;IAElB,IAAI,CAAC,oBAAoB,sBAAsB,GAAG,CAAA,GAAA,eAAO,EAA4B;IACrF,CAAA,GAAA,gBAAQ,EAAE;QACR,IAAI,uBAAuB,SACzB,2BAA2B;aACtB,IAAI,oBACT,2BAA2B;IAE/B,GAAG;QAAC;KAAmB;IAEvB,IAAI,CAAC,oBAAoB,sBAAsB,GAAG,CAAA,GAAA,eAAO,EAA4B;IACrF,CAAA,GAAA,gBAAQ,EAAE;QACR,IAAI,uBAAuB,SACzB,2BAA2B;aACtB,IAAI,oBACT,2BAA2B;IAE/B,GAAG;QAAC;KAAmB;IAEvB,OAAO;QACL,iBAAiB;YACf,MAAM;YACN,iBAAiB,UAAU,aAAa,CAAC,MAAM,SAAS,QAAQ;YAChE,kBAAkB;YAClB,iBAAiB;YACjB,iBAAiB;YACjB,iBAAiB,cAAc;YAC/B,iBAAiB,cAAc;YAC/B,iBAAiB,cAAc;uBAC/B;qBACA;oBACA;QACF;QACA,sBAAsB;YACpB,cAAc,CAAC;gBACb;gBACA,IAAI,EAAE,WAAW,KAAK,SAAS;oBAC7B,wBAAA,kCAAA;oBACA,sBAAsB;gBACxB,OAAO;oBACL,kBAAkB,QAAQ,iBAAiB,iBAAiB;wBAAC,SAAS;oBAAI;oBAC1E,KAAK,OAAO,GAAG;oBACf,2GAA2G;oBAC3G,8BAA8B;oBAC9B,sBAAsB;gBACxB;gBACA,kBAAkB,QAAQ,eAAe;YAC3C;YACA,WAAW,CAAC;gBACV;gBACA,IAAI,EAAE,WAAW,KAAK,SACpB,KAAK,OAAO,GAAG;gBAEjB;gBACA,sBAAsB;YACxB;YACA,YAAY,CAAC;gBACX;gBACA,IAAI,EAAE,WAAW,KAAK,SACpB;oBAAA,IAAI,CAAC,WAAW,OAAO,IAAI,KAAK,OAAO,EACrC,wBAAA,kCAAA;gBACF;gBAEF,KAAK,OAAO,GAAG;gBACf,sBAAsB;YACxB;qBACA;oBACA;QACF;QACA,sBAAsB;YACpB,cAAc,CAAC;gBACb;gBACA,IAAI,EAAE,WAAW,KAAK,SAAS;oBAC7B,wBAAA,kCAAA;oBACA,sBAAsB;gBACxB,OAAO;oBACL,kBAAkB,QAAQ,iBAAiB,iBAAiB;wBAAC,SAAS;oBAAI;oBAC1E,KAAK,OAAO,GAAG;oBACf,2GAA2G;oBAC3G,8BAA8B;oBAC9B,sBAAsB;gBACxB;YACF;YACA,WAAW,CAAC;gBACV;gBACA,IAAI,EAAE,WAAW,KAAK,SACpB,KAAK,OAAO,GAAG;gBAEjB;gBACA,sBAAsB;YACxB;YACA,YAAY,CAAC;gBACX;gBACA,IAAI,EAAE,WAAW,KAAK,SACpB;oBAAA,IAAI,CAAC,WAAW,OAAO,IAAI,KAAK,OAAO,EACrC,wBAAA,kCAAA;gBACF;gBAEF,KAAK,OAAO,GAAG;gBACf,sBAAsB;YACxB;qBACA;oBACA;QACF;IACF;AACF","sources":["packages/@react-aria/spinbutton/src/useSpinButton.ts"],"sourcesContent":["/*\n * Copyright 2020 Adobe. All rights reserved.\n * This file is licensed to you under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License. You may obtain a copy\n * of the License at http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under\n * the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\n * OF ANY KIND, either express or implied. See the License for the specific language\n * governing permissions and limitations under the License.\n */\n\nimport {announce, clearAnnouncer} from '@react-aria/live-announcer';\nimport {AriaButtonProps} from '@react-types/button';\nimport {DOMAttributes, InputBase, RangeInputBase, Validation, ValueBase} from '@react-types/shared';\n// @ts-ignore\nimport intlMessages from '../intl/*.json';\nimport {useCallback, useEffect, useRef, useState} from 'react';\nimport {useEffectEvent, useGlobalListeners} from '@react-aria/utils';\nimport {useLocalizedStringFormatter} from '@react-aria/i18n';\n\n\nconst noop = () => {};\n\nexport interface SpinButtonProps extends InputBase, Validation<number>, ValueBase<number>, RangeInputBase<number> {\n textValue?: string,\n onIncrement?: () => void,\n onIncrementPage?: () => void,\n onDecrement?: () => void,\n onDecrementPage?: () => void,\n onDecrementToMin?: () => void,\n onIncrementToMax?: () => void\n}\n\nexport interface SpinbuttonAria {\n spinButtonProps: DOMAttributes,\n incrementButtonProps: AriaButtonProps,\n decrementButtonProps: AriaButtonProps\n}\n\nexport function useSpinButton(\n props: SpinButtonProps\n): SpinbuttonAria {\n const _async = useRef<number>(undefined);\n let {\n value,\n textValue,\n minValue,\n maxValue,\n isDisabled,\n isReadOnly,\n isRequired,\n onIncrement,\n onIncrementPage,\n onDecrement,\n onDecrementPage,\n onDecrementToMin,\n onIncrementToMax\n } = props;\n const stringFormatter = useLocalizedStringFormatter(intlMessages, '@react-aria/spinbutton');\n\n let isSpinning = useRef(false);\n const clearAsync = useCallback(() => {\n clearTimeout(_async.current);\n isSpinning.current = false;\n }, []);\n const clearAsyncEvent = useEffectEvent(() => {\n clearAsync();\n });\n\n useEffect(() => {\n return () => clearAsyncEvent();\n }, []);\n\n let onKeyDown = (e) => {\n if (e.ctrlKey || e.metaKey || e.shiftKey || e.altKey || isReadOnly || e.nativeEvent.isComposing) {\n return;\n }\n\n switch (e.key) {\n case 'PageUp':\n if (onIncrementPage) {\n e.preventDefault();\n onIncrementPage?.();\n break;\n }\n // fallthrough!\n case 'ArrowUp':\n case 'Up':\n if (onIncrement) {\n e.preventDefault();\n onIncrement?.();\n }\n break;\n case 'PageDown':\n if (onDecrementPage) {\n e.preventDefault();\n onDecrementPage?.();\n break;\n }\n // fallthrough\n case 'ArrowDown':\n case 'Down':\n if (onDecrement) {\n e.preventDefault();\n onDecrement?.();\n }\n break;\n case 'Home':\n if (onDecrementToMin) {\n e.preventDefault();\n onDecrementToMin?.();\n }\n break;\n case 'End':\n if (onIncrementToMax) {\n e.preventDefault();\n onIncrementToMax?.();\n }\n break;\n }\n };\n\n let isFocused = useRef(false);\n let onFocus = () => {\n isFocused.current = true;\n };\n\n let onBlur = () => {\n isFocused.current = false;\n };\n\n // Replace Unicode hyphen-minus (U+002D) with minus sign (U+2212).\n // This ensures that macOS VoiceOver announces it as \"minus\" even with other characters between the minus sign\n // and the number (e.g. currency symbol). Otherwise it announces nothing because it assumes the character is a hyphen.\n // In addition, replace the empty string with the word \"Empty\" so that iOS VoiceOver does not read \"50%\" for an empty field.\n let ariaTextValue = textValue === '' ? stringFormatter.format('Empty') : (textValue || `${value}`).replace('-', '\\u2212');\n\n useEffect(() => {\n if (isFocused.current) {\n clearAnnouncer('assertive');\n announce(ariaTextValue, 'assertive');\n }\n }, [ariaTextValue]);\n\n // For touch users, if they move their finger like they're scrolling, we don't want to trigger a spin.\n let onPointerCancel = useCallback(() => {\n clearAsync();\n }, [clearAsync]);\n\n const onIncrementEvent = useEffectEvent(onIncrement ?? noop);\n const onDecrementEvent = useEffectEvent(onDecrement ?? noop);\n\n const stepUpEvent = useEffectEvent(() => {\n if (maxValue === undefined || isNaN(maxValue) || value === undefined || isNaN(value) || value < maxValue) {\n onIncrementEvent();\n onIncrementPressStartEvent(60);\n }\n });\n\n const onIncrementPressStartEvent = useEffectEvent((initialStepDelay: number) => {\n clearAsyncEvent();\n isSpinning.current = true;\n // Start spinning after initial delay\n _async.current = window.setTimeout(stepUpEvent, initialStepDelay);\n });\n\n const stepDownEvent = useEffectEvent(() => {\n if (minValue === undefined || isNaN(minValue) || value === undefined || isNaN(value) || value > minValue) {\n onDecrementEvent();\n onDecrementPressStartEvent(60);\n }\n });\n\n const onDecrementPressStartEvent = useEffectEvent((initialStepDelay: number) => {\n clearAsyncEvent();\n isSpinning.current = true;\n // Start spinning after initial delay\n _async.current = window.setTimeout(stepDownEvent, initialStepDelay);\n });\n\n let cancelContextMenu = (e) => {\n e.preventDefault();\n };\n\n let {addGlobalListener, removeAllGlobalListeners} = useGlobalListeners();\n\n // Tracks in touch if the press end event was preceded by a press up.\n // If it wasn't, then we know the finger left the button while still in contact with the screen.\n // This means that the user is trying to scroll or interact in some way that shouldn't trigger\n // an increment or decrement.\n let isUp = useRef(false);\n\n let [isIncrementPressed, setIsIncrementPressed] = useState<'touch' | 'mouse' | null>(null);\n useEffect(() => {\n if (isIncrementPressed === 'touch') {\n onIncrementPressStartEvent(600);\n } else if (isIncrementPressed) {\n onIncrementPressStartEvent(400);\n }\n }, [isIncrementPressed]);\n\n let [isDecrementPressed, setIsDecrementPressed] = useState<'touch' | 'mouse' | null>(null);\n useEffect(() => {\n if (isDecrementPressed === 'touch') {\n onDecrementPressStartEvent(600);\n } else if (isDecrementPressed) {\n onDecrementPressStartEvent(400);\n }\n }, [isDecrementPressed]);\n\n return {\n spinButtonProps: {\n role: 'spinbutton',\n 'aria-valuenow': value !== undefined && !isNaN(value) ? value : undefined,\n 'aria-valuetext': ariaTextValue,\n 'aria-valuemin': minValue,\n 'aria-valuemax': maxValue,\n 'aria-disabled': isDisabled || undefined,\n 'aria-readonly': isReadOnly || undefined,\n 'aria-required': isRequired || undefined,\n onKeyDown,\n onFocus,\n onBlur\n },\n incrementButtonProps: {\n onPressStart: (e) => {\n clearAsync();\n if (e.pointerType !== 'touch') {\n onIncrement?.();\n setIsIncrementPressed('mouse');\n } else {\n addGlobalListener(window, 'pointercancel', onPointerCancel, {capture: true});\n isUp.current = false;\n // For touch users, don't trigger a decrement on press start, we'll wait for the press end to trigger it if\n // the control isn't spinning.\n setIsIncrementPressed('touch');\n }\n addGlobalListener(window, 'contextmenu', cancelContextMenu);\n },\n onPressUp: (e) => {\n clearAsync();\n if (e.pointerType === 'touch') {\n isUp.current = true;\n }\n removeAllGlobalListeners();\n setIsIncrementPressed(null);\n },\n onPressEnd: (e) => {\n clearAsync();\n if (e.pointerType === 'touch') {\n if (!isSpinning.current && isUp.current) {\n onIncrement?.();\n }\n }\n isUp.current = false;\n setIsIncrementPressed(null);\n },\n onFocus,\n onBlur\n },\n decrementButtonProps: {\n onPressStart: (e) => {\n clearAsync();\n if (e.pointerType !== 'touch') {\n onDecrement?.();\n setIsDecrementPressed('mouse');\n } else {\n addGlobalListener(window, 'pointercancel', onPointerCancel, {capture: true});\n isUp.current = false;\n // For touch users, don't trigger a decrement on press start, we'll wait for the press end to trigger it if\n // the control isn't spinning.\n setIsDecrementPressed('touch');\n }\n },\n onPressUp: (e) => {\n clearAsync();\n if (e.pointerType === 'touch') {\n isUp.current = true;\n }\n removeAllGlobalListeners();\n setIsDecrementPressed(null);\n },\n onPressEnd: (e) => {\n clearAsync();\n if (e.pointerType === 'touch') {\n if (!isSpinning.current && isUp.current) {\n onDecrement?.();\n }\n }\n isUp.current = false;\n setIsDecrementPressed(null);\n },\n onFocus,\n onBlur\n }\n };\n}\n"],"names":[],"version":3,"file":"useSpinButton.module.js.map"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@react-aria/spinbutton",
3
- "version": "3.7.0",
3
+ "version": "3.7.1",
4
4
  "description": "Spectrum UI components in React",
5
5
  "license": "Apache-2.0",
6
6
  "main": "dist/main.js",
@@ -26,11 +26,11 @@
26
26
  "url": "https://github.com/adobe/react-spectrum"
27
27
  },
28
28
  "dependencies": {
29
- "@react-aria/i18n": "^3.12.14",
29
+ "@react-aria/i18n": "^3.12.15",
30
30
  "@react-aria/live-announcer": "^3.4.4",
31
- "@react-aria/utils": "^3.32.0",
32
- "@react-types/button": "^3.14.1",
33
- "@react-types/shared": "^3.32.1",
31
+ "@react-aria/utils": "^3.33.0",
32
+ "@react-types/button": "^3.15.0",
33
+ "@react-types/shared": "^3.33.0",
34
34
  "@swc/helpers": "^0.5.0"
35
35
  },
36
36
  "peerDependencies": {
@@ -40,5 +40,5 @@
40
40
  "publishConfig": {
41
41
  "access": "public"
42
42
  },
43
- "gitHead": "4d838da5bfe36abb35aed166995a9ef63825370f"
43
+ "gitHead": "66e51757606b43a89ed02c574ca24517323a2ab9"
44
44
  }
@@ -20,6 +20,8 @@ import {useEffectEvent, useGlobalListeners} from '@react-aria/utils';
20
20
  import {useLocalizedStringFormatter} from '@react-aria/i18n';
21
21
 
22
22
 
23
+ const noop = () => {};
24
+
23
25
  export interface SpinButtonProps extends InputBase, Validation<number>, ValueBase<number>, RangeInputBase<number> {
24
26
  textValue?: string,
25
27
  onIncrement?: () => void,
@@ -146,39 +148,36 @@ export function useSpinButton(
146
148
  clearAsync();
147
149
  }, [clearAsync]);
148
150
 
149
- const onIncrementPressStart = useEffectEvent(
150
- (initialStepDelay: number) => {
151
- clearAsyncEvent();
152
- isSpinning.current = true;
153
- onIncrement?.();
154
- // Start spinning after initial delay
155
- _async.current = window.setTimeout(
156
- () => {
157
- if ((maxValue === undefined || isNaN(maxValue)) || (value === undefined || isNaN(value)) || value < maxValue) {
158
- onIncrementPressStart(60);
159
- }
160
- },
161
- initialStepDelay
162
- );
151
+ const onIncrementEvent = useEffectEvent(onIncrement ?? noop);
152
+ const onDecrementEvent = useEffectEvent(onDecrement ?? noop);
153
+
154
+ const stepUpEvent = useEffectEvent(() => {
155
+ if (maxValue === undefined || isNaN(maxValue) || value === undefined || isNaN(value) || value < maxValue) {
156
+ onIncrementEvent();
157
+ onIncrementPressStartEvent(60);
163
158
  }
164
- );
159
+ });
165
160
 
166
- const onDecrementPressStart = useEffectEvent(
167
- (initialStepDelay: number) => {
168
- clearAsyncEvent();
169
- isSpinning.current = true;
170
- onDecrement?.();
171
- // Start spinning after initial delay
172
- _async.current = window.setTimeout(
173
- () => {
174
- if ((minValue === undefined || isNaN(minValue)) || (value === undefined || isNaN(value)) || value > minValue) {
175
- onDecrementPressStart(60);
176
- }
177
- },
178
- initialStepDelay
179
- );
161
+ const onIncrementPressStartEvent = useEffectEvent((initialStepDelay: number) => {
162
+ clearAsyncEvent();
163
+ isSpinning.current = true;
164
+ // Start spinning after initial delay
165
+ _async.current = window.setTimeout(stepUpEvent, initialStepDelay);
166
+ });
167
+
168
+ const stepDownEvent = useEffectEvent(() => {
169
+ if (minValue === undefined || isNaN(minValue) || value === undefined || isNaN(value) || value > minValue) {
170
+ onDecrementEvent();
171
+ onDecrementPressStartEvent(60);
180
172
  }
181
- );
173
+ });
174
+
175
+ const onDecrementPressStartEvent = useEffectEvent((initialStepDelay: number) => {
176
+ clearAsyncEvent();
177
+ isSpinning.current = true;
178
+ // Start spinning after initial delay
179
+ _async.current = window.setTimeout(stepDownEvent, initialStepDelay);
180
+ });
182
181
 
183
182
  let cancelContextMenu = (e) => {
184
183
  e.preventDefault();
@@ -195,18 +194,18 @@ export function useSpinButton(
195
194
  let [isIncrementPressed, setIsIncrementPressed] = useState<'touch' | 'mouse' | null>(null);
196
195
  useEffect(() => {
197
196
  if (isIncrementPressed === 'touch') {
198
- onIncrementPressStart(60);
197
+ onIncrementPressStartEvent(600);
199
198
  } else if (isIncrementPressed) {
200
- onIncrementPressStart(400);
199
+ onIncrementPressStartEvent(400);
201
200
  }
202
201
  }, [isIncrementPressed]);
203
202
 
204
203
  let [isDecrementPressed, setIsDecrementPressed] = useState<'touch' | 'mouse' | null>(null);
205
204
  useEffect(() => {
206
205
  if (isDecrementPressed === 'touch') {
207
- onDecrementPressStart(60);
206
+ onDecrementPressStartEvent(600);
208
207
  } else if (isDecrementPressed) {
209
- onDecrementPressStart(400);
208
+ onDecrementPressStartEvent(400);
210
209
  }
211
210
  }, [isDecrementPressed]);
212
211
 
@@ -226,38 +225,34 @@ export function useSpinButton(
226
225
  },
227
226
  incrementButtonProps: {
228
227
  onPressStart: (e) => {
228
+ clearAsync();
229
229
  if (e.pointerType !== 'touch') {
230
+ onIncrement?.();
230
231
  setIsIncrementPressed('mouse');
231
232
  } else {
232
- if (_async.current) {
233
- clearAsync();
234
- }
235
-
236
233
  addGlobalListener(window, 'pointercancel', onPointerCancel, {capture: true});
237
234
  isUp.current = false;
238
235
  // For touch users, don't trigger a decrement on press start, we'll wait for the press end to trigger it if
239
236
  // the control isn't spinning.
240
- _async.current = window.setTimeout(() => {
241
- setIsIncrementPressed('touch');
242
- }, 600);
237
+ setIsIncrementPressed('touch');
243
238
  }
244
239
  addGlobalListener(window, 'contextmenu', cancelContextMenu);
245
240
  },
246
241
  onPressUp: (e) => {
242
+ clearAsync();
247
243
  if (e.pointerType === 'touch') {
248
244
  isUp.current = true;
249
245
  }
250
- clearAsync();
251
246
  removeAllGlobalListeners();
252
247
  setIsIncrementPressed(null);
253
248
  },
254
249
  onPressEnd: (e) => {
250
+ clearAsync();
255
251
  if (e.pointerType === 'touch') {
256
252
  if (!isSpinning.current && isUp.current) {
257
253
  onIncrement?.();
258
254
  }
259
255
  }
260
- clearAsync();
261
256
  isUp.current = false;
262
257
  setIsIncrementPressed(null);
263
258
  },
@@ -266,37 +261,33 @@ export function useSpinButton(
266
261
  },
267
262
  decrementButtonProps: {
268
263
  onPressStart: (e) => {
264
+ clearAsync();
269
265
  if (e.pointerType !== 'touch') {
266
+ onDecrement?.();
270
267
  setIsDecrementPressed('mouse');
271
268
  } else {
272
- if (_async.current) {
273
- clearAsync();
274
- }
275
-
276
269
  addGlobalListener(window, 'pointercancel', onPointerCancel, {capture: true});
277
270
  isUp.current = false;
278
271
  // For touch users, don't trigger a decrement on press start, we'll wait for the press end to trigger it if
279
272
  // the control isn't spinning.
280
- _async.current = window.setTimeout(() => {
281
- setIsDecrementPressed('touch');
282
- }, 600);
273
+ setIsDecrementPressed('touch');
283
274
  }
284
275
  },
285
276
  onPressUp: (e) => {
277
+ clearAsync();
286
278
  if (e.pointerType === 'touch') {
287
279
  isUp.current = true;
288
280
  }
289
- clearAsync();
290
281
  removeAllGlobalListeners();
291
282
  setIsDecrementPressed(null);
292
283
  },
293
284
  onPressEnd: (e) => {
285
+ clearAsync();
294
286
  if (e.pointerType === 'touch') {
295
287
  if (!isSpinning.current && isUp.current) {
296
288
  onDecrement?.();
297
289
  }
298
290
  }
299
- clearAsync();
300
291
  isUp.current = false;
301
292
  setIsDecrementPressed(null);
302
293
  },