Label
Renders an accessible label associated with controls.
- v1.0.0
- SSR
- Zoneless
- 1.3 kB gzip
import { Component } from '@angular/core';
import { Input } from '@/ui/input/input';
import { Label } from '@/ui/label/label';
/** A label naming its input. */
@Component({
selector: 'example-label-demo',
imports: [Label, Input],
template: `
<div class="grid w-full max-w-sm gap-3">
<label ndLabel for="label-demo-name">Full name</label>
<input ndInput id="label-demo-name" placeholder="Ada Lovelace" />
</div>
`,
})
export class LabelDemoExample {}
A label names a form control. ndLabel styles a native label, which names
the control its for attribute points at and moves focus to it when
clicked. When the control is an input[ndInput], the label also mirrors its
state with data-invalid and data-disabled, so the two style together.
Installation
npx @ndop/cli add labelpnpm dlx @ndop/cli add labelyarn dlx @ndop/cli add labelbunx @ndop/cli add labelInstall the dependencies
npm install @ndop/primitives @ndop/corepnpm add @ndop/primitives @ndop/coreyarn add @ndop/primitives @ndop/corebun add @ndop/primitives @ndop/coreCopy the code into your project
At the paths your
ndop.jsonaliases point to; these use the defaults.src/app/ui/label/label.tsimport { computed, Directive, input } from '@angular/core'; import { NdLabel } from '@ndop/primitives/label'; import { cn } from '@/lib/utils'; /** * Styled label. Names its control natively through `for`, and mirrors an * `input[ndInput]`'s disabled and invalid state (`@ndop/primitives/label`). * * @example * ```html * <label ndLabel for="email">Email</label> * ``` */ @Directive({ selector: 'label[ndLabel]', hostDirectives: [{ directive: NdLabel, inputs: ['for'] }], host: { 'data-slot': 'label', '[class]': 'classes()' }, }) export class Label { /** Extra classes, merged last so they win. */ readonly class = input(''); protected readonly classes = computed(() => cn( 'flex items-center gap-2 text-sm leading-none font-medium select-none group-data-[disabled=true]:pointer-events-none group-data-[disabled=true]:opacity-50 peer-disabled:cursor-not-allowed peer-disabled:opacity-50', this.class(), ), ); }src/app/lib/utils.ts/** * Class helpers used by every styled item. They come from `@ndop/core`; * this file is yours, so it is the place to customize them, for example by * wrapping `cn` with an extended tailwind-merge configuration for your own * utilities. * * @packageDocumentation */ export { cn, variants, type ClassValue, type VariantOf } from '@ndop/core';Update the import paths to match your project
The files import each other through the
@/uiand@/libaliases.
Usage
import { Input } from '@/ui/input/input';
import { Label } from '@/ui/label/label';<div class="grid w-full max-w-sm gap-3">
<label ndLabel for="label-demo-name">Full name</label>
<input ndInput id="label-demo-name" placeholder="Ada Lovelace" />
</div>Examples
Label disabled
A label that dims with its disabled input.
import { Component } from '@angular/core';
import { Input } from '@/ui/input/input';
import { Label } from '@/ui/label/label';
/** A label that dims with its disabled input. */
@Component({
selector: 'example-label-disabled',
imports: [Label, Input],
template: `
<div class="grid w-full max-w-sm gap-3">
<label ndLabel for="label-disabled-plan">Plan</label>
<input ndInput id="label-disabled-plan" value="Team" disabled />
</div>
`,
})
export class LabelDisabledExample {}
Accessibility
Focus
- Clicking the label moves focus to the associated control (native behavior, unchanged).
Right-to-left
Nothing mirrors.
API reference
Label
label[ndLabel]Styled label. Names its control natively through for, and mirrors an
input[ndInput]'s disabled and invalid state (@ndop/primitives/label).
| Label binding | Type | Default |
|---|---|---|
[class]Extra classes, merged last so they win. | string | '' |
[for]Id of the labelled control. | string | undefined | — |
| Data attribute | Values |
|---|---|
data-slot | label |
data-disabled | — |
data-invalid | — |
Agent notes
Do
- Give every input a visible label, and point its
forat the input'sid. - Keep labels short: name the value, and put instructions in a description linked with
aria-describedby.
Don't
- Don't use placeholder text instead of a label; it disappears as soon as someone types.
- Don't style a
divorspanas a label; only a nativelabelnames its control.