@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/table/README.md
CHANGED
|
@@ -1,11 +1,429 @@
|
|
|
1
|
-
# Table
|
|
1
|
+
# Table (`@egose/shadcn-theme-ng/table`)
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
A data table, equivalent to [shadcn/ui Table](https://ui.shadcn.com/docs/components/table). This subpath ships nine **thin styling directives** — no behavior, no spartan-ng primitive, no inputs/outputs. Apply them to native `<div>`/`<table>`/`<thead>`/`<tbody>`/`<tfoot>`/`<tr>`/`<th>`/`<td>`/`<caption>` elements to get shadcn table styling (hover rows, muted header/footer, compact cells) while keeping fully semantic markup you control.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
> **Ships as:** `@egose/shadcn-theme-ng/table` and `@egose/shadcn-theme-ng-tw/table` (the `tw:`-prefixed Tailwind variant). See the [package README](../../README.md) for install steps, peer dependencies, Tailwind setup, and testing/release guidance. 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
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
No extra runtime dependencies. See the [package README](../../README.md) for the peer-dependency table.
|
|
18
|
+
|
|
19
|
+
## Imports
|
|
20
|
+
|
|
21
|
+
All public symbols are re-exported from `projects/table/src/public-api.ts`:
|
|
22
|
+
|
|
23
|
+
```ts
|
|
24
|
+
import {
|
|
25
|
+
HlmCaption,
|
|
26
|
+
HlmTable,
|
|
27
|
+
HlmTableContainer,
|
|
28
|
+
HlmTBody,
|
|
29
|
+
HlmTableImports,
|
|
30
|
+
HlmTableModule,
|
|
31
|
+
HlmTd,
|
|
32
|
+
HlmTFoot,
|
|
33
|
+
HlmTh,
|
|
34
|
+
HlmTHead,
|
|
35
|
+
HlmTr,
|
|
36
|
+
} from '@egose/shadcn-theme-ng/table';
|
|
37
|
+
// tw variant: swap to '@egose/shadcn-theme-ng-tw/table'
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
Standalone-component usage (preferred):
|
|
41
|
+
|
|
42
|
+
```ts
|
|
43
|
+
import { Component } from '@angular/core';
|
|
44
|
+
import { HlmTableImports } from '@egose/shadcn-theme-ng/table';
|
|
45
|
+
|
|
46
|
+
@Component({
|
|
47
|
+
selector: 'app-demo',
|
|
48
|
+
standalone: true,
|
|
49
|
+
imports: [...HlmTableImports],
|
|
50
|
+
template: `<!-- table markup here -->`,
|
|
51
|
+
})
|
|
52
|
+
export class DemoComponent {}
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
NgModule usage:
|
|
56
|
+
|
|
57
|
+
```ts
|
|
58
|
+
import { NgModule } from '@angular/core';
|
|
59
|
+
import { HlmTableModule } from '@egose/shadcn-theme-ng/table';
|
|
60
|
+
|
|
61
|
+
@NgModule({ imports: [HlmTableModule] })
|
|
62
|
+
export class FeatureModule {}
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
| Symbol | Kind | Host selector (real) |
|
|
66
|
+
| ------------------- | ------------- | --------------------------------------------------------------------------------------- |
|
|
67
|
+
| `HlmTableContainer` | Directive | `div[hlmTableContainer]` |
|
|
68
|
+
| `HlmTable` | Directive | `table[hlmTable]` |
|
|
69
|
+
| `HlmTHead` | Directive | `thead[hlmTHead], thead[hlmTableHeader]` |
|
|
70
|
+
| `HlmTBody` | Directive | `tbody[hlmTBody], tbody[hlmTableBody]` |
|
|
71
|
+
| `HlmTFoot` | Directive | `tfoot[hlmTFoot], tfoot[hlmTableFooter]` |
|
|
72
|
+
| `HlmTr` | Directive | `tr[hlmTr], tr[hlmTableRow]` |
|
|
73
|
+
| `HlmTh` | Directive | `th[hlmTh], th[hlmTableHead]` |
|
|
74
|
+
| `HlmTd` | Directive | `td[hlmTd], td[hlmTableCell]` |
|
|
75
|
+
| `HlmCaption` | Directive | `caption[hlmCaption], caption[hlmTableCaption]` |
|
|
76
|
+
| `HlmTableImports` | `const` array | All nine directives, in caption/container/table/body/cell/footer/head/header/row order. |
|
|
77
|
+
| `HlmTableModule` | NgModule | Imports + re-exports all nine directives. |
|
|
78
|
+
|
|
79
|
+
## Anatomy / Structure
|
|
80
|
+
|
|
81
|
+
```html
|
|
82
|
+
<div hlmTableContainer>
|
|
83
|
+
<table hlmTable>
|
|
84
|
+
<caption hlmCaption>
|
|
85
|
+
A list of recent invoices.
|
|
86
|
+
</caption>
|
|
87
|
+
<thead hlmTHead>
|
|
88
|
+
<tr hlmTr>
|
|
89
|
+
<th hlmTh>Invoice</th>
|
|
90
|
+
<th hlmTh>Status</th>
|
|
91
|
+
<th hlmTh>Method</th>
|
|
92
|
+
<th hlmTh class="text-right">Amount</th>
|
|
93
|
+
</tr>
|
|
94
|
+
</thead>
|
|
95
|
+
<tbody hlmTBody>
|
|
96
|
+
<tr hlmTr>
|
|
97
|
+
<td hlmTd>INV001</td>
|
|
98
|
+
<td hlmTd>Paid</td>
|
|
99
|
+
<td hlmTd>Card</td>
|
|
100
|
+
<td hlmTd class="text-right">$250.00</td>
|
|
101
|
+
</tr>
|
|
102
|
+
</tbody>
|
|
103
|
+
<tfoot hlmTFoot>
|
|
104
|
+
<tr hlmTr>
|
|
105
|
+
<td hlmTd colspan="3">Total</td>
|
|
106
|
+
<td hlmTd class="text-right">$250.00</td>
|
|
107
|
+
</tr>
|
|
108
|
+
</tfoot>
|
|
109
|
+
</table>
|
|
110
|
+
</div>
|
|
11
111
|
```
|
|
112
|
+
|
|
113
|
+
Each element also accepts the long alias (`hlmTableHeader`, `hlmTableBody`, `hlmTableFooter`, `hlmTableRow`, `hlmTableHead`, `hlmTableCell`, `hlmTableCaption`) — use whichever reads better; both selectors apply identical styles and `data-slot` attributes.
|
|
114
|
+
|
|
115
|
+
## API reference
|
|
116
|
+
|
|
117
|
+
There are **no inputs, outputs, or methods** on any table directive. Each directive only merges a fixed class list via `classes()` and sets a `data-slot` host attribute:
|
|
118
|
+
|
|
119
|
+
| Directive | `data-slot` | Fixed classes (abridged) |
|
|
120
|
+
| ---------------------------------------------- | ----------------- | ----------------------------------------------------------------------------------- |
|
|
121
|
+
| `HlmTableContainer` (`div[hlmTableContainer]`) | `table-container` | `relative w-full overflow-x-auto` |
|
|
122
|
+
| `HlmTable` (`table[hlmTable]`) | `table` | `w-full caption-bottom text-sm` |
|
|
123
|
+
| `HlmTHead` | `table-header` | `[&_tr]:border-b` |
|
|
124
|
+
| `HlmTBody` | `table-body` | `[&_tr:last-child]:border-0` |
|
|
125
|
+
| `HlmTFoot` | `table-footer` | `bg-muted/50 border-t font-medium …` |
|
|
126
|
+
| `HlmTr` | `table-row` | `hover:bg-muted/50 data-[state=selected]:bg-muted border-b transition-colors …` |
|
|
127
|
+
| `HlmTh` | `table-head` | `text-foreground h-10 px-2 text-start align-middle font-medium whitespace-nowrap …` |
|
|
128
|
+
| `HlmTd` | `table-cell` | `p-2 align-middle whitespace-nowrap …` |
|
|
129
|
+
| `HlmCaption` | `table-caption` | `text-muted-foreground mt-4 text-sm` |
|
|
130
|
+
|
|
131
|
+
User `class` attributes on the same element are preserved and merged (the `classes()` helper keeps base classes).
|
|
132
|
+
|
|
133
|
+
## Examples
|
|
134
|
+
|
|
135
|
+
### 1. Basic invoice table
|
|
136
|
+
|
|
137
|
+
```ts
|
|
138
|
+
// demo-basic.component.ts
|
|
139
|
+
import { Component } from '@angular/core';
|
|
140
|
+
import { HlmTableImports } from '@egose/shadcn-theme-ng/table';
|
|
141
|
+
|
|
142
|
+
@Component({
|
|
143
|
+
selector: 'demo-basic',
|
|
144
|
+
standalone: true,
|
|
145
|
+
imports: [...HlmTableImports],
|
|
146
|
+
template: `
|
|
147
|
+
<div hlmTableContainer>
|
|
148
|
+
<table hlmTable>
|
|
149
|
+
<caption hlmCaption>
|
|
150
|
+
A list of your recent invoices.
|
|
151
|
+
</caption>
|
|
152
|
+
<thead hlmTHead>
|
|
153
|
+
<tr hlmTr>
|
|
154
|
+
<th hlmTh>Invoice</th>
|
|
155
|
+
<th hlmTh>Status</th>
|
|
156
|
+
<th hlmTh>Method</th>
|
|
157
|
+
<th hlmTh class="text-right">Amount</th>
|
|
158
|
+
</tr>
|
|
159
|
+
</thead>
|
|
160
|
+
<tbody hlmTBody>
|
|
161
|
+
<tr hlmTr>
|
|
162
|
+
<td hlmTd class="font-medium">INV001</td>
|
|
163
|
+
<td hlmTd>Paid</td>
|
|
164
|
+
<td hlmTd>Credit Card</td>
|
|
165
|
+
<td hlmTd class="text-right">$250.00</td>
|
|
166
|
+
</tr>
|
|
167
|
+
<tr hlmTr>
|
|
168
|
+
<td hlmTd class="font-medium">INV002</td>
|
|
169
|
+
<td hlmTd>Pending</td>
|
|
170
|
+
<td hlmTd>PayPal</td>
|
|
171
|
+
<td hlmTd class="text-right">$150.00</td>
|
|
172
|
+
</tr>
|
|
173
|
+
</tbody>
|
|
174
|
+
<tfoot hlmTFoot>
|
|
175
|
+
<tr hlmTr>
|
|
176
|
+
<td hlmTd colspan="3">Total</td>
|
|
177
|
+
<td hlmTd class="text-right">$400.00</td>
|
|
178
|
+
</tr>
|
|
179
|
+
</tfoot>
|
|
180
|
+
</table>
|
|
181
|
+
</div>
|
|
182
|
+
`,
|
|
183
|
+
})
|
|
184
|
+
export class DemoBasic {}
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
### 2. Async data with loading / empty states
|
|
188
|
+
|
|
189
|
+
```ts
|
|
190
|
+
// demo-async.component.ts
|
|
191
|
+
import { Component, inject, signal } from '@angular/core';
|
|
192
|
+
import { HttpClient } from '@angular/common/http';
|
|
193
|
+
import { HlmTableImports } from '@egose/shadcn-theme-ng/table';
|
|
194
|
+
import { HlmSpinnerImports } from '@egose/shadcn-theme-ng/spinner';
|
|
195
|
+
|
|
196
|
+
interface Invoice {
|
|
197
|
+
id: string;
|
|
198
|
+
status: string;
|
|
199
|
+
method: string;
|
|
200
|
+
amount: number;
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
@Component({
|
|
204
|
+
selector: 'demo-async',
|
|
205
|
+
standalone: true,
|
|
206
|
+
imports: [...HlmTableImports, ...HlmSpinnerImports],
|
|
207
|
+
template: `
|
|
208
|
+
<div hlmTableContainer>
|
|
209
|
+
<table hlmTable>
|
|
210
|
+
<caption hlmCaption>
|
|
211
|
+
{{
|
|
212
|
+
caption()
|
|
213
|
+
}}
|
|
214
|
+
</caption>
|
|
215
|
+
<thead hlmTHead>
|
|
216
|
+
<tr hlmTr>
|
|
217
|
+
<th hlmTh>Invoice</th>
|
|
218
|
+
<th hlmTh>Status</th>
|
|
219
|
+
<th hlmTh>Method</th>
|
|
220
|
+
<th hlmTh class="text-right">Amount</th>
|
|
221
|
+
</tr>
|
|
222
|
+
</thead>
|
|
223
|
+
<tbody hlmTBody>
|
|
224
|
+
@if (loading()) {
|
|
225
|
+
<tr hlmTr>
|
|
226
|
+
<td hlmTd colspan="4"><hlm-spinner size="1.25rem" /></td>
|
|
227
|
+
</tr>
|
|
228
|
+
} @else if (invoices().length === 0) {
|
|
229
|
+
<tr hlmTr>
|
|
230
|
+
<td hlmTd colspan="4" class="text-center">No invoices found.</td>
|
|
231
|
+
</tr>
|
|
232
|
+
} @else {
|
|
233
|
+
@for (inv of invoices(); track inv.id) {
|
|
234
|
+
<tr hlmTr>
|
|
235
|
+
<td hlmTd class="font-medium">{{ inv.id }}</td>
|
|
236
|
+
<td hlmTd>{{ inv.status }}</td>
|
|
237
|
+
<td hlmTd>{{ inv.method }}</td>
|
|
238
|
+
<td hlmTd class="text-right">{{ inv.amount }}</td>
|
|
239
|
+
</tr>
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
</tbody>
|
|
243
|
+
</table>
|
|
244
|
+
</div>
|
|
245
|
+
`,
|
|
246
|
+
})
|
|
247
|
+
export class DemoAsync {
|
|
248
|
+
private readonly http = inject(HttpClient);
|
|
249
|
+
readonly invoices = signal<Invoice[]>([]);
|
|
250
|
+
readonly loading = signal(true);
|
|
251
|
+
readonly caption = signal('Loading…');
|
|
252
|
+
|
|
253
|
+
constructor() {
|
|
254
|
+
this.http.get<Invoice[]>('/api/invoices').subscribe({
|
|
255
|
+
next: (rows) => {
|
|
256
|
+
this.invoices.set(rows);
|
|
257
|
+
this.loading.set(false);
|
|
258
|
+
this.caption.set(`${rows.length} invoices.`);
|
|
259
|
+
},
|
|
260
|
+
error: () => {
|
|
261
|
+
this.loading.set(false);
|
|
262
|
+
this.caption.set('Could not load invoices.');
|
|
263
|
+
},
|
|
264
|
+
});
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
```
|
|
268
|
+
|
|
269
|
+
### 3. Row selection with checkboxes
|
|
270
|
+
|
|
271
|
+
`HlmTh`/`HlmTd` automatically remove padding when they contain `[role=checkbox]` (`[&:has([role=checkbox])]:pe-0`).
|
|
272
|
+
|
|
273
|
+
```ts
|
|
274
|
+
// demo-select.component.ts
|
|
275
|
+
import { Component, signal } from '@angular/core';
|
|
276
|
+
import { HlmTableImports } from '@egose/shadcn-theme-ng/table';
|
|
277
|
+
import { HlmCheckboxImports } from '@egose/shadcn-theme-ng/checkbox';
|
|
278
|
+
|
|
279
|
+
@Component({
|
|
280
|
+
selector: 'demo-select',
|
|
281
|
+
standalone: true,
|
|
282
|
+
imports: [...HlmTableImports, ...HlmCheckboxImports],
|
|
283
|
+
template: `
|
|
284
|
+
<div hlmTableContainer>
|
|
285
|
+
<table hlmTable>
|
|
286
|
+
<thead hlmTHead>
|
|
287
|
+
<tr hlmTr>
|
|
288
|
+
<th hlmTh><hlm-checkbox [checked]="all()" (changed)="toggleAll($event)" aria-label="Select all" /></th>
|
|
289
|
+
<th hlmTh>Name</th>
|
|
290
|
+
<th hlmTh class="text-right">Role</th>
|
|
291
|
+
</tr>
|
|
292
|
+
</thead>
|
|
293
|
+
<tbody hlmTBody>
|
|
294
|
+
@for (u of users(); track u.id) {
|
|
295
|
+
<tr hlmTr [attr.data-state]="u.selected ? 'selected' : null">
|
|
296
|
+
<td hlmTd><hlm-checkbox [(checked)]="u.selected" [aria-label]="'Select ' + u.name" /></td>
|
|
297
|
+
<td hlmTd>{{ u.name }}</td>
|
|
298
|
+
<td hlmTd class="text-right">{{ u.role }}</td>
|
|
299
|
+
</tr>
|
|
300
|
+
}
|
|
301
|
+
</tbody>
|
|
302
|
+
</table>
|
|
303
|
+
</div>
|
|
304
|
+
`,
|
|
305
|
+
})
|
|
306
|
+
export class DemoSelect {
|
|
307
|
+
readonly users = signal([
|
|
308
|
+
{ id: 1, name: 'Ada', role: 'Admin', selected: false },
|
|
309
|
+
{ id: 2, name: 'Grace', role: 'Editor', selected: true },
|
|
310
|
+
]);
|
|
311
|
+
readonly all = signal(false);
|
|
312
|
+
|
|
313
|
+
toggleAll(v: boolean) {
|
|
314
|
+
this.users.update((rows) => rows.map((r) => ({ ...r, selected: v })));
|
|
315
|
+
this.all.set(v);
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
```
|
|
319
|
+
|
|
320
|
+
Selected rows pick up `data-[state=selected]:bg-muted` highlighting — set `[attr.data-state]="'selected'"` yourself, as above.
|
|
321
|
+
|
|
322
|
+
### 4. Long-alias selectors
|
|
323
|
+
|
|
324
|
+
Identical output — pick the alias style your team prefers:
|
|
325
|
+
|
|
326
|
+
```html
|
|
327
|
+
<div hlmTableContainer>
|
|
328
|
+
<table hlmTable>
|
|
329
|
+
<caption hlmTableCaption>
|
|
330
|
+
Aliases work everywhere.
|
|
331
|
+
</caption>
|
|
332
|
+
<thead hlmTableHeader>
|
|
333
|
+
<tr hlmTableRow>
|
|
334
|
+
<th hlmTableHead>A</th>
|
|
335
|
+
<th hlmTableHead>B</th>
|
|
336
|
+
</tr>
|
|
337
|
+
</thead>
|
|
338
|
+
<tbody hlmTableBody>
|
|
339
|
+
<tr hlmTableRow>
|
|
340
|
+
<td hlmTableCell>1</td>
|
|
341
|
+
<td hlmTableCell>2</td>
|
|
342
|
+
</tr>
|
|
343
|
+
</tbody>
|
|
344
|
+
<tfoot hlmTableFooter>
|
|
345
|
+
<tr hlmTableRow>
|
|
346
|
+
<td hlmTableCell>Total</td>
|
|
347
|
+
<td hlmTableCell>3</td>
|
|
348
|
+
</tr>
|
|
349
|
+
</tfoot>
|
|
350
|
+
</table>
|
|
351
|
+
</div>
|
|
352
|
+
```
|
|
353
|
+
|
|
354
|
+
### 5. Status badges + right-aligned numeric columns
|
|
355
|
+
|
|
356
|
+
```ts
|
|
357
|
+
// demo-rich.component.ts
|
|
358
|
+
import { Component } from '@angular/core';
|
|
359
|
+
import { HlmTableImports } from '@egose/shadcn-theme-ng/table';
|
|
360
|
+
import { HlmBadge } from '@egose/shadcn-theme-ng/badge';
|
|
361
|
+
|
|
362
|
+
@Component({
|
|
363
|
+
selector: 'demo-rich',
|
|
364
|
+
standalone: true,
|
|
365
|
+
imports: [...HlmTableImports, HlmBadge],
|
|
366
|
+
template: `
|
|
367
|
+
<div hlmTableContainer>
|
|
368
|
+
<table hlmTable>
|
|
369
|
+
<thead hlmTHead>
|
|
370
|
+
<tr hlmTr>
|
|
371
|
+
<th hlmTh>Order</th>
|
|
372
|
+
<th hlmTh>Status</th>
|
|
373
|
+
<th hlmTh class="text-right">Total</th>
|
|
374
|
+
</tr>
|
|
375
|
+
</thead>
|
|
376
|
+
<tbody hlmTBody>
|
|
377
|
+
<tr hlmTr>
|
|
378
|
+
<td hlmTd class="font-medium">#1001</td>
|
|
379
|
+
<td hlmTd><span hlmBadge>Paid</span></td>
|
|
380
|
+
<td hlmTd class="text-right tabular-nums">$1,250.00</td>
|
|
381
|
+
</tr>
|
|
382
|
+
<tr hlmTr>
|
|
383
|
+
<td hlmTd class="font-medium">#1002</td>
|
|
384
|
+
<td hlmTd><span hlmBadge variant="secondary">Pending</span></td>
|
|
385
|
+
<td hlmTd class="text-right tabular-nums">$320.00</td>
|
|
386
|
+
</tr>
|
|
387
|
+
<tr hlmTr>
|
|
388
|
+
<td hlmTd class="font-medium">#1003</td>
|
|
389
|
+
<td hlmTd><span hlmBadge variant="destructive">Refunded</span></td>
|
|
390
|
+
<td hlmTd class="text-right tabular-nums">$99.00</td>
|
|
391
|
+
</tr>
|
|
392
|
+
</tbody>
|
|
393
|
+
</table>
|
|
394
|
+
</div>
|
|
395
|
+
`,
|
|
396
|
+
})
|
|
397
|
+
export class DemoRich {}
|
|
398
|
+
```
|
|
399
|
+
|
|
400
|
+
### 6. Overflow container for wide tables
|
|
401
|
+
|
|
402
|
+
`HlmTableContainer` adds `overflow-x-auto` — wide tables scroll horizontally on small screens instead of breaking layout:
|
|
403
|
+
|
|
404
|
+
```html
|
|
405
|
+
<div hlmTableContainer class="max-w-3xl rounded-md border">
|
|
406
|
+
<table hlmTable>
|
|
407
|
+
<!-- many columns… -->
|
|
408
|
+
</table>
|
|
409
|
+
</div>
|
|
410
|
+
```
|
|
411
|
+
|
|
412
|
+
## Accessibility notes
|
|
413
|
+
|
|
414
|
+
- Keep semantic structure: exactly one `<thead>` with `<th>` header cells, body rows in `<tbody>`, summaries in `<tfoot>`, and a `<caption>` (or `aria-label`) describing the table.
|
|
415
|
+
- Use `scope="col"` / `scope="row"` on `<th>` elements when the table has row headers.
|
|
416
|
+
- Right-align numeric columns but keep DOM order logical — screen readers read row by row.
|
|
417
|
+
- For selectable rows, expose selection via `aria-selected` or the checkbox's accessible name; the `data-state="selected"` highlight is visual only.
|
|
418
|
+
- Avoid nested interactive chaos: if a row is clickable _and_ contains buttons/links, make the row action a real button in a cell rather than a `(click)` on `<tr>`.
|
|
419
|
+
|
|
420
|
+
## Theming / CSS variables
|
|
421
|
+
|
|
422
|
+
All styling keys off shadcn tokens (`text-foreground`, `text-muted-foreground`, `bg-muted/50`, `border-*`). The table inherits your theme automatically; add borders, rounding, or width constraints via `class` on the container (merged, not clobbered).
|
|
423
|
+
|
|
424
|
+
## Related subpaths
|
|
425
|
+
|
|
426
|
+
- `@egose/shadcn-theme-ng/badge` — status pills inside cells.
|
|
427
|
+
- `@egose/shadcn-theme-ng/checkbox` — row-selection checkboxes.
|
|
428
|
+
- `@egose/shadcn-theme-ng/spinner` / `@egose/shadcn-theme-ng/skeleton` — loading states for async tables.
|
|
429
|
+
- `@egose/shadcn-theme-ng/pagination` — paging controls below large tables.
|