Files
HMDesign/packages/ui/src/theme/input.css
T

108 lines
4.5 KiB
CSS

/* Input mapping: the control only. Label, Required star and Helper/Error message are consumer composition, not part of Input.
States use native selectors (:focus-visible, [aria-invalid="true"], :disabled, [readonly]); size uses data-size. */
:root, [data-hm-theme] {
/* ui_viz: docs/components/input.md §24, §16 — Confirmed (size, padding-x). Not aliased to Button or the global control height. */
--hm-input-height-sm: 28px;
--hm-input-height-md: 34px;
--hm-input-height-lg: 42px;
--hm-input-padding-x-sm: 10px;
--hm-input-padding-x-md: 12px;
--hm-input-padding-x-lg: 12px;
/* ui_viz: docs/components/input.md §9, §21 INPUT_VALUE_ROLE_FOLLOWS_SIZE — owner decision (value and placeholder per size) */
--hm-input-font-size-sm: 12px;
--hm-input-line-height-sm: 18px;
--hm-input-font-size-md: 14px;
--hm-input-line-height-md: 20px;
--hm-input-font-size-lg: 16px;
--hm-input-line-height-lg: 24px;
--hm-input-font-weight: 400;
/* ui_viz: docs/components/input.md §10, §11, §1.1 D-005 — Confirmed */
--hm-input-radius: var(--hm-radius-input);
--hm-input-border-width: 1px;
--hm-input-state-border-width: 1.5px;
--hm-input-background: var(--hm-sem-bg-surface);
--hm-input-text: var(--hm-sem-fg-primary);
--hm-input-placeholder: var(--hm-sem-fg-placeholder);
--hm-input-border-color: var(--hm-sem-stroke-input-default);
--hm-input-focus-border-color: var(--hm-sem-stroke-input-focus);
--hm-input-error-border-color: var(--hm-sem-action-destructive);
}
/* Large is the default when size is omitted. Height is a min-height, so the control keeps one line of text centered. */
[data-slot="input"] {
--hm-input-height: var(--hm-input-height-lg);
--hm-input-padding-x: var(--hm-input-padding-x-lg);
--hm-input-font-size: var(--hm-input-font-size-lg);
--hm-input-line-height: var(--hm-input-line-height-lg);
box-sizing: border-box;
height: auto;
min-height: var(--hm-input-height);
padding: 0 var(--hm-input-padding-x);
border: var(--hm-input-border-width) solid var(--hm-input-border-color);
border-radius: var(--hm-input-radius);
background: var(--hm-input-background);
color: var(--hm-input-text);
font-size: var(--hm-input-font-size);
line-height: var(--hm-input-line-height);
font-weight: var(--hm-input-font-weight);
box-shadow: none;
}
[data-slot="input"][data-size="medium"] {
--hm-input-height: var(--hm-input-height-md);
--hm-input-padding-x: var(--hm-input-padding-x-md);
--hm-input-font-size: var(--hm-input-font-size-md);
--hm-input-line-height: var(--hm-input-line-height-md);
}
[data-slot="input"][data-size="small"] {
--hm-input-height: var(--hm-input-height-sm);
--hm-input-padding-x: var(--hm-input-padding-x-sm);
--hm-input-font-size: var(--hm-input-font-size-sm);
--hm-input-line-height: var(--hm-input-line-height-sm);
}
[data-slot="input"]::placeholder {
color: var(--hm-input-placeholder);
opacity: 1;
}
/* Focus: the border alone marks it (1.5px, no shadow or glow). Padding gives back the extra 0.5px so the value does not move. */
[data-slot="input"]:focus-visible {
outline: none;
border-width: var(--hm-input-state-border-width);
border-color: var(--hm-input-focus-border-color);
padding-inline: calc(var(--hm-input-padding-x) - (var(--hm-input-state-border-width) - var(--hm-input-border-width)));
}
/* Invalid owns the border; keyboard focus adds the HM 3px / 50% semantic ring independently. */
[data-slot="input"][aria-invalid="true"] {
border-width: var(--hm-input-state-border-width);
border-color: var(--hm-input-error-border-color);
padding-inline: calc(var(--hm-input-padding-x) - (var(--hm-input-state-border-width) - var(--hm-input-border-width)));
}
[data-slot="input"][aria-invalid="true"]:focus-visible {
border-color: var(--hm-input-error-border-color);
outline: none;
box-shadow: 0 0 0 3px color-mix(in srgb, var(--ring) 50%, transparent);
}
/* Disabled keeps the white face. Dimming (opacity 0.6) is set in ui/input.tsx: 2026-10-02 user decision, Input and Select only, not a global Disabled token. */
[data-slot="input"]:disabled {
background: var(--hm-input-background);
}
/* Readonly: no box, text only, not dimmed. Always Large metrics, whatever the size. */
[data-slot="input"][readonly] {
--hm-input-height: var(--hm-input-height-lg);
--hm-input-font-size: var(--hm-input-font-size-lg);
--hm-input-line-height: var(--hm-input-line-height-lg);
border-width: 0;
padding-inline: 0;
background: transparent;
}
[data-slot="input"][readonly]:focus-visible {
border-width: 0;
padding-inline: 0;
outline: revert;
}