@egose/shadcn-theme-ng 0.1.0 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/accordion/README.md +405 -2
- package/alert/README.md +372 -2
- package/alert-dialog/README.md +471 -5
- package/aspect-ratio/README.md +272 -5
- package/autocomplete/README.md +502 -2
- package/avatar/README.md +357 -5
- package/badge/README.md +318 -2
- package/basic-alert/README.md +353 -2
- package/breadcrumb/README.md +406 -5
- package/button/README.md +482 -2
- package/button/fesm2022/button.mjs +85 -107
- package/button/types/button.d.ts +5 -8
- package/button-group/README.md +318 -5
- package/calendar/README.md +357 -2
- package/card/README.md +331 -5
- package/carousel/README.md +333 -5
- package/carousel/fesm2022/carousel.mjs +4 -1
- package/checkbox/README.md +320 -2
- package/collapsible/README.md +332 -5
- package/combobox/README.md +507 -5
- package/combobox/fesm2022/combobox.mjs +4 -1
- package/command/README.md +435 -5
- package/confirmation-dialog/README.md +301 -2
- package/context-menu/README.md +366 -5
- package/date-picker/README.md +465 -2
- package/date-picker/fesm2022/date-picker.mjs +2 -2
- package/dialog/README.md +448 -2
- package/drawer/README.md +395 -5
- package/dropdown-menu/README.md +417 -5
- package/empty/README.md +329 -5
- package/field/README.md +385 -5
- package/form-checkbox/README.md +312 -2
- package/form-date-picker/README.md +322 -2
- package/form-field/README.md +356 -2
- package/form-field-simple/README.md +340 -2
- package/form-searchable-multiselect/README.md +361 -2
- package/form-select/README.md +350 -2
- package/form-text-input/README.md +371 -2
- package/form-textarea/README.md +347 -2
- package/hover-card/README.md +256 -5
- package/icon/README.md +239 -2
- package/input/README.md +269 -2
- package/input-group/README.md +335 -5
- package/input-group/fesm2022/input-group.mjs +3 -3
- package/input-otp/README.md +375 -5
- package/item/README.md +385 -5
- package/item/fesm2022/item.mjs +3 -3
- package/kbd/README.md +291 -5
- package/label/README.md +272 -2
- package/layout-simple/README.md +193 -2
- package/layout-simple/fesm2022/layout-simple.mjs +472 -236
- package/layout-simple/types/layout-simple.d.ts +174 -137
- package/menu/README.md +417 -2
- package/menubar/README.md +343 -5
- package/native-select/README.md +323 -5
- package/navigation-menu/README.md +369 -5
- package/package.json +1 -1
- package/pagination/README.md +388 -5
- package/popover/README.md +331 -2
- package/progress/README.md +311 -5
- package/radio-group/README.md +364 -2
- package/radio-group/fesm2022/radio-group.mjs +5 -1
- package/radio-group/types/radio-group.d.ts +1 -1
- package/resizable/README.md +269 -5
- package/scroll-area/README.md +233 -5
- package/searchable-multiselect/README.md +323 -2
- package/select/README.md +437 -2
- package/separator/README.md +222 -2
- package/sheet/README.md +311 -2
- package/sidebar/README.md +457 -5
- package/skeleton/README.md +217 -5
- package/slider/README.md +273 -5
- package/slider/fesm2022/slider.mjs +3 -3
- package/sonner/README.md +346 -2
- package/spinner/README.md +284 -2
- package/switch/README.md +310 -2
- package/table/README.md +423 -5
- package/tabs/README.md +411 -2
- package/tabs/fesm2022/tabs.mjs +2 -2
- package/textarea/README.md +282 -5
- package/toggle/README.md +270 -5
- package/toggle-group/README.md +340 -5
- package/tooltip/README.md +269 -2
- package/typography/README.md +271 -5
- package/typography/types/typography.d.ts +8 -8
- package/utils/README.md +303 -2
package/kbd/README.md
CHANGED
|
@@ -1,11 +1,297 @@
|
|
|
1
|
-
# Kbd
|
|
1
|
+
# Kbd (`@egose/shadcn-theme-ng/kbd`)
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Keyboard-keycap (`<kbd>`) styling for shortcut hints, ported from shadcn/ui `kbd`. There is no interactive primitive underneath — these are thin presentational directives that attach the shadcn keycap look (muted background, fixed `h-5` height, rounded, mono-adjacent `text-xs` label) plus a grouping row directive for multi-key chords such as `Ctrl + K`.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
Ships as `@egose/shadcn-theme-ng/kbd` and `@egose/shadcn-theme-ng-tw/kbd` (tw: variant). See the [package README](../../README.md) for installation, peer dependencies, Tailwind setup, and testing. Do not publish this project directory independently.
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
## Installation
|
|
8
8
|
|
|
9
9
|
```bash
|
|
10
|
-
|
|
10
|
+
# Plain Tailwind (no prefix):
|
|
11
|
+
npm install @egose/shadcn-theme-ng
|
|
12
|
+
|
|
13
|
+
# Or the tw:-prefixed variant:
|
|
14
|
+
npm install @egose/shadcn-theme-ng-tw
|
|
11
15
|
```
|
|
16
|
+
|
|
17
|
+
Peer dependencies are inherited from the package root (see [package README](../../README.md) — `@angular/core`, `@angular/common`, `@spartan-ng/brain`, `rxjs`, `@ng-icons/core`). This subpath itself declares `@angular/common`, `@angular/core`, `@spartan-ng/brain` as peers plus a `tslib` runtime dependency. No extra install step is needed beyond the package install above.
|
|
18
|
+
|
|
19
|
+
## Imports
|
|
20
|
+
|
|
21
|
+
Real exported symbols (from `src/public-api.ts`):
|
|
22
|
+
|
|
23
|
+
```ts
|
|
24
|
+
import {
|
|
25
|
+
HlmKbd, // directive: kbd[hlmKbd]
|
|
26
|
+
HlmKbdGroup, // directive: kbd[hlmKbdGroup]
|
|
27
|
+
HlmKbdImports, // readonly [HlmKbd, HlmKbdGroup]
|
|
28
|
+
HlmKbdModule, // NgModule wrapping HlmKbdImports
|
|
29
|
+
} from '@egose/shadcn-theme-ng/kbd';
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
Standalone usage:
|
|
33
|
+
|
|
34
|
+
```ts
|
|
35
|
+
import { Component } from '@angular/core';
|
|
36
|
+
import { HlmKbdImports } from '@egose/shadcn-theme-ng/kbd';
|
|
37
|
+
|
|
38
|
+
@Component({
|
|
39
|
+
selector: 'app-demo',
|
|
40
|
+
standalone: true,
|
|
41
|
+
imports: [...HlmKbdImports],
|
|
42
|
+
template: `<kbd hlmKbd>⌘</kbd>`,
|
|
43
|
+
})
|
|
44
|
+
export class DemoComponent {}
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
NgModule usage:
|
|
48
|
+
|
|
49
|
+
```ts
|
|
50
|
+
import { NgModule } from '@angular/core';
|
|
51
|
+
import { HlmKbdModule } from '@egose/shadcn-theme-ng/kbd';
|
|
52
|
+
|
|
53
|
+
@NgModule({ imports: [HlmKbdModule] })
|
|
54
|
+
export class DemoModule {}
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
For the `tw:` build, swap the specifier to `@egose/shadcn-theme-ng-tw/kbd`. Symbol names are identical.
|
|
58
|
+
|
|
59
|
+
## Anatomy / Structure
|
|
60
|
+
|
|
61
|
+
```html
|
|
62
|
+
<!-- Single key -->
|
|
63
|
+
<kbd hlmKbd>Ctrl</kbd>
|
|
64
|
+
|
|
65
|
+
<!-- Chord / sequence: outer kbd carries the group layout, inner kbds carry keycap styling -->
|
|
66
|
+
<kbd hlmKbdGroup>
|
|
67
|
+
<kbd hlmKbd>Ctrl</kbd>
|
|
68
|
+
<span>+</span>
|
|
69
|
+
<kbd hlmKbd>K</kbd>
|
|
70
|
+
</kbd hlmKbdGroup>
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
| Class | Selector | Element | Role |
|
|
74
|
+
| ------------- | ------------------ | ------------ | ------------------------------------- |
|
|
75
|
+
| `HlmKbd` | `kbd[hlmKbd]` | `<kbd>` only | Single keycap |
|
|
76
|
+
| `HlmKbdGroup` | `kbd[hlmKbdGroup]` | `<kbd>` only | Inline-flex row that lays out a chord |
|
|
77
|
+
|
|
78
|
+
Both selectors require a native `<kbd>` host. Applying `hlmKbd` to a `<span>` or `<div>` will not match and no styles are applied. Both set a `data-slot` host attribute (`kbd` / `kbd-group`) used by downstream tooltip overrides.
|
|
79
|
+
|
|
80
|
+
## API reference
|
|
81
|
+
|
|
82
|
+
Neither directive declares any `input()`, `output()`, method, or signal. They are pure styling directives: the constructor calls `classes(() => '…')` from `@egose/shadcn-theme-ng/utils`. All customization is via the host element itself (text content, `class`, `title`, `aria-*`).
|
|
83
|
+
|
|
84
|
+
| Selector | Inputs | Outputs | Notes |
|
|
85
|
+
| ------------------ | ------ | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
86
|
+
| `kbd[hlmKbd]` | — | — | `data-slot="kbd"`. Fixed keycap treatment: `h-5 w-fit min-w-5`, `rounded-sm`, `bg-muted text-muted-foreground`, `pointer-events-none select-none`, inline-flex centered. Includes `in-data-[slot=tooltip-content]` overrides so keys stay legible inside tooltips (light and dark). Icon sizing rule `[&_ng-icon:not([class*='text-'])]:text-[length:--spacing(3)]` normalizes bare `ng-icon` children. |
|
|
87
|
+
| `kbd[hlmKbdGroup]` | — | — | `data-slot="kbd-group"`. `inline-flex items-center gap-1`. Nest `HlmKbd` keycaps plus literal separators inside. |
|
|
88
|
+
|
|
89
|
+
## Examples
|
|
90
|
+
|
|
91
|
+
### 1. Basic single key
|
|
92
|
+
|
|
93
|
+
A lone keycap next to an action label.
|
|
94
|
+
|
|
95
|
+
```ts
|
|
96
|
+
import { Component } from '@angular/core';
|
|
97
|
+
import { HlmKbdImports } from '@egose/shadcn-theme-ng/kbd';
|
|
98
|
+
|
|
99
|
+
@Component({
|
|
100
|
+
selector: 'app-kbd-basic',
|
|
101
|
+
standalone: true,
|
|
102
|
+
imports: [...HlmKbdImports],
|
|
103
|
+
template: ` <p>Press <kbd hlmKbd>Enter</kbd> to submit.</p> `,
|
|
104
|
+
})
|
|
105
|
+
export class KbdBasicComponent {}
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
```html
|
|
109
|
+
<p>Press <kbd hlmKbd>Enter</kbd> to submit.</p>
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
### 2. Keyboard chord (Ctrl + K)
|
|
113
|
+
|
|
114
|
+
The canonical command-palette hint. The outer `kbd[hlmKbdGroup]` provides the row; inner keycaps provide the boxes.
|
|
115
|
+
|
|
116
|
+
```ts
|
|
117
|
+
import { Component } from '@angular/core';
|
|
118
|
+
import { HlmKbdImports } from '@egose/shadcn-theme-ng/kbd';
|
|
119
|
+
|
|
120
|
+
@Component({
|
|
121
|
+
selector: 'app-kbd-chord',
|
|
122
|
+
standalone: true,
|
|
123
|
+
imports: [...HlmKbdImports],
|
|
124
|
+
template: `
|
|
125
|
+
<div class="tw:flex tw:items-center tw:gap-2 tw:text-sm tw:text-muted-foreground">
|
|
126
|
+
<span>Search</span>
|
|
127
|
+
<kbd hlmKbdGroup>
|
|
128
|
+
<kbd hlmKbd>Ctrl</kbd>
|
|
129
|
+
<span>+</span>
|
|
130
|
+
<kbd hlmKbd>K</kbd>
|
|
131
|
+
</kbd>
|
|
132
|
+
</div>
|
|
133
|
+
`,
|
|
134
|
+
})
|
|
135
|
+
export class KbdChordComponent {}
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
```html
|
|
139
|
+
<div class="tw:flex tw:items-center tw:gap-2 tw:text-sm tw:text-muted-foreground">
|
|
140
|
+
<span>Search</span>
|
|
141
|
+
<kbd hlmKbdGroup>
|
|
142
|
+
<kbd hlmKbd>Ctrl</kbd>
|
|
143
|
+
<span>+</span>
|
|
144
|
+
<kbd hlmKbd>K</kbd>
|
|
145
|
+
</kbd>
|
|
146
|
+
</div>
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
### 3. macOS-style symbols and sequences
|
|
150
|
+
|
|
151
|
+
```ts
|
|
152
|
+
import { Component } from '@angular/core';
|
|
153
|
+
import { HlmKbdImports } from '@egose/shadcn-theme-ng/kbd';
|
|
154
|
+
|
|
155
|
+
@Component({
|
|
156
|
+
selector: 'app-kbd-symbols',
|
|
157
|
+
standalone: true,
|
|
158
|
+
imports: [...HlmKbdImports],
|
|
159
|
+
template: `
|
|
160
|
+
<ul class="tw:flex tw:flex-col tw:gap-2 tw:text-sm">
|
|
161
|
+
<li class="tw:flex tw:items-center tw:gap-2">
|
|
162
|
+
<span class="tw:w-32">Copy</span>
|
|
163
|
+
<kbd hlmKbdGroup><kbd hlmKbd>⌘</kbd><span>+</span><kbd hlmKbd>C</kbd></kbd>
|
|
164
|
+
</li>
|
|
165
|
+
<li class="tw:flex tw:items-center tw:gap-2">
|
|
166
|
+
<span class="tw:w-32">Save</span>
|
|
167
|
+
<kbd hlmKbdGroup><kbd hlmKbd>⌘</kbd><span>+</span><kbd hlmKbd>S</kbd></kbd>
|
|
168
|
+
</li>
|
|
169
|
+
<li class="tw:flex tw:items-center tw:gap-2">
|
|
170
|
+
<span class="tw:w-32">Close window</span>
|
|
171
|
+
<kbd hlmKbdGroup>
|
|
172
|
+
<kbd hlmKbd>⌘</kbd><span>+</span><kbd hlmKbd>Shift</kbd><span>+</span><kbd hlmKbd>W</kbd>
|
|
173
|
+
</kbd>
|
|
174
|
+
</li>
|
|
175
|
+
</ul>
|
|
176
|
+
`,
|
|
177
|
+
})
|
|
178
|
+
export class KbdSymbolsComponent {}
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
### 4. Inside buttons, inputs, and menus
|
|
182
|
+
|
|
183
|
+
Keycaps are `pointer-events-none`, so they compose safely inside interactive parents.
|
|
184
|
+
|
|
185
|
+
```ts
|
|
186
|
+
import { Component } from '@angular/core';
|
|
187
|
+
import { HlmKbdImports } from '@egose/shadcn-theme-ng/kbd';
|
|
188
|
+
import { HlmButtonImports } from '@egose/shadcn-theme-ng/button';
|
|
189
|
+
import { HlmInput } from '@egose/shadcn-theme-ng/input';
|
|
190
|
+
|
|
191
|
+
@Component({
|
|
192
|
+
selector: 'app-kbd-composed',
|
|
193
|
+
standalone: true,
|
|
194
|
+
imports: [...HlmKbdImports, ...HlmButtonImports, HlmInput],
|
|
195
|
+
template: `
|
|
196
|
+
<div class="tw:flex tw:flex-col tw:gap-3 tw:max-w-sm">
|
|
197
|
+
<button hlmButton variant="secondary" appearance="outline" type="button">
|
|
198
|
+
<span>Command palette</span>
|
|
199
|
+
<kbd hlmKbdGroup class="tw:ml-auto">
|
|
200
|
+
<kbd hlmKbd>Ctrl</kbd>
|
|
201
|
+
<span>+</span>
|
|
202
|
+
<kbd hlmKbd>K</kbd>
|
|
203
|
+
</kbd>
|
|
204
|
+
</button>
|
|
205
|
+
|
|
206
|
+
<label class="tw:flex tw:flex-col tw:gap-1 tw:text-sm">
|
|
207
|
+
<span class="tw:flex tw:items-center tw:gap-2"> Search <kbd hlmKbd>/</kbd> </span>
|
|
208
|
+
<input hlmInput placeholder="Type here, or press / to focus" />
|
|
209
|
+
</label>
|
|
210
|
+
</div>
|
|
211
|
+
`,
|
|
212
|
+
})
|
|
213
|
+
export class KbdComposedComponent {}
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
### 5. Shortcut legend / settings table
|
|
217
|
+
|
|
218
|
+
```ts
|
|
219
|
+
import { Component, signal } from '@angular/core';
|
|
220
|
+
import { HlmKbdImports } from '@egose/shadcn-theme-ng/kbd';
|
|
221
|
+
|
|
222
|
+
interface Shortcut {
|
|
223
|
+
action: string;
|
|
224
|
+
keys: string[];
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
@Component({
|
|
228
|
+
selector: 'app-kbd-legend',
|
|
229
|
+
standalone: true,
|
|
230
|
+
imports: [...HlmKbdImports],
|
|
231
|
+
template: `
|
|
232
|
+
<table class="tw:w-full tw:text-sm">
|
|
233
|
+
<tbody>
|
|
234
|
+
@for (s of shortcuts(); track s.action) {
|
|
235
|
+
<tr class="tw:border-b">
|
|
236
|
+
<td class="tw:py-2">{{ s.action }}</td>
|
|
237
|
+
<td class="tw:py-2 tw:text-right">
|
|
238
|
+
<kbd hlmKbdGroup class="tw:justify-end">
|
|
239
|
+
@for (k of s.keys; track k; let last = $last) {
|
|
240
|
+
<kbd hlmKbd>{{ k }}</kbd>
|
|
241
|
+
@if (!last) {
|
|
242
|
+
<span>+</span>
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
</kbd>
|
|
246
|
+
</td>
|
|
247
|
+
</tr>
|
|
248
|
+
}
|
|
249
|
+
</tbody>
|
|
250
|
+
</table>
|
|
251
|
+
`,
|
|
252
|
+
})
|
|
253
|
+
export class KbdLegendComponent {
|
|
254
|
+
readonly shortcuts = signal<Shortcut[]>([
|
|
255
|
+
{ action: 'Undo', keys: ['Ctrl', 'Z'] },
|
|
256
|
+
{ action: 'Redo', keys: ['Ctrl', 'Shift', 'Z'] },
|
|
257
|
+
{ action: 'Toggle sidebar', keys: ['Ctrl', 'B'] },
|
|
258
|
+
]);
|
|
259
|
+
}
|
|
260
|
+
```
|
|
261
|
+
|
|
262
|
+
### 6. NgModule consumer
|
|
263
|
+
|
|
264
|
+
```ts
|
|
265
|
+
import { NgModule, Component } from '@angular/core';
|
|
266
|
+
import { HlmKbdModule } from '@egose/shadcn-theme-ng/kbd';
|
|
267
|
+
|
|
268
|
+
@Component({
|
|
269
|
+
selector: 'app-kbd-legacy',
|
|
270
|
+
template: `<kbd hlmKbd>Esc</kbd> to close.`,
|
|
271
|
+
})
|
|
272
|
+
export class KbdLegacyComponent {}
|
|
273
|
+
|
|
274
|
+
@NgModule({
|
|
275
|
+
declarations: [KbdLegacyComponent],
|
|
276
|
+
imports: [HlmKbdModule],
|
|
277
|
+
exports: [KbdLegacyComponent],
|
|
278
|
+
})
|
|
279
|
+
export class KbdLegacyModule {}
|
|
280
|
+
```
|
|
281
|
+
|
|
282
|
+
## Accessibility notes
|
|
283
|
+
|
|
284
|
+
- `<kbd>` is natively semantic ("keyboard input"). Keep the text content exactly what the user presses (`Ctrl`, not `Control` unless that is the label on the keyboard).
|
|
285
|
+
- For chords, screen readers linearize the group content; the `+` separators are announced. If verbosity matters, add an `aria-label` on the group (e.g. `aria-label="Control plus K"`) — plain HTML, no library input needed.
|
|
286
|
+
- Do not put interactive content inside a keycap: `HlmKbd` is `pointer-events-none` by design.
|
|
287
|
+
- `title`/`aria-keyshortcuts` belong on the _action_ that the shortcut triggers (e.g. the button), not on the `<kbd>` itself.
|
|
288
|
+
|
|
289
|
+
## Theming / CSS variables
|
|
290
|
+
|
|
291
|
+
No component inputs. Styling keys off shadcn semantic tokens (`bg-muted`, `text-muted-foreground`, `bg-background` inside tooltip content) so dark mode and theme overrides flow through automatically. Add extra utilities via `class` on the host `<kbd>` (merged by the `classes()` helper).
|
|
292
|
+
|
|
293
|
+
## Related subpaths
|
|
294
|
+
|
|
295
|
+
- `@egose/shadcn-theme-ng/tooltip` — keycaps render legibly inside tooltip content via the built-in `in-data-[slot=tooltip-content]` overrides.
|
|
296
|
+
- `@egose/shadcn-theme-ng/menu` (`HlmMenuShortcut`) — right-aligned shortcut column inside menus; use `kbd` keycaps inside it for key chords.
|
|
297
|
+
- `@egose/shadcn-theme-ng/button`, `@egose/shadcn-theme-ng/input` — common parents for inline shortcut hints.
|
package/label/README.md
CHANGED
|
@@ -1,3 +1,273 @@
|
|
|
1
|
-
# Label
|
|
1
|
+
# Label (`@egose/shadcn-theme-ng/label`)
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Form-field label ported from shadcn/ui `label` (Radix Label equivalent). A thin directive wrapper around the spartan-ng `BrnLabel` brain primitive: it forwards label semantics/association (`id`, `for`) to `BrnLabel` via host directives and adds the shadcn label treatment (small medium-weight text plus disabled-state dimming that reacts to `peer`/`group`/`has-[[disabled]]` context).
|
|
4
|
+
|
|
5
|
+
Ships as `@egose/shadcn-theme-ng/label` and `@egose/shadcn-theme-ng-tw/label` (tw: variant). See the [package README](../../README.md) for installation, peer dependencies, Tailwind setup, and testing. Do not publish this project directory independently.
|
|
6
|
+
|
|
7
|
+
## Installation
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
# Plain Tailwind (no prefix):
|
|
11
|
+
npm install @egose/shadcn-theme-ng
|
|
12
|
+
|
|
13
|
+
# Or the tw:-prefixed variant:
|
|
14
|
+
npm install @egose/shadcn-theme-ng-tw
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
Peer dependencies are inherited from the package root (see [package README](../../README.md)). This subpath itself declares `@angular/common`, `@angular/core`, `@spartan-ng/brain` as peers plus a `tslib` runtime dependency. No extra install step is needed beyond the package install above.
|
|
18
|
+
|
|
19
|
+
## Imports
|
|
20
|
+
|
|
21
|
+
Real exported symbols (from `src/public-api.ts`):
|
|
22
|
+
|
|
23
|
+
```ts
|
|
24
|
+
import {
|
|
25
|
+
HlmLabel, // directive: [hlmLabel]
|
|
26
|
+
HlmLabelImports, // readonly [HlmLabel]
|
|
27
|
+
HlmLabelModule, // NgModule wrapping HlmLabelImports
|
|
28
|
+
} from '@egose/shadcn-theme-ng/label';
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
Standalone usage:
|
|
32
|
+
|
|
33
|
+
```ts
|
|
34
|
+
import { Component } from '@angular/core';
|
|
35
|
+
import { HlmLabelImports } from '@egose/shadcn-theme-ng/label';
|
|
36
|
+
|
|
37
|
+
@Component({
|
|
38
|
+
selector: 'app-demo',
|
|
39
|
+
standalone: true,
|
|
40
|
+
imports: [...HlmLabelImports],
|
|
41
|
+
template: `<label hlmLabel for="email">Email</label>`,
|
|
42
|
+
})
|
|
43
|
+
export class DemoComponent {}
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
NgModule usage:
|
|
47
|
+
|
|
48
|
+
```ts
|
|
49
|
+
import { NgModule } from '@angular/core';
|
|
50
|
+
import { HlmLabelModule } from '@egose/shadcn-theme-ng/label';
|
|
51
|
+
|
|
52
|
+
@NgModule({ imports: [HlmLabelModule] })
|
|
53
|
+
export class DemoModule {}
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
For the `tw:` build, swap the specifier to `@egose/shadcn-theme-ng-tw/label`. Symbol names are identical.
|
|
57
|
+
|
|
58
|
+
## Anatomy / Structure
|
|
59
|
+
|
|
60
|
+
```html
|
|
61
|
+
<label hlmLabel for="email">Email address</label>
|
|
62
|
+
<input hlmInput id="email" type="email" />
|
|
63
|
+
|
|
64
|
+
<!-- extra classes merge via class input -->
|
|
65
|
+
<label hlmLabel for="bio" class="tw:mb-2">Bio</label>
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
| Class | Selector | Element | Role |
|
|
69
|
+
| ---------- | ------------ | -------------------------------------- | --------------------------------- |
|
|
70
|
+
| `HlmLabel` | `[hlmLabel]` | any labelable host, normally `<label>` | Accessible label + shadcn styling |
|
|
71
|
+
|
|
72
|
+
`HlmLabel` declares `hostDirectives: [{ directive: BrnLabel, inputs: ['id', 'for'] }]`, so the `id` and `for` bindings you write on the host are forwarded to the brain directive that owns label association.
|
|
73
|
+
|
|
74
|
+
## API reference
|
|
75
|
+
|
|
76
|
+
### `HlmLabel` (`[hlmLabel]`)
|
|
77
|
+
|
|
78
|
+
| Member | Kind | Type / Default | Notes |
|
|
79
|
+
| --------------------- | ------------------------------------- | -------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
|
80
|
+
| `id` | input (via `BrnLabel` host directive) | `string` | Forwarded to `BrnLabel`. Rarely set on the label itself. |
|
|
81
|
+
| `for` | input (via `BrnLabel` host directive) | `string` | Forwarded to `BrnLabel`. Associates the label with the control whose `id` matches. |
|
|
82
|
+
| `userClass` (`class`) | input | `ClassValue`, default `''` | Extra Tailwind/classes merged after the base label classes via `hlm()`. |
|
|
83
|
+
| `_computedClass` | protected computed | `string` | Base: `flex select-none items-center gap-2 text-sm font-medium leading-none` plus disabled dimming: `peer-disabled:cursor-not-allowed peer-disabled:opacity-50`, `has-[[disabled]]:cursor-not-allowed has-[[disabled]]:opacity-50`, `group-data-[disabled=true]:pointer-events-none group-data-[disabled=true]:opacity-50`, `peer-data-[disabled]:cursor-not-allowed peer-data-[disabled]:opacity-50`. |
|
|
84
|
+
|
|
85
|
+
No outputs, methods, or signals beyond the inputs above.
|
|
86
|
+
|
|
87
|
+
## Examples
|
|
88
|
+
|
|
89
|
+
### 1. Basic label + input
|
|
90
|
+
|
|
91
|
+
```ts
|
|
92
|
+
import { Component } from '@angular/core';
|
|
93
|
+
import { HlmLabelImports } from '@egose/shadcn-theme-ng/label';
|
|
94
|
+
import { HlmInput } from '@egose/shadcn-theme-ng/input';
|
|
95
|
+
|
|
96
|
+
@Component({
|
|
97
|
+
selector: 'app-label-basic',
|
|
98
|
+
standalone: true,
|
|
99
|
+
imports: [...HlmLabelImports, HlmInput],
|
|
100
|
+
template: `
|
|
101
|
+
<div class="tw:grid tw:gap-1.5">
|
|
102
|
+
<label hlmLabel for="email">Email</label>
|
|
103
|
+
<input hlmInput id="email" type="email" placeholder="you@example.com" />
|
|
104
|
+
</div>
|
|
105
|
+
`,
|
|
106
|
+
})
|
|
107
|
+
export class LabelBasicComponent {}
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
```html
|
|
111
|
+
<div class="tw:grid tw:gap-1.5">
|
|
112
|
+
<label hlmLabel for="email">Email</label>
|
|
113
|
+
<input hlmInput id="email" type="email" placeholder="you@example.com" />
|
|
114
|
+
</div>
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
### 2. Required marker and hint text
|
|
118
|
+
|
|
119
|
+
```ts
|
|
120
|
+
import { Component } from '@angular/core';
|
|
121
|
+
import { HlmLabelImports } from '@egose/shadcn-theme-ng/label';
|
|
122
|
+
import { HlmInput } from '@egose/shadcn-theme-ng/input';
|
|
123
|
+
|
|
124
|
+
@Component({
|
|
125
|
+
selector: 'app-label-required',
|
|
126
|
+
standalone: true,
|
|
127
|
+
imports: [...HlmLabelImports, HlmInput],
|
|
128
|
+
template: `
|
|
129
|
+
<div class="tw:grid tw:gap-1.5">
|
|
130
|
+
<label hlmLabel for="username">
|
|
131
|
+
Username
|
|
132
|
+
<span aria-hidden="true" class="tw:text-destructive">*</span>
|
|
133
|
+
<span class="tw:sr-only">(required)</span>
|
|
134
|
+
</label>
|
|
135
|
+
<input hlmInput id="username" required minlength="3" placeholder="ada_lovelace" />
|
|
136
|
+
<p class="tw:text-xs tw:text-muted-foreground">Lowercase letters, numbers, underscores.</p>
|
|
137
|
+
</div>
|
|
138
|
+
`,
|
|
139
|
+
})
|
|
140
|
+
export class LabelRequiredComponent {}
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
### 3. Template-driven form
|
|
144
|
+
|
|
145
|
+
```ts
|
|
146
|
+
import { Component } from '@angular/core';
|
|
147
|
+
import { FormsModule } from '@angular/forms';
|
|
148
|
+
import { HlmLabelImports } from '@egose/shadcn-theme-ng/label';
|
|
149
|
+
import { HlmInput } from '@egose/shadcn-theme-ng/input';
|
|
150
|
+
|
|
151
|
+
@Component({
|
|
152
|
+
selector: 'app-label-template-driven',
|
|
153
|
+
standalone: true,
|
|
154
|
+
imports: [FormsModule, ...HlmLabelImports, HlmInput],
|
|
155
|
+
template: `
|
|
156
|
+
<form #f="ngForm" class="tw:grid tw:gap-4">
|
|
157
|
+
<div class="tw:grid tw:gap-1.5">
|
|
158
|
+
<label hlmLabel for="displayName">Display name</label>
|
|
159
|
+
<input hlmInput id="displayName" name="displayName" [(ngModel)]="name" required />
|
|
160
|
+
</div>
|
|
161
|
+
<p class="tw:text-sm tw:text-muted-foreground">Hello, {{ name || 'stranger' }}.</p>
|
|
162
|
+
</form>
|
|
163
|
+
`,
|
|
164
|
+
})
|
|
165
|
+
export class LabelTemplateDrivenComponent {
|
|
166
|
+
name = '';
|
|
167
|
+
}
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
### 4. Reactive form with disabled state
|
|
171
|
+
|
|
172
|
+
The label dims automatically when the associated control is a disabled `peer` (or inside a disabled group) thanks to the built-in `peer-disabled:` / `group-data-[disabled=true]:` rules.
|
|
173
|
+
|
|
174
|
+
```ts
|
|
175
|
+
import { Component } from '@angular/core';
|
|
176
|
+
import { ReactiveFormsModule, FormControl, FormGroup } from '@angular/forms';
|
|
177
|
+
import { HlmLabelImports } from '@egose/shadcn-theme-ng/label';
|
|
178
|
+
import { HlmInput } from '@egose/shadcn-theme-ng/input';
|
|
179
|
+
|
|
180
|
+
@Component({
|
|
181
|
+
selector: 'app-label-reactive',
|
|
182
|
+
standalone: true,
|
|
183
|
+
imports: [ReactiveFormsModule, ...HlmLabelImports, HlmInput],
|
|
184
|
+
template: `
|
|
185
|
+
<form [formGroup]="form" class="tw:grid tw:gap-4">
|
|
186
|
+
<div class="tw:grid tw:gap-1.5">
|
|
187
|
+
<label hlmLabel for="company">Company</label>
|
|
188
|
+
<input hlmInput id="company" class="tw:peer" formControlName="company" />
|
|
189
|
+
</div>
|
|
190
|
+
<label class="tw:flex tw:items-center tw:gap-2 tw:text-sm">
|
|
191
|
+
<input type="checkbox" (change)="toggleDisabled()" />
|
|
192
|
+
Disable company field
|
|
193
|
+
</label>
|
|
194
|
+
</form>
|
|
195
|
+
`,
|
|
196
|
+
})
|
|
197
|
+
export class LabelReactiveComponent {
|
|
198
|
+
readonly form = new FormGroup({
|
|
199
|
+
company: new FormControl({ value: 'Acme', disabled: false }),
|
|
200
|
+
});
|
|
201
|
+
|
|
202
|
+
toggleDisabled(): void {
|
|
203
|
+
const control = this.form.controls.company;
|
|
204
|
+
control.disabled ? control.enable() : control.disable();
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
> Add `class="tw:peer"` to the input so the label's `peer-disabled:` rule can observe it. Without the `peer` class the label still dims via the `has-[[disabled]]` fallback when the control is nested in the same wrapper.
|
|
210
|
+
|
|
211
|
+
### 5. Checkbox / switch labels and custom spacing
|
|
212
|
+
|
|
213
|
+
```ts
|
|
214
|
+
import { Component } from '@angular/core';
|
|
215
|
+
import { HlmLabelImports } from '@egose/shadcn-theme-ng/label';
|
|
216
|
+
import { HlmCheckbox } from '@egose/shadcn-theme-ng/checkbox';
|
|
217
|
+
import { HlmSwitch } from '@egose/shadcn-theme-ng/switch';
|
|
218
|
+
|
|
219
|
+
@Component({
|
|
220
|
+
selector: 'app-label-checks',
|
|
221
|
+
standalone: true,
|
|
222
|
+
imports: [...HlmLabelImports, HlmCheckbox, HlmSwitch],
|
|
223
|
+
template: `
|
|
224
|
+
<div class="tw:flex tw:flex-col tw:gap-4">
|
|
225
|
+
<div class="tw:flex tw:items-center tw:gap-2">
|
|
226
|
+
<hlm-checkbox id="marketing" />
|
|
227
|
+
<label hlmLabel for="marketing" class="tw:cursor-pointer">Email me product news</label>
|
|
228
|
+
</div>
|
|
229
|
+
<div class="tw:flex tw:items-center tw:gap-2">
|
|
230
|
+
<hlm-switch id="notifications" />
|
|
231
|
+
<label hlmLabel for="notifications">Push notifications</label>
|
|
232
|
+
</div>
|
|
233
|
+
</div>
|
|
234
|
+
`,
|
|
235
|
+
})
|
|
236
|
+
export class LabelChecksComponent {}
|
|
237
|
+
```
|
|
238
|
+
|
|
239
|
+
### 6. NgModule consumer
|
|
240
|
+
|
|
241
|
+
```ts
|
|
242
|
+
import { NgModule, Component } from '@angular/core';
|
|
243
|
+
import { HlmLabelModule } from '@egose/shadcn-theme-ng/label';
|
|
244
|
+
|
|
245
|
+
@Component({
|
|
246
|
+
selector: 'app-label-legacy',
|
|
247
|
+
template: `<label hlmLabel for="city">City</label>`,
|
|
248
|
+
})
|
|
249
|
+
export class LabelLegacyComponent {}
|
|
250
|
+
|
|
251
|
+
@NgModule({
|
|
252
|
+
declarations: [LabelLegacyComponent],
|
|
253
|
+
imports: [HlmLabelModule],
|
|
254
|
+
exports: [LabelLegacyComponent],
|
|
255
|
+
})
|
|
256
|
+
export class LabelLegacyModule {}
|
|
257
|
+
```
|
|
258
|
+
|
|
259
|
+
## Accessibility notes
|
|
260
|
+
|
|
261
|
+
- Always pair `for` with the control's `id` (or nest the control inside the `<label>`). The `for` binding is forwarded to `BrnLabel`, which owns the association semantics.
|
|
262
|
+
- Keep label text visible and concise; use `aria-hidden` + `sr-only` for decorative markers like `*` (see example 2).
|
|
263
|
+
- Do not use `placeholder` as a label substitute — the shadcn label treatment assumes a real `<label>` element.
|
|
264
|
+
- The disabled dimming is visual only; disable the control itself (`disabled` attribute / `FormControl.disable()`) so assistive tech reports the state.
|
|
265
|
+
|
|
266
|
+
## Theming / CSS variables
|
|
267
|
+
|
|
268
|
+
No theming inputs. The label inherits `text-sm font-medium` and theme tokens automatically; pass extra utilities via `class` (merged by `hlm()` after the base classes, so yours win on conflict).
|
|
269
|
+
|
|
270
|
+
## Related subpaths
|
|
271
|
+
|
|
272
|
+
- `@egose/shadcn-theme-ng/input`, `@egose/shadcn-theme-ng/textarea`, `@egose/shadcn-theme-ng/checkbox`, `@egose/shadcn-theme-ng/switch` — controls that `for`/`id` pairs target.
|
|
273
|
+
- `@egose/shadcn-theme-ng/form-field`, `@egose/shadcn-theme-ng/form-field-simple` — higher-level field wrappers that compose labels with errors and hints.
|