# Date

Use `ui-date` when users need one exact day rather than a month, week, or date-time value. It works well for booking, deadlines, confirmations, and review workflows where the day matters but the time does not.

## Import
```ts
import { DateComponent } from 'ui';
```

## Basic date selection
```ts
import { Component } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { ButtonComponent, DateComponent } from 'ui';

@Component({
  selector: 'app-date-basic-demo',
  standalone: true,
  imports: [FormsModule, ButtonComponent, DateComponent],
  template: `
    <div style="display:flex;flex-direction:column;gap:1rem;max-width:22rem">
      <ui-date
        label="Start date"
        placeholder="YYYY-MM-DD"
        [(ngModel)]="value"
        [ngModelOptions]="{ standalone: true }"
      />

      <div
        style="display:flex;flex-wrap:wrap;gap:0.75rem;align-items:center;padding:0.75rem 0.875rem;border:1px dashed var(--color-neutral-stroke-rest);border-radius:0.875rem;background:var(--color-neutral-background-rest)"
      >
        <ui-button type="button" appearance="subtle" (click)="value = ''">Clear</ui-button>
        <span style="font-size:0.75rem;color:var(--color-neutral-foreground2-rest)">
          {{ value || 'No date selected.' }}
        </span>
      </div>
    </div>
  `,
})
export class DateBasicDemoComponent {
  protected value = '2026-05-12';
}
```

## Size and input variant
```ts
import { Component } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { DateComponent } from 'ui';

@Component({
  selector: 'app-date-size-variant-demo',
  standalone: true,
  imports: [FormsModule, DateComponent],
  template: `
    <div
      style="display:grid;grid-template-columns:repeat(auto-fit,minmax(16rem,1fr));gap:1rem;align-items:start"
    >
      <ui-date
        label="Small filled"
        placeholder="YYYY-MM-DD"
        size="small"
        inputVariant="filled"
        [(ngModel)]="smallValue"
        [ngModelOptions]="{ standalone: true }"
      />

      <ui-date
        label="Medium filled gray"
        placeholder="YYYY-MM-DD"
        size="medium"
        inputVariant="filled-gray"
        [(ngModel)]="mediumValue"
        [ngModelOptions]="{ standalone: true }"
      />

      <ui-date
        label="Large underlined"
        placeholder="YYYY-MM-DD"
        size="large"
        inputVariant="underlined"
        [(ngModel)]="largeValue"
        [ngModelOptions]="{ standalone: true }"
      />
    </div>
  `,
})
export class DateSizeVariantDemoComponent {
  protected smallValue = '2026-05-08';
  protected mediumValue = '2026-05-12';
  protected largeValue = '2026-05-21';
}
```

## Min and max constraints
```ts
import { Component } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { DateComponent } from 'ui';

@Component({
  selector: 'app-date-constraints-demo',
  standalone: true,
  imports: [FormsModule, DateComponent],
  template: `
    <div style="display:flex;flex-direction:column;gap:1rem;max-width:22rem">
      <ui-date
        label="Booking date"
        placeholder="YYYY-MM-DD"
        min="2026-05-12"
        max="2026-05-26"
        [(ngModel)]="value"
        [ngModelOptions]="{ standalone: true }"
      />

      <div
        style="display:flex;flex-direction:column;gap:0.375rem;padding:0.75rem 0.875rem;border:1px dashed var(--color-neutral-stroke-rest);border-radius:0.875rem;background:var(--color-neutral-background-rest);font-size:0.75rem;color:var(--color-neutral-foreground2-rest)"
      >
        <span>Allowed window: 2026-05-12 to 2026-05-26</span>
        <span>Selected: {{ value || 'None' }}</span>
      </div>
    </div>
  `,
})
export class DateConstraintsDemoComponent {
  protected value = '2026-05-15';
}
```

## Readonly, disabled, and required states
```ts
import { Component } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { DateComponent } from 'ui';

@Component({
  selector: 'app-date-states-demo',
  standalone: true,
  imports: [FormsModule, DateComponent],
  template: `
    <div
      style="display:grid;grid-template-columns:repeat(auto-fit,minmax(16rem,1fr));gap:1rem;align-items:start"
    >
      <ui-date
        label="Readonly"
        placeholder="YYYY-MM-DD"
        [readonly]="true"
        [(ngModel)]="readonlyValue"
        [ngModelOptions]="{ standalone: true }"
      />

      <ui-date
        label="Disabled"
        placeholder="YYYY-MM-DD"
        [disabled]="true"
        [(ngModel)]="disabledValue"
        [ngModelOptions]="{ standalone: true }"
      />

      <ui-date
        label="Required"
        placeholder="YYYY-MM-DD"
        helpText="Choose the confirmation date."
        [required]="true"
        [(ngModel)]="requiredValue"
        [ngModelOptions]="{ standalone: true }"
      />
    </div>
  `,
})
export class DateStatesDemoComponent {
  protected readonlyValue = '2026-05-18';
  protected disabledValue = '2026-05-20';
  protected requiredValue = '';
}
```

