Skip to content
Lenso UI

DateField 日期字段

基于 React Aria DateField 的日期输入字段,包含标签、说明与校验

用法

import { DateField } from '@lenso/ui';

此预览复用英文版适配,不代表中文源示例已完成本地实现。

"use client";
// HeroUI v3.2.6. Copyright NextUI Inc. SPDX-License-Identifier: Apache-2.0.import { DateField } from "@lenso/ui";import { styles } from "./demo-styles";
export function Basic() {  return (    <DateField xstyle={styles.field} name="date">      <DateField.Label>Date</DateField.Label>      <DateField.Group>        <DateField.Input>{(segment) => <DateField.Segment segment={segment} />}</DateField.Input>      </DateField.Group>    </DateField>  );}

Local adaptation source above. Derived from HeroUI v3.2.6 source.

组件结构

import {DateField, Label, Description, FieldError} from '@lenso/ui';
export default () => (  <DateField>    <Label />    <DateField.Group>      <DateField.Input>        {(segment) => <DateField.Segment segment={segment} />}      </DateField.Input>    </DateField.Group>    <Description />    <FieldError />  </DateField>)

DateField 将标签、日期输入、说明与错误信息组合为单个无障碍组件。

示例

带图标

通过前缀或后缀图标增强日期输入。

此预览复用英文版适配,不代表中文源示例已完成本地实现。

"use client";// HeroUI v3.2.6. Copyright NextUI Inc. SPDX-License-Identifier: Apache-2.0.import { Calendar } from "@gravity-ui/icons";import { DateField } from "@lenso/ui";import * as stylex from "@stylexjs/stylex";import { styles } from "./demo-styles";
export function WithPrefixIcon() {  return (    <DateField xstyle={styles.field} name="date">      <DateField.Label>Date</DateField.Label>      <DateField.Group>        <DateField.Prefix>          <Calendar {...stylex.props(styles.icon)} aria-hidden="true" />        </DateField.Prefix>        <DateField.Input>{(segment) => <DateField.Segment segment={segment} />}</DateField.Input>      </DateField.Group>    </DateField>  );}

Local adaptation source above. Derived from HeroUI v3.2.6 source.

此预览复用英文版适配,不代表中文源示例已完成本地实现。

"use client";// HeroUI v3.2.6. Copyright NextUI Inc. SPDX-License-Identifier: Apache-2.0.import { Calendar } from "@gravity-ui/icons";import { DateField } from "@lenso/ui";import * as stylex from "@stylexjs/stylex";import { styles } from "./demo-styles";
export function WithSuffixIcon() {  return (    <DateField xstyle={styles.field} name="date">      <DateField.Label>Date</DateField.Label>      <DateField.Group>        <DateField.Input>{(segment) => <DateField.Segment segment={segment} />}</DateField.Input>        <DateField.Suffix>          <Calendar {...stylex.props(styles.icon)} aria-hidden="true" />        </DateField.Suffix>      </DateField.Group>    </DateField>  );}

Local adaptation source above. Derived from HeroUI v3.2.6 source.

此预览复用英文版适配,不代表中文源示例已完成本地实现。

"use client";// HeroUI v3.2.6. Copyright NextUI Inc. SPDX-License-Identifier: Apache-2.0.import { Calendar, ChevronDown } from "@gravity-ui/icons";import { DateField } from "@lenso/ui";import * as stylex from "@stylexjs/stylex";import { styles } from "./demo-styles";
export function WithPrefixAndSuffix() {  return (    <DateField xstyle={styles.field} name="date">      <DateField.Label>Date</DateField.Label>      <DateField.Group>        <DateField.Prefix>          <Calendar {...stylex.props(styles.icon)} aria-hidden="true" />        </DateField.Prefix>        <DateField.Input>{(segment) => <DateField.Segment segment={segment} />}</DateField.Input>        <DateField.Suffix>          <ChevronDown {...stylex.props(styles.icon)} aria-hidden="true" />        </DateField.Suffix>      </DateField.Group>      <DateField.Description>Enter a date</DateField.Description>    </DateField>  );}

Local adaptation source above. Derived from HeroUI v3.2.6 source.

变体

