@lmfaole/basics 0.4.0 → 0.5.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/LICENSE +21 -0
- package/README.md +78 -499
- package/basic-components/basic-accordion/README.md +53 -0
- package/{components → basic-components}/basic-accordion/index.js +59 -37
- package/basic-components/basic-alert/README.md +48 -0
- package/basic-components/basic-carousel/README.md +108 -0
- package/basic-components/basic-carousel/index.d.ts +73 -0
- package/basic-components/basic-carousel/index.js +255 -0
- package/basic-components/basic-carousel/register.js +3 -0
- package/basic-components/basic-dialog/README.md +57 -0
- package/basic-components/basic-popover/README.md +56 -0
- package/basic-components/basic-summary-table/README.md +93 -0
- package/basic-components/basic-table/README.md +89 -0
- package/basic-components/basic-tabs/README.md +63 -0
- package/basic-components/basic-toast/README.md +62 -0
- package/{components → basic-components}/basic-toast/index.d.ts +3 -0
- package/{components → basic-components}/basic-toast/index.js +264 -3
- package/basic-components/basic-toc/README.md +43 -0
- package/basic-components/basic-toc/register.d.ts +1 -0
- package/basic-styling/components/basic-accordion.css +38 -4
- package/basic-styling/components/basic-carousel.css +183 -0
- package/basic-styling/components/basic-popover.css +2 -4
- package/basic-styling/components/basic-summary-table.css +27 -5
- package/basic-styling/components/basic-table.css +22 -4
- package/basic-styling/components/basic-tabs.css +26 -10
- package/basic-styling/components.css +2 -0
- package/basic-styling/forms.css +55 -0
- package/basic-styling/global.css +1 -0
- package/basic-styling/interaction.css +90 -0
- package/basic-styling/tokens/palette.css +112 -0
- package/basic-styling/tokens/palette.tokens.json +768 -0
- package/index.d.ts +10 -9
- package/index.js +10 -9
- package/package.json +49 -29
- package/readme.mdx +0 -6
- /package/{components → basic-components}/basic-accordion/index.d.ts +0 -0
- /package/{components → basic-components}/basic-accordion/register.d.ts +0 -0
- /package/{components → basic-components}/basic-accordion/register.js +0 -0
- /package/{components → basic-components}/basic-alert/index.d.ts +0 -0
- /package/{components → basic-components}/basic-alert/index.js +0 -0
- /package/{components → basic-components}/basic-alert/register.d.ts +0 -0
- /package/{components → basic-components}/basic-alert/register.js +0 -0
- /package/{components/basic-dialog → basic-components/basic-carousel}/register.d.ts +0 -0
- /package/{components → basic-components}/basic-dialog/index.d.ts +0 -0
- /package/{components → basic-components}/basic-dialog/index.js +0 -0
- /package/{components/basic-popover → basic-components/basic-dialog}/register.d.ts +0 -0
- /package/{components → basic-components}/basic-dialog/register.js +0 -0
- /package/{components → basic-components}/basic-popover/index.d.ts +0 -0
- /package/{components → basic-components}/basic-popover/index.js +0 -0
- /package/{components/basic-summary-table → basic-components/basic-popover}/register.d.ts +0 -0
- /package/{components → basic-components}/basic-popover/register.js +0 -0
- /package/{components → basic-components}/basic-summary-table/index.d.ts +0 -0
- /package/{components → basic-components}/basic-summary-table/index.js +0 -0
- /package/{components/basic-table → basic-components/basic-summary-table}/register.d.ts +0 -0
- /package/{components → basic-components}/basic-summary-table/register.js +0 -0
- /package/{components → basic-components}/basic-table/index.d.ts +0 -0
- /package/{components → basic-components}/basic-table/index.js +0 -0
- /package/{components/basic-tabs → basic-components/basic-table}/register.d.ts +0 -0
- /package/{components → basic-components}/basic-table/register.js +0 -0
- /package/{components → basic-components}/basic-tabs/index.d.ts +0 -0
- /package/{components → basic-components}/basic-tabs/index.js +0 -0
- /package/{components/basic-toast → basic-components/basic-tabs}/register.d.ts +0 -0
- /package/{components → basic-components}/basic-tabs/register.js +0 -0
- /package/{components/basic-toc → basic-components/basic-toast}/register.d.ts +0 -0
- /package/{components → basic-components}/basic-toast/register.js +0 -0
- /package/{components → basic-components}/basic-toc/index.d.ts +0 -0
- /package/{components → basic-components}/basic-toc/index.js +0 -0
- /package/{components → basic-components}/basic-toc/register.js +0 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Ole Jorgen Bakken
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# `@lmfaole/basics`
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Unstyled custom elements for common UI patterns, with an optional starter CSS layer.
|
|
4
4
|
|
|
5
5
|
## Install
|
|
6
6
|
|
|
@@ -8,233 +8,18 @@ Simple custom elements and DOM helpers, with optional starter styles.
|
|
|
8
8
|
pnpm add @lmfaole/basics
|
|
9
9
|
```
|
|
10
10
|
|
|
11
|
-
##
|
|
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
|
-
|
|
43
|
-
## Storybook
|
|
44
|
-
|
|
45
|
-
```sh
|
|
46
|
-
pnpm storybook
|
|
47
|
-
```
|
|
48
|
-
|
|
49
|
-
```sh
|
|
50
|
-
pnpm build-storybook
|
|
51
|
-
```
|
|
52
|
-
|
|
53
|
-
```sh
|
|
54
|
-
pnpm test:storybook
|
|
55
|
-
```
|
|
56
|
-
|
|
57
|
-
```sh
|
|
58
|
-
pnpm test:storybook:coverage
|
|
59
|
-
```
|
|
60
|
-
|
|
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.
|
|
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/`.
|
|
68
|
-
|
|
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.
|
|
70
|
-
|
|
71
|
-
GitHub Actions now splits Storybook automation by purpose:
|
|
72
|
-
|
|
73
|
-
- `CI` runs the browser-backed Storybook test suite on pull requests and pushes to `main`.
|
|
74
|
-
- `Storybook Preview` builds Storybook for pull requests and uploads `storybook-static` as an artifact.
|
|
75
|
-
- `Storybook Pages` deploys the built Storybook from `main` to GitHub Pages.
|
|
76
|
-
- `Chromatic` publishes Storybook builds on branch pushes when the `CHROMATIC_PROJECT_TOKEN` repository secret is configured.
|
|
77
|
-
|
|
78
|
-
## Changesets
|
|
79
|
-
|
|
80
|
-
For changes that affect the published package, run:
|
|
81
|
-
|
|
82
|
-
```sh
|
|
83
|
-
pnpm changeset
|
|
84
|
-
```
|
|
85
|
-
|
|
86
|
-
Commit the generated Markdown file under `.changeset/` with the rest of your work. If a change is repo-only and does not affect the published package, no changeset file is needed.
|
|
87
|
-
|
|
88
|
-
## Releasing
|
|
89
|
-
|
|
90
|
-
Merging changesets into `main` causes the `Release` workflow to open or update a `chore: release` pull request. Merging that release pull request will:
|
|
91
|
-
|
|
92
|
-
1. run `pnpm release`
|
|
93
|
-
2. publish the package to npm with trusted publishing from GitHub Actions
|
|
94
|
-
3. create the matching `vX.Y.Z` git tag and GitHub Release
|
|
95
|
-
4. attach the packed tarball to the GitHub Release
|
|
96
|
-
|
|
97
|
-
Trusted publishing must be configured on npm for `@lmfaole/basics` against the GitHub Actions workflow file `.github/workflows/release.yml` in the `lmfaole/basics` repository. No `NPM_TOKEN` repository secret is needed once trusted publishing is active.
|
|
98
|
-
|
|
99
|
-
If a release needs to be retried after the workflow changes land, use the `Release` workflow's `publish_current_version` manual input to publish the current `package.json` version from `main` when it is still unpublished.
|
|
100
|
-
|
|
101
|
-
## Commits
|
|
102
|
-
|
|
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`.
|
|
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.
|
|
11
|
+
## Quick Start
|
|
166
12
|
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
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
|
-
|
|
185
|
-
## Basic Popover
|
|
186
|
-
|
|
187
|
-
```html
|
|
188
|
-
<basic-popover data-label="Filtre" data-anchor-trigger data-position-area="bottom">
|
|
189
|
-
<button type="button" data-popover-open>Toggle popover</button>
|
|
190
|
-
|
|
191
|
-
<section data-popover-panel>
|
|
192
|
-
<h2 data-popover-title>Filtre</h2>
|
|
193
|
-
<p>Popover body.</p>
|
|
194
|
-
<button type="button" data-popover-close>Close</button>
|
|
195
|
-
</section>
|
|
196
|
-
</basic-popover>
|
|
197
|
-
|
|
198
|
-
<script type="module">
|
|
199
|
-
import "@lmfaole/basics/components/basic-popover/register";
|
|
200
|
-
</script>
|
|
201
|
-
```
|
|
202
|
-
|
|
203
|
-
The element upgrades popover trigger-and-panel markup into an accessible non-modal overlay without adding any styles of its own.
|
|
204
|
-
|
|
205
|
-
### Attributes
|
|
206
|
-
|
|
207
|
-
- `data-label`: fallback accessible name when the popover has no `aria-label`, `aria-labelledby`, or `[data-popover-title]`.
|
|
208
|
-
- `data-anchor-trigger`: uses the opener as the popover's implicit anchor so consumer CSS can position the panel relative to the trigger.
|
|
209
|
-
- `data-position-area`: sets the CSS anchor-positioning area used when `data-anchor-trigger` is enabled. Defaults to `bottom`.
|
|
210
|
-
- `data-position-try-fallbacks`: optional comma-separated fallback list used when the default anchored placement would overflow. By default the component derives a sensible sequence from `data-position-area`.
|
|
211
|
-
|
|
212
|
-
### Behavior
|
|
213
|
-
|
|
214
|
-
- Uses the native Popover API in auto mode for outside-click and `Esc` dismissal.
|
|
215
|
-
- Syncs `aria-expanded`, `aria-controls`, and `data-open` between the trigger and panel.
|
|
216
|
-
- Restores focus to the opener when dismissal should return to it, while preserving focus on an outside control the user explicitly clicked.
|
|
217
|
-
- When `data-anchor-trigger` is set, opening the popover passes the trigger as the Popover API `source`, establishes the panel's implicit anchor, and applies the configured `position-area`.
|
|
218
|
-
- When `data-anchor-trigger` is set and `data-position-try-fallbacks` is not provided, the component derives a fallback sequence from the default placement:
|
|
219
|
-
`bottom` or `top` start with `flip-block`, while `left` or `right` start with `flip-inline`.
|
|
220
|
-
- `[data-popover-close]` controls can dismiss the panel from inside the overlay.
|
|
221
|
-
|
|
222
|
-
### Markup Contract
|
|
223
|
-
|
|
224
|
-
- Provide one descendant `[data-popover-panel]`.
|
|
225
|
-
- Use `[data-popover-open]` on buttons that should toggle the panel.
|
|
226
|
-
- Use `[data-popover-title]` for the popover heading when you want it to become the accessible name.
|
|
227
|
-
- If you set `data-anchor-trigger`, you can tune the default anchored placement with `data-position-area` and optionally override its overflow fallbacks with `data-position-try-fallbacks`.
|
|
228
|
-
- Keep layout and styling outside the package; the component only manages semantics and open or close behavior.
|
|
229
|
-
|
|
230
|
-
## Basic Dialog
|
|
13
|
+
1. Import the register module for the component you want to use.
|
|
14
|
+
2. Render the expected HTML markup.
|
|
15
|
+
3. Optionally import the starter styles.
|
|
231
16
|
|
|
232
17
|
```html
|
|
233
|
-
<basic-dialog data-label="
|
|
18
|
+
<basic-dialog data-label="Confirm action">
|
|
234
19
|
<button type="button" data-dialog-open>Open dialog</button>
|
|
235
20
|
|
|
236
21
|
<dialog data-dialog-panel>
|
|
237
|
-
<h2 data-dialog-title>
|
|
22
|
+
<h2 data-dialog-title>Confirm action</h2>
|
|
238
23
|
<p>Dialog body.</p>
|
|
239
24
|
<button type="button" data-dialog-close>Cancel</button>
|
|
240
25
|
<button type="button" data-dialog-close data-dialog-close-value="confirmed">
|
|
@@ -244,317 +29,111 @@ The element upgrades popover trigger-and-panel markup into an accessible non-mod
|
|
|
244
29
|
</basic-dialog>
|
|
245
30
|
|
|
246
31
|
<script type="module">
|
|
247
|
-
import "@lmfaole/basics/components/basic-dialog/register";
|
|
32
|
+
import "@lmfaole/basics/basic-components/basic-dialog/register";
|
|
248
33
|
</script>
|
|
249
34
|
```
|
|
250
35
|
|
|
251
|
-
|
|
36
|
+
Import register modules once in your app entry point. They define the custom element and leave styling to your application unless you also opt into `basic-styling`.
|
|
252
37
|
|
|
253
|
-
|
|
38
|
+
## Component Guides
|
|
254
39
|
|
|
255
|
-
|
|
256
|
-
- `data-backdrop-close`: allows clicks on the dialog backdrop to close the modal.
|
|
40
|
+
Each component now has its own colocated README with markup, attributes, behavior, and usage notes:
|
|
257
41
|
|
|
258
|
-
|
|
42
|
+
- [`basic-alert`](./basic-components/basic-alert/README.md): inline live-region alerts
|
|
43
|
+
- [`basic-accordion`](./basic-components/basic-accordion/README.md): single-open or multi-open disclosure sections
|
|
44
|
+
- [`basic-carousel`](./basic-components/basic-carousel/README.md): scroll-snap carousels with native CSS controls where supported
|
|
45
|
+
- [`basic-dialog`](./basic-components/basic-dialog/README.md): modal dialogs built on native `<dialog>`
|
|
46
|
+
- [`basic-popover`](./basic-components/basic-popover/README.md): non-modal overlays using the Popover API
|
|
47
|
+
- [`basic-summary-table`](./basic-components/basic-summary-table/README.md): tables with generated totals in `<tfoot>`
|
|
48
|
+
- [`basic-table`](./basic-components/basic-table/README.md): accessible table naming and header relationships
|
|
49
|
+
- [`basic-tabs`](./basic-components/basic-tabs/README.md): accessible tablists and panels
|
|
50
|
+
- [`basic-toast`](./basic-components/basic-toast/README.md): transient toast notifications
|
|
51
|
+
- [`basic-toc`](./basic-components/basic-toc/README.md): generated table-of-contents navigation
|
|
259
52
|
|
|
260
|
-
|
|
261
|
-
- Restores focus to the element that opened the dialog when the modal closes.
|
|
262
|
-
- `Esc` closes the modal through the platform's dialog behavior.
|
|
263
|
-
- `[data-dialog-close]` controls can optionally set `data-dialog-close-value` to pass a close value.
|
|
264
|
-
|
|
265
|
-
### Markup Contract
|
|
266
|
-
|
|
267
|
-
- Provide one descendant `<dialog data-dialog-panel>`.
|
|
268
|
-
- Use `[data-dialog-open]` on buttons that should open the modal.
|
|
269
|
-
- Use `[data-dialog-title]` for the dialog heading when you want it to become the accessible name.
|
|
270
|
-
- Keep layout and styling outside the package; the component only manages semantics and open or close behavior.
|
|
271
|
-
|
|
272
|
-
## Basic Accordion
|
|
53
|
+
## Optional Styling
|
|
273
54
|
|
|
274
|
-
|
|
275
|
-
<basic-accordion>
|
|
276
|
-
<details open>
|
|
277
|
-
<summary>Oversikt</summary>
|
|
278
|
-
<p>Viser en kort oppsummering.</p>
|
|
279
|
-
</details>
|
|
280
|
-
|
|
281
|
-
<details>
|
|
282
|
-
<summary>Implementasjon</summary>
|
|
283
|
-
<p>Viser implementasjonsdetaljer.</p>
|
|
284
|
-
</details>
|
|
285
|
-
</basic-accordion>
|
|
55
|
+
The components are unstyled by default. To opt into the starter CSS:
|
|
286
56
|
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
</script>
|
|
57
|
+
```css
|
|
58
|
+
@import "@lmfaole/basics/basic-styling";
|
|
290
59
|
```
|
|
291
60
|
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
### Attributes
|
|
295
|
-
|
|
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.
|
|
298
|
-
|
|
299
|
-
### Markup Contract
|
|
300
|
-
|
|
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.
|
|
305
|
-
|
|
306
|
-
### Behavior
|
|
307
|
-
|
|
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.
|
|
313
|
-
|
|
314
|
-
## Basic Tabs
|
|
315
|
-
|
|
316
|
-
```html
|
|
317
|
-
<basic-tabs data-label="Eksempelkode">
|
|
318
|
-
<div data-tabs-list>
|
|
319
|
-
<button type="button" data-tab>Oversikt</button>
|
|
320
|
-
<button type="button" data-tab>Implementasjon</button>
|
|
321
|
-
<button type="button" data-tab>Tilgjengelighet</button>
|
|
322
|
-
</div>
|
|
323
|
-
|
|
324
|
-
<section data-tab-panel>
|
|
325
|
-
<p>Viser en kort oppsummering.</p>
|
|
326
|
-
</section>
|
|
327
|
-
<section data-tab-panel>
|
|
328
|
-
<p>Viser implementasjonsdetaljer.</p>
|
|
329
|
-
</section>
|
|
330
|
-
<section data-tab-panel>
|
|
331
|
-
<p>Viser tilgjengelighetsnotater.</p>
|
|
332
|
-
</section>
|
|
333
|
-
</basic-tabs>
|
|
61
|
+
Or import the global layer and component layer separately:
|
|
334
62
|
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
63
|
+
```css
|
|
64
|
+
@import "@lmfaole/basics/basic-styling/global.css";
|
|
65
|
+
@import "@lmfaole/basics/basic-styling/components.css";
|
|
338
66
|
```
|
|
339
67
|
|
|
340
|
-
|
|
68
|
+
You can also import individual files from:
|
|
341
69
|
|
|
342
|
-
|
|
70
|
+
- `@lmfaole/basics/basic-styling/forms.css`
|
|
71
|
+
- `@lmfaole/basics/basic-styling/tokens/*`
|
|
72
|
+
- `@lmfaole/basics/basic-styling/components/basic-*.css`
|
|
343
73
|
|
|
344
|
-
|
|
345
|
-
- `data-activation`: chooses whether arrow-key focus changes also activate the panel. Supported values are `automatic` and `manual`.
|
|
346
|
-
- `data-selected-index`: sets the initially selected tab by zero-based index. Defaults to the first enabled tab.
|
|
74
|
+
The starter styling is intentionally minimal. It provides tokens, spacing, and baseline component styles without taking over your design system.
|
|
347
75
|
|
|
348
|
-
###
|
|
76
|
+
### Selection Panels
|
|
349
77
|
|
|
350
|
-
|
|
351
|
-
- `aria-selected`, `aria-controls`, `aria-labelledby`, `hidden`, and `data-selected` stay in sync with the active tab.
|
|
352
|
-
- Click, `ArrowLeft`, `ArrowRight`, `Home`, and `End` move between tabs.
|
|
353
|
-
- Disabled tabs are skipped during keyboard navigation.
|
|
354
|
-
- In `manual` mode, arrow keys move focus and `Enter` or `Space` activates the focused tab.
|
|
355
|
-
|
|
356
|
-
### Markup Contract
|
|
357
|
-
|
|
358
|
-
- Provide one descendant element with `data-tabs-list` to hold the interactive tab controls.
|
|
359
|
-
- Provide matching counts of `[data-tab]` and `[data-tab-panel]` descendants in the same order.
|
|
360
|
-
- Prefer `<button>` elements for tabs so click and keyboard activation stay native.
|
|
361
|
-
- Keep layout and styling outside the package; the component only manages semantics, state, and keyboard behavior.
|
|
362
|
-
|
|
363
|
-
## Basic Table
|
|
78
|
+
The form layer can render a native checkbox or radio like a selectable panel by adding `data-panel` to the input.
|
|
364
79
|
|
|
365
80
|
```html
|
|
366
|
-
<
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
>
|
|
372
|
-
|
|
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>
|
|
81
|
+
<label>
|
|
82
|
+
<input type="checkbox" name="days" value="day-1" data-panel checked />
|
|
83
|
+
<span>
|
|
84
|
+
<strong>Day 1: Product systems</strong>
|
|
85
|
+
<span>Keynotes, leadership sessions, and case studies.</span>
|
|
86
|
+
</span>
|
|
87
|
+
</label>
|
|
418
88
|
```
|
|
419
89
|
|
|
420
|
-
|
|
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
|
|
90
|
+
Use the pattern like this:
|
|
449
91
|
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
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
|
-
```
|
|
92
|
+
- Import `@lmfaole/basics/basic-styling/forms.css`, `global.css`, or the full `basic-styling` entry point.
|
|
93
|
+
- Put `data-panel` on the native checkbox or radio, not on the label.
|
|
94
|
+
- Keep the control as a direct child of the label.
|
|
95
|
+
- Place the visible body copy after the input in a sibling `span` or `div`.
|
|
96
|
+
- Use native `fieldset` and `legend` when the choices belong to one group.
|
|
97
|
+
- Keep shared `name` values on radio groups so the browser preserves single-select behavior.
|
|
501
98
|
|
|
502
|
-
|
|
99
|
+
This is still a native checkbox or radio. Keyboard behavior, form submission, validation, checked state, and radio-group semantics all stay browser-driven.
|
|
100
|
+
See Storybook `Native Elements/Forms` for live examples of the same markup.
|
|
503
101
|
|
|
504
|
-
|
|
102
|
+
## Package Entry Points
|
|
505
103
|
|
|
506
|
-
-
|
|
507
|
-
-
|
|
508
|
-
-
|
|
509
|
-
-
|
|
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.
|
|
104
|
+
- Register a custom element: `@lmfaole/basics/basic-components/<component>/register`
|
|
105
|
+
- Import a component module directly: `@lmfaole/basics/basic-components/<component>`
|
|
106
|
+
- Root module exports the component classes and helpers from `@lmfaole/basics`
|
|
107
|
+
- Legacy compatibility aliases remain available under `@lmfaole/basics/components/<component>`
|
|
514
108
|
|
|
515
|
-
|
|
109
|
+
## Browser Support
|
|
516
110
|
|
|
517
|
-
|
|
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.
|
|
111
|
+
The package targets modern evergreen browsers. The live widgets below render in Storybook's Readme page via the official `<baseline-status>` custom element, and each line also links to the underlying feature page for plain Markdown viewers.
|
|
522
112
|
|
|
523
|
-
|
|
113
|
+
As of March 29, 2026, the biggest compatibility gaps are the shared style-query layer in Firefox and the native carousel marker/button controls outside Chromium-based browsers.
|
|
524
114
|
|
|
525
|
-
-
|
|
526
|
-
-
|
|
527
|
-
-
|
|
528
|
-
-
|
|
115
|
+
- Core custom elements (`basic-alert`, `basic-accordion`, `basic-carousel`, `basic-summary-table`, `basic-table`, `basic-tabs`, `basic-toc`, `basic-toast`): <baseline-status featureId="autonomous-custom-elements"></baseline-status> ([Autonomous custom elements](https://web-platform-dx.github.io/web-features-explorer/features/autonomous-custom-elements/))
|
|
116
|
+
- `basic-dialog` modal behavior: <baseline-status featureId="dialog"></baseline-status> ([`<dialog>`](https://web-platform-dx.github.io/web-features-explorer/features/dialog/))
|
|
117
|
+
- `basic-popover` overlays and `basic-toast` top-layer placement: <baseline-status featureId="popover"></baseline-status> ([Popover](https://web-platform-dx.github.io/web-features-explorer/features/popover/))
|
|
118
|
+
- `basic-carousel` scroll-snap foundation: <baseline-status featureId="scroll-snap"></baseline-status> ([Scroll snap](https://web-platform-dx.github.io/web-features-explorer/features/scroll-snap/))
|
|
119
|
+
- `basic-carousel` native marker and arrow controls: <baseline-status featureId="scroll-markers"></baseline-status> <baseline-status featureId="scroll-buttons"></baseline-status> ([Scroll markers](https://web-platform-dx.github.io/web-features-explorer/features/scroll-markers/), [`::scroll-button`](https://web-platform-dx.github.io/web-features-explorer/features/scroll-buttons/))
|
|
120
|
+
- Starter CSS color and selector baseline: <baseline-status featureId="nesting"></baseline-status> <baseline-status featureId="has"></baseline-status> <baseline-status featureId="light-dark"></baseline-status> <baseline-status featureId="oklab"></baseline-status> ([Nesting](https://web-platform-dx.github.io/web-features-explorer/features/nesting/), [`:has()`](https://web-platform-dx.github.io/web-features-explorer/features/has/), [`light-dark()`](https://web-platform-dx.github.io/web-features-explorer/features/light-dark/), [Oklab and OkLCh](https://web-platform-dx.github.io/web-features-explorer/features/oklab/))
|
|
121
|
+
- Shared interaction state layer and other style-query-driven refinements: <baseline-status featureId="container-style-queries"></baseline-status> ([Container style queries](https://web-platform-dx.github.io/web-features-explorer/features/container-style-queries/))
|
|
529
122
|
|
|
530
|
-
##
|
|
531
|
-
|
|
532
|
-
```html
|
|
533
|
-
<basic-toc data-title="Innhold">
|
|
534
|
-
<nav aria-label="Innhold" data-page-toc-nav></nav>
|
|
535
|
-
</basic-toc>
|
|
123
|
+
## Storybook
|
|
536
124
|
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
</script>
|
|
125
|
+
```sh
|
|
126
|
+
pnpm storybook
|
|
540
127
|
```
|
|
541
128
|
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
- `data-title`: sets the generated nav's accessible label. Defaults to `Innhold`.
|
|
547
|
-
- `data-heading-selector`: limits which headings are indexed. Defaults to `h1, h2, h3, h4, h5, h6`.
|
|
548
|
-
|
|
549
|
-
### Behavior
|
|
129
|
+
```sh
|
|
130
|
+
pnpm build-storybook
|
|
131
|
+
```
|
|
550
132
|
|
|
551
|
-
|
|
552
|
-
- Duplicate headings receive unique fragment ids.
|
|
553
|
-
- Hidden headings are ignored.
|
|
554
|
-
- The outline is rebuilt when matching headings are added or changed.
|
|
133
|
+
Storybook now focuses on package documentation pages such as the readme, changelog, contributing guide, security policy, and palette tokens.
|
|
555
134
|
|
|
556
|
-
|
|
135
|
+
## More Docs
|
|
557
136
|
|
|
558
|
-
-
|
|
559
|
-
-
|
|
560
|
-
-
|
|
137
|
+
- [CHANGELOG.md](./CHANGELOG.md)
|
|
138
|
+
- [CONTRIBUTING.md](./CONTRIBUTING.md)
|
|
139
|
+
- [SECURITY.md](./SECURITY.md)
|