## Reactive form integration
```ts
import { Component, computed } from '@angular/core';
import { FormControl, ReactiveFormsModule, Validators } from '@angular/forms';
import { ButtonComponent, DateComponent, MessageBarComponent } from 'ui';

@Component({
  selector: 'app-date-reactive-form-demo',
  standalone: true,
  imports: [ReactiveFormsModule, ButtonComponent, DateComponent, MessageBarComponent],
  template: `
    <div
      style="display:flex;flex-direction:column;gap:1rem;max-width:24rem;padding:1rem;border:1px solid var(--color-neutral-stroke-rest);border-radius:1rem;background:var(--color-neutral-background-rest)"
    >
      <div style="display:flex;flex-direction:column;gap:0.25rem">
        <div style="font-size:0.9375rem;font-weight:600">Review deadline</div>
        <div style="font-size:0.8125rem;color:var(--color-neutral-foreground2-rest)">
          Date usually matters as part of a real form flow with validation and submit state.
        </div>
      </div>

      <ui-date
        label="Deadline date"
        placeholder="YYYY-MM-DD"
        helpText="Choose the final review deadline."
        [required]="true"
        [formControl]="dateControl"
      />

      @if (dateControl.invalid && dateControl.touched) {
        <ui-message-bar
          title="Date required"
          message="Choose the deadline date before continuing."
          variant="warning"
          appearance="subtle"
          [dismissible]="false"
        />
      }

      <div
        style="display:flex;flex-wrap:wrap;gap:0.75rem;align-items:center;padding:0.75rem 0.875rem;border:1px dashed var(--color-neutral-stroke-rest);border-radius:0.875rem;background:var(--color-neutral-background-rest)"
      >
        <ui-button type="button" variant="primary" [disabled]="dateControl.invalid">
          Save deadline
        </ui-button>
        <ui-button type="button" appearance="subtle" (click)="reset()">Reset</ui-button>
        <span style="font-size:0.75rem;color:var(--color-neutral-foreground2-rest)">
          {{ summary() }}
        </span>
      </div>
    </div>
  `,
})
export class DateReactiveFormDemoComponent {
  protected readonly dateControl = new FormControl<string | null>('2026-05-19', {
    nonNullable: false,
    validators: [Validators.required],
  });

  protected readonly summary = computed(() => this.dateControl.value || 'No date selected.');

  protected reset(): void {
    this.dateControl.reset('2026-05-19');
  }
}
```

## Booking panel composition
```ts
import { Component } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { ButtonComponent, DateComponent, MessageBarComponent, TagComponent } from 'ui';

@Component({
  selector: 'app-date-booking-panel-demo',
  standalone: true,
  imports: [FormsModule, ButtonComponent, DateComponent, MessageBarComponent, TagComponent],
  template: `
    <div
      style="display:grid;grid-template-columns:repeat(auto-fit,minmax(18rem,1fr));gap:1rem;align-items:start;max-width:48rem"
    >
      <div
        style="display:flex;flex-direction:column;gap:1rem;padding:1rem;border:1px solid var(--color-neutral-stroke-rest);border-radius:1rem;background:var(--color-neutral-background-rest)"
      >
        <div style="display:flex;flex-direction:column;gap:0.25rem">
          <div style="font-size:0.9375rem;font-weight:600">Visit booking</div>
          <div style="font-size:0.8125rem;color:var(--color-neutral-foreground2-rest)">
            Date is strongest when users need one specific day with surrounding booking context.
          </div>
        </div>

        <ui-date
          label="Visit date"
          placeholder="YYYY-MM-DD"
          [(ngModel)]="value"
          [ngModelOptions]="{ standalone: true }"
        />

        <ui-message-bar
          title="Availability note"
          message="Confirm the selected day with the team before sending the final confirmation."
          variant="info"
          appearance="subtle"
          [dismissible]="false"
        />
      </div>

      <div
        style="display:flex;flex-direction:column;gap:0.875rem;padding:1rem;border:1px solid var(--color-neutral-stroke-rest);border-radius:1rem;background:var(--color-neutral-background-rest)"
      >
        <div style="display:flex;flex-wrap:wrap;gap:0.5rem">
          <ui-tag text="On-site" appearance="filled" variant="secondary" />
          <ui-tag text="Weekday slot" appearance="subtle" variant="info" />
          <ui-tag text="Ready to confirm" appearance="subtle" variant="success" />
        </div>

        <div style="display:flex;flex-direction:column;gap:0.375rem">
          <div style="font-size:0.8125rem;color:var(--color-neutral-foreground2-rest)">
            Selected day
          </div>
          <div style="font-size:0.9375rem;font-weight:600">{{ value || 'Not selected' }}</div>
        </div>

        <div
          style="display:flex;flex-wrap:wrap;gap:0.75rem;align-items:center;padding:0.75rem 0.875rem;border:1px dashed var(--color-neutral-stroke-rest);border-radius:0.875rem;background:var(--color-neutral-background-rest)"
        >
          <ui-button type="button" variant="primary">Confirm visit</ui-button>
          <ui-button type="button" appearance="subtle" (click)="value = ''">Reset</ui-button>
        </div>
      </div>
    </div>
  `,
})
export class DateBookingPanelDemoComponent {
  protected value = '2026-05-22';
}
```

## Accessibility

### Input and popup behavior
`ui-date` behaves like a text field on desktop and can fall back to a native `type="date"` input on mobile when `useNativeOnMobile` is enabled.

| Mode | Behavior |
| --- | --- |
| desktop text input | exposes `aria-haspopup="dialog"` and `aria-expanded` |
| mobile native date input | relies on native platform date input semantics |
| disabled or readonly | prevents opening or changing the value |

### Keyboard
Keyboard handling follows the shared field and popup model.

| Key | Action |
| --- | --- |
| `Tab` / `Shift+Tab` | moves through the field and calendar controls |
| `Enter` / click on trigger actions | opens the date picker panel on desktop |
| button activation | selects a day or runs footer actions like clear or today |

### Labels and guidance
Use a task-specific label such as deadline date, visit date, or confirmation date so the meaning of the chosen day is obvious. If the valid window is narrow, add helper text or nearby status text that explains the allowed range.