DateField.Group 组件支持两种视觉变体:

  • primary(默认)- 标准样式带阴影,适用于大多数场景
  • secondary - 低强调变体无阴影,适用于 Surface 组件内

此预览复用英文版适配,不代表中文源示例已完成本地实现。

"use client";// HeroUI v3.2.6. Copyright NextUI Inc. SPDX-License-Identifier: Apache-2.0.import { DateField } from "@lenso/ui";import * as stylex from "@stylexjs/stylex";import { styles } from "./demo-styles";
export function Variants() {  return (    <div {...stylex.props(styles.column)}>      <DateField xstyle={styles.field} name="primary-date">        <DateField.Label>Primary variant</DateField.Label>        <DateField.Group variant="primary">          <DateField.Input>{(segment) => <DateField.Segment segment={segment} />}</DateField.Input>        </DateField.Group>      </DateField>      <DateField xstyle={styles.field} name="secondary-date">        <DateField.Label>Secondary variant</DateField.Label>        <DateField.Group variant="secondary">          <DateField.Input>{(segment) => <DateField.Segment segment={segment} />}</DateField.Input>        </DateField.Group>      </DateField>    </div>  );}

Local adaptation source above. Derived from HeroUI v3.2.6 source.

表面样式

在 Surface 内使用时,请在 DateField.Group 上使用 variant="secondary" 以应用适合 Surface 背景的低强调变体。

此预览复用英文版适配,不代表中文源示例已完成本地实现。

"use client";// HeroUI v3.2.6. Copyright NextUI Inc. SPDX-License-Identifier: Apache-2.0.import { Calendar } from "@gravity-ui/icons";import { DateField, Surface } from "@lenso/ui";import * as stylex from "@stylexjs/stylex";import { styles } from "./demo-styles";
export function OnSurface() {  return (    <Surface xstyle={styles.surface}>      <DateField xstyle={styles.full} name="date">        <DateField.Label>Date</DateField.Label>        <DateField.Group variant="secondary">          <DateField.Input>{(segment) => <DateField.Segment segment={segment} />}</DateField.Input>        </DateField.Group>        <DateField.Description>Enter a date</DateField.Description>      </DateField>      <DateField xstyle={styles.full} name="date-2">        <DateField.Label>Appointment date</DateField.Label>        <DateField.Group variant="secondary">          <DateField.Prefix>            <Calendar {...stylex.props(styles.icon)} aria-hidden="true" />          </DateField.Prefix>          <DateField.Input>{(segment) => <DateField.Segment segment={segment} />}</DateField.Input>        </DateField.Group>        <DateField.Description>Enter a date for your appointment</DateField.Description>      </DateField>    </Surface>  );}

Local adaptation source above. Derived from HeroUI v3.2.6 source.

带描述

此预览复用英文版适配,不代表中文源示例已完成本地实现。

"use client";// HeroUI v3.2.6. Copyright NextUI Inc. SPDX-License-Identifier: Apache-2.0.import { DateField } from "@lenso/ui";import * as stylex from "@stylexjs/stylex";import { styles } from "./demo-styles";
export function WithDescription() {  return (    <div {...stylex.props(styles.column)}>      <DateField xstyle={styles.field} name="date">        <DateField.Label>Birth date</DateField.Label>        <DateField.Group>          <DateField.Input>{(segment) => <DateField.Segment segment={segment} />}</DateField.Input>        </DateField.Group>        <DateField.Description>Enter your date of birth</DateField.Description>      </DateField>      <DateField xstyle={styles.field} name="appointment-date">        <DateField.Label>Appointment date</DateField.Label>        <DateField.Group>          <DateField.Input>{(segment) => <DateField.Segment segment={segment} />}</DateField.Input>        </DateField.Group>        <DateField.Description>Enter a date for your appointment</DateField.Description>      </DateField>    </div>  );}

Local adaptation source above. Derived from HeroUI v3.2.6 source.

必填字段

此预览复用英文版适配,不代表中文源示例已完成本地实现。

