@lmfaole/basics 0.2.1 → 0.4.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 +306 -22
- package/basic-styling/components/basic-accordion.css +65 -0
- package/basic-styling/components/basic-alert.css +27 -0
- package/basic-styling/components/basic-dialog.css +41 -0
- package/basic-styling/components/basic-popover.css +54 -0
- package/basic-styling/components/basic-summary-table.css +76 -0
- package/basic-styling/components/basic-table.css +48 -0
- package/basic-styling/components/basic-tabs.css +45 -0
- package/basic-styling/components/basic-toast.css +102 -0
- package/basic-styling/components/basic-toc.css +30 -0
- package/basic-styling/components.css +9 -0
- package/basic-styling/global.css +61 -0
- package/basic-styling/index.css +2 -0
- package/basic-styling/tokens/base.css +19 -0
- package/basic-styling/tokens/palette.css +117 -0
- package/basic-styling/tokens/palette.tokens.json +1019 -0
- package/components/basic-accordion/index.d.ts +5 -5
- package/components/basic-accordion/index.js +169 -165
- package/components/basic-alert/index.d.ts +53 -0
- package/components/basic-alert/index.js +189 -0
- package/components/basic-alert/register.d.ts +1 -0
- package/components/basic-alert/register.js +3 -0
- package/components/basic-dialog/index.js +21 -1
- package/components/basic-summary-table/index.d.ts +69 -0
- package/components/basic-summary-table/index.js +536 -0
- package/components/basic-summary-table/register.d.ts +1 -0
- package/components/basic-summary-table/register.js +3 -0
- package/components/basic-table/index.d.ts +75 -0
- package/components/basic-table/index.js +612 -0
- package/components/basic-table/register.d.ts +1 -0
- package/components/basic-table/register.js +3 -0
- package/components/basic-tabs/index.d.ts +2 -3
- package/components/basic-tabs/index.js +4 -30
- package/components/basic-toast/index.d.ts +65 -0
- package/components/basic-toast/index.js +429 -0
- package/components/basic-toast/register.d.ts +1 -0
- package/components/basic-toast/register.js +3 -0
- package/index.d.ts +4 -0
- package/index.js +4 -0
- package/package.json +28 -41
- package/readme.mdx +1 -1
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# `@lmfaole/basics`
|
|
2
2
|
|
|
3
|
-
Simple
|
|
3
|
+
Simple custom elements and DOM helpers, with optional starter styles.
|
|
4
4
|
|
|
5
5
|
## Install
|
|
6
6
|
|
|
@@ -8,6 +8,38 @@ Simple unstyled custom elements and DOM helpers.
|
|
|
8
8
|
pnpm add @lmfaole/basics
|
|
9
9
|
```
|
|
10
10
|
|
|
11
|
+
## Optional Styling
|
|
12
|
+
|
|
13
|
+
Import the full starter layer:
|
|
14
|
+
|
|
15
|
+
```css
|
|
16
|
+
@import "@lmfaole/basics/basic-styling";
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
Or split it into the global layer and component styles:
|
|
20
|
+
|
|
21
|
+
```css
|
|
22
|
+
@import "@lmfaole/basics/basic-styling/global.css";
|
|
23
|
+
@import "@lmfaole/basics/basic-styling/components.css";
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
Individual token and component files are also exported:
|
|
27
|
+
|
|
28
|
+
- `@lmfaole/basics/basic-styling/tokens/base.css`
|
|
29
|
+
- `@lmfaole/basics/basic-styling/tokens/palette.css`
|
|
30
|
+
- `@lmfaole/basics/basic-styling/tokens/palette.tokens.json`
|
|
31
|
+
- `@lmfaole/basics/basic-styling/components/basic-alert.css`
|
|
32
|
+
- `@lmfaole/basics/basic-styling/components/basic-accordion.css`
|
|
33
|
+
- `@lmfaole/basics/basic-styling/components/basic-dialog.css`
|
|
34
|
+
- `@lmfaole/basics/basic-styling/components/basic-popover.css`
|
|
35
|
+
- `@lmfaole/basics/basic-styling/components/basic-summary-table.css`
|
|
36
|
+
- `@lmfaole/basics/basic-styling/components/basic-table.css`
|
|
37
|
+
- `@lmfaole/basics/basic-styling/components/basic-tabs.css`
|
|
38
|
+
- `@lmfaole/basics/basic-styling/components/basic-toc.css`
|
|
39
|
+
- `@lmfaole/basics/basic-styling/components/basic-toast.css`
|
|
40
|
+
|
|
41
|
+
The core components remain unstyled by default. The `basic-styling` subpath is optional and meant as a very simple token-based baseline that focuses on spacing, padding, and margins first. The shared token sources live under `basic-styling/tokens/`, while the component-specific styles live under `basic-styling/components/`. `base.css` defines the non-color primitives, `palette.css` holds the computed color tokens and alternate palettes that the global layer consumes, and `palette.tokens.json` exposes the same palette data in W3C design-token format.
|
|
42
|
+
|
|
11
43
|
## Storybook
|
|
12
44
|
|
|
13
45
|
```sh
|
|
@@ -27,6 +59,11 @@ pnpm test:storybook:coverage
|
|
|
27
59
|
```
|
|
28
60
|
|
|
29
61
|
Autodocs is enabled globally for the package stories, and the Docs page includes Storybook's built-in Code panel for rendered examples.
|
|
62
|
+
Use the `Styling` toolbar control in Storybook to toggle the optional `basic-styling` layer on or off across all stories.
|
|
63
|
+
Use the `Theme` toolbar control to preview the starter styling in light, dark, or system mode through the CSS `light-dark()` tokens.
|
|
64
|
+
Use the `Palette` toolbar control to swap the computed starter palettes between `slate`, `sand`, `ocean`, and `berry`.
|
|
65
|
+
The `Techniques/Color` stories show how to force a local `color-scheme`, scope a different palette with `data-basic-palette`, and override the semantic `--basic-color-*` tokens for one section.
|
|
66
|
+
The `Overview/Palette Tokens` docs page renders the exported token values with Storybook's built-in `ColorPalette` and `ColorItem` blocks.
|
|
30
67
|
Storybook Test coverage is enabled through the Vitest addon. In the Storybook UI, turn coverage on in the testing panel to see the summary and open the full report at `/coverage/index.html`. From the CLI, `test:storybook:coverage` writes reports to `coverage/storybook/`.
|
|
31
68
|
|
|
32
69
|
The Visual Tests panel is provided by `@chromatic-com/storybook`. To run cloud visual checks, connect the addon to a Chromatic project from the Storybook UI.
|
|
@@ -65,6 +102,86 @@ If a release needs to be retried after the workflow changes land, use the `Relea
|
|
|
65
102
|
|
|
66
103
|
Use Conventional Commits for commit messages and pull request titles. The GitHub workflow accepts `build`, `chore`, `ci`, `docs`, `feat`, `fix`, `perf`, `refactor`, `revert`, `style`, and `test`, with an optional scope such as `feat(tabs): add keyboard support`.
|
|
67
104
|
|
|
105
|
+
## Basic Alert
|
|
106
|
+
|
|
107
|
+
```html
|
|
108
|
+
<basic-alert data-label="Lagring fullfort" data-live="polite">
|
|
109
|
+
<h2 data-alert-title>Endringer lagret</h2>
|
|
110
|
+
<p>Meldingen ble lagret uten feil.</p>
|
|
111
|
+
<button type="button" data-alert-close>Dismiss</button>
|
|
112
|
+
</basic-alert>
|
|
113
|
+
|
|
114
|
+
<script type="module">
|
|
115
|
+
import "@lmfaole/basics/components/basic-alert/register";
|
|
116
|
+
</script>
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
The element upgrades inline content into a named live-region alert without adding any styles of its own.
|
|
120
|
+
|
|
121
|
+
### Attributes
|
|
122
|
+
|
|
123
|
+
- `data-label`: fallback accessible name when the alert has no `aria-label`, `aria-labelledby`, or `[data-alert-title]`.
|
|
124
|
+
- `data-live`: chooses the live-region mode. Use `assertive` for `role="alert"` or `polite` for `role="status"`.
|
|
125
|
+
|
|
126
|
+
### Behavior
|
|
127
|
+
|
|
128
|
+
- Applies the matching live-region role, `aria-live`, and `aria-atomic="true"` on the root element.
|
|
129
|
+
- Uses `[data-alert-title]` as the accessible name when present, otherwise falls back to `data-label`.
|
|
130
|
+
- `[data-alert-close]` controls hide the alert and remove its managed `data-open` state.
|
|
131
|
+
- `show()` and `hide()` methods can be used for programmatic visibility changes.
|
|
132
|
+
|
|
133
|
+
### Markup Contract
|
|
134
|
+
|
|
135
|
+
- Put the content directly inside `<basic-alert>`.
|
|
136
|
+
- Use `[data-alert-title]` when the alert should have a visible accessible name.
|
|
137
|
+
- Use `[data-alert-close]` when the alert should be dismissible.
|
|
138
|
+
- Keep layout and styling outside the package; the component only manages semantics and simple dismissal behavior.
|
|
139
|
+
|
|
140
|
+
## Basic Toast
|
|
141
|
+
|
|
142
|
+
```html
|
|
143
|
+
<basic-toast data-label="Lagring fullfort" data-duration="5000">
|
|
144
|
+
<button type="button" data-toast-open>Show toast</button>
|
|
145
|
+
|
|
146
|
+
<section data-toast-panel>
|
|
147
|
+
<h2 data-toast-title>Lagret</h2>
|
|
148
|
+
<p>Meldingen ble lagret uten feil.</p>
|
|
149
|
+
<button type="button" data-toast-close>Dismiss</button>
|
|
150
|
+
</section>
|
|
151
|
+
</basic-toast>
|
|
152
|
+
|
|
153
|
+
<script type="module">
|
|
154
|
+
import "@lmfaole/basics/components/basic-toast/register";
|
|
155
|
+
</script>
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
The element upgrades trigger-and-panel markup into a toast notification flow without adding any styles of its own.
|
|
159
|
+
|
|
160
|
+
### Attributes
|
|
161
|
+
|
|
162
|
+
- `data-label`: fallback accessible name when the toast panel has no `aria-label`, `aria-labelledby`, or `[data-toast-title]`.
|
|
163
|
+
- `data-live`: chooses the live-region mode. Use `polite` for `role="status"` or `assertive` for `role="alert"`.
|
|
164
|
+
- `data-duration`: auto-dismiss timeout in milliseconds. Use `0` to disable auto-dismiss.
|
|
165
|
+
- `data-open`: optional initial open state for the toast panel.
|
|
166
|
+
|
|
167
|
+
### Behavior
|
|
168
|
+
|
|
169
|
+
- Uses the Popover API in manual mode when available so the toast panel can render in the top layer.
|
|
170
|
+
- Syncs the panel's open state, `hidden`, and `data-open` on the toast panel and root element.
|
|
171
|
+
- Uses `[data-toast-title]` as the accessible name when present, otherwise falls back to `data-label`.
|
|
172
|
+
- `[data-toast-open]` toggles the toast, while `[data-toast-close]` dismisses it.
|
|
173
|
+
- Auto-dismisses after `data-duration` milliseconds unless the duration is `0`.
|
|
174
|
+
- `show()`, `hide()`, and `toggle()` methods support programmatic control.
|
|
175
|
+
|
|
176
|
+
### Markup Contract
|
|
177
|
+
|
|
178
|
+
- Provide one descendant `[data-toast-panel]`.
|
|
179
|
+
- Use `[data-toast-open]` on buttons that should show or toggle the toast.
|
|
180
|
+
- Use `[data-toast-close]` when the toast should expose an explicit dismiss action.
|
|
181
|
+
- Use `[data-toast-title]` when the toast should have a visible accessible name.
|
|
182
|
+
- When using the optional starter styling, set `data-toast-position` to presets such as `top-right`, `bottom-center`, or `center` to move the top-layer toast around the viewport.
|
|
183
|
+
- Keep layout and styling outside the package; the component only manages semantics, open state, and optional auto-dismiss behavior.
|
|
184
|
+
|
|
68
185
|
## Basic Popover
|
|
69
186
|
|
|
70
187
|
```html
|
|
@@ -156,15 +273,15 @@ The element upgrades native `<dialog>` markup into an accessible modal flow with
|
|
|
156
273
|
|
|
157
274
|
```html
|
|
158
275
|
<basic-accordion>
|
|
159
|
-
<
|
|
160
|
-
|
|
276
|
+
<details open>
|
|
277
|
+
<summary>Oversikt</summary>
|
|
161
278
|
<p>Viser en kort oppsummering.</p>
|
|
162
|
-
</
|
|
279
|
+
</details>
|
|
163
280
|
|
|
164
|
-
<
|
|
165
|
-
|
|
281
|
+
<details>
|
|
282
|
+
<summary>Implementasjon</summary>
|
|
166
283
|
<p>Viser implementasjonsdetaljer.</p>
|
|
167
|
-
</
|
|
284
|
+
</details>
|
|
168
285
|
</basic-accordion>
|
|
169
286
|
|
|
170
287
|
<script type="module">
|
|
@@ -172,26 +289,27 @@ The element upgrades native `<dialog>` markup into an accessible modal flow with
|
|
|
172
289
|
</script>
|
|
173
290
|
```
|
|
174
291
|
|
|
175
|
-
The element
|
|
292
|
+
The element coordinates direct child `details` items into an accordion without adding any styles of its own.
|
|
176
293
|
|
|
177
294
|
### Attributes
|
|
178
295
|
|
|
179
|
-
- `data-multiple`: allows multiple
|
|
180
|
-
- `data-collapsible`: allows the last open
|
|
296
|
+
- `data-multiple`: allows multiple items to stay open at the same time.
|
|
297
|
+
- `data-collapsible`: allows the last open item in single mode to close.
|
|
181
298
|
|
|
182
|
-
###
|
|
299
|
+
### Markup Contract
|
|
183
300
|
|
|
184
|
-
-
|
|
185
|
-
-
|
|
186
|
-
-
|
|
187
|
-
-
|
|
188
|
-
- Disabled triggers are skipped during keyboard navigation.
|
|
301
|
+
- Provide direct child `<details>` items, each with a first-child `<summary>`.
|
|
302
|
+
- Add `open` to any item that should start expanded.
|
|
303
|
+
- Add `data-disabled` to a `<details>` item when it should be skipped by arrow-key navigation and blocked from toggling.
|
|
304
|
+
- Keep layout and styling outside the package; the component only manages root-level open-state rules and keyboard behavior.
|
|
189
305
|
|
|
190
|
-
###
|
|
306
|
+
### Behavior
|
|
191
307
|
|
|
192
|
-
-
|
|
193
|
-
-
|
|
194
|
-
-
|
|
308
|
+
- Native `details` and `summary` semantics are preserved.
|
|
309
|
+
- `data-open` stays in sync with the normalized open state for optional styling hooks.
|
|
310
|
+
- `ArrowUp`, `ArrowDown`, `Home`, and `End` move focus between enabled summaries.
|
|
311
|
+
- `Enter` and `Space` keep using the platform's native `summary` toggle behavior.
|
|
312
|
+
- In single-open mode, the component keeps one enabled item open unless `data-collapsible` is set.
|
|
195
313
|
|
|
196
314
|
## Basic Tabs
|
|
197
315
|
|
|
@@ -224,7 +342,6 @@ The element upgrades existing markup into an accessible tab interface without ad
|
|
|
224
342
|
### Attributes
|
|
225
343
|
|
|
226
344
|
- `data-label`: sets the generated tablist's accessible name when the tablist does not already have `aria-label` or `aria-labelledby`. Defaults to `Faner`.
|
|
227
|
-
- `data-orientation`: sets arrow-key behavior and mirrors `aria-orientation` on the tablist. Supported values are `horizontal` and `vertical`.
|
|
228
345
|
- `data-activation`: chooses whether arrow-key focus changes also activate the panel. Supported values are `automatic` and `manual`.
|
|
229
346
|
- `data-selected-index`: sets the initially selected tab by zero-based index. Defaults to the first enabled tab.
|
|
230
347
|
|
|
@@ -232,7 +349,7 @@ The element upgrades existing markup into an accessible tab interface without ad
|
|
|
232
349
|
|
|
233
350
|
- Missing tab and panel ids are generated automatically.
|
|
234
351
|
- `aria-selected`, `aria-controls`, `aria-labelledby`, `hidden`, and `data-selected` stay in sync with the active tab.
|
|
235
|
-
- Click, `
|
|
352
|
+
- Click, `ArrowLeft`, `ArrowRight`, `Home`, and `End` move between tabs.
|
|
236
353
|
- Disabled tabs are skipped during keyboard navigation.
|
|
237
354
|
- In `manual` mode, arrow keys move focus and `Enter` or `Space` activates the focused tab.
|
|
238
355
|
|
|
@@ -243,6 +360,173 @@ The element upgrades existing markup into an accessible tab interface without ad
|
|
|
243
360
|
- Prefer `<button>` elements for tabs so click and keyboard activation stay native.
|
|
244
361
|
- Keep layout and styling outside the package; the component only manages semantics, state, and keyboard behavior.
|
|
245
362
|
|
|
363
|
+
## Basic Table
|
|
364
|
+
|
|
365
|
+
```html
|
|
366
|
+
<basic-table
|
|
367
|
+
data-caption="Bemanning per sprint"
|
|
368
|
+
data-description="Viser team, lokasjon og ledig kapasitet per sprint."
|
|
369
|
+
data-row-headers
|
|
370
|
+
data-row-header-column="2"
|
|
371
|
+
>
|
|
372
|
+
<table>
|
|
373
|
+
<thead>
|
|
374
|
+
<tr>
|
|
375
|
+
<th>Statuskode</th>
|
|
376
|
+
<th>Team</th>
|
|
377
|
+
<th>Lokasjon</th>
|
|
378
|
+
<th>Sprint</th>
|
|
379
|
+
<th>Ledige timer</th>
|
|
380
|
+
</tr>
|
|
381
|
+
</thead>
|
|
382
|
+
<tbody>
|
|
383
|
+
<tr>
|
|
384
|
+
<td>A1</td>
|
|
385
|
+
<td>Plattform</td>
|
|
386
|
+
<td>Oslo</td>
|
|
387
|
+
<td>14</td>
|
|
388
|
+
<td>18</td>
|
|
389
|
+
</tr>
|
|
390
|
+
<tr>
|
|
391
|
+
<td>B4</td>
|
|
392
|
+
<td>Designsystem</td>
|
|
393
|
+
<td>Trondheim</td>
|
|
394
|
+
<td>14</td>
|
|
395
|
+
<td>10</td>
|
|
396
|
+
</tr>
|
|
397
|
+
<tr>
|
|
398
|
+
<td>C2</td>
|
|
399
|
+
<td>Innsikt</td>
|
|
400
|
+
<td>Bergen</td>
|
|
401
|
+
<td>15</td>
|
|
402
|
+
<td>26</td>
|
|
403
|
+
</tr>
|
|
404
|
+
<tr>
|
|
405
|
+
<td>D7</td>
|
|
406
|
+
<td>Betaling</td>
|
|
407
|
+
<td>Stockholm</td>
|
|
408
|
+
<td>15</td>
|
|
409
|
+
<td>8</td>
|
|
410
|
+
</tr>
|
|
411
|
+
</tbody>
|
|
412
|
+
</table>
|
|
413
|
+
</basic-table>
|
|
414
|
+
|
|
415
|
+
<script type="module">
|
|
416
|
+
import "@lmfaole/basics/components/basic-table/register";
|
|
417
|
+
</script>
|
|
418
|
+
```
|
|
419
|
+
|
|
420
|
+
The element upgrades a regular table with stronger accessible naming and header associations without imposing any styles.
|
|
421
|
+
|
|
422
|
+
### Attributes
|
|
423
|
+
|
|
424
|
+
- `data-caption`: generates a visible `<caption>` when the wrapped table does not already define one.
|
|
425
|
+
- `data-column-headers`: promotes the first row to column headers when the author provides a plain table without a header row.
|
|
426
|
+
- `data-description`: generates a hidden description and connects it with `aria-describedby`.
|
|
427
|
+
- `data-label`: sets a fallback accessible name when the table has no caption, `aria-label`, or `aria-labelledby`. Defaults to `Tabell`.
|
|
428
|
+
- `data-row-header-column`: sets which one-based body column should become the generated row header. Defaults to `1`.
|
|
429
|
+
- `data-row-headers`: enables generated row headers in body rows. If `data-row-header-column` is present, row-header mode is enabled automatically.
|
|
430
|
+
|
|
431
|
+
### Behavior
|
|
432
|
+
|
|
433
|
+
- Preserves author-provided captions and only generates one when needed.
|
|
434
|
+
- Can generate hidden helper text for extra context without requiring a separate authored description element.
|
|
435
|
+
- Can promote a plain first row to column headers when consumers start from simple body-only markup.
|
|
436
|
+
- Infers common `scope` values for header cells and assigns missing header ids.
|
|
437
|
+
- Populates each data cell's `headers` attribute from the matching row and column headers.
|
|
438
|
+
- Re-runs automatically when the wrapped table changes.
|
|
439
|
+
|
|
440
|
+
### Markup Contract
|
|
441
|
+
|
|
442
|
+
- Provide one descendant `<table>` inside the custom element.
|
|
443
|
+
- Use real table sections and header cells where possible; the component strengthens semantics but does not replace the HTML table model.
|
|
444
|
+
- Add `data-row-headers` when one body column identifies each row, and use `data-row-header-column` when that column is not the first one.
|
|
445
|
+
- Add `data-column-headers` when you want the component to promote a plain first row instead of authoring a header row yourself.
|
|
446
|
+
- Keep layout and styling outside the package; the component only manages semantics and accessibility metadata.
|
|
447
|
+
|
|
448
|
+
## Basic Summary Table
|
|
449
|
+
|
|
450
|
+
```html
|
|
451
|
+
<basic-summary-table
|
|
452
|
+
data-caption="Månedlig kostnadsoversikt"
|
|
453
|
+
data-description="Viser antall og summerte beløp for faste kostnader."
|
|
454
|
+
data-row-headers
|
|
455
|
+
data-summary-columns="2,4"
|
|
456
|
+
data-total-label="Totalt"
|
|
457
|
+
data-locale="nb-NO"
|
|
458
|
+
>
|
|
459
|
+
<table>
|
|
460
|
+
<thead>
|
|
461
|
+
<tr>
|
|
462
|
+
<th>Post</th>
|
|
463
|
+
<th>Antall</th>
|
|
464
|
+
<th>Enhetspris</th>
|
|
465
|
+
<th>Beløp</th>
|
|
466
|
+
</tr>
|
|
467
|
+
</thead>
|
|
468
|
+
<tbody>
|
|
469
|
+
<tr>
|
|
470
|
+
<td>Basisabonnement</td>
|
|
471
|
+
<td>12</td>
|
|
472
|
+
<td>49,00 kr</td>
|
|
473
|
+
<td>588,00 kr</td>
|
|
474
|
+
</tr>
|
|
475
|
+
<tr>
|
|
476
|
+
<td>Supportavtale</td>
|
|
477
|
+
<td>1</td>
|
|
478
|
+
<td>299,00 kr</td>
|
|
479
|
+
<td>299,00 kr</td>
|
|
480
|
+
</tr>
|
|
481
|
+
<tr>
|
|
482
|
+
<td>Lagringstillegg</td>
|
|
483
|
+
<td>4</td>
|
|
484
|
+
<td>120,00 kr</td>
|
|
485
|
+
<td>480,00 kr</td>
|
|
486
|
+
</tr>
|
|
487
|
+
<tr>
|
|
488
|
+
<td>Opplæringsplasser</td>
|
|
489
|
+
<td>3</td>
|
|
490
|
+
<td>180,00 kr</td>
|
|
491
|
+
<td>540,00 kr</td>
|
|
492
|
+
</tr>
|
|
493
|
+
</tbody>
|
|
494
|
+
</table>
|
|
495
|
+
</basic-summary-table>
|
|
496
|
+
|
|
497
|
+
<script type="module">
|
|
498
|
+
import "@lmfaole/basics/components/basic-summary-table/register";
|
|
499
|
+
</script>
|
|
500
|
+
```
|
|
501
|
+
|
|
502
|
+
The element upgrades a calculation-heavy table with an automatically maintained totals row in `<tfoot>`.
|
|
503
|
+
|
|
504
|
+
### Attributes
|
|
505
|
+
|
|
506
|
+
- `data-caption`: generates a visible `<caption>` when the wrapped table does not already define one.
|
|
507
|
+
- `data-description`: generates hidden helper text and connects it with `aria-describedby`.
|
|
508
|
+
- `data-label`: sets a fallback accessible name when the table has no caption, `aria-label`, or `aria-labelledby`. Defaults to `Tabell`.
|
|
509
|
+
- `data-row-headers`: enables generated row headers in body rows.
|
|
510
|
+
- `data-row-header-column`: sets which one-based body column should become the generated row header. Defaults to `1`.
|
|
511
|
+
- `data-summary-columns`: chooses which one-based columns should be totalled in the generated footer row. If omitted, numeric body columns are inferred automatically.
|
|
512
|
+
- `data-total-label`: sets the footer row label. Defaults to `Totalt`.
|
|
513
|
+
- `data-locale`: passes a locale through to `Intl.NumberFormat` for generated footer totals.
|
|
514
|
+
|
|
515
|
+
### Behavior
|
|
516
|
+
|
|
517
|
+
- Inherits caption, description, row-header, and `headers` association behavior from `basic-table`.
|
|
518
|
+
- Parses numbers from cell text and supports raw calculation values through `data-value` on individual body cells.
|
|
519
|
+
- Generates or updates a totals row in `<tfoot>` without requiring consumers to author the footer manually.
|
|
520
|
+
- Preserves a consistent displayed unit or currency affix such as `kr`, `%`, or `t` in generated footer totals.
|
|
521
|
+
- Recalculates totals automatically when body rows or `data-value` attributes change.
|
|
522
|
+
|
|
523
|
+
### Markup Contract
|
|
524
|
+
|
|
525
|
+
- Provide one descendant `<table>` with line items in `<tbody>`.
|
|
526
|
+
- Prefer a label column such as `Post` or `Kategori` and enable `data-row-headers` so each line item remains easy to navigate.
|
|
527
|
+
- Use `data-value` on cells when the displayed text is formatted differently from the numeric value you want summed.
|
|
528
|
+
- Keep layout and styling outside the package; the component only manages semantics, totals, and footer structure.
|
|
529
|
+
|
|
246
530
|
## Basic Toc
|
|
247
531
|
|
|
248
532
|
```html
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
basic-accordion {
|
|
2
|
+
--basic-accordion-padding: var(--basic-panel-padding);
|
|
3
|
+
display: grid;
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
basic-accordion > details {
|
|
7
|
+
margin: 0;
|
|
8
|
+
border: var(--basic-border-width) solid var(--basic-color-border);
|
|
9
|
+
border-radius: var(--basic-radius);
|
|
10
|
+
background: var(--basic-color-surface);
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
basic-accordion > details > summary {
|
|
14
|
+
list-style: none;
|
|
15
|
+
display: flex;
|
|
16
|
+
align-items: center;
|
|
17
|
+
justify-content: space-between;
|
|
18
|
+
padding: var(--basic-control-padding-block) var(--basic-control-padding-inline);
|
|
19
|
+
color: inherit;
|
|
20
|
+
font-weight: 600;
|
|
21
|
+
text-align: left;
|
|
22
|
+
cursor: pointer;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
basic-accordion > details > summary::-webkit-details-marker {
|
|
26
|
+
display: none;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
basic-accordion > details > summary::after {
|
|
30
|
+
content: "+";
|
|
31
|
+
flex: none;
|
|
32
|
+
color: var(--basic-color-text-muted);
|
|
33
|
+
font-size: var(--basic-font-size-title);
|
|
34
|
+
line-height: 1;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
basic-accordion > details[open] > summary {
|
|
38
|
+
background: var(--basic-color-surface-muted);
|
|
39
|
+
margin-block-end: var(--basic-flow-space);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
basic-accordion > details[open] > summary::after {
|
|
43
|
+
content: "-";
|
|
44
|
+
color: inherit;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
basic-accordion > details[open] {
|
|
48
|
+
padding-block-end: var(--basic-accordion-padding);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
basic-accordion > details > :where(:not(summary)) {
|
|
52
|
+
margin-block: 0;
|
|
53
|
+
margin-inline: var(--basic-accordion-padding);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
basic-accordion > details > :not(summary) + :not(summary) {
|
|
57
|
+
margin-block-start: var(--basic-flow-space);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
basic-accordion > details[data-disabled] > summary,
|
|
61
|
+
basic-accordion > details[disabled] > summary,
|
|
62
|
+
basic-accordion > details[aria-disabled="true"] > summary {
|
|
63
|
+
color: var(--basic-color-text-muted);
|
|
64
|
+
cursor: default;
|
|
65
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
basic-alert {
|
|
2
|
+
display: block;
|
|
3
|
+
padding: var(--basic-panel-padding);
|
|
4
|
+
border: var(--basic-border-width) solid var(--basic-color-border);
|
|
5
|
+
border-radius: var(--basic-radius);
|
|
6
|
+
background: var(--basic-color-surface-muted);
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
basic-alert > :where(*) {
|
|
10
|
+
margin-block: 0;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
basic-alert > :where(* + *) {
|
|
14
|
+
margin-block-start: var(--basic-flow-space);
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
basic-alert [data-alert-close] {
|
|
18
|
+
display: inline-flex;
|
|
19
|
+
align-items: center;
|
|
20
|
+
justify-content: center;
|
|
21
|
+
padding: var(--basic-control-padding-block) var(--basic-control-padding-inline);
|
|
22
|
+
border: var(--basic-border-width) solid var(--basic-color-border);
|
|
23
|
+
border-radius: var(--basic-radius-pill);
|
|
24
|
+
background: var(--basic-color-surface);
|
|
25
|
+
color: inherit;
|
|
26
|
+
cursor: pointer;
|
|
27
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
basic-dialog {
|
|
2
|
+
--basic-dialog-control-gap: var(--basic-space-2);
|
|
3
|
+
--basic-dialog-panel-gap: var(--basic-flow-space);
|
|
4
|
+
--basic-dialog-panel-padding: var(--basic-panel-padding);
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
basic-dialog [data-dialog-open],
|
|
8
|
+
basic-dialog [data-dialog-close] {
|
|
9
|
+
display: inline-flex;
|
|
10
|
+
align-items: center;
|
|
11
|
+
justify-content: center;
|
|
12
|
+
gap: var(--basic-dialog-control-gap);
|
|
13
|
+
padding: var(--basic-control-padding-block) var(--basic-control-padding-inline);
|
|
14
|
+
border: var(--basic-border-width) solid var(--basic-color-border);
|
|
15
|
+
border-radius: var(--basic-radius-pill);
|
|
16
|
+
background: var(--basic-color-surface);
|
|
17
|
+
color: inherit;
|
|
18
|
+
cursor: pointer;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
basic-dialog [data-dialog-panel] {
|
|
22
|
+
width: min(var(--basic-dialog-width, 32rem), var(--basic-dialog-max-width, calc(100vw - 2rem)));
|
|
23
|
+
max-width: var(--basic-dialog-max-width, calc(100vw - 2rem));
|
|
24
|
+
padding: var(--basic-dialog-panel-padding);
|
|
25
|
+
border: var(--basic-border-width) solid var(--basic-color-border);
|
|
26
|
+
border-radius: var(--basic-radius);
|
|
27
|
+
background: var(--basic-color-surface);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
basic-dialog [data-dialog-panel] > :where(*) {
|
|
31
|
+
margin-block: 0;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
basic-dialog [data-dialog-panel] > :where(* + *) {
|
|
35
|
+
margin-block-start: var(--basic-dialog-panel-gap);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
basic-dialog [data-dialog-title] {
|
|
39
|
+
font-size: var(--basic-font-size-title);
|
|
40
|
+
line-height: 1.2;
|
|
41
|
+
}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
basic-popover {
|
|
2
|
+
--basic-popover-control-gap: var(--basic-space-2);
|
|
3
|
+
--basic-popover-panel-gap: var(--basic-flow-space);
|
|
4
|
+
--basic-popover-panel-padding: var(--basic-panel-padding);
|
|
5
|
+
display: inline-block;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
basic-popover [data-popover-open],
|
|
9
|
+
basic-popover [data-popover-close] {
|
|
10
|
+
display: inline-flex;
|
|
11
|
+
align-items: center;
|
|
12
|
+
justify-content: center;
|
|
13
|
+
gap: var(--basic-popover-control-gap);
|
|
14
|
+
padding: var(--basic-control-padding-block) var(--basic-control-padding-inline);
|
|
15
|
+
border: var(--basic-border-width) solid var(--basic-color-border);
|
|
16
|
+
border-radius: var(--basic-radius-pill);
|
|
17
|
+
background: var(--basic-color-surface);
|
|
18
|
+
color: inherit;
|
|
19
|
+
cursor: pointer;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
basic-popover [data-popover-open][aria-expanded="true"] {
|
|
23
|
+
background: var(--basic-color-surface-muted);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
basic-popover [data-popover-panel] {
|
|
27
|
+
width: min(var(--basic-popover-width, 20rem), var(--basic-popover-max-width, calc(100vw - 2rem)));
|
|
28
|
+
max-width: var(--basic-popover-max-width, calc(100vw - 2rem));
|
|
29
|
+
padding: var(--basic-popover-panel-padding);
|
|
30
|
+
border: var(--basic-border-width) solid var(--basic-color-border);
|
|
31
|
+
border-radius: var(--basic-radius);
|
|
32
|
+
background: var(--basic-color-surface);
|
|
33
|
+
color: inherit;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
basic-popover [data-popover-panel] > :where(*) {
|
|
37
|
+
margin-block: 0;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
basic-popover [data-popover-panel] > :where(* + *) {
|
|
41
|
+
margin-block-start: var(--basic-popover-panel-gap);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
basic-popover [data-popover-panel] label {
|
|
45
|
+
display: flex;
|
|
46
|
+
align-items: center;
|
|
47
|
+
gap: var(--basic-space-2);
|
|
48
|
+
color: var(--basic-color-text-muted);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
basic-popover [data-popover-title] {
|
|
52
|
+
font-size: var(--basic-font-size-title);
|
|
53
|
+
line-height: 1.2;
|
|
54
|
+
}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
basic-summary-table {
|
|
2
|
+
--basic-summary-table-caption-gap: var(--basic-flow-space);
|
|
3
|
+
--basic-summary-table-cell-padding-block: var(--basic-space-3);
|
|
4
|
+
--basic-summary-table-cell-padding-inline: var(--basic-space-4);
|
|
5
|
+
|
|
6
|
+
display: block;
|
|
7
|
+
overflow-x: auto;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
basic-summary-table table {
|
|
11
|
+
width: 100%;
|
|
12
|
+
min-width: var(--basic-summary-table-min-width, 32rem);
|
|
13
|
+
border-collapse: collapse;
|
|
14
|
+
border: var(--basic-border-width) solid var(--basic-color-border);
|
|
15
|
+
background: var(--basic-color-surface);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
basic-summary-table caption {
|
|
19
|
+
margin-bottom: var(--basic-summary-table-caption-gap);
|
|
20
|
+
color: var(--basic-color-text);
|
|
21
|
+
font-weight: 700;
|
|
22
|
+
text-align: left;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
basic-summary-table tr {
|
|
26
|
+
text-align: right;
|
|
27
|
+
|
|
28
|
+
*:first-child {
|
|
29
|
+
text-align: left;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
basic-summary-table th,
|
|
34
|
+
basic-summary-table td {
|
|
35
|
+
padding: var(--basic-summary-table-cell-padding-block) var(--basic-summary-table-cell-padding-inline);
|
|
36
|
+
border-block-end: var(--basic-border-width) solid var(--basic-color-border);
|
|
37
|
+
vertical-align: top;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
basic-summary-table td {
|
|
41
|
+
font-variant-numeric: tabular-nums;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
basic-summary-table thead th {
|
|
45
|
+
background: var(--basic-color-surface-muted);
|
|
46
|
+
font-weight: 700;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
basic-summary-table tbody tr:last-child th,
|
|
50
|
+
basic-summary-table tbody tr:last-child td {
|
|
51
|
+
border-block-end: 0;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
basic-summary-table tbody th {
|
|
55
|
+
font-weight: 600;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
basic-summary-table tbody td {
|
|
59
|
+
color: var(--basic-color-text-muted);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
basic-summary-table tfoot th,
|
|
63
|
+
basic-summary-table tfoot td {
|
|
64
|
+
border-block-start: calc(var(--basic-border-width) * 2) solid var(--basic-color-border);
|
|
65
|
+
border-block-end: 0;
|
|
66
|
+
background: var(--basic-color-surface-muted);
|
|
67
|
+
font-weight: 700;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
basic-summary-table tfoot td[data-summary-empty] {
|
|
71
|
+
color: var(--basic-color-text-muted);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
basic-summary-table tfoot td[data-summary-total] {
|
|
75
|
+
color: inherit;
|
|
76
|
+
}
|