Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

95 changes: 77 additions & 18 deletions src/components/DatePicker/DatePicker.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -65,16 +65,25 @@ const meta = {
type: { summary: 'boolean' },
},
},
isReadonly: {
description: '編集不可(読み取り専用)状態であるかどうかを指定します。',
control: { type: 'boolean' },
table: {
defaultValue: { summary: 'false' },
type: { summary: 'boolean' },
},
},
},
args: {
size: 'lg',
isError: false,
isDisabled: false,
children: ({ yearRef, monthRef, dateRef }) => (
isReadonly: false,
children: ({ yearRef, monthRef, dateRef, ...rest }) => (
<>
<DatePickerYear ref={yearRef} />
<DatePickerMonth ref={monthRef} />
<DatePickerDate ref={dateRef} />
<DatePickerYear ref={yearRef} {...rest} />
<DatePickerMonth ref={monthRef} {...rest} />
<DatePickerDate ref={dateRef} {...rest} />
</>
),
},
Expand All @@ -95,11 +104,11 @@ export const WithFieldset: Story = {
</Legend>
<SupportText id='date-picker-1-support-text'>例:2025年01月20日</SupportText>
<DatePicker {...args}>
{({ yearRef, monthRef, dateRef }) => (
{({ yearRef, monthRef, dateRef, ...rest }) => (
<>
<DatePickerYear ref={yearRef} />
<DatePickerMonth ref={monthRef} />
<DatePickerDate ref={dateRef} />
<DatePickerYear ref={yearRef} {...rest} />
<DatePickerMonth ref={monthRef} {...rest} />
<DatePickerDate ref={dateRef} {...rest} />
</>
)}
</DatePicker>
Expand All @@ -125,24 +134,24 @@ export const Errored: Story = {
</Legend>
<SupportText id='date-picker-3-support-text'>例:2025年01月20日</SupportText>
<DatePicker {...args}>
{({ yearRef, monthRef, dateRef }) => (
{({ yearRef, monthRef, dateRef, ...rest }) => (
<>
<DatePickerYear
ref={yearRef}
aria-describedby='date-picker-3-support-text date-picker-3-error-text'
aria-invalid={true}
{...rest}
/>
<DatePickerMonth
ref={monthRef}
defaultValue={10}
aria-describedby='date-picker-3-support-text date-picker-3-error-text'
aria-invalid={true}
{...rest}
/>
<DatePickerDate
ref={dateRef}
defaultValue={28}
aria-describedby='date-picker-3-support-text date-picker-3-error-text'
aria-invalid={true}
{...rest}
/>
</>
)}
Expand All @@ -166,24 +175,71 @@ export const Disabled: Story = {
<Legend>
日付<RequirementBadge isOptional>※任意</RequirementBadge>
</Legend>
<SupportText id='date-picker-5-support-text'>例:2025年01月20日</SupportText>
<SupportText id='date-picker-5-support-text'>
〜の理由により、この項目は編集できません。
</SupportText>
<DatePicker {...args}>
{({ yearRef, monthRef, dateRef }) => (
{({ yearRef, monthRef, dateRef, ...rest }) => (
<>
<DatePickerYear
ref={yearRef}
aria-disabled={true}
aria-describedby='date-picker-5-support-text'
{...rest}
/>
<DatePickerMonth
ref={monthRef}
aria-disabled={true}
aria-describedby='date-picker-5-support-text'
{...rest}
/>
<DatePickerDate
ref={dateRef}
aria-disabled={true}
aria-describedby='date-picker-5-support-text'
{...rest}
/>
</>
)}
</DatePicker>
</fieldset>
);
},
};

/**
* Readonly状態を表示した例
*/
export const Readonly: Story = {
args: {
isReadonly: true,
},
render({ ...args }) {
return (
<fieldset className='flex flex-col gap-2 items-start'>
<Legend>
日付<RequirementBadge isOptional>※任意</RequirementBadge>
</Legend>
<SupportText id='date-picker-6-support-text'>
〜の理由により、この項目は編集できません。
</SupportText>
<DatePicker {...args}>
{({ yearRef, monthRef, dateRef, ...rest }) => (
<>
<DatePickerYear
ref={yearRef}
value={2025}
aria-describedby='date-picker-6-support-text'
{...rest}
/>
<DatePickerMonth
ref={monthRef}
value={10}
aria-describedby='date-picker-6-support-text'
{...rest}
/>
<DatePickerDate
ref={dateRef}
value={28}
aria-describedby='date-picker-6-support-text'
{...rest}
/>
</>
)}
Expand Down Expand Up @@ -230,25 +286,28 @@ export const WithCalendar: Story = {
return (
<>
<DatePicker size={size} {...args}>
{({ yearRef, monthRef, dateRef }) => (
{({ yearRef, monthRef, dateRef, ...rest }) => (
<>
<DatePickerYear
ref={yearRef}
value={yearInput}
onChange={(e) => setYearInput(e.target.value)}
onBlur={updateCalendarDate}
{...rest}
/>
<DatePickerMonth
ref={monthRef}
value={monthInput}
onChange={(e) => setMonthInput(e.target.value)}
onBlur={updateCalendarDate}
{...rest}
/>
<DatePickerDate
ref={dateRef}
value={dayInput}
onChange={(e) => setDayInput(e.target.value)}
onBlur={updateCalendarDate}
{...rest}
/>
</>
)}
Expand Down
18 changes: 15 additions & 3 deletions src/components/DatePicker/DatePicker.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,20 @@ export type DatePickerSize = 'lg' | 'md' | 'sm';
export type DatePickerProps = Omit<ComponentProps<'div'>, 'children'> & {
size?: DatePickerSize;
isError?: boolean;
isReadonly?: boolean;
isDisabled?: boolean;
children: (props: {
yearRef: Ref<HTMLInputElement>;
monthRef: Ref<HTMLInputElement>;
dateRef: Ref<HTMLInputElement>;
readOnly?: boolean;
'aria-disabled'?: boolean;
'aria-invalid'?: boolean;
}) => JSX.Element;
};

export const DatePicker = (props: DatePickerProps) => {
const { className, size = 'lg', isError, isDisabled, children, ...rest } = props;
const { className, size = 'lg', isError, isReadonly, isDisabled, children, ...rest } = props;

const yearRef = useRef<HTMLInputElement>(null);
const monthRef = useRef<HTMLInputElement>(null);
Expand Down Expand Up @@ -67,14 +71,22 @@ export const DatePicker = (props: DatePickerProps) => {
return (
// biome-ignore lint/a11y/noStaticElementInteractions: For date input navigation
<div
className={`inline-flex h-14 -space-x-1 rounded-8 border border-solid-gray-600 bg-[--bg] p-0.5 pe-0 text-solid-gray-900 [--bg:theme(colors.white)] focus-within:border-black hover:border-solid-gray-900 data-[size=md]:h-12 data-[size=sm]:h-10 data-[disabled]:border-solid-gray-300 data-[error]:border-error-1 data-[disabled]:text-solid-gray-420 data-[disabled]:[--bg:theme(colors.solid-gray.50)] data-[error]:focus-within:border-red-1000 data-[error]:hover:border-red-1000 forced-colors:data-[disabled]:border-[GrayText] forced-colors:data-[disabled]:text-[GrayText] ${className ?? ''}`}
className={`inline-flex h-14 -space-x-1 rounded-8 border border-solid-gray-600 bg-[--bg] p-0.5 pe-0 text-solid-gray-900 [--bg:theme(colors.white)] focus-within:border-black hover:border-solid-gray-900 data-[size=md]:h-12 data-[size=sm]:h-10 data-[readonly]:border-dashed data-[disabled]:border-solid-gray-300 data-[error]:border-error-1 data-[disabled]:text-solid-gray-420 data-[disabled]:[--bg:theme(colors.solid-gray.50)] data-[error]:focus-within:border-red-1000 data-[error]:hover:border-red-1000 data-[error]:hover:data-[readonly]:border-error-1 hover:data-[readonly]:border-solid-gray-600 forced-colors:data-[disabled]:border-[GrayText] forced-colors:data-[disabled]:text-[GrayText] ${className ?? ''}`}
data-size={size}
data-error={isError || null}
data-readonly={isReadonly || null}
data-disabled={isDisabled || null}
onKeyDown={handleKeyDown}
{...rest}
>
{children({ yearRef, monthRef, dateRef })}
{children({
yearRef,
monthRef,
dateRef,
readOnly: isReadonly,
'aria-disabled': isDisabled,
'aria-invalid': isError,
})}
</div>
);
};
6 changes: 3 additions & 3 deletions src/components/DatePicker/parts/DatePickerDate.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { type ComponentProps, forwardRef } from 'react';
export type DatePickerDateProps = ComponentProps<'input'> & {};

export const DatePickerDate = forwardRef<HTMLInputElement, DatePickerDateProps>((props, ref) => {
const { className, 'aria-disabled': disabled, readOnly, ...rest } = props;
const { className, 'aria-disabled': ariaDisabled, readOnly, ...rest } = props;

return (
<label className='relative z-0 inline-flex flex-row-reverse last:pe-4 [&:has([aria-disabled="true"])]:pointer-events-none'>
Expand All @@ -13,8 +13,8 @@ export const DatePickerDate = forwardRef<HTMLInputElement, DatePickerDateProps>(
type='text'
inputMode='numeric'
pattern='\d+'
readOnly={disabled ? true : readOnly}
aria-disabled={disabled}
readOnly={ariaDisabled === 'true' || ariaDisabled === true || readOnly}
aria-disabled={ariaDisabled}
ref={ref}
{...rest}
/>
Expand Down
6 changes: 3 additions & 3 deletions src/components/DatePicker/parts/DatePickerMonth.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { type ComponentProps, forwardRef } from 'react';
export type DatePickerMonthProps = ComponentProps<'input'> & {};

export const DatePickerMonth = forwardRef<HTMLInputElement, DatePickerMonthProps>((props, ref) => {
const { className, 'aria-disabled': disabled, readOnly, ...rest } = props;
const { className, 'aria-disabled': ariaDisabled, readOnly, ...rest } = props;

return (
<label className='relative z-0 inline-flex flex-row-reverse last:pe-4 [&:has([aria-disabled="true"])]:pointer-events-none'>
Expand All @@ -13,8 +13,8 @@ export const DatePickerMonth = forwardRef<HTMLInputElement, DatePickerMonthProps
type='text'
inputMode='numeric'
pattern='\d+'
readOnly={disabled ? true : readOnly}
aria-disabled={disabled}
readOnly={ariaDisabled === 'true' || ariaDisabled === true || readOnly}
aria-disabled={ariaDisabled}
ref={ref}
{...rest}
/>
Expand Down
6 changes: 3 additions & 3 deletions src/components/DatePicker/parts/DatePickerYear.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { type ComponentProps, forwardRef } from 'react';
export type DatePickerYearProps = ComponentProps<'input'> & {};

export const DatePickerYear = forwardRef<HTMLInputElement, DatePickerYearProps>((props, ref) => {
const { className, 'aria-disabled': disabled, readOnly, ...rest } = props;
const { className, 'aria-disabled': ariaDisabled, readOnly, ...rest } = props;

return (
<label className='relative z-0 inline-flex flex-row-reverse last:pe-4 [&:has([aria-disabled="true"])]:pointer-events-none'>
Expand All @@ -13,8 +13,8 @@ export const DatePickerYear = forwardRef<HTMLInputElement, DatePickerYearProps>(
type='text'
inputMode='numeric'
pattern='\d+'
readOnly={disabled ? true : readOnly}
aria-disabled={disabled}
readOnly={ariaDisabled === 'true' || ariaDisabled === true || readOnly}
aria-disabled={ariaDisabled}
ref={ref}
{...rest}
/>
Expand Down
Loading