Skip to content

Commit

Permalink
fix: direction support in segment groups and readonly/disabled support
Browse files Browse the repository at this point in the history
  • Loading branch information
logaretm committed Feb 19, 2025
1 parent 1f1d7b7 commit 379b5cf
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 4 deletions.
5 changes: 5 additions & 0 deletions packages/core/src/useDateTimeField/useDateTimeField.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import { useErrorMessage, useLabel } from '../a11y';
import { fromDateToCalendarZonedDateTime, useTemporalStore } from './useTemporalStore';
import { ZonedDateTime, Calendar } from '@internationalized/date';
import { useInputValidity } from '../validation';
import { createDisabledContext } from '../helpers/createDisabledContext';

export interface DateTimeFieldProps {
/**
Expand Down Expand Up @@ -96,6 +97,7 @@ export function useDateTimeField(_props: Reactivify<DateTimeFieldProps, 'schema'
timeZone: () => toValue(props.timeZone),
});

const isDisabled = createDisabledContext(props.disabled);
const formatter = useDateFormatter(locale, props.formatOptions);
const controlId = useUniqId(FieldTypePrefixes.DateTimeField);

Expand Down Expand Up @@ -126,8 +128,10 @@ export function useDateTimeField(_props: Reactivify<DateTimeFieldProps, 'schema'
formatter,
locale,
formatOptions: props.formatOptions,
direction,
controlEl,
temporalValue,
readonly: props.readonly,
onValueChange,
onTouched: () => field.setTouched(true),
min: computed(() => fromDateToCalendarZonedDateTime(toValue(props.min), calendar.value, timeZone.value)),
Expand Down Expand Up @@ -172,6 +176,7 @@ export function useDateTimeField(_props: Reactivify<DateTimeFieldProps, 'schema'
...labelledByProps.value,
...describedByProps.value,
...accessibleErrorProps.value,
'aria-disabled': isDisabled.value || undefined,
},
controlEl,
);
Expand Down
24 changes: 21 additions & 3 deletions packages/core/src/useDateTimeField/useDateTimeSegment.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { FieldTypePrefixes } from '../constants';
import { blockEvent } from '../utils/events';
import { DateTimeSegmentType } from './types';
import { isEditableSegmentType } from './constants';
import { createDisabledContext } from '../helpers/createDisabledContext';

export interface DateTimeSegmentProps {
/**
Expand All @@ -22,6 +23,11 @@ export interface DateTimeSegmentProps {
* Whether the segment is disabled.
*/
disabled?: boolean;

/**
* Whether the segment is readonly.
*/
readonly?: boolean;
}

interface DateTimeSegmentDomProps {
Expand All @@ -30,6 +36,7 @@ interface DateTimeSegmentDomProps {
role?: string;
contenteditable: string | undefined;
'aria-disabled': boolean | undefined;
'aria-readonly': boolean | undefined;
'data-segment-type': DateTimeSegmentType;
style: CSSProperties;
'aria-label'?: string;
Expand All @@ -48,7 +55,8 @@ export function useDateTimeSegment(_props: Reactivify<DateTimeSegmentProps>) {
const id = useUniqId(FieldTypePrefixes.DateTimeSegment);
const segmentEl = shallowRef<HTMLSpanElement>();
const segmentGroup = inject(DateTimeSegmentGroupKey, null);
const isNonEditable = () => toValue(props.disabled) || !isEditableSegmentType(toValue(props.type));
const isDisabled = createDisabledContext(props.disabled);
const isNonEditable = () => isDisabled.value || !isEditableSegmentType(toValue(props.type));

if (!segmentGroup) {
throw new Error('DateTimeSegmentGroup is not provided');
Expand Down Expand Up @@ -80,6 +88,11 @@ export function useDateTimeSegment(_props: Reactivify<DateTimeSegmentProps>) {
currentInput = '';
},
onBeforeinput(evt: InputEvent) {
if (toValue(props.readonly) || isDisabled.value) {
blockEvent(evt);
return;
}

// No data,like backspace or whatever
if (isNullOrUndefined(evt.data)) {
return;
Expand Down Expand Up @@ -129,6 +142,10 @@ export function useDateTimeSegment(_props: Reactivify<DateTimeSegmentProps>) {
currentInput = '';
},
onKeydown(evt: KeyboardEvent) {
if (toValue(props.readonly) || isDisabled.value) {
return;
}

if (hasKeyCode(evt, 'Enter')) {
blockEvent(evt);
focusNext();
Expand Down Expand Up @@ -165,9 +182,10 @@ export function useDateTimeSegment(_props: Reactivify<DateTimeSegmentProps>) {
id,
tabindex: isNonEditable() ? -1 : 0,
contenteditable: isNonEditable() ? undefined : 'plaintext-only',
'aria-disabled': toValue(props.disabled),
'aria-disabled': isDisabled.value,
'data-segment-type': toValue(props.type),
'aria-label': isNonEditable() ? undefined : toValue(props.type),
'aria-readonly': toValue(props.readonly) ? true : undefined,
autocorrect: isNonEditable() ? undefined : 'off',
spellcheck: isNonEditable() ? undefined : false,
enterkeyhint: isNonEditable() ? undefined : isLast() ? 'done' : 'next',
Expand Down Expand Up @@ -203,7 +221,7 @@ export function useDateTimeSegment(_props: Reactivify<DateTimeSegmentProps>) {

export const DateTimeSegment = defineComponent<DateTimeSegmentProps>({
name: 'DateTimeSegment',
props: ['type', 'value', 'disabled'],
props: ['type', 'value', 'disabled', 'readonly'],
setup(props) {
const { segmentProps } = useDateTimeSegment(props);

Expand Down
13 changes: 12 additions & 1 deletion packages/core/src/useDateTimeField/useDateTimeSegmentGroup.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ export interface DateTimeSegmentGroupProps {
temporalValue: MaybeRefOrGetter<ZonedDateTime | TemporalPartial>;
direction?: MaybeRefOrGetter<Direction>;
controlEl: Ref<HTMLElement | undefined>;
readonly?: MaybeRefOrGetter<boolean | undefined>;
min?: MaybeRefOrGetter<Maybe<ZonedDateTime>>;
max?: MaybeRefOrGetter<Maybe<ZonedDateTime>>;
onValueChange: (value: ZonedDateTime) => void;
Expand All @@ -59,6 +60,7 @@ export function useDateTimeSegmentGroup({
direction,
locale,
controlEl,
readonly,
min,
max,
onValueChange,
Expand All @@ -78,7 +80,7 @@ export function useDateTimeSegmentGroup({

const segments = computed(() => {
const date = toValue(temporalValue);
const parts = formatter.value.formatToParts(date.toDate()) as {
let parts = formatter.value.formatToParts(date.toDate()) as {
type: DateTimeSegmentType;
value: string;
}[];
Expand All @@ -95,6 +97,15 @@ export function useDateTimeSegmentGroup({
}
}

if (toValue(readonly)) {
parts = parts.map(part => {
return {
...part,
readonly: true,
};
});
}

return parts;
});

Expand Down

0 comments on commit 379b5cf

Please sign in to comment.