# `hb-input-date`

**Category:** inputs · **Tags:** inputs

## Description

`hb-input-date` is a native HTML **`type="date"`** control wrapped in Bulma **`field`** / **`control`** markup. It reads its configuration from a serialized **`schemaentry`** object (same shape as form rows in `hb-form`), keeps the chosen value in sync with that schema, and optionally shows Bulma validation styling (**`is-success`** / **`is-danger`**) plus **`help is-danger`** feedback.

Optional inclusive bounds come from **`schemaentry.params`**: **`min`** and **`max`** are parsed with **`new Date(...)`** for validation. When those dates are finite, the same bounds are written to the native **`min`** / **`max`** attributes using the UTC calendar day from **`Date#toISOString()`** (first 10 characters, `YYYY-MM-DD`).

The component dispatches **`setVal`** whenever the current value or validity changes (for fields with an **`id`**), and **`clickEnter`** when the user presses **Enter** inside the input.

## Styling (Bulma)

Bulma **1.x** Sass is bundled in the shadow root: **`form/shared`**, **`form/input-textarea`**, and **`form/tools`**, with the light theme applied on **`:host`**. Set **`--bulma-*`** on the host (or on ancestors so they inherit) — see [Bulma CSS variables](https://bulma.io/documentation/features/css-variables/). Public tokens are listed in **`extra/docs.ts`** (`styleSetup.vars`).

| CSS variable (`:host`) | Role |
|------------------------|------|
| `--bulma-text` | Label, native date value, and help text. |
| `--bulma-border` | Input border before success/danger modifiers. |
| `--bulma-danger` | Invalid state border and **`help is-danger`** emphasis. |
| `--bulma-success` | Valid state (**`is-success`**) when validation styling is enabled. |
| `--bulma-scheme-main` | Input surface background inside the shadow root. |

The host is **`display: inline-block`** with flush field margins (see **`styles/webcomponent.scss`**).

## CSS `::part` names

| Part | Description |
|------|-------------|
| `invalid-feedback` | The **`p.help.is-danger`** node shown when **`show_validation="yes"`**, the field is invalid, and **`validationTip`** is set on **`schemaentry`**. |

## HTML slots

None.

## Custom element

| Name | Tag |
| --- | --- |
| `hb-input-date` | `<hb-input-date …></hb-input-date>` |

## Attributes (snake_case; string values in HTML)

From **`types/webcomponent.type.d.ts`**, all reflected host attributes are strings.

| Attribute | Required | Description |
|-----------|----------|-------------|
| `schemaentry` | Yes | JSON string describing the field (see below). May be updated over time; when its fingerprint changes, the internal value is reset from **`schemaentry.value`**. |
| `show_validation` | No | **`"yes"`** or **`"no"`** (default **`"no"`**). When **`"yes"`** and the field is **`required`**, the input gets **`is-success`** / **`is-danger`** and an optional danger **`help`** line. |
| `id` | No | Optional id on the host element. |
| `style` | No | Optional inline styles on the host element. |

### `schemaentry` JSON shape

The payload is a **`FormSchemaEntry`** for this host (see **`types/webcomponent.type.d.ts`**), based on **`FormSchemaEntryShared`** from **`form/types/webcomponent.type.d.ts`**, with **`params`** narrowed to **`InputDateParams`**.

| Property | Required | Description |
|----------|----------|-------------|
| `id` | **Yes** (for events) | Passed to the native **`input`** as **`id`**. **`setVal`** is only emitted when **`id`** is present. |
| `label` | No | Not rendered by this component; useful for forms and documentation. |
| `value` | No | Initial / controlled value, stringified when applied. Use an ISO-like date string (e.g. **`"1984-02-27"`**); the control uses **`type="date"`**. |
| `required` | No | When **`true`**, an empty value fails validation, and **`min`** / **`max`** (if set) are enforced inclusively. When **`false`** or omitted, the derived validity is always **`true`**. |
| `validationTip` | No | Message shown inside **`::part(invalid-feedback)`** when **`show_validation="yes"`** and the field is invalid. |
| `placeholder` | No | Forwarded to the native **`placeholder`** (browser support for placeholders on date inputs varies). |
| `readonly` | No | Forwarded to the native **`readonly`** attribute. |
| `disabled` | No | When **`true`**, the input is disabled. |
| `params` | No | **`InputDateParams`**: optional **`min`** / **`max`**, each a **`string`** or **`number`** understood by **`new Date(...)`**. Used for inclusive range checks and, when valid, for native **`min`** / **`max`**. |

Other keys from the shared form schema type (**`type`**, **`dependencies`**, **`validationRegex`**, etc.) may appear in JSON for compatibility with **`hb-form`** but are not used by this component’s template.

### Validation rules

- **`show_validation="yes"`** and **`required`**: the input is **`is-success`** when valid and **`is-danger`** when invalid.
- **`required`**: the user must pick a date (**non-empty** value).
- **`params.min`** / **`params.max`**: if present and parse to a real date, the chosen date’s timestamp must be **≥ `min`** and **≤ `max`** (inclusive). If **`required`** is false, these bounds are not applied by the derived **`valid`** flag (it stays **`true`**).

## Events

| Event | `detail` | When |
|-------|----------|------|
| `setVal` | `{ value: string \| undefined; valid: boolean; id: string }` | After **`schemaentry`** is applied and whenever **`value`** or **`valid`** changes; skipped if **`schemaentry.id`** is missing. |
| `clickEnter` | `{ value: string \| undefined; valid: boolean; id?: string }` | **`keypress`** with **`Enter`** on the input (**`preventDefault`**). |

Listen with **`addEventListener`** in the same way as for other **`hb-*`** elements.

## Usage notes

- **`schemaentry`** must be valid JSON when provided as a string; invalid JSON yields no parsed field and nothing is rendered inside the shadow root.
- Booleans in HTML attributes use this library’s convention: **`show_validation="yes"`** / **`"no"`** (not bare boolean attributes).
- **`setVal`** deduplication uses the same payload shape internally; consumers should not rely on duplicate suppression details.
- **Timezone:** bounds use **`Date`** arithmetic; the attributes **`min`** / **`max`** on the native control use the UTC date from **`toISOString()`**, which can differ from local calendar expectations for edge timestamps — prefer plain calendar dates (e.g. midnight UTC strings) when possible.

## TypeScript

Authoring types live in **`types/webcomponent.type.d.ts`**:

- **`InputDateParams`** — `{ min?: string | number; max?: string | number }`
- **`FormSchemaEntry`** — shared form row fields plus optional **`value`** and **`params`**
- **`Component`** — host props: **`id?`**, **`style?`**, **`show_validation?`**, **`schemaentry`**
- **`Events`** — **`setVal`** and **`clickEnter`** payloads

Built packages also emit **`types/html-elements.d.ts`** and **`types/svelte-elements.d.ts`** after **`npm run build:wc`**.

## Minimal HTML example

```html
<hb-input-date
  schemaentry="{&quot;id&quot;:&quot;birth_date&quot;,&quot;label&quot;:&quot;Birth date&quot;,&quot;required&quot;:true,&quot;validationTip&quot;:&quot;Please choose a valid date.&quot;}"
  show_validation="yes"
></hb-input-date>
```

With optional bounds (values must be JSON-escaped in HTML):

```html
<hb-input-date
  schemaentry="{&quot;id&quot;:&quot;appointment&quot;,&quot;required&quot;:true,&quot;params&quot;:{&quot;min&quot;:&quot;2024-01-01&quot;,&quot;max&quot;:&quot;2024-12-31&quot;}}"
  show_validation="no"
></hb-input-date>
```
