@react-aria/datepicker
Advanced tools
Comparing version
@@ -14,3 +14,3 @@ module.exports = { | ||
"selectedTimeDescription": (args)=>`Ausgew\xe4hlte Zeit: ${args.time}`, | ||
"startDate": `Anfangsdatum`, | ||
"startDate": `Startdatum`, | ||
"timeZoneName": `Zeitzone`, | ||
@@ -17,0 +17,0 @@ "weekday": `Wochentag`, |
@@ -15,3 +15,3 @@ var $35cea00159787840$exports = {}; | ||
"selectedTimeDescription": (args)=>`Ausgew\xe4hlte Zeit: ${args.time}`, | ||
"startDate": `Anfangsdatum`, | ||
"startDate": `Startdatum`, | ||
"timeZoneName": `Zeitzone`, | ||
@@ -18,0 +18,0 @@ "weekday": `Wochentag`, |
@@ -123,3 +123,3 @@ var $c1905b78f6d2f5bf$exports = require("./intlStrings.main.js"); | ||
]); | ||
(0, $lVMtq$reactariautils.useFormReset)(props.inputRef, state.value, state.setValue); | ||
(0, $lVMtq$reactariautils.useFormReset)(props.inputRef, state.defaultValue, state.setValue); | ||
(0, $lVMtq$reactariaform.useFormValidation)({ | ||
@@ -134,2 +134,3 @@ ...props, | ||
name: props.name, | ||
form: props.form, | ||
value: ((_state_value = state.value) === null || _state_value === void 0 ? void 0 : _state_value.toString()) || '', | ||
@@ -161,2 +162,5 @@ disabled: props.isDisabled | ||
if (props.onKeyUp) props.onKeyUp(e); | ||
}, | ||
style: { | ||
unicodeBidi: 'isolate' | ||
} | ||
@@ -163,0 +167,0 @@ }), |
@@ -113,3 +113,3 @@ import $7Gzdi$intlStringsmodulejs from "./intlStrings.module.js"; | ||
]); | ||
(0, $7Gzdi$useFormReset)(props.inputRef, state.value, state.setValue); | ||
(0, $7Gzdi$useFormReset)(props.inputRef, state.defaultValue, state.setValue); | ||
(0, $7Gzdi$useFormValidation)({ | ||
@@ -124,2 +124,3 @@ ...props, | ||
name: props.name, | ||
form: props.form, | ||
value: ((_state_value = state.value) === null || _state_value === void 0 ? void 0 : _state_value.toString()) || '', | ||
@@ -151,2 +152,5 @@ disabled: props.isDisabled | ||
if (props.onKeyUp) props.onKeyUp(e); | ||
}, | ||
style: { | ||
unicodeBidi: 'isolate' | ||
} | ||
@@ -153,0 +157,0 @@ }), |
@@ -72,8 +72,24 @@ var $c1905b78f6d2f5bf$exports = require("./intlStrings.main.js"); | ||
]); | ||
let isFocused = (0, $bxHoL$react.useRef)(false); | ||
let { focusWithinProps: focusWithinProps } = (0, $bxHoL$reactariainteractions.useFocusWithin)({ | ||
...props, | ||
isDisabled: state.isOpen, | ||
onBlurWithin: props.onBlur, | ||
onFocusWithin: props.onFocus, | ||
onFocusWithinChange: props.onFocusChange | ||
onBlurWithin: (e)=>{ | ||
// Ignore when focus moves into the popover. | ||
let dialog = document.getElementById(dialogId); | ||
if (!(dialog === null || dialog === void 0 ? void 0 : dialog.contains(e.relatedTarget))) { | ||
var _props_onBlur, _props_onFocusChange; | ||
isFocused.current = false; | ||
(_props_onBlur = props.onBlur) === null || _props_onBlur === void 0 ? void 0 : _props_onBlur.call(props, e); | ||
(_props_onFocusChange = props.onFocusChange) === null || _props_onFocusChange === void 0 ? void 0 : _props_onFocusChange.call(props, false); | ||
} | ||
}, | ||
onFocusWithin: (e)=>{ | ||
if (!isFocused.current) { | ||
var _props_onFocus, _props_onFocusChange; | ||
isFocused.current = true; | ||
(_props_onFocus = props.onFocus) === null || _props_onFocus === void 0 ? void 0 : _props_onFocus.call(props, e); | ||
(_props_onFocusChange = props.onFocusChange) === null || _props_onFocusChange === void 0 ? void 0 : _props_onFocusChange.call(props, true); | ||
} | ||
} | ||
}); | ||
@@ -107,2 +123,3 @@ return { | ||
value: state.value, | ||
defaultValue: state.defaultValue, | ||
onChange: state.setValue, | ||
@@ -121,3 +138,4 @@ placeholderValue: props.placeholderValue, | ||
autoFocus: props.autoFocus, | ||
name: props.name | ||
name: props.name, | ||
form: props.form | ||
}, | ||
@@ -152,3 +170,5 @@ descriptionProps: descriptionProps, | ||
isInvalid: state.isInvalid, | ||
errorMessage: typeof props.errorMessage === 'function' ? props.errorMessage(state.displayValidation) : props.errorMessage || state.displayValidation.validationErrors.join(' ') | ||
errorMessage: typeof props.errorMessage === 'function' ? props.errorMessage(state.displayValidation) : props.errorMessage || state.displayValidation.validationErrors.join(' '), | ||
firstDayOfWeek: props.firstDayOfWeek, | ||
pageBehavior: props.pageBehavior | ||
}, | ||
@@ -155,0 +175,0 @@ isInvalid: isInvalid, |
@@ -10,3 +10,3 @@ import $4lVjK$intlStringsmodulejs from "./intlStrings.module.js"; | ||
import {useLocalizedStringFormatter as $4lVjK$useLocalizedStringFormatter, useLocale as $4lVjK$useLocale} from "@react-aria/i18n"; | ||
import {useMemo as $4lVjK$useMemo} from "react"; | ||
import {useMemo as $4lVjK$useMemo, useRef as $4lVjK$useRef} from "react"; | ||
@@ -67,8 +67,24 @@ | ||
]); | ||
let isFocused = (0, $4lVjK$useRef)(false); | ||
let { focusWithinProps: focusWithinProps } = (0, $4lVjK$useFocusWithin)({ | ||
...props, | ||
isDisabled: state.isOpen, | ||
onBlurWithin: props.onBlur, | ||
onFocusWithin: props.onFocus, | ||
onFocusWithinChange: props.onFocusChange | ||
onBlurWithin: (e)=>{ | ||
// Ignore when focus moves into the popover. | ||
let dialog = document.getElementById(dialogId); | ||
if (!(dialog === null || dialog === void 0 ? void 0 : dialog.contains(e.relatedTarget))) { | ||
var _props_onBlur, _props_onFocusChange; | ||
isFocused.current = false; | ||
(_props_onBlur = props.onBlur) === null || _props_onBlur === void 0 ? void 0 : _props_onBlur.call(props, e); | ||
(_props_onFocusChange = props.onFocusChange) === null || _props_onFocusChange === void 0 ? void 0 : _props_onFocusChange.call(props, false); | ||
} | ||
}, | ||
onFocusWithin: (e)=>{ | ||
if (!isFocused.current) { | ||
var _props_onFocus, _props_onFocusChange; | ||
isFocused.current = true; | ||
(_props_onFocus = props.onFocus) === null || _props_onFocus === void 0 ? void 0 : _props_onFocus.call(props, e); | ||
(_props_onFocusChange = props.onFocusChange) === null || _props_onFocusChange === void 0 ? void 0 : _props_onFocusChange.call(props, true); | ||
} | ||
} | ||
}); | ||
@@ -102,2 +118,3 @@ return { | ||
value: state.value, | ||
defaultValue: state.defaultValue, | ||
onChange: state.setValue, | ||
@@ -116,3 +133,4 @@ placeholderValue: props.placeholderValue, | ||
autoFocus: props.autoFocus, | ||
name: props.name | ||
name: props.name, | ||
form: props.form | ||
}, | ||
@@ -147,3 +165,5 @@ descriptionProps: descriptionProps, | ||
isInvalid: state.isInvalid, | ||
errorMessage: typeof props.errorMessage === 'function' ? props.errorMessage(state.displayValidation) : props.errorMessage || state.displayValidation.validationErrors.join(' ') | ||
errorMessage: typeof props.errorMessage === 'function' ? props.errorMessage(state.displayValidation) : props.errorMessage || state.displayValidation.validationErrors.join(' '), | ||
firstDayOfWeek: props.firstDayOfWeek, | ||
pageBehavior: props.pageBehavior | ||
}, | ||
@@ -150,0 +170,0 @@ isInvalid: isInvalid, |
@@ -36,4 +36,9 @@ var $19S5E$reactariafocus = require("@react-aria/focus"); | ||
e.stopPropagation(); | ||
if (direction === 'rtl') focusManager.focusNext(); | ||
else focusManager.focusPrevious(); | ||
if (direction === 'rtl') { | ||
if (ref.current) { | ||
let target = e.target; | ||
let prev = $715562ad3b4cced4$var$findNextSegment(ref.current, target.getBoundingClientRect().left, -1); | ||
if (prev) prev.focus(); | ||
} | ||
} else focusManager.focusPrevious(); | ||
break; | ||
@@ -43,4 +48,9 @@ case 'ArrowRight': | ||
e.stopPropagation(); | ||
if (direction === 'rtl') focusManager.focusPrevious(); | ||
else focusManager.focusNext(); | ||
if (direction === 'rtl') { | ||
if (ref.current) { | ||
let target = e.target; | ||
let next = $715562ad3b4cced4$var$findNextSegment(ref.current, target.getBoundingClientRect().left, 1); | ||
if (next) next.focus(); | ||
} | ||
} else focusManager.focusNext(); | ||
break; | ||
@@ -85,3 +95,3 @@ } | ||
onPress (e) { | ||
if (e.pointerType !== 'mouse') focusLast(); | ||
if (e.pointerType === 'touch' || e.pointerType === 'pen') focusLast(); | ||
} | ||
@@ -93,4 +103,23 @@ }); | ||
} | ||
function $715562ad3b4cced4$var$findNextSegment(group, fromX, direction) { | ||
let walker = (0, $19S5E$reactariafocus.getFocusableTreeWalker)(group, { | ||
tabbable: true | ||
}); | ||
let node = walker.nextNode(); | ||
let closest = null; | ||
let closestDistance = Infinity; | ||
while(node){ | ||
let x = node.getBoundingClientRect().left; | ||
let distance = x - fromX; | ||
let absoluteDistance = Math.abs(distance); | ||
if (Math.sign(distance) === direction && absoluteDistance < closestDistance) { | ||
closest = node; | ||
closestDistance = absoluteDistance; | ||
} | ||
node = walker.nextNode(); | ||
} | ||
return closest; | ||
} | ||
//# sourceMappingURL=useDatePickerGroup.main.js.map |
@@ -30,4 +30,9 @@ import {createFocusManager as $7CEvq$createFocusManager, getFocusableTreeWalker as $7CEvq$getFocusableTreeWalker} from "@react-aria/focus"; | ||
e.stopPropagation(); | ||
if (direction === 'rtl') focusManager.focusNext(); | ||
else focusManager.focusPrevious(); | ||
if (direction === 'rtl') { | ||
if (ref.current) { | ||
let target = e.target; | ||
let prev = $3dfb0f96be0d6a08$var$findNextSegment(ref.current, target.getBoundingClientRect().left, -1); | ||
if (prev) prev.focus(); | ||
} | ||
} else focusManager.focusPrevious(); | ||
break; | ||
@@ -37,4 +42,9 @@ case 'ArrowRight': | ||
e.stopPropagation(); | ||
if (direction === 'rtl') focusManager.focusPrevious(); | ||
else focusManager.focusNext(); | ||
if (direction === 'rtl') { | ||
if (ref.current) { | ||
let target = e.target; | ||
let next = $3dfb0f96be0d6a08$var$findNextSegment(ref.current, target.getBoundingClientRect().left, 1); | ||
if (next) next.focus(); | ||
} | ||
} else focusManager.focusNext(); | ||
break; | ||
@@ -79,3 +89,3 @@ } | ||
onPress (e) { | ||
if (e.pointerType !== 'mouse') focusLast(); | ||
if (e.pointerType === 'touch' || e.pointerType === 'pen') focusLast(); | ||
} | ||
@@ -87,2 +97,21 @@ }); | ||
} | ||
function $3dfb0f96be0d6a08$var$findNextSegment(group, fromX, direction) { | ||
let walker = (0, $7CEvq$getFocusableTreeWalker)(group, { | ||
tabbable: true | ||
}); | ||
let node = walker.nextNode(); | ||
let closest = null; | ||
let closestDistance = Infinity; | ||
while(node){ | ||
let x = node.getBoundingClientRect().left; | ||
let distance = x - fromX; | ||
let absoluteDistance = Math.abs(distance); | ||
if (Math.sign(distance) === direction && absoluteDistance < closestDistance) { | ||
closest = node; | ||
closestDistance = absoluteDistance; | ||
} | ||
node = walker.nextNode(); | ||
} | ||
return closest; | ||
} | ||
@@ -89,0 +118,0 @@ |
@@ -43,3 +43,3 @@ var $4acc2f407c169e55$exports = require("./useDateField.main.js"); | ||
function $20f695b1b69e6b9e$export$12fd5f0e9f4bb192(props, state, ref) { | ||
var _state_value, _state_value1, _state_dateRange; | ||
var _state_value, _state_defaultValue, _state_value1, _state_defaultValue1, _state_dateRange; | ||
let stringFormatter = (0, $Xt1Bd$reactariai18n.useLocalizedStringFormatter)((0, ($parcel$interopDefault($c1905b78f6d2f5bf$exports))), '@react-aria/datepicker'); | ||
@@ -100,8 +100,24 @@ let { isInvalid: isInvalid, validationErrors: validationErrors, validationDetails: validationDetails } = state.displayValidation; | ||
let domProps = (0, $Xt1Bd$reactariautils.filterDOMProps)(props); | ||
let isFocused = (0, $Xt1Bd$react.useRef)(false); | ||
let { focusWithinProps: focusWithinProps } = (0, $Xt1Bd$reactariainteractions.useFocusWithin)({ | ||
...props, | ||
isDisabled: state.isOpen, | ||
onBlurWithin: props.onBlur, | ||
onFocusWithin: props.onFocus, | ||
onFocusWithinChange: props.onFocusChange | ||
onBlurWithin: (e)=>{ | ||
// Ignore when focus moves into the popover. | ||
let dialog = document.getElementById(dialogId); | ||
if (!(dialog === null || dialog === void 0 ? void 0 : dialog.contains(e.relatedTarget))) { | ||
var _props_onBlur, _props_onFocusChange; | ||
isFocused.current = false; | ||
(_props_onBlur = props.onBlur) === null || _props_onBlur === void 0 ? void 0 : _props_onBlur.call(props, e); | ||
(_props_onFocusChange = props.onFocusChange) === null || _props_onFocusChange === void 0 ? void 0 : _props_onFocusChange.call(props, false); | ||
} | ||
}, | ||
onFocusWithin: (e)=>{ | ||
if (!isFocused.current) { | ||
var _props_onFocus, _props_onFocusChange; | ||
isFocused.current = true; | ||
(_props_onFocus = props.onFocus) === null || _props_onFocus === void 0 ? void 0 : _props_onFocus.call(props, e); | ||
(_props_onFocusChange = props.onFocusChange) === null || _props_onFocusChange === void 0 ? void 0 : _props_onFocusChange.call(props, true); | ||
} | ||
} | ||
}); | ||
@@ -150,5 +166,7 @@ let startFieldValidation = (0, $Xt1Bd$react.useRef)((0, $Xt1Bd$reactstatelyform.DEFAULT_VALIDATION_RESULT)); | ||
value: (_state_value_start = (_state_value = state.value) === null || _state_value === void 0 ? void 0 : _state_value.start) !== null && _state_value_start !== void 0 ? _state_value_start : null, | ||
defaultValue: (_state_defaultValue = state.defaultValue) === null || _state_defaultValue === void 0 ? void 0 : _state_defaultValue.start, | ||
onChange: (start)=>state.setDateTime('start', start), | ||
autoFocus: props.autoFocus, | ||
name: props.startName, | ||
form: props.form, | ||
[(0, $Xt1Bd$reactstatelyform.privateValidationStateProp)]: { | ||
@@ -169,4 +187,6 @@ realtimeValidation: state.realtimeValidation, | ||
value: (_state_value_end = (_state_value1 = state.value) === null || _state_value1 === void 0 ? void 0 : _state_value1.end) !== null && _state_value_end !== void 0 ? _state_value_end : null, | ||
defaultValue: (_state_defaultValue1 = state.defaultValue) === null || _state_defaultValue1 === void 0 ? void 0 : _state_defaultValue1.end, | ||
onChange: (end)=>state.setDateTime('end', end), | ||
name: props.endName, | ||
form: props.form, | ||
[(0, $Xt1Bd$reactstatelyform.privateValidationStateProp)]: { | ||
@@ -197,3 +217,5 @@ realtimeValidation: state.realtimeValidation, | ||
isInvalid: state.isInvalid, | ||
errorMessage: typeof props.errorMessage === 'function' ? props.errorMessage(state.displayValidation) : props.errorMessage || state.displayValidation.validationErrors.join(' ') | ||
errorMessage: typeof props.errorMessage === 'function' ? props.errorMessage(state.displayValidation) : props.errorMessage || state.displayValidation.validationErrors.join(' '), | ||
firstDayOfWeek: props.firstDayOfWeek, | ||
pageBehavior: props.pageBehavior | ||
}, | ||
@@ -200,0 +222,0 @@ isInvalid: isInvalid, |
@@ -37,3 +37,3 @@ import {focusManagerSymbol as $16f0b7bb276bc17e$export$7b3062cd49e80452, roleSymbol as $16f0b7bb276bc17e$export$300019f83c56d282} from "./useDateField.module.js"; | ||
function $887cac91b7cc8801$export$12fd5f0e9f4bb192(props, state, ref) { | ||
var _state_value, _state_value1, _state_dateRange; | ||
var _state_value, _state_defaultValue, _state_value1, _state_defaultValue1, _state_dateRange; | ||
let stringFormatter = (0, $eIQ1H$useLocalizedStringFormatter)((0, ($parcel$interopDefault($eIQ1H$intlStringsmodulejs))), '@react-aria/datepicker'); | ||
@@ -94,8 +94,24 @@ let { isInvalid: isInvalid, validationErrors: validationErrors, validationDetails: validationDetails } = state.displayValidation; | ||
let domProps = (0, $eIQ1H$filterDOMProps)(props); | ||
let isFocused = (0, $eIQ1H$useRef)(false); | ||
let { focusWithinProps: focusWithinProps } = (0, $eIQ1H$useFocusWithin)({ | ||
...props, | ||
isDisabled: state.isOpen, | ||
onBlurWithin: props.onBlur, | ||
onFocusWithin: props.onFocus, | ||
onFocusWithinChange: props.onFocusChange | ||
onBlurWithin: (e)=>{ | ||
// Ignore when focus moves into the popover. | ||
let dialog = document.getElementById(dialogId); | ||
if (!(dialog === null || dialog === void 0 ? void 0 : dialog.contains(e.relatedTarget))) { | ||
var _props_onBlur, _props_onFocusChange; | ||
isFocused.current = false; | ||
(_props_onBlur = props.onBlur) === null || _props_onBlur === void 0 ? void 0 : _props_onBlur.call(props, e); | ||
(_props_onFocusChange = props.onFocusChange) === null || _props_onFocusChange === void 0 ? void 0 : _props_onFocusChange.call(props, false); | ||
} | ||
}, | ||
onFocusWithin: (e)=>{ | ||
if (!isFocused.current) { | ||
var _props_onFocus, _props_onFocusChange; | ||
isFocused.current = true; | ||
(_props_onFocus = props.onFocus) === null || _props_onFocus === void 0 ? void 0 : _props_onFocus.call(props, e); | ||
(_props_onFocusChange = props.onFocusChange) === null || _props_onFocusChange === void 0 ? void 0 : _props_onFocusChange.call(props, true); | ||
} | ||
} | ||
}); | ||
@@ -144,5 +160,7 @@ let startFieldValidation = (0, $eIQ1H$useRef)((0, $eIQ1H$DEFAULT_VALIDATION_RESULT)); | ||
value: (_state_value_start = (_state_value = state.value) === null || _state_value === void 0 ? void 0 : _state_value.start) !== null && _state_value_start !== void 0 ? _state_value_start : null, | ||
defaultValue: (_state_defaultValue = state.defaultValue) === null || _state_defaultValue === void 0 ? void 0 : _state_defaultValue.start, | ||
onChange: (start)=>state.setDateTime('start', start), | ||
autoFocus: props.autoFocus, | ||
name: props.startName, | ||
form: props.form, | ||
[(0, $eIQ1H$privateValidationStateProp)]: { | ||
@@ -163,4 +181,6 @@ realtimeValidation: state.realtimeValidation, | ||
value: (_state_value_end = (_state_value1 = state.value) === null || _state_value1 === void 0 ? void 0 : _state_value1.end) !== null && _state_value_end !== void 0 ? _state_value_end : null, | ||
defaultValue: (_state_defaultValue1 = state.defaultValue) === null || _state_defaultValue1 === void 0 ? void 0 : _state_defaultValue1.end, | ||
onChange: (end)=>state.setDateTime('end', end), | ||
name: props.endName, | ||
form: props.form, | ||
[(0, $eIQ1H$privateValidationStateProp)]: { | ||
@@ -191,3 +211,5 @@ realtimeValidation: state.realtimeValidation, | ||
isInvalid: state.isInvalid, | ||
errorMessage: typeof props.errorMessage === 'function' ? props.errorMessage(state.displayValidation) : props.errorMessage || state.displayValidation.validationErrors.join(' ') | ||
errorMessage: typeof props.errorMessage === 'function' ? props.errorMessage(state.displayValidation) : props.errorMessage || state.displayValidation.validationErrors.join(' '), | ||
firstDayOfWeek: props.firstDayOfWeek, | ||
pageBehavior: props.pageBehavior | ||
}, | ||
@@ -194,0 +216,0 @@ isInvalid: isInvalid, |
@@ -40,3 +40,3 @@ var $4acc2f407c169e55$exports = require("./useDateField.main.js"); | ||
let enteredKeys = (0, $5Tgzj$react.useRef)(''); | ||
let { locale: locale } = (0, $5Tgzj$reactariai18n.useLocale)(); | ||
let { locale: locale, direction: direction } = (0, $5Tgzj$reactariai18n.useLocale)(); | ||
let displayNames = (0, $934ac650a0aceb4b$exports.useDisplayNames)(); | ||
@@ -332,2 +332,13 @@ let { ariaLabel: ariaLabel, ariaLabelledBy: ariaLabelledBy, ariaDescribedBy: ariaDescribedBy, focusManager: focusManager } = (0, $4acc2f407c169e55$exports.hookData).get(state); | ||
}; | ||
let segmentStyle = { | ||
caretColor: 'transparent' | ||
}; | ||
if (direction === 'rtl') { | ||
// While the bidirectional algorithm seems to work properly on inline elements with actual values, it returns different results for placeholder strings. | ||
// To ensure placeholder render in correct format, we apply the CSS equivalent of LRE (left-to-right embedding). See https://www.unicode.org/reports/tr9/#Explicit_Directional_Embeddings. | ||
// However, we apply this to both placeholders and date segments with an actual value because the date segments will shift around when deleting otherwise. | ||
segmentStyle.unicodeBidi = 'embed'; | ||
let format = options[segment.type]; | ||
if (format === 'numeric' || format === '2-digit') segmentStyle.direction = 'ltr'; | ||
} | ||
return { | ||
@@ -351,5 +362,3 @@ segmentProps: (0, $5Tgzj$reactariautils.mergeProps)(spinButtonProps, labelProps, { | ||
onFocus: onFocus, | ||
style: { | ||
caretColor: 'transparent' | ||
}, | ||
style: segmentStyle, | ||
// Prevent pointer events from reaching useDatePickerGroup, and allow native browser behavior to focus the segment. | ||
@@ -356,0 +365,0 @@ onPointerDown (e) { |
@@ -30,3 +30,3 @@ import {hookData as $16f0b7bb276bc17e$export$653eddfc964b0f8a} from "./useDateField.module.js"; | ||
let enteredKeys = (0, $4d1jn$useRef)(''); | ||
let { locale: locale } = (0, $4d1jn$useLocale)(); | ||
let { locale: locale, direction: direction } = (0, $4d1jn$useLocale)(); | ||
let displayNames = (0, $3aeceb3a64eb8358$export$d42c60378c8168f8)(); | ||
@@ -322,2 +322,13 @@ let { ariaLabel: ariaLabel, ariaLabelledBy: ariaLabelledBy, ariaDescribedBy: ariaDescribedBy, focusManager: focusManager } = (0, $16f0b7bb276bc17e$export$653eddfc964b0f8a).get(state); | ||
}; | ||
let segmentStyle = { | ||
caretColor: 'transparent' | ||
}; | ||
if (direction === 'rtl') { | ||
// While the bidirectional algorithm seems to work properly on inline elements with actual values, it returns different results for placeholder strings. | ||
// To ensure placeholder render in correct format, we apply the CSS equivalent of LRE (left-to-right embedding). See https://www.unicode.org/reports/tr9/#Explicit_Directional_Embeddings. | ||
// However, we apply this to both placeholders and date segments with an actual value because the date segments will shift around when deleting otherwise. | ||
segmentStyle.unicodeBidi = 'embed'; | ||
let format = options[segment.type]; | ||
if (format === 'numeric' || format === '2-digit') segmentStyle.direction = 'ltr'; | ||
} | ||
return { | ||
@@ -341,5 +352,3 @@ segmentProps: (0, $4d1jn$mergeProps)(spinButtonProps, labelProps, { | ||
onFocus: onFocus, | ||
style: { | ||
caretColor: 'transparent' | ||
}, | ||
style: segmentStyle, | ||
// Prevent pointer events from reaching useDatePickerGroup, and allow native browser behavior to focus the segment. | ||
@@ -346,0 +355,0 @@ onPointerDown (e) { |
{ | ||
"name": "@react-aria/datepicker", | ||
"version": "3.0.0-nightly-ec25ca46d-241211", | ||
"version": "3.0.0-nightly-ecb05e28d-250909", | ||
"description": "Spectrum UI components in React", | ||
@@ -9,3 +9,7 @@ "license": "Apache-2.0", | ||
"exports": { | ||
"types": "./dist/types.d.ts", | ||
"source": "./src/index.ts", | ||
"types": [ | ||
"./dist/types.d.ts", | ||
"./src/index.ts" | ||
], | ||
"import": "./dist/import.mjs", | ||
@@ -26,19 +30,19 @@ "require": "./dist/main.js" | ||
"dependencies": { | ||
"@internationalized/date": "3.0.0-nightly-ec25ca46d-241211", | ||
"@internationalized/number": "3.0.0-nightly-ec25ca46d-241211", | ||
"@internationalized/string": "3.0.0-nightly-ec25ca46d-241211", | ||
"@react-aria/focus": "3.0.0-nightly-ec25ca46d-241211", | ||
"@react-aria/form": "3.0.0-nightly-ec25ca46d-241211", | ||
"@react-aria/i18n": "3.0.0-nightly-ec25ca46d-241211", | ||
"@react-aria/interactions": "3.0.0-nightly-ec25ca46d-241211", | ||
"@react-aria/label": "3.0.0-nightly-ec25ca46d-241211", | ||
"@react-aria/spinbutton": "3.0.0-nightly-ec25ca46d-241211", | ||
"@react-aria/utils": "3.0.0-nightly-ec25ca46d-241211", | ||
"@react-stately/datepicker": "3.0.0-nightly-ec25ca46d-241211", | ||
"@react-stately/form": "3.0.0-nightly-ec25ca46d-241211", | ||
"@react-types/button": "3.0.0-nightly-ec25ca46d-241211", | ||
"@react-types/calendar": "3.0.0-nightly-ec25ca46d-241211", | ||
"@react-types/datepicker": "3.0.0-nightly-ec25ca46d-241211", | ||
"@react-types/dialog": "3.0.0-nightly-ec25ca46d-241211", | ||
"@react-types/shared": "3.0.0-nightly-ec25ca46d-241211", | ||
"@internationalized/date": "3.0.0-nightly-ecb05e28d-250909", | ||
"@internationalized/number": "3.0.0-nightly-ecb05e28d-250909", | ||
"@internationalized/string": "3.0.0-nightly-ecb05e28d-250909", | ||
"@react-aria/focus": "3.0.0-nightly-ecb05e28d-250909", | ||
"@react-aria/form": "3.0.0-nightly-ecb05e28d-250909", | ||
"@react-aria/i18n": "3.0.0-nightly-ecb05e28d-250909", | ||
"@react-aria/interactions": "3.0.0-nightly-ecb05e28d-250909", | ||
"@react-aria/label": "3.0.0-nightly-ecb05e28d-250909", | ||
"@react-aria/spinbutton": "3.0.0-nightly-ecb05e28d-250909", | ||
"@react-aria/utils": "3.0.0-nightly-ecb05e28d-250909", | ||
"@react-stately/datepicker": "3.0.0-nightly-ecb05e28d-250909", | ||
"@react-stately/form": "3.0.0-nightly-ecb05e28d-250909", | ||
"@react-types/button": "3.0.0-nightly-ecb05e28d-250909", | ||
"@react-types/calendar": "3.0.0-nightly-ecb05e28d-250909", | ||
"@react-types/datepicker": "3.0.0-nightly-ecb05e28d-250909", | ||
"@react-types/dialog": "3.0.0-nightly-ecb05e28d-250909", | ||
"@react-types/shared": "3.0.0-nightly-ecb05e28d-250909", | ||
"@swc/helpers": "^0.5.0" | ||
@@ -45,0 +49,0 @@ }, |
@@ -54,8 +54,8 @@ /* | ||
export const hookData = new WeakMap<DateFieldState, HookData>(); | ||
export const hookData: WeakMap<DateFieldState, HookData> = new WeakMap<DateFieldState, HookData>(); | ||
// Private props that we pass from useDatePicker/useDateRangePicker. | ||
// Ideally we'd use a Symbol for this, but React doesn't support them: https://github.com/facebook/react/issues/7552 | ||
export const roleSymbol = '__role_' + Date.now(); | ||
export const focusManagerSymbol = '__focusManager_' + Date.now(); | ||
export const roleSymbol: string = '__role_' + Date.now(); | ||
export const focusManagerSymbol: string = '__focusManager_' + Date.now(); | ||
@@ -142,3 +142,3 @@ /** | ||
useFormReset(props.inputRef, state.value, state.setValue); | ||
useFormReset(props.inputRef, state.defaultValue, state.setValue); | ||
useFormValidation({ | ||
@@ -154,2 +154,3 @@ ...props, | ||
name: props.name, | ||
form: props.form, | ||
value: state.value?.toString() || '', | ||
@@ -187,2 +188,5 @@ disabled: props.isDisabled | ||
} | ||
}, | ||
style: { | ||
unicodeBidi: 'isolate' | ||
} | ||
@@ -189,0 +193,0 @@ }), |
@@ -29,3 +29,3 @@ /* | ||
import {useLocale, useLocalizedStringFormatter} from '@react-aria/i18n'; | ||
import {useMemo} from 'react'; | ||
import {useMemo, useRef} from 'react'; | ||
@@ -81,8 +81,22 @@ export interface DatePickerAria extends ValidationResult { | ||
let isFocused = useRef(false); | ||
let {focusWithinProps} = useFocusWithin({ | ||
...props, | ||
isDisabled: state.isOpen, | ||
onBlurWithin: props.onBlur, | ||
onFocusWithin: props.onFocus, | ||
onFocusWithinChange: props.onFocusChange | ||
onBlurWithin: e => { | ||
// Ignore when focus moves into the popover. | ||
let dialog = document.getElementById(dialogId); | ||
if (!dialog?.contains(e.relatedTarget)) { | ||
isFocused.current = false; | ||
props.onBlur?.(e); | ||
props.onFocusChange?.(false); | ||
} | ||
}, | ||
onFocusWithin: e => { | ||
if (!isFocused.current) { | ||
isFocused.current = true; | ||
props.onFocus?.(e); | ||
props.onFocusChange?.(true); | ||
} | ||
} | ||
}); | ||
@@ -127,2 +141,3 @@ | ||
value: state.value, | ||
defaultValue: state.defaultValue, | ||
onChange: state.setValue, | ||
@@ -141,3 +156,4 @@ placeholderValue: props.placeholderValue, | ||
autoFocus: props.autoFocus, | ||
name: props.name | ||
name: props.name, | ||
form: props.form | ||
}, | ||
@@ -172,3 +188,5 @@ descriptionProps, | ||
isInvalid: state.isInvalid, | ||
errorMessage: typeof props.errorMessage === 'function' ? props.errorMessage(state.displayValidation) : (props.errorMessage || state.displayValidation.validationErrors.join(' ')) | ||
errorMessage: typeof props.errorMessage === 'function' ? props.errorMessage(state.displayValidation) : (props.errorMessage || state.displayValidation.validationErrors.join(' ')), | ||
firstDayOfWeek: props.firstDayOfWeek, | ||
pageBehavior: props.pageBehavior | ||
}, | ||
@@ -175,0 +193,0 @@ isInvalid, |
import {createFocusManager, getFocusableTreeWalker} from '@react-aria/focus'; | ||
import {DateFieldState, DatePickerState, DateRangePickerState} from '@react-stately/datepicker'; | ||
import {FocusableElement, KeyboardEvent, RefObject} from '@react-types/shared'; | ||
import {DOMAttributes, FocusableElement, KeyboardEvent, RefObject} from '@react-types/shared'; | ||
import {mergeProps} from '@react-aria/utils'; | ||
@@ -9,3 +9,3 @@ import {useLocale} from '@react-aria/i18n'; | ||
export function useDatePickerGroup(state: DatePickerState | DateRangePickerState | DateFieldState, ref: RefObject<Element | null>, disableArrowNavigation?: boolean) { | ||
export function useDatePickerGroup(state: DatePickerState | DateRangePickerState | DateFieldState, ref: RefObject<Element | null>, disableArrowNavigation?: boolean): DOMAttributes<FocusableElement> { | ||
let {direction} = useLocale(); | ||
@@ -35,3 +35,10 @@ let focusManager = useMemo(() => createFocusManager(ref), [ref]); | ||
if (direction === 'rtl') { | ||
focusManager.focusNext(); | ||
if (ref.current) { | ||
let target = e.target as FocusableElement; | ||
let prev = findNextSegment(ref.current, target.getBoundingClientRect().left, -1); | ||
if (prev) { | ||
prev.focus(); | ||
} | ||
} | ||
} else { | ||
@@ -45,3 +52,10 @@ focusManager.focusPrevious(); | ||
if (direction === 'rtl') { | ||
focusManager.focusPrevious(); | ||
if (ref.current) { | ||
let target = e.target as FocusableElement; | ||
let next = findNextSegment(ref.current, target.getBoundingClientRect().left, 1); | ||
if (next) { | ||
next.focus(); | ||
} | ||
} | ||
} else { | ||
@@ -102,3 +116,3 @@ focusManager.focusNext(); | ||
onPress(e) { | ||
if (e.pointerType !== 'mouse') { | ||
if (e.pointerType === 'touch' || e.pointerType === 'pen') { | ||
focusLast(); | ||
@@ -111,1 +125,19 @@ } | ||
} | ||
function findNextSegment(group: Element, fromX: number, direction: number) { | ||
let walker = getFocusableTreeWalker(group, {tabbable: true}); | ||
let node = walker.nextNode(); | ||
let closest: FocusableElement | null = null; | ||
let closestDistance = Infinity; | ||
while (node) { | ||
let x = (node as Element).getBoundingClientRect().left; | ||
let distance = x - fromX; | ||
let absoluteDistance = Math.abs(distance); | ||
if (Math.sign(distance) === direction && absoluteDistance < closestDistance) { | ||
closest = node as FocusableElement; | ||
closestDistance = absoluteDistance; | ||
} | ||
node = walker.nextNode(); | ||
} | ||
return closest; | ||
} |
@@ -112,8 +112,22 @@ /* | ||
let isFocused = useRef(false); | ||
let {focusWithinProps} = useFocusWithin({ | ||
...props, | ||
isDisabled: state.isOpen, | ||
onBlurWithin: props.onBlur, | ||
onFocusWithin: props.onFocus, | ||
onFocusWithinChange: props.onFocusChange | ||
onBlurWithin: e => { | ||
// Ignore when focus moves into the popover. | ||
let dialog = document.getElementById(dialogId); | ||
if (!dialog?.contains(e.relatedTarget)) { | ||
isFocused.current = false; | ||
props.onBlur?.(e); | ||
props.onFocusChange?.(false); | ||
} | ||
}, | ||
onFocusWithin: e => { | ||
if (!isFocused.current) { | ||
isFocused.current = true; | ||
props.onFocus?.(e); | ||
props.onFocusChange?.(true); | ||
} | ||
} | ||
}); | ||
@@ -173,5 +187,7 @@ | ||
value: state.value?.start ?? null, | ||
defaultValue: state.defaultValue?.start, | ||
onChange: start => state.setDateTime('start', start), | ||
autoFocus: props.autoFocus, | ||
name: props.startName, | ||
form: props.form, | ||
[privateValidationStateProp]: { | ||
@@ -192,4 +208,6 @@ realtimeValidation: state.realtimeValidation, | ||
value: state.value?.end ?? null, | ||
defaultValue: state.defaultValue?.end, | ||
onChange: end => state.setDateTime('end', end), | ||
name: props.endName, | ||
form: props.form, | ||
[privateValidationStateProp]: { | ||
@@ -220,3 +238,5 @@ realtimeValidation: state.realtimeValidation, | ||
isInvalid: state.isInvalid, | ||
errorMessage: typeof props.errorMessage === 'function' ? props.errorMessage(state.displayValidation) : (props.errorMessage || state.displayValidation.validationErrors.join(' ')) | ||
errorMessage: typeof props.errorMessage === 'function' ? props.errorMessage(state.displayValidation) : (props.errorMessage || state.displayValidation.validationErrors.join(' ')), | ||
firstDayOfWeek: props.firstDayOfWeek, | ||
pageBehavior: props.pageBehavior | ||
}, | ||
@@ -223,0 +243,0 @@ isInvalid, |
@@ -18,3 +18,3 @@ /* | ||
import {NumberParser} from '@internationalized/number'; | ||
import React, {useMemo, useRef} from 'react'; | ||
import React, {CSSProperties, useMemo, useRef} from 'react'; | ||
import {RefObject} from '@react-types/shared'; | ||
@@ -37,3 +37,3 @@ import {useDateFormatter, useFilter, useLocale} from '@react-aria/i18n'; | ||
let enteredKeys = useRef(''); | ||
let {locale} = useLocale(); | ||
let {locale, direction} = useLocale(); | ||
let displayNames = useDisplayNames(); | ||
@@ -390,2 +390,14 @@ let {ariaLabel, ariaLabelledBy, ariaDescribedBy, focusManager} = hookData.get(state)!; | ||
let segmentStyle: CSSProperties = {caretColor: 'transparent'}; | ||
if (direction === 'rtl') { | ||
// While the bidirectional algorithm seems to work properly on inline elements with actual values, it returns different results for placeholder strings. | ||
// To ensure placeholder render in correct format, we apply the CSS equivalent of LRE (left-to-right embedding). See https://www.unicode.org/reports/tr9/#Explicit_Directional_Embeddings. | ||
// However, we apply this to both placeholders and date segments with an actual value because the date segments will shift around when deleting otherwise. | ||
segmentStyle.unicodeBidi = 'embed'; | ||
let format = options[segment.type]; | ||
if (format === 'numeric' || format === '2-digit') { | ||
segmentStyle.direction = 'ltr'; | ||
} | ||
} | ||
return { | ||
@@ -409,5 +421,3 @@ segmentProps: mergeProps(spinButtonProps, labelProps, { | ||
onFocus, | ||
style: { | ||
caretColor: 'transparent' | ||
}, | ||
style: segmentStyle, | ||
// Prevent pointer events from reaching useDatePickerGroup, and allow native browser behavior to focus the segment. | ||
@@ -414,0 +424,0 @@ onPointerDown(e) { |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
565747
5.34%6813
5.12%+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
Updated
Updated
Updated
Updated
Updated
Updated
Updated