"use client";// HeroUI v3.2.6. Copyright NextUI Inc. SPDX-License-Identifier: Apache-2.0.import { DateField } from "@lenso/ui";import * as stylex from "@stylexjs/stylex";import { styles } from "./demo-styles";
export function Required() {  return (    <div {...stylex.props(styles.column)}>      <DateField isRequired xstyle={styles.field} name="date">        <DateField.Label>Date</DateField.Label>        <DateField.Group>          <DateField.Input>{(segment) => <DateField.Segment segment={segment} />}</DateField.Input>        </DateField.Group>      </DateField>      <DateField isRequired xstyle={styles.field} name="start-date">        <DateField.Label>Start date</DateField.Label>        <DateField.Group>          <DateField.Input>{(segment) => <DateField.Segment segment={segment} />}</DateField.Input>        </DateField.Group>        <DateField.Description>Required field</DateField.Description>      </DateField>    </div>  );}

Local adaptation source above. Derived from HeroUI v3.2.6 source.

禁用

此预览复用英文版适配,不代表中文源示例已完成本地实现。

"use client";// HeroUI v3.2.6. Copyright NextUI Inc. SPDX-License-Identifier: Apache-2.0.import { DateField } from "@lenso/ui";import { getLocalTimeZone, today } from "@internationalized/date";import * as stylex from "@stylexjs/stylex";import { styles } from "./demo-styles";
export function Disabled() {  return (    <div {...stylex.props(styles.column)}>      <DateField isDisabled xstyle={styles.field} name="date" value={today(getLocalTimeZone())}>        <DateField.Label>Date</DateField.Label>        <DateField.Group>          <DateField.Input>{(segment) => <DateField.Segment segment={segment} />}</DateField.Input>        </DateField.Group>        <DateField.Description>This date field is disabled</DateField.Description>      </DateField>      <DateField isDisabled xstyle={styles.field} name="date-empty">        <DateField.Label>Date</DateField.Label>        <DateField.Group>          <DateField.Input>{(segment) => <DateField.Segment segment={segment} />}</DateField.Input>        </DateField.Group>        <DateField.Description>This date field is disabled</DateField.Description>      </DateField>    </div>  );}

Local adaptation source above. Derived from HeroUI v3.2.6 source.

宽度充满

此预览复用英文版适配,不代表中文源示例已完成本地实现。

"use client";// HeroUI v3.2.6. Copyright NextUI Inc. SPDX-License-Identifier: Apache-2.0.import { Calendar, ChevronDown } from "@gravity-ui/icons";import { DateField } from "@lenso/ui";import * as stylex from "@stylexjs/stylex";import { styles } from "./demo-styles";
export function FullWidth() {  return (    <div {...stylex.props(styles.wide)}>      <DateField fullWidth name="date">        <DateField.Label>Date</DateField.Label>        <DateField.Group>          <DateField.Input>{(segment) => <DateField.Segment segment={segment} />}</DateField.Input>        </DateField.Group>      </DateField>      <DateField fullWidth name="date-icons">        <DateField.Label>Date</DateField.Label>        <DateField.Group>          <DateField.Prefix>            <Calendar {...stylex.props(styles.icon)} aria-hidden="true" />          </DateField.Prefix>          <DateField.Input>{(segment) => <DateField.Segment segment={segment} />}</DateField.Input>          <DateField.Suffix>            <ChevronDown {...stylex.props(styles.icon)} aria-hidden="true" />          </DateField.Suffix>        </DateField.Group>      </DateField>    </div>  );}

Local adaptation source above. Derived from HeroUI v3.2.6 source.

表单校验

配合 FieldError 使用 isInvalid 展示校验消息。

此预览复用英文版适配,不代表中文源示例已完成本地实现。

"use client";// HeroUI v3.2.6. Copyright NextUI Inc. SPDX-License-Identifier: Apache-2.0.import { DateField } from "@lenso/ui";import * as stylex from "@stylexjs/stylex";import { styles } from "./demo-styles";
export function Invalid() {  return (    <div {...stylex.props(styles.column)}>      <DateField isInvalid isRequired xstyle={styles.field} name="date">        <DateField.Label>Date</DateField.Label>        <DateField.Group>          <DateField.Input>{(segment) => <DateField.Segment segment={segment} />}</DateField.Input>        </DateField.Group>        <DateField.Error>Please enter a valid date</DateField.Error>      </DateField>      <DateField isInvalid xstyle={styles.field} name="invalid-date">        <DateField.Label>Date</DateField.Label>        <DateField.Group>          <DateField.Input>{(segment) => <DateField.Segment segment={segment} />}</DateField.Input>        </DateField.Group>        <DateField.Error>Date must be in the future</DateField.Error>      </DateField>    </div>  );}

