ClickorKeyboard shortcut Alt + L

Dragto resize

Nord Design System SearchDeveloperDeveloperGetting startedUsing Web ComponentsWebfontsCDNLocalizationCSS Framework Legacy ESLint PluginWorking with AIFAQDesignDesignGetting startedFoundationsAccessibilityColor SystemColor UtilitiesPrinciplesFigma ToolkitGridIconographyNamingNordhealth BrandTypographyThemesBrand assetsToolsComponentsComponentsAccordion New Aside New Autocomplete New AvatarBadgeBannerButtonButton GroupCalendarCard Updated CheckboxCollapsible New Combobox New Command MenuDate PickerDate Range Picker New DividerDrawer Updated DropdownEmpty StateField New FieldsetFilter Add ButtonFilter DateFilter Date RangeFilter DropdownFilter FieldFilter InputFilter Reset ButtonFooterHeaderIconInputInput Group New Item New Kbd New LayoutMessageMeter New Modal Updated NavigationNotificationNumber Field New Otp Field New Outline New Overflow List New Pagination New PopoutProgressProgress BarQrcodeRadioRangeResizable New Scroll Area New Segmented ControlSelectSkeletonSpinnerStackTabTableTagTextareaTime Picker New Timestamp New ToastToggleTooltipTop BarTruncate New Visually HiddenDesign TokensDesign TokensTailwind CSSTailwind CSSBlocksBlocksTemplatesTemplatesIconsIconsPlaygroundPlaygroundLatest UpdatesLatest UpdatesChangelogChangelogMigration guidesMigration guides
GitHub

Clickto expandKeyboard shortcut Alt + L

Input Group New Alpha Light DOM & Tailwind

Open in Storybook

Combines one Nord text control with contextual add-ons inside a shared field surface.

This component is considered alpha. We're still finalising the API, so it may include a breaking change at any time — use it at your own risk.
Loading...

Usage

Input Group composes exactly one Input or Textarea with reusable Nord content. The nested control remains the only editable, form-associated element and retains its Shadow DOM, value, events, methods, validation, and reset behavior. The Light DOM group and add-ons provide only the shared presentation.

Import both modules to register the group and add-on elements:

import "@nordhealth/components/lib/InputGroup"
import "@nordhealth/components/lib/InputGroupAddon"

Composition

Input Group Addon positions contextual content around the shared control surface.

Give a standalone group a label, or place it inside a Field. Add-ons can contain text, icons, buttons, keyboard hints, spinners, or a dropdown without replacing those components’ semantics.

Supported controls: compose exactly one direct Nord Input or Textarea. Native inputs and arbitrary custom or third-party controls are unsupported because they cannot consume the Field, validation, focus, and presentation contexts; those compositions use the diagnostic fallback.

The Input Group is presentational, while the nested Input, Textarea, or surrounding Field owns the form semantics. Use the group label API for a standalone compound field, or let Field own label, hint, error, required, and invalid presentation when the group is composed inside one.

Examples

Label ownership

Choose one source for field copy: use Input Group’s label and hint API when it stands alone, or Field when the composition needs shared form layout and description.

Hint placement

Use hint-below when a standalone group’s hint should follow the control instead of appearing beside its label. Field compositions continue to follow Field’s own description layout.

Add-on alignments

The position property uses logical directions and does not depend on source order. The default is inline-start. Keep interactive children in the DOM order users should encounter with a keyboard or screen reader.

The group shell owns the one shared background and outline. Add-ons and the nested Input or Textarea stay transparent and borderless inside it, with no internal divider seams.

At medium size, inline add-ons keep their token-based outer inset and remove only the padding beside the control. The grouped control supplies one small --n-space-xs seam gap. A standalone decorative Icon receives a subtle token-derived optical adjustment automatically. An exact direct Button or Dropdown matching the group size supplies its own control padding; intentionally smaller nested controls keep the normal add-on inset. Private token roles scale that geometry, add-on typography, child gap, padding, and target height with group size; block add-ons align to the native text inset.

inline-start

Use inline-start for prefixes or leading context.

inline-end

Use inline-end for suffixes, units, or trailing context.

block-start

Block-start add-ons span the shared surface above the editable control.

block-end

Block-end add-ons span the shared surface below the control and grow with multiline content.

Icon

