Skip to content
Open
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
42 changes: 38 additions & 4 deletions src/PickerPanel/TimePanel/TimePanelBody/TimeColumn.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,23 @@ import { useLayoutEffect } from '@rc-component/util';
import * as React from 'react';
import { usePanelContext } from '../../context';
import useScrollTo from './useScrollTo';
import type { Locale } from '../../../interface';

const SCROLL_DELAY = 300;

export type Unit<ValueType = number | string> = {
label: React.ReactText;
label: string | number;
value: ValueType;
disabled?: boolean;
};

type TimeUnitType = 'hour' | 'minute' | 'second' | 'millisecond' | 'meridiem';

export interface TimeUnitColumnProps {
units: Unit[];
value: number | string;
optionalValue?: number | string;
type: 'hour' | 'minute' | 'second' | 'millisecond' | 'meridiem';
type: TimeUnitType;
onChange: (value: number | string) => void;
onHover: (value: number | string) => void;
onDblClick?: VoidFunction;
Expand All @@ -28,6 +31,25 @@ function flattenUnits(units: Unit<string | number>[]) {
return units.map(({ value, label, disabled }) => [value, label, disabled].join(',')).join(';');
}

const LIST_LABEL_MAP: Record<TimeUnitType, (locale: Locale) => string> = {
hour: (locale) => locale.hourSelect,
minute: (locale) => locale.minuteSelect,
second: (locale) => locale.secondSelect,
millisecond: (locale) => locale.millisecondSelect,
meridiem: (locale) => locale.meridiemSelect,
};

const LIST_ITEM_LABEL_MAP: Record<
TimeUnitType,
(value: string | number, locale: Locale) => string
> = {
hour: (value, locale) => `${value} ${locale.hours}`,
minute: (value, locale) => `${value} ${locale.minutes}`,
second: (value, locale) => `${value} ${locale.seconds}`,
millisecond: (value, locale) => `${value} ${locale.milliseconds}`,
meridiem: (value) => value.toString(),
};

export default function TimeColumn<DateType extends object>(props: TimeUnitColumnProps) {
const { units, value, optionalValue, type, onChange, onHover, onDblClick, changeOnScroll } =
props;
Expand Down Expand Up @@ -96,16 +118,28 @@ export default function TimeColumn<DateType extends object>(props: TimeUnitColum
const columnPrefixCls = `${panelPrefixCls}-column`;

return (
<ul className={columnPrefixCls} ref={ulRef} data-type={type} onScroll={onInternalScroll}>
<ul
role="listbox"
aria-label={LIST_LABEL_MAP[type](locale)}
className={columnPrefixCls}
ref={ulRef}
data-type={type}
onScroll={onInternalScroll}
>
{units.map(({ label, value: unitValue, disabled }) => {
const inner = <div className={`${cellPrefixCls}-inner`}>{label}</div>;
const isSelected = value === unitValue;

return (
<li
key={unitValue}
aria-label={LIST_ITEM_LABEL_MAP[type](unitValue, locale)}
role="option"
aria-selected={isSelected}
aria-disabled={disabled}
style={styles.item}
className={clsx(cellPrefixCls, classNames.item, {
[`${cellPrefixCls}-selected`]: value === unitValue,
[`${cellPrefixCls}-selected`]: isSelected,
[`${cellPrefixCls}-disabled`]: disabled,
})}
onClick={() => {
Expand Down
6 changes: 5 additions & 1 deletion src/PickerPanel/TimePanel/TimePanelBody/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -271,7 +271,11 @@ export default function TimePanelBody<DateType extends object = any>(
};

return (
<div className={clsx(`${prefixCls}-content`, classNames.content)} style={styles.content}>
<div
role="group"
className={clsx(`${prefixCls}-content`, classNames.content)}
style={styles.content}
>
Comment on lines +274 to +278

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The container div has been given role="group" to group the time columns (hours, minutes, seconds, etc.). To make this group accessible and identifiable to screen readers, it should have an accessible name. Adding aria-label={locale?.timeSelect} provides the necessary context for assistive technologies.

Suggested change
<div
role="group"
className={clsx(`${prefixCls}-content`, classNames.content)}
style={styles.content}
>
<div
role="group"
aria-label={locale?.timeSelect}
className={clsx(`${prefixCls}-content`, classNames.content)}
style={styles.content}
>

{showHour && (
<TimeColumn
units={hourUnits}
Expand Down
17 changes: 10 additions & 7 deletions src/interface.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -66,11 +66,20 @@ export type Locale = {
week: string;
month: string;
year: string;
hours: string;
minutes: string;
seconds: string;
milliseconds: string;
previousMonth: string;
nextMonth: string;
monthSelect: string;
yearSelect: string;
decadeSelect: string;
hourSelect: string;
minuteSelect: string;
secondSelect: string;
millisecondSelect: string;
meridiemSelect: string;
Comment on lines +69 to +82

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

不要把新增 locale 字段设为必填。

Locale 是导出的公共类型。把这 9 个字段直接改成必填会让现有自定义 locale 对象在升级后全部类型报错,属于破坏性 API 变更。更稳妥的是先改成可选,并在 TimeColumn 里为缺省值提供 fallback。

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/interface.tsx` around lines 69 - 82, The new locale fields on the public
Locale type should not be made required because that breaks existing custom
locale objects. Update the Locale definition to make these added fields
optional, then adjust TimeColumn to use fallback values whenever a field is
missing so existing consumers keep compiling and behavior stays unchanged.


previousYear: string;
nextYear: string;
Expand Down Expand Up @@ -316,13 +325,7 @@ export type SemanticName = 'root' | 'prefix' | 'input' | 'suffix';
export type PreviewValueType = 'hover';

export type PanelSemanticName =
| 'root'
| 'header'
| 'body'
| 'content'
| 'item'
| 'footer'
| 'container';
'root' | 'header' | 'body' | 'content' | 'item' | 'footer' | 'container';

export interface SharedPickerProps<DateType extends object = any>
extends
Expand Down
9 changes: 9 additions & 0 deletions src/locale/am_ET.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,21 @@ const locale: Locale = {
week: 'ሳምንት',
month: 'ወር',
year: 'ዓመት',
hours: 'ሰዓቶች',
minutes: 'ደቂቃዎች',
seconds: 'ሰከንዶች',
milliseconds: 'ሚሊሰከንዶች',
timeSelect: 'ሰዓት ምረጥ',
dateSelect: 'ቀን ምረጥ',
weekSelect: 'ሳምንት ምረጥ',
monthSelect: 'ወር ምረጥ',
yearSelect: 'አመት ምረጥ',
decadeSelect: 'አስርት አመታት ምረጥ',
hourSelect: 'ሰዓት ይምረጡ',
minuteSelect: 'ደቂቃ ይምረጡ',
secondSelect: 'ሰከንድ ይምረጡ',
millisecondSelect: 'ሚሊሰከንድ ይምረጡ',
meridiemSelect: 'ሜሪዲየም ይምረጡ',
yearFormat: 'YYYY',
dayFormat: 'D',
monthBeforeYear: true,
Expand Down
9 changes: 9 additions & 0 deletions src/locale/ar_EG.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,20 @@ const locale: Locale = {
week: 'الأسبوع',
month: 'الشهر',
year: 'السنة',
hours: 'الساعات',
minutes: 'الدقائق',
seconds: 'الثواني',
milliseconds: 'المللي ثانية',
timeSelect: 'اختيار الوقت',
dateSelect: 'اختيار التاريخ',
monthSelect: 'اختيار الشهر',
yearSelect: 'اختيار السنة',
decadeSelect: 'اختيار العقد',
hourSelect: 'اختر ساعة',
minuteSelect: 'اختر دقيقة',
secondSelect: 'اختر ثانية',
millisecondSelect: 'اختر جزء من الثانية',
meridiemSelect: 'اختر صباحاً/مساءً',
previousMonth: 'الشهر السابق (PageUp)',
nextMonth: 'الشهر التالى(PageDown)',
previousYear: 'العام السابق (Control + left)',
Expand Down
9 changes: 9 additions & 0 deletions src/locale/az_AZ.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,21 @@ const locale: Locale = {
week: 'Həftə',
month: 'Ay',
year: 'İl',
hours: 'Saat',
minutes: 'Dəqiqə',
seconds: 'Saniyə',
milliseconds: 'Millisaniyə',
timeSelect: 'vaxtı seç',
dateSelect: 'tarixi seç',
weekSelect: 'Həftə seç',
monthSelect: 'Ay seç',
yearSelect: 'il seç',
decadeSelect: 'Onillik seçin',
hourSelect: 'Saat seçin',
minuteSelect: 'Dəqiqə seçin',
secondSelect: 'Saniyə seçin',
millisecondSelect: 'Millisaniyə seçin',
meridiemSelect: 'Meridyemi seçin',
previousMonth: 'Əvvəlki ay (PageUp)',
nextMonth: 'Növbəti ay (PageDown)',
previousYear: 'Sonuncu il (Control + left)',
Expand Down
9 changes: 9 additions & 0 deletions src/locale/bg_BG.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,20 @@ const locale: Locale = {
week: 'Седмица',
month: 'Месец',
year: 'Година',
hours: 'Часове',
minutes: 'Минути',
seconds: 'Секунди',
milliseconds: 'Милисекунди',
Comment on lines +15 to +18

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟠 Major | 🏗️ Heavy lift

不要把时间项读法压缩成单个静态名词。

src/PickerPanel/TimePanel/TimePanelBody/TimeColumn.tsx:34-65 会直接拼出 ${value} ${locale.hours} 这样的 aria-label。这里使用固定复数后,单数项会被读成 1 Часове1 Секунди 这类错误词形,读屏文案会稳定出错。建议把这些字段改成按值生成的 formatter,或至少拆成 singular/plural 两套字段。

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/locale/bg_BG.ts` around lines 15 - 18, Update the Bulgarian locale
entries in the locale object so time unit labels are not fixed plural nouns,
since TimeColumn builds aria labels like “${value} ${locale.hours}” and will
read singular values incorrectly. Adjust the locale shape used by TimeColumn to
provide value-aware formatters or separate singular/plural fields for hours,
minutes, seconds, and milliseconds, then wire the TimePanel/TimeColumn consumers
to use those symbols instead of static strings.

timeSelect: 'Избор на час',
dateSelect: 'Избор на дата',
monthSelect: 'Избор на месец',
yearSelect: 'Избор на година',
decadeSelect: 'Десетилетие',
hourSelect: 'Изберете час',
minuteSelect: 'Изберете минута',
secondSelect: 'Изберете секунда',
millisecondSelect: 'Изберете милисекунда',
meridiemSelect: 'Изберете меридием',
previousMonth: 'Предишен месец (PageUp)',
nextMonth: 'Следващ месец (PageDown)',
previousYear: 'Последна година (Control + left)',
Expand Down
9 changes: 9 additions & 0 deletions src/locale/bn_BD.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,21 @@ const locale: Locale = {
week: 'সপ্তাহ',
month: 'মাস',
year: 'বছর',
hours: 'ঘণ্টা',
minutes: 'মিনিট',
seconds: 'সেকেন্ড',
milliseconds: 'মিলিসেকেন্ড',
timeSelect: 'সময় নির্বাচন',
dateSelect: 'তারিখ নির্বাচন',
weekSelect: 'সপ্তাহ পছন্দ করুন',
monthSelect: 'মাস পছন্দ করুন',
yearSelect: 'বছর পছন্দ করুন',
decadeSelect: 'একটি দশক পছন্দ করুন',
hourSelect: 'একটি ঘণ্টা নির্বাচন করুন',
minuteSelect: 'একটি মিনিট নির্বাচন করুন',
secondSelect: 'একটি সেকেন্ড নির্বাচন করুন',
millisecondSelect: 'একটি মিলিসেকেন্ড নির্বাচন করুন',
meridiemSelect: 'মেরিডিয়েম নির্বাচন করুন',
previousMonth: 'গত মাস (PageUp)',
nextMonth: 'আগামী মাস (PageDown)',
previousYear: 'গত বছর (Control + left)',
Expand Down
9 changes: 9 additions & 0 deletions src/locale/by_BY.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,21 @@ const locale: Locale = {
week: 'Тыдзень',
month: 'Месяц',
year: 'Год',
hours: 'Гадзіны',
minutes: 'Хвіліны',
seconds: 'Секунды',
milliseconds: 'Мілісекунды',
timeSelect: 'Выбраць час',
dateSelect: 'Выбраць дату',
weekSelect: 'Выбраць тыдзень',
monthSelect: 'Выбраць месяц',
yearSelect: 'Выбраць год',
decadeSelect: 'Выбраць дзесяцігоддзе',
hourSelect: 'Выберыце гадзіну',
minuteSelect: 'Выберыце хвіліну',
secondSelect: 'Выберыце секунду',
millisecondSelect: 'Выберыце мілісекунду',
meridiemSelect: 'Выберыце мерыдыем',

previousMonth: 'Папярэдні месяц (PageUp)',
nextMonth: 'Наступны месяц (PageDown)',
Expand Down
9 changes: 9 additions & 0 deletions src/locale/ca_ES.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,20 @@ const locale: Locale = {
week: 'Setmana',
month: 'Mes',
year: 'Any',
hours: 'Hores',
minutes: 'Minuts',
seconds: 'Segons',
milliseconds: 'Mil·lisegons',
timeSelect: 'Seleccionar hora',
dateSelect: 'Seleccionar data',
monthSelect: 'Escollir un mes',
yearSelect: 'Escollir un any',
decadeSelect: 'Escollir una dècada',
hourSelect: 'Seleccioneu una hora',
minuteSelect: 'Seleccioneu un minut',
secondSelect: 'Seleccioneu un segon',
millisecondSelect: 'Seleccioneu un mil·lisegon',
meridiemSelect: 'Seleccioneu el meridiem',
previousMonth: 'Mes anterior (PageUp)',
nextMonth: 'Mes següent (PageDown)',
previousYear: 'Any anterior (Control + left)',
Expand Down
9 changes: 9 additions & 0 deletions src/locale/cs_CZ.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,20 @@ const locale: Locale = {
week: 'Týden',
month: 'Měsíc',
year: 'Rok',
hours: 'Hodiny',
minutes: 'Minuty',
seconds: 'Sekundy',
milliseconds: 'Milisekundy',
timeSelect: 'Vybrat čas',
dateSelect: 'Vybrat datum',
monthSelect: 'Vyberte měsíc',
yearSelect: 'Vyberte rok',
decadeSelect: 'Vyberte dekádu',
hourSelect: 'Vyberte hodinu',
minuteSelect: 'Vyberte minutu',
secondSelect: 'Vyberte sekundu',
millisecondSelect: 'Vyberte milisekundu',
meridiemSelect: 'Vyberte meridiem',

previousMonth: 'Předchozí měsíc (PageUp)',
nextMonth: 'Následující (PageDown)',
Expand Down
9 changes: 9 additions & 0 deletions src/locale/da_DK.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,20 @@ const locale: Locale = {
week: 'Uge',
month: 'Måned',
year: 'År',
hours: 'Timer',
minutes: 'Minutter',
seconds: 'Sekunder',
milliseconds: 'Millisekunder',
timeSelect: 'Vælg tidspunkt',
dateSelect: 'Vælg dato',
monthSelect: 'Vælg måned',
yearSelect: 'Vælg år',
decadeSelect: 'Vælg årti',
hourSelect: 'Vælg en time',
minuteSelect: 'Vælg et minut',
secondSelect: 'Vælg et sekund',
millisecondSelect: 'Vælg et millisekund',
meridiemSelect: 'Vælg meridiem',

previousMonth: 'Forrige måned (Page Up)',
nextMonth: 'Næste måned (Page Down)',
Expand Down
9 changes: 9 additions & 0 deletions src/locale/de_DE.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,20 @@ const locale: Locale = {
week: 'Woche',
month: 'Monat',
year: 'Jahr',
hours: 'Stunden',
minutes: 'Minuten',
seconds: 'Sekunden',
milliseconds: 'Millisekunden',
timeSelect: 'Zeit wählen',
dateSelect: 'Datum wählen',
monthSelect: 'Wähle einen Monat',
yearSelect: 'Wähle ein Jahr',
decadeSelect: 'Wähle ein Jahrzehnt',
hourSelect: 'Stunde wählen',
minuteSelect: 'Minute wählen',
secondSelect: 'Sekunde wählen',
millisecondSelect: 'Millisekunde wählen',
meridiemSelect: 'Tageshälfte wählen',

previousMonth: 'Vorheriger Monat (PageUp)',
nextMonth: 'Nächster Monat (PageDown)',
Expand Down
9 changes: 9 additions & 0 deletions src/locale/el_GR.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,20 @@ const locale: Locale = {
week: 'Εβδομάδα',
month: 'Μήνας',
year: 'Έτος',
hours: 'Ώρες',
minutes: 'Λεπτά',
seconds: 'Δευτερόλεπτα',
milliseconds: 'Χιλιοστά δευτερολέπτου',
timeSelect: 'Επιλογή ώρας',
dateSelect: 'Επιλογή ημερομηνίας',
monthSelect: 'Επιλογή μήνα',
yearSelect: 'Επιλογή έτους',
decadeSelect: 'Επιλογή δεκαετίας',
hourSelect: 'Επιλέξτε ώρα',
minuteSelect: 'Επιλέξτε λεπτό',
secondSelect: 'Επιλέξτε δευτερόλεπτο',
millisecondSelect: 'Επιλέξτε χιλιοστό δευτερολέπτου',
meridiemSelect: 'Επιλέξτε ΠΜ/ΜΜ',

previousMonth: 'Προηγούμενος μήνας (PageUp)',
nextMonth: 'Επόμενος μήνας (PageDown)',
Expand Down
9 changes: 9 additions & 0 deletions src/locale/en_GB.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,20 @@ const locale: Locale = {
week: 'Week',
month: 'Month',
year: 'Year',
hours: 'Hours',
minutes: 'Minutes',
seconds: 'Seconds',
milliseconds: 'Milliseconds',
timeSelect: 'Select time',
dateSelect: 'Select date',
monthSelect: 'Choose a month',
yearSelect: 'Choose a year',
decadeSelect: 'Choose a decade',
hourSelect: 'Select an hour',
minuteSelect: 'Select a minute',
secondSelect: 'Select a second',
millisecondSelect: 'Select a millisecond',
meridiemSelect: 'Select a meridiem',

previousMonth: 'Previous month (PageUp)',
nextMonth: 'Next month (PageDown)',
Expand Down
Loading
Loading