Local adaptation source above. Derived from HeroUI v3.2.6 source.

时间粒度

此预览复用英文版适配,不代表中文源示例已完成本地实现。

"use client";// HeroUI v3.2.6. Copyright NextUI Inc. SPDX-License-Identifier: Apache-2.0.import type { DateValue } from "@internationalized/date";import { CircleQuestion } from "@gravity-ui/icons";import { DateField, Select, Tooltip } from "@lenso/ui";import { parseDate, parseZonedDateTime } from "@internationalized/date";import { useState, useId } from "react";import * as stylex from "@stylexjs/stylex";import { styles } from "./demo-styles";
export function Granularity() {  const granularityOptions = [    { id: "day", label: "Day" },    { id: "hour", label: "Hour" },    { id: "minute", label: "Minute" },    { id: "second", label: "Second" },  ] as const;  const [granularity, setGranularity] = useState<"day" | "hour" | "minute" | "second">("day");  const labelId = useId();  const defaultValue: DateValue =    granularity === "day"      ? parseDate("2025-02-03")      : parseZonedDateTime("2025-02-03T08:45:00[America/Los_Angeles]");  return (    <div {...stylex.props(styles.granularity)}>      <DateField        key={granularity}        xstyle={styles.field}        defaultValue={defaultValue}        granularity={granularity}        name="granularity-date"      >        <DateField.Label>Appointment Date</DateField.Label>        <DateField.Group>          <DateField.Input>{(segment) => <DateField.Segment segment={segment} />}</DateField.Input>        </DateField.Group>      </DateField>      <div {...stylex.props(styles.selector)}>        <div {...stylex.props(styles.selectorLabel)}>          <span id={labelId}>Granularity</span>          <Tooltip>            <Tooltip.Trigger delay={0} aria-label="Granularity information">              <CircleQuestion {...stylex.props(styles.icon)} aria-hidden="true" />            </Tooltip.Trigger>            <Tooltip.Portal>              <Tooltip.Positioner side="bottom" align="start">                <Tooltip.Popup>                  <p>                    Determines the smallest unit displayed in the date picker. By default, this is                    "day" for dates, and "minute" for times.                  </p>                </Tooltip.Popup>              </Tooltip.Positioner>            </Tooltip.Portal>          </Tooltip>        </div>        <Select          value={granularity}          variant="secondary"          onValueChange={(value) => {            if (value) setGranularity(value);          }}        >          <Select.Trigger xstyle={styles.select} aria-labelledby={labelId}>            <Select.Value>              {(value) =>                granularityOptions.find((option) => option.id === value)?.label ??                "Select granularity"              }            </Select.Value>            <Select.Indicator />          </Select.Trigger>          <Select.Portal>            <Select.Positioner>              <Select.Popover>                <Select.List>                  {granularityOptions.map((option) => (                    <Select.Item key={option.id} value={option.id}>                      <Select.ItemText>{option.label}</Select.ItemText>                      <Select.ItemIndicator />                    </Select.Item>                  ))}                </Select.List>              </Select.Popover>            </Select.Positioner>          </Select.Portal>        </Select>      </div>    </div>  );}

Local adaptation source above. Derived from HeroUI v3.2.6 source.

受控组件

控制 value 以与其他组件或状态管理同步。

此预览复用英文版适配,不代表中文源示例已完成本地实现。

