# Month

Use `ui-month` when users need to work with monthly periods rather than exact dates. It fits billing cycles, reporting, budget planning, and recurring schedules where the month matters but the day does not.

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

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

@Component({
  selector: 'app-month-basic-demo',
  standalone: true,
  imports: [FormsModule, ButtonComponent, MonthComponent],
  template: `
    <div style="display:flex;flex-direction:column;gap:1rem;max-width:22rem">
      <ui-month
        label="Billing month"
        placeholder="YYYY-MM"
        [(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 month selected.' }}
        </span>
      </div>
    </div>
  `,
})
export class MonthBasicDemoComponent {
  protected value = '2026-05';
}
```

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

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

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

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

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

@Component({
  selector: 'app-month-constraints-demo',
  standalone: true,
  imports: [FormsModule, MonthComponent],
  template: `
    <div style="display:flex;flex-direction:column;gap:1rem;max-width:22rem">
      <ui-month
        label="Forecast month"
        placeholder="YYYY-MM"
        min="2026-04"
        max="2026-09"
        [(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-04 to 2026-09</span>
        <span>Selected: {{ value || 'None' }}</span>
      </div>
    </div>
  `,
})
export class MonthConstraintsDemoComponent {
  protected value = '2026-06';
}
```

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

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

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

      <ui-month
        label="Required"
        placeholder="YYYY-MM"
        helpText="Choose the closing month."
        [required]="true"
        [(ngModel)]="requiredValue"
        [ngModelOptions]="{ standalone: true }"
      />
    </div>
  `,
})
export class MonthStatesDemoComponent {
  protected readonlyValue = '2026-07';
  protected disabledValue = '2026-08';
  protected requiredValue = '';
}
```

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

@Component({
  selector: 'app-month-reactive-form-demo',
  standalone: true,
  imports: [ReactiveFormsModule, ButtonComponent, MessageBarComponent, MonthComponent],
  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">Monthly close</div>
        <div style="font-size:0.8125rem;color:var(--color-neutral-foreground2-rest)">
          Month selection usually lives in reporting, finance, or scheduling forms rather than as an
          isolated picker.
        </div>
      </div>

      <ui-month
        label="Closing month"
        placeholder="YYYY-MM"
        helpText="Select the month for the financial close."
        [required]="true"
        [formControl]="monthControl"
      />

      @if (monthControl.invalid && monthControl.touched) {
        <ui-message-bar
          title="Month required"
          message="Choose the reporting month 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]="monthControl.invalid">
          Save close
        </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 MonthReactiveFormDemoComponent {
  protected readonly monthControl = new FormControl<string | null>('2026-05', {
    nonNullable: false,
    validators: [Validators.required],
  });

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

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

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

@Component({
  selector: 'app-month-reporting-panel-demo',
  standalone: true,
  imports: [FormsModule, ButtonComponent, MessageBarComponent, MonthComponent, TagComponent],
  template: `
    <div
      style="display:grid;grid-template-columns:repeat(auto-fit,minmax(18rem,1fr));gap:1rem;align-items:start;max-width:46rem"
    >
      <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">Reporting cycle</div>
          <div style="font-size:0.8125rem;color:var(--color-neutral-foreground2-rest)">
            Month pickers are common in budgets, reporting cycles, and recurring planning workflows.
          </div>
        </div>

        <ui-month
          label="Report month"
          placeholder="YYYY-MM"
          [(ngModel)]="month"
          [ngModelOptions]="{ standalone: true }"
        />

        <ui-message-bar
          title="Submission note"
          message="The selected month drives budget aggregation and report ownership."
          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="Finance" appearance="filled" variant="secondary" />
          <ui-tag text="Monthly cadence" appearance="subtle" variant="info" />
          <ui-tag text="Ready to review" 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 month
          </div>
          <div style="font-size:0.9375rem;font-weight:600">{{ month || '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">Generate report</ui-button>
          <ui-button type="button" appearance="subtle" (click)="month = ''">Reset</ui-button>
        </div>
      </div>
    </div>
  `,
})
export class MonthReportingPanelDemoComponent {
  protected month = '2026-09';
}
```

## Accessibility

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

| Mode | Behavior |
| --- | --- |
| desktop text input | exposes `aria-haspopup="dialog"` and `aria-expanded` |
| mobile native month input | relies on native platform month 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 overlay controls |
| `Enter` / click on trigger actions | opens the month picker panel on desktop |
| button activation | selects a month or runs footer actions like clear or this month |

### Labels and guidance
Use a precise label such as report month, billing month, or closing month so users understand the period context. If the valid range is narrow, add helper text or status text that explains the allowed months.
