DateTimePicker
日付、時刻、日時、またはそれぞれの期間を、カレンダーと時刻のホイールや時計の文字盤から選べるようにします。ダイアログとして、またはフィールドの下に開くサーフェスとして表示します。
- カテゴリ
- 選択
- トークン
comp.date-time-picker- レベル
- 合成
- 構成要素
- Calendar, Modal layer
- Web
tanrei-date-time-pickerschedule - SwiftUI
tanreiDateTimePickerradio_button_unchecked - Jetpack Compose
TanreiDateTimePickerradio_button_unchecked - Flutter
TanreiDateTimePickerradio_button_unchecked - React Native
DateTimePickerradio_button_unchecked
生成元 docs/status/status.json, specs/date-time-picker.spec.json
DateTimePicker は、カレンダー、時刻の部分、またはその両方を収めるサーフェスです。mode は date、time、date-time のいずれかで、range を付けるとどれでも開始と終了を選ぶ期間になります。スクリムの上のダイアログとして(modal)、または開いたフィールドやボタンの下のサーフェスとして(docked)表示します。値は 2026-09-17、19:30、2026-09-17T19:30 のような文字列で、秒もタイムゾーンも持ちません。
現在は Web のみ、ほかは予定
Web コンポーネントは、このページの説明どおりにピッカーを実装しています。期間の両端はダッシュでつないだ 2 つのフィールドになり、午前・午後は時刻の控えめな一部になり、入力方式のタブはグリフで描かれ、ホイールには数字を打ち込めます。デモはそのコンポーネントです。SwiftUI、Compose、Flutter、React Native はまだ作っていません。これらのパッケージには廃止した日付ピッカーと時刻ピッカーのコードが残っていますが、このページでは説明しません。
ボタンで開く:ドック型の日付と、モーダルの時刻
ピッカーは制御コンポーネントです。open を設定して開き、ピッカーは close で閉じるよう求めます。change を発火する前に、自分の value(または start と end)を設定します。開いた元のフィールドには何も書き込みません。
<!-- 任意のボタンから開く、モーダルの時刻ピッカー。 -->
<tanrei-button id="alarm-button" variant="outlined">アラーム</tanrei-button>
<tanrei-date-time-picker id="alarm" mode="time" value="07:30" minute-step="5" label="アラーム"></tanrei-date-time-picker>
<!-- テキストフィールドの下に開くドック型のピッカー。フィールドのピッカーボタンから開きます。 -->
<tanrei-text-field id="due" label="期限" type="date" picker picker-label="日付を選択"></tanrei-text-field>
<tanrei-date-time-picker id="due-picker" presentation="docked" anchor="due" label="期限"></tanrei-date-time-picker>
<!-- 営業時間:時刻の期間。終了が開始と同じかそれより前なら、翌日になります。 -->
<tanrei-date-time-picker id="hours" mode="time" range start="09:00" end="17:30" label="営業時間"></tanrei-date-time-picker>
<script type="module">
import '@tanrei/web/components/date-time-picker';
const alarm = document.querySelector('#alarm');
document.querySelector('#alarm-button').addEventListener('click', () => (alarm.open = true));
alarm.addEventListener('change', (e) => save(e.detail.value)); // "07:35":alarm.value はすでに新しい値です
// ピッカーが自分で閉じることはありません。e.detail.reason は escape、back、outside、tab、focus-out、cancel、confirm、select のいずれかです。
alarm.addEventListener('close', () => (alarm.open = false));
// フィールドは依頼するだけです。ピッカーを開き、値を書き戻すのはプロダクト側です。
const field = document.querySelector('#due');
const due = document.querySelector('#due-picker');
field.addEventListener('pickerrequest', (e) => {
Object.assign(due, { value: e.detail.value, min: e.detail.min, max: e.detail.max, open: true });
});
due.addEventListener('change', (e) => (field.value = e.detail.value));
due.addEventListener('close', () => (due.open = false));
const hours = document.querySelector('#hours');
hours.addEventListener('change', (e) => saveHours(e.detail.start, e.detail.end));
hours.addEventListener('close', () => (hours.open = false));
</script>import { useState } from 'react';
import { DateTimePicker, TextField } from '@tanrei/react';
const [due, setDue] = useState('');
const [open, setOpen] = useState(false);
<TextField
id="due"
label="期限"
type="date"
value={due}
picker
pickerLabel="日付を選択"
onChange={(e) => setDue(e.currentTarget.value)}
onPickerRequest={() => setOpen(true)}
/>
<DateTimePicker
presentation="docked"
anchor="due"
open={open}
value={due}
onChange={(e) => setDue(e.detail.value)}
onClose={() => setOpen(false)}
/>
// モーダルの日時。15 分刻みです。
<DateTimePicker
mode="date-time"
minuteStep={15}
label="会議の開始"
open={meetingOpen}
value={meeting}
onChange={(e) => setMeeting(e.detail.value)}
onClose={() => setMeetingOpen(false)}
/>SwiftUI、Compose、Flutter、React Native の例はありません。これらのプラットフォームは、まだピッカーを作っていないからです。各プラットフォームでの名前は、仕様のプラットフォーム対応表にあります。
| 以前 | 現在 |
|---|---|
| 日付ピッカー(モーダル、ドック) | date モードの DateTimePicker(modal または docked) |
| 期間を選ぶ日付ピッカー | mode を date にして range を付ける |
| 時刻ピッカー | time モードの DateTimePicker。文字盤は入力方式の 1 つで、もう 1 つのホイールが既定です |
| 時刻ピッカーの AM・PM のセグメント | 午前・午後。時と分のホイールの横の短い 3 つ目のホイール、または文字盤モードで分の横に置くセレクターです |
| ピッカーの中での日付や時刻の文字入力 | type を date、time、date-time にしたテキストフィールド。そのピッカーボタンが、このピッカーを開くようプロダクトに求めます |
| ページに置く月のグリッド | カレンダー |
| 2 つのピッカーのトークン | サーフェス・ヘッダー・時刻の部分・アクションは comp.date-time-picker.*、グリッドは comp.calendar.* |
このコンポーネントで新しくできるようになったのは、date-time モード、時刻の期間(終了が翌日になってもよい)、ホイール、minuteStep です。
Web では、日付を選ぶ要素と時刻を選ぶ要素という以前の 2 つは、なくなりました。どちらも <tanrei-date-time-picker> で、mode="date" か mode="time" を付けます。ドック型のピッカーは、これまでどおり anchor と opener(下に置く要素と、開く要素の id)を受け取り、open で開いて close を受けて閉じます。文字盤は entry-mode="dial" です。
- Material 3 のドック型とモーダルの date picker は
dateモードの DateTimePicker で、date range picker はそれにrangeを付けたものです。 - Material 3 の time picker は
timeモードの DateTimePicker です。m3-like プリセットは文字盤だけを提供し、Material の大きめのセレクターと文字盤、末尾寄せのテキストのアクションで描きます。 - Material の全画面の期間ピッカーと、文字入力に切り替える鉛筆やキーボードのボタンに相当するものはありません。文字入力はテキストフィールドの役目です。
- Apple のホイール式の時刻ピッカーは、ホイールにあたります。cupertino プリセットはホイールだけを提供し、Apple の灰色の帯で描きます。
- Flutter の
showDatePickerとshowTimePickerはshowTanreiDateTimePicker、SwiftUI で表示するピッカーは.tanreiDateTimePickerモディファイアー、Compose のピッカーのダイアログはTanreiDateTimePickerにあたります。React Native ではDateTimePickerですが、同じ名前のコミュニティパッケージとは別物です。
以下のデモは、Web の inline 属性を使って、開いたサーフェスをその場に描いています。この属性はドキュメントとテストのためのものです。プロダクトのピッカーはページの上に開きます。
日付:ヘッダーとアクションのあるモーダルと、日を選ぶと確定するドック型
時刻:既定のホイールと、文字盤(12 時間制)
翌日に終わる時刻の期間と、15 分刻みの 24 時間制
日時と、日付の期間
構成要素
| パーツ | 説明 |
|---|---|
1 scrim · 任意 | The modal layer's scrim over everything behind a modal picker (MDL-1). It blocks presses, and a press on it dismisses the picker. |
2 container | The raised surface that holds everything else: centred in the window (modal) or below its anchor (docked). |
3 header · 任意 | The title row — the picker's label at the start and, when the picker sets a time, the entry-mode tabs at the end — and, in a modal picker that sets a date, the chosen value in large type below it. |
4 entry-mode-tabs · 任意 | Tanrei Tabs of the secondary variant, each drawing a glyph alone: the keyboard glyph for the wheels at the start and the schedule glyph for the dial at the end. They choose how the time is set, and their words are their accessible names only. Drawn only while the system offers both (comp.date-time-picker.time.entry-modes). |
5 divider · 任意 | The hairline below the header of a modal picker that shows the chosen value. |
6 calendar · 任意 | A Tanrei Calendar, for the date or the range of dates. Present while mode is date or date-time. |
7 time-section · 任意 | Everything that sets a time, top to bottom: the range display across its whole width, then the time display (dial mode) and the wheels or the dial. The period of a 12-hour time is a part of the wheels and of the time display, not a row of its own. Present while mode is time or date-time. |
8 range-display · 任意 | The two ends of a range that has a time: the start's range field, an en dash and the end's range field, in reading order, filling the width of the time section because everything below it sets the end it names. No word says which end is which; the order and the dash do. Present in a range that has a time. |
9 range-field · 任意 | One end of the range in the range display: its time on a container that the person presses to make the wheels or the dial set that end. The one being set is drawn as selected, with the mark the dial mode gives the unit it sets. |
10 range-separator · 任意 | The en dash between the two range fields. |
11 wheels · 任意 | The hour wheel and the minute wheel with the separator between them and, with a 12-hour clock, the period wheel beside them. The chosen value of each stands on that wheel's own selection container (on one band across all of them in a system that joins them), and a press on the hour's or the minute's lets the person type the number. Each wheel is a spin button for assistive technology. |
12 time-display · 任意 | Dial mode: the hour and the minute, each in a selector box that the person presses or focuses to set that unit on the dial, and that the arrow keys adjust; the one whose unit the dial shows is selected. With a 12-hour clock the period selector stands in the same row. It is the row next to the dial, with nothing between them. |
13 period · 任意 | Before or after noon (AM, PM), drawn as the last part of the time — or its first, where the locale writes the period before the hour — and never as tabs: in the wheels mode a short wheel of the two names beside the minute wheel, in the dial mode a narrow selector beside the minute selector that shows the pending period and changes to the other when pressed. It is smaller and quieter than the hour and the minute and never carries the mark of the unit being set. Present with a 12-hour clock. |
14 separator · 任意 | The locale's separator between the hour and the minute (":" in most locales), between the wheels and in the time display. |
15 dial · 任意 | Dial mode: a round clock face with the hours (two rings for a 24-hour clock) or the minutes, which the person presses or drags to set the selected unit. |
16 handle · 任意 | The circle over the chosen value on the dial, joined to the dial's centre by the track; the number under it is drawn in the handle's content color. |
17 error · 任意 | The line that says a range's end is before its start (date-time ranges). |
18 actions · 任意 | Cancel and OK: Tanrei Buttons that the picker places as a full-width Button group places a dismissive and a confirming item, in the variant comp.date-time-picker.actions.variant names. Absent from a docked picker that sets a date only. |
19 focus-ring | Gap-then-ring indicator around the selector, period selector, range field or wheel that has keyboard focus. The calendar, the tabs and the Buttons draw their own. |
プロパティ
| プロパティ | 型 | 既定値 | 説明 |
|---|---|---|---|
open | boolean | false | Whether the picker is shown. The product opens it (from a Text field's trailing button, or from any button). Where open is a plain value (web, Compose, React Native) the product closes it by setting open to false when the picker emits close; where it is a binding or a controller (SwiftUI, Flutter) the picker closes itself through it (DTM-5). |
presentation | modal | docked | "modal" | modal: a dialog over a scrim, with a header and Cancel and OK; the choice is committed by OK. docked: a surface below an anchor (the product's field or button) that the rest of the page stays usable around; a date alone is committed by choosing it, and anything with a time by OK. |
mode | date | time | date-time | "date" | What is chosen: a calendar date, a time of day, or a date with a time of day. |
range | boolean | false | Chooses a span, from start to end, instead of one value: a span of dates, of times (opening hours; the end may fall on the next day) or of dates with times (a booking). |
value | string | "" | The chosen value when range is false; empty when none is chosen. An ISO 8601 calendar date in mode date ("2026-09-17"), 24-hour hours and minutes in mode time ("19:30", as an HTML time input holds it), and a local date and time joined by T in mode date-time ("2026-09-17T19:30", as an HTML datetime-local input holds it). No value has seconds or a time zone. |
start | string | "" | The first value of the chosen span when range is true, in the mode's form (as value); empty when none is chosen. |
end | string | "" | The last value of the chosen span when range is true, in the mode's form; empty while only start is chosen. Never before start, except in mode time, where an end at or before start falls on the next day. |
min | string | "" | The earliest value that can be chosen, in the mode's ISO 8601 form — the form the Text field it opens from takes: a calendar date in mode date ("2026-09-17"), a time of day in mode time ("09:00"), and a date and time in mode date-time ("2026-09-17T09:00"), where a calendar date alone bounds the dates and not the times. Empty for no limit. It bounds the calendar by its date and the time by its time (DTM-49). |
max | string | "" | The latest value that can be chosen, in the mode's ISO 8601 form, as min ("2026-09-30", "17:00", "2026-09-30T17:00"); empty for no limit. It bounds the calendar by its date and the time by its time (DTM-49). |
disabledDates | strings | | Dates inside min and max that cannot be chosen, as ISO 8601 calendar dates; with the platform's isDateDisabled predicate, passed to the calendar (CAL-16). |
today | string | "" | The date the calendar draws as today, as an ISO 8601 calendar date; empty uses the device's current date. Set it in tests. |
firstDayOfWeek | locale | sunday | monday | tuesday | wednesday | thursday | friday | saturday | "locale" | The weekday in the calendar's first column, passed to it. |
locale | string | "" | A BCP 47 language tag ("en-US", "ja-JP") for month, weekday and period names, digits, date and time forms, the separator between hours and minutes, the first day of the week and the preferred clock. Empty uses the platform's current locale. |
startView | day | year | "day" | Whether the calendar opens on the days of a month or on the list of years, passed to it. |
showAdjacentDays | boolean | false | Whether the calendar shows the days of the previous and next month in its spare cells, passed to it (CAL-15). |
hourCycle | locale | h12 | h23 | "locale" | h12: hours 1 to 12 with a period (AM, PM). h23: hours 00 to 23. locale takes the locale's preferred clock. Values are 24-hour in every cycle. |
minuteStep | number | 1 | The minutes a person can choose: every minute (1), or every 5, 10, 15 or 30 minutes. The minute wheel lists only those minutes, the dial snaps to them, and a typed minute is rounded down to one. |
entryMode | wheels | dial | "wheels" | How the time is set when the picker opens: on wheels, which also take a typed number, or on a clock dial. The person can switch with the entry-mode tabs while it is open. Ignored when the system offers one mode only (comp.date-time-picker.time.entry-modes). |
unit | hour | minute | "hour" | Dial mode: the unit the dial shows, and the selector that takes focus, when the picker opens. minute suits a product that mostly adjusts minutes. |
layout | auto | vertical | horizontal | "auto" | vertical: the calendar above the time section (and, in the dial mode, the time display above the dial). horizontal: side by side, for a short window or a wide one (in the dial mode, the time display beside the dial, with the range display across both). auto chooses horizontal only when the window is too short for vertical and wide enough for horizontal. |
label | string | "" | Names the picker, in the product's language ("Select date", "Check-in"): the accessible name of its surface and the start of its title row. Required, and this instance's alone: the picker has no words for it and the product's words have none, because what is being chosen differs from one picker to the next. Empty, the title row draws no words, the surface has no name, and it is reported. |
dateLabel | string | "" | What the header shows for a date that is not chosen yet: the date of a single value, and either end of a range, in the product's language ("Date"). The product's: Tanrei has no words for it. Empty reads the product's words. |
startLabel | string | "" | Range: the accessible name of the start's range field and the description of the calendar's start day. It is never drawn, in the product's language ("Start"). The product's: Tanrei has no words for it. Empty reads the product's words. |
endLabel | string | "" | Range: the accessible name of the end's range field and the description of the calendar's end day. It is never drawn, in the product's language ("End"). The product's: Tanrei has no words for it. Empty reads the product's words. |
confirmLabel | string | "" | The label of the button that commits the choice, in the product's language ("OK"). The product's: Tanrei has no words for it. Empty reads the product's words. |
cancelLabel | string | "" | The label of the button that closes the picker without committing, in the product's language ("Cancel"). The product's: Tanrei has no words for it. Empty reads the product's words. |
previousMonthLabel | string | "" | Passed to the calendar, in the product's language ("Previous month"). The product's: Tanrei has no words for it. Empty reads the product's words. |
nextMonthLabel | string | "" | Passed to the calendar, in the product's language ("Next month"). The product's: Tanrei has no words for it. Empty reads the product's words. |
yearViewLabel | string | "" | Passed to the calendar, in the product's language ("Choose a year"). The product's: Tanrei has no words for it. Empty reads the product's words. |
todayLabel | string | "" | Passed to the calendar, in the product's language ("Today"). The product's: Tanrei has no words for it. Empty reads the product's words. With neither, the platform's own word in the locale, where it has one. |
hourLabel | string | "" | The accessible name of the hour wheel and the hour selector, in the product's language ("Hour"). The product's: Tanrei has no words for it. Empty reads the product's words. With neither, the platform's own word in the locale, where it has one. |
minuteLabel | string | "" | The accessible name of the minute wheel and the minute selector, in the product's language ("Minute"). The product's: Tanrei has no words for it. Empty reads the product's words. With neither, the platform's own word in the locale, where it has one. |
wheelsLabel | string | "" | The accessible name of the entry-mode tab that shows the wheels; the tab draws the keyboard glyph alone, in the product's language ("Wheels"). The product's: Tanrei has no words for it. Empty reads the product's words. |
dialLabel | string | "" | The accessible name of the entry-mode tab that shows the dial; the tab draws the schedule glyph alone, in the product's language ("Dial"). The product's: Tanrei has no words for it. Empty reads the product's words. |
entryModeLabel | string | "" | The accessible name of the row of entry-mode tabs, in the product's language ("Time input"). The product's: Tanrei has no words for it. Empty reads the product's words. |
periodLabel | string | "" | The accessible name of the period (AM or PM): the period wheel in the wheels mode and the period selector in the dial mode, in the product's language ("Period"). The product's: Tanrei has no words for it. Empty reads the product's words. With neither, the platform's own word in the locale, where it has one. |
rangeLabel | string | "" | The accessible name of the range display, the group of the two range fields, in the product's language ("Range"). The product's: Tanrei has no words for it. Empty reads the product's words. |
nextDayLabel | string | "" | Mode time with a range: added after the end's time, in its range field and its accessible name, while the end falls on the next day ("6:00 AM next day"), in the product's language. The product's: Tanrei has no words for it. Empty reads the product's words. |
rangeErrorText | string | "" | Mode date-time with a range: the error line shown while the end is before the start, in the product's language ("End must be after start"). The product's: Tanrei has no words for it. Empty reads the product's words. |
イベント
| イベント | 説明 |
|---|---|
change | The person committed a choice that differs from value (or from start and end): by OK, or by choosing a date in a docked picker that sets a date only. Carries the new value, or the new start and end, in the mode's form. Emitted before the close it causes. |
close | The picker asks to be closed. Carries the reason, named escape, back, outside, tab, focus-out, cancel, confirm, select or anchor-hidden (in the platform's casing). Emitted after change when both are emitted. |
状態
振る舞い
EARS 記法による要件です。各プラットフォームの実装は、この ID に対応するテストで検証されます。要件の原文は仕様ファイルのものをそのまま掲載しています。
| ID | 要件 |
|---|---|
DTM-1 | WHEN open becomes true WHILE presentation is modal THE date-time picker SHALL present its container as a modal overlay on its modal layer, in the platform's own modal presentation (named in the platform notes): centred in the window's safe area, at least comp.date-time-picker.modal.container.margin from every edge and from the on-screen keyboard, above everything in its window with the layer's scrim in comp.date-time-picker.modal.scrim.color and comp.date-time-picker.modal.scrim.blur over the whole window behind it (MDL-1); it SHALL make everything outside it inert, keep the content behind it from scrolling and keep focus inside it, as its modal layer does (MDL-2, MDL-3, MDL-4), and draw the container in comp.date-time-picker.modal.container.color with comp.date-time-picker.modal.container.elevation and comp.date-time-picker.modal.container.shape corners eased by sys.shape.corner-smoothing (0 is a quarter circle, 0.6 the iOS continuous corner; a platform with only the OS curve draws it for any amount above 0). |
DTM-2 | WHEN open becomes true WHILE presentation is docked THE date-time picker SHALL present its container in the platform's overlay layer (the web's top layer through the popover API, an overlay SwiftUI draws above its anchor, Compose's Popup, Flutter's Overlay, React Native's overlay layer that TanreiProvider renders), comp.date-time-picker.docked.offset below its anchor with the start edges aligned; WHERE the space below has less room than the surface needs within comp.date-time-picker.docked.viewport-margin of the edge of the visible part of the window, above the on-screen keyboard while one is shown, and the space above has more it SHALL flip above the anchor, it SHALL shift along the anchor to stay within that margin, and SHALL keep following the anchor while it moves. It SHALL draw the container in comp.date-time-picker.docked.container.color with comp.date-time-picker.docked.container.elevation and comp.date-time-picker.docked.container.shape corners eased by sys.shape.corner-smoothing, and SHALL NOT trap focus, make the rest of the screen inert or draw a scrim: it is an operated overlay that is not modal. WHEN the layout direction is right-to-left start and end SHALL mirror. |
DTM-3 | WHEN the date-time picker opens THE date-time picker SHALL move focus into it, because it is an operated overlay in both presentations: to the calendar's active day (CAL-10) while mode is date or date-time, or to its displayed year in the year view; in mode time to the hour wheel in the wheels mode, or to the selector of unit in the dial mode. Focus SHALL move when it opens, not when its motion ends. |
DTM-4 | WHEN the date-time picker closes THE date-time picker SHALL return focus to the element that had it when the picker opened (the anchor or the opener, for a docked picker) or, where that element no longer exists or cannot take focus, to the platform's default for a closed overlay, and SHALL restore the content behind a modal picker to what it was before, as its modal layer does (MDL-2, MDL-5); focus SHALL move when it closes, not when its motion ends. |
DTM-5 | WHEN the user presses Escape or the platform's back (Android's back gesture or button, the iOS accessibility escape gesture), presses the scrim of a modal picker (as its modal layer answers these, MDL-6) or outside a docked picker and its anchor, presses Tab or Shift+Tab out of a docked picker or moves focus out of it, activates Cancel or OK, or completes a choice in a docked picker that sets a date only (DTM-7) THE date-time picker SHALL emit close once with that reason (escape, back, outside, tab, focus-out, cancel, confirm or select) and SHALL be closed: through its binding or controller where open is one (SwiftUI, Flutter), and by the product setting open to false where open is a plain value (web, Compose, React Native). A close for any reason but confirm and select SHALL commit nothing, and Tab or Shift+Tab SHALL then move focus on from the anchor as they would have from it. Whether a press outside a docked picker also reaches the element under it SHALL follow the platform and be stated in its README, as for the menu. |
DTM-6 | WHILE presentation is modal, or mode is time or date-time, THE date-time picker SHALL hold the person's choice as a pending choice that starts, when it opens, as value (or as start and end) — a value the product sets while it is open SHALL NOT change it — SHALL show it in the header, the calendar, the range display, the wheels, the time display, the period and the dial, and SHALL commit it only WHEN OK is activated: it SHALL then emit change once with the pending choice in the mode's form if it differs from the one the picker opened with, and after that emit close with confirm. OK SHALL be disabled while the pending choice is incomplete (no date; no start or no end in a range) or a date-time range's end is before its start (DTM-33). |
DTM-7 | WHILE presentation is docked and mode is date, WHEN the user chooses a day that completes a choice (any available day; the end of a range) THE date-time picker SHALL emit change once with the new choice if it differs from value (or from start and end), and then emit close with select; choosing a range's start SHALL emit nothing and keep the picker open. Such a picker SHALL draw no actions. |
DTM-8 | THE date-time picker SHALL read and write value, start and end in the mode's form: "YYYY-MM-DD" in mode date, 24-hour "HH:MM" in mode time, "YYYY-MM-DDTHH:MM" in mode date-time. WHEN it opens with a time part empty (value, start or end empty, in mode time or date-time) it SHALL start that pending time at the device's current local time; WHEN a pending time's minute, from value or the device, is not a multiple of minuteStep it SHALL round it down to the step, so that the minute wheel and the dial can show it, and OK SHALL then commit the rounded time. In mode date-time a date chosen before its time keeps the pending time, and a date not yet chosen leaves the choice incomplete (DTM-6). |
DTM-9 | THE date-time picker SHALL lay out, from top to bottom, the header (DTM-10), the body and the actions (DTM-34), and between the body and the actions the error line while it is shown (DTM-33); it SHALL inset the body, the error line and the actions by comp.date-time-picker.container.padding-inline on both sides, and the body by comp.date-time-picker.container.padding-block above and below. The body SHALL hold the calendar while mode is date or date-time and the time section while mode is time or date-time: WHILE the vertical layout is used the calendar above the time section, and WHILE the horizontal layout is used side by side, the calendar at the start, comp.date-time-picker.container.gap apart; in mode time the horizontal layout SHALL keep the range display across the whole time section (DTM-12) and SHALL put, below it, the time display in a start column and the dial in an end column, each centred on the other, so that the time display stands beside the dial; in the wheels mode, which has one row below the range display, the horizontal layout SHALL draw the time section as the vertical one does. layout vertical and horizontal SHALL choose that layout; layout auto SHALL choose horizontal only WHEN the window's height less the margins is smaller than the vertical layout needs and its width less the margins can hold the horizontal layout, and otherwise vertical, deciding again when the window changes. |
DTM-10 | THE date-time picker SHALL draw a title row — label at the start in comp.date-time-picker.header.label.typescale and comp.date-time-picker.header.label.color, and the entry-mode tabs (DTM-13) at the end while they are drawn — in a modal picker always, and in a docked one only while the entry-mode tabs are drawn. WHILE presentation is modal and mode is date or date-time it SHALL draw below the title row, comp.date-time-picker.header.gap apart, the pending choice in comp.date-time-picker.header.value.typescale and comp.date-time-picker.header.value.color — a date in the locale's form with the abbreviated weekday, month and day ("Thu, Sep 17", "9月17日(木)"), with the time as the locale writes it in the clock in use in mode date-time ("Thu, Sep 17, 7:30 PM"), and a range as its start and end joined by an en dash ("Sep 10 – Sep 16"), each of the two an isolated run written as the locale writes it and the two in reading order, so that in a right-to-left layout the start stands at the right of the dash and the end at its left, with the year added to each date not in the current year — a date not chosen yet, the single value's or either end's of a range, written as dateLabel in comp.date-time-picker.header.placeholder.color, and never as a word for start or end, which the order and the dash already say; and below the header a divider of comp.date-time-picker.divider.width in comp.date-time-picker.divider.color across the container. THE date-time picker SHALL inset the header by comp.date-time-picker.header.padding-inline-start at the start, comp.date-time-picker.header.padding-inline-end at the end and comp.date-time-picker.header.padding-block above and below; the header SHALL grow with enlarged text, and its value SHALL wrap rather than be cut. THE date-time picker SHALL set the header's value's letter-spacing by the script of its text, as every title is set (PRS-20): no negative letter-spacing WHERE its language is Chinese, Japanese or Korean, and none WHERE its script joins its letters or stacks marks on them. |
DTM-11 | WHILE mode is date or date-time THE date-time picker SHALL show a Tanrei Calendar in single mode, or in range mode while range is true, giving it the pending dates, the dates of min and max (DTM-49), disabledDates and the isDateDisabled predicate, today, firstDayOfWeek, locale, startView, showAdjacentDays, startLabel, endLabel, previousMonthLabel, nextMonthLabel, yearViewLabel and todayLabel, and no label of its own (the picker's surface names it); a choice in the calendar SHALL change the pending dates and nothing else. It SHALL NOT change the calendar's tokens. WHILE range is true and mode is date-time, WHEN a start is chosen in the calendar the start's range field SHALL be selected, and WHEN an end is chosen the end's (DTM-15). |
DTM-12 | WHILE mode is time or date-time THE date-time picker SHALL draw the time section as rows, top to bottom and comp.date-time-picker.container.gap apart: the range display while range is true (DTM-15); the time display in the dial mode (DTM-21); and the wheels (DTM-18) or the dial (DTM-23). The time section SHALL be as wide as its widest row needs, never narrower than comp.date-time-picker.dial.container.size where the space it is given allows, and, WHILE the system offers both entry modes (DTM-13), as wide in the one as in the other — the wider of what the two need — so that switching the mode does not change the picker's width. The range display SHALL span the whole width of the time section in every layout — both columns in the horizontal layout of mode time (DTM-9) — because it is the first branch: which end everything below it shows and sets; every other row SHALL be centred. The time display SHALL be the row next to the dial in every layout — above it in the vertical layout, beside it in the horizontal one — with nothing between the two. The period of a 12-hour time SHALL be a part of the time display and of the wheels (DTM-14) and SHALL have no row of its own: THE date-time picker SHALL draw no row of tabs in the time section, and the entry-mode tabs of the title row (DTM-13) SHALL be its only tabs, Tanrei Tabs of the secondary variant whose variant and tokens the picker SHALL NOT change. |
DTM-13 | WHILE mode is time or date-time and comp.date-time-picker.time.entry-modes is both THE date-time picker SHALL draw the entry-mode tabs at the end of the title row: two tabs that hug their content, each an icon-only tab that draws a glyph of the system's icon set and keeps its word as its accessible name — the keyboard glyph named wheelsLabel first (at the start), because the wheels are where a number is typed (DTM-43), and the schedule glyph named dialLabel second — in a row named entryModeLabel whose panel is the time section, with the tab of the mode shown selected. THE date-time picker SHALL draw no word in these tabs; the glyphs' size, family and mirroring are the Tabs' own, and the icon set marks neither as mirrored. entryMode SHALL choose the mode shown WHEN the picker opens, and WHEN the other tab is selected THE date-time picker SHALL show that mode and keep the pending time, ending a typed entry first (DTM-45). WHILE comp.date-time-picker.time.entry-modes is wheels or dial THE date-time picker SHALL draw no entry-mode tabs and show that mode whatever entryMode says. |
DTM-14 | WHILE the 12-hour clock is used THE date-time picker SHALL draw the period — before or after noon — as a part of the time, and never as tabs, as a switch that spans the time section or as anything that reads as a choice above the time: in the wheels mode as the period wheel (DTM-46) and in the dial mode as the period selector, in the row of the hour and the minute. The period SHALL stand comp.date-time-picker.period.gap after the minute, or, WHERE the locale writes the period before the hour ("午前7:30"), the same gap before the hour. The period selector SHALL be a container at least comp.date-time-picker.period.container.width wide and as tall as the hour and minute selectors, with comp.date-time-picker.selector.container.shape corners eased by sys.shape.corner-smoothing, holding the name of the pending period as the locale writes it ("AM" or "PM"; "午前" or "午後") centred in comp.date-time-picker.period.label.typescale, and growing wider rather than cutting a longer name. It SHALL be drawn from the unselected selector's tokens in every state (comp.date-time-picker.unselected.selector.container.color, comp.date-time-picker.unselected.selector.label.color, comp.date-time-picker.unselected.selector.outline.color and comp.date-time-picker.unselected.selector.outline.width) and SHALL never be drawn from the selected condition: selected marks the unit the dial sets, and the period is not one, so the mark stays with the hour or the minute and the period stays the quiet part of the time. DTM-27 to DTM-32 SHALL hold for the period selector as for a selector of the unselected condition. WHEN the user activates the period selector by pointer, touch, Enter or Space THE date-time picker SHALL make the other period the pending period and keep the hour's number (7 before noon becomes 7 after noon, 19:00), show the new name at once, and SHALL NOT change the unit the dial shows, which selector is selected or where focus is. WHILE the 24-hour clock is used THE date-time picker SHALL draw no period. |
DTM-15 | WHILE range is true and mode is time or date-time THE date-time picker SHALL draw the range display: the start's range field, an en dash and the end's range field, in reading order and comp.date-time-picker.range-field.gap apart, in a group named rangeLabel, as the first row of the time section and across its whole width (DTM-12). Each range field SHALL be a container at least comp.date-time-picker.range-field.container.height tall with comp.date-time-picker.selector.container.shape corners eased by sys.shape.corner-smoothing, padded by comp.date-time-picker.range-field.container.padding-inline at each end, holding its end's pending time as the locale writes a time in the clock in use ("9:00 AM", "17:30"), centred, in comp.date-time-picker.range-field.label.typescale, with nextDayLabel added after the end's time while it falls on the next day (DTM-33); the two SHALL be equally wide and SHALL together fill the width of the time section less the dash and its gaps — never less than the wider one needs — so that the dash stands at the middle of the section and the range display is as wide as everything it governs. THE date-time picker SHALL draw each range field's container, label and outline from the selector tokens of its condition (comp.date-time-picker.unselected.selector.container.color, comp.date-time-picker.unselected.selector.label.color, comp.date-time-picker.unselected.selector.outline.color and comp.date-time-picker.unselected.selector.outline.width, and the same parts of selected): selected for the end the time section sets and unselected for the other, so that the end being set carries the mark the dial mode gives the unit being set. The dash SHALL be drawn in comp.date-time-picker.range-field.label.typescale and comp.date-time-picker.separator.color and be hidden from assistive technology. THE date-time picker SHALL draw no word for start or for end. The start's range field SHALL be selected when the picker opens, and the wheels, the time display, the period and the dial SHALL show and set the pending time of the end whose range field is selected. |
DTM-16 | THE date-time picker SHALL use the clock that hourCycle names: WHILE it is h12 hours SHALL run from 1 to 12 with a period; WHILE it is h23 hours SHALL run from 00 to 23 with no period; WHILE it is locale THE date-time picker SHALL use the locale's preferred clock, taking a locale that counts 0 to 11 as h12 and one that counts 1 to 24 as h23. WHERE the platform reports that the person chose 12- or 24-hour time for the whole device, that choice SHALL win over the locale's while hourCycle is locale; a platform that does not report it uses the locale alone. Values SHALL be 24-hour in every cycle. |
DTM-17 | THE date-time picker SHALL offer as minutes only the multiples of minuteStep from 00 up to 59: every minute for 1, and 00, 05 … 55 for 5, 00 … 50 for 10, 00, 15, 30, 45 for 15, and 00 and 30 for 30. WHEN minuteStep is not one of 1, 5, 10, 15 and 30 THE date-time picker SHALL behave as for 1 and in debug builds report the value. |
DTM-18 | WHILE the wheels mode is shown THE date-time picker SHALL draw the hour wheel, the separator and the minute wheel, always in that order from left to right, comp.date-time-picker.wheel.gap apart: each wheel comp.date-time-picker.wheel.width wide and comp.date-time-picker.wheel.height tall, a column of rows comp.date-time-picker.wheel.row.height tall holding its values in order (the hours of the clock in use, written as the locale writes an hour of it; the minutes of DTM-17 with two digits; both in the locale's digits) centred in comp.date-time-picker.wheel.label.typescale, running on past its ends from the first value again, so that the pending value sits in the middle row. Behind the middle row of each wheel THE date-time picker SHALL draw that wheel's selection container, as wide as the wheel and one row tall, in comp.date-time-picker.wheel.selection.container.color with comp.date-time-picker.wheel.selection.container.shape corners eased by sys.shape.corner-smoothing, so that the hour and the minute each stand on a ground of their own with the separator between the two grounds, as the selectors of the dial mode's time display do (DTM-21); WHILE comp.date-time-picker.wheel.selection.span is joined it SHALL instead draw one such container behind the middle row of both wheels and the separator. The values on a selection container SHALL be drawn in comp.date-time-picker.wheel.selected-label.color and the others in comp.date-time-picker.wheel.label.color. With the 12-hour clock the period wheel stands beside them (DTM-46), with its own selection container or, WHILE the span is joined, on the same band, which then runs behind all three. The separator SHALL be the locale's, level with the middle row, in comp.date-time-picker.wheel.label.typescale and comp.date-time-picker.separator.color. |
DTM-19 | WHEN the user drags or scrolls a wheel THE date-time picker SHALL move its rows with the pointer, and WHEN the drag ends SHALL let a fling carry on and slow down, then settle the nearest available row (DTM-50) on the selection container — over comp.date-time-picker.motion.wheel-duration with comp.date-time-picker.motion.wheel-easing when the wheel is not already moving — and make that row's value the pending hour or minute once it has settled; a drag released after the pointer has not moved for longer than the time after which the platform's velocity tracker takes a pointer as stopped (40 milliseconds in Android's VelocityTracker, Jetpack Compose's VelocityTracker and Flutter's VelocityTracker) or, where the platform names none (the web, SwiftUI, React Native), 40 milliseconds has no velocity, so THE date-time picker SHALL settle the nearest available row without carrying the wheel on; WHEN the user presses a row above or below the selection container THE date-time picker SHALL settle that row on it the same way — or, where that row is unavailable, the available row nearest it — and a press on the middle row that ends without a drag SHALL begin a typed entry (DTM-43). Moving a wheel SHALL NOT change the other wheel or the period, wrapping included (12 to 1 and 23 to 00 for hours, the last minute to 00), except where an hour leaves the time outside min and max, which DTM-49 then moves into them. WHERE motion is reduced a wheel SHALL settle at once and a fling SHALL stop where the drag ends. |
DTM-20 | THE date-time picker SHALL make the hour wheel and the minute wheel each one focusable adjustable control (a spin button) named hourLabel or minuteLabel (the period wheel's name and keys are DTM-47's), whose value is its value as drawn, with the period's name added to the hour's value while the 12-hour clock is used ("7 AM"): Up Arrow SHALL make its value the next available one and Down Arrow the previous one (DTM-50), wrapping from the last value to the first and back without changing the other unit or the period, each moving the rows over comp.date-time-picker.motion.wheel-duration (at once where motion is reduced); WHILE minuteStep is 1 Page Up and Page Down SHALL move the minute by five; Home and End SHALL set the first and the last available value; assistive technology's increment and decrement actions SHALL do what Up Arrow and Down Arrow do. The rows off the selection container SHALL be hidden from assistive technology. WHEN a wheel receives keyboard focus THE date-time picker SHALL show the focus ring around the wheel's selection container (around the wheel's part of it while the containers are joined), without animation; focus gained by pointer or touch SHALL NOT show it. Focus that a typed entry moves to the minute wheel (DTM-44) is keyboard focus, and a wheel that has focus becomes keyboard-focused WHEN a key or typed text works it — a digit, a key that moves it, a key that ends its entry — however focus first reached it. A digit typed while a wheel has focus SHALL begin a typed entry (DTM-43). A wheel SHALL draw no hover or press state: pressing a wheel starts a drag or, on its middle row, a typed entry. |
DTM-21 | WHILE the dial mode is shown THE date-time picker SHALL draw the time display as the hour selector, the separator and the minute selector, comp.date-time-picker.selector.gap apart, always in that order from left to right: each selector a container at least comp.date-time-picker.selector.container.width wide and comp.date-time-picker.selector.container.height tall with comp.date-time-picker.selector.container.shape corners eased by sys.shape.corner-smoothing, in the container color of its condition with an outline of its condition's width and color (comp.date-time-picker.unselected.selector.container.color, comp.date-time-picker.unselected.selector.outline.width and comp.date-time-picker.unselected.selector.outline.color, and so on), holding its value centred in comp.date-time-picker.selector.label.typescale and its condition's label color; the hour SHALL be written as the locale writes an hour of the clock in use ("7" in en-US with h12, "07" with h23) and the minute with two digits, both in the locale's digits; the separator SHALL be the locale's, in comp.date-time-picker.separator.typescale and comp.date-time-picker.separator.color. The selector whose unit the dial shows SHALL be drawn from the selected condition and the other from unselected. With the 12-hour clock the period selector stands in the same row, after the minute or before the hour (DTM-14). |
DTM-22 | THE date-time picker SHALL make each selector a focusable adjustable control (a spin button) named hourLabel or minuteLabel, whose value is its text as drawn with the period's name added to the hour's in the 12-hour clock: Up Arrow and Right Arrow SHALL make its value the next one and Down Arrow and Left Arrow the previous one (the next and previous available value, DTM-50; the minutes of DTM-17 for minutes), wrapping without changing the other unit or the period; WHILE minuteStep is 1 Page Up and Page Down SHALL move the minute by five; Home and End SHALL set the first and the last available value; assistive technology's increment and decrement actions SHALL do what Up Arrow and Down Arrow do. WHEN a selector receives focus or is pressed THE date-time picker SHALL show its unit on the dial and draw it as selected. A digit typed on a keyboard while a selector has focus SHALL be read as a wheel's typed entry is (DTM-44, DTM-45) — the same values, the same rounding to minuteStep, the hour's entry moving focus to the minute selector — with what has been typed shown as the selector's text; the dial mode SHALL NOT raise an on-screen keyboard. |
DTM-23 | WHILE the dial mode is shown THE date-time picker SHALL draw the dial as a circle of diameter comp.date-time-picker.dial.container.size in comp.date-time-picker.dial.container.color holding numbers at equal angles clockwise from the top: for hours with the 12-hour clock 12 at the top and 1 to 11; for hours with the 24-hour clock 00 at the top and 01 to 11 on the outer ring, and 12 at the top and 13 to 23 on an inner ring; for minutes 00 at the top and then every five minutes (05 to 55) while minuteStep is 1 or 5, and every step (10 to 50, 15 to 45, or 30) while it is larger; in the locale's digits, in comp.date-time-picker.dial.label.typescale and comp.date-time-picker.dial.label.color. The outer ring's numbers SHALL be centred on a circle whose radius is half comp.date-time-picker.dial.container.size less comp.date-time-picker.dial.padding less half comp.date-time-picker.dial.handle.size, and the inner ring's on a circle smaller by comp.date-time-picker.dial.handle.size. The dial SHALL run clockwise in every layout direction. |
DTM-24 | THE date-time picker SHALL draw the handle as a circle of diameter comp.date-time-picker.dial.handle.size in comp.date-time-picker.dial.handle.color centred where the pending value lies on the dial (an hour at its number, on the inner ring for 12 to 23 in 24-hour; a minute on the outer ring at six degrees a minute), a line of comp.date-time-picker.dial.track.width in comp.date-time-picker.dial.track.color from the dial's centre to the handle's centre, and a dot of diameter comp.date-time-picker.dial.center.size in comp.date-time-picker.dial.track.color at the centre; the part of a number that lies under the handle SHALL be drawn in comp.date-time-picker.dial.selected-label.color, and WHILE the minute dial shows a minute that is not a multiple of five the handle SHALL hold a dot of diameter comp.date-time-picker.dial.center.size in comp.date-time-picker.dial.selected-label.color at its centre. |
DTM-25 | WHEN the user presses or drags on the dial THE date-time picker SHALL move the handle, without animation, to the available value (DTM-50) whose angle from the dial's centre is nearest the pointer's (on the hour dial of the 24-hour clock, on the ring whose radius is nearer the pointer's distance from the centre; on the minute dial, to the nearest minute of DTM-17) and make it the pending hour or minute as it moves; WHEN a press or drag on the hour dial ends THE date-time picker SHALL show the minute dial, draw the minute selector as selected, and move focus to the minute selector if focus was on the hour selector. The dial SHALL be hidden from assistive technology, whose controls are the selectors (DTM-22). |
DTM-26 | WHEN the dial changes between hours and minutes THE date-time picker SHALL cross-fade its numbers and move the handle to the new unit's value over comp.date-time-picker.motion.dial-duration with comp.date-time-picker.motion.dial-easing, and WHEN the pending hour or minute changes by a key, a typed entry, an action of assistive technology or a range field it SHALL move the handle along the shorter arc over the same duration and easing; WHEN the entry-mode tabs switch between wheels and dial it SHALL cross-fade the two over the same duration and easing; WHERE motion is reduced it SHALL make these changes at once. |
DTM-27 | WHILE a selector or a range field is hovered, keyboard-focused or pressed THE date-time picker SHALL render its container, label, outline and opacity from the selector tokens of its condition in the highest-precedence active state, with precedence pressed over focused over hovered; focus gained by pointer or touch SHALL NOT select the focused state. WHEN these colors change between states or conditions THE date-time picker SHALL animate them over comp.date-time-picker.motion.state-duration with comp.date-time-picker.motion.state-easing, and SHALL change them at once where motion is reduced. |
DTM-28 | WHEN a selector or a range field receives keyboard focus THE date-time picker SHALL show the focus ring around its container without animation; focus gained by pointer or touch SHALL NOT show it. |
DTM-29 | WHEN the date-time picker's selector or range field is pressed by pointer, touch, Enter or Space THE date-time picker SHALL show the pressed state without delay and SHALL keep it visible for at least sys.motion.duration.press-hold, even when the press ends sooner. |
DTM-30 | WHILE pressed THE date-time picker's selector or range field SHALL answer as sys.behavior.pressed-feedback names: overlay applies the pressed tokens to the whole container at once; ripple grows the pressed state layer from the point of contact (from the center for keyboard activation); dim applies the pressed opacity to the whole control and draws no state layer; none draws no answer to the press. Under ripple and dim only the container color stays with the state under the press; label, outline, opacity and shape still come from the pressed tokens. Under none every part stays with the state under the press. The ripple grows over comp.date-time-picker.motion.feedback-duration with comp.date-time-picker.motion.state-easing, fades over comp.date-time-picker.motion.state-duration with comp.date-time-picker.motion.state-easing once the press has ended and press-hold has passed, and appears whole where motion is reduced. |
DTM-31 | THE date-time picker's selector and range field and the wheels' selection containers SHALL ease their corners by sys.shape.corner-smoothing (0 is a quarter circle, 0.6 the iOS continuous corner; a platform with only the OS curve draws it for any amount above 0), and its selector, range field and wheels SHALL show their keyboard focus as sys.behavior.focus-style names (ring or glow); a platform that cannot draw a choice SHALL fall back to the first value and state that in its README. |
DTM-32 | WHERE a selector or a range field would be smaller than the minimum target THE date-time picker SHALL make it at least sys.target.touch in each dimension for touch input and sys.target.pointer for fine pointers, because the selectors, and the range fields, sit side by side and cannot extend their hit areas over each other; a platform that cannot tell the input type SHALL use sys.target.touch. A wheel's rows SHALL each be at least the same target tall. |
DTM-33 | WHILE range is true and mode is time, WHEN the pending end is at or before the pending start THE date-time picker SHALL keep it as a time on the next day, add nextDayLabel after it in the end's range field (DTM-15) and commit it as it is. WHILE range is true, mode is date-time and the pending end is before the pending start THE date-time picker SHALL show rangeErrorText as the error line, in comp.date-time-picker.error.typescale and comp.date-time-picker.error.color, announce it once, politely, WHEN it appears, expose it as the description of the end's range field, and that field as invalid where the platform has that state for a button, and keep OK disabled; WHEN the end is no longer before the start it SHALL remove the line. |
DTM-34 | WHILE presentation is modal, or mode is time or date-time, THE date-time picker SHALL draw Cancel and OK as Tanrei Buttons of the medium size labelled cancelLabel and confirmLabel, in the variant comp.date-time-picker.actions.variant names, placed as a standard Button group places a dismissive and a confirming item (BGR-13 to BGR-19): Cancel at the start and OK at the end of a row, OK on top of a column, with focus and reading order following that order, comp.date-time-picker.actions.gap apart, with comp.date-time-picker.actions.padding-block above and below. WHILE comp.date-time-picker.actions.arrangement is fill they SHALL share the container's inner width equally, and WHILE it is end they SHALL keep their own widths, aligned to the end; either SHALL stack into a column WHEN a label does not fit its place on one line, deciding again when the width or the text size changes. THE date-time picker SHALL NOT change the Buttons' size or tokens; WHEN Cancel is activated it SHALL emit close with cancel. |
DTM-35 | WHEN a modal picker opens THE date-time picker SHALL fade its scrim in with its container (MDL-7), and make its container appear as every modal surface appears: from sys.motion.appear.opacity, sys.motion.appear.scale, sys.motion.appear.distance and sys.motion.appear.blur to whole, grown about its centre and travelling up into place — on both axes WHERE sys.behavior.appearance is unfold — over comp.date-time-picker.modal.motion.open-duration with comp.date-time-picker.modal.motion.open-easing, and WHEN it closes take the container back the same way to where it started while fading the scrim out, over comp.date-time-picker.modal.motion.close-duration with comp.date-time-picker.modal.motion.close-easing, a motion turned round going on from the opacity and the size it has reached; WHEN a modal picker is mounted with open true it SHALL appear without its motion while the document has not yet been first painted, and with it when it is mounted after that. WHEN a docked picker opens it SHALL fade its container in and grow it from the edge that faces the anchor over comp.date-time-picker.docked.motion.open-duration with comp.date-time-picker.docked.motion.open-easing, and WHEN it closes fade it out over comp.date-time-picker.docked.motion.close-duration with comp.date-time-picker.docked.motion.close-easing. WHERE motion is reduced a modal picker SHALL only fade its container in and out, over sys.motion.role.reduced, with no scale, distance or blur, and a docked one SHALL appear and disappear at once, and both SHALL appear and disappear at once on a platform whose reduced-motion setting removes every animation (Android's). |
DTM-36 | WHEN the parts of a modal picker do not fit in the window's height less the margins THE date-time picker SHALL keep the header and the actions in place and scroll the body and the error line between them, and WHEN the header and the actions alone leave no room it SHALL scroll all of its parts together; WHEN a docked picker is taller than the room left beside its anchor it SHALL limit its height to that room and scroll. WHERE the window is narrower than the picker's parts THE date-time picker SHALL be as wide as the window less the margins, let the calendar narrow as CAL-25 says, the entry-mode tabs scroll or truncate as tabs do and the range fields narrow equally, wrapping their text rather than cutting it, and never be wider than the window. Its wheels, selectors, period, range fields and dial numbers SHALL grow with enlarged text rather than clip it. |
DTM-37 | THE date-time picker SHALL expose its surface as a dialog named by label — its modal layer's modal dialog WHILE presentation is modal (MDL-10) — its entry-mode tabs as a tab list with its panel (DTM-13), the period as a spin button of two values (DTM-47), the range display as a group named rangeLabel that holds its two range fields as buttons (DTM-42), each wheel and each selector as a spin button (DTM-20, DTM-22) that stays one while a number is typed into it (DTM-43), the error line as the description of the end's range field while it is shown, and Cancel and OK by their labels; the dial, its numbers and the handle SHALL be hidden from assistive technology. A docked picker SHALL expose, on the element a person presses to open it, that it opens a dialog and whether it is open, where the platform has that property: that element is its anchor unless the platform takes a separate opener, as a Text field anchors the picker and its trailing button opens it. |
DTM-38 | THE date-time picker SHALL take month, weekday and period names, digits, date and time forms, the separator between hours and minutes, the first day of the week and the preferred clock from locale, or from the platform's current locale while locale is empty. Every date SHALL be a Gregorian calendar date and every time a time of day, without a time zone. |
DTM-39 | WHEN the layout direction is right-to-left THE date-time picker SHALL mirror its layout — the title row (the label at the right, the entry-mode tabs at the left, the wheels' tab still first), the columns of the horizontal layout, the side of the time the period stands on (after the minute is at the left of the time, before the hour at its right, DTM-14), the range display (the start's range field at the right of the dash and the end's at its left, each time an isolated run written as the locale writes it, as the header's range is, DTM-10) and the actions — and SHALL NOT mirror the order of the hour, the separator and the minute in the wheels and the time display, which is written left to right as a time is, nor the dial, which runs clockwise, nor the arrow keys of an hour or minute selector (DTM-22), where Right Arrow is the next value in every layout direction, nor those of the period (DTM-47), nor the period wheel, whose two names are one above the other, nor the order in which typed digits are read (DTM-44). |
DTM-40 | WHEN presentation, mode, hourCycle, entryMode, unit, layout, startView or firstDayOfWeek names a value the date-time picker does not define THE date-time picker SHALL behave as its default value and in debug builds report the unknown value; WHEN value, start or end is not empty and not in the mode's form, value is set while range is true or start or end while it is false, a date-time end is before its start, today or an entry of disabledDates is not an ISO 8601 calendar date, or min or max is not in a form the mode takes for it (a calendar date in mode date; a time of day in mode time; a date and time, or a calendar date, in mode date-time) THE date-time picker SHALL ignore it and in debug builds report it; WHEN min is later than max, or no time of minuteStep lies between them (DTM-49), THE date-time picker SHALL ignore both and report it in debug builds. |
DTM-41 | THE date-time picker SHALL take its layout direction from where it is used — the direction of the nearest ancestor that sets one, and the platform's own where none does — and SHALL have no direction setting of its own; WHEN that direction changes while the date-time picker is shown THE date-time picker SHALL draw itself for the new direction at once, without a motion of its own, keeping its open state, the pending choice and its focus, a docked container placed again by the new direction (DTM-2). |
DTM-42 | WHEN the user activates a range field that is not selected by pointer, touch, Enter or Space THE date-time picker SHALL make it the selected one, show its end's pending time in the wheels, the time display, the period and the dial (moving them as DTM-26 says, the dial keeping the unit it shows), end a typed entry first (DTM-45) and keep focus where it is; WHEN the selected range field is activated THE date-time picker SHALL change nothing. Each range field SHALL be a Tab stop of its own, the start's before the end's, and focus alone SHALL NOT select one, so that Tab passes the end's range field on its way to the wheels without changing which end they set. THE date-time picker SHALL expose each range field as a button named startLabel or endLabel followed by its time as drawn ("Start, 9:00 AM"; "End, 6:00 AM next day"), with its selected state (the pressed state of a toggle button where a button has no selected state, as on the web). Selecting a range field SHALL change no pending time and emit nothing. |
DTM-43 | WHILE the wheels mode is shown, WHEN the user presses the middle row of the hour wheel or the minute wheel and releases without dragging past the platform's touch slop (8 points where the platform names none), or types a digit while that wheel has focus, THE date-time picker SHALL begin a typed entry on that wheel: it SHALL give the wheel focus, ask the platform for its number keyboard where an on-screen keyboard is in use, keep the wheel a spin button for assistive technology, and for as long as the entry lasts draw the wheel's selection container, the value on it and its outline from the selected selector's tokens (comp.date-time-picker.selected.selector.container.color, comp.date-time-picker.selected.selector.label.color, comp.date-time-picker.selected.selector.outline.color and comp.date-time-picker.selected.selector.outline.width) — on the wheel's own part of the container while comp.date-time-picker.wheel.selection.span is joined — so that the unit being typed carries the mark the dial mode gives the unit being set, changing between the two looks as DTM-27 says. A press that begins an entry SHALL leave the wheel's value shown, as the text the first digit replaces; the rows above and below SHALL stay, and a press on one of them SHALL still settle it (DTM-19). Focus that reaches a wheel by Tab, or WHEN the picker opens (DTM-3), SHALL NOT begin an entry or raise the on-screen keyboard, and a modal picker SHALL stay clear of the on-screen keyboard as DTM-1 says. |
DTM-44 | WHILE a wheel takes a typed entry THE date-time picker SHALL read digits, ASCII or the locale's, and show what has been typed on the wheel's middle row in place of its value. The first digit SHALL replace the value. A second digit SHALL join the first WHERE the two make a value of the unit — an hour of the clock in use (1 to 12 with the 12-hour clock, 0 to 23 with the 24-hour clock), or a minute from 0 to 59 — and WHERE they do not, which only an hour can meet, the hour's entry SHALL end with the first digit and the second SHALL begin the minute's, so that 1 3 0 types half past one in the 12-hour clock. THE date-time picker SHALL end an entry, keeping what it read (DTM-45), WHEN it has two digits or one digit that no second digit could join (2 to 9 for the 12-hour hour, 3 to 9 for the 24-hour hour, 6 to 9 for the minute); an hour's entry that ends by its digits SHALL move focus to the minute wheel, where the next digit begins an entry, so that 7 3 0 and 0 7 3 0 both type half past seven. WHEN the locale's separator between hours and minutes, a colon, a full stop or a space is typed on the hour wheel THE date-time picker SHALL end the hour's entry and move focus to the minute wheel the same way. Backspace SHALL remove the last digit typed. Every other character SHALL be ignored, text that is pasted SHALL be read as its characters typed in order, and a typed entry SHALL never change the period (DTM-14). |
DTM-45 | WHEN a typed entry ends — by its digits (DTM-44), by Enter or the keyboard's action key, by Tab or focus leaving the wheel, by the on-screen keyboard being dismissed, by a press elsewhere in the picker, or by the wheel being dragged or scrolled — THE date-time picker SHALL make what it read the wheel's pending value WHERE it is a value of the unit, rounding a minute down to a multiple of minuteStep as DTM-8 does (a typed 50 is 45 with a step of 15) and taking an hour of the 12-hour clock in the pending period, and SHALL keep the value the wheel had WHERE nothing was typed, what was typed is not a value of the unit (0 alone for the 12-hour hour), or it is a value DTM-50 makes unavailable. It SHALL then show the pending value on the middle row, moving the rows to it over comp.date-time-picker.motion.wheel-duration with comp.date-time-picker.motion.wheel-easing (at once where motion is reduced), draw the selection container as it was before the entry, and expose the spin button's new value to assistive technology. WHEN Escape is pressed during a typed entry THE date-time picker SHALL end it, keep the value the wheel had and stay open, the press closing nothing (DTM-5); Enter SHALL end the entry without activating OK. WHILE an entry lasts Up Arrow, Down Arrow, Page Up, Page Down, Home and End SHALL first end it, keeping what it read, and then act as DTM-20 says. A typed entry SHALL be checked against nothing else: min and max are answered as DTM-49 and DTM-50 say; a range's end at or before its start is answered as DTM-33 says, whichever way it was set; and the time is committed by OK alone (DTM-6), so that a typed entry emits nothing. |
DTM-46 | WHILE the wheels mode is shown and the 12-hour clock is used THE date-time picker SHALL draw the period wheel beside the hour and minute wheels, at the side DTM-14 names and comp.date-time-picker.period.gap from them: a wheel at least comp.date-time-picker.period.container.width wide and as tall as the others, with rows of comp.date-time-picker.wheel.row.height holding the two names of the period as the locale writes them, the one before noon above the one after, centred in comp.date-time-picker.period.label.typescale, and not running on past its ends, so that the pending period sits in the middle row and the other in the row above or below it. It SHALL draw its selection container behind its middle row as the other wheels do (DTM-18), its own or its part of the joined band, with the name on it in comp.date-time-picker.wheel.selected-label.color and the other in comp.date-time-picker.wheel.label.color. THE period wheel SHALL be dragged, scrolled and settled as a wheel is (DTM-19), stopping at its first and its last name: WHEN it settles on the other name THE date-time picker SHALL make that period the pending period and keep the hour's number, and it SHALL settle back to the pending name from a name DTM-50 makes unavailable; a press on the other name's row SHALL settle it; and a press on the middle row that ends without a drag SHALL settle the other name too, because the period begins no typed entry (DTM-43): a typed letter sets it at once (DTM-47). It SHALL draw no hover or press state, as a wheel draws none (DTM-20). |
DTM-47 | THE date-time picker SHALL make the period — the period wheel or the period selector — one focusable adjustable control (a spin button) named periodLabel, whose value is the name of the pending period as drawn and which has two values, the one before noon first: Up Arrow and Down Arrow, and on the period selector Right Arrow and Left Arrow too, SHALL make the other period the pending period, in every layout direction; Home SHALL set the period before noon and End the one after; Enter and Space SHALL do what Up Arrow does; assistive technology's increment and decrement actions SHALL do what Up Arrow and Down Arrow do. The period SHALL be one Tab stop, where it is drawn: after the minute's, or before the hour's where it stands before the hour. WHEN it receives keyboard focus THE date-time picker SHALL show the focus ring around the period selector (DTM-28) or around the period wheel's selection container (DTM-20); taking focus SHALL change neither the period, the unit the dial shows nor which selector is selected, and WHEN the picker opens focus SHALL still go to the hour (DTM-3), wherever the period stands. A key, a press or a typed letter that asks for a period DTM-50 makes unavailable SHALL change nothing. A change of the period, however it is made, SHALL keep the hour's number and the minute (unless DTM-49 moves the time into min and max), leave the dial's handle where it is, change the value the hour's spin button exposes ("7 PM"), set the end whose range field is selected in a range (DTM-15), and commit nothing by itself (DTM-6). WHEN the person types, while the period has focus, the first character of the name of a period in the locale — compared without case, so A or P in English — THE date-time picker SHALL make that period the pending period, and WHERE the locale's two names begin with the same character (午前 and 午後) typing it SHALL make the other period the pending period, as a browser's own time field and the common time inputs do, so that a person who types a time types its period too; every other character typed while the period has focus, a digit among them, SHALL be ignored, and a typed entry of the hour or the minute still never changes the period (DTM-44). |
DTM-48 | THE date-time picker SHALL have no words of its own: it SHALL take dateLabel, startLabel, endLabel, confirmLabel, cancelLabel, previousMonthLabel, nextMonthLabel, yearViewLabel, todayLabel, hourLabel, minuteLabel, wheelsLabel, dialLabel, entryModeLabel, periodLabel, rangeLabel, nextDayLabel and rangeErrorText from the instance's prop and, WHILE that is empty, from the product's words of the same name; WHILE neither gives hourLabel, minuteLabel, periodLabel or todayLabel it SHALL take that word from the platform's locale data WHERE the platform has the locale's own name for the hour, the minute, the day period or the present day; label SHALL be the instance's alone; and it SHALL take no other word from anywhere. IF a word that is drawn is given by none of them THE date-time picker SHALL draw in its place a mark without words where one says the same — the glyph close for cancelLabel and the glyph check for confirmLabel, each in an icon-only Button of the same variant and size in the same place, and +1 in the locale's digits for nextDayLabel — and otherwise SHALL draw nothing and keep the place's height: the header's place for a date not chosen, the error line of DTM-33, whose other answers stand, and the title's words WHILE label is empty. IF a control or a group has no accessible name THE date-time picker SHALL still draw it and keep it working. In debug builds it SHALL report each missing word once, naming the prop. |
DTM-49 | WHILE mode is time or date-time THE date-time picker SHALL offer as times only those between min and max, both included: in mode time the times of day from min's to max's; in mode date-time, on the date of min the times from its time on, on the date of max the times up to its time, and every time of the days between — a bound that is a calendar date bounding the dates alone; and in a range each end by its own pending date. It SHALL take as the earliest time it offers the first minute of minuteStep at or after min, and as the latest the last one at or before max (a min of 09:07 with a step of 15 offers 09:15 first), so that it never offers a time that the Text field it opens from, which gives it its min and max with its request (TXI-33), refuses (TXI-46). WHEN the pending time of an end falls before the earliest time offered for it THE date-time picker SHALL make it that earliest time, and WHEN it falls after the latest, that latest time — as the picker opens with a value or a device time outside them (DTM-8), as a date chosen in the calendar is the date of a bound, and as an hour or a period that is set leaves the time outside them (7:30 AM under a min of 09:00 set to 9 is 9:00) — so that the pending time is always one that can be chosen and OK never commits a time min and max refuse; this is the only way one unit of the time changes another (DTM-19, DTM-47). WHILE mode is date-time THE date-time picker SHALL give the calendar the dates of min and max, and for min the date of the earliest time offered where minuteStep carries it into the next day. |
DTM-50 | WHILE mode is time or date-time THE date-time picker SHALL treat as unavailable an hour none of whose minutes of minuteStep it offers (DTM-49) — an hour of the 12-hour clock being one of the pending period —, a minute it does not offer in the pending hour, and a period none of whose times it offers. It SHALL keep every unavailable value in its place on the wheels, the period wheel and the dial and never leave one out, so that the values keep the order and the places a person knows them by and a wheel still runs on past its ends; and it SHALL draw an unavailable value at comp.date-time-picker.time.unavailable-opacity of its color. No entry mode SHALL make an unavailable value the pending one: a wheel or the period wheel that a drag, a fling, a scroll or a press would settle on one SHALL settle on the nearest available row instead, the one back toward where it came from on a tie (DTM-19, DTM-46); Up Arrow and Down Arrow, Right Arrow and Left Arrow on a selector, and assistive technology's increment and decrement SHALL make the value the next or the previous available one, passing over the unavailable ones and wrapping as DTM-20 and DTM-22 say; Page Up and Page Down SHALL move by five or, where that value is unavailable, to the available value nearest it on the way; Home and End SHALL set the first and the last available value; a press or a drag on the dial SHALL take the available value nearest the pointer (DTM-25); a typed entry that ends on an unavailable value SHALL keep the value it had (DTM-45); and a key, a press or a typed letter that asks for an unavailable period SHALL change nothing (DTM-47). THE date-time picker SHALL expose as the minimum and the maximum of each spin button — the hour, the minute and the period — the smallest and the largest of its available values, so that assistive technology, which never hears an unavailable value as a spin button's value, hears the range a person can reach; the rows off the selection container and the dial stay hidden from it (DTM-20, DTM-25). |
DTM-51 | WHEN the anchor of an open docked picker is no longer drawn: taken out of the page, given no box (on the web display none on it or on an ancestor), made invisible (visibility hidden) or skipped by its platform's content visibility (on the web content-visibility hidden, or auto while it is off screen), THE date-time picker SHALL emit close once with the reason anchor-hidden, choosing nothing, and SHALL NOT place its container against the anchor while it is not drawn, because a container with nothing beside it no longer says what it belongs to; WHEN it then closes THE date-time picker SHALL return focus as DTM-4 says. WHEN the anchor is drawn again while the picker is still open THE date-time picker SHALL follow it again, and emit close again the next time it is no longer drawn. A modal picker is placed against no anchor, and SHALL NOT close for this. |
DTM-52 | WHERE the platform has ARIA attributes (the web), WHEN the product sets an aria- attribute on the host, by the attribute or by the ARIA property that reflects it, THE date-time picker SHALL move it to the data-aria- attribute of the same name, so that the host is no second node with its name, description or state, and SHALL expose it on its surface, the dialog it is in every presentation — an id reference by the elements it names in the host's tree or a tree around it, a description after its own. WHILE label is not empty it is the surface's name, over a name given so; WHILE label is empty, a name given so is the surface's name, and the title row still draws no words (DTM-48). WHEN the product removes the aria- attribute or its data-aria- twin, or sets the ARIA property that reflects it (ariaLabel, ariaDescribedByElements…) to null, THE date-time picker SHALL take it off that element. |
プラットフォーム別の名前対応
パリティは API が同一であることを意味しません。同じ契約を、各プラットフォームの流儀で表現します。
| 仕様 | Web | SwiftUI | Jetpack Compose | Flutter | React Native |
|---|---|---|---|---|---|
| コンポーネント | tanrei-date-time-picker | tanreiDateTimePicker | TanreiDateTimePicker | TanreiDateTimePicker | DateTimePicker |
open · プロパティ | open | isPresented | visible | showTanreiDateTimePicker | visible |
presentation · プロパティ | presentation | presentation | presentation | TanreiDateTimePickerAnchor | presentation |
mode · プロパティ | mode | mode | mode | mode | mode |
range · プロパティ | range | range | range | range | range |
value · プロパティ | value | selection | value | value | value |
start · プロパティ | start | range | start | start | start |
end · プロパティ | end | range | end | end | end |
min · プロパティ | min | minDate | min | firstDate | min |
max · プロパティ | max | maxDate | max | lastDate | max |
disabledDates · プロパティ | disabledDates | disabledDates | disabledDates | disabledDates | disabledDates |
today · プロパティ | today | today | today | currentDate | today |
firstDayOfWeek · プロパティ | firstDayOfWeek | firstDayOfWeek | firstDayOfWeek | firstDayOfWeek | firstDayOfWeek |
locale · プロパティ | locale | locale | locale | locale | locale |
startView · プロパティ | startView | startView | startView | startView | startView |
showAdjacentDays · プロパティ | showAdjacentDays | showsAdjacentDays | showAdjacentDays | showAdjacentDays | showAdjacentDays |
hourCycle · プロパティ | hourCycle | hourCycle | hourCycle | hourCycle | hourCycle |
minuteStep · プロパティ | minuteStep | minuteStep | minuteStep | minuteStep | minuteStep |
entryMode · プロパティ | entryMode | entryMode | entryMode | entryMode | entryMode |
unit · プロパティ | unit | unit | unit | unit | unit |
layout · プロパティ | layout | layout | layout | layout | layout |
label · プロパティ | label | label | label | label | label |
dateLabel · プロパティ | dateLabel | dateLabel | dateLabel | dateLabel | dateLabel |
startLabel · プロパティ | startLabel | startLabel | startLabel | startLabel | startLabel |
endLabel · プロパティ | endLabel | endLabel | endLabel | endLabel | endLabel |
confirmLabel · プロパティ | confirmLabel | confirmLabel | confirmLabel | confirmLabel | confirmLabel |
cancelLabel · プロパティ | cancelLabel | cancelLabel | cancelLabel | cancelLabel | cancelLabel |
previousMonthLabel · プロパティ | previousMonthLabel | previousMonthLabel | previousMonthLabel | previousMonthLabel | previousMonthLabel |
nextMonthLabel · プロパティ | nextMonthLabel | nextMonthLabel | nextMonthLabel | nextMonthLabel | nextMonthLabel |
yearViewLabel · プロパティ | yearViewLabel | yearViewLabel | yearViewLabel | yearViewLabel | yearViewLabel |
todayLabel · プロパティ | todayLabel | todayLabel | todayLabel | todayLabel | todayLabel |
hourLabel · プロパティ | hourLabel | hourLabel | hourLabel | hourLabel | hourLabel |
minuteLabel · プロパティ | minuteLabel | minuteLabel | minuteLabel | minuteLabel | minuteLabel |
wheelsLabel · プロパティ | wheelsLabel | wheelsLabel | wheelsLabel | wheelsLabel | wheelsLabel |
dialLabel · プロパティ | dialLabel | dialLabel | dialLabel | dialLabel | dialLabel |
entryModeLabel · プロパティ | entryModeLabel | entryModeLabel | entryModeLabel | entryModeLabel | entryModeLabel |
periodLabel · プロパティ | periodLabel | periodLabel | periodLabel | periodLabel | periodLabel |
rangeLabel · プロパティ | rangeLabel | rangeLabel | rangeLabel | rangeLabel | rangeLabel |
nextDayLabel · プロパティ | nextDayLabel | nextDayLabel | nextDayLabel | nextDayLabel | nextDayLabel |
rangeErrorText · プロパティ | rangeErrorText | rangeErrorText | rangeErrorText | rangeErrorText | rangeErrorText |
change · イベント | change | selection | onChange | onChanged | onChange |
close · イベント | close | onClose | onClose | onClose | onClose |
| 備考 | Attributes are kebab-case (disabled-dates is a space-separated list of ISO dates, first-day-of-week, start-view, show-adjacent-days, hour-cycle, minute-step, entry-mode, wheels-label, …); isDateDisabled is a property only. entryMode is not HTML's global inputmode. value, start and end are the strings of <input type=date>, type=time and type=datetime-local, set before change fires; close is a CustomEvent whose detail.reason is the reason. A modal picker is a native <dialog> opened with showModal() in the shadow root, with ::backdrop as the scrim; its cancel becomes close with escape when an Escape key caused it, and with back otherwise. A docked picker takes anchor and opener (element ids), sets aria-haspopup="dialog", aria-controls and aria-expanded on the opener, and is a manual popover in the top layer with its own light dismiss so that close carries its reason. Inside the shadow root: a <tanrei-calendar>; one <tanrei-tabs variant="secondary"> row, the entry-mode tabs, which hugs and whose two <tanrei-tab>s are label-hidden with icon="keyboard" and icon="schedule", and whose panel is the time section; the period as an element with role spinbutton (aria-valuemin="1", aria-valuemax="2", aria-valuenow and the period's name as aria-valuetext), part="period" — a third wheel of two rows that does not loop in the wheels mode, a button-like cell in the time display in the dial mode — placed before the hour when formatToParts gives the dayPeriod part before the hour part; the range display as a role="group" with two <button part="range-field" aria-pressed> and an aria-hidden dash, in a grid with two equal columns that fills the time section's inline size (and both columns of the horizontal layout of mode time); wheels and selectors as elements with role spinbutton, a wheel's middle row being an <input inputmode="numeric" role="spinbutton"> that is read-only until a typed entry begins (a tap that ends without a drag, or a digit key), so that a drag raises no keyboard; the dial drawn with pointer events and aria-hidden; Cancel and OK as <tanrei-button>s placed by the button group's placement code, with the variant read from the resolved comp.date-time-picker.actions.variant. The entry modes offered are read from the resolved comp.date-time-picker.time.entry-modes once per system. Locale data from Intl.DateTimeFormat (formatToParts with hour12 for the period names and the separator; resolvedOptions().hourCycle for the preferred clock); without locale it reads the nearest lang attribute, then navigator.language. It uses the package's locale helpers, overlay placement and dial (clock.ts). A value outside min and max (DTM-50) is a wheel row or a dial number with data-unavailable, faded by opacity; a spin button's aria-valuemin and aria-valuemax are its first and last available values. The inline attribute, for tests, draws the open surface in place (DTM-1's verify). Words: the element has no words of its own. A words attribute (confirm-label, cancel-label, hour-label and the others) left empty read the product's words, set once with setWords() from @tanrei/web; the element draws again when they change. Where neither the instance nor the product gives them, the hour's, the minute's and the period's names are Intl.DisplayNames(locale, { type: 'dateTimeField' }) (hour, minute, dayPeriod) and the present day's word is Intl.RelativeTimeFormat's for day 0. | Planned. A view modifier, as .sheet and .popover are: .tanreiDateTimePicker(isPresented:, selection: Binding<DateComponents?>, mode:, presentation:, …) for one value and .tanreiDateTimePicker(isPresented:, range: Binding<TanreiDateTimeRange>, mode:, …) for a span, where TanreiDateTimeRange holds start and end as DateComponents?; the overload is range, and mode chooses which components are read and written (year, month and day; hour and minute; or both), so no time zone enters. Writing the binding is change; the picker writes false to isPresented itself and calls onClose with the reason. The words are fields of a TanreiDateTimePickerLabels passed as labels:, whose field names are the spec's. locale defaults to the \.locale environment; the preferred clock comes from DateFormatter.dateFormat(fromTemplate: "j", …). Modal: .fullScreenCover with a clear background and the system transition off, as the dialog. Docked: drawn in its anchor's overlay and placed by Tanrei. The calendar is TanreiCalendar, the entry-mode tabs TanreiTabs (each with a glyph and labelStyle: .iconOnly), the period one view with .accessibilityAdjustableAction and .accessibilityValue (a third wheel in the wheels mode, a pressable cell in the dial mode), the range fields two Buttons with the .isSelected trait in an accessibility container, a typed entry a hidden TextField with .keyboardType(.numberPad) on iOS and .onKeyPress for digits elsewhere, the actions TanreiButtons; the wheels are Tanrei's own (a scroll view with .scrollTargetBehavior(.viewAligned) per wheel) with .accessibilityAdjustableAction, not the system's wheel picker, whose look no token reaches. Snapshot harness: TanreiDateTimePickerSurface drawn in place on the fixture's stage. The product's words are read from the \.tanreiWords environment value. | Planned. TanreiDateTimePicker(visible, onClose, presentation, mode, range, value, start, end, onChange, min, max, disabledDates, isDateDisabled, today, firstDayOfWeek, locale, startView, showAdjacentDays, hourCycle, minuteStep, entryMode, unit, layout, labels). Values are TanreiDateTime(date: TanreiDate?, time: TanreiTime?), of which mode says which half is read (API 23 has no java.time); onChange receives a TanreiDateTimeSelection(value, start, end); the caller keeps the state (hoisting) and sets visible to false from onClose, which carries the reason. The words, label among them, are fields of a TanreiDateTimePickerLabels. Modal: a Dialog window with the platform width and dim off, as TanreiDialog. Docked: a Popup inside the anchor's Box, as TanreiMenu. The calendar is TanreiCalendar, the entry-mode tabs TanreiTabs (icon-only), the period one node with progressBarRangeInfo over two steps, stateDescription for its name and setProgress (a third wheel in the wheels mode, a clickable cell in the dial mode), the range fields two boxes with Role.Button and selected semantics, a typed entry a BasicTextField with KeyboardType.Number behind the wheel's middle row and onPreviewKeyEvent for digits, the actions TanreiButtons; each wheel is a LazyColumn with snapping fling and progressBarRangeInfo / setProgress semantics; the dial is pointerInput with clearAndSetSemantics {}. Snapshot harness: TanreiDateTimePickerContent drawn in place on the fixture's stage. The product's words are read from LocalTanreiWords. | Planned. Flutter's idiom, as its own date and time pickers: a modal picker is showTanreiDateTimePicker(context:, mode:, range:, value:, start:, end:, firstDate:, lastDate:, …), which pushes a modal route that draws the scrim as its barrier and returns a Future<TanreiDateTimeSelection?>, completed with the committed choice on OK and with null otherwise; onChanged and onClose are also called, in that order. A docked picker is TanreiDateTimePickerAnchor(controller:, builder:, …), shaped like the menu's anchor and shown in the Overlay. firstDate, lastDate and currentDate keep Flutter's names. Values are DateTimes of which only the parts mode names are read. Month, weekday and period names, date forms, the separator and the preferred clock come from TanreiDateLocalizations (English built in, no intl dependency), and MediaQuery.alwaysUse24HourFormatOf wins for hourCycle locale. The calendar is TanreiCalendar, the entry-mode tabs TanreiTabBar (icon-only), the period one widget under Semantics with value, increasedValue, decreasedValue, onIncrease and onDecrease (a third wheel that does not loop in the wheels mode, a pressable cell in the dial mode), the range fields two widgets under Semantics(button: true, selected:), a typed entry an EditableText with TextInputType.number behind the wheel's middle row and a Focus onKeyEvent for digits, the actions TanreiButtons; each wheel is a ListWheelScrollView.useDelegate with a looping child delegate and a FixedExtentScrollPhysics, under Semantics with increasedValue, decreasedValue, onIncrease and onDecrease. Snapshot harness: a golden of the whole stage after showTanreiDateTimePicker (modal), or of TanreiDateTimePicker drawn in place (docked). The product's words are read from the TanreiWords inherited widget, which the app fills from its own localizations. | Planned. Controlled: visible, onClose({ reason }) and onChange({ value, start, end }), the values being the mode's ISO strings, never Date objects; the caller moves them and sets visible to false. A product that also uses the community package of the same name imports this one under another name. A modal picker is presented in a transparent Modal with animationType="none", statusBarTranslucent and navigationBarTranslucent, as the dialog; a docked picker takes anchorRef and is drawn on the overlay layer that TanreiProvider renders, placed by measuring the anchor, with Android's back (BackHandler) as close. The calendar is the package's Calendar, the entry-mode tabs its Tabs (icon-only), the period one view with the adjustable role, accessibilityValue.text and the increment and decrement actions (a third wheel in the wheels mode, a Pressable cell in the dial mode), the range fields two Pressables with the button role and accessibilityState.selected, a typed entry a TextInput with keyboardType="number-pad" behind the wheel's middle row, the actions its Buttons; each wheel is a FlatList with snapToInterval and the adjustable role with the increment and decrement actions; the dial uses the responder system and is hidden from accessibility. Locale data from Hermes's Intl.DateTimeFormat. Snapshot harness: DateTimePickerSurface drawn in place on the fixture's stage. The product's words are read from the TanreiWordsProvider context. |
トークン
| トークン | 参照先 | 解決値(ライト) |
|---|---|---|
--tanrei-comp-date-time-picker-actions-arrangement | — | 0 |
--tanrei-comp-date-time-picker-actions-gap | sys.space.space200 | 16px |
--tanrei-comp-date-time-picker-actions-padding-block | sys.space.space150 | 12px |
--tanrei-comp-date-time-picker-actions-variant | — | 1 |
--tanrei-comp-date-time-picker-container-gap | sys.space.space200 | 16px |
--tanrei-comp-date-time-picker-container-padding-block | sys.space.space100 | 8px |
--tanrei-comp-date-time-picker-container-padding-inline | sys.space.space150 | 12px |
--tanrei-comp-date-time-picker-dial-center-size | — | 8px |
--tanrei-comp-date-time-picker-dial-container-color | sys.color.surface-dim | |
--tanrei-comp-date-time-picker-dial-container-size | — | 256px |
--tanrei-comp-date-time-picker-dial-handle-color | sys.color.primary | |
--tanrei-comp-date-time-picker-dial-handle-size | — | 48px |
--tanrei-comp-date-time-picker-dial-label-color | sys.color.on-surface | |
--tanrei-comp-date-time-picker-dial-padding | sys.space.space100 | 8px |
--tanrei-comp-date-time-picker-dial-selected-label-color | sys.color.on-primary | |
--tanrei-comp-date-time-picker-dial-track-color | sys.color.primary | |
--tanrei-comp-date-time-picker-dial-track-width | sys.border.thick | 2px |
--tanrei-comp-date-time-picker-divider-color | sys.color.outline-variant | |
--tanrei-comp-date-time-picker-divider-width | sys.border.hairline | 1px |
--tanrei-comp-date-time-picker-docked-container-color | sys.color.surface-bright | |
--tanrei-comp-date-time-picker-docked-container-elevation | sys.elevation.level2 | 0px 0px 0px 1px rgb(0 0 0 / 0.08), 0px 1px 2px 0px rgb(0 0 0 / 0.04) |
--tanrei-comp-date-time-picker-docked-container-shape | sys.shape.corner.medium | 8px |
--tanrei-comp-date-time-picker-docked-motion-close-duration | sys.motion.role.appear.anchored.exit | 250ms |
--tanrei-comp-date-time-picker-docked-motion-close-easing | sys.motion.easing.exit | cubic-bezier(0.3, 0, 1, 1) |
--tanrei-comp-date-time-picker-docked-motion-open-duration | sys.motion.role.appear.anchored.enter | 300ms |
--tanrei-comp-date-time-picker-docked-motion-open-easing | sys.motion.easing.enter | cubic-bezier(0.2, 0, 0, 1) |
--tanrei-comp-date-time-picker-docked-offset | sys.space.space50 | 4px |
--tanrei-comp-date-time-picker-docked-viewport-margin | sys.space.space100 | 8px |
--tanrei-comp-date-time-picker-error-color | sys.color.error | |
--tanrei-comp-date-time-picker-focused-opacity | — | 1 |
--tanrei-comp-date-time-picker-header-gap | sys.space.space50 | 4px |
--tanrei-comp-date-time-picker-header-label-color | sys.color.on-surface-variant | |
--tanrei-comp-date-time-picker-header-padding-block | sys.space.space200 | 16px |
--tanrei-comp-date-time-picker-header-padding-inline-end | sys.space.space150 | 12px |
--tanrei-comp-date-time-picker-header-padding-inline-start | sys.space.space300 | 24px |
--tanrei-comp-date-time-picker-header-placeholder-color | sys.color.on-surface-variant | |
--tanrei-comp-date-time-picker-header-value-color | sys.color.on-surface | |
--tanrei-comp-date-time-picker-hovered-opacity | — | 1 |
--tanrei-comp-date-time-picker-modal-container-color | sys.color.surface-bright | |
--tanrei-comp-date-time-picker-modal-container-elevation | sys.elevation.level3 | 0px 0px 0px 1px rgb(0 0 0 / 0.08), 0px 1px 1px 0px rgb(0 0 0 / 0.04), 0px 4px 8px -4px rgb(0 0 0 / 0.04), 0px 16px 24px -8px rgb(0 0 0 / 0.06) |
--tanrei-comp-date-time-picker-modal-container-margin | sys.space.space200 | 16px |
--tanrei-comp-date-time-picker-modal-container-shape | sys.shape.corner.large | 12px |
--tanrei-comp-date-time-picker-modal-motion-close-duration | comp.modal-layer.motion.exit-duration | 300ms |
--tanrei-comp-date-time-picker-modal-motion-close-easing | comp.modal-layer.motion.exit-easing | cubic-bezier(0.3, 0, 1, 1) |
--tanrei-comp-date-time-picker-modal-motion-open-duration | comp.modal-layer.motion.enter-duration | 350ms |
--tanrei-comp-date-time-picker-modal-motion-open-easing | comp.modal-layer.motion.enter-easing | cubic-bezier(0.2, 0, 0, 1) |
--tanrei-comp-date-time-picker-modal-scrim-blur | comp.modal-layer.scrim.blur | 0px |
--tanrei-comp-date-time-picker-modal-scrim-color | comp.modal-layer.scrim.color | |
--tanrei-comp-date-time-picker-motion-dial-duration | sys.motion.role.selection.travel | 250ms |
--tanrei-comp-date-time-picker-motion-dial-easing | sys.motion.easing.spatial | cubic-bezier(0.2, 0, 0, 1) |
--tanrei-comp-date-time-picker-motion-feedback-duration | sys.motion.role.feedback | 450ms |
--tanrei-comp-date-time-picker-motion-state-duration | sys.motion.role.state.compact | 200ms |
--tanrei-comp-date-time-picker-motion-state-easing | sys.motion.easing.state | cubic-bezier(0.2, 0, 0, 1) |
--tanrei-comp-date-time-picker-motion-wheel-duration | sys.motion.duration.medium1 | 250ms |
--tanrei-comp-date-time-picker-motion-wheel-easing | sys.motion.easing.standard-decelerate | cubic-bezier(0, 0, 0, 1) |
--tanrei-comp-date-time-picker-period-container-width | — | 56px |
--tanrei-comp-date-time-picker-period-gap | sys.space.space100 | 8px |
--tanrei-comp-date-time-picker-pressed-opacity | — | 1 |
--tanrei-comp-date-time-picker-range-field-container-height | — | 48px |
--tanrei-comp-date-time-picker-range-field-container-padding-inline | sys.space.space200 | 16px |
--tanrei-comp-date-time-picker-range-field-gap | sys.space.space100 | 8px |
--tanrei-comp-date-time-picker-selected-focused-selector-container-color | — | |
--tanrei-comp-date-time-picker-selected-focused-selector-label-color | — | |
--tanrei-comp-date-time-picker-selected-focused-selector-outline-color | — | |
--tanrei-comp-date-time-picker-selected-focused-selector-outline-width | — | 2px |
--tanrei-comp-date-time-picker-selected-focused-selector-state-layer-color | — | |
--tanrei-comp-date-time-picker-selected-hovered-selector-container-color | — | |
--tanrei-comp-date-time-picker-selected-hovered-selector-label-color | — | |
--tanrei-comp-date-time-picker-selected-hovered-selector-outline-color | — | |
--tanrei-comp-date-time-picker-selected-hovered-selector-outline-width | — | 2px |
--tanrei-comp-date-time-picker-selected-hovered-selector-state-layer-color | — | |
--tanrei-comp-date-time-picker-selected-pressed-selector-container-color | — | |
--tanrei-comp-date-time-picker-selected-pressed-selector-label-color | — | |
--tanrei-comp-date-time-picker-selected-pressed-selector-outline-color | — | |
--tanrei-comp-date-time-picker-selected-pressed-selector-outline-width | — | 2px |
--tanrei-comp-date-time-picker-selected-pressed-selector-state-layer-color | — | |
--tanrei-comp-date-time-picker-selected-selector-container-color | sys.color.surface-dim | |
--tanrei-comp-date-time-picker-selected-selector-label-color | sys.color.on-surface | |
--tanrei-comp-date-time-picker-selected-selector-outline-color | sys.color.primary | |
--tanrei-comp-date-time-picker-selected-selector-outline-width | sys.border.thick | 2px |
--tanrei-comp-date-time-picker-selected-selector-state-layer-color | comp.date-time-picker.selected.selector.label.color | |
--tanrei-comp-date-time-picker-selector-container-height | — | 80px |
--tanrei-comp-date-time-picker-selector-container-shape | sys.shape.corner.medium | 8px |
--tanrei-comp-date-time-picker-selector-container-width | — | 96px |
--tanrei-comp-date-time-picker-selector-gap | sys.space.space50 | 4px |
--tanrei-comp-date-time-picker-separator-color | sys.color.on-surface | |
--tanrei-comp-date-time-picker-time-entry-modes | — | 0 |
--tanrei-comp-date-time-picker-time-unavailable-opacity | sys.state.disabled-content-opacity | 0.38 |
--tanrei-comp-date-time-picker-unselected-focused-selector-container-color | — | |
--tanrei-comp-date-time-picker-unselected-focused-selector-label-color | — | |
--tanrei-comp-date-time-picker-unselected-focused-selector-outline-color | — | |
--tanrei-comp-date-time-picker-unselected-focused-selector-outline-width | — | 1px |
--tanrei-comp-date-time-picker-unselected-focused-selector-state-layer-color | — | |
--tanrei-comp-date-time-picker-unselected-hovered-selector-container-color | — | |
--tanrei-comp-date-time-picker-unselected-hovered-selector-label-color | — | |
--tanrei-comp-date-time-picker-unselected-hovered-selector-outline-color | — | |
--tanrei-comp-date-time-picker-unselected-hovered-selector-outline-width | — | 1px |
--tanrei-comp-date-time-picker-unselected-hovered-selector-state-layer-color | — | |
--tanrei-comp-date-time-picker-unselected-pressed-selector-container-color | — | |
--tanrei-comp-date-time-picker-unselected-pressed-selector-label-color | — | |
--tanrei-comp-date-time-picker-unselected-pressed-selector-outline-color | — | |
--tanrei-comp-date-time-picker-unselected-pressed-selector-outline-width | — | 1px |
--tanrei-comp-date-time-picker-unselected-pressed-selector-state-layer-color | — | |
--tanrei-comp-date-time-picker-unselected-selector-container-color | sys.color.surface-dim | |
--tanrei-comp-date-time-picker-unselected-selector-label-color | sys.color.on-surface | |
--tanrei-comp-date-time-picker-unselected-selector-outline-color | — | |
--tanrei-comp-date-time-picker-unselected-selector-outline-width | sys.border.hairline | 1px |
--tanrei-comp-date-time-picker-unselected-selector-state-layer-color | comp.date-time-picker.unselected.selector.label.color | |
--tanrei-comp-date-time-picker-wheel-gap | sys.space.space50 | 4px |
--tanrei-comp-date-time-picker-wheel-height | — | 240px |
--tanrei-comp-date-time-picker-wheel-label-color | sys.color.on-surface-variant | |
--tanrei-comp-date-time-picker-wheel-row-height | — | 48px |
--tanrei-comp-date-time-picker-wheel-selected-label-color | sys.color.on-surface | |
--tanrei-comp-date-time-picker-wheel-selection-container-color | sys.color.surface-dim | |
--tanrei-comp-date-time-picker-wheel-selection-container-shape | sys.shape.corner.medium | 8px |
--tanrei-comp-date-time-picker-wheel-selection-span | — | 0 |
--tanrei-comp-date-time-picker-wheel-width | — | 80px |
--tanrei-comp-date-time-picker-dial-label-typescale | sys.typescale.body-large | 400 16px/1.625 |
--tanrei-comp-date-time-picker-error-typescale | sys.typescale.body-small | 400 13px/1.5385 |
--tanrei-comp-date-time-picker-header-label-typescale | sys.typescale.label | 500 14px/1.4286 |
--tanrei-comp-date-time-picker-header-value-typescale | sys.typescale.heading-2 | 500 24px/1.3333 |
--tanrei-comp-date-time-picker-period-label-typescale | sys.typescale.heading-5 | 500 16px/1.5 |
--tanrei-comp-date-time-picker-range-field-label-typescale | sys.typescale.heading-5 | 500 16px/1.5 |
--tanrei-comp-date-time-picker-selector-label-typescale | sys.typescale.display | 450 48px/1.0833 |
--tanrei-comp-date-time-picker-separator-typescale | sys.typescale.display | 450 48px/1.0833 |
--tanrei-comp-date-time-picker-wheel-label-typescale | sys.typescale.heading-3 | 500 20px/1.4 |
フィクスチャ
基準となる描画パターンです。全プラットフォームが同じ ID でスナップショットを撮り、結果を比較できるようにしています。
modal-date
open: true mode: date value: 2026-09-17 today: 2026-09-24 locale: en-US label: Select date dateLabel: Date confirmLabel: OK cancelLabel: Cancel previousMonthLabel: Previous month nextMonthLabel: Next month yearViewLabel: Choose a year todayLabel: Today 480 × 720 のウィンドウに単独で描画modal-date-empty
open: true mode: date today: 2026-09-24 locale: en-US label: Select date dateLabel: Date confirmLabel: OK cancelLabel: Cancel previousMonthLabel: Previous month nextMonthLabel: Next month yearViewLabel: Choose a year todayLabel: Today 480 × 720 のウィンドウに単独で描画modal-date-range
open: true mode: date range: true start: 2026-09-10 end: 2026-09-16 today: 2026-09-24 locale: en-US label: Select dates dateLabel: Date startLabel: Start endLabel: End confirmLabel: OK cancelLabel: Cancel previousMonthLabel: Previous month nextMonthLabel: Next month yearViewLabel: Choose a year todayLabel: Today 480 × 720 のウィンドウに単独で描画modal-date-range-start
open: true mode: date range: true start: 2026-09-10 today: 2026-09-24 locale: en-US label: Select dates dateLabel: Date startLabel: Start endLabel: End confirmLabel: OK cancelLabel: Cancel previousMonthLabel: Previous month nextMonthLabel: Next month yearViewLabel: Choose a year todayLabel: Today 480 × 720 のウィンドウに単独で描画modal-date-year
open: true mode: date value: 2026-09-17 today: 2027-01-15 locale: en-US startView: year label: Select date dateLabel: Date confirmLabel: OK cancelLabel: Cancel previousMonthLabel: Previous month nextMonthLabel: Next month yearViewLabel: Choose a year todayLabel: Today 480 × 720 のウィンドウに単独で描画modal-time
open: true mode: time value: 07:30 locale: en-US hourCycle: h12 label: Select time confirmLabel: OK cancelLabel: Cancel hourLabel: Hour minuteLabel: Minute wheelsLabel: Wheels dialLabel: Dial entryModeLabel: Time input periodLabel: Period 480 × 720 のウィンドウに単独で描画modal-time-24h
open: true mode: time value: 19:30 locale: en-US hourCycle: h23 label: Select time confirmLabel: OK cancelLabel: Cancel hourLabel: Hour minuteLabel: Minute wheelsLabel: Wheels dialLabel: Dial entryModeLabel: Time input periodLabel: Period 480 × 720 のウィンドウに単独で描画modal-time-ja
open: true mode: time value: 07:30 locale: ja-JP hourCycle: h12 label: 時刻を選択 confirmLabel: OK cancelLabel: キャンセル hourLabel: 時 minuteLabel: 分 wheelsLabel: ホイール dialLabel: ダイヤル entryModeLabel: 時刻の入力方法 periodLabel: 午前/午後 480 × 720 のウィンドウに単独で描画modal-time-step
open: true mode: time value: 07:45 locale: en-US hourCycle: h12 minuteStep: 15 label: Select time confirmLabel: OK cancelLabel: Cancel hourLabel: Hour minuteLabel: Minute wheelsLabel: Wheels dialLabel: Dial entryModeLabel: Time input periodLabel: Period 480 × 720 のウィンドウに単独で描画modal-time-bounded
open: true mode: time value: 09:30 min: 09:15 max: 17:45 locale: en-US hourCycle: h23 minuteStep: 15 label: Select time confirmLabel: OK cancelLabel: Cancel hourLabel: Hour minuteLabel: Minute wheelsLabel: Wheels dialLabel: Dial entryModeLabel: Time input periodLabel: Period 480 × 720 のウィンドウに単独で描画modal-time-dial
open: true mode: time value: 07:30 locale: en-US hourCycle: h12 entryMode: dial label: Select time confirmLabel: OK cancelLabel: Cancel hourLabel: Hour minuteLabel: Minute wheelsLabel: Wheels dialLabel: Dial entryModeLabel: Time input periodLabel: Period 480 × 720 のウィンドウに単独で描画modal-time-dial-minute
open: true mode: time value: 19:45 locale: en-US hourCycle: h12 entryMode: dial unit: minute label: Select time confirmLabel: OK cancelLabel: Cancel hourLabel: Hour minuteLabel: Minute wheelsLabel: Wheels dialLabel: Dial entryModeLabel: Time input periodLabel: Period 480 × 720 のウィンドウに単独で描画modal-time-dial-minute-between
open: true mode: time value: 07:32 locale: en-US hourCycle: h12 entryMode: dial unit: minute label: Select time confirmLabel: OK cancelLabel: Cancel hourLabel: Hour minuteLabel: Minute wheelsLabel: Wheels dialLabel: Dial entryModeLabel: Time input periodLabel: Period 480 × 720 のウィンドウに単独で描画modal-time-dial-step
open: true mode: time value: 07:20 locale: en-US hourCycle: h12 minuteStep: 10 entryMode: dial unit: minute label: Select time confirmLabel: OK cancelLabel: Cancel hourLabel: Hour minuteLabel: Minute wheelsLabel: Wheels dialLabel: Dial entryModeLabel: Time input periodLabel: Period 480 × 720 のウィンドウに単独で描画modal-time-dial-24h
open: true mode: time value: 19:30 locale: en-US hourCycle: h23 entryMode: dial label: Select time confirmLabel: OK cancelLabel: Cancel hourLabel: Hour minuteLabel: Minute wheelsLabel: Wheels dialLabel: Dial entryModeLabel: Time input periodLabel: Period 480 × 720 のウィンドウに単独で描画modal-time-dial-bounded
open: true mode: time value: 09:30 min: 09:15 max: 17:45 locale: en-US hourCycle: h12 minuteStep: 15 entryMode: dial label: Select time confirmLabel: OK cancelLabel: Cancel hourLabel: Hour minuteLabel: Minute wheelsLabel: Wheels dialLabel: Dial entryModeLabel: Time input periodLabel: Period 480 × 720 のウィンドウに単独で描画modal-time-dial-ja
open: true mode: time value: 19:30 locale: ja-JP hourCycle: h12 entryMode: dial label: 時刻を選択 confirmLabel: OK cancelLabel: キャンセル hourLabel: 時 minuteLabel: 分 wheelsLabel: ホイール dialLabel: ダイヤル entryModeLabel: 時刻の入力方法 periodLabel: 午前/午後 480 × 720 のウィンドウに単独で描画modal-time-dial-rtl
open: true mode: time value: 19:30 locale: en-US hourCycle: h12 entryMode: dial label: Select time confirmLabel: OK cancelLabel: Cancel hourLabel: Hour minuteLabel: Minute wheelsLabel: Wheels dialLabel: Dial entryModeLabel: Time input periodLabel: Period direction: rtl 480 × 720 のウィンドウに単独で描画modal-time-range
open: true mode: time range: true start: 09:00 end: 17:30 locale: en-US hourCycle: h12 label: Select times startLabel: Start endLabel: End confirmLabel: OK cancelLabel: Cancel hourLabel: Hour minuteLabel: Minute wheelsLabel: Wheels dialLabel: Dial entryModeLabel: Time input periodLabel: Period rangeLabel: Range nextDayLabel: next day 480 × 720 のウィンドウに単独で描画modal-time-range-overnight
open: true mode: time range: true start: 22:00 end: 06:00 locale: en-US hourCycle: h23 label: Select times startLabel: Start endLabel: End confirmLabel: OK cancelLabel: Cancel hourLabel: Hour minuteLabel: Minute wheelsLabel: Wheels dialLabel: Dial entryModeLabel: Time input periodLabel: Period rangeLabel: Range nextDayLabel: next day 480 × 720 のウィンドウに単独で描画modal-time-range-dial
open: true mode: time range: true start: 09:00 end: 17:30 locale: en-US hourCycle: h12 entryMode: dial label: Select times startLabel: Start endLabel: End confirmLabel: OK cancelLabel: Cancel hourLabel: Hour minuteLabel: Minute wheelsLabel: Wheels dialLabel: Dial entryModeLabel: Time input periodLabel: Period rangeLabel: Range nextDayLabel: next day 480 × 720 のウィンドウに単独で描画modal-time-range-dial-horizontal
open: true mode: time range: true start: 09:00 end: 17:30 locale: en-US hourCycle: h12 entryMode: dial layout: horizontal label: Select times startLabel: Start endLabel: End confirmLabel: OK cancelLabel: Cancel hourLabel: Hour minuteLabel: Minute wheelsLabel: Wheels dialLabel: Dial entryModeLabel: Time input periodLabel: Period rangeLabel: Range nextDayLabel: next day 800 × 640 のウィンドウに単独で描画modal-time-range-rtl
open: true mode: time range: true start: 09:00 end: 17:30 locale: en-US hourCycle: h12 label: Select times startLabel: Start endLabel: End confirmLabel: OK cancelLabel: Cancel hourLabel: Hour minuteLabel: Minute wheelsLabel: Wheels dialLabel: Dial entryModeLabel: Time input periodLabel: Period rangeLabel: Range nextDayLabel: next day direction: rtl 480 × 720 のウィンドウに単独で描画modal-time-horizontal
open: true mode: time value: 07:30 locale: en-US hourCycle: h12 entryMode: dial layout: horizontal label: Select time confirmLabel: OK cancelLabel: Cancel hourLabel: Hour minuteLabel: Minute wheelsLabel: Wheels dialLabel: Dial entryModeLabel: Time input periodLabel: Period 800 × 640 のウィンドウに単独で描画modal-time-wheels-horizontal
open: true mode: time value: 07:30 locale: en-US hourCycle: h12 layout: horizontal label: Select time confirmLabel: OK cancelLabel: Cancel hourLabel: Hour minuteLabel: Minute wheelsLabel: Wheels dialLabel: Dial entryModeLabel: Time input periodLabel: Period 800 × 640 のウィンドウに単独で描画modal-date-time
open: true mode: date-time value: 2026-09-17T19:30 today: 2026-09-24 locale: en-US hourCycle: h12 layout: horizontal label: Select date and time dateLabel: Date confirmLabel: OK cancelLabel: Cancel previousMonthLabel: Previous month nextMonthLabel: Next month yearViewLabel: Choose a year todayLabel: Today hourLabel: Hour minuteLabel: Minute wheelsLabel: Wheels dialLabel: Dial entryModeLabel: Time input periodLabel: Period 800 × 640 のウィンドウに単独で描画modal-date-time-range
open: true mode: date-time range: true start: 2026-09-10T09:00 end: 2026-09-16T17:00 today: 2026-09-24 locale: en-US hourCycle: h12 layout: horizontal label: Select dates and times dateLabel: Date startLabel: Start endLabel: End confirmLabel: OK cancelLabel: Cancel previousMonthLabel: Previous month nextMonthLabel: Next month yearViewLabel: Choose a year todayLabel: Today hourLabel: Hour minuteLabel: Minute wheelsLabel: Wheels dialLabel: Dial entryModeLabel: Time input periodLabel: Period rangeLabel: Range rangeErrorText: End must be after start 800 × 640 のウィンドウに単独で描画docked-date
open: true presentation: docked mode: date value: 2026-09-17 today: 2026-09-24 locale: en-US label: Select date dateLabel: Date previousMonthLabel: Previous month nextMonthLabel: Next month yearViewLabel: Choose a year todayLabel: Today 480 × 720 のウィンドウに単独で描画docked-date-range
open: true presentation: docked mode: date range: true start: 2026-09-10 end: 2026-09-16 today: 2026-09-24 locale: en-US label: Select dates dateLabel: Date startLabel: Start endLabel: End previousMonthLabel: Previous month nextMonthLabel: Next month yearViewLabel: Choose a year todayLabel: Today 480 × 720 のウィンドウに単独で描画docked-time
open: true presentation: docked mode: time value: 07:30 locale: en-US hourCycle: h12 label: Select time confirmLabel: OK cancelLabel: Cancel hourLabel: Hour minuteLabel: Minute wheelsLabel: Wheels dialLabel: Dial entryModeLabel: Time input periodLabel: Period 480 × 720 のウィンドウに単独で描画docked-date-time
open: true presentation: docked mode: date-time value: 2026-09-17T19:30 today: 2026-09-24 locale: en-US hourCycle: h12 layout: horizontal label: Select date and time dateLabel: Date confirmLabel: OK cancelLabel: Cancel previousMonthLabel: Previous month nextMonthLabel: Next month yearViewLabel: Choose a year todayLabel: Today hourLabel: Hour minuteLabel: Minute wheelsLabel: Wheels dialLabel: Dial entryModeLabel: Time input periodLabel: Period 800 × 640 のウィンドウに単独で描画生成元 specs/date-time-picker.spec.json, tokens/comp/date-time-picker.tokens.json, design/tokens/
日付や時刻を選ぶときに、カレンダーや時計が見えると助けになる場面で使います。何曜日か、どれくらい先か、何時台か、といった場面です。テキストフィールドのピッカーボタンか、任意のボタンから開きます。テキストフィールドから開けば、値がわかっている人は入力もできます。日付を選ぶことがページの作業そのものなら、代わりにカレンダーをページに置きます。
| 選ぶもの | 設定 |
|---|---|
| 日付 | mode を date(既定)にします。手早く選ぶならフィールドの下の docked、日付に画面を使う価値があるなら modal です |
| 日付の期間 | mode を date にして range を付けます |
| 時刻 | mode を time にします |
| 営業時間、シフト、おやすみ時間 | mode を time にして range を付けます。終了が開始と同じかそれより前なら、翌日になります |
| 予定の日時 | mode を date-time にします |
| ある時点から別の時点までの予約 | mode を date-time にして range を付けます |
disabledDates、today、firstDayOfWeek、startView、showAdjacentDays はカレンダーに渡され、意味はカレンダーと同じです。min と max は、テキストフィールドのものと同じく、モードの形式で指定します。date モードでは日付、time モードでは 09:00 のような時刻、date-time モードでは 2026-09-17T09:00 のような日時です。カレンダーにはその日付が渡り、時刻の部分ではその間の時刻だけを選べます。date-time モードでは、境界が時刻を制限するのはその境界の日だけで、日付だけの境界は日付だけを制限します。
ピッカーは制御コンポーネントです。テキストフィールドの pickerRequest やボタンのハンドラーから open を設定して開き、ピッカーは理由を付けて close を発火します。Web、Compose、React Native では、open を false に戻すのはプロダクト側です。SwiftUI と Flutter では、バインディングやルートが閉じます。
- モーダル、または時刻を含むもの。 ピッカーは選択を保留して持ち、OK で確定します。選択が変わっていれば
changeを発火し、続けてconfirmのcloseを発火します。選択がそろうまで OK は無効です。キャンセル、Escape、戻る操作、スクリムを押すと、何も確定せずに閉じます。開いているあいだにプロダクト側から値を設定しても、保留中の選択は動きません。 - ドック型で日付だけのもの。 選択がそろう日を選んだ時点で確定し、ピッカーを閉じます(
select)。アクションはありません。期間の開始日を選んだだけでは閉じません。 - 書き戻し。 ピッカーはフィールドに何も書き込みません。
changeからフィールドのvalueを設定します。閉じると、フォーカスは開く前の場所、多くはフィールドのピッカーボタンに戻ります。
間にプロダクトが入るのは、2 つのフィールドから作る期間、分の刻み、日の述語のように、フィールドの知らないことからピッカーを設定することが多いからです。
Web のドック型のピッカーは、下に置く要素の id を anchor で受け取り、別の要素が開く場合は opener も受け取ります。テキストフィールドをアンカーにすると、そのピッカーボタンを、ダイアログを開くコントロールとして伝えます。
上から順に、ヘッダー、本体、アクションです。
| 部分 | 説明 |
|---|---|
| ヘッダー | 先頭揃えのタイトル行です。何を選ぶのかを表す label(「チェックイン」など)と、時刻を設定するピッカーでは末尾に入力方式のタブを置きます。label に当たる言葉をピッカー自身は持ちません。なければ、この行は言葉を描きません。日付を含むモーダルのピッカーでは、その下に保留中の値(「9月17日(木)」「9月10日 – 9月16日」。まだ選んでいない日付は dateLabel)も表示し、ヘッダーの下に細い線を引きます。 |
| カレンダー | date と date-time で表示します。ピッカーはプロパティをカレンダーに渡すだけで、見た目は変えません。 |
| 時刻の部分 | time と date-time で表示します。上から、range のときは部分の幅いっぱいの期間の表示、文字盤モードでの時刻の表示、ホイールまたは文字盤です。午前・午後は、時と分の行に並びます。 |
| アクション | キャンセルと OK です。ダイアログと同じく、役割に応じて置かれる全幅の Tonal ボタンの行です。 |
layout が vertical ならカレンダーの下に時刻の部分を重ね、horizontal なら横に並べます。文字盤モードの時刻だけのピッカーでは、horizontal は時刻の表示を文字盤の横に置きます。既定の auto は、縦には短すぎて横には十分広いウィンドウでだけ横並びにします。パーツが収まらないときは、ヘッダーとアクションはその場に残り、本体がその間でスクロールします。
- ホイールか文字盤か。 既定はホイールで、タブでも先に並びます。文字盤は時計の文字盤で、時と分のセレクターからなる時刻の表示が、その隣の行に来ます。
entryModeで開いたときの方式を選び、利用者は入力方式のタブで切り替えられます。タブはタイトル行の末尾にあるアイコンだけの 2 つで、ホイールはキーボードのグリフ、文字盤は時計のグリフです。言葉(wheelsLabel、dialLabel)はアクセシブルネームになります。1 つの方式だけを提供するプロダクトはcomp.date-time-picker.time.entry-modesを設定し、そのときタブは描かれません。 - 数字を打ち込む。 ホイールの選択中の値を押すか、ホイールにフォーカスがあるときに数字を打つと、打ち込みが始まります。タッチ端末では数字のキーボードが出ます。2 桁打つか、次の桁が続かない 1 桁を打つと打ち込みは終わり、時が決まると分に進みます。そのため
730で 7:30 になります。文字盤モードのセレクターも、キーボードの数字を同じように読みます。日付全体は、これまでどおりテキストフィールドで入力します。 - 時計の方式。
hourCycleは既定でロケールに従い、h12かh23も指定できます。値はどの方式でも 24 時間制です。 - 午前・午後。 12 時間制では、午前・午後は時刻の一部であり、時刻の上に置く切り替えではありません。ホイールモードでは短い 3 つ目のホイール、文字盤モードでは押すともう一方に変わる幅の狭いセレクターです。分のあとに置かれ、日本語のように午前・午後を先に書くロケールでは時の前に置かれます。変えても時の数字はそのままで、午前か午後かが変わります。控えめに描かれ、設定中の単位を示す印が付くことはありません。
- 分の刻み。
minuteStep(1、5、10、15、30)で、分のホイールの行と文字盤の数字が決まります。刻みに合わない時刻は、設定した値でも打ち込んだ値でも、刻みに切り捨てます。 - 範囲。
minとmaxの外の時刻も、ホイールと文字盤の同じ位置に残り、薄く描かれます(comp.date-time-picker.time.unavailable-opacity)。その時刻は選べません。ホイールは選べるいちばん近い時刻に止まり、矢印キーは次の選べる値へ飛び、文字盤では選べるいちばん近い数字になり、範囲の外の数字を打ち込んでも採用されません。選べる最初の時刻はminをminuteStepに切り上げたもの、最後の時刻はmaxを切り捨てたものです。保留中の時刻が範囲の外にあるとき、また時や午前・午後を変えると範囲の外に出るときは、近いほうの境界の時刻になります。 - 時刻が空のとき は、現在の時刻から始まります。
日付の期間は、カレンダーで開始日、終了日の順に選びます。
時刻を含む期間は、両端をダッシュでつないだ 2 つの期間フィールドで表示します(「9:00 – 17:30」)。開始や終了という言葉は描かず、並び順とダッシュがそれを伝えます。設定中のフィールドには選択の印が付き、下のホイールや文字盤がその時刻を表示して設定します。もう一方のフィールドを押すと、そちらの端を設定するようになります。フォーカスだけでは切り替わらないので、Tab でフィールドを通り過ぎても、設定中の端は変わりません。日時の期間では、カレンダーで開始日を選ぶと開始のフィールドが、終了日を選ぶと終了のフィールドが選ばれます。
- 時刻の期間で終了が開始と同じかそれより前なら、終了は翌日になり、終了のフィールドにそう表示します(
nextDayLabel)。 - 日時の期間で終了が開始より前なら、
rangeErrorTextを表示し、OK は無効のままです。
Tanrei は言葉を同梱しません。ピッカーが表示したり読み上げたりする言葉は、すべてプロダクトのものです。label は、そのピッカーが何を選ぶのかを表し、ピッカーごとに書きます。ほかの言葉は、ピッカーがどこに描かれても同じなので、このページがしているように、プロダクト全体に、言語ごとに一度だけ渡します。
import { setWords } from '@tanrei/web';
setWords(
{
confirmLabel: 'OK',
cancelLabel: 'キャンセル',
dateLabel: '日付',
startLabel: '開始',
endLabel: '終了',
rangeLabel: '期間',
nextDayLabel: '翌日',
rangeErrorText: '終了は開始より後にしてください。',
hourLabel: '時',
minuteLabel: '分',
periodLabel: '午前・午後',
wheelsLabel: 'ホイール',
dialLabel: '文字盤',
entryModeLabel: '時刻の入力方式',
previousMonthLabel: '前の月',
nextMonthLabel: '次の月',
yearViewLabel: '年を選ぶ',
todayLabel: '今日',
},
{ lang: 'ja' },
);この呼び出しは、このページが実際に実行しているものです。上のサンプルには label だけを書いていて、これらの言葉は書いていません。ほかと違う言葉を使うピッカーは、自分の属性で渡します(confirm-label="予約")。属性は常に優先されます。どれも渡さなくても、ピッカーは動作します。キャンセルと OK は、閉じるグリフとチェックのグリフだけのボタンになり、翌日にまたがる終了は +1 と表示され、まだ選ばれていない日付は何も描かれません。デバッグビルドは、足りない言葉をそれぞれ報告します。時・分・午前午後の名前と今日を表す言葉は、渡さなければブラウザーのロケールデータから取ります。
- テキストフィールドのピッカーボタンから開き、値を入力することもできるようにします。
labelには何を選ぶのか(「チェックイン」「会議の開始」など)をプロダクトの言語で書き、ピッカーが表示するほかの言葉も設定します。- 予約で 15 分ごとにしか選べないときのように、意味のある分が限られるなら
minuteStepを使います。 - ピッカーには、対応するフィールドと同じ
min、max、disabledDatesを渡し、両方が同じ日付と時刻を受け付けるようにします。フィールドのpickerRequestには、そのminとmaxが含まれています。
- 生年月日のように利用者がすでに知っている日付を、DateTimePicker だけで入力させない。文字でも入力できるようにします。
- 入力方式やアクションの見た目を、ピッカーごとに変えない。レイヤで決めるプロダクトの設定です。
changeより前にフィールドへ値を書き込まない。ピッカーが確定するのは、OK を押したとき、またはドック型の日付ピッカーで日を選んだときだけです。- Web、Compose、React Native では、
closeのあとにopenを true のままにしない。これらのプラットフォームでは、ピッカーが自分で閉じることはありません。 - Web の
inline属性をプロダクトで使わない。オーバーレイとしての振る舞いなしにサーフェスを描くだけです。
- ロール
dialog- ラベル付け
- The surface is a dialog named by label. The calendar, the tabs and the Buttons label themselves from the words the picker gives them: the calendar's days by their full dates, the entry-mode tabs by wheelsLabel and dialLabel, which are their names though they draw glyphs alone, in a row named entryModeLabel. The range display is a group named rangeLabel whose two range fields are buttons named startLabel and endLabel with their times, each exposing whether it is the one being set; no word for start or end is drawn, so these names are what tells assistive technology which is which. The hour and minute wheels and selectors are spin buttons named by hourLabel and minuteLabel, whose values are read as drawn (the hour with its period in a 12-hour clock), and they stay spin buttons while a number is typed into them. The period is a third spin button beside them, named periodLabel, whose value is the locale's name for before or after noon. The dial is a pointer surface hidden from assistive technology: everything it does, the selectors do too.
- 最小ターゲット
- 見た目のサイズが小さくても、ヒット領域は最小ターゲットサイズを満たします。 minimum 32px · pointer 44px · spacing 8px · touch 48px
キーボード操作
| キー | 動作 |
|---|---|
| Tab / Shift+Tab | Modal: moves through the entry-mode tabs, the calendar (its view toggle, its navigation buttons and its active day), the two range fields, the hour, the minute and the period (the period first where the locale writes it first), and Cancel and OK, in reading order, wrapping; focus never leaves. Docked: the same without wrapping; leaving the picker closes it (reason tab). |
| Arrow keys in the calendar | As the calendar: by day or week, changing the month as needed (CAL-11). |
| Left / Right Arrow on the entry-mode tabs | Select the other tab: the other entry mode. |
| Enter / Space on a range field | Makes the wheels or the dial set that end of the range. Focus alone does not. |
| Up / Down Arrow on a wheel / a selector | The next or previous available value, wrapping without changing the other unit or the period; a time outside min and max is passed over. |
| Up / Down Arrow, Enter / Space on the period | The other period (AM or PM), keeping the hour's number. Home is before noon, End after noon; on the dial mode's period selector Left and Right Arrow do the same as Up and Down. |
| Digits on a wheel / a selector | Type the hour or the minute; a finished hour moves on to the minute, and the hour-and-minute separator does too. Backspace removes the last digit. |
| Page Up / Page Down on the minute wheel / selector | Five minutes later or earlier, while minuteStep is 1. |
| Home / End on a wheel / a selector | The first or last available value of its unit. |
| Enter / Space | Choose the active day; activate the focused button or tab; change the period on the period; end a typed entry, keeping it. |
| Escape | During a typed entry, ends it and keeps the value before it. Otherwise closes the picker without committing (reason escape) and returns focus to where it was. |
備考
- The selectors, the period selector and the range fields are at least the minimum target in both dimensions and a wheel's rows at least the target's height (DTM-32); the dial is larger than the target. The calendar's cells, the tabs and the Buttons meet the target themselves (CAL-1, TAB-5, BTN-5).
- Focus: a modal picker is a modal overlay — it keeps focus in and draws a scrim. A docked picker is an operated overlay that is not modal: it takes focus and returns it to its anchor, but Tab leaves it and closes it.
- Typing a whole date or time is still the Text field's job (a trailing icon-only Button opens this picker), with its own reading rules for a date in the locale's order. Here a wheel takes only its own number: a press on its chosen value, or a digit on a keyboard, types the hour or the minute (DTM-43 to DTM-45), so a person who types reaches a time in three or four keys, and a person who does not still reaches every value by the arrow keys, by dragging and by assistive technology's increment and decrement.
- The two ends of a range are not tabs: tabs say one of several views, and the two ends are two values that are both always shown. They are two buttons in a named group, each read with its name, its time and whether it is the one being set ("Start, 9:00 AM, selected"). The dash between them is decoration and is hidden; the names carry what the dash and the order show.
- The entry-mode tabs draw glyphs alone. Their accessible names are wheelsLabel and dialLabel, so a screen reader reads "Wheels, tab, 1 of 2"; both words are the product's.
- Escape ends a typed entry before it closes the picker, as it ends any edit inside a dialog first: one press never both discards a number and dismisses the surface.
- The period is not tabs: tabs say that what is below them is one of several views, and AM or PM is a part of one value. It is exposed as the third field of a time, as the AM/PM field of a native time input is: a spin button of two values named periodLabel ("Period, PM"), which Up and Down Arrow, a press, and assistive technology's increment and decrement change. The hour's own value repeats the period ("7 PM"), so a person who never reaches the period control still hears which half of the day is set.
- The dial mode's period selector shows the pending period alone and changes to the other when pressed. It is one target the height of the selectors: two names stacked in that height would be two targets shorter than the minimum, each over the other's edge (DTM-32). In the wheels mode both names are in view, as every value of a wheel's neighbourhood is.
- The picker has no words of its own. Month, weekday and period names, digits and date and time forms are the platform's locale data, in the locale the picker was given. Every other word it shows or announces is the product's: a prop of this instance, or the product's words set once. Its name, label, is this instance's alone.
- The web exposes each wheel and selector with role spinbutton, aria-valuenow, aria-valuemin, aria-valuemax and aria-valuetext, a wheel on an input whose inputmode is numeric so that a touch keyboard is the number pad, and each range field as a button with aria-pressed in a role group; SwiftUI with the adjustable trait (accessibilityAdjustableAction) and a number-pad text field for an entry; Compose with progressBarRangeInfo and setProgress semantics and KeyboardType.Number; Flutter with Semantics increasedValue, decreasedValue, onIncrease and onDecrease and TextInputType.number; React Native with the adjustable role, the increment and decrement actions and a number-pad TextInput.
- Text size: at 200% the wheels, the selectors and the dial's numbers grow; a modal picker scrolls between its header and its actions when the window is short (DTM-36), and the horizontal layout keeps a phone held sideways usable.
- How a state looks is a value decision of the active design system; components read the state's tokens and never compute the effect themselves.
- A time outside min and max keeps its place on the wheels and the dial, drawn faded, and is passed over: a wheel settles on the nearest available row, the arrow keys go on to the next available value, and the dial takes the available value nearest the pointer, as the out-of-range values of a native time picker are dimmed and not chosen. Assistive technology never hears one as a spin button's value: each spin button's minimum and maximum are its first and last available values. Leaving them out instead would move every value after them, so that the place a person knows a time by (12 at the top of the dial, the next hour below this one) would change with the bounds.
生成元 specs/date-time-picker.spec.json, tokens/sys/measure.tokens.json
- サーフェスは
labelを名前とするダイアログです。モーダルのピッカーはフォーカスを内側に保ち、スクリムを描きます。ドック型のピッカーはフォーカスを受け取り、閉じるとアンカーに返しますが、Tab で外に出ると閉じます。開くと、フォーカスはカレンダーのアクティブな日か、時に移ります。 - カレンダー、タブ、ボタンは、ピッカーが渡す言葉で自分の名前を付けます。入力方式のタブは本物のタブリストで、グリフだけを描いていても、名前と位置が読み上げられます(「ホイール、タブ、1 / 2」)。
- 期間の両端は、
rangeLabelを名前とするグループの中の 2 つのボタンです。それぞれ、名前、時刻、設定中かどうかが読み上げられます(「開始、9:00」)。startLabelとendLabelは描かれることがなく、どちらの端かを支援技術に伝えるためのものです。ダッシュは隠されます。 - 時と分のホイールやセレクターはスピンボタンで、矢印キー、Page Up・Page Down、Home・End で操作でき、表示どおりに読み上げます(12 時間制では時に午前・午後が付きます)。数字を打ち込んでいるあいだもスピンボタンのままです。午前・午後は、値が 2 つの 3 つ目のスピンボタンで、名前は
periodLabelです。午前・午後の名前の頭文字(英語なら A か P)を打つと、その側になります。minとmaxの外の時刻がスピンボタンの値になることはなく、各スピンボタンの最小値と最大値は、選べる最初と最後の値です。文字盤は支援技術からは隠れていますが、文字盤でできることはすべてセレクターでもできます。 - Escape は、打ち込みの途中ならまずそれを終わらせ、打ち込む前の値に戻します。そうでなければ、何も確定せずにピッカーを閉じ、フォーカスを元の場所に戻します。
- 日時の期間で終了が開始より前になると、一度だけ控えめに読み上げ、終了の期間フィールドの説明として伝えます。
- セレクター、期間フィールド、ホイールの行はどれも最小ターゲット以上で、ホイール、セレクター、午前・午後、文字盤の数字は、文字を大きくすると切れずに大きくなります。狭いウィンドウでも、ピッカーがウィンドウより広くなることはありません。カレンダーのマスと期間フィールドが狭まります。
- 右から左のレイアウトでは、タイトル行、列、期間の表示、午前・午後を置く側、アクションが反転します。時、区切り、分の並び順は変わらず、文字盤は時計回りのままです。
プラットフォームごとの既知の制約:
- SwiftUI、Compose、Flutter、React Native は、まだ DateTimePicker を作っていません。各プラットフォームは、追従するときにこの仕様から作ります。
- Web:終了の期間フィールドはボタンで、ボタンには無効な値の状態がありません。そのため、期間のエラーが支援技術に伝わるのは、説明と読み上げによってだけです。
- Web:ブラウザーは、端末全体の 12 時間制・24 時間制の設定を知らせません。そのため、
hourCycleがlocaleのときはロケールだけに従います。 - Web:ドック型のピッカーの外を押すと、ピッカーが閉じ、その押下は下にある要素にも届きます。メニューと同じです。
- Web:ドック型のピッカーはスクリプトで配置しており、まだ CSS のアンカーポジショニングは使っていません。
- Web:ホイール、文字盤、カレンダーのドラッグは、指での操作をまだ実機で確認していません。また、Firefox と WebKit で失敗するテストがあります。
- ホイールは、文字盤の直径ともセレクターの幅とも合っていません。合わせるかどうかは未決定です。
- すべてのピッカーに、何を選ぶのかを表す
labelを与えます(「チェックイン」「会議の時刻」)。これはそのピッカーだけのものです。なければ、タイトルの行は言葉を描かず、ダイアログは名前を持ちません。 - ピッカーが表示したり読み上げたりするほかの言葉もすべて渡します。ピッカーに書くか、このページがしているように、
setWords()でプロダクト全体に一度だけ渡します。Tanrei は言葉を同梱しません。アクション(confirmLabel、cancelLabel)、dateLabel、nextDayLabel、rangeErrorText、カレンダーの 6 つの言葉のほか、読み上げだけに使う名前(wheelsLabel、dialLabel、entryModeLabel、rangeLabel、startLabel、endLabel)があります。これらがなければ、同じことを表せる印があるところではそれを代わりに描きます。閉じるアイコンとチェックのアイコンだけのボタン、翌日にまたがる終了のあとの+1です。足りない言葉は、それぞれ開発時に報告されます。時・分・午前午後の名前と今日を表す言葉は、渡されなければブラウザーのロケールデータから取ります。プロダクトの言葉を参照してください。 - テキストフィールドの、
pickerLabel(「日付を選択」など)を名前とするピッカーボタンのように、何を開くかがわかるコントロールから開きます。 changeからフィールドのvalueを設定し、openが単なる値のプラットフォームでは、closeを受けてピッカーを閉じます。- テキストフィールドでの入力もできるようにします。