"use client";// HeroUI v3.2.6. Copyright NextUI Inc. SPDX-License-Identifier: Apache-2.0.import type { DateValue } from "@internationalized/date";import { Button, DateField } from "@lenso/ui";import { getLocalTimeZone, today } from "@internationalized/date";import { useState } from "react";import * as stylex from "@stylexjs/stylex";import { styles } from "./demo-styles";
export function Controlled() {  const [value, setValue] = useState<DateValue | null>(null);  return (    <div {...stylex.props(styles.column)}>      <DateField xstyle={styles.field} name="date" value={value} onChange={setValue}>        <DateField.Label>Date</DateField.Label>        <DateField.Group>          <DateField.Input>{(segment) => <DateField.Segment segment={segment} />}</DateField.Input>        </DateField.Group>        <DateField.Description>          Current value: {value ? value.toString() : "(empty)"}        </DateField.Description>      </DateField>      <div {...stylex.props(styles.row)}>        <Button variant="tertiary" onClick={() => setValue(today(getLocalTimeZone()))}>          Set today        </Button>        <Button variant="tertiary" onClick={() => setValue(null)}>          Clear        </Button>      </div>    </div>  );}

Local adaptation source above. Derived from HeroUI v3.2.6 source.

表单示例

包含校验与提交的完整表单示例。

此预览复用英文版适配,不代表中文源示例已完成本地实现。

"use client";// HeroUI v3.2.6. Copyright NextUI Inc. SPDX-License-Identifier: Apache-2.0.import type { DateValue } from "@internationalized/date";import { Calendar } from "@gravity-ui/icons";import { Button, DateField } from "@lenso/ui";import { Form } from "react-aria-components/Form";import { getLocalTimeZone, today } from "@internationalized/date";import { useState, type FormEvent } from "react";import * as stylex from "@stylexjs/stylex";import { styles } from "./demo-styles";
export function FormExample() {  const [value, setValue] = useState<DateValue | null>(null);  const [isSubmitting, setIsSubmitting] = useState(false);  const todayDate = today(getLocalTimeZone());  const isInvalid = value !== null && value.compare(todayDate) < 0;  const handleSubmit = (event: FormEvent<HTMLFormElement>) => {    event.preventDefault();    if (!value || isInvalid || isSubmitting) return;    setIsSubmitting(true);    setTimeout(() => {      console.log("Date submitted:", { date: value });      setValue(null);      setIsSubmitting(false);    }, 1500);  };  return (    <Form {...stylex.props(styles.form)} onSubmit={handleSubmit}>      <DateField        isRequired        xstyle={styles.full}        isInvalid={isInvalid}        minValue={todayDate}        name="date"        value={value}        onChange={setValue}      >        <DateField.Label>Appointment date</DateField.Label>        <DateField.Group>          <DateField.Prefix>            <Calendar {...stylex.props(styles.icon)} aria-hidden="true" />          </DateField.Prefix>          <DateField.Input>{(segment) => <DateField.Segment segment={segment} />}</DateField.Input>        </DateField.Group>        {isInvalid ? (          <DateField.Error>Date must be today or in the future</DateField.Error>        ) : (          <DateField.Description>Enter a date from today onwards</DateField.Description>        )}      </DateField>      <Button        xstyle={styles.full}        disabled={!value || isInvalid}        isLoading={isSubmitting}        type="submit"        variant="primary"      >        {isSubmitting ? "Submitting..." : "Submit"}      </Button>    </Form>  );}

Local adaptation source above. Derived from HeroUI v3.2.6 source.

带校验

DateField 支持 minValue、maxValue 与自定义校验逻辑。

此预览复用英文版适配,不代表中文源示例已完成本地实现。

"use client";// HeroUI v3.2.6. Copyright NextUI Inc. SPDX-License-Identifier: Apache-2.0.import type { DateValue } from "@internationalized/date";import { DateField } from "@lenso/ui";import { getLocalTimeZone, today } from "@internationalized/date";import { useState } from "react";import * as stylex from "@stylexjs/stylex";import { styles } from "./demo-styles";
export function WithValidation() {  const [value, setValue] = useState<DateValue | null>(null);  const todayDate = today(getLocalTimeZone());  const isInvalid = value !== null && value.compare(todayDate) < 0;  return (    <div {...stylex.props(styles.column)}>      <DateField        isRequired        xstyle={styles.field}        isInvalid={isInvalid}        minValue={todayDate}        name="date"        value={value}        onChange={setValue}      >        <DateField.Label>Date</DateField.Label>        <DateField.Group>          <DateField.Input>{(segment) => <DateField.Segment segment={segment} />}</DateField.Input>        </DateField.Group>        {isInvalid ? (          <DateField.Error>Date must be today or in the future</DateField.Error>        ) : (          <DateField.Description>Enter a date from today onwards</DateField.Description>        )}      </DateField>    </div>  );}