Use a decorative icon to reinforce the expected content or status. Icon-only actions still need their own accessible name.

Text

Short text add-ons work well for currency, units, URL fragments, or account suffixes. Put longer guidance in a hint or Field Description instead.

Button

Buttons and links remain independent actions. Clicking them does not focus or activate the text control. Pair an unfamiliar icon-only action with an accessible label and Tooltip.

Kbd

Keyboard hints retain their kbd semantics and can sit beside other add-on content.

A Dropdown trigger keeps its own focus, menu interaction, and disabled state. The group does not synthesize clicks or disable add-on actions implicitly.

Spinner

Use a labeled Spinner for meaningful asynchronous state such as saving or loading. Readonly can prevent editing while the operation completes without removing the current value from form submission.

Textarea

Textarea retains its multiline and auto-growth behavior. Block add-ons remain above or below the control while the shared border grows with its content.

Size

Set size to s, m (default), or l. Input Group owns the effective presentation of its direct Input or Textarea and add-ons so their font size, line height, spacing, and height stay aligned. An explicit child size remains unchanged but group size takes presentation precedence while composed; the child’s own size resumes if it moves outside the group. The default token geometry follows the corresponding Nord text-control sizes, and --n-input-group-target-size can raise the shared minimum where a larger product-specific touch target is required.

Custom Input

Custom Input styling uses Nord Input properties and Input Group’s public CSS custom properties. Third-party text controls are intentionally unsupported: accepting only Nord Input or Textarea preserves form association, password-manager handling, native events, validation, and the one-surface presentation contract.

Available presentation variables are --n-input-group-inline-size, --n-input-group-background, --n-input-group-background-inactive, --n-input-group-border-color, --n-input-group-border-radius, and --n-input-group-target-size. Target size defaults to the effective s, m, or l Nord control geometry and can be increased for larger compound controls.

RTL

Logical inline positions mirror with the surrounding writing direction. DOM and keyboard order stay unchanged.

Validation and Field composition

For standalone use, provide label and optionally hint, error, required, or invalid on the group. Inside nord-field, Field owns the label, helper/error content, and invalid presentation; avoid providing both sets of field copy. Disabled state OR-merges Field, group, and direct-control state. Setting required on either the group or direct control marks the Field Label required, while readonly state comes from either the group or direct control.

Disabled and readonly

Group disabled and readonly state flows to the editable control and combines with the direct control’s own state; Field disabled state also participates in the disabled OR-merge. Disabled values are omitted from FormData; readonly values remain submitted. Add-on actions follow only their own explicit disabled state, so disable them separately when the action should also be unavailable.

Accessibility

  • Clicking noninteractive icon, text, or empty add-on space focuses the text control without changing its value.
  • Buttons, links, menu triggers, and other interactive descendants retain their own pointer and keyboard behavior.
  • The shared boundary reflects hover, keyboard focus-visible, invalid, disabled, and readonly state without adding a second inner border.
  • Every group needs an accessible label. A standalone group can use label or the label slot; a group inside Field uses Field Label.
  • Hint and error content is associated with the inner Shadow DOM control, and invalid state is exposed through native and ARIA state.
  • Logical properties, Nord semantic tokens, forced-colors handling, reduced motion, compact widths, and multiline growth support themes, RTL, zoom, and high contrast.

API reference

InputGroup

Input Group composes exactly one Nord Input or Textarea with reusable add-ons while leaving the editable control, form state, and all consumer nodes owned by the consumer.

<nord-input-group></nord-input-group>

Props

PropertyAttribute Description TypeDefault
sizesizeControls the effective size of the grouped Input or Textarea and add-ons.'s' | 'm' | 'l''m'
labellabelPlain-text label used when the group is not inside a Nord Field.string''
hinthintOptional standalone hint text.string | undefined
hintBelowhint-belowPlaces the standalone hint below the group surface.booleanfalse
errorerrorOptional standalone error text. Supplying it makes the group invalid.string | undefined
requiredrequiredMakes the grouped text control required.booleanfalse
hideLabelhide-labelVisually hides the standalone label while preserving its accessible name.booleanfalse
hideRequiredhide-requiredHides the visual required indicator without changing native required state.booleanfalse
invalidinvalidApplies invalid state when the group is standalone.booleanfalse
disableddisabledDisables the grouped text control without implicitly disabling add-on actions.booleanfalse
readonlyreadonlyMakes the grouped text control readonly.booleanfalse

