@jungherz-de/notionkit-elements 1.20.1 → 1.21.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/CHANGELOG.md +32 -0
- package/README.md +6 -5
- package/SKILL.md +36 -33
- package/dist/components/base.js +2 -2
- package/dist/components/nk-table-view.js +46 -0
- package/dist/notionkit-elements.esm.js +50 -4
- package/dist/notionkit-elements.esm.min.js +1 -1
- package/dist/notionkit-elements.esm.min.js.map +1 -1
- package/dist/notionkit-elements.js +50 -4
- package/dist/notionkit-elements.min.js +1 -1
- package/package.json +3 -3
- package/src/components/data/nk-table-view.js +46 -0
- package/src/util/strings.js +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,37 @@ All notable changes to NotionKit Elements are documented here. The format follow
|
|
|
4
4
|
[Keep a Changelog](https://keepachangelog.com/en/1.1.0/); versions follow
|
|
5
5
|
[Semantic Versioning](https://semver.org/).
|
|
6
6
|
|
|
7
|
+
## [1.21.0] – 2026-10-18
|
|
8
|
+
|
|
9
|
+
Built against NotionKit CSS 1.21.0 (peer `>= 1.21.0`).
|
|
10
|
+
|
|
11
|
+
### Added
|
|
12
|
+
- **Select all from the header of a checkbox column (#4).** A `checkbox`
|
|
13
|
+
column with `selectAll: true` is a selection column: its header holds the
|
|
14
|
+
cells' own checkbox instead of a name – empty when no row is chosen, a dash
|
|
15
|
+
for some, a check for all (`th.select-all`, NotionKit 1.21.0) – and sorts
|
|
16
|
+
nothing. A click or Space sets the column for every row the view has – a
|
|
17
|
+
dash selects all, as in Notion –, renders the cells again and fires **one**
|
|
18
|
+
`nk-change { key, value, all: true, rows }`, so an app that keeps its own
|
|
19
|
+
selection follows with one update instead of one per row; Space leaves the
|
|
20
|
+
focus on the header box. A row's own box keeps the header in step without
|
|
21
|
+
losing its focus. Without rows the header box is disabled. What "all" means
|
|
22
|
+
beyond the view's rows – more pages, a filter on the server – stays with
|
|
23
|
+
the app. Its accessible name is the new built-in text `selectAll`
|
|
24
|
+
("Select all" / "Alle auswählen"). Requested by Mailverse for its
|
|
25
|
+
quarantine list.
|
|
26
|
+
- `<nk-check indeterminate>` finally shows its mixed state – a dash in the
|
|
27
|
+
accent box (NotionKit 1.21.0); it looked empty before. The docs show it
|
|
28
|
+
next to the table's selection column.
|
|
29
|
+
|
|
30
|
+
### Fixed
|
|
31
|
+
- Through NotionKit 1.21.0: a table row with a checkbox cell was 39.5px
|
|
32
|
+
instead of 36px; a selection column would have grown every row.
|
|
33
|
+
|
|
34
|
+
### Tests
|
|
35
|
+
- The parity test runs a script in the class markup too, for what only a
|
|
36
|
+
script sets – an `indeterminate` checkbox – as the docs page does.
|
|
37
|
+
|
|
7
38
|
## [1.20.1] – 2026-10-14
|
|
8
39
|
|
|
9
40
|
Elements only; NotionKit CSS stays at 1.20.0 (peer `>= 1.20.0`).
|
|
@@ -806,6 +837,7 @@ built and tested against NotionKit CSS 1.1.1 (peer range `>= 1.0.0`).
|
|
|
806
837
|
import, never in the core bundle – shadow-less, adding `nk-block-host` to
|
|
807
838
|
itself so the foundation's editor adapter rules apply.
|
|
808
839
|
|
|
840
|
+
[1.21.0]: https://github.com/JUNGHERZ/NotionKit-Elements/releases/tag/v1.21.0
|
|
809
841
|
[1.20.1]: https://github.com/JUNGHERZ/NotionKit-Elements/releases/tag/v1.20.1
|
|
810
842
|
[1.20.0]: https://github.com/JUNGHERZ/NotionKit-Elements/releases/tag/v1.20.0
|
|
811
843
|
[1.19.0]: https://github.com/JUNGHERZ/NotionKit-Elements/releases/tag/v1.19.0
|
package/README.md
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
<h1 align="center">🧩 NotionKit Elements</h1>
|
|
2
2
|
|
|
3
3
|
<p align="center">
|
|
4
|
-
<a href="https://www.npmjs.com/package/@jungherz-de/notionkit-elements"><img src="https://img.shields.io/badge/version-1.
|
|
4
|
+
<a href="https://www.npmjs.com/package/@jungherz-de/notionkit-elements"><img src="https://img.shields.io/badge/version-1.21.0-2383e2?style=flat-square" alt="Version"></a>
|
|
5
5
|
<a href="#"><img src="https://img.shields.io/badge/vanilla_JS-no_dependencies-448361?style=flat-square" alt="Vanilla JS"></a>
|
|
6
6
|
<a href="#"><img src="https://img.shields.io/badge/elements-88-529cca?style=flat-square" alt="88 Elements"></a>
|
|
7
7
|
<a href="LICENSE"><img src="https://img.shields.io/badge/license-MIT-9065b0?style=flat-square" alt="MIT License"></a>
|
|
8
|
-
<a href="CHANGELOG.md"><img src="https://img.shields.io/badge/changelog-v1.
|
|
8
|
+
<a href="CHANGELOG.md"><img src="https://img.shields.io/badge/changelog-v1.21.0-lightgrey?style=flat-square" alt="Changelog"></a>
|
|
9
9
|
<a href="https://www.npmjs.com/package/@jungherz-de/notionkit-elements"><img src="https://img.shields.io/badge/npm-%40jungherz--de%2Fnotionkit--elements-cb3837?style=flat-square&logo=npm" alt="npm"></a>
|
|
10
10
|
</p>
|
|
11
11
|
|
|
@@ -71,8 +71,8 @@ It is the **app layer** of the NotionKit family – three layers, one design lan
|
|
|
71
71
|
<!DOCTYPE html>
|
|
72
72
|
<html lang="en" data-theme="light">
|
|
73
73
|
<head>
|
|
74
|
-
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@jungherz-de/notionkit@1.
|
|
75
|
-
<script src="https://cdn.jsdelivr.net/npm/@jungherz-de/notionkit-elements@1.
|
|
74
|
+
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@jungherz-de/notionkit@1.21.0/notionkit.min.css">
|
|
75
|
+
<script src="https://cdn.jsdelivr.net/npm/@jungherz-de/notionkit-elements@1.21.0/dist/notionkit-elements.min.js"></script>
|
|
76
76
|
</head>
|
|
77
77
|
<body class="nk-body">
|
|
78
78
|
<nk-field label="Display name" desc="Shown next to your comments">
|
|
@@ -104,7 +104,7 @@ Without a build step, an import map can point at the minified module instead: `"
|
|
|
104
104
|
|
|
105
105
|
Do not mix the full bundle with the per-component files: each brings its own `NkElement`. With the bundle, take `componentsSheet` and `NkElement` from the bundle (`NotionKitElements.componentsSheet` from the `<script>` build).
|
|
106
106
|
|
|
107
|
-
Two prerequisites, always: `notionkit.css` on the document (the peer dependency, `>= 1.
|
|
107
|
+
Two prerequisites, always: `notionkit.css` on the document (the peer dependency, `>= 1.21.0`; 1.21.0 brings the select-all header of a table and the dash of an indeterminate checkbox and keeps a row with a checkbox at 36px, 1.20.0 brings the appearance glyph of a three-state theme toggle, 1.19.1 keeps a toast with an × at its height, 1.19.0 brings the toast with an action, 1.18.0 brings a bar and its label in one row, stacked properties that keep to their card on a phone and icons in the copy field, 1.17.0 brings a step's label and a gallery card as links, 1.16.0 brings `--nk-block-space` and `flush` for blocks in a column, keeps a wide progress bar and a stretched button's label in shape and lays floating menus above dialogs, 1.15.0 brings table text with a tone and a second line, 1.14.0 brings the gallery view and a banner action that stands at the right edge again, 1.13.0 keeps fields inside narrow panels, leaves a page without icon its padding under the cover and makes cover heights tokens, 1.12.0 brings a tag or button beside a panel's title, lists and grids without outer margin, text values, steps with states in any order and in a row, scrolling tabs, a cap for full pages and buttons per table row, 1.11.0 keeps a floating menu inside an open modal or dialog in place and inside the window and brings the banner's action as a button, fields that share a row and tooltips of several lines, 1.10.1 lets a disabled button show its tooltip, 1.10.0 brings the collapsing sidebar, the resizable side peek, the dialog and the tooltip, 1.9.0 the date picker and the calendar view, 1.8.0 the side peek, the bookmark, the copy field and pictures on the profile row, 1.7.0 the sheet, menus that float in and become sheets on a phone, the sidebar drawer, the database toolbar with filter pills and the steps, 1.7.1 minified files that carry all of it, 1.6.0 page properties, page options, list view, panels, prose and the avatar, 1.5.1 the safe areas, 1.5.0 the Notion-2025 tokens, the nine tag colours and the filled inputs; from 1.5.0 on, Elements and the foundation share one version number – the elements are built and tested against the same release) and `class="nk-body"` on `<body>`. The elements ship no visual CSS of their own – every rule comes from the foundation. The bundle injects the design tokens once as `@layer notionkit-defaults`, so any plain `:root { --nk-accent: … }` of yours re-brands every element in both themes.
|
|
108
108
|
|
|
109
109
|
## Elements
|
|
110
110
|
|
|
@@ -161,6 +161,7 @@ The elements on the page take new texts at once, after `setStrings()` and when `
|
|
|
161
161
|
| `commandPlaceholder` | `nk-cmdk` | `placeholder` | Search or type a command … | Suchen oder Befehl eingeben … |
|
|
162
162
|
| `emojiPlaceholder` | `nk-emoji-picker` | `placeholder` | Search… | Suchen … |
|
|
163
163
|
| `toggleTheme` | `nk-theme-toggle` | `title` | Toggle light / dark | Hell / Dunkel |
|
|
164
|
+
| `selectAll` | `nk-table-view` (a `checkbox` column with `selectAll`) | – | Select all | Alle auswählen |
|
|
164
165
|
| `appearance` | `nk-theme-toggle` (`modes` with `auto`) | `title` | Appearance: {mode} – click: {next} | Darstellung: {mode} – Klick: {next} |
|
|
165
166
|
| `themeAuto` | `nk-theme-toggle` (`modes` with `auto`) | – | automatic (follows the system) | automatisch (wie das System) |
|
|
166
167
|
| `themeLight` | `nk-theme-toggle` (`modes` with `auto`) | – | light | hell |
|
package/SKILL.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: notionkit-elements
|
|
3
|
-
description: NotionKit Elements is a vanilla-JS Web Components library (v1.
|
|
3
|
+
description: NotionKit Elements is a vanilla-JS Web Components library (v1.21.0) wrapping NotionKit CSS v1.21.0 – the calm, document-centric design system in the Notion idiom. 88 custom elements with the `nk-` prefix, Shadow DOM, automatic light/dark sync via data-theme on <html>, and form-associated controls. Use this reference whenever generating HTML that uses <nk-*> tags to get attributes, slots, events and composition right.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# NotionKit Elements – AI Component Reference
|
|
@@ -21,8 +21,8 @@ description: NotionKit Elements is a vanilla-JS Web Components library (v1.20.1)
|
|
|
21
21
|
<head>
|
|
22
22
|
<meta charset="UTF-8">
|
|
23
23
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
24
|
-
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@jungherz-de/notionkit@1.
|
|
25
|
-
<script src="https://cdn.jsdelivr.net/npm/@jungherz-de/notionkit-elements@1.
|
|
24
|
+
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@jungherz-de/notionkit@1.21.0/notionkit.min.css">
|
|
25
|
+
<script src="https://cdn.jsdelivr.net/npm/@jungherz-de/notionkit-elements@1.21.0/dist/notionkit-elements.min.js"></script>
|
|
26
26
|
</head>
|
|
27
27
|
<body class="nk-body">
|
|
28
28
|
<nk-btn variant="primary">Save</nk-btn>
|
|
@@ -412,9 +412,10 @@ Renders `button.nk-switch[role=switch]`; the stylesheet keys the knob on `aria-c
|
|
|
412
412
|
|
|
413
413
|
### 3.9 `<nk-check>` – Checkbox
|
|
414
414
|
|
|
415
|
-
A `label.nk-check` with a custom-drawn checkbox; the label text is slotted, so clicking it toggles the box.
|
|
415
|
+
A `label.nk-check` with a custom-drawn checkbox; the label text is slotted, so clicking it toggles the box. `indeterminate` shows a dash (NotionKit 1.21.0) – for a box over a group partly chosen.
|
|
416
416
|
|
|
417
417
|
```html
|
|
418
|
+
<nk-check indeterminate>All</nk-check>
|
|
418
419
|
<nk-check name="digest" value="weekly" checked>Weekly digest</nk-check>
|
|
419
420
|
<nk-check name="digest" value="mentions">Mentions only</nk-check>
|
|
420
421
|
```
|
|
@@ -437,6 +438,7 @@ A `label.nk-check` with a custom-drawn checkbox; the label text is slotted, so c
|
|
|
437
438
|
|
|
438
439
|
```html
|
|
439
440
|
<!-- equivalent class markup -->
|
|
441
|
+
<label class="nk-check"><input type="checkbox">All</label><script>document.currentScript.previousElementSibling.querySelector('input').indeterminate = true</script>
|
|
440
442
|
<label class="nk-check"><input type="checkbox" name="digest" value="weekly" checked>Weekly digest</label>
|
|
441
443
|
<label class="nk-check"><input type="checkbox" name="digest" value="mentions">Mentions only</label>
|
|
442
444
|
```
|
|
@@ -2659,13 +2661,14 @@ The view switcher with Notion’s toolbar: child views (`nk-table-view`, `nk-boa
|
|
|
2659
2661
|
|
|
2660
2662
|
### 3.78 `<nk-table-view>` – Table view
|
|
2661
2663
|
|
|
2662
|
-
Renders `columns` × `rows` as the NotionKit table. Cells are polymorphic (`text`, `select`, `multi-select`, `date`, `person`, `checkbox`, `url`, `number`, `progress`) and rendered as plain markup by the exported `renderPropertyCell()` – every cell rule starts with `.nk-table`, so a cell element of its own would never be styled. Header clicks sort with `sortable`. A `number` column stands right-aligned in figures of equal width, formatted by its `locale` and `format` (Intl.NumberFormat options); a person’s `color` takes one of the nine names. A column of type `actions` (NotionKit 1.12.0) sets buttons in each row from `column.actions` – `[{ action, label, icon, danger, disabled, tooltip }]` –, and a row’s value – a list of action names – picks which of them it shows; a click fires `nk-action { action, row, id, anchor }` instead of selecting the row. A `url` value may be `{ href, label, target }`: a link of your own, to another page of the app, with its own text. A text value may be `{ text, desc, color, tooltip }` (NotionKit 1.15.0): a quiet second line, one of Notion’s nine text colours – `orange` for an error –, the whole text in a tooltip. Sorting goes by the value, not the text shown: dates by their time, selects by the order of their options, empty cells last; `sortKey` on a column sorts by another field of the row, a `sort` in a cell’s object by that value. A `date` column with `format` – `'short'`, `'relative'` or the options of Intl.DateTimeFormat – shows ISO dates and date-times formatted in its `locale`.
|
|
2664
|
+
Renders `columns` × `rows` as the NotionKit table. Cells are polymorphic (`text`, `select`, `multi-select`, `date`, `person`, `checkbox`, `url`, `number`, `progress`) and rendered as plain markup by the exported `renderPropertyCell()` – every cell rule starts with `.nk-table`, so a cell element of its own would never be styled. Header clicks sort with `sortable`. A `number` column stands right-aligned in figures of equal width, formatted by its `locale` and `format` (Intl.NumberFormat options); a person’s `color` takes one of the nine names. A column of type `actions` (NotionKit 1.12.0) sets buttons in each row from `column.actions` – `[{ action, label, icon, danger, disabled, tooltip }]` –, and a row’s value – a list of action names – picks which of them it shows; a click fires `nk-action { action, row, id, anchor }` instead of selecting the row. A `url` value may be `{ href, label, target }`: a link of your own, to another page of the app, with its own text. A text value may be `{ text, desc, color, tooltip }` (NotionKit 1.15.0): a quiet second line, one of Notion’s nine text colours – `orange` for an error –, the whole text in a tooltip. Sorting goes by the value, not the text shown: dates by their time, selects by the order of their options, empty cells last; `sortKey` on a column sorts by another field of the row, a `sort` in a cell’s object by that value. A `date` column with `format` – `'short'`, `'relative'` or the options of Intl.DateTimeFormat – shows ISO dates and date-times formatted in its `locale`. A `checkbox` column with `selectAll: true` (1.21.0) is a selection column: its header is a checkbox – empty, a dash for some rows, a check for all – that sorts nothing; a click or Space sets the column for every row the view has (a dash selects all, as in Notion) and fires one `nk-change { key, value, all: true, rows }`. What “all” means beyond these rows – more pages, a filter on the server – stays with the app. Its name comes from the texts (`selectAll`).
|
|
2663
2665
|
|
|
2664
2666
|
```html
|
|
2665
2667
|
<nk-table-view new-row sortable></nk-table-view>
|
|
2666
2668
|
<script>{
|
|
2667
2669
|
const db = document.currentScript.previousElementSibling;
|
|
2668
2670
|
db.columns = [
|
|
2671
|
+
{ key: 'selected', type: 'checkbox', selectAll: true },
|
|
2669
2672
|
{ key: 'name', label: 'Name', type: 'text', icon: '📄', title: true },
|
|
2670
2673
|
{ key: 'status', label: 'Status', type: 'select', icon: '◉', options: [
|
|
2671
2674
|
{ value: 'planned', label: 'Planned', color: 'orange' }, { value: 'progress', label: 'In progress', color: 'blue' }, { value: 'done', label: 'Done', color: 'green' } ] },
|
|
@@ -2676,9 +2679,9 @@ Renders `columns` × `rows` as the NotionKit table. Cells are polymorphic (`text
|
|
|
2676
2679
|
{ key: 'actions', type: 'actions', actions: [{ action: 'open', label: 'Open' }, { action: 'archive', label: 'Archive', danger: true }] },
|
|
2677
2680
|
];
|
|
2678
2681
|
db.rows = [
|
|
2679
|
-
{ id: 1, icon: '🧭', name: { text: 'App shell & sidebar', desc: 'Three open questions' }, status: 'done', owner: { name: 'Marcel', initials: 'MK', color: 'purple' }, due: '08.05.2026', progress: 100, effort: 6, cover: '/covers/aurora.svg' },
|
|
2682
|
+
{ id: 1, icon: '🧭', name: { text: 'App shell & sidebar', desc: 'Three open questions' }, status: 'done', owner: { name: 'Marcel', initials: 'MK', color: 'purple' }, due: '08.05.2026', progress: 100, effort: 6, cover: '/covers/aurora.svg', selected: true },
|
|
2680
2683
|
{ id: 2, icon: '📄', name: 'Page shell & typography', status: 'done', owner: { name: 'Marcel', initials: 'MK', color: 'purple' }, due: '10.05.2026', progress: 100, effort: 4.5, cover: '/covers/dunes.svg' },
|
|
2681
|
-
{ id: 3, icon: '🗃️', name: 'Database table view', status: 'progress', owner: { name: 'Marcel', initials: 'MK', color: 'purple' }, due: '20.05.2026', progress: 65, effort: 12.5, cover: '/covers/meadow.svg' },
|
|
2684
|
+
{ id: 3, icon: '🗃️', name: 'Database table view', status: 'progress', owner: { name: 'Marcel', initials: 'MK', color: 'purple' }, due: '20.05.2026', progress: 65, effort: 12.5, cover: '/covers/meadow.svg', selected: true },
|
|
2682
2685
|
{ id: 4, icon: '▤', name: 'Board view & drag-and-drop', status: 'planned', due: '02.06.2026', progress: 0, effort: 8, actions: ['open'], cover: '/covers/tide.svg' },
|
|
2683
2686
|
];
|
|
2684
2687
|
}</script>
|
|
@@ -2697,23 +2700,23 @@ Renders `columns` × `rows` as the NotionKit table. Cells are polymorphic (`text
|
|
|
2697
2700
|
| `sort-dir` | asc | desc | – | Direction. |
|
|
2698
2701
|
| `wrap` | boolean | – | Cell text may break (Notion's "wrap column"). |
|
|
2699
2702
|
|
|
2700
|
-
**Events:** `nk-select` `{ row, id, key, cell }` – Row clicked. · `nk-change` `{ row, key, value }` – Checkbox cell toggled (row updated in place). · `nk-action` `{ action: 'sort' | 'new-row' | an actions column's action, key?, value?, row?, id?, anchor? }` – Header, add row or a row’s button clicked.
|
|
2703
|
+
**Events:** `nk-select` `{ row, id, key, cell }` – Row clicked. · `nk-change` `{ row, key, value } · selectAll: { key, value, all: true, rows }` – Checkbox cell toggled (row updated in place); from a selectAll header once for every row. · `nk-action` `{ action: 'sort' | 'new-row' | an actions column's action, key?, value?, row?, id?, anchor? }` – Header, add row or a row’s button clicked.
|
|
2701
2704
|
|
|
2702
2705
|
**Properties:** `columns`, `rows`, `data` · **Methods:** `refresh()`
|
|
2703
2706
|
|
|
2704
|
-
**Replaces:** `.nk-table-wrap`, `.nk-table`, `.wrap`, `.th-icon`, `.row-title`, `.date-cell`, `.person-cell`, `.nk-avatar`, `.num`, `.row-actions`, `.actions`, `.td-text`, `.td-desc`, `.nk-new-row`
|
|
2707
|
+
**Replaces:** `.nk-table-wrap`, `.nk-table`, `.wrap`, `.th-icon`, `.row-title`, `.date-cell`, `.person-cell`, `.nk-avatar`, `.num`, `.row-actions`, `.actions`, `.select-all`, `.nk-check`, `.td-text`, `.td-desc`, `.nk-new-row`
|
|
2705
2708
|
|
|
2706
2709
|
```html
|
|
2707
2710
|
<!-- equivalent class markup -->
|
|
2708
2711
|
<div class="nk-table-wrap"><table class="nk-table">
|
|
2709
|
-
<thead><tr><th><span class="th-icon">📄</span>Name</th><th><span class="th-icon">◉</span>Status</th><th><span class="th-icon">👤</span>Owner</th><th><span class="th-icon">📅</span>Due</th><th><span class="th-icon">▰</span>Progress</th><th><span class="th-icon">#</span>Effort (h)</th><th class="actions"></th></tr></thead>
|
|
2712
|
+
<thead><tr><th class="select-all"><label class="nk-check"><input type="checkbox" aria-label="Select all"></label></th><th><span class="th-icon">📄</span>Name</th><th><span class="th-icon">◉</span>Status</th><th><span class="th-icon">👤</span>Owner</th><th><span class="th-icon">📅</span>Due</th><th><span class="th-icon">▰</span>Progress</th><th><span class="th-icon">#</span>Effort (h)</th><th class="actions"></th></tr></thead>
|
|
2710
2713
|
<tbody>
|
|
2711
|
-
<tr><td><span class="row-title">🧭 App shell & sidebar</span><span class="td-desc">Three open questions</span></td><td><span class="nk-tag green">Done</span></td><td><span class="person-cell"><span class="nk-avatar small purple">MK</span> Marcel</span></td><td><span class="date-cell">08.05.2026</span></td><td><span class="nk-progress"><i style="width:100%"></i></span><span class="nk-progress-label">100%</span></td><td class="num"><span>6.0</span></td><td><span class="row-actions"><button class="nk-btn secondary small">Open</button><button class="nk-btn danger small">Archive</button></span></td></tr>
|
|
2712
|
-
<tr><td><span class="row-title">📄 Page shell & typography</span></td><td><span class="nk-tag green">Done</span></td><td><span class="person-cell"><span class="nk-avatar small purple">MK</span> Marcel</span></td><td><span class="date-cell">10.05.2026</span></td><td><span class="nk-progress"><i style="width:100%"></i></span><span class="nk-progress-label">100%</span></td><td class="num"><span>4.5</span></td><td><span class="row-actions"><button class="nk-btn secondary small">Open</button><button class="nk-btn danger small">Archive</button></span></td></tr>
|
|
2713
|
-
<tr><td><span class="row-title">🗃️ Database table view</span></td><td><span class="nk-tag blue">In progress</span></td><td><span class="person-cell"><span class="nk-avatar small purple">MK</span> Marcel</span></td><td><span class="date-cell">20.05.2026</span></td><td><span class="nk-progress"><i style="width:65%"></i></span><span class="nk-progress-label">65%</span></td><td class="num"><span>12.5</span></td><td><span class="row-actions"><button class="nk-btn secondary small">Open</button><button class="nk-btn danger small">Archive</button></span></td></tr>
|
|
2714
|
-
<tr><td><span class="row-title">▤ Board view & drag-and-drop</span></td><td><span class="nk-tag orange">Planned</span></td><td><span class="person-cell">—</span></td><td><span class="date-cell">02.06.2026</span></td><td><span class="nk-progress"><i style="width:0%"></i></span><span class="nk-progress-label">0%</span></td><td class="num"><span>8.0</span></td><td><span class="row-actions"><button class="nk-btn secondary small">Open</button></span></td></tr>
|
|
2714
|
+
<tr><td><label class="nk-check"><input type="checkbox" checked></label></td><td><span class="row-title">🧭 App shell & sidebar</span><span class="td-desc">Three open questions</span></td><td><span class="nk-tag green">Done</span></td><td><span class="person-cell"><span class="nk-avatar small purple">MK</span> Marcel</span></td><td><span class="date-cell">08.05.2026</span></td><td><span class="nk-progress"><i style="width:100%"></i></span><span class="nk-progress-label">100%</span></td><td class="num"><span>6.0</span></td><td><span class="row-actions"><button class="nk-btn secondary small">Open</button><button class="nk-btn danger small">Archive</button></span></td></tr>
|
|
2715
|
+
<tr><td><label class="nk-check"><input type="checkbox"></label></td><td><span class="row-title">📄 Page shell & typography</span></td><td><span class="nk-tag green">Done</span></td><td><span class="person-cell"><span class="nk-avatar small purple">MK</span> Marcel</span></td><td><span class="date-cell">10.05.2026</span></td><td><span class="nk-progress"><i style="width:100%"></i></span><span class="nk-progress-label">100%</span></td><td class="num"><span>4.5</span></td><td><span class="row-actions"><button class="nk-btn secondary small">Open</button><button class="nk-btn danger small">Archive</button></span></td></tr>
|
|
2716
|
+
<tr><td><label class="nk-check"><input type="checkbox" checked></label></td><td><span class="row-title">🗃️ Database table view</span></td><td><span class="nk-tag blue">In progress</span></td><td><span class="person-cell"><span class="nk-avatar small purple">MK</span> Marcel</span></td><td><span class="date-cell">20.05.2026</span></td><td><span class="nk-progress"><i style="width:65%"></i></span><span class="nk-progress-label">65%</span></td><td class="num"><span>12.5</span></td><td><span class="row-actions"><button class="nk-btn secondary small">Open</button><button class="nk-btn danger small">Archive</button></span></td></tr>
|
|
2717
|
+
<tr><td><label class="nk-check"><input type="checkbox"></label></td><td><span class="row-title">▤ Board view & drag-and-drop</span></td><td><span class="nk-tag orange">Planned</span></td><td><span class="person-cell">—</span></td><td><span class="date-cell">02.06.2026</span></td><td><span class="nk-progress"><i style="width:0%"></i></span><span class="nk-progress-label">0%</span></td><td class="num"><span>8.0</span></td><td><span class="row-actions"><button class="nk-btn secondary small">Open</button></span></td></tr>
|
|
2715
2718
|
</tbody>
|
|
2716
|
-
</table><div class="nk-new-row">+ New page</div></div>
|
|
2719
|
+
</table><div class="nk-new-row">+ New page</div></div><script>document.currentScript.previousElementSibling.querySelector('th.select-all input').indeterminate = true</script>
|
|
2717
2720
|
```
|
|
2718
2721
|
|
|
2719
2722
|
**Small screens:** Scrolls horizontally inside `.nk-table-wrap`.
|
|
@@ -3152,8 +3155,8 @@ Eight skeletons, one per app shape, mirroring the NotionKit CSS SKILL.md. Copy o
|
|
|
3152
3155
|
<html lang="en" data-theme="light">
|
|
3153
3156
|
<head>
|
|
3154
3157
|
<meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
3155
|
-
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@jungherz-de/notionkit@1.
|
|
3156
|
-
<script src="https://cdn.jsdelivr.net/npm/@jungherz-de/notionkit-elements@1.
|
|
3158
|
+
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@jungherz-de/notionkit@1.21.0/notionkit.min.css">
|
|
3159
|
+
<script src="https://cdn.jsdelivr.net/npm/@jungherz-de/notionkit-elements@1.21.0/dist/notionkit-elements.min.js"></script>
|
|
3157
3160
|
</head>
|
|
3158
3161
|
<body class="nk-body">
|
|
3159
3162
|
<nk-app>
|
|
@@ -3234,8 +3237,8 @@ Rules of the shell: `nk-sidebar`, `nk-topbar` and `nk-page` are `display: conten
|
|
|
3234
3237
|
<html lang="en" data-theme="light">
|
|
3235
3238
|
<head>
|
|
3236
3239
|
<meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
3237
|
-
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@jungherz-de/notionkit@1.
|
|
3238
|
-
<script src="https://cdn.jsdelivr.net/npm/@jungherz-de/notionkit-elements@1.
|
|
3240
|
+
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@jungherz-de/notionkit@1.21.0/notionkit.min.css">
|
|
3241
|
+
<script src="https://cdn.jsdelivr.net/npm/@jungherz-de/notionkit-elements@1.21.0/dist/notionkit-elements.min.js"></script>
|
|
3239
3242
|
</head>
|
|
3240
3243
|
<body class="nk-body">
|
|
3241
3244
|
<nk-app>
|
|
@@ -3342,8 +3345,8 @@ Data contract: `columns` describe the properties (`type`: text | select | multi-
|
|
|
3342
3345
|
<html lang="en" data-theme="light">
|
|
3343
3346
|
<head>
|
|
3344
3347
|
<meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
3345
|
-
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@jungherz-de/notionkit@1.
|
|
3346
|
-
<script src="https://cdn.jsdelivr.net/npm/@jungherz-de/notionkit-elements@1.
|
|
3348
|
+
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@jungherz-de/notionkit@1.21.0/notionkit.min.css">
|
|
3349
|
+
<script src="https://cdn.jsdelivr.net/npm/@jungherz-de/notionkit-elements@1.21.0/dist/notionkit-elements.min.js"></script>
|
|
3347
3350
|
</head>
|
|
3348
3351
|
<body class="nk-body">
|
|
3349
3352
|
<nk-app>
|
|
@@ -3402,8 +3405,8 @@ Data contract: `columns` describe the properties (`type`: text | select | multi-
|
|
|
3402
3405
|
<html lang="en" data-theme="light">
|
|
3403
3406
|
<head>
|
|
3404
3407
|
<meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
3405
|
-
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@jungherz-de/notionkit@1.
|
|
3406
|
-
<script src="https://cdn.jsdelivr.net/npm/@jungherz-de/notionkit-elements@1.
|
|
3408
|
+
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@jungherz-de/notionkit@1.21.0/notionkit.min.css">
|
|
3409
|
+
<script src="https://cdn.jsdelivr.net/npm/@jungherz-de/notionkit-elements@1.21.0/dist/notionkit-elements.min.js"></script>
|
|
3407
3410
|
</head>
|
|
3408
3411
|
<body class="nk-body">
|
|
3409
3412
|
<!-- your app -->
|
|
@@ -3480,8 +3483,8 @@ The open/close contract is one attribute: `settings.open = true`, `settings.show
|
|
|
3480
3483
|
<html lang="en" data-theme="light">
|
|
3481
3484
|
<head>
|
|
3482
3485
|
<meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
3483
|
-
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@jungherz-de/notionkit@1.
|
|
3484
|
-
<script src="https://cdn.jsdelivr.net/npm/@jungherz-de/notionkit-elements@1.
|
|
3486
|
+
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@jungherz-de/notionkit@1.21.0/notionkit.min.css">
|
|
3487
|
+
<script src="https://cdn.jsdelivr.net/npm/@jungherz-de/notionkit-elements@1.21.0/dist/notionkit-elements.min.js"></script>
|
|
3485
3488
|
</head>
|
|
3486
3489
|
<body class="nk-body">
|
|
3487
3490
|
<div class="nk-page" style="padding-top:48px">
|
|
@@ -3527,8 +3530,8 @@ The open/close contract is one attribute: `settings.open = true`, `settings.show
|
|
|
3527
3530
|
<html lang="en" data-theme="light">
|
|
3528
3531
|
<head>
|
|
3529
3532
|
<meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
3530
|
-
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@jungherz-de/notionkit@1.
|
|
3531
|
-
<script src="https://cdn.jsdelivr.net/npm/@jungherz-de/notionkit-elements@1.
|
|
3533
|
+
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@jungherz-de/notionkit@1.21.0/notionkit.min.css">
|
|
3534
|
+
<script src="https://cdn.jsdelivr.net/npm/@jungherz-de/notionkit-elements@1.21.0/dist/notionkit-elements.min.js"></script>
|
|
3532
3535
|
</head>
|
|
3533
3536
|
<body class="nk-body">
|
|
3534
3537
|
<nk-page narrow icon="📘" cover>
|
|
@@ -3572,8 +3575,8 @@ Note `narrow`: the page is the document, so there is no inner scroll wrapper –
|
|
|
3572
3575
|
<html lang="en" data-theme="light">
|
|
3573
3576
|
<head>
|
|
3574
3577
|
<meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
3575
|
-
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@jungherz-de/notionkit@1.
|
|
3576
|
-
<script src="https://cdn.jsdelivr.net/npm/@jungherz-de/notionkit-elements@1.
|
|
3578
|
+
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@jungherz-de/notionkit@1.21.0/notionkit.min.css">
|
|
3579
|
+
<script src="https://cdn.jsdelivr.net/npm/@jungherz-de/notionkit-elements@1.21.0/dist/notionkit-elements.min.js"></script>
|
|
3577
3580
|
</head>
|
|
3578
3581
|
<body class="nk-body">
|
|
3579
3582
|
<nk-app>
|
|
@@ -3627,8 +3630,8 @@ Note `narrow`: the page is the document, so there is no inner scroll wrapper –
|
|
|
3627
3630
|
<html lang="en" data-theme="light">
|
|
3628
3631
|
<head>
|
|
3629
3632
|
<meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
3630
|
-
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@jungherz-de/notionkit@1.
|
|
3631
|
-
<script src="https://cdn.jsdelivr.net/npm/@jungherz-de/notionkit-elements@1.
|
|
3633
|
+
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@jungherz-de/notionkit@1.21.0/notionkit.min.css">
|
|
3634
|
+
<script src="https://cdn.jsdelivr.net/npm/@jungherz-de/notionkit-elements@1.21.0/dist/notionkit-elements.min.js"></script>
|
|
3632
3635
|
</head>
|
|
3633
3636
|
<body class="nk-body">
|
|
3634
3637
|
<!-- A narrow column, centred: layout is yours, so it is inline. -->
|
|
@@ -3839,10 +3842,10 @@ Form controls additionally re-dispatch a native, bubbling `change` event, so `fo
|
|
|
3839
3842
|
| Texts | `src/util/strings.js` – the English and German dictionary and `setStrings()`; `NkElement#str(key)` reads it in the element's language, `onStringsChanged()` runs after `setStrings()` and when `<html lang>` changes |
|
|
3840
3843
|
| Components | `src/components/{forms,content,shell,page,overlays,data}/nk-*.js`, one tag per file, `customElements.define` at the bottom |
|
|
3841
3844
|
| Build | Rollup: IIFE, minified IIFE, ESM, and per-component ESM entries on a stable `dist/components/base.js` that import NotionKit's sheet (`@jungherz-de/notionkit/notionkit-styles.js`) instead of inlining it; the full bundles inline it and export `componentsSheet` |
|
|
3842
|
-
| Peer | `@jungherz-de/notionkit >= 1.
|
|
3845
|
+
| Peer | `@jungherz-de/notionkit >= 1.21.0` – from 1.5.0 on the elements and the foundation share one version number; the bundle embeds that release's stylesheet, so keep them in step |
|
|
3843
3846
|
|
|
3844
3847
|
Lifecycle: construct (attach shadow, adopt sheets) → first connect (wrapper + `render()`) → every connect (`setupEvents()`, theme registration, light-DOM observer) → `attributeChangedCallback` → `onAttributeChanged` → disconnect (`teardownEvents()`, unregister).
|
|
3845
3848
|
|
|
3846
3849
|
|
|
3847
3850
|
---
|
|
3848
|
-
*NotionKit Elements v1.
|
|
3851
|
+
*NotionKit Elements v1.21.0 · wrapping NotionKit CSS v1.21.0 · MIT · Jungherz GmbH*
|
package/dist/components/base.js
CHANGED
|
@@ -21,7 +21,7 @@ const BUILT_IN = {
|
|
|
21
21
|
appearance: 'Appearance: {mode} – click: {next}', themeAuto: 'automatic (follows the system)', themeLight: 'light', themeDark: 'dark',
|
|
22
22
|
message: 'Message', breadcrumb: 'Breadcrumb', commandPalette: 'Command palette', comment: 'Comment',
|
|
23
23
|
searchEmoji: 'Search emoji', settings: 'Settings', title: 'Title', changeIcon: 'Change icon',
|
|
24
|
-
add: 'Add', more: 'More',
|
|
24
|
+
add: 'Add', more: 'More', selectAll: 'Select all',
|
|
25
25
|
},
|
|
26
26
|
de: {
|
|
27
27
|
copy: 'Kopieren', copied: 'Kopiert', show: 'Zeigen', hide: 'Verbergen',
|
|
@@ -36,7 +36,7 @@ const BUILT_IN = {
|
|
|
36
36
|
appearance: 'Darstellung: {mode} – Klick: {next}', themeAuto: 'automatisch (wie das System)', themeLight: 'hell', themeDark: 'dunkel',
|
|
37
37
|
message: 'Nachricht', breadcrumb: 'Pfad', commandPalette: 'Befehlspalette', comment: 'Kommentar',
|
|
38
38
|
searchEmoji: 'Emoji suchen', settings: 'Einstellungen', title: 'Titel', changeIcon: 'Symbol ändern',
|
|
39
|
-
add: 'Hinzufügen', more: 'Mehr',
|
|
39
|
+
add: 'Hinzufügen', more: 'Mehr', selectAll: 'Alle auswählen',
|
|
40
40
|
},
|
|
41
41
|
};
|
|
42
42
|
const custom = {};
|
|
@@ -16,6 +16,15 @@ import './shared/dates-a32DcW1l.js';
|
|
|
16
16
|
// type 'actions' (NotionKit 1.12.0) sets buttons in each row; a click on one
|
|
17
17
|
// fires nk-action { action, row, id, anchor } instead of selecting the row,
|
|
18
18
|
// and its header sorts nothing.
|
|
19
|
+
//
|
|
20
|
+
// A checkbox column with `selectAll: true` (1.21.0) is a selection column:
|
|
21
|
+
// its header holds a checkbox instead of a name – empty, a dash for some
|
|
22
|
+
// rows, a check for all – and sorts nothing (th.select-all, NotionKit
|
|
23
|
+
// 1.21.0). A click or Space sets the column for every row the view has –
|
|
24
|
+
// a dash selects all, as Notion does –, renders again and fires one
|
|
25
|
+
// nk-change { key, value, all: true, rows }, so an app that keeps its own
|
|
26
|
+
// selection follows with one update. What "all" means beyond these rows –
|
|
27
|
+
// more pages, a filter on the server – stays with the app.
|
|
19
28
|
class NkTableView extends NkElement {
|
|
20
29
|
static get observedAttributes() { return ['name', 'label', 'badge', 'count', 'new-row', 'new-row-label', 'sortable', 'sort-key', 'sort-dir', 'wrap']; }
|
|
21
30
|
|
|
@@ -45,6 +54,7 @@ class NkTableView extends NkElement {
|
|
|
45
54
|
this._table.classList.toggle('wrap', this.getBoolAttr('wrap'));
|
|
46
55
|
const tr = document.createElement('tr');
|
|
47
56
|
for (const col of this._columns) {
|
|
57
|
+
if (col.type === 'checkbox' && col.selectAll) { tr.appendChild(this._selectAllHeader(col)); continue; }
|
|
48
58
|
const actions = col.type === 'actions';
|
|
49
59
|
const th = this.createElement('th', actions ? ['actions'] : [], actions ? { scope: 'col' } : { 'data-key': col.key, scope: 'col' });
|
|
50
60
|
if (col.icon) { const i = this.createElement('span', ['th-icon']); i.textContent = col.icon; th.appendChild(i); }
|
|
@@ -68,6 +78,40 @@ class NkTableView extends NkElement {
|
|
|
68
78
|
}
|
|
69
79
|
this._newRow.textContent = this.getAttribute('new-row-label') || this.str('newPage');
|
|
70
80
|
this._newRow.style.display = this.getBoolAttr('new-row') ? '' : 'none';
|
|
81
|
+
this._syncSelectAll();
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/** The header of a selection column: the cells' own checkbox, named "Select all". */
|
|
85
|
+
_selectAllHeader(col) {
|
|
86
|
+
const th = this.createElement('th', ['select-all'], { scope: 'col' });
|
|
87
|
+
const label = this.createElement('label', ['nk-check']);
|
|
88
|
+
label.appendChild(this.createElement('input', [], { type: 'checkbox', 'aria-label': this.str('selectAll'), 'data-select-all': col.key }));
|
|
89
|
+
th.appendChild(label);
|
|
90
|
+
if (col.width) th.style.width = col.width;
|
|
91
|
+
return th;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
/** Every header box shows its column: checked for all rows, a dash for some, empty for none – and nothing to choose without rows. */
|
|
95
|
+
_syncSelectAll() {
|
|
96
|
+
for (const input of this._thead?.querySelectorAll('input[data-select-all]') ?? []) {
|
|
97
|
+
const key = input.dataset.selectAll, on = this._rows.filter(r => r[key]).length;
|
|
98
|
+
input.checked = on > 0 && on === this._rows.length;
|
|
99
|
+
input.indeterminate = on > 0 && on < this._rows.length;
|
|
100
|
+
input.disabled = !this._rows.length;
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
/** A click or Space on a header box: the column for every row, one event. */
|
|
105
|
+
_selectAll(input) {
|
|
106
|
+
const key = input.dataset.selectAll;
|
|
107
|
+
// A dash selects all, as Notion does; only a full column clears.
|
|
108
|
+
const value = !(this._rows.length && this._rows.every(r => r[key]));
|
|
109
|
+
for (const row of this._rows) row[key] = value;
|
|
110
|
+
const focused = this._shadow.activeElement === input;
|
|
111
|
+
this._render();
|
|
112
|
+
// Space should leave the focus where it was – on the new header box.
|
|
113
|
+
if (focused) [...this._thead.querySelectorAll('input[data-select-all]')].find(i => i.dataset.selectAll === key)?.focus();
|
|
114
|
+
this.emit('nk-change', { key, value, all: true, rows: this._rows });
|
|
71
115
|
}
|
|
72
116
|
|
|
73
117
|
setupEvents() {
|
|
@@ -98,8 +142,10 @@ class NkTableView extends NkElement {
|
|
|
98
142
|
this._onChange = (e) => {
|
|
99
143
|
const input = e.target;
|
|
100
144
|
if (input.type !== 'checkbox') return;
|
|
145
|
+
if (input.dataset.selectAll != null) { this._selectAll(input); return; }
|
|
101
146
|
const row = this._rowById(input.dataset.rowId);
|
|
102
147
|
if (row) row[input.dataset.key] = input.checked;
|
|
148
|
+
this._syncSelectAll();
|
|
103
149
|
this.emit('nk-change', { row, key: input.dataset.key, value: input.checked });
|
|
104
150
|
};
|
|
105
151
|
this._onKey = (e) => { if ((e.key === 'Enter' || e.key === ' ') && e.target === this._newRow) { e.preventDefault(); this.emit('nk-action', { action: 'new-row' }); } };
|