Local adaptation source above. Derived from HeroUI v3.2.6 source.

渲染函数

此预览复用英文版适配,不代表中文源示例已完成本地实现。

"use client";// HeroUI v3.2.6. Copyright NextUI Inc. SPDX-License-Identifier: Apache-2.0.import { DateField } from "@lenso/ui";import { styles } from "./demo-styles";
export function RenderFunction() {  return (    <DateField      xstyle={styles.field}      name="date"      render={(props) => <div {...props} data-custom="date-field" />}    >      <DateField.Label render={(props) => <span {...props} data-custom="date-field-label" />}>        Date      </DateField.Label>      <DateField.Group render={(props) => <div {...props} data-custom="date-field-group" />}>        <DateField.Input render={(props) => <div {...props} data-custom="date-field-input" />}>          {(segment) => <DateField.Segment segment={segment} />}        </DateField.Input>      </DateField.Group>    </DateField>  );}

Local adaptation source above. Derived from HeroUI v3.2.6 source.

自定义样式

Tailwind CSS

此预览复用英文版适配,不代表中文源示例已完成本地实现。

"use client";// HeroUI v3.2.6. Copyright NextUI Inc. SPDX-License-Identifier: Apache-2.0.import { DateField } from "@lenso/ui";import { styles } from "./demo-styles";
export function CustomStyles() {  return (    <DateField xstyle={styles.field} name="due-date">      <DateField.Label>Due date</DateField.Label>      <DateField.Group xstyle={styles.dateCustom} variant="secondary">        <DateField.Input>{(segment) => <DateField.Segment segment={segment} />}</DateField.Input>      </DateField.Group>    </DateField>  );}

Local adaptation source above. Derived from HeroUI v3.2.6 source.

全局 CSS

DateField 默认样式较轻量。覆盖 .date-field 类可自定义容器样式。

@layer components {  .date-field {    @apply flex flex-col gap-1;
    &[data-invalid="true"],    &[aria-invalid="true"] {      [data-slot="description"] {        @apply hidden;      }    }
    [data-slot="label"] {      @apply w-fit;    }
    [data-slot="description"] {      @apply px-1;    }  }}

样式参考

HeroUI 遵循 BEM 方法论,确保组件变体与状态可复用且易于自定义。

CSS 类

  • .date-field – 轻量样式的根容器(flex flex-col gap-1)

Note: 子组件(Label、Description、FieldError)拥有各自的 CSS 类与样式。自定义方式请参阅对应文档。DateField.Group 样式见下文 API 参考。

交互状态

DateField 会根据状态自动设置以下 data 属性:

  • Invalid:[data-invalid="true"] 或 [aria-invalid="true"] - 无效时自动隐藏 description slot
  • Required:[data-required="true"] - 当 isRequired 为 true 时应用
  • Disabled:[data-disabled="true"] - 当 isDisabled 为 true 时应用
  • Focus Within:[data-focus-within="true"] - 任一子输入聚焦时应用

API 参考

DateField

DateField 继承 React Aria DateField 的全部 props。

Base Props

Prop类型默认值描述
childrenReact.ReactNode | (values: DateFieldRenderProps) => React.ReactNode-子组件(Label、DateField.Group 等)或渲染函数。
classNamestring | (values: DateFieldRenderProps) => string-用于样式的 CSS 类,支持渲染 prop。
styleReact.CSSProperties | (values: DateFieldRenderProps) => React.CSSProperties-内联样式,支持渲染 prop。
fullWidthbooleanfalse日期字段是否占满容器宽度。
idstring-元素的唯一 id。
renderDOMRenderFunction<keyof React.JSX.IntrinsicElements, DateFieldRenderProps>-使用自定义渲染函数覆盖默认 DOM 元素。

Value Props

Prop类型默认值描述
valueDateValue | null-当前值(受控)。类型见 @internationalized/date。
defaultValueDateValue | null-默认值(非受控)。类型见 @internationalized/date。
onChange(value: DateValue | null) => void-值变化时触发的事件处理函数。
placeholderValueDateValue | null-影响占位符格式的占位日期。