Slots

Slot name Description
Default slotA single nord-input or nord-textarea plus Input Group Addons.
labelOptional rich label content for a standalone group.
hintOptional rich hint content for a standalone group.
errorOptional rich validation message for a standalone group.

CSS Properties

CSS Custom Properties provide more fine grain control over component presentation. We advise utilizing existing properties on the component before using these.

PropertyDescriptionDefault
--n-input-group-inline-sizeControls the group's inline size.100%
--n-input-group-backgroundControls the shared control surface.var(--n-color-surface)
--n-input-group-background-inactiveControls the disabled and readonly surface.var(--n-color-active)
--n-input-group-border-colorControls the shared border colour.var(--n-color-border-strong)
--n-input-group-border-radiusControls the shared corner radius.var(--n-border-radius-s)
--n-input-group-target-sizeOverrides the size-derived compound control minimum block size.

State attributes

These data-* attributes are set by the component to reflect its current state. Use them as styling hooks — they are read-only and should not be set manually.

AttributeDescription
data-invalidPresent while the effective Field/group state is invalid.
data-disabledPresent while the effective Field/group state is disabled.
data-readonlyPresent while the group or control is readonly.
data-focusedPresent while the control or an add-on action has focus.
data-focus-visiblePresent while the text control has keyboard-visible focus.
data-composition-invalidPresent unless exactly one supported text control is composed.
Light DOM & Tailwind. This component renders in the light DOM, so you can style it directly with your own CSS or Tailwind utility classes — there is no shadow boundary, and its default styles are low specificity, so your utilities win.

Parts

This component is made up of the following parts.

Input Group Addon

Positions reusable Nord content around the text control in an Input Group. Its children retain their native semantics and interaction behavior.

<nord-input-group-addon></nord-input-group-addon>

Props

PropertyAttribute Description TypeDefault
positionpositionLogical position around the grouped text control.InputGroupAddonPosition'inline-start'

Slots

Slot name Description
Default slotText, icons, keyboard hints, spinners, buttons, dropdowns, or other reusable content.
Design guidelinesFor designers

Usage

Input Group presents exactly one Input or Textarea and one or more add-ons as a single field surface. The original control remains the sole editable, form-associated element; the group does not clone, move, or replace consumer content.

Supported controls: the editable child must be exactly one direct nord-input or nord-textarea. Native inputs and arbitrary custom/third-party controls are unsupported because they cannot consume the group’s Field, validation, focus, and presentation contexts; unsupported compositions render the diagnostic fallback.

Do

  • Use add-ons for short context such as units, URL prefixes, icons, keyboard hints, loading state, or a closely related action.
  • Provide exactly one direct nord-input or nord-textarea child and give the group a label, or compose it inside a Field.
  • Use logical inline-start, inline-end, block-start, and block-end positions so the layout adapts to right-to-left languages.
  • Keep interactive add-ons explicitly enabled or disabled according to their own action state.

Don’t

  • Don’t put multiple editable controls in one group; use a Field Group for multiple fields.
  • Don’t use an add-on for lengthy help or validation copy; use a hint, Field Description, or Field Error.
  • Don’t visually reorder interactive add-ons with custom CSS, because keyboard order follows source order.
  • Don’t substitute a third-party input element. Input Group supports Nord Input and Textarea so it can preserve their established form, validation, and accessibility behavior.

Add-on positions

nord-input-group-addon defaults to position="inline-start". Inline positions sit before or after the text control in the current writing direction. Block positions span the group above or below the control. Position is independent of source order, but focus and assistive-technology order still follow the DOM, so place interactive content in the order users should encounter it.

The group shell supplies the one shared background and outline. Add-ons and the nested text control are transparent within that surface and do not draw internal divider borders.

At the default medium size, inline add-ons keep the normal --n-space-s outer inset but remove padding at the control seam; the grouped control contributes one --n-space-xs gap on that side. A direct, standalone Icon gets a small token-derived optical adjustment automatically. An exact direct Button or Dropdown whose own size matches the group supplies its own control padding, so the add-on removes the duplicate wrapper padding; intentionally smaller nested controls retain the normal inset. Private Nord-token roles scale add-on typography, child gap, padding, seam gap, and target height with group size, while block add-ons share the native control's effective text inset.