Validation Props

Prop类型默认值描述
isRequiredbooleanfalse是否在提交表单前要求用户输入。
isInvalidboolean-值是否无效。
minValueDateValue | null-用户可选择最早日期。类型见 @internationalized/date。
maxValueDateValue | null-用户可选择最晚日期。类型见 @internationalized/date。
isDateUnavailable(date: DateValue) => boolean-针对每个日期调用;返回 true 表示该日期不可用。
validate(value: DateValue) => ValidationError | true | null | undefined-自定义校验函数。
validationBehavior'native' | 'aria''native'使用原生 HTML 表单校验还是 ARIA 属性。

Format Props

Prop类型默认值描述
granularityGranularity-显示的最小单位。日期默认为 "day",时间默认为 "minute"。
hourCycle12 | 24-以 12 或 24 小时制显示时间;默认由语言环境决定。
hideTimeZonebooleanfalse是否隐藏时区缩写。
shouldForceLeadingZerosboolean-是否始终为月、日、小时等显示前导零。

State Props

Prop类型默认值描述
isDisabledboolean-是否禁用输入。
isReadOnlyboolean-是否可选中但不可修改。

Form Props

Prop类型默认值描述
namestring-输入元素的 name,用于 HTML 表单提交;以 ISO 8601 字符串提交。
autoFocusboolean-是否在渲染后自动聚焦该元素。
autoCompletestring-输入应提供的自动完成类型。

Accessibility Props

Prop类型默认值描述
aria-labelstring-无可见标签时的无障碍标签。
aria-labelledbystring-标注该字段的元素 id。
aria-describedbystring-描述该字段的元素 id。
aria-detailsstring-包含额外详情的元素 id。

Composition Components

DateField 与以下独立组件配合使用,请分别导入并直接使用:

  • Label – 来自 @lenso/ui 的字段标签
  • DateField.Group – 日期输入分组(详见下文)
  • DateField.Input – 来自 @lenso/ui 的分段位编辑输入
  • DateField.InputContainer – 可横向滚动的容器,用于组合多个输入(例如开始/结束范围)
  • DateField.Segment – 单个日期段位(年、月、日等)
  • DateField.Prefix / DateField.Suffix – 输入组的前缀与后缀插槽
  • Description – 来自 @lenso/ui 的辅助说明
  • FieldError – 来自 @lenso/ui 的校验错误信息

这些组件各自有独立的 props API。在 DateField 中直接组合使用:

import {parseDate} from '@internationalized/date';import {DateField, Label, Description, FieldError} from '@lenso/ui';
<DateField  isRequired  isInvalid={hasError}  minValue={today(getLocalTimeZone())}  value={date}  onChange={setDate}>  <Label>Appointment Date</Label>  <DateField.Group>    <DateField.Input>      {(segment) => <DateField.Segment segment={segment} />}    </DateField.Input>  </DateField.Group>  <Description>Select a date from today onwards.</Description>  <FieldError>Please select a valid date.</FieldError></DateField>

DateValue Types

DateField 使用 @internationalized/date 中的类型:

  • CalendarDate – 不含时间与时区的日期
  • CalendarDateTime – 含时间、不含时区
  • ZonedDateTime – 含时间与时区
  • Time – 仅时间

示例:

import {parseDate, today, getLocalTimeZone} from '@internationalized/date';
// Parse from stringconst date = parseDate('2024-01-15');
// Today's dateconst todayDate = today(getLocalTimeZone());
// Use in DateField<DateField value={date} onChange={setDate}>  {/* ... */}</DateField>

说明: DateField 依赖 @internationalized/date 进行解析、运算与类型定义。更多类型与函数见 Internationalized Date 文档。

Render Props

对 className、style 或 children 使用渲染 prop 时,可使用以下值:

Prop类型描述
isDisabledboolean字段是否禁用。
isInvalidboolean字段当前是否无效。
isReadOnlyboolean字段是否只读。
isRequiredboolean字段是否必填。
isFocusedboolean字段是否聚焦。
isFocusWithinboolean是否有子元素聚焦。
isFocusVisibleboolean焦点是否可见(键盘导航)。

DateField.Group

DateField.Group 继承 React Aria Group 的全部 props,并额外支持:

Prop类型默认值描述
classNamestring-与组件样式合并的 Tailwind CSS 类。
fullWidthbooleanfalse日期输入组是否占满容器宽度。
variant"primary" | "secondary""primary"视觉变体。primary 为默认带阴影样式;secondary 为低强调、无阴影,适合用于 Surface。

DateField.Input

DateField.Input 继承 React Aria DateInput 的全部 props,并额外支持:

Prop类型默认值描述
classNamestring-与组件样式合并的 Tailwind CSS 类。
variant"primary" | "secondary""primary"输入的视觉变体。primary 为默认带阴影样式;secondary 为低强调、无阴影,适合用于 Surface。

DateField.Input 接受渲染函数作为子节点,函数参数为日期段位;每个段位对应日期的一部分(年、月、日等)。

DateField.Segment

DateField.Segment 继承 React Aria DateSegment 的全部 props:

Prop类型默认值描述
segmentDateSegment-来自 DateField.Input 渲染函数的 DateSegment 对象。
classNamestring-与组件样式合并的 Tailwind CSS 类。

DateField.InputContainer

DateField.InputContainer 接受标准 HTML div 属性:

Prop类型默认值描述
classNamestring-与组件样式合并的 Tailwind CSS 类。
childrenReactNode-滚动容器中的内容(通常为多个 DateField.Input)。

DateField.Prefix

DateField.Prefix 接受标准 HTML div 属性:

Prop类型默认值描述
classNamestring-与组件样式合并的 Tailwind CSS 类。
childrenReactNode-前缀插槽中要显示的内容。

DateField.Suffix

DateField.Suffix 接受标准 HTML div 属性:

Prop类型默认值描述
classNamestring-与组件样式合并的 Tailwind CSS 类。
childrenReactNode-后缀插槽中要显示的内容。

DateField.Group Styling

Customizing the component classes

基础类作用于所有实例,可通过 @layer components 一次性覆盖。

@layer components {  .date-input-group {    @apply inline-flex h-9 items-center overflow-hidden rounded-field border bg-field text-sm text-field-foreground shadow-field outline-none;
    &:hover,    &[data-hovered="true"] {      @apply bg-field-hover;    }
    &[data-focus-within="true"],    &:focus-within {      @apply status-focused-field;    }
    &[data-invalid="true"] {      @apply status-invalid-field;    }
    &[data-disabled="true"],    &[aria-disabled="true"] {      @apply status-disabled;    }  }
  .date-input-group__input {    @apply flex flex-1 items-center gap-px rounded-none border-0 bg-transparent px-3 py-2 shadow-none outline-none;  }
  .date-input-group__segment {    @apply inline-block rounded-md px-0.5 text-end tabular-nums outline-none;
    &:focus,    &[data-focused="true"] {      @apply bg-accent-soft text-accent-soft-foreground;    }  }
  .date-input-group__input-container {    @apply flex flex-1 items-center;    overflow-x: auto;    overflow-y: clip;    scrollbar-width: none;  }
  .date-input-group__prefix,  .date-input-group__suffix {    @apply pointer-events-none shrink-0 text-field-placeholder flex items-center;  }}

DateField.Group CSS Classes

  • .date-input-group – 根容器样式
  • .date-input-group__input – 输入包裹层样式
  • .date-input-group__input-container – 用于组合多个输入的滚动容器
  • .date-input-group__segment – 单个日期段位样式
  • .date-input-group__prefix – 前缀元素样式
  • .date-input-group__suffix – 后缀元素样式

DateField.Group Interactive States

  • Hover::hover 或 [data-hovered="true"]
  • Focus Within:[data-focus-within="true"] 或 :focus-within
  • Invalid:[data-invalid="true"](与 aria-invalid 同步)
  • Disabled:[data-disabled="true"] 或 [aria-disabled="true"]
  • Segment Focus:段位上 :focus 或 [data-focused="true"]
  • Segment Placeholder:段位上 [data-placeholder="true"]

相关组件