Clicking noninteractive add-on content focuses the text control. Buttons, links, dropdown triggers, and other interactive descendants keep their own pointer and keyboard behavior; Input Group neither synthesizes a control click nor disables those actions implicitly.

Label ownership

Input Group supports two label owners. Choose one pattern for each group; do not provide field copy in both places.

Standalone Input Group

Use the group’s label when Input Group stands on its own. Put hint, error, required, invalid, disabled, and readonly on the group when they describe the combined control. Input Group renders that field UI once and supplies its accessible name and description to the nested Shadow DOM control.

Hint text appears above the shared surface by default. Add hint-below when the helper copy should follow the control. If an error is also present, the error appears first and the hint follows it, matching Input and Textarea.

<nord-input-group label="Website" hint="Enter the public address." hint-below required>
  <nord-input placeholder="example.com"></nord-input>
  <nord-input-group-addon position="inline-start">https://</nord-input-group-addon>
</nord-input-group>

Input Group inside Field

Use Field when the surrounding form should own the label, description, error, disabled state, or invalid state. Do not also set label, hint, error, or invalid on Input Group. Field is the sole visible and accessible field owner; the group continues to own the combined surface.

Put required on the direct Input or Textarea so Field Label can reflect it. A control may still own control-specific properties such as name, value, autocomplete, readonly, and native validation constraints.

<nord-field invalid>
  <nord-field-label for="website">Website</nord-field-label>
  <nord-input-group>
    <nord-input id="website" placeholder="example.com" required></nord-input>
    <nord-input-group-addon position="inline-start">https://</nord-input-group-addon>
  </nord-input-group>
  <nord-field-description>Enter the public address.</nord-field-description>
  <nord-field-error>This address is unavailable.</nord-field-error>
</nord-field>

The nested Input or Textarea’s built-in label, hint, and error UI is suppressed while Field or standalone Input Group owns that field context. Keep this copy on the selected owner so users receive one label and one description.

Field state

Disabled state is an OR-merge of Field, Input Group, and the direct Input or Textarea: any one can disable the editable control. A required group or direct control publishes required state to the Field Label. Readonly state likewise comes from either the group or direct control. The nested Input or Textarea keeps its value, name, autocomplete, validation, native input and change events, focus methods, and form participation. Form reset restores its initial value, disabled controls are omitted from FormData, and readonly values remain submitted.

Size

Set group size to s, m (default), or l. The group owns the effective presentation of its direct Input or Textarea and add-ons so typography, line height, spacing, and block size stay aligned. A child’s own public size value is not mutated: group size takes presentation precedence only while the child is composed, and the child’s explicit size resumes if it moves outside.

Custom presentation

Use the group’s public CSS custom properties to adapt a supported Nord control rather than replacing it:

  • --n-input-group-inline-size
  • --n-input-group-background
  • --n-input-group-background-inactive
  • --n-input-group-border-color
  • --n-input-group-border-radius
  • --n-input-group-target-size (overrides the effective size’s token-derived target height)

The Custom Input example customizes the supported Nord Input with its public properties and these variables; it does not accept a different control implementation. The exact-one-Nord-control boundary is intentional: it avoids forking form association, password-manager behavior, native events, and validation semantics.

Accessibility

  • Every group needs an accessible label. Use the group’s label/label slot when standalone, or a connected Field Label inside Field.
  • Decorative icons should have no label. Give icon-only add-on buttons their own accessible label and associate a Tooltip when the action benefits from visible explanation.
  • Keep spinners labeled when they communicate meaningful asynchronous state.
  • Required, invalid, disabled, and readonly visuals mirror the effective native and ARIA state of the nested control.
  • Focus-visible styling follows keyboard focus on the text control, while :focus-within keeps the shared surface coherent as focus moves to add-on actions.
  • Logical layout, token-based colors, forced-colors support, reduced motion, multiline growth, and compact-width constraints are built into the group shell.

Rendering boundary

Input Group and Input Group Addon are scoped Light DOM shells. Input and Textarea retain their existing Shadow DOM. Only component-owned label, hint, error, and shell nodes receive the private scope stamp; consumer controls, add-on children, state, listeners, text, and DOM identity remain untouched.