@jungherz-de/notionkit-elements 1.10.1 → 1.11.1
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 +641 -0
- package/README.md +6 -6
- package/SKILL.md +3748 -0
- package/dist/components/nk-ai-msg.js +6 -4
- package/dist/components/nk-avatar.js +1 -1
- package/dist/components/nk-banner.js +5 -2
- package/dist/components/nk-board-view.js +2 -2
- package/dist/components/nk-calendar.js +2 -2
- package/dist/components/nk-comment.js +1 -1
- package/dist/components/nk-dialog.js +14 -8
- package/dist/components/nk-fields.js +13 -3
- package/dist/components/nk-filter-bar.js +5 -3
- package/dist/components/nk-list-view.js +2 -2
- package/dist/components/nk-member-row.js +1 -1
- package/dist/components/nk-menu.js +2 -2
- package/dist/components/nk-page.js +3 -2
- package/dist/components/nk-select.js +15 -7
- package/dist/components/nk-switch.js +5 -1
- package/dist/components/nk-table-view.js +2 -2
- package/dist/components/nk-tooltip.js +17 -7
- package/dist/components/nk-tree-item.js +10 -4
- package/dist/components/shared/{avatar-BiqCaHOt.js → avatar-CzPZN3uP.js} +2 -2
- package/dist/components/shared/floating-CtqV6MBj.js +66 -0
- package/dist/components/shared/{property-cell-o7N30kAQ.js → property-cell-Cddz5n2O.js} +1 -1
- package/dist/notionkit-elements.esm.js +137 -56
- package/dist/notionkit-elements.js +137 -56
- package/dist/notionkit-elements.min.js +1 -1
- package/package.json +7 -4
- package/src/components/data/nk-ai-msg.js +6 -4
- package/src/components/data/nk-filter-bar.js +5 -3
- package/src/components/forms/nk-calendar.js +1 -1
- package/src/components/forms/nk-fields.js +13 -3
- package/src/components/forms/nk-select.js +15 -7
- package/src/components/forms/nk-switch.js +5 -1
- package/src/components/overlays/nk-dialog.js +14 -8
- package/src/components/overlays/nk-menu.js +1 -1
- package/src/components/overlays/nk-tooltip.js +16 -6
- package/src/components/page/nk-banner.js +5 -2
- package/src/components/page/nk-page.js +3 -2
- package/src/components/shell/nk-tree-item.js +10 -4
- package/src/util/avatar.js +2 -2
- package/src/util/floating.js +39 -10
- package/dist/components/shared/floating-CxHxy-Cb.js +0 -37
package/SKILL.md
ADDED
|
@@ -0,0 +1,3748 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: notionkit-elements
|
|
3
|
+
description: NotionKit Elements is a vanilla-JS Web Components library (v1.11.1) wrapping NotionKit CSS v1.11.1 – the calm, document-centric design system in the Notion idiom. 87 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
|
+
---
|
|
5
|
+
|
|
6
|
+
# NotionKit Elements – AI Component Reference
|
|
7
|
+
|
|
8
|
+
> Machine-readable reference for generating correct `<nk-*>` markup. The class-based companion (`.nk-*`) is documented in the NotionKit CSS SKILL.md at https://notionkit.jungherz.com/SKILL.md – every element here has the same word stem as its class.
|
|
9
|
+
|
|
10
|
+
# 1. Setup & Boilerplate
|
|
11
|
+
|
|
12
|
+
## Prerequisites (always)
|
|
13
|
+
|
|
14
|
+
1. Load **notionkit.css** on the document (it is the peer dependency) and put `class="nk-body"` on `<body>`. Shadow roots inherit font, colour and the scoped reset from there; the elements ship no visual CSS of their own.
|
|
15
|
+
2. Load the elements bundle **once**. It also injects the design tokens as a cascade layer (`@layer notionkit-defaults`), so your own unlayered `:root { --nk-* }` always wins.
|
|
16
|
+
3. Theme: `data-theme="light|dark"` on `<html>` only.
|
|
17
|
+
|
|
18
|
+
```html
|
|
19
|
+
<!DOCTYPE html>
|
|
20
|
+
<html lang="en" data-theme="light">
|
|
21
|
+
<head>
|
|
22
|
+
<meta charset="UTF-8">
|
|
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.11.1/notionkit.min.css">
|
|
25
|
+
<script src="https://cdn.jsdelivr.net/npm/@jungherz-de/notionkit-elements@1.11.1/dist/notionkit-elements.min.js"></script>
|
|
26
|
+
</head>
|
|
27
|
+
<body class="nk-body">
|
|
28
|
+
<nk-btn variant="primary">Save</nk-btn>
|
|
29
|
+
</body>
|
|
30
|
+
</html>
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
## npm
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
npm install @jungherz-de/notionkit-elements @jungherz-de/notionkit
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
```js
|
|
40
|
+
import '@jungherz-de/notionkit/notionkit.css'; // via your bundler, or a <link>
|
|
41
|
+
import '@jungherz-de/notionkit-elements'; // registers every <nk-*> tag
|
|
42
|
+
// or one element at a time (shared code: base.js):
|
|
43
|
+
import '@jungherz-de/notionkit-elements/components/nk-btn.js';
|
|
44
|
+
// the sheet the elements adopt, for your own views – never a second copy:
|
|
45
|
+
import { componentsSheet } from '@jungherz-de/notionkit-elements';
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
The per-component files import NotionKit's sheet as `@jungherz-de/notionkit/notionkit-styles.js` instead of carrying a copy. A bundler resolves it; a build-free page maps it once:
|
|
49
|
+
|
|
50
|
+
```html
|
|
51
|
+
<script type="importmap">{ "imports": { "@jungherz-de/notionkit/notionkit-styles.js": "/node_modules/@jungherz-de/notionkit/notionkit-styles.js" } }</script>
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
Never mix the full bundle with the per-component files – each brings its own `NkElement`. With the bundle, take `componentsSheet` and `NkElement` from it (`NotionKitElements.componentsSheet` from the `<script>` build).
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
# 2. Core Concepts
|
|
58
|
+
|
|
59
|
+
| Concept | Rule |
|
|
60
|
+
|---|---|
|
|
61
|
+
| Tag prefix | Every element is `<nk-*>`; the word stem equals the CSS class (`.nk-callout` ↔ `<nk-callout>`). |
|
|
62
|
+
| Modifiers | A modifier class becomes an attribute: `.nk-btn.primary` → `<nk-btn variant="primary">`, `.nk-tag.green` → `<nk-tag color="green">`. |
|
|
63
|
+
| States | A state class becomes a boolean attribute: `.active`, `.open`, `.selected`, `checked`. Set the attribute (or property) – never reach into the shadow root. |
|
|
64
|
+
| Rendering | Open Shadow DOM. The shadow root adopts the NotionKit *component* sheet only; tokens are inherited from the document. |
|
|
65
|
+
| Hosts | Every host is `display: contents` – no box of its own, the inner `.nk-*` element sits in the parent layout exactly like the class markup. Style the parent or the tokens, never the host; `hidden` on the host works. |
|
|
66
|
+
| Theme | One MutationObserver watches `data-theme` on `<html>` and mirrors it into every element. Nothing else switches themes. |
|
|
67
|
+
| Branding | Declare `--nk-*` tokens on `:root` in any plain stylesheet; every element follows in both themes. |
|
|
68
|
+
| Data | Static content via attributes and slots; dynamic data via JS properties (`tree.data`, `database.rows`, `cmdk.commands`). No fetching, no two-way binding. |
|
|
69
|
+
| Events | Custom events with fixed names (`nk-select`, `nk-change`, `nk-view-change`, `nk-command`, `nk-toggle`, `nk-submit`, `nk-action`). All bubble and are composed; payload in `event.detail`. |
|
|
70
|
+
| Forms | Controls are form-associated: FormData, reset, `required`, `<fieldset disabled>` work inside a `<form>`. |
|
|
71
|
+
| Icons | `::slotted()` only matches the assigned node. Pass an icon as the slotted node itself – `<span slot="icon">📁</span>` – never wrapped. |
|
|
72
|
+
| Light-DOM children | Elements that copy children (`nk-select` options, breadcrumb crumbs) watch them; `element.refresh()` is the escape hatch. The empty string is a valid value. |
|
|
73
|
+
| Moving elements | An element moved in the DOM keeps working – listeners and theme registration are re-armed on every connect. |
|
|
74
|
+
| Attributes are live | Every documented attribute re-renders when changed after connect (`stat.setAttribute('value', '129')`, `el.open = true`); properties reflect to attributes where a setter is listed. |
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
# 3. Element Catalog (87 elements)
|
|
78
|
+
|
|
79
|
+
## Forms & controls (wave 1)
|
|
80
|
+
|
|
81
|
+
### 3.1 `<nk-btn>` – Button
|
|
82
|
+
|
|
83
|
+
Renders `button.nk-btn`, or `a.nk-btn` when `href` is set. Modifier classes become attributes. A slotted `<svg>` is sized by the stylesheet – pass it directly, never wrapped.
|
|
84
|
+
|
|
85
|
+
```html
|
|
86
|
+
<nk-btn variant="primary">Save</nk-btn>
|
|
87
|
+
<nk-btn variant="secondary">Cancel</nk-btn>
|
|
88
|
+
<nk-btn variant="danger" small>Delete</nk-btn>
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
| Attribute | Type | Default | Description |
|
|
92
|
+
|---|---|---|---|
|
|
93
|
+
| `variant` | primary | secondary | danger | danger-solid | topbar | share | tool | sidebar | – | Visual variant. `topbar` and `share` render `.nk-topbar-btn` for the top bar. `tool` renders `.nk-db-tool`, a tool in the database toolbar (`slot="tools"` of `nk-database`). `sidebar` is the ☰ `.nk-topbar-btn.nk-sidebar-toggle`: shown below 860px only, a click opens the `nk-sidebar` of its app as a drawer and sets `aria-expanded`. |
|
|
94
|
+
| `active` | boolean | – | A tool in effect – a set filter – takes the accent (`variant="tool"`). |
|
|
95
|
+
| `small` | boolean | – | Compact padding and 12.5px text. |
|
|
96
|
+
| `disabled` | boolean | – | Disabled; clicks are swallowed. |
|
|
97
|
+
| `type` | button | submit | reset | `button` | For `submit`/`reset` the surrounding `<form>` is submitted or reset. |
|
|
98
|
+
| `href` | URL | – | Renders a link instead of a button. |
|
|
99
|
+
|
|
100
|
+
**Slots:** `(default)` – Label text and an optional `<svg>` icon.
|
|
101
|
+
|
|
102
|
+
**Events:** `click` `(native, composed)` – The native click bubbles out of the shadow root.
|
|
103
|
+
|
|
104
|
+
**Replaces:** `.nk-btn`, `.primary`, `.secondary`, `.danger`, `.danger-solid`, `.small`, `.nk-topbar-btn`, `.nk-share-btn`, `.nk-db-tool`, `.active`, `.nk-sidebar-toggle`
|
|
105
|
+
|
|
106
|
+
```html
|
|
107
|
+
<!-- equivalent class markup -->
|
|
108
|
+
<button class="nk-btn primary">Save</button>
|
|
109
|
+
<button class="nk-btn secondary">Cancel</button>
|
|
110
|
+
<button class="nk-btn danger small">Delete</button>
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
**Small screens:** Unchanged. The button grows with its label; combine with `small` in dense toolbars.
|
|
114
|
+
|
|
115
|
+
### 3.2 `<nk-input>` – Input
|
|
116
|
+
|
|
117
|
+
A native `<input>` inside the shadow root, wired into the surrounding form through ElementInternals: FormData, reset and `required` validation work as with a plain input.
|
|
118
|
+
|
|
119
|
+
```html
|
|
120
|
+
<nk-input name="name" value="Ada Lovelace" placeholder="Display name"></nk-input>
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
| Attribute | Type | Default | Description |
|
|
124
|
+
|---|---|---|---|
|
|
125
|
+
| `value` | string | – | Current value; also the reset value. |
|
|
126
|
+
| `type` | text | email | password | number | date | … | `text` | Forwarded to the native input. |
|
|
127
|
+
| `placeholder` | string | – | Placeholder text. |
|
|
128
|
+
| `name` | string | – | Form field name (FormData key). |
|
|
129
|
+
| `disabled` | boolean | – | Disables the control. |
|
|
130
|
+
| `required` | boolean | – | Marks the field required; validity is mirrored onto the host. |
|
|
131
|
+
| `readonly` | boolean | – | Read-only. |
|
|
132
|
+
| `wide` | boolean | – | Full width (`.wide`). |
|
|
133
|
+
|
|
134
|
+
**Events:** `nk-change` `{ value, name }` – Fired on commit (blur/Enter), like the native change event. · `nk-input` `{ value, name }` – Fired on every keystroke.
|
|
135
|
+
|
|
136
|
+
**Properties:** `value`, `name`, `disabled`, `required`, `form`, `validity` · **Methods:** `focus()`, `blur()`, `select()`, `checkValidity()`, `reportValidity()`
|
|
137
|
+
|
|
138
|
+
**Replaces:** `.nk-input`, `.wide`
|
|
139
|
+
|
|
140
|
+
```html
|
|
141
|
+
<!-- equivalent class markup -->
|
|
142
|
+
<input class="nk-input" name="name" value="Ada Lovelace" placeholder="Display name">
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
**Small screens:** Minimum width 210px; use `wide` to fill the row.
|
|
146
|
+
|
|
147
|
+
### 3.3 `<nk-copy-field>` – Copy field
|
|
148
|
+
|
|
149
|
+
A value to take along – a link, an address, a key – as tall as an input, with Copy inside on the right: it writes the clipboard and says “Copied” in green for a moment; where the clipboard is not allowed, the value is shown and selected for ⌘C. `secret` masks it behind Show/Hide, Copy still copies the real value. `value` set as a property is not reflected, so a key never lands in the markup.
|
|
150
|
+
|
|
151
|
+
```html
|
|
152
|
+
<div style="max-width:340px"><nk-copy-field value="https://monahilft.notionkit.app" copy-label="Copy"></nk-copy-field></div>
|
|
153
|
+
<div style="max-width:340px;margin-top:10px"><nk-copy-field value="ntn_4f2a9c1e8b7d6a5f3e2c" secret mono copy-label="Copy" show-label="Show"></nk-copy-field></div>
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
| Attribute | Type | Default | Description |
|
|
157
|
+
|---|---|---|---|
|
|
158
|
+
| `value` | string | – | The value. |
|
|
159
|
+
| `secret` | boolean | – | Masked, with Show/Hide. |
|
|
160
|
+
| `mono` | boolean | – | Monospace – addresses, keys, code. |
|
|
161
|
+
| `wrap` | boolean | – | A long value breaks instead of an ellipsis. |
|
|
162
|
+
| `wide` | boolean | – | Fills the row. |
|
|
163
|
+
| `copy-label` | string | `Copy` | Button text. |
|
|
164
|
+
| `copied-label` | string | `Copied` | Text for the moment after. |
|
|
165
|
+
| `show-label` | string | `Show` | Reveal (secret). |
|
|
166
|
+
| `hide-label` | string | `Hide` | Mask again. |
|
|
167
|
+
|
|
168
|
+
**Events:** `nk-action` `{ action: 'copy', value, ok }` – Copy clicked; `ok` is false where the clipboard refused.
|
|
169
|
+
|
|
170
|
+
**Properties:** `value`, `secret` · **Methods:** `copy()`
|
|
171
|
+
|
|
172
|
+
**Replaces:** `.nk-copy-field`, `.cf-value`, `.cf-btn`, `.copied`, `.mono`, `.wrap`, `.wide`
|
|
173
|
+
|
|
174
|
+
```html
|
|
175
|
+
<!-- equivalent class markup -->
|
|
176
|
+
<div style="max-width:340px"><div class="nk-copy-field"><span class="cf-value">https://monahilft.notionkit.app</span><button class="cf-btn">Copy</button></div></div>
|
|
177
|
+
<div style="max-width:340px;margin-top:10px"><div class="nk-copy-field mono"><span class="cf-value">••••••••••••••••••••••••</span><button class="cf-btn">Show</button><button class="cf-btn">Copy</button></div></div>
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
**Small screens:** Keeps to its column: the value is cut, never the actions.
|
|
181
|
+
|
|
182
|
+
### 3.4 `<nk-image-picker>` – Image picker
|
|
183
|
+
|
|
184
|
+
A picture for a person or a workspace, on NotionKit’s profile row: round, or `square` for a workspace icon, with Upload / Change and Remove beside it. From GlassKit Elements: the file is decoded with its EXIF rotation, drawn no larger than `max` and handed over as a data URL in `nk-change` – upload it yourself; an unreadable file fires `nk-error`. JPEG is drawn on white; `type="image/png"` keeps transparency. `src` as a property is not reflected, so megabytes never land in the DOM.
|
|
185
|
+
|
|
186
|
+
```html
|
|
187
|
+
<nk-image-picker initials="AL" choose-label="Upload image"></nk-image-picker>
|
|
188
|
+
<nk-image-picker square src="/favicon.svg" change-label="Change image" remove-label="Remove"></nk-image-picker>
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
| Attribute | Type | Default | Description |
|
|
192
|
+
|---|---|---|---|
|
|
193
|
+
| `src` | URL / data URL | – | Starting picture. |
|
|
194
|
+
| `initials` | string | – | Shown without a picture. |
|
|
195
|
+
| `square` | boolean | – | Rounded square – a workspace icon. |
|
|
196
|
+
| `max` | px | `512` | Longest edge after scaling. |
|
|
197
|
+
| `type` | MIME | `image/jpeg` | Output format. |
|
|
198
|
+
| `quality` | 0–1 | `0.82` | JPEG / WebP quality. |
|
|
199
|
+
| `accept` | string | `image/*` | File dialog filter. |
|
|
200
|
+
| `label` | string | – | Names the group. |
|
|
201
|
+
| `choose-label` | string | `Upload image` | Without a picture. |
|
|
202
|
+
| `change-label` | string | `Change image` | With a picture. |
|
|
203
|
+
| `remove-label` | string | `Remove` | Remove button. |
|
|
204
|
+
|
|
205
|
+
**Events:** `nk-change` `{ dataUrl, width, height, size }` – A picture chosen – or removed, with an empty dataUrl. · `nk-error` `{ message, name }` – The file cannot be decoded.
|
|
206
|
+
|
|
207
|
+
**Properties:** `src`, `square` · **Methods:** `choose()`
|
|
208
|
+
|
|
209
|
+
**Replaces:** `.nk-profile-row`, `.big-avatar`, `.square`, `.pr-actions`, `.pr-remove`
|
|
210
|
+
|
|
211
|
+
```html
|
|
212
|
+
<!-- equivalent class markup -->
|
|
213
|
+
<div class="nk-profile-row"><div class="big-avatar">AL</div><div class="pr-actions"><button class="nk-btn secondary small">Upload image</button></div></div>
|
|
214
|
+
<div class="nk-profile-row"><div class="big-avatar square"><img src="/favicon.svg" alt=""></div><div class="pr-actions"><button class="nk-btn secondary small">Change image</button><button class="nk-btn secondary small pr-remove">Remove</button></div></div>
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
**Small screens:** Unchanged; the actions stay beside the picture.
|
|
218
|
+
|
|
219
|
+
### 3.5 `<nk-calendar>` – Date picker
|
|
220
|
+
|
|
221
|
+
Notion’s date picker as one element (NotionKit 1.9.0): a month with Today and ‹ ›, the keys, bounds and a form value. The value is a day (`YYYY-MM-DD`); with `range` an interval `start/end`, picked in two clicks in either order; with `time` a day and a time (`YYYY-MM-DDTHH:MM`). `weeks` puts the ISO calendar week in front of each row (“KW” in German), `weekend` greys the days not worked, the `days` property adds holidays (`off` with a `label`) and up to three `marks` per day in the nine colours – deadlines, milestones. Days outside `min`/`max` are announced as unavailable and cannot be picked. Arrows move by a day or a week, Home/End to the ends of the week, PageUp/PageDown by a month (with Shift a year), Enter or Space picks; one day is in the tab order. Month names, weekdays and the first day of the week come from the page’s language; `week-start="1"` fixes Monday. With `floating sheet` it is a popover that `show(anchor)` opens under a property or a cell, and a bottom sheet on a phone; a pick closes it.
|
|
222
|
+
|
|
223
|
+
```html
|
|
224
|
+
<div style="display:flex;gap:16px;flex-wrap:wrap;align-items:flex-start">
|
|
225
|
+
<div class="nk-pop"><nk-calendar name="due" value="2026-06-02T09:30" time clearable weeks week-start="1" weekend="6,0" today="2026-06-17" today-label="Today" time-label="Time" clear-label="Clear" days='{"2026-06-04":{"off":true,"label":"Corpus Christi"},"2026-06-02":{"marks":["blue"]},"2026-06-11":{"marks":["orange","red"]},"2026-06-24":{"marks":["green"]}}'></nk-calendar></div>
|
|
226
|
+
<div class="nk-pop"><nk-calendar name="sprint" range value="2026-06-08/2026-06-12" weeks week-start="1" weekend="6,0" today="2026-06-17" today-label="Today" days='{"2026-06-04":{"off":true,"label":"Corpus Christi"}}'></nk-calendar></div>
|
|
227
|
+
</div>
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
| Attribute | Type | Default | Description |
|
|
231
|
+
|---|---|---|---|
|
|
232
|
+
| `value` | YYYY-MM-DD | start/end | …THH:MM | – | The day, the range or the day and time; also the reset value. |
|
|
233
|
+
| `month` | YYYY-MM | – | The month shown first; default the value’s, else today’s. |
|
|
234
|
+
| `min` | YYYY-MM-DD | – | First day that can be picked. |
|
|
235
|
+
| `max` | YYYY-MM-DD | – | Last day that can be picked. |
|
|
236
|
+
| `range` | boolean | – | Two picks make a range `start/end`. |
|
|
237
|
+
| `time` | boolean | – | A time field under the month – single days only. |
|
|
238
|
+
| `clearable` | boolean | – | A Clear button under the month. |
|
|
239
|
+
| `weeks` | boolean | – | The ISO calendar week in front of each row. |
|
|
240
|
+
| `week-start` | 0–6 | `Intl` | First day of the week: 0 Sunday, 1 Monday … |
|
|
241
|
+
| `weekend` | list | – | Weekdays not worked, greyed – `6,0`. |
|
|
242
|
+
| `days` | JSON | – | Per day `{ off, label, marks }`; also the property. |
|
|
243
|
+
| `today` | YYYY-MM-DD | – | Another today – for tests and docs. |
|
|
244
|
+
| `locale` | BCP 47 | `lang` | Language of the names and the week. |
|
|
245
|
+
| `floating` | boolean | – | A popover over the page: `show(anchor)`, `close()`. |
|
|
246
|
+
| `sheet` | boolean | – | Floating: a bottom sheet on a phone. |
|
|
247
|
+
| `open` | boolean | – | Floating: shown. |
|
|
248
|
+
| `align` | end | start | `end` | Floating: right or left edge on the anchor’s. |
|
|
249
|
+
| `label` | string | – | Names the month group for screen readers. |
|
|
250
|
+
| `today-label` | string | `Today` | Today button. |
|
|
251
|
+
| `prev-label` | string | `Previous month` | Names ‹. |
|
|
252
|
+
| `next-label` | string | `Next month` | Names ›. |
|
|
253
|
+
| `week-label` | string | `W · KW` | Head of the week column. |
|
|
254
|
+
| `time-label` | string | `Time` | Names the time field. |
|
|
255
|
+
| `clear-label` | string | `Clear` | Clear button. |
|
|
256
|
+
| `name` | string | – | Form field name (FormData key). |
|
|
257
|
+
| `disabled` | boolean | – | Disables the control. |
|
|
258
|
+
| `required` | boolean | – | A value is required; validity is set on the host. |
|
|
259
|
+
|
|
260
|
+
**Events:** `nk-change` `{ value, start, end, time }` – The value changed: a day picked – for a range the second one –, a new time, or Clear. The same day again is no change. · `nk-month` `{ month }` – Another month shown. · `nk-toggle` `{ open }` – Floating: opened or closed.
|
|
261
|
+
|
|
262
|
+
**Properties:** `value`, `start`, `end`, `month`, `days`, `open`, `form`, `validity` · **Methods:** `show(anchor)`, `close()`, `toggle(anchor)`, `focusDay()`, `checkValidity()`
|
|
263
|
+
|
|
264
|
+
**Replaces:** `.nk-calendar`, `.weeks`, `.cal-head`, `.cal-title`, `.cal-nav`, `.cal-grid`, `.cal-wd`, `.cal-week`, `.cal-day`, `.out`, `.off`, `.today`, `.selected`, `.start`, `.end`, `.in-range`, `.cal-marks`, `.cal-foot`, `.nk-pop`, `.floating`, `.sheet`, `.open`
|
|
265
|
+
|
|
266
|
+
```html
|
|
267
|
+
<!-- equivalent class markup -->
|
|
268
|
+
<div style="display:flex;gap:16px;flex-wrap:wrap;align-items:flex-start">
|
|
269
|
+
<div class="nk-pop">
|
|
270
|
+
<div class="nk-calendar weeks">
|
|
271
|
+
<div class="cal-head"><div class="cal-title">June 2026</div><button class="cal-nav">Today</button><button class="cal-nav" aria-label="Previous month"><svg viewBox="0 0 24 24" aria-hidden="true"><path d="M15 6l-6 6 6 6"/></svg></button><button class="cal-nav" aria-label="Next month"><svg viewBox="0 0 24 24" aria-hidden="true"><path d="M9 6l6 6-6 6"/></svg></button></div>
|
|
272
|
+
<div class="cal-grid">
|
|
273
|
+
<span class="cal-wd">W</span><span class="cal-wd">Mo</span><span class="cal-wd">Tu</span><span class="cal-wd">We</span><span class="cal-wd">Th</span><span class="cal-wd">Fr</span><span class="cal-wd">Sa</span><span class="cal-wd">Su</span>
|
|
274
|
+
<span class="cal-week">23</span><button class="cal-day">1</button><button class="cal-day selected">2<span class="cal-marks"><i class="blue"></i></span></button><button class="cal-day">3</button><button class="cal-day off" title="Corpus Christi">4</button><button class="cal-day">5</button><button class="cal-day off">6</button><button class="cal-day off">7</button>
|
|
275
|
+
<span class="cal-week">24</span><button class="cal-day">8</button><button class="cal-day">9</button><button class="cal-day">10</button><button class="cal-day">11<span class="cal-marks"><i class="orange"></i><i class="red"></i></span></button><button class="cal-day">12</button><button class="cal-day off">13</button><button class="cal-day off">14</button>
|
|
276
|
+
<span class="cal-week">25</span><button class="cal-day">15</button><button class="cal-day">16</button><button class="cal-day today">17</button><button class="cal-day">18</button><button class="cal-day">19</button><button class="cal-day off">20</button><button class="cal-day off">21</button>
|
|
277
|
+
<span class="cal-week">26</span><button class="cal-day">22</button><button class="cal-day">23</button><button class="cal-day">24<span class="cal-marks"><i class="green"></i></span></button><button class="cal-day">25</button><button class="cal-day">26</button><button class="cal-day off">27</button><button class="cal-day off">28</button>
|
|
278
|
+
<span class="cal-week">27</span><button class="cal-day">29</button><button class="cal-day">30</button><button class="cal-day out">1</button><button class="cal-day out">2</button><button class="cal-day out">3</button><button class="cal-day out off">4</button><button class="cal-day out off">5</button>
|
|
279
|
+
<span class="cal-week">28</span><button class="cal-day out">6</button><button class="cal-day out">7</button><button class="cal-day out">8</button><button class="cal-day out">9</button><button class="cal-day out">10</button><button class="cal-day out off">11</button><button class="cal-day out off">12</button>
|
|
280
|
+
</div>
|
|
281
|
+
<div class="cal-foot"><input class="nk-input" type="time" value="09:30" aria-label="Time"><button class="cal-nav">Clear</button></div>
|
|
282
|
+
</div>
|
|
283
|
+
</div>
|
|
284
|
+
<div class="nk-pop">
|
|
285
|
+
<div class="nk-calendar weeks">
|
|
286
|
+
<div class="cal-head"><div class="cal-title">June 2026</div><button class="cal-nav">Today</button><button class="cal-nav" aria-label="Previous month"><svg viewBox="0 0 24 24" aria-hidden="true"><path d="M15 6l-6 6 6 6"/></svg></button><button class="cal-nav" aria-label="Next month"><svg viewBox="0 0 24 24" aria-hidden="true"><path d="M9 6l6 6-6 6"/></svg></button></div>
|
|
287
|
+
<div class="cal-grid">
|
|
288
|
+
<span class="cal-wd">W</span><span class="cal-wd">Mo</span><span class="cal-wd">Tu</span><span class="cal-wd">We</span><span class="cal-wd">Th</span><span class="cal-wd">Fr</span><span class="cal-wd">Sa</span><span class="cal-wd">Su</span>
|
|
289
|
+
<span class="cal-week">23</span><button class="cal-day">1</button><button class="cal-day">2</button><button class="cal-day">3</button><button class="cal-day off" title="Corpus Christi">4</button><button class="cal-day">5</button><button class="cal-day off">6</button><button class="cal-day off">7</button>
|
|
290
|
+
<span class="cal-week">24</span><button class="cal-day start">8</button><button class="cal-day in-range">9</button><button class="cal-day in-range">10</button><button class="cal-day in-range">11</button><button class="cal-day end">12</button><button class="cal-day off">13</button><button class="cal-day off">14</button>
|
|
291
|
+
<span class="cal-week">25</span><button class="cal-day">15</button><button class="cal-day">16</button><button class="cal-day today">17</button><button class="cal-day">18</button><button class="cal-day">19</button><button class="cal-day off">20</button><button class="cal-day off">21</button>
|
|
292
|
+
<span class="cal-week">26</span><button class="cal-day">22</button><button class="cal-day">23</button><button class="cal-day">24</button><button class="cal-day">25</button><button class="cal-day">26</button><button class="cal-day off">27</button><button class="cal-day off">28</button>
|
|
293
|
+
<span class="cal-week">27</span><button class="cal-day">29</button><button class="cal-day">30</button><button class="cal-day out">1</button><button class="cal-day out">2</button><button class="cal-day out">3</button><button class="cal-day out off">4</button><button class="cal-day out off">5</button>
|
|
294
|
+
<span class="cal-week">28</span><button class="cal-day out">6</button><button class="cal-day out">7</button><button class="cal-day out">8</button><button class="cal-day out">9</button><button class="cal-day out">10</button><button class="cal-day out off">11</button><button class="cal-day out off">12</button>
|
|
295
|
+
</div>
|
|
296
|
+
</div>
|
|
297
|
+
</div>
|
|
298
|
+
</div>
|
|
299
|
+
```
|
|
300
|
+
|
|
301
|
+
**Small screens:** Floating with `sheet`: a bottom sheet with 44px cells, a thumb’s width; seven days and the week column still fit a 390px screen.
|
|
302
|
+
|
|
303
|
+
### 3.6 `<nk-textarea>` – Textarea
|
|
304
|
+
|
|
305
|
+
Multi-line sibling of `nk-input`. The initial value is the `value` attribute or the element’s text content.
|
|
306
|
+
|
|
307
|
+
```html
|
|
308
|
+
<nk-textarea name="bio" rows="3" placeholder="A sentence about you"></nk-textarea>
|
|
309
|
+
```
|
|
310
|
+
|
|
311
|
+
| Attribute | Type | Default | Description |
|
|
312
|
+
|---|---|---|---|
|
|
313
|
+
| `value` | string | – | Current value. |
|
|
314
|
+
| `placeholder` | string | – | Placeholder text. |
|
|
315
|
+
| `rows` | number | – | Visible rows. |
|
|
316
|
+
| `name` | string | – | Form field name (FormData key). |
|
|
317
|
+
| `disabled` | boolean | – | Disables the control. |
|
|
318
|
+
| `required` | boolean | – | Required field. |
|
|
319
|
+
| `wide` | boolean | – | Full width. |
|
|
320
|
+
|
|
321
|
+
**Slots:** `(default)` – Initial text (used when `value` is absent).
|
|
322
|
+
|
|
323
|
+
**Events:** `nk-change` `{ value, name }` – On commit. · `nk-input` `{ value, name }` – On every keystroke.
|
|
324
|
+
|
|
325
|
+
**Replaces:** `.nk-textarea`, `.wide`
|
|
326
|
+
|
|
327
|
+
```html
|
|
328
|
+
<!-- equivalent class markup -->
|
|
329
|
+
<textarea class="nk-textarea" name="bio" rows="3" placeholder="A sentence about you"></textarea>
|
|
330
|
+
```
|
|
331
|
+
|
|
332
|
+
**Small screens:** Resizes vertically only; `wide` fills the row.
|
|
333
|
+
|
|
334
|
+
### 3.7 `<nk-select>` – Select
|
|
335
|
+
|
|
336
|
+
Light-DOM `<option>` and `<optgroup>` children are copied into the shadow `<select>` and kept in step when a framework swaps them. The empty string is a valid value; a `value` naming no option leaves the selection alone. A `value` set before its option exists – a framework sets properties before children – waits and is applied once the option arrives.
|
|
337
|
+
|
|
338
|
+
```html
|
|
339
|
+
<nk-select name="role" value="editor">
|
|
340
|
+
<option value="viewer">Viewer</option>
|
|
341
|
+
<option value="editor">Editor</option>
|
|
342
|
+
<option value="admin">Admin</option>
|
|
343
|
+
</nk-select>
|
|
344
|
+
```
|
|
345
|
+
|
|
346
|
+
| Attribute | Type | Default | Description |
|
|
347
|
+
|---|---|---|---|
|
|
348
|
+
| `value` | string | – | Selected value. |
|
|
349
|
+
| `name` | string | – | Form field name (FormData key). |
|
|
350
|
+
| `disabled` | boolean | – | Disables the control. |
|
|
351
|
+
| `required` | boolean | – | Required field. |
|
|
352
|
+
| `compact` | boolean | – | 120px minimum width (`.compact`), e.g. inside a member row. |
|
|
353
|
+
| `wide` | boolean | – | Full width (`.nk-select.wide`). |
|
|
354
|
+
|
|
355
|
+
**Slots:** `(default)` – `<option>` / `<optgroup>` children – direct children only.
|
|
356
|
+
|
|
357
|
+
**Events:** `nk-change` `{ value, name }` – On selection.
|
|
358
|
+
|
|
359
|
+
**Properties:** `value`, `selectedIndex`, `options` · **Methods:** `refresh()`
|
|
360
|
+
|
|
361
|
+
**Replaces:** `.nk-select`, `.compact`
|
|
362
|
+
|
|
363
|
+
```html
|
|
364
|
+
<!-- equivalent class markup -->
|
|
365
|
+
<select class="nk-select" name="role">
|
|
366
|
+
<option value="viewer">Viewer</option>
|
|
367
|
+
<option value="editor" selected>Editor</option>
|
|
368
|
+
<option value="admin">Admin</option>
|
|
369
|
+
</select>
|
|
370
|
+
```
|
|
371
|
+
|
|
372
|
+
**Small screens:** Uses the native picker of the platform (`color-scheme` follows the theme).
|
|
373
|
+
|
|
374
|
+
### 3.8 `<nk-switch>` – Switch
|
|
375
|
+
|
|
376
|
+
Renders `button.nk-switch[role=switch]`; the stylesheet keys the knob on `aria-checked`, the element does the toggling. Submits `value` (default `on`) when checked, nothing otherwise – like a checkbox.
|
|
377
|
+
|
|
378
|
+
```html
|
|
379
|
+
<div style="display:flex;gap:20px;flex-wrap:wrap;align-items:center"><nk-switch name="notify" checked label="Email notifications"></nk-switch>
|
|
380
|
+
<nk-switch name="planned" checked>Planned</nk-switch><nk-switch name="progress">In progress</nk-switch><nk-switch name="done" text="Done" checked></nk-switch></div>
|
|
381
|
+
```
|
|
382
|
+
|
|
383
|
+
| Attribute | Type | Default | Description |
|
|
384
|
+
|---|---|---|---|
|
|
385
|
+
| `checked` | boolean | – | On/off state. |
|
|
386
|
+
| `name` | string | – | Form field name (FormData key). |
|
|
387
|
+
| `disabled` | boolean | – | Disables the control. |
|
|
388
|
+
| `value` | string | `on` | Submitted value when checked. |
|
|
389
|
+
| `text` | string | – | Visible text beside the switch (alternative to the default slot). |
|
|
390
|
+
| `label` | string | – | Accessible name (`aria-label`) when there is no visible text. |
|
|
391
|
+
|
|
392
|
+
**Slots:** `(default)` – Visible text beside the switch; part of the hit area. Without it the element renders the bare button.
|
|
393
|
+
|
|
394
|
+
**Events:** `nk-change` `{ checked, value, name }` – On toggle.
|
|
395
|
+
|
|
396
|
+
**Methods:** `toggle()`
|
|
397
|
+
|
|
398
|
+
**Replaces:** `.nk-switch`, `.nk-switch-label`
|
|
399
|
+
|
|
400
|
+
```html
|
|
401
|
+
<!-- equivalent class markup -->
|
|
402
|
+
<div style="display:flex;gap:20px;flex-wrap:wrap;align-items:center"><button class="nk-switch" role="switch" aria-checked="true" aria-label="Email notifications"></button>
|
|
403
|
+
<label class="nk-switch-label"><button class="nk-switch" role="switch" aria-checked="true"></button><span>Planned</span></label><label class="nk-switch-label"><button class="nk-switch" role="switch" aria-checked="false"></button><span>In progress</span></label><label class="nk-switch-label"><button class="nk-switch" role="switch" aria-checked="true"></button><span>Done</span></label></div>
|
|
404
|
+
```
|
|
405
|
+
|
|
406
|
+
**Small screens:** 34×20px – below the 44px touch target. Give it a label row (`nk-field`) to enlarge the hit area.
|
|
407
|
+
|
|
408
|
+
### 3.9 `<nk-check>` – Checkbox
|
|
409
|
+
|
|
410
|
+
A `label.nk-check` with a custom-drawn checkbox; the label text is slotted, so clicking it toggles the box.
|
|
411
|
+
|
|
412
|
+
```html
|
|
413
|
+
<nk-check name="digest" value="weekly" checked>Weekly digest</nk-check>
|
|
414
|
+
<nk-check name="digest" value="mentions">Mentions only</nk-check>
|
|
415
|
+
```
|
|
416
|
+
|
|
417
|
+
| Attribute | Type | Default | Description |
|
|
418
|
+
|---|---|---|---|
|
|
419
|
+
| `checked` | boolean | – | Checked state. |
|
|
420
|
+
| `indeterminate` | boolean | – | Mixed state (cleared on the next click). |
|
|
421
|
+
| `name` | string | – | Form field name (FormData key). |
|
|
422
|
+
| `disabled` | boolean | – | Disables the control. |
|
|
423
|
+
| `value` | string | `on` | Submitted value. |
|
|
424
|
+
| `required` | boolean | – | Must be checked to submit. |
|
|
425
|
+
| `text` | string | – | Label text (alternative to the default slot). |
|
|
426
|
+
|
|
427
|
+
**Slots:** `(default)` – Label text.
|
|
428
|
+
|
|
429
|
+
**Events:** `nk-change` `{ checked, value, name }` – On toggle.
|
|
430
|
+
|
|
431
|
+
**Replaces:** `.nk-check`
|
|
432
|
+
|
|
433
|
+
```html
|
|
434
|
+
<!-- equivalent class markup -->
|
|
435
|
+
<label class="nk-check"><input type="checkbox" name="digest" value="weekly" checked>Weekly digest</label>
|
|
436
|
+
<label class="nk-check"><input type="checkbox" name="digest" value="mentions">Mentions only</label>
|
|
437
|
+
```
|
|
438
|
+
|
|
439
|
+
**Small screens:** Row height ~24px; the whole label is the hit area.
|
|
440
|
+
|
|
441
|
+
### 3.10 `<nk-radio>` – Radio
|
|
442
|
+
|
|
443
|
+
Same optics as `nk-check` with a round mark. Radios with the same `name` in the same tree and form form one group – across shadow roots, which native radios cannot do. One tab stop per group; arrow keys move, wrap and skip disabled entries. There is deliberately no `nk-radio-group`.
|
|
444
|
+
|
|
445
|
+
```html
|
|
446
|
+
<nk-radio name="style" value="concise">Concise</nk-radio>
|
|
447
|
+
<nk-radio name="style" value="balanced" checked>Balanced</nk-radio>
|
|
448
|
+
<nk-radio name="style" value="detailed">Detailed</nk-radio>
|
|
449
|
+
```
|
|
450
|
+
|
|
451
|
+
| Attribute | Type | Default | Description |
|
|
452
|
+
|---|---|---|---|
|
|
453
|
+
| `checked` | boolean | – | Selected; the last checked radio in markup wins. |
|
|
454
|
+
| `name` | string | – | Form field name (FormData key). |
|
|
455
|
+
| `disabled` | boolean | – | Disables the control. |
|
|
456
|
+
| `value` | string | – | Submitted value. |
|
|
457
|
+
| `required` | boolean | – | One of the group must be selected. |
|
|
458
|
+
| `text` | string | – | Label text (alternative to the default slot). |
|
|
459
|
+
|
|
460
|
+
**Slots:** `(default)` – Label text.
|
|
461
|
+
|
|
462
|
+
**Events:** `nk-change` `{ checked, value, name }` – On selection, also via arrow keys.
|
|
463
|
+
|
|
464
|
+
**Replaces:** `.nk-check`
|
|
465
|
+
|
|
466
|
+
```html
|
|
467
|
+
<!-- equivalent class markup -->
|
|
468
|
+
<label class="nk-check"><input type="radio" name="style" value="concise">Concise</label>
|
|
469
|
+
<label class="nk-check"><input type="radio" name="style" value="balanced" checked>Balanced</label>
|
|
470
|
+
<label class="nk-check"><input type="radio" name="style" value="detailed">Detailed</label>
|
|
471
|
+
```
|
|
472
|
+
|
|
473
|
+
**Small screens:** As `nk-check`.
|
|
474
|
+
|
|
475
|
+
### 3.11 `<nk-slider>` – Slider
|
|
476
|
+
|
|
477
|
+
A range input with `accent-color` from the tokens, plus an optional value readout below.
|
|
478
|
+
|
|
479
|
+
```html
|
|
480
|
+
<nk-slider name="size" min="12" max="18" value="14" unit="px" show-value></nk-slider>
|
|
481
|
+
```
|
|
482
|
+
|
|
483
|
+
| Attribute | Type | Default | Description |
|
|
484
|
+
|---|---|---|---|
|
|
485
|
+
| `value` | number | – | Current value. |
|
|
486
|
+
| `min` | number | – | Minimum. |
|
|
487
|
+
| `max` | number | – | Maximum. |
|
|
488
|
+
| `step` | number | – | Step. |
|
|
489
|
+
| `name` | string | – | Form field name (FormData key). |
|
|
490
|
+
| `disabled` | boolean | – | Disables the control. |
|
|
491
|
+
| `show-value` | boolean | – | Shows the value below the slider. |
|
|
492
|
+
| `unit` | string | – | Suffix for the readout (e.g. `px`). |
|
|
493
|
+
|
|
494
|
+
**Events:** `nk-change` `{ value, name }` – On release. · `nk-input` `{ value, name }` – While dragging.
|
|
495
|
+
|
|
496
|
+
**Replaces:** `.nk-slider`, `.nk-slider-value`
|
|
497
|
+
|
|
498
|
+
```html
|
|
499
|
+
<!-- equivalent class markup -->
|
|
500
|
+
<input type="range" class="nk-slider" name="size" min="12" max="18" value="14"><div class="nk-slider-value">14px</div>
|
|
501
|
+
```
|
|
502
|
+
|
|
503
|
+
**Small screens:** 210px wide; the native thumb is touch-sized by the platform.
|
|
504
|
+
|
|
505
|
+
### 3.12 `<nk-field>` – Field row
|
|
506
|
+
|
|
507
|
+
The settings row: label and description left, control right. Put any control – `nk-input`, `nk-switch`, `nk-select` – in the default slot. `stacked` puts the label above a full-width control (textareas, long descriptions) and sets `wide` on the control for you; `compact` shrinks the label to 12px tertiary text. Inside `nk-fields` both are on by default.
|
|
508
|
+
|
|
509
|
+
```html
|
|
510
|
+
<nk-field label="Display name" desc="Shown next to your comments.">
|
|
511
|
+
<nk-input value="Ada Lovelace"></nk-input>
|
|
512
|
+
</nk-field>
|
|
513
|
+
<nk-field label="Email notifications">
|
|
514
|
+
<nk-switch checked></nk-switch>
|
|
515
|
+
</nk-field>
|
|
516
|
+
<nk-field label="Short bio" stacked>
|
|
517
|
+
<nk-textarea rows="2" placeholder="A sentence about you"></nk-textarea>
|
|
518
|
+
</nk-field>
|
|
519
|
+
```
|
|
520
|
+
|
|
521
|
+
| Attribute | Type | Default | Description |
|
|
522
|
+
|---|---|---|---|
|
|
523
|
+
| `label` | string | – | Label text. |
|
|
524
|
+
| `desc` | string | – | Secondary description. |
|
|
525
|
+
| `stacked` | boolean | – | Label above a full-width control. |
|
|
526
|
+
| `compact` | boolean | – | Small tertiary label, no row padding. |
|
|
527
|
+
|
|
528
|
+
**Slots:** `(default)` – The control. · `label` – Rich label content (instead of the attribute). · `desc` – Rich description.
|
|
529
|
+
|
|
530
|
+
**Replaces:** `.nk-field`, `.f-label`, `.f-desc`, `.f-control`, `.stacked`, `.compact`
|
|
531
|
+
|
|
532
|
+
```html
|
|
533
|
+
<!-- equivalent class markup -->
|
|
534
|
+
<div class="nk-field">
|
|
535
|
+
<div><div class="f-label">Display name</div><div class="f-desc">Shown next to your comments.</div></div>
|
|
536
|
+
<div class="f-control"><input class="nk-input" value="Ada Lovelace"></div>
|
|
537
|
+
</div>
|
|
538
|
+
<div class="nk-field">
|
|
539
|
+
<div><div class="f-label">Email notifications</div></div>
|
|
540
|
+
<div class="f-control"><button class="nk-switch" role="switch" aria-checked="true"></button></div>
|
|
541
|
+
</div>
|
|
542
|
+
<div class="nk-field stacked">
|
|
543
|
+
<div><div class="f-label">Short bio</div></div>
|
|
544
|
+
<div class="f-control"><textarea class="nk-textarea wide" rows="2" placeholder="A sentence about you"></textarea></div>
|
|
545
|
+
</div>
|
|
546
|
+
```
|
|
547
|
+
|
|
548
|
+
**Small screens:** Stays a row; long descriptions wrap under the label. Use `stacked` where the control needs the whole width.
|
|
549
|
+
|
|
550
|
+
### 3.13 `<nk-fields>` – Field grid
|
|
551
|
+
|
|
552
|
+
Several short fields in one row: a grid of `minmax(150px, 1fr)` columns that wraps as the width allows. Every `nk-field` inside renders itself stacked and compact – a 12px label above a full-width control – so nothing collides.
|
|
553
|
+
|
|
554
|
+
```html
|
|
555
|
+
<nk-fields>
|
|
556
|
+
<nk-field label="Display name"><nk-input value="Ada Lovelace"></nk-input></nk-field>
|
|
557
|
+
<nk-field label="Email"><nk-input value="ada@acme.com"></nk-input></nk-field>
|
|
558
|
+
<nk-field label="Role"><nk-select value="editor"><option value="viewer">Viewer</option><option value="editor">Editor</option></nk-select></nk-field>
|
|
559
|
+
</nk-fields>
|
|
560
|
+
```
|
|
561
|
+
|
|
562
|
+
| Attribute | Type | Default | Description |
|
|
563
|
+
|---|---|---|---|
|
|
564
|
+
| `fit` | boolean | – | The fields share the row instead of keeping 150px columns – two fields in a wide dialog are two halves. |
|
|
565
|
+
|
|
566
|
+
**Slots:** `(default)` – `nk-field` children.
|
|
567
|
+
|
|
568
|
+
**Replaces:** `.nk-fields`, `.fit`
|
|
569
|
+
|
|
570
|
+
```html
|
|
571
|
+
<!-- equivalent class markup -->
|
|
572
|
+
<div class="nk-fields">
|
|
573
|
+
<div class="nk-field"><div><div class="f-label">Display name</div></div><div class="f-control"><input class="nk-input" value="Ada Lovelace"></div></div>
|
|
574
|
+
<div class="nk-field"><div><div class="f-label">Email</div></div><div class="f-control"><input class="nk-input" value="ada@acme.com"></div></div>
|
|
575
|
+
<div class="nk-field"><div><div class="f-label">Role</div></div><div class="f-control"><select class="nk-select"><option>Viewer</option><option selected>Editor</option></select></div></div>
|
|
576
|
+
</div>
|
|
577
|
+
```
|
|
578
|
+
|
|
579
|
+
**Small screens:** Wraps to one or two columns on its own; no breakpoint needed.
|
|
580
|
+
|
|
581
|
+
## Content elements (wave 1)
|
|
582
|
+
|
|
583
|
+
### 3.14 `<nk-tag>` – Tag
|
|
584
|
+
|
|
585
|
+
The select option as Notion draws it, in its nine colours. The colour modifier class becomes the `color` attribute; without one it is the grey tag. Each pair is tuned per theme.
|
|
586
|
+
|
|
587
|
+
```html
|
|
588
|
+
<nk-tag>Not started</nk-tag> <nk-tag color="brown">Archive</nk-tag> <nk-tag color="orange">Planned</nk-tag> <nk-tag color="yellow">Review</nk-tag> <nk-tag color="green">Done</nk-tag> <nk-tag color="blue">In progress</nk-tag> <nk-tag color="purple">Design</nk-tag> <nk-tag color="pink">Idea</nk-tag> <nk-tag color="red">Blocked</nk-tag>
|
|
589
|
+
```
|
|
590
|
+
|
|
591
|
+
| Attribute | Type | Default | Description |
|
|
592
|
+
|---|---|---|---|
|
|
593
|
+
| `color` | gray | brown | orange | yellow | green | blue | purple | pink | red | – | Colour pair; grey without it. |
|
|
594
|
+
|
|
595
|
+
**Slots:** `(default)` – Tag text.
|
|
596
|
+
|
|
597
|
+
**Replaces:** `.nk-tag`, `.gray`, `.brown`, `.orange`, `.yellow`, `.green`, `.blue`, `.purple`, `.pink`, `.red`
|
|
598
|
+
|
|
599
|
+
```html
|
|
600
|
+
<!-- equivalent class markup -->
|
|
601
|
+
<span class="nk-tag">Not started</span> <span class="nk-tag brown">Archive</span> <span class="nk-tag orange">Planned</span> <span class="nk-tag yellow">Review</span> <span class="nk-tag green">Done</span> <span class="nk-tag blue">In progress</span> <span class="nk-tag purple">Design</span> <span class="nk-tag pink">Idea</span> <span class="nk-tag red">Blocked</span>
|
|
602
|
+
```
|
|
603
|
+
|
|
604
|
+
**Small screens:** Unchanged.
|
|
605
|
+
|
|
606
|
+
### 3.15 `<nk-progress>` – Progress
|
|
607
|
+
|
|
608
|
+
A 60px bar with an optional label. `value`/`max` set the fill; the bar carries `role="progressbar"`.
|
|
609
|
+
|
|
610
|
+
```html
|
|
611
|
+
<nk-progress value="72" label="72%"></nk-progress>
|
|
612
|
+
```
|
|
613
|
+
|
|
614
|
+
| Attribute | Type | Default | Description |
|
|
615
|
+
|---|---|---|---|
|
|
616
|
+
| `value` | number | `0` | Current value. |
|
|
617
|
+
| `max` | number | `100` | Maximum. |
|
|
618
|
+
| `label` | string | – | Text after the bar. |
|
|
619
|
+
| `wide` | boolean | – | Fills its row – a property value, a panel; in a flex row the label stays beside it. |
|
|
620
|
+
|
|
621
|
+
|
|
622
|
+
|
|
623
|
+
**Replaces:** `.nk-progress`, `.nk-progress-label`, `.wide`
|
|
624
|
+
|
|
625
|
+
```html
|
|
626
|
+
<!-- equivalent class markup -->
|
|
627
|
+
<span class="nk-progress"><i style="width:72%"></i></span><span class="nk-progress-label">72%</span>
|
|
628
|
+
```
|
|
629
|
+
|
|
630
|
+
**Small screens:** Unchanged.
|
|
631
|
+
|
|
632
|
+
### 3.16 `<nk-callout>` – Callout
|
|
633
|
+
|
|
634
|
+
One thought that must not be missed. The icon comes from the `icon` attribute or a `slot="icon"` node – the node itself, never wrapped.
|
|
635
|
+
|
|
636
|
+
```html
|
|
637
|
+
<nk-callout icon="💡"><b>Core idea:</b> A callout carries one thought that must not be missed.</nk-callout>
|
|
638
|
+
```
|
|
639
|
+
|
|
640
|
+
| Attribute | Type | Default | Description |
|
|
641
|
+
|---|---|---|---|
|
|
642
|
+
| `icon` | string | `💡` | Emoji or text icon. |
|
|
643
|
+
|
|
644
|
+
**Slots:** `(default)` – Body. · `icon` – Icon node (e.g. `<span slot="icon">📌</span>`).
|
|
645
|
+
|
|
646
|
+
**Replaces:** `.nk-callout`, `.c-icon`
|
|
647
|
+
|
|
648
|
+
```html
|
|
649
|
+
<!-- equivalent class markup -->
|
|
650
|
+
<div class="nk-callout"><span class="c-icon">💡</span><div><b>Core idea:</b> A callout carries one thought that must not be missed.</div></div>
|
|
651
|
+
```
|
|
652
|
+
|
|
653
|
+
**Small screens:** Unchanged; wraps with the text.
|
|
654
|
+
|
|
655
|
+
### 3.17 `<nk-bookmark>` – Bookmark
|
|
656
|
+
|
|
657
|
+
Notion’s link block, filled from what you know of the page – `og:title`, `og:description`, `og:image`: title, two lines of description and the address with its icon on the left, the image on the right in a third, 240px at most. `title` is the heading, never a tooltip; without it the host name stands in. `url` shows an address other than `href`. Opens in a new tab unless `target` says otherwise; a part without a value is left out.
|
|
658
|
+
|
|
659
|
+
```html
|
|
660
|
+
<div style="max-width:600px"><nk-bookmark href="https://notionkit.jungherz.com" title="NotionKit – the calm workspace look as CSS" desc="NotionKit is a pure CSS component library in the Notion idiom: sidebar, page tree, document shell, database views, settings and AI surfaces." favicon="/favicon.svg" cover="/covers/notionkit-og.jpg"></nk-bookmark></div>
|
|
661
|
+
```
|
|
662
|
+
|
|
663
|
+
| Attribute | Type | Default | Description |
|
|
664
|
+
|---|---|---|---|
|
|
665
|
+
| `href` | URL | – | The link. |
|
|
666
|
+
| `title` | string | – | Title – og:title. |
|
|
667
|
+
| `desc` | string | – | Description, two lines – og:description. |
|
|
668
|
+
| `favicon` | URL | – | The site’s icon, 16px. |
|
|
669
|
+
| `cover` | URL | – | Preview image – og:image. |
|
|
670
|
+
| `url` | string | – | The address shown (default: href). |
|
|
671
|
+
| `target` | string | `_blank` | Link target. |
|
|
672
|
+
|
|
673
|
+
**Events:** `click` `(native)` – The link is a plain `<a>`.
|
|
674
|
+
|
|
675
|
+
**Properties:** `title`, `href`
|
|
676
|
+
|
|
677
|
+
**Replaces:** `.nk-bookmark`, `.bm-text`, `.bm-title`, `.bm-desc`, `.bm-url`, `.bm-favicon`, `.bm-cover`
|
|
678
|
+
|
|
679
|
+
```html
|
|
680
|
+
<!-- equivalent class markup -->
|
|
681
|
+
<div style="max-width:600px"><a class="nk-bookmark" href="https://notionkit.jungherz.com" target="_blank" rel="noopener"><span class="bm-text"><span class="bm-title">NotionKit – the calm workspace look as CSS</span><span class="bm-desc">NotionKit is a pure CSS component library in the Notion idiom: sidebar, page tree, document shell, database views, settings and AI surfaces.</span><span class="bm-url"><img class="bm-favicon" src="/favicon.svg" alt=""><span>https://notionkit.jungherz.com</span></span></span><span class="bm-cover"><img src="/covers/notionkit-og.jpg" alt=""></span></a></div>
|
|
682
|
+
```
|
|
683
|
+
|
|
684
|
+
**Small screens:** The image keeps its third and is cropped at the centre; title and address end in an ellipsis.
|
|
685
|
+
|
|
686
|
+
### 3.18 `<nk-divider>` – Divider
|
|
687
|
+
|
|
688
|
+
A hairline `<hr>` with block spacing.
|
|
689
|
+
|
|
690
|
+
```html
|
|
691
|
+
<nk-divider></nk-divider>
|
|
692
|
+
```
|
|
693
|
+
|
|
694
|
+
_No attributes._
|
|
695
|
+
|
|
696
|
+
|
|
697
|
+
|
|
698
|
+
**Replaces:** `.nk-divider`
|
|
699
|
+
|
|
700
|
+
```html
|
|
701
|
+
<!-- equivalent class markup -->
|
|
702
|
+
<hr class="nk-divider">
|
|
703
|
+
```
|
|
704
|
+
|
|
705
|
+
**Small screens:** Unchanged.
|
|
706
|
+
|
|
707
|
+
### 3.19 `<nk-heading>` – Heading
|
|
708
|
+
|
|
709
|
+
A section heading. `level` chooses the real heading element (h1–h4), so the document outline stays honest.
|
|
710
|
+
|
|
711
|
+
```html
|
|
712
|
+
<nk-heading>Section heading</nk-heading>
|
|
713
|
+
```
|
|
714
|
+
|
|
715
|
+
| Attribute | Type | Default | Description |
|
|
716
|
+
|---|---|---|---|
|
|
717
|
+
| `level` | 1 | 2 | 3 | 4 | `2` | Heading level. |
|
|
718
|
+
|
|
719
|
+
**Slots:** `(default)` – Heading text.
|
|
720
|
+
|
|
721
|
+
**Replaces:** `.nk-heading`
|
|
722
|
+
|
|
723
|
+
```html
|
|
724
|
+
<!-- equivalent class markup -->
|
|
725
|
+
<h2 class="nk-heading">Section heading</h2>
|
|
726
|
+
```
|
|
727
|
+
|
|
728
|
+
**Small screens:** Unchanged.
|
|
729
|
+
|
|
730
|
+
### 3.20 `<nk-toggle>` – Toggle block
|
|
731
|
+
|
|
732
|
+
A `<details>` block. The summary is rendered inside the element (its marker is a pseudo-element and cannot be styled on slotted content); the body is slotted.
|
|
733
|
+
|
|
734
|
+
```html
|
|
735
|
+
<nk-toggle label="Details" open>Folded content lives here.</nk-toggle>
|
|
736
|
+
```
|
|
737
|
+
|
|
738
|
+
| Attribute | Type | Default | Description |
|
|
739
|
+
|---|---|---|---|
|
|
740
|
+
| `label` | string | – | Summary text. |
|
|
741
|
+
| `open` | boolean | – | Expanded state, reflected both ways. |
|
|
742
|
+
|
|
743
|
+
**Slots:** `(default)` – Folded content. · `label` – Rich summary content.
|
|
744
|
+
|
|
745
|
+
**Events:** `nk-toggle` `{ open }` – On open/close.
|
|
746
|
+
|
|
747
|
+
**Replaces:** `.nk-toggle`, `.toggle-body`
|
|
748
|
+
|
|
749
|
+
```html
|
|
750
|
+
<!-- equivalent class markup -->
|
|
751
|
+
<details class="nk-toggle" open><summary>Details</summary><div class="toggle-body">Folded content lives here.</div></details>
|
|
752
|
+
```
|
|
753
|
+
|
|
754
|
+
**Small screens:** Unchanged.
|
|
755
|
+
|
|
756
|
+
### 3.21 `<nk-todo>` – To-do
|
|
757
|
+
|
|
758
|
+
Checkbox line with strike-through when done. Form-associated like `nk-check`.
|
|
759
|
+
|
|
760
|
+
```html
|
|
761
|
+
<nk-todo checked>Write the docs</nk-todo>
|
|
762
|
+
<nk-todo>Ship it</nk-todo>
|
|
763
|
+
```
|
|
764
|
+
|
|
765
|
+
| Attribute | Type | Default | Description |
|
|
766
|
+
|---|---|---|---|
|
|
767
|
+
| `checked` | boolean | – | Done. |
|
|
768
|
+
| `name` | string | – | Form field name (FormData key). |
|
|
769
|
+
| `disabled` | boolean | – | Disables the control. |
|
|
770
|
+
| `value` | string | `on` | Submitted value. |
|
|
771
|
+
|
|
772
|
+
**Slots:** `(default)` – Task text.
|
|
773
|
+
|
|
774
|
+
**Events:** `nk-change` `{ checked, value, name }` – On toggle.
|
|
775
|
+
|
|
776
|
+
**Replaces:** `.nk-todo`
|
|
777
|
+
|
|
778
|
+
```html
|
|
779
|
+
<!-- equivalent class markup -->
|
|
780
|
+
<label class="nk-todo"><input type="checkbox" checked><span>Write the docs</span></label>
|
|
781
|
+
<label class="nk-todo"><input type="checkbox"><span>Ship it</span></label>
|
|
782
|
+
```
|
|
783
|
+
|
|
784
|
+
**Small screens:** Unchanged.
|
|
785
|
+
|
|
786
|
+
### 3.22 `<nk-kbd>` – Key cap
|
|
787
|
+
|
|
788
|
+
A keyboard key, e.g. in shortcut hints.
|
|
789
|
+
|
|
790
|
+
```html
|
|
791
|
+
<nk-kbd>⌘</nk-kbd> <nk-kbd>K</nk-kbd>
|
|
792
|
+
```
|
|
793
|
+
|
|
794
|
+
_No attributes._
|
|
795
|
+
|
|
796
|
+
**Slots:** `(default)` – Key label.
|
|
797
|
+
|
|
798
|
+
**Replaces:** `.nk-kbd`
|
|
799
|
+
|
|
800
|
+
```html
|
|
801
|
+
<!-- equivalent class markup -->
|
|
802
|
+
<kbd class="nk-kbd">⌘</kbd> <kbd class="nk-kbd">K</kbd>
|
|
803
|
+
```
|
|
804
|
+
|
|
805
|
+
**Small screens:** Unchanged.
|
|
806
|
+
|
|
807
|
+
### 3.23 `<nk-code>` – Code block
|
|
808
|
+
|
|
809
|
+
Pre-formatted block with a language badge. Whitespace is kept as written; escape `<` as `<`. With `highlight`, HTML tags and attributes are coloured.
|
|
810
|
+
|
|
811
|
+
```html
|
|
812
|
+
<nk-code lang="html" highlight><nk-btn variant="primary">Save</nk-btn></nk-code>
|
|
813
|
+
```
|
|
814
|
+
|
|
815
|
+
| Attribute | Type | Default | Description |
|
|
816
|
+
|---|---|---|---|
|
|
817
|
+
| `lang` | string | – | Language badge, top right. |
|
|
818
|
+
| `highlight` | boolean | – | Colour HTML tags/attributes. |
|
|
819
|
+
|
|
820
|
+
**Slots:** `(default)` – The code, as text.
|
|
821
|
+
|
|
822
|
+
**Replaces:** `.nk-code`, `.lang`, `.tag`, `.attr`
|
|
823
|
+
|
|
824
|
+
```html
|
|
825
|
+
<!-- equivalent class markup -->
|
|
826
|
+
<div class="nk-code"><span class="lang">html</span><<span class="tag">nk-btn</span> <span class="attr">variant</span>="primary">Save</<span class="tag">nk-btn</span>></div>
|
|
827
|
+
```
|
|
828
|
+
|
|
829
|
+
**Small screens:** Scrolls horizontally instead of wrapping.
|
|
830
|
+
|
|
831
|
+
### 3.24 `<nk-quote>` – Quote
|
|
832
|
+
|
|
833
|
+
A block quote with an optional citation line.
|
|
834
|
+
|
|
835
|
+
```html
|
|
836
|
+
<nk-quote cite="Unknown">The best interface is the one that gets out of the way.</nk-quote>
|
|
837
|
+
```
|
|
838
|
+
|
|
839
|
+
| Attribute | Type | Default | Description |
|
|
840
|
+
|---|---|---|---|
|
|
841
|
+
| `cite` | string | – | Citation text. |
|
|
842
|
+
|
|
843
|
+
**Slots:** `(default)` – Quote text.
|
|
844
|
+
|
|
845
|
+
**Replaces:** `.nk-quote`, `.q-cite`
|
|
846
|
+
|
|
847
|
+
```html
|
|
848
|
+
<!-- equivalent class markup -->
|
|
849
|
+
<blockquote class="nk-quote">The best interface is the one that gets out of the way.<cite class="q-cite">Unknown</cite></blockquote>
|
|
850
|
+
```
|
|
851
|
+
|
|
852
|
+
**Small screens:** Unchanged.
|
|
853
|
+
|
|
854
|
+
## App shell & navigation (wave 2)
|
|
855
|
+
|
|
856
|
+
### 3.25 `<nk-app>` – App shell
|
|
857
|
+
|
|
858
|
+
The outermost element of a workspace app: a full-height flex row with the sidebar slot left and `main.nk-main` right. Everything in the default slot – `nk-topbar`, `nk-page` – becomes a flex child of the main column.
|
|
859
|
+
|
|
860
|
+
```html
|
|
861
|
+
<nk-app>
|
|
862
|
+
<nk-sidebar slot="sidebar">
|
|
863
|
+
<nk-workspace-switcher slot="workspace" name="MonaHilft"></nk-workspace-switcher>
|
|
864
|
+
<nk-tree>
|
|
865
|
+
<nk-tree-item icon="🔍">Search<span slot="end" class="nk-kbd-hint"><nk-kbd>⌘</nk-kbd><nk-kbd>K</nk-kbd></span></nk-tree-item>
|
|
866
|
+
<nk-tree-item icon="🏠" active>Home</nk-tree-item>
|
|
867
|
+
<nk-tree-item icon="📥">Inbox</nk-tree-item>
|
|
868
|
+
</nk-tree>
|
|
869
|
+
<nk-tree-item slot="footer" icon="⚙️">Settings</nk-tree-item>
|
|
870
|
+
</nk-sidebar>
|
|
871
|
+
<nk-topbar>
|
|
872
|
+
<nk-breadcrumb><span>📊 Project overview</span></nk-breadcrumb>
|
|
873
|
+
<nk-btn slot="actions" variant="share">Share</nk-btn>
|
|
874
|
+
<nk-theme-toggle slot="actions"></nk-theme-toggle>
|
|
875
|
+
</nk-topbar>
|
|
876
|
+
<div class="nk-page-scroll"><div class="nk-page" style="padding-top:16px">
|
|
877
|
+
<h1 class="nk-page-title" style="font-size:28px">NotionKit MVP</h1>
|
|
878
|
+
<p class="lead">A calm, document-centric workspace app – built from elements only.</p>
|
|
879
|
+
</div></div>
|
|
880
|
+
</nk-app>
|
|
881
|
+
```
|
|
882
|
+
|
|
883
|
+
| Attribute | Type | Default | Description |
|
|
884
|
+
|---|---|---|---|
|
|
885
|
+
| `peek-inset` | boolean | – | The main column makes room for the side peek – `<nk-peek inset>` sets it while open. |
|
|
886
|
+
|
|
887
|
+
**Slots:** `sidebar` – An `nk-sidebar`. · `(default)` – Topbar, page – the main column.
|
|
888
|
+
|
|
889
|
+
**Replaces:** `.nk-app`, `.nk-main`, `.peek-inset`
|
|
890
|
+
|
|
891
|
+
```html
|
|
892
|
+
<!-- equivalent class markup -->
|
|
893
|
+
<div class="nk-app">
|
|
894
|
+
<aside class="nk-sidebar">
|
|
895
|
+
<div class="nk-workspace"><div class="avatar">M</div><span>MonaHilft</span><span class="chev">⌄</span></div>
|
|
896
|
+
<div class="nk-sidebar-scroll">
|
|
897
|
+
<div class="nk-tree-item"><span class="icon">🔍</span><span class="label">Search</span><span class="nk-kbd-hint"><kbd class="nk-kbd">⌘</kbd><kbd class="nk-kbd">K</kbd></span></div>
|
|
898
|
+
<div class="nk-tree-item active"><span class="icon">🏠</span><span class="label">Home</span></div>
|
|
899
|
+
<div class="nk-tree-item"><span class="icon">📥</span><span class="label">Inbox</span></div>
|
|
900
|
+
</div>
|
|
901
|
+
<div class="nk-sidebar-footer">
|
|
902
|
+
<div class="nk-tree-item"><span class="icon">⚙️</span><span class="label">Settings</span></div>
|
|
903
|
+
</div>
|
|
904
|
+
</aside>
|
|
905
|
+
<main class="nk-main">
|
|
906
|
+
<div class="nk-topbar">
|
|
907
|
+
<nav class="nk-breadcrumb"><span class="crumb current">📊 Project overview</span></nav>
|
|
908
|
+
<div class="nk-topbar-actions"><button class="nk-topbar-btn nk-share-btn">Share</button><button class="nk-topbar-btn nk-theme-toggle">🌙</button></div>
|
|
909
|
+
</div>
|
|
910
|
+
<div class="nk-page-scroll"><div class="nk-page" style="padding-top:16px">
|
|
911
|
+
<h1 class="nk-page-title" style="font-size:28px">NotionKit MVP</h1>
|
|
912
|
+
<p class="lead">A calm, document-centric workspace app – built from elements only.</p>
|
|
913
|
+
</div></div>
|
|
914
|
+
</main>
|
|
915
|
+
</div>
|
|
916
|
+
```
|
|
917
|
+
|
|
918
|
+
**Small screens:** Below 860px the sidebar is hidden; open it as a drawer with `sidebar.open = true`.
|
|
919
|
+
|
|
920
|
+
### 3.26 `<nk-sidebar>` – Sidebar
|
|
921
|
+
|
|
922
|
+
The left rail: workspace slot on top, a scrolling default slot for the tree, a pinned footer slot. Footer tree items automatically get `compact` (26px rows). The host is `display: contents`, so the `aside` is a direct flex child of the app – exactly like the class markup. `collapsible` adds Notion’s « beside the workspace row, shown while the pointer is over the sidebar: on the desktop it collapses the sidebar – it slides out, the main column takes the width, nothing in it takes focus – and `<nk-btn variant="sidebar">` in the topbar shows and brings it back; ⌘\ or Ctrl+\ toggles it. `collapsed` is the state, `nk-collapse` the moment to keep it.
|
|
923
|
+
|
|
924
|
+
```html
|
|
925
|
+
<div style="display:flex;height:100%"><nk-sidebar collapsible collapse-label="Close sidebar">
|
|
926
|
+
<nk-workspace-switcher slot="workspace" name="MonaHilft"></nk-workspace-switcher>
|
|
927
|
+
<nk-tree>
|
|
928
|
+
<nk-tree-item icon="🏠" active>Home</nk-tree-item>
|
|
929
|
+
<nk-tree-item icon="📥">Inbox</nk-tree-item>
|
|
930
|
+
</nk-tree>
|
|
931
|
+
<nk-tree-item slot="footer" icon="⚙️">Settings</nk-tree-item>
|
|
932
|
+
<nk-tree-item slot="footer" icon="🗑️">Trash</nk-tree-item>
|
|
933
|
+
</nk-sidebar></div>
|
|
934
|
+
```
|
|
935
|
+
|
|
936
|
+
| Attribute | Type | Default | Description |
|
|
937
|
+
|---|---|---|---|
|
|
938
|
+
| `open` | boolean | – | Drawer state on small screens (no effect on desktop). |
|
|
939
|
+
| `collapsible` | boolean | – | Shows the « that collapses it on the desktop, and ⌘\. |
|
|
940
|
+
| `collapsed` | boolean | – | Collapsed on the desktop (no effect on a phone). |
|
|
941
|
+
| `collapse-label` | string | `Close sidebar` | Name and tooltip of the «. |
|
|
942
|
+
|
|
943
|
+
**Slots:** `workspace` – `nk-workspace-switcher`. · `(default)` – The tree (scrolls). · `footer` – Pinned bottom rows (Settings, Trash).
|
|
944
|
+
|
|
945
|
+
**Events:** `nk-toggle` `{ open }` – Drawer opened/closed. · `nk-collapse` `{ collapsed }` – Collapsed / expanded on the desktop.
|
|
946
|
+
|
|
947
|
+
**Properties:** `open`, `collapsed` · **Methods:** `show()`, `close()`, `toggle()`, `collapse()`, `expand()`, `toggleCollapsed()`
|
|
948
|
+
|
|
949
|
+
**Replaces:** `.nk-sidebar`, `.nk-sidebar-head`, `.nk-sidebar-collapse`, `.nk-sidebar-scroll`, `.nk-sidebar-footer`, `.nk-sidebar-backdrop`, `.open`, `.collapsed`
|
|
950
|
+
|
|
951
|
+
```html
|
|
952
|
+
<!-- equivalent class markup -->
|
|
953
|
+
<div style="display:flex;height:100%"><aside class="nk-sidebar">
|
|
954
|
+
<div class="nk-sidebar-head"><div class="nk-workspace"><div class="avatar">M</div><span>MonaHilft</span><span class="chev">⌄</span></div><button class="nk-sidebar-collapse" aria-label="Close sidebar"><svg viewBox="0 0 24 24" aria-hidden="true"><path d="m18 17-5-5 5-5M11 17l-5-5 5-5"/></svg></button></div>
|
|
955
|
+
<div class="nk-sidebar-scroll">
|
|
956
|
+
<div class="nk-tree-item active"><span class="icon">🏠</span><span class="label">Home</span></div>
|
|
957
|
+
<div class="nk-tree-item"><span class="icon">📥</span><span class="label">Inbox</span></div>
|
|
958
|
+
</div>
|
|
959
|
+
<div class="nk-sidebar-footer">
|
|
960
|
+
<div class="nk-tree-item"><span class="icon">⚙️</span><span class="label">Settings</span></div>
|
|
961
|
+
<div class="nk-tree-item"><span class="icon">🗑️</span><span class="label">Trash</span></div>
|
|
962
|
+
</div>
|
|
963
|
+
</aside></div>
|
|
964
|
+
```
|
|
965
|
+
|
|
966
|
+
**Small screens:** Hidden below 860px. `open` shows it as a drawer over the page with a scrim – NotionKit’s own rules since 1.7.0 (`.nk-sidebar.open`, `.nk-sidebar-backdrop`), the same as the class markup’s; `<nk-btn variant="sidebar">` in the topbar is the ☰ that opens it. Escape and the scrim close it. The drawer slides in over 240ms and the scrim fades, closing runs backwards – CSS only (`transition-behavior: allow-discrete` + `@starting-style`; older browsers switch hard, reduced motion snaps). In landscape the drawer grows by the left safe-area inset, so its rows clear the Dynamic Island.
|
|
967
|
+
|
|
968
|
+
### 3.27 `<nk-workspace-switcher>` – Workspace switcher
|
|
969
|
+
|
|
970
|
+
The row at the very top of the sidebar. A click toggles `open` and shows whatever sits in the `menu` slot below it (an `nk-menu`, from wave 4); outside clicks and Escape close it.
|
|
971
|
+
|
|
972
|
+
```html
|
|
973
|
+
<div style="background:var(--nk-bg-sidebar);border-radius:8px;max-width:260px"><nk-workspace-switcher name="MonaHilft"></nk-workspace-switcher></div>
|
|
974
|
+
```
|
|
975
|
+
|
|
976
|
+
| Attribute | Type | Default | Description |
|
|
977
|
+
|---|---|---|---|
|
|
978
|
+
| `name` | string | – | Workspace name. |
|
|
979
|
+
| `avatar` | string | – | Avatar text (default: first letter of the name). |
|
|
980
|
+
| `open` | boolean | – | Menu shown. |
|
|
981
|
+
|
|
982
|
+
**Slots:** `avatar` – Custom avatar node. · `menu` – The popover content.
|
|
983
|
+
|
|
984
|
+
**Events:** `nk-toggle` `{ open }` – Menu opened/closed. · `nk-select` `(from the menu)` – Bubbles up from a menu item; the menu closes.
|
|
985
|
+
|
|
986
|
+
**Methods:** `show()`, `close()`, `toggle()`
|
|
987
|
+
|
|
988
|
+
**Replaces:** `.nk-workspace`, `.avatar`, `.chev`
|
|
989
|
+
|
|
990
|
+
```html
|
|
991
|
+
<!-- equivalent class markup -->
|
|
992
|
+
<div style="background:var(--nk-bg-sidebar);border-radius:8px;max-width:260px"><div class="nk-workspace"><div class="avatar">M</div><span>MonaHilft</span><span class="chev">⌄</span></div></div>
|
|
993
|
+
```
|
|
994
|
+
|
|
995
|
+
**Small screens:** Unchanged.
|
|
996
|
+
|
|
997
|
+
### 3.28 `<nk-section-label>` – Section label
|
|
998
|
+
|
|
999
|
+
Small uppercase-ish heading between tree sections. With `addable` a + appears on hover and fires `nk-action`.
|
|
1000
|
+
|
|
1001
|
+
```html
|
|
1002
|
+
<div style="background:var(--nk-bg-sidebar);border-radius:8px;max-width:244px;padding:0 8px 6px"><nk-section-label addable>Favourites</nk-section-label><nk-tree-item icon="📊">Project overview</nk-tree-item></div>
|
|
1003
|
+
```
|
|
1004
|
+
|
|
1005
|
+
| Attribute | Type | Default | Description |
|
|
1006
|
+
|---|---|---|---|
|
|
1007
|
+
| `addable` | boolean | – | Shows the + on hover. |
|
|
1008
|
+
| `label` | string | – | Text (alternative to the slot). |
|
|
1009
|
+
|
|
1010
|
+
**Slots:** `(default)` – Label text.
|
|
1011
|
+
|
|
1012
|
+
**Events:** `nk-action` `{ action: 'add' }` – + clicked.
|
|
1013
|
+
|
|
1014
|
+
**Replaces:** `.nk-section-label`, `.plus`
|
|
1015
|
+
|
|
1016
|
+
```html
|
|
1017
|
+
<!-- equivalent class markup -->
|
|
1018
|
+
<div style="background:var(--nk-bg-sidebar);border-radius:8px;max-width:244px;padding:0 8px 6px"><div class="nk-section-label">Favourites <span class="plus">+</span></div><div class="nk-tree-item"><span class="icon">📊</span><span class="label">Project overview</span><span class="actions"><span>+</span><span>⋯</span></span></div></div>
|
|
1019
|
+
```
|
|
1020
|
+
|
|
1021
|
+
**Small screens:** Unchanged.
|
|
1022
|
+
|
|
1023
|
+
### 3.29 `<nk-tree>` – Tree
|
|
1024
|
+
|
|
1025
|
+
Container for `nk-tree-item`s: keeps exactly one item `active` (listening to `nk-select` at any depth), gives the whole tree a single tab stop with arrow-key navigation (↑↓ move, → expands or enters, ← collapses or leaves, Home/End), and renders items from `tree.data`. `tree.value` is read-only – select programmatically with `item.select()` or the `active` attribute. Section labels may sit between items; their + fires `nk-action { action: 'add' }` without a value.
|
|
1026
|
+
|
|
1027
|
+
```html
|
|
1028
|
+
<div style="background:var(--nk-bg-sidebar);border-radius:8px;max-width:244px;padding:6px 8px"><nk-tree>
|
|
1029
|
+
<nk-section-label addable>Favourites</nk-section-label>
|
|
1030
|
+
<nk-tree-item icon="📊" open>Project overview
|
|
1031
|
+
<nk-tree-item icon="🚀" active>NotionKit MVP</nk-tree-item>
|
|
1032
|
+
<nk-tree-item icon="🎙️">Voice-Office-Hub</nk-tree-item>
|
|
1033
|
+
</nk-tree-item>
|
|
1034
|
+
<nk-tree-item icon="🧠">Knowledge base
|
|
1035
|
+
<nk-tree-item icon="📄">Onboarding</nk-tree-item>
|
|
1036
|
+
</nk-tree-item>
|
|
1037
|
+
<nk-tree-item icon="🎨">Design system</nk-tree-item>
|
|
1038
|
+
</nk-tree></div>
|
|
1039
|
+
```
|
|
1040
|
+
|
|
1041
|
+
| Attribute | Type | Default | Description |
|
|
1042
|
+
|---|---|---|---|
|
|
1043
|
+
| `manual` | boolean | – | Do not move `active` automatically. |
|
|
1044
|
+
|
|
1045
|
+
**Slots:** `(default)` – `nk-tree-item` and `nk-section-label` children.
|
|
1046
|
+
|
|
1047
|
+
**Events:** `nk-select` `{ value, label, href, item }` – Bubbles from the selected item. · `nk-toggle` `{ open, value }` – A branch opened/closed. · `nk-action` `{ action, value }` – Hover action of an item.
|
|
1048
|
+
|
|
1049
|
+
**Properties:** `data`, `activeItem`, `value`
|
|
1050
|
+
|
|
1051
|
+
**Replaces:**
|
|
1052
|
+
|
|
1053
|
+
```html
|
|
1054
|
+
<!-- equivalent class markup -->
|
|
1055
|
+
<div style="background:var(--nk-bg-sidebar);border-radius:8px;max-width:244px;padding:6px 8px"><div>
|
|
1056
|
+
<div class="nk-section-label">Favourites <span class="plus">+</span></div>
|
|
1057
|
+
<div class="nk-tree-item"><span class="nk-toggle-arrow open">▸</span><span class="icon">📊</span><span class="label">Project overview</span><span class="actions"><span>+</span><span>⋯</span></span></div>
|
|
1058
|
+
<div class="nk-tree-children">
|
|
1059
|
+
<div class="nk-tree-item active"><span class="icon">🚀</span><span class="label">NotionKit MVP</span><span class="actions"><span>+</span><span>⋯</span></span></div>
|
|
1060
|
+
<div class="nk-tree-item"><span class="icon">🎙️</span><span class="label">Voice-Office-Hub</span><span class="actions"><span>+</span><span>⋯</span></span></div>
|
|
1061
|
+
</div>
|
|
1062
|
+
<div class="nk-tree-item"><span class="nk-toggle-arrow">▸</span><span class="icon">🧠</span><span class="label">Knowledge base</span><span class="actions"><span>+</span><span>⋯</span></span></div>
|
|
1063
|
+
<div class="nk-tree-children collapsed">
|
|
1064
|
+
<div class="nk-tree-item"><span class="icon">📄</span><span class="label">Onboarding</span></div>
|
|
1065
|
+
</div>
|
|
1066
|
+
<div class="nk-tree-item"><span class="icon">🎨</span><span class="label">Design system</span><span class="actions"><span>+</span><span>⋯</span></span></div>
|
|
1067
|
+
</div></div>
|
|
1068
|
+
```
|
|
1069
|
+
|
|
1070
|
+
**Small screens:** Rows are 28px; raise the hit area in a touch drawer via the sidebar’s `open` state styling of your own.
|
|
1071
|
+
|
|
1072
|
+
### 3.30 `<nk-tree-item>` – Tree item
|
|
1073
|
+
|
|
1074
|
+
One row of the page tree – and its children box. Text content is the label, nested `nk-tree-item`s are the children (the arrow appears only then), `slot="icon"` and `slot="end"` go where they say. Hover actions +/⋯ report through `nk-action`; a click fires `nk-select` (cancelable). Outside an `nk-tree` (sidebar footer) an item marks itself `active` on click unless the event is cancelled.
|
|
1075
|
+
|
|
1076
|
+
```html
|
|
1077
|
+
<div style="background:var(--nk-bg-sidebar);border-radius:8px;max-width:244px;padding:6px 8px">
|
|
1078
|
+
<nk-tree-item icon="🔍" value="search">Search<span slot="end" class="nk-kbd-hint"><nk-kbd>⌘</nk-kbd><nk-kbd>K</nk-kbd></span></nk-tree-item>
|
|
1079
|
+
<nk-tree-item icon="📊" active>Project overview</nk-tree-item>
|
|
1080
|
+
<nk-tree-item icon="🎨">Design system</nk-tree-item>
|
|
1081
|
+
</div>
|
|
1082
|
+
```
|
|
1083
|
+
|
|
1084
|
+
| Attribute | Type | Default | Description |
|
|
1085
|
+
|---|---|---|---|
|
|
1086
|
+
| `icon` | string | – | Emoji/text icon (or `slot="icon"`). |
|
|
1087
|
+
| `label` | string | – | Label (alternative to text content). |
|
|
1088
|
+
| `value` | string | – | Value reported in events (default: label). |
|
|
1089
|
+
| `href` | URL | – | Navigate on select. |
|
|
1090
|
+
| `active` | boolean | – | Current item. |
|
|
1091
|
+
| `open` | boolean | – | Children expanded. |
|
|
1092
|
+
| `compact` | boolean | – | 26px row (footer, settings nav). |
|
|
1093
|
+
| `no-actions` | boolean | – | Hide the +/⋯ hover actions. |
|
|
1094
|
+
|
|
1095
|
+
**Slots:** `(default)` – Label text and nested `nk-tree-item`s. · `icon` – Icon node. · `end` – Trailing content, e.g. `<span slot="end" class="nk-kbd-hint">` with `nk-kbd`s (hides the actions).
|
|
1096
|
+
|
|
1097
|
+
**Events:** `nk-select` `{ value, label, href, item }` – Row clicked / Enter. `preventDefault()` keeps it from becoming active. · `nk-toggle` `{ open, value }` – Arrow clicked. · `nk-action` `{ action: 'add' | 'more', value }` – Hover action clicked.
|
|
1098
|
+
|
|
1099
|
+
**Properties:** `label`, `value`, `active`, `open`, `hasChildren` · **Methods:** `select()`, `toggle()`, `focus()`
|
|
1100
|
+
|
|
1101
|
+
**Replaces:** `.nk-tree-item`, `.icon`, `.label`, `.actions`, `.active`, `.compact`, `.nk-tree-children`, `.collapsed`, `.nk-toggle-arrow`, `.open`, `.nk-kbd-hint`
|
|
1102
|
+
|
|
1103
|
+
```html
|
|
1104
|
+
<!-- equivalent class markup -->
|
|
1105
|
+
<div style="background:var(--nk-bg-sidebar);border-radius:8px;max-width:244px;padding:6px 8px">
|
|
1106
|
+
<div class="nk-tree-item"><span class="icon">🔍</span><span class="label">Search</span><span class="nk-kbd-hint"><kbd class="nk-kbd">⌘</kbd><kbd class="nk-kbd">K</kbd></span></div>
|
|
1107
|
+
<div class="nk-tree-item active"><span class="icon">📊</span><span class="label">Project overview</span><span class="actions"><span>+</span><span>⋯</span></span></div>
|
|
1108
|
+
<div class="nk-tree-item"><span class="icon">🎨</span><span class="label">Design system</span><span class="actions"><span>+</span><span>⋯</span></span></div>
|
|
1109
|
+
</div>
|
|
1110
|
+
```
|
|
1111
|
+
|
|
1112
|
+
**Small screens:** 28px rows (26px with `compact`) – below the 44px touch target; the tree does not force a height.
|
|
1113
|
+
|
|
1114
|
+
### 3.31 `<nk-topbar>` – Top bar
|
|
1115
|
+
|
|
1116
|
+
The 44px bar above the page: breadcrumb in the default slot, buttons in the `actions` slot (right-aligned). Use `nk-btn variant="topbar"` / `"share"` and `nk-theme-toggle` there, and `<span class="nk-topbar-meta">` for passive text such as “Edited 2 min ago”.
|
|
1117
|
+
|
|
1118
|
+
```html
|
|
1119
|
+
<div style="border:1px solid var(--nk-border);border-radius:8px;display:flex;flex-direction:column"><nk-topbar>
|
|
1120
|
+
<nk-breadcrumb><span>📊 Project overview</span><span>🚀 NotionKit MVP</span></nk-breadcrumb>
|
|
1121
|
+
<span slot="actions" class="nk-topbar-meta">Last edited 2 min ago</span>
|
|
1122
|
+
<nk-btn slot="actions" variant="share">Share</nk-btn>
|
|
1123
|
+
<nk-btn slot="actions" variant="topbar">⭐</nk-btn>
|
|
1124
|
+
<nk-theme-toggle slot="actions"></nk-theme-toggle>
|
|
1125
|
+
</nk-topbar></div>
|
|
1126
|
+
```
|
|
1127
|
+
|
|
1128
|
+
_No attributes._
|
|
1129
|
+
|
|
1130
|
+
**Slots:** `(default)` – Breadcrumb / title. · `actions` – Buttons on the right.
|
|
1131
|
+
|
|
1132
|
+
**Replaces:** `.nk-topbar`, `.nk-topbar-actions`, `.nk-topbar-btn`, `.nk-topbar-meta`, `.nk-share-btn`
|
|
1133
|
+
|
|
1134
|
+
```html
|
|
1135
|
+
<!-- equivalent class markup -->
|
|
1136
|
+
<div style="border:1px solid var(--nk-border);border-radius:8px;display:flex;flex-direction:column"><div class="nk-topbar">
|
|
1137
|
+
<nav class="nk-breadcrumb"><span class="crumb">📊 Project overview</span><span class="sep">/</span><span class="crumb current">🚀 NotionKit MVP</span></nav>
|
|
1138
|
+
<div class="nk-topbar-actions"><span class="nk-topbar-meta">Last edited 2 min ago</span><button class="nk-topbar-btn nk-share-btn">Share</button><button class="nk-topbar-btn">⭐</button><button class="nk-topbar-btn nk-theme-toggle">🌙</button></div>
|
|
1139
|
+
</div></div>
|
|
1140
|
+
```
|
|
1141
|
+
|
|
1142
|
+
**Small screens:** Below 860px only the last crumb stays and ends in an ellipsis, `nk-topbar-meta` hides, and the actions keep to one line – as in Notion’s mobile app.
|
|
1143
|
+
|
|
1144
|
+
### 3.32 `<nk-breadcrumb>` – Breadcrumb
|
|
1145
|
+
|
|
1146
|
+
Give it plain `<span>` or `<a>` children; they are cloned into the bar with separators between them and the last one marked current (or the child with a `current` attribute). Text changes, added or removed children are picked up automatically (`refresh()` only for what the observer cannot see). Clicking a crumb fires `nk-select` and forwards the click to the original child, so links navigate exactly once.
|
|
1147
|
+
|
|
1148
|
+
```html
|
|
1149
|
+
<nk-breadcrumb><a href="#">📊 Project overview</a><span>🚀 NotionKit MVP</span></nk-breadcrumb>
|
|
1150
|
+
```
|
|
1151
|
+
|
|
1152
|
+
| Attribute | Type | Default | Description |
|
|
1153
|
+
|---|---|---|---|
|
|
1154
|
+
| `separator` | string | `/` | Separator glyph. |
|
|
1155
|
+
|
|
1156
|
+
**Slots:** `(default)` – Crumb children (direct children only, no `slot` attribute).
|
|
1157
|
+
|
|
1158
|
+
**Events:** `nk-select` `{ index, value, label, href, current }` – Crumb clicked; `preventDefault()` stops the forwarded click.
|
|
1159
|
+
|
|
1160
|
+
**Methods:** `refresh()`
|
|
1161
|
+
|
|
1162
|
+
**Replaces:** `.nk-breadcrumb`, `.crumb`, `.sep`, `.current`
|
|
1163
|
+
|
|
1164
|
+
```html
|
|
1165
|
+
<!-- equivalent class markup -->
|
|
1166
|
+
<nav class="nk-breadcrumb"><a class="crumb" href="#">📊 Project overview</a><span class="sep">/</span><span class="crumb current">🚀 NotionKit MVP</span></nav>
|
|
1167
|
+
```
|
|
1168
|
+
|
|
1169
|
+
**Small screens:** Stays on one line; keep crumbs short.
|
|
1170
|
+
|
|
1171
|
+
### 3.33 `<nk-theme-toggle>` – Theme toggle
|
|
1172
|
+
|
|
1173
|
+
The ☀️/🌙 button. Flips `data-theme` on `<html>`, remembers the choice in `localStorage`, applies a stored or system preference on first connect when `<html>` has no theme yet, and accepts `postMessage({ nkTheme })` from a parent page. `apply(theme)` does everything a click does: sets, persists and fires `nk-change`.
|
|
1174
|
+
|
|
1175
|
+
```html
|
|
1176
|
+
<nk-theme-toggle></nk-theme-toggle>
|
|
1177
|
+
```
|
|
1178
|
+
|
|
1179
|
+
| Attribute | Type | Default | Description |
|
|
1180
|
+
|---|---|---|---|
|
|
1181
|
+
| `storage-key` | string | `nk-theme` | localStorage key. |
|
|
1182
|
+
| `title` | string | – | Tooltip. |
|
|
1183
|
+
|
|
1184
|
+
**Events:** `nk-change` `{ value: 'light' | 'dark' }` – Theme applied.
|
|
1185
|
+
|
|
1186
|
+
**Properties:** `value` · **Methods:** `apply(theme)`
|
|
1187
|
+
|
|
1188
|
+
**Replaces:** `.nk-theme-toggle`
|
|
1189
|
+
|
|
1190
|
+
```html
|
|
1191
|
+
<!-- equivalent class markup -->
|
|
1192
|
+
<button class="nk-topbar-btn nk-theme-toggle">🌙</button>
|
|
1193
|
+
```
|
|
1194
|
+
|
|
1195
|
+
**Small screens:** Unchanged.
|
|
1196
|
+
|
|
1197
|
+
### 3.34 `<nk-tab-bar>` – Tab bar (mobile)
|
|
1198
|
+
|
|
1199
|
+
The thumb-reachable twin of the sidebar for phones and installed PWAs. Put it last inside `nk-app`: it is slotted into the main column below the scrolling page, so it never moves and no bottom padding is needed. Keeps exactly one `nk-tab-bar-item` active (listening to `nk-select`); a `drawer` item opens the sidebar instead. Needs NotionKit CSS 1.2.0.
|
|
1200
|
+
|
|
1201
|
+
```html
|
|
1202
|
+
<div style="max-width:390px;border:1px solid var(--nk-border);border-radius:12px;overflow:hidden"><nk-tab-bar always value="inbox">
|
|
1203
|
+
<nk-tab-bar-item icon="🏠" value="home">Home</nk-tab-bar-item>
|
|
1204
|
+
<nk-tab-bar-item icon="📥" value="inbox">Inbox</nk-tab-bar-item>
|
|
1205
|
+
<nk-tab-bar-item icon="🔍" value="search">Search</nk-tab-bar-item>
|
|
1206
|
+
<nk-tab-bar-item icon="⚙️" value="settings">Settings</nk-tab-bar-item>
|
|
1207
|
+
<nk-tab-bar-item icon="☰" drawer>More</nk-tab-bar-item>
|
|
1208
|
+
</nk-tab-bar></div>
|
|
1209
|
+
```
|
|
1210
|
+
|
|
1211
|
+
| Attribute | Type | Default | Description |
|
|
1212
|
+
|---|---|---|---|
|
|
1213
|
+
| `value` | string | – | Active item value (default: the item with `active`, else the first). |
|
|
1214
|
+
| `always` | boolean | – | Visible at every width, not only below 860px. |
|
|
1215
|
+
| `fixed` | boolean | – | Pinned to the viewport bottom instead of sitting in the column – for standalone PWAs; a spacer keeps its height (`--nk-tab-bar-height` + safe area) in the flow. |
|
|
1216
|
+
| `floating` | boolean | – | A fixed capsule with rounded corners instead of the full-width bar. |
|
|
1217
|
+
| `label` | string | – | `aria-label` of the `nav`. |
|
|
1218
|
+
|
|
1219
|
+
**Slots:** `(default)` – `nk-tab-bar-item` children, up to five.
|
|
1220
|
+
|
|
1221
|
+
**Events:** `nk-change` `{ value }` – Active item changed. · `nk-select` `{ value, label, href, item, drawer }` – Bubbles from the tapped item; cancelable.
|
|
1222
|
+
|
|
1223
|
+
**Properties:** `value`, `items`
|
|
1224
|
+
|
|
1225
|
+
**Replaces:** `.nk-tab-bar`, `.nk-tab-bar-spacer`, `.always`, `.fixed`, `.floating`
|
|
1226
|
+
|
|
1227
|
+
```html
|
|
1228
|
+
<!-- equivalent class markup -->
|
|
1229
|
+
<div style="max-width:390px;border:1px solid var(--nk-border);border-radius:12px;overflow:hidden"><nav class="nk-tab-bar always">
|
|
1230
|
+
<button class="nk-tab-bar-item"><span class="icon">🏠</span><span class="label">Home</span></button>
|
|
1231
|
+
<button class="nk-tab-bar-item active"><span class="icon">📥</span><span class="label">Inbox</span></button>
|
|
1232
|
+
<button class="nk-tab-bar-item"><span class="icon">🔍</span><span class="label">Search</span></button>
|
|
1233
|
+
<button class="nk-tab-bar-item"><span class="icon">⚙️</span><span class="label">Settings</span></button>
|
|
1234
|
+
<button class="nk-tab-bar-item"><span class="icon">☰</span><span class="label">More</span></button>
|
|
1235
|
+
</nav></div>
|
|
1236
|
+
```
|
|
1237
|
+
|
|
1238
|
+
**Small screens:** This is where it lives: hidden above 860px (the sidebar is the navigation there), shown below. `always` shows it at every width – previews, phone frames. The bottom padding is the larger of 6px and `env(safe-area-inset-bottom)`; in landscape the side padding grows to the left/right insets.
|
|
1239
|
+
|
|
1240
|
+
### 3.35 `<nk-tab-bar-item>` – Tab bar item
|
|
1241
|
+
|
|
1242
|
+
One destination of `nk-tab-bar`: an icon over a short label. A tap emits `nk-select` (cancelable), then moves the bar’s `value`; with `href` it navigates afterwards. `drawer` turns it into the “More” item that opens the nearest `nk-sidebar` as a drawer and never becomes active. Standalone it toggles its own `active`.
|
|
1243
|
+
|
|
1244
|
+
```html
|
|
1245
|
+
<div style="max-width:390px;border:1px solid var(--nk-border);border-radius:12px;overflow:hidden"><nk-tab-bar always><nk-tab-bar-item icon="🏠" value="home" active>Home</nk-tab-bar-item><nk-tab-bar-item icon="📥" value="inbox">Inbox</nk-tab-bar-item></nk-tab-bar></div>
|
|
1246
|
+
```
|
|
1247
|
+
|
|
1248
|
+
| Attribute | Type | Default | Description |
|
|
1249
|
+
|---|---|---|---|
|
|
1250
|
+
| `icon` | string | – | Emoji or glyph (alternative: `slot="icon"`). |
|
|
1251
|
+
| `value` | string | – | Value (default: the label). |
|
|
1252
|
+
| `label` | string | – | Label text (alternative to the default slot). |
|
|
1253
|
+
| `href` | string | – | Navigates after `nk-select`. |
|
|
1254
|
+
| `active` | boolean | – | The current destination (`aria-current="page"`). |
|
|
1255
|
+
| `drawer` | boolean | – | Opens the sidebar drawer instead of becoming active. |
|
|
1256
|
+
| `disabled` | boolean | – | Not selectable. |
|
|
1257
|
+
|
|
1258
|
+
**Slots:** `(default)` – Label. · `icon` – Icon node instead of the attribute.
|
|
1259
|
+
|
|
1260
|
+
**Events:** `nk-select` `{ value, label, href, item, drawer }` – Tapped; cancelable.
|
|
1261
|
+
|
|
1262
|
+
**Methods:** `select()`, `focus()`
|
|
1263
|
+
|
|
1264
|
+
**Replaces:** `.nk-tab-bar-item`, `.icon`, `.label`, `.active`
|
|
1265
|
+
|
|
1266
|
+
```html
|
|
1267
|
+
<!-- equivalent class markup -->
|
|
1268
|
+
<div style="max-width:390px;border:1px solid var(--nk-border);border-radius:12px;overflow:hidden"><nav class="nk-tab-bar always"><button class="nk-tab-bar-item active"><span class="icon">🏠</span><span class="label">Home</span></button><button class="nk-tab-bar-item"><span class="icon">📥</span><span class="label">Inbox</span></button></nav></div>
|
|
1269
|
+
```
|
|
1270
|
+
|
|
1271
|
+
**Small screens:** Made for the thumb: 20px icon, 10.5px label, the whole column is the hit area.
|
|
1272
|
+
|
|
1273
|
+
## Page shell & blocks (wave 3)
|
|
1274
|
+
|
|
1275
|
+
### 3.36 `<nk-page>` – Page
|
|
1276
|
+
|
|
1277
|
+
The document column: a scrolling wrapper, an optional cover, the 760px page with 64px side padding, and the page icon (rendered here because its slotted twin is keyed on the parent). `narrow` drops the scroll wrapper for pages that are the document itself.
|
|
1278
|
+
|
|
1279
|
+
```html
|
|
1280
|
+
<div style="display:flex;flex-direction:column;height:100%"><nk-page icon="🚀" cover>
|
|
1281
|
+
<nk-page-title>NotionKit MVP</nk-page-title>
|
|
1282
|
+
<nk-page-actions><span>👤 Marcel Karas</span><span>📅 Created 12 May 2026</span><span>🏷️ <nk-tag color="purple">Design system</nk-tag></span></nk-page-actions>
|
|
1283
|
+
<p class="lead">A calm, document-centric workspace app – built from elements only.</p>
|
|
1284
|
+
</nk-page></div>
|
|
1285
|
+
```
|
|
1286
|
+
|
|
1287
|
+
| Attribute | Type | Default | Description |
|
|
1288
|
+
|---|---|---|---|
|
|
1289
|
+
| `icon` | string | – | Page emoji; click fires `nk-action`. |
|
|
1290
|
+
| `full` | boolean | – | Page option “Full width”: the column fills the window instead of stopping at 760px. |
|
|
1291
|
+
| `small` | boolean | – | Page option “Small text”: document text 14px instead of 16px; headings, lead, prose and editor follow. |
|
|
1292
|
+
| `cover` | boolean | – | Shows the cover strip; the icon then overlaps its bottom edge and the page drops its top padding (the stylesheet’s `covered` state, also set for a slotted `nk-page-cover`). Without it the icon sits in 24px top padding, fully visible. |
|
|
1293
|
+
| `narrow` | boolean | – | No scroll wrapper (landing / docs page). |
|
|
1294
|
+
|
|
1295
|
+
**Slots:** `(default)` – Title, meta, blocks – anything with `class="lead"` on a `<p>` becomes the lead paragraph. · `cover` – An `nk-page-cover` (instead of the `cover` attribute). · `icon` – Custom icon node.
|
|
1296
|
+
|
|
1297
|
+
**Events:** `nk-action` `{ action: 'icon', value }` – Icon clicked (open an emoji picker).
|
|
1298
|
+
|
|
1299
|
+
**Replaces:** `.nk-page-scroll`, `.nk-page`, `.nk-page-icon`, `.nk-cover`, `.lead`, `.full`, `.small`
|
|
1300
|
+
|
|
1301
|
+
```html
|
|
1302
|
+
<!-- equivalent class markup -->
|
|
1303
|
+
<div style="display:flex;flex-direction:column;height:100%"><div class="nk-page-scroll"><div class="nk-cover"></div><div class="nk-page">
|
|
1304
|
+
<div class="nk-page-icon">🚀</div>
|
|
1305
|
+
<h1 class="nk-page-title">NotionKit MVP</h1>
|
|
1306
|
+
<div class="nk-page-meta"><span>👤 Marcel Karas</span><span>📅 Created 12 May 2026</span><span>🏷️ <span class="nk-tag purple">Design system</span></span></div>
|
|
1307
|
+
<p class="lead">A calm, document-centric workspace app – built from elements only.</p>
|
|
1308
|
+
</div></div></div>
|
|
1309
|
+
```
|
|
1310
|
+
|
|
1311
|
+
**Small screens:** Side padding drops to 24px below 860px.
|
|
1312
|
+
|
|
1313
|
+
### 3.37 `<nk-page-cover>` – Page cover
|
|
1314
|
+
|
|
1315
|
+
The 200px cover band. Without `src` it shows the token gradient; with `src` a picture – an `<img>` inside the band, cropped rather than stretched. `position` moves the crop, as Notion’s “Reposition” does.
|
|
1316
|
+
|
|
1317
|
+
```html
|
|
1318
|
+
<nk-page-cover src="/covers/meadow.svg"></nk-page-cover>
|
|
1319
|
+
```
|
|
1320
|
+
|
|
1321
|
+
| Attribute | Type | Default | Description |
|
|
1322
|
+
|---|---|---|---|
|
|
1323
|
+
| `src` | URL | – | Cover picture. |
|
|
1324
|
+
| `position` | CSS object-position | `center` | Where the crop sits. |
|
|
1325
|
+
|
|
1326
|
+
|
|
1327
|
+
|
|
1328
|
+
**Replaces:** `.nk-cover`
|
|
1329
|
+
|
|
1330
|
+
```html
|
|
1331
|
+
<!-- equivalent class markup -->
|
|
1332
|
+
<div class="nk-cover"><img src="/covers/meadow.svg" alt=""></div>
|
|
1333
|
+
```
|
|
1334
|
+
|
|
1335
|
+
**Small screens:** Unchanged.
|
|
1336
|
+
|
|
1337
|
+
### 3.38 `<nk-page-title>` – Page title
|
|
1338
|
+
|
|
1339
|
+
The 40px heading. With `editable` it becomes a plain-text field: Enter commits, blur fires `nk-change`.
|
|
1340
|
+
|
|
1341
|
+
```html
|
|
1342
|
+
<nk-page-title editable>NotionKit MVP</nk-page-title>
|
|
1343
|
+
```
|
|
1344
|
+
|
|
1345
|
+
| Attribute | Type | Default | Description |
|
|
1346
|
+
|---|---|---|---|
|
|
1347
|
+
| `editable` | boolean | – | Inline editing. |
|
|
1348
|
+
| `placeholder` | string | – | Shown when empty (editable). |
|
|
1349
|
+
| `value` | string | – | Title text (alternative to content). |
|
|
1350
|
+
|
|
1351
|
+
**Slots:** `(default)` – Title text.
|
|
1352
|
+
|
|
1353
|
+
**Events:** `nk-change` `{ value }` – Edited title committed.
|
|
1354
|
+
|
|
1355
|
+
**Properties:** `value`
|
|
1356
|
+
|
|
1357
|
+
**Replaces:** `.nk-page-title`
|
|
1358
|
+
|
|
1359
|
+
```html
|
|
1360
|
+
<!-- equivalent class markup -->
|
|
1361
|
+
<h1 class="nk-page-title" contenteditable="plaintext-only" spellcheck="false">NotionKit MVP</h1>
|
|
1362
|
+
```
|
|
1363
|
+
|
|
1364
|
+
**Small screens:** Unchanged; long titles wrap.
|
|
1365
|
+
|
|
1366
|
+
### 3.39 `<nk-page-actions>` – Page meta row
|
|
1367
|
+
|
|
1368
|
+
The quiet row under the title: owner, date, tags – any inline content, 16px apart.
|
|
1369
|
+
|
|
1370
|
+
```html
|
|
1371
|
+
<nk-page-actions><span>👤 Marcel Karas</span><span>📅 Created 12 May 2026</span><span>🏷️ <nk-tag color="purple">Design system</nk-tag></span></nk-page-actions>
|
|
1372
|
+
```
|
|
1373
|
+
|
|
1374
|
+
_No attributes._
|
|
1375
|
+
|
|
1376
|
+
**Slots:** `(default)` – Meta items.
|
|
1377
|
+
|
|
1378
|
+
**Replaces:** `.nk-page-meta`
|
|
1379
|
+
|
|
1380
|
+
```html
|
|
1381
|
+
<!-- equivalent class markup -->
|
|
1382
|
+
<div class="nk-page-meta"><span>👤 Marcel Karas</span><span>📅 Created 12 May 2026</span><span>🏷️ <span class="nk-tag purple">Design system</span></span></div>
|
|
1383
|
+
```
|
|
1384
|
+
|
|
1385
|
+
**Small screens:** Wraps naturally.
|
|
1386
|
+
|
|
1387
|
+
### 3.40 `<nk-props>` – Page properties
|
|
1388
|
+
|
|
1389
|
+
The properties under the title of a database page, the pattern Notion is known for: a list of `nk-prop` rows. The rows are hosts with `display: contents`, so each renders as a row of this list – no markup of their own around them.
|
|
1390
|
+
|
|
1391
|
+
```html
|
|
1392
|
+
<nk-props style="max-width:520px">
|
|
1393
|
+
<nk-prop label="Status" icon="◉"><nk-tag color="blue">In progress</nk-tag></nk-prop>
|
|
1394
|
+
<nk-prop label="Owner" icon="👤"><nk-avatar size="small" color="purple">AL</nk-avatar>Ada Lovelace</nk-prop>
|
|
1395
|
+
<nk-prop label="Due" icon="📅">2 June 2026</nk-prop>
|
|
1396
|
+
<nk-prop label="Tags" icon="🏷️"><nk-tag color="purple">Design system</nk-tag><nk-tag>CSS</nk-tag></nk-prop>
|
|
1397
|
+
<nk-prop label="Progress" icon="▰"><nk-progress value="65" label="65 %" wide></nk-progress></nk-prop>
|
|
1398
|
+
</nk-props>
|
|
1399
|
+
```
|
|
1400
|
+
|
|
1401
|
+
_No attributes._
|
|
1402
|
+
|
|
1403
|
+
**Slots:** `(default)` – `nk-prop` children.
|
|
1404
|
+
|
|
1405
|
+
**Replaces:** `.nk-props`
|
|
1406
|
+
|
|
1407
|
+
```html
|
|
1408
|
+
<!-- equivalent class markup -->
|
|
1409
|
+
<dl class="nk-props" style="max-width:520px">
|
|
1410
|
+
<div class="nk-prop"><dt class="p-name"><span class="p-icon">◉</span>Status</dt><dd class="p-value"><span class="nk-tag blue">In progress</span></dd></div>
|
|
1411
|
+
<div class="nk-prop"><dt class="p-name"><span class="p-icon">👤</span>Owner</dt><dd class="p-value"><span class="nk-avatar small purple">AL</span>Ada Lovelace</dd></div>
|
|
1412
|
+
<div class="nk-prop"><dt class="p-name"><span class="p-icon">📅</span>Due</dt><dd class="p-value">2 June 2026</dd></div>
|
|
1413
|
+
<div class="nk-prop"><dt class="p-name"><span class="p-icon">🏷️</span>Tags</dt><dd class="p-value"><span class="nk-tag purple">Design system</span><span class="nk-tag">CSS</span></dd></div>
|
|
1414
|
+
<div class="nk-prop"><dt class="p-name"><span class="p-icon">▰</span>Progress</dt><dd class="p-value"><span class="nk-progress wide"><i style="width:65%"></i></span><span class="nk-progress-label">65 %</span></dd></div>
|
|
1415
|
+
</dl>
|
|
1416
|
+
```
|
|
1417
|
+
|
|
1418
|
+
**Small screens:** Below 860px each property stacks: the name above its value.
|
|
1419
|
+
|
|
1420
|
+
### 3.41 `<nk-prop>` – Page property
|
|
1421
|
+
|
|
1422
|
+
One property: the name with its type icon in a 160px column, the value beside it, 34px with the hover wash on both halves. The value is the element’s content – tags, an avatar and a name, a date, `<nk-progress wide>`. A click fires `nk-action` with the half that was hit, the moment Notion opens the property’s editor.
|
|
1423
|
+
|
|
1424
|
+
```html
|
|
1425
|
+
<nk-props style="max-width:520px"><nk-prop label="Due" icon="📅">2 June 2026</nk-prop></nk-props>
|
|
1426
|
+
```
|
|
1427
|
+
|
|
1428
|
+
| Attribute | Type | Default | Description |
|
|
1429
|
+
|---|---|---|---|
|
|
1430
|
+
| `label` | string | – | Property name. |
|
|
1431
|
+
| `icon` | string | – | Type icon. |
|
|
1432
|
+
|
|
1433
|
+
**Slots:** `(default)` – The value. · `icon` – Icon node.
|
|
1434
|
+
|
|
1435
|
+
**Events:** `nk-action` `{ action: 'name' | 'value', label }` – Name or value clicked.
|
|
1436
|
+
|
|
1437
|
+
**Replaces:** `.nk-prop`, `.p-name`, `.p-icon`, `.p-value`
|
|
1438
|
+
|
|
1439
|
+
```html
|
|
1440
|
+
<!-- equivalent class markup -->
|
|
1441
|
+
<dl class="nk-props" style="max-width:520px"><div class="nk-prop"><dt class="p-name"><span class="p-icon">📅</span>Due</dt><dd class="p-value">2 June 2026</dd></div></dl>
|
|
1442
|
+
```
|
|
1443
|
+
|
|
1444
|
+
**Small screens:** Stacks below 860px.
|
|
1445
|
+
|
|
1446
|
+
### 3.42 `<nk-panels>` – Panels
|
|
1447
|
+
|
|
1448
|
+
A grid of `nk-panel`s: columns of at least 200px that share the row. The panels are hosts with `display: contents`, so each is a cell of this grid.
|
|
1449
|
+
|
|
1450
|
+
```html
|
|
1451
|
+
<nk-panels>
|
|
1452
|
+
<nk-panel href="#" cover="/covers/aurora.svg" icon="🚀" title="NotionKit MVP"><p>2 min ago</p></nk-panel>
|
|
1453
|
+
<nk-panel href="#" cover="/covers/dunes.svg" icon="📚" title="Knowledge base"><p>Yesterday</p></nk-panel>
|
|
1454
|
+
<nk-panel title="Weekly review"><p>Three pages changed, one comment is waiting for an answer.</p></nk-panel>
|
|
1455
|
+
</nk-panels>
|
|
1456
|
+
```
|
|
1457
|
+
|
|
1458
|
+
_No attributes._
|
|
1459
|
+
|
|
1460
|
+
**Slots:** `(default)` – `nk-panel` children.
|
|
1461
|
+
|
|
1462
|
+
**Replaces:** `.nk-panels`
|
|
1463
|
+
|
|
1464
|
+
```html
|
|
1465
|
+
<!-- equivalent class markup -->
|
|
1466
|
+
<div class="nk-panels">
|
|
1467
|
+
<a class="nk-panel" href="#"><div class="nk-cover"><img src="/covers/aurora.svg" alt=""></div><div class="nk-page-icon">🚀</div><h3>NotionKit MVP</h3><p>2 min ago</p></a>
|
|
1468
|
+
<a class="nk-panel" href="#"><div class="nk-cover"><img src="/covers/dunes.svg" alt=""></div><div class="nk-page-icon">📚</div><h3>Knowledge base</h3><p>Yesterday</p></a>
|
|
1469
|
+
<div class="nk-panel"><h3>Weekly review</h3><p>Three pages changed, one comment is waiting for an answer.</p></div>
|
|
1470
|
+
</div>
|
|
1471
|
+
```
|
|
1472
|
+
|
|
1473
|
+
**Small screens:** Falls to one column as soon as two 200px columns no longer fit.
|
|
1474
|
+
|
|
1475
|
+
### 3.43 `<nk-panel>` – Panel
|
|
1476
|
+
|
|
1477
|
+
A neutral surface for content that belongs together – the cards on Notion’s Home, the boxes in its settings. `title` is the heading (never a tooltip); the content goes in as `<p>`s and blocks. `cover` without a value draws the gradient band, with a URL a picture; `icon` overlaps the cover as on a page – a page tile. With `href` the panel is a link.
|
|
1478
|
+
|
|
1479
|
+
```html
|
|
1480
|
+
<div style="max-width:260px"><nk-panel href="#" cover icon="🚀" title="NotionKit MVP"><p>2 min ago</p></nk-panel></div>
|
|
1481
|
+
```
|
|
1482
|
+
|
|
1483
|
+
| Attribute | Type | Default | Description |
|
|
1484
|
+
|---|---|---|---|
|
|
1485
|
+
| `title` | string | – | Heading. |
|
|
1486
|
+
| `icon` | string | – | Page icon. |
|
|
1487
|
+
| `cover` | URL | empty | – | Cover band: empty for the gradient, a URL for a picture. |
|
|
1488
|
+
| `href` | URL | – | Makes the panel a link. |
|
|
1489
|
+
| `target` | string | – | Link target. |
|
|
1490
|
+
|
|
1491
|
+
**Slots:** `(default)` – Content: `<p>`, a prose block, a progress bar.
|
|
1492
|
+
|
|
1493
|
+
**Replaces:** `.nk-panel`, `.nk-cover`, `.nk-page-icon`
|
|
1494
|
+
|
|
1495
|
+
```html
|
|
1496
|
+
<!-- equivalent class markup -->
|
|
1497
|
+
<div style="max-width:260px"><a class="nk-panel" href="#"><div class="nk-cover"></div><div class="nk-page-icon">🚀</div><h3>NotionKit MVP</h3><p>2 min ago</p></a></div>
|
|
1498
|
+
```
|
|
1499
|
+
|
|
1500
|
+
**Small screens:** Takes the width of its grid cell.
|
|
1501
|
+
|
|
1502
|
+
### 3.44 `<nk-block-host>` – Block host
|
|
1503
|
+
|
|
1504
|
+
The optical shell for editor content: hover wash, focus ring, drop-target line, an optional drag handle. It stays behaviour-neutral – mount your editor into the light DOM; `nk-editor` (v1.1) will do that for TipTap.
|
|
1505
|
+
|
|
1506
|
+
```html
|
|
1507
|
+
<nk-block-host handle><p style="margin:0" contenteditable="true">Block content lives here – click to focus.</p></nk-block-host>
|
|
1508
|
+
```
|
|
1509
|
+
|
|
1510
|
+
| Attribute | Type | Default | Description |
|
|
1511
|
+
|---|---|---|---|
|
|
1512
|
+
| `handle` | boolean | – | Render the ⠿ drag handle (shown on hover). |
|
|
1513
|
+
| `drop-target` | boolean | – | Drop indicator line above the block. |
|
|
1514
|
+
|
|
1515
|
+
**Slots:** `(default)` – Block content / the editor root.
|
|
1516
|
+
|
|
1517
|
+
**Replaces:** `.nk-block-host`, `.nk-block-handle`, `.nk-drop-target`
|
|
1518
|
+
|
|
1519
|
+
```html
|
|
1520
|
+
<!-- equivalent class markup -->
|
|
1521
|
+
<div class="nk-block-host"><span class="nk-block-handle">⠿</span><p style="margin:0" contenteditable="true">Block content lives here – click to focus.</p></div>
|
|
1522
|
+
```
|
|
1523
|
+
|
|
1524
|
+
**Small screens:** The handle sits 26px left of the column and is hidden when there is no room.
|
|
1525
|
+
|
|
1526
|
+
### 3.45 `<nk-banner>` – Banner
|
|
1527
|
+
|
|
1528
|
+
A tinted notice row. The colour modifier becomes `variant`; the action – a `<button>` – goes into `slot="action"` and sits at the right edge.
|
|
1529
|
+
|
|
1530
|
+
```html
|
|
1531
|
+
<nk-banner variant="info">ℹ️ <span>This page is a <b>component preview</b> – every element follows the same design tokens.</span><button slot="action" type="button">Open palette</button></nk-banner>
|
|
1532
|
+
<nk-banner variant="warning">⚠️ <span>The “Project overview” database has 2 overdue entries.</span><button slot="action" type="button">View</button></nk-banner>
|
|
1533
|
+
<nk-banner variant="success">✓ <span>All changes have been synced.</span></nk-banner>
|
|
1534
|
+
<nk-banner variant="danger">⛔ <span>The connection to Notion was lost.</span></nk-banner>
|
|
1535
|
+
```
|
|
1536
|
+
|
|
1537
|
+
| Attribute | Type | Default | Description |
|
|
1538
|
+
|---|---|---|---|
|
|
1539
|
+
| `variant` | info | success | warning | danger | – | Tint. |
|
|
1540
|
+
|
|
1541
|
+
**Slots:** `(default)` – Icon and text. · `action` – The action – a `<button>`, shown as underlined text on the right.
|
|
1542
|
+
|
|
1543
|
+
**Replaces:** `.nk-banner`, `.info`, `.success`, `.warning`, `.danger`, `.b-action`
|
|
1544
|
+
|
|
1545
|
+
```html
|
|
1546
|
+
<!-- equivalent class markup -->
|
|
1547
|
+
<div class="nk-banner info">ℹ️ <span>This page is a <b>component preview</b> – every element follows the same design tokens.</span><button class="b-action" type="button">Open palette</button></div>
|
|
1548
|
+
<div class="nk-banner warning">⚠️ <span>The “Project overview” database has 2 overdue entries.</span><button class="b-action" type="button">View</button></div>
|
|
1549
|
+
<div class="nk-banner success">✓ <span>All changes have been synced.</span></div>
|
|
1550
|
+
<div class="nk-banner danger">⛔ <span>The connection to Notion was lost.</span></div>
|
|
1551
|
+
```
|
|
1552
|
+
|
|
1553
|
+
**Small screens:** Below 860px the action moves under the text instead of squeezing it into a narrow column.
|
|
1554
|
+
|
|
1555
|
+
### 3.46 `<nk-empty>` – Empty state
|
|
1556
|
+
|
|
1557
|
+
Dashed box with icon, title, description and whatever call to action you slot in.
|
|
1558
|
+
|
|
1559
|
+
```html
|
|
1560
|
+
<nk-empty icon="🗂️" title="No entries yet" desc="Create the first entry or import existing data."><nk-btn variant="primary" small>+ New entry</nk-btn><nk-btn variant="secondary" small>Import</nk-btn></nk-empty>
|
|
1561
|
+
```
|
|
1562
|
+
|
|
1563
|
+
| Attribute | Type | Default | Description |
|
|
1564
|
+
|---|---|---|---|
|
|
1565
|
+
| `icon` | string | – | Emoji. |
|
|
1566
|
+
| `title` | string | – | Title. Read once and taken off the host, so it never shows as a tooltip. |
|
|
1567
|
+
| `desc` | string | – | Description. |
|
|
1568
|
+
|
|
1569
|
+
**Slots:** `(default)` – Call to action – several buttons sit in a centred row, 8px apart. · `icon` – Rich icon. · `title` – Rich title. · `desc` – Rich description.
|
|
1570
|
+
|
|
1571
|
+
**Replaces:** `.nk-empty`, `.e-icon`, `.e-title`, `.e-desc`, `.e-actions`
|
|
1572
|
+
|
|
1573
|
+
```html
|
|
1574
|
+
<!-- equivalent class markup -->
|
|
1575
|
+
<div class="nk-empty"><div class="e-icon">🗂️</div><div class="e-title">No entries yet</div><div class="e-desc">Create the first entry or import existing data.</div><div class="e-actions"><button class="nk-btn primary small">+ New entry</button><button class="nk-btn secondary small">Import</button></div></div>
|
|
1576
|
+
```
|
|
1577
|
+
|
|
1578
|
+
**Small screens:** Unchanged.
|
|
1579
|
+
|
|
1580
|
+
### 3.47 `<nk-skeleton>` – Skeleton
|
|
1581
|
+
|
|
1582
|
+
Shimmering placeholder lines. `lines` renders several; `widths` gives each its own width.
|
|
1583
|
+
|
|
1584
|
+
```html
|
|
1585
|
+
<nk-skeleton height="18" width="60%"></nk-skeleton>
|
|
1586
|
+
<nk-skeleton lines="3" widths="100%,85%,40%"></nk-skeleton>
|
|
1587
|
+
```
|
|
1588
|
+
|
|
1589
|
+
| Attribute | Type | Default | Description |
|
|
1590
|
+
|---|---|---|---|
|
|
1591
|
+
| `lines` | number | `1` | Number of lines. |
|
|
1592
|
+
| `height` | px | CSS length | `13` | Line height. |
|
|
1593
|
+
| `width` | CSS length | – | Width for every line. |
|
|
1594
|
+
| `widths` | list | – | Comma-separated width per line. |
|
|
1595
|
+
|
|
1596
|
+
|
|
1597
|
+
|
|
1598
|
+
**Replaces:** `.nk-skeleton`
|
|
1599
|
+
|
|
1600
|
+
```html
|
|
1601
|
+
<!-- equivalent class markup -->
|
|
1602
|
+
<div class="nk-skeleton" style="height:18px;width:60%"></div>
|
|
1603
|
+
<div class="nk-skeleton" style="height:13px"></div>
|
|
1604
|
+
<div class="nk-skeleton" style="height:13px;width:85%"></div>
|
|
1605
|
+
<div class="nk-skeleton" style="height:13px;width:40%"></div>
|
|
1606
|
+
```
|
|
1607
|
+
|
|
1608
|
+
**Small screens:** Unchanged; respects reduced motion.
|
|
1609
|
+
|
|
1610
|
+
### 3.48 `<nk-synced>` – Synced block
|
|
1611
|
+
|
|
1612
|
+
Content that appears in several places, framed with a badge.
|
|
1613
|
+
|
|
1614
|
+
```html
|
|
1615
|
+
<nk-synced badge="⟳ 3 places"><div style="font-size:14px;line-height:1.55"><b>Our mission:</b> Take real weight off the working day – calm, clear, effective.</div></nk-synced>
|
|
1616
|
+
```
|
|
1617
|
+
|
|
1618
|
+
| Attribute | Type | Default | Description |
|
|
1619
|
+
|---|---|---|---|
|
|
1620
|
+
| `badge` | string | `⟳ synced` | Badge text. |
|
|
1621
|
+
|
|
1622
|
+
**Slots:** `(default)` – Content.
|
|
1623
|
+
|
|
1624
|
+
**Replaces:** `.nk-synced`, `.synced-badge`
|
|
1625
|
+
|
|
1626
|
+
```html
|
|
1627
|
+
<!-- equivalent class markup -->
|
|
1628
|
+
<div class="nk-synced"><span class="synced-badge">⟳ 3 places</span><div style="font-size:14px;line-height:1.55"><b>Our mission:</b> Take real weight off the working day – calm, clear, effective.</div></div>
|
|
1629
|
+
```
|
|
1630
|
+
|
|
1631
|
+
**Small screens:** Unchanged.
|
|
1632
|
+
|
|
1633
|
+
### 3.49 `<nk-tabs>` – Tabs
|
|
1634
|
+
|
|
1635
|
+
A tab strip with panels. `nk-tab` children are the tabs; elements with `slot="panel"` and a matching `data-tab` are the panels – the tabs hide every panel but the active one through `hidden`. Arrow keys move between tabs.
|
|
1636
|
+
|
|
1637
|
+
```html
|
|
1638
|
+
<nk-tabs value="notes">
|
|
1639
|
+
<nk-tab value="notes">📝 Notes</nk-tab>
|
|
1640
|
+
<nk-tab value="tasks">✅ Tasks</nk-tab>
|
|
1641
|
+
<nk-tab value="files">📎 Files</nk-tab>
|
|
1642
|
+
<div slot="panel" data-tab="notes" class="nk-tab-panel">Free-form notes on the project – meeting minutes, ideas, rough drafts.</div>
|
|
1643
|
+
<div slot="panel" data-tab="tasks" class="nk-tab-panel">Tasks for this project, linked to the database below.</div>
|
|
1644
|
+
<div slot="panel" data-tab="files" class="nk-tab-panel">Attached files and exports.</div>
|
|
1645
|
+
</nk-tabs>
|
|
1646
|
+
```
|
|
1647
|
+
|
|
1648
|
+
| Attribute | Type | Default | Description |
|
|
1649
|
+
|---|---|---|---|
|
|
1650
|
+
| `value` | string | – | Active tab value (default: the tab with `active`, else the first). |
|
|
1651
|
+
|
|
1652
|
+
**Slots:** `(default)` – `nk-tab` children. · `panel` – Panels with `data-tab`.
|
|
1653
|
+
|
|
1654
|
+
**Events:** `nk-change` `{ value }` – Active tab changed. · `nk-select` `{ value, label }` – From the clicked tab.
|
|
1655
|
+
|
|
1656
|
+
**Properties:** `value`
|
|
1657
|
+
|
|
1658
|
+
**Replaces:** `.nk-tabs`, `.nk-tab`, `.active`, `.nk-tab-panel`
|
|
1659
|
+
|
|
1660
|
+
```html
|
|
1661
|
+
<!-- equivalent class markup -->
|
|
1662
|
+
<div class="nk-tabs">
|
|
1663
|
+
<span class="nk-tab active">📝 Notes</span>
|
|
1664
|
+
<span class="nk-tab">✅ Tasks</span>
|
|
1665
|
+
<span class="nk-tab">📎 Files</span>
|
|
1666
|
+
</div>
|
|
1667
|
+
<div class="nk-tab-panel">Free-form notes on the project – meeting minutes, ideas, rough drafts.</div>
|
|
1668
|
+
```
|
|
1669
|
+
|
|
1670
|
+
**Small screens:** Strip stays on one line; keep labels short.
|
|
1671
|
+
|
|
1672
|
+
### 3.50 `<nk-tab>` – Tab
|
|
1673
|
+
|
|
1674
|
+
One tab of `nk-tabs`. Standalone it toggles its own `active`.
|
|
1675
|
+
|
|
1676
|
+
```html
|
|
1677
|
+
<nk-tabs><nk-tab value="a" active>📝 Notes</nk-tab><nk-tab value="b">✅ Tasks</nk-tab></nk-tabs>
|
|
1678
|
+
```
|
|
1679
|
+
|
|
1680
|
+
| Attribute | Type | Default | Description |
|
|
1681
|
+
|---|---|---|---|
|
|
1682
|
+
| `value` | string | – | Value (default: text). |
|
|
1683
|
+
| `active` | boolean | – | Active. |
|
|
1684
|
+
| `disabled` | boolean | – | Not selectable. |
|
|
1685
|
+
|
|
1686
|
+
**Slots:** `(default)` – Label.
|
|
1687
|
+
|
|
1688
|
+
**Events:** `nk-select` `{ value, label }` – Clicked / Enter.
|
|
1689
|
+
|
|
1690
|
+
**Replaces:** `.nk-tab`, `.active`
|
|
1691
|
+
|
|
1692
|
+
```html
|
|
1693
|
+
<!-- equivalent class markup -->
|
|
1694
|
+
<div class="nk-tabs"><span class="nk-tab active">📝 Notes</span><span class="nk-tab">✅ Tasks</span></div>
|
|
1695
|
+
```
|
|
1696
|
+
|
|
1697
|
+
**Small screens:** Unchanged.
|
|
1698
|
+
|
|
1699
|
+
### 3.51 `<nk-segmented>` – Segmented control
|
|
1700
|
+
|
|
1701
|
+
Plain `<button value>` children stay in the light DOM (the stylesheet’s slotted twins shape them); the element moves `.active`, handles arrow keys and submits `value` with the form. With `scroll` the chosen option stays in view: after the first layout, on every change and when the row’s width changes, the row – never the page – scrolls the least distance, right to left as well.
|
|
1702
|
+
|
|
1703
|
+
```html
|
|
1704
|
+
<nk-segmented name="range" value="week"><button value="week">Week</button><button value="month">Month</button><button value="quarter">Quarter</button></nk-segmented>
|
|
1705
|
+
<div style="max-width:300px;margin-top:12px"><nk-segmented name="filter" value="all" scroll><button value="all">All</button><button value="attention">⚠️ Attention</button><button value="failed">Failed</button><button value="read">Read</button><button value="ignored">Ignored</button></nk-segmented></div>
|
|
1706
|
+
<div style="max-width:300px;margin-top:12px"><nk-segmented name="filter2" value="all" wrap><button value="all">All</button><button value="attention">⚠️ Attention</button><button value="failed">Failed</button><button value="read">Read</button><button value="ignored">Ignored</button></nk-segmented></div>
|
|
1707
|
+
```
|
|
1708
|
+
|
|
1709
|
+
| Attribute | Type | Default | Description |
|
|
1710
|
+
|---|---|---|---|
|
|
1711
|
+
| `value` | string | – | Selected value (default: the button with `.active`, else the first). |
|
|
1712
|
+
| `scroll` | boolean | – | Horizontally scrollable row, scrollbar hidden. |
|
|
1713
|
+
| `wrap` | boolean | – | Segments wrap onto further rows. |
|
|
1714
|
+
| `name` | string | – | Form field name (FormData key). |
|
|
1715
|
+
| `disabled` | boolean | – | Disables the control. |
|
|
1716
|
+
|
|
1717
|
+
**Slots:** `(default)` – `<button value="…">` children.
|
|
1718
|
+
|
|
1719
|
+
**Events:** `nk-change` `{ value, name }` – Selection changed.
|
|
1720
|
+
|
|
1721
|
+
**Replaces:** `.nk-segmented`, `.active`, `.scroll`, `.wrap`
|
|
1722
|
+
|
|
1723
|
+
```html
|
|
1724
|
+
<!-- equivalent class markup -->
|
|
1725
|
+
<div class="nk-segmented"><button class="active">Week</button><button>Month</button><button>Quarter</button></div>
|
|
1726
|
+
<div style="max-width:300px;margin-top:12px"><div class="nk-segmented scroll"><button class="active">All</button><button>⚠️ Attention</button><button>Failed</button><button>Read</button><button>Ignored</button></div></div>
|
|
1727
|
+
<div style="max-width:300px;margin-top:12px"><div class="nk-segmented wrap"><button class="active">All</button><button>⚠️ Attention</button><button>Failed</button><button>Read</button><button>Ignored</button></div></div>
|
|
1728
|
+
```
|
|
1729
|
+
|
|
1730
|
+
**Small screens:** One row by default, which five filter options overflow on a phone: `scroll` keeps one thumb-swipeable row capped at the parent width (scrollbar hidden), `wrap` breaks it onto further rows.
|
|
1731
|
+
|
|
1732
|
+
### 3.52 `<nk-steps>` – Steps
|
|
1733
|
+
|
|
1734
|
+
A short flow – connecting an account, setting up a model – calm and vertical: a numbered circle per step joined by a hairline, done steps with a check on the green tag, the current one ringed in the accent and marked `aria-current="step"`. `current` counts from 1; one past the last marks every step done, and `next()` moves on. The `steps` attribute is a comma-separated list; the property also takes `{ label, desc }` objects for a line under the label.
|
|
1735
|
+
|
|
1736
|
+
```html
|
|
1737
|
+
<nk-steps label="Connect your own model" current="2"></nk-steps>
|
|
1738
|
+
<script>{ document.currentScript.previousElementSibling.steps = [{ label: 'Choose a provider', desc: 'Anthropic' }, 'Enter the API key', 'Test the connection']; }</script>
|
|
1739
|
+
```
|
|
1740
|
+
|
|
1741
|
+
| Attribute | Type | Default | Description |
|
|
1742
|
+
|---|---|---|---|
|
|
1743
|
+
| `steps` | list | – | Comma-separated step labels. |
|
|
1744
|
+
| `current` | number | `1` | The current step, from 1. |
|
|
1745
|
+
| `label` | string | – | The list’s accessible name. |
|
|
1746
|
+
|
|
1747
|
+
**Properties:** `steps`, `current` · **Methods:** `next()`
|
|
1748
|
+
|
|
1749
|
+
**Replaces:** `.nk-steps`, `.nk-step`, `.st-mark`, `.st-desc`, `.done`, `.current`
|
|
1750
|
+
|
|
1751
|
+
```html
|
|
1752
|
+
<!-- equivalent class markup -->
|
|
1753
|
+
<ol class="nk-steps" aria-label="Connect your own model">
|
|
1754
|
+
<li class="nk-step done"><span class="st-mark">✓</span><span>Choose a provider<span class="st-desc">Anthropic</span></span></li>
|
|
1755
|
+
<li class="nk-step current" aria-current="step"><span class="st-mark">2</span><span>Enter the API key</span></li>
|
|
1756
|
+
<li class="nk-step"><span class="st-mark">3</span><span>Test the connection</span></li>
|
|
1757
|
+
</ol>
|
|
1758
|
+
```
|
|
1759
|
+
|
|
1760
|
+
**Small screens:** Unchanged: vertical, so it never runs out of width.
|
|
1761
|
+
|
|
1762
|
+
### 3.53 `<nk-stats>` – Stat cards
|
|
1763
|
+
|
|
1764
|
+
`nk-stats` is the row; each `nk-stat` shows label, value and a trend line coloured by `trend`.
|
|
1765
|
+
|
|
1766
|
+
```html
|
|
1767
|
+
<nk-stats>
|
|
1768
|
+
<nk-stat label="Active pages" value="128" delta="▲ 12 this week" trend="up"></nk-stat>
|
|
1769
|
+
<nk-stat label="AI requests" value="847" delta="▲ 23 %" trend="up"></nk-stat>
|
|
1770
|
+
<nk-stat label="Open tasks" value="14" delta="▼ 5 since yesterday" trend="down"></nk-stat>
|
|
1771
|
+
</nk-stats>
|
|
1772
|
+
```
|
|
1773
|
+
|
|
1774
|
+
| Attribute | Type | Default | Description |
|
|
1775
|
+
|---|---|---|---|
|
|
1776
|
+
| `label` | string | – | (nk-stat) Label. |
|
|
1777
|
+
| `value` | string | – | (nk-stat) Big number. |
|
|
1778
|
+
| `delta` | string | – | (nk-stat) Trend text. |
|
|
1779
|
+
| `trend` | up | down | – | (nk-stat) Colours the delta. |
|
|
1780
|
+
|
|
1781
|
+
**Slots:** `(default)` – (nk-stats) `nk-stat` children; (nk-stat) slots `label`, `value`, `delta` for rich content.
|
|
1782
|
+
|
|
1783
|
+
**Replaces:** `.nk-stats`, `.nk-stat`, `.s-label`, `.s-value`, `.s-delta`, `.up`, `.down`
|
|
1784
|
+
|
|
1785
|
+
```html
|
|
1786
|
+
<!-- equivalent class markup -->
|
|
1787
|
+
<div class="nk-stats">
|
|
1788
|
+
<div class="nk-stat"><div class="s-label">Active pages</div><div class="s-value">128</div><div class="s-delta up">▲ 12 this week</div></div>
|
|
1789
|
+
<div class="nk-stat"><div class="s-label">AI requests</div><div class="s-value">847</div><div class="s-delta up">▲ 23 %</div></div>
|
|
1790
|
+
<div class="nk-stat"><div class="s-label">Open tasks</div><div class="s-value">14</div><div class="s-delta down">▼ 5 since yesterday</div></div>
|
|
1791
|
+
</div>
|
|
1792
|
+
```
|
|
1793
|
+
|
|
1794
|
+
**Small screens:** The row wraps below 860px.
|
|
1795
|
+
|
|
1796
|
+
### 3.54 `<nk-stat>` – Stat card
|
|
1797
|
+
|
|
1798
|
+
One card; see `nk-stats` for the row.
|
|
1799
|
+
|
|
1800
|
+
```html
|
|
1801
|
+
<nk-stats><nk-stat label="Active pages" value="128" delta="▲ 12 this week" trend="up"></nk-stat></nk-stats>
|
|
1802
|
+
```
|
|
1803
|
+
|
|
1804
|
+
| Attribute | Type | Default | Description |
|
|
1805
|
+
|---|---|---|---|
|
|
1806
|
+
| `label` | string | – | Label. |
|
|
1807
|
+
| `value` | string | – | Value. |
|
|
1808
|
+
| `delta` | string | – | Trend text. |
|
|
1809
|
+
| `trend` | up | down | – | Delta colour. |
|
|
1810
|
+
|
|
1811
|
+
**Slots:** `label` – Rich label. · `value` – Rich value. · `delta` – Rich delta (add `class="up"` / `"down"`).
|
|
1812
|
+
|
|
1813
|
+
**Replaces:** `.nk-stat`
|
|
1814
|
+
|
|
1815
|
+
```html
|
|
1816
|
+
<!-- equivalent class markup -->
|
|
1817
|
+
<div class="nk-stats"><div class="nk-stat"><div class="s-label">Active pages</div><div class="s-value">128</div><div class="s-delta up">▲ 12 this week</div></div></div>
|
|
1818
|
+
```
|
|
1819
|
+
|
|
1820
|
+
**Small screens:** Unchanged.
|
|
1821
|
+
|
|
1822
|
+
### 3.55 `<nk-avatar-group>` – Avatar group
|
|
1823
|
+
|
|
1824
|
+
Overlapping `.mini-avatar` children (light DOM, styled by the slotted twins) plus a “more” bubble from the attribute. Pass `.mini-avatar`, not `.nk-avatar`: the document rule of `.nk-avatar` sets its own 24px, and for slotted nodes the document wins over the group’s 26px.
|
|
1825
|
+
|
|
1826
|
+
```html
|
|
1827
|
+
<div style="display:flex;align-items:center;gap:12px"><nk-avatar-group more="+2"><span class="mini-avatar" style="background:linear-gradient(135deg,var(--nk-decor-purple),var(--nk-decor-blue))">MK</span><span class="mini-avatar" style="background:var(--nk-color-green)">SL</span><span class="mini-avatar" style="background:var(--nk-color-orange)">TW</span></nk-avatar-group><span style="font-size:12.5px;color:var(--nk-text-tertiary)">5 people have access</span></div>
|
|
1828
|
+
```
|
|
1829
|
+
|
|
1830
|
+
| Attribute | Type | Default | Description |
|
|
1831
|
+
|---|---|---|---|
|
|
1832
|
+
| `more` | string | – | Text of the trailing bubble, e.g. `+2`. |
|
|
1833
|
+
|
|
1834
|
+
**Slots:** `(default)` – `<span class="mini-avatar" style="background:…">` children.
|
|
1835
|
+
|
|
1836
|
+
**Replaces:** `.nk-avatar-group`, `.mini-avatar`, `.more`
|
|
1837
|
+
|
|
1838
|
+
```html
|
|
1839
|
+
<!-- equivalent class markup -->
|
|
1840
|
+
<div style="display:flex;align-items:center;gap:12px"><div class="nk-avatar-group"><span class="nk-avatar">MK</span><span class="nk-avatar green">SL</span><span class="nk-avatar orange">TW</span><span class="mini-avatar more">+2</span></div><span style="font-size:12.5px;color:var(--nk-text-tertiary)">5 people have access</span></div>
|
|
1841
|
+
```
|
|
1842
|
+
|
|
1843
|
+
**Small screens:** Unchanged.
|
|
1844
|
+
|
|
1845
|
+
### 3.56 `<nk-avatar>` – Avatar
|
|
1846
|
+
|
|
1847
|
+
A person or a workspace: initials, an emoji or a photo in a circle. `size` small (20px), default 24px, large (32px), xlarge (56px); `color` one of Notion’s nine names or any CSS background, without it the avatar gradient; `square` for a workspace icon. Without content the initials come from `name`; with `src` a photo fills the circle and `name` becomes its alt text. Initials from `name` are the first letter or digit of each word: “Planer (Dev)” → PD, “Anna-Lena Groß” → AG.
|
|
1848
|
+
|
|
1849
|
+
```html
|
|
1850
|
+
<div style="display:flex;align-items:center;gap:10px"><nk-avatar size="small" color="blue">TW</nk-avatar><nk-avatar>AL</nk-avatar><nk-avatar color="green">SL</nk-avatar><nk-avatar size="large" color="orange">MK</nk-avatar><nk-avatar size="xlarge" color="purple" name="Ada Lovelace"></nk-avatar><nk-avatar size="large" square>A</nk-avatar></div>
|
|
1851
|
+
```
|
|
1852
|
+
|
|
1853
|
+
| Attribute | Type | Default | Description |
|
|
1854
|
+
|---|---|---|---|
|
|
1855
|
+
| `size` | small | large | xlarge | – | Size; default 24px. |
|
|
1856
|
+
| `color` | colour name | CSS | – | gray, brown, orange, yellow, green, blue, purple, pink, red – or any CSS background. |
|
|
1857
|
+
| `square` | boolean | – | Corners instead of a circle. |
|
|
1858
|
+
| `name` | string | – | Initials when empty; alt text of the photo. |
|
|
1859
|
+
| `src` | URL | – | Photo. |
|
|
1860
|
+
|
|
1861
|
+
**Slots:** `(default)` – Initials or an emoji.
|
|
1862
|
+
|
|
1863
|
+
**Replaces:** `.nk-avatar`, `.small`, `.large`, `.xlarge`, `.square`, `.green`, `.blue`, `.orange`, `.purple`
|
|
1864
|
+
|
|
1865
|
+
```html
|
|
1866
|
+
<!-- equivalent class markup -->
|
|
1867
|
+
<div style="display:flex;align-items:center;gap:10px"><span class="nk-avatar small blue">TW</span><span class="nk-avatar">AL</span><span class="nk-avatar green">SL</span><span class="nk-avatar large orange">MK</span><span class="nk-avatar xlarge purple">AL</span><span class="nk-avatar large square">A</span></div>
|
|
1868
|
+
```
|
|
1869
|
+
|
|
1870
|
+
**Small screens:** Unchanged. A fixed size, so a row of avatars never reflows.
|
|
1871
|
+
|
|
1872
|
+
### 3.57 `<nk-mention>` – Mention
|
|
1873
|
+
|
|
1874
|
+
Inline chip for a person (with avatar slot), a page or a date.
|
|
1875
|
+
|
|
1876
|
+
```html
|
|
1877
|
+
<p style="margin:0;line-height:1.7"><nk-mention type="person"><span slot="avatar" class="mini-avatar" style="background:#448361">SL</span>Sara Lindt</nk-mention> · <nk-mention type="page">📄 Onboarding</nk-mention> · <nk-mention type="date">📅 20 May</nk-mention></p>
|
|
1878
|
+
```
|
|
1879
|
+
|
|
1880
|
+
| Attribute | Type | Default | Description |
|
|
1881
|
+
|---|---|---|---|
|
|
1882
|
+
| `type` | person | page | date | – | Kind of mention. |
|
|
1883
|
+
|
|
1884
|
+
**Slots:** `avatar` – `.mini-avatar` for persons. · `(default)` – Text.
|
|
1885
|
+
|
|
1886
|
+
**Replaces:** `.nk-mention`, `.person`, `.page`, `.date`, `.mini-avatar`
|
|
1887
|
+
|
|
1888
|
+
```html
|
|
1889
|
+
<!-- equivalent class markup -->
|
|
1890
|
+
<p style="margin:0;line-height:1.7"><span class="nk-mention person"><span class="mini-avatar" style="background:#448361">SL</span>Sara Lindt</span> · <span class="nk-mention page">📄 Onboarding</span> · <span class="nk-mention date">📅 20 May</span></p>
|
|
1891
|
+
```
|
|
1892
|
+
|
|
1893
|
+
**Small screens:** Unchanged; never wraps.
|
|
1894
|
+
|
|
1895
|
+
### 3.58 `<nk-template-btn>` – Template button
|
|
1896
|
+
|
|
1897
|
+
Full-width, left-aligned button on the callout background – “insert a template”. Fires `nk-select` with `value`.
|
|
1898
|
+
|
|
1899
|
+
```html
|
|
1900
|
+
<nk-template-btn icon="📅" value="week-plan">Insert week plan</nk-template-btn>
|
|
1901
|
+
<nk-template-btn icon="🤝" value="minutes">Insert meeting minutes</nk-template-btn>
|
|
1902
|
+
<nk-template-btn icon="🔁" value="retro">Insert retro board</nk-template-btn>
|
|
1903
|
+
```
|
|
1904
|
+
|
|
1905
|
+
| Attribute | Type | Default | Description |
|
|
1906
|
+
|---|---|---|---|
|
|
1907
|
+
| `icon` | string | – | Leading emoji. |
|
|
1908
|
+
| `value` | string | – | Reported value (default: text). |
|
|
1909
|
+
| `disabled` | boolean | – | Disabled. |
|
|
1910
|
+
|
|
1911
|
+
**Slots:** `(default)` – Label.
|
|
1912
|
+
|
|
1913
|
+
**Events:** `nk-select` `{ value, label }` – Clicked.
|
|
1914
|
+
|
|
1915
|
+
**Replaces:** `.nk-template-btn`
|
|
1916
|
+
|
|
1917
|
+
```html
|
|
1918
|
+
<!-- equivalent class markup -->
|
|
1919
|
+
<button class="nk-template-btn">📅 Insert week plan</button>
|
|
1920
|
+
<button class="nk-template-btn">🤝 Insert meeting minutes</button>
|
|
1921
|
+
<button class="nk-template-btn">🔁 Insert retro board</button>
|
|
1922
|
+
```
|
|
1923
|
+
|
|
1924
|
+
**Small screens:** Unchanged.
|
|
1925
|
+
|
|
1926
|
+
### 3.59 `<nk-model-card>` – Model card
|
|
1927
|
+
|
|
1928
|
+
A radio-like card. Cards with the same `name` form a group; the selected one submits `value` with the form.
|
|
1929
|
+
|
|
1930
|
+
```html
|
|
1931
|
+
<nk-model-card name="model" value="pro" title="Mona Pro" desc="Best for long documents and research." selected></nk-model-card>
|
|
1932
|
+
<nk-model-card name="model" value="fast" title="Mona Fast" desc="Quick answers, lower cost."></nk-model-card>
|
|
1933
|
+
```
|
|
1934
|
+
|
|
1935
|
+
| Attribute | Type | Default | Description |
|
|
1936
|
+
|---|---|---|---|
|
|
1937
|
+
| `title` | string | – | Name line. Read once and taken off the host, so it never shows as a tooltip. |
|
|
1938
|
+
| `desc` | string | – | Description. |
|
|
1939
|
+
| `name` | string | – | Form field name (FormData key). |
|
|
1940
|
+
| `disabled` | boolean | – | Disables the control. |
|
|
1941
|
+
| `value` | string | – | Submitted value. |
|
|
1942
|
+
| `selected` | boolean | – | Selected. |
|
|
1943
|
+
|
|
1944
|
+
**Slots:** `title` – Rich name line (e.g. with an `nk-tag`). · `desc` – Rich description.
|
|
1945
|
+
|
|
1946
|
+
**Events:** `nk-change` `{ value, name, checked }` – Selected. · `nk-select` `{ value, label }` – Selected.
|
|
1947
|
+
|
|
1948
|
+
**Replaces:** `.nk-model-card`, `.selected`, `.m-radio`, `.m-name`, `.m-desc`
|
|
1949
|
+
|
|
1950
|
+
```html
|
|
1951
|
+
<!-- equivalent class markup -->
|
|
1952
|
+
<div class="nk-model-card selected"><div class="m-radio"></div><div><div class="m-name">Mona Pro</div><div class="m-desc">Best for long documents and research.</div></div></div>
|
|
1953
|
+
<div class="nk-model-card"><div class="m-radio"></div><div><div class="m-name">Mona Fast</div><div class="m-desc">Quick answers, lower cost.</div></div></div>
|
|
1954
|
+
```
|
|
1955
|
+
|
|
1956
|
+
**Small screens:** Unchanged.
|
|
1957
|
+
|
|
1958
|
+
### 3.60 `<nk-profile-row>` – Profile row
|
|
1959
|
+
|
|
1960
|
+
A 56px gradient avatar with whatever you slot beside it – usually two buttons.
|
|
1961
|
+
|
|
1962
|
+
```html
|
|
1963
|
+
<nk-profile-row avatar="MK"><nk-btn variant="secondary" small>Change photo</nk-btn> <nk-btn variant="danger" small>Remove</nk-btn></nk-profile-row>
|
|
1964
|
+
```
|
|
1965
|
+
|
|
1966
|
+
| Attribute | Type | Default | Description |
|
|
1967
|
+
|---|---|---|---|
|
|
1968
|
+
| `avatar` | string | – | Initials. |
|
|
1969
|
+
|
|
1970
|
+
**Slots:** `avatar` – Custom avatar (e.g. an image). · `(default)` – Content beside the avatar.
|
|
1971
|
+
|
|
1972
|
+
**Replaces:** `.nk-profile-row`, `.big-avatar`
|
|
1973
|
+
|
|
1974
|
+
```html
|
|
1975
|
+
<!-- equivalent class markup -->
|
|
1976
|
+
<div class="nk-profile-row"><div class="big-avatar">MK</div><button class="nk-btn secondary small">Change photo</button> <button class="nk-btn danger small">Remove</button></div>
|
|
1977
|
+
```
|
|
1978
|
+
|
|
1979
|
+
**Small screens:** Unchanged.
|
|
1980
|
+
|
|
1981
|
+
### 3.61 `<nk-danger-zone>` – Danger zone
|
|
1982
|
+
|
|
1983
|
+
Red-framed box for destructive settings.
|
|
1984
|
+
|
|
1985
|
+
```html
|
|
1986
|
+
<nk-danger-zone title="Danger zone"><nk-field label="Delete workspace" desc="Deleting the workspace removes every page."><nk-btn variant="danger-solid" small>Delete</nk-btn></nk-field></nk-danger-zone>
|
|
1987
|
+
```
|
|
1988
|
+
|
|
1989
|
+
| Attribute | Type | Default | Description |
|
|
1990
|
+
|---|---|---|---|
|
|
1991
|
+
| `title` | string | – | Red heading. Read once and taken off the host, so it never shows as a tooltip. |
|
|
1992
|
+
|
|
1993
|
+
**Slots:** `(default)` – Fields and buttons.
|
|
1994
|
+
|
|
1995
|
+
**Replaces:** `.nk-danger-zone`, `.dz-title`
|
|
1996
|
+
|
|
1997
|
+
```html
|
|
1998
|
+
<!-- equivalent class markup -->
|
|
1999
|
+
<div class="nk-danger-zone"><div class="dz-title">Danger zone</div><div class="nk-field"><div><div class="f-label">Delete workspace</div><div class="f-desc">Deleting the workspace removes every page.</div></div><div class="f-control"><button class="nk-btn danger-solid small">Delete</button></div></div></div>
|
|
2000
|
+
```
|
|
2001
|
+
|
|
2002
|
+
**Small screens:** Unchanged.
|
|
2003
|
+
|
|
2004
|
+
### 3.62 `<nk-member-list>` – Member list
|
|
2005
|
+
|
|
2006
|
+
Rows of `nk-member-row`; the list marks the last row so it loses its bottom border. Each row shows avatar (initials + `color`), name, mail and a `slot="role"` control on the right.
|
|
2007
|
+
|
|
2008
|
+
```html
|
|
2009
|
+
<nk-member-list>
|
|
2010
|
+
<nk-member-row name="Sara Lindt" mail="sara@example.com" color="#448361"><nk-select slot="role" compact value="editor"><option value="viewer">Viewer</option><option value="editor">Editor</option><option value="admin">Admin</option></nk-select></nk-member-row>
|
|
2011
|
+
<nk-member-row name="Tom Weber" mail="tom@example.com" color="#d9730d"><nk-select slot="role" compact value="viewer"><option value="viewer">Viewer</option><option value="editor">Editor</option><option value="admin">Admin</option></nk-select></nk-member-row>
|
|
2012
|
+
</nk-member-list>
|
|
2013
|
+
```
|
|
2014
|
+
|
|
2015
|
+
| Attribute | Type | Default | Description |
|
|
2016
|
+
|---|---|---|---|
|
|
2017
|
+
| `name` | string | – | (row) Name. |
|
|
2018
|
+
| `mail` | string | – | (row) Mail line. |
|
|
2019
|
+
| `avatar` | string | – | (row) Initials (default: from the name). |
|
|
2020
|
+
| `color` | CSS color | – | (row) Avatar background. |
|
|
2021
|
+
| `last` | boolean | – | (row) No bottom border – set by the list. |
|
|
2022
|
+
|
|
2023
|
+
**Slots:** `(default)` – (list) rows; (row) extra content. · `role` – (row) A control on the right, e.g. `nk-select compact`. · `avatar` – (row) Custom avatar.
|
|
2024
|
+
|
|
2025
|
+
**Replaces:** `.nk-member-list`, `.nk-member-row`, `.last`, `.m-mail`, `.mini-avatar`
|
|
2026
|
+
|
|
2027
|
+
```html
|
|
2028
|
+
<!-- equivalent class markup -->
|
|
2029
|
+
<div class="nk-member-list">
|
|
2030
|
+
<div class="nk-member-row"><span class="mini-avatar" style="background:#448361">SL</span><div>Sara Lindt<div class="m-mail">sara@example.com</div></div><select class="nk-select"><option>Viewer</option><option selected>Editor</option><option>Admin</option></select></div>
|
|
2031
|
+
<div class="nk-member-row"><span class="mini-avatar" style="background:#d9730d">TW</span><div>Tom Weber<div class="m-mail">tom@example.com</div></div><select class="nk-select"><option selected>Viewer</option><option>Editor</option><option>Admin</option></select></div>
|
|
2032
|
+
</div>
|
|
2033
|
+
```
|
|
2034
|
+
|
|
2035
|
+
**Small screens:** Unchanged; the role select shrinks to 120px.
|
|
2036
|
+
|
|
2037
|
+
### 3.63 `<nk-member-row>` – Member row
|
|
2038
|
+
|
|
2039
|
+
One row; see `nk-member-list`.
|
|
2040
|
+
|
|
2041
|
+
```html
|
|
2042
|
+
<nk-member-row name="Sara Lindt" mail="sara@example.com" color="green" last></nk-member-row>
|
|
2043
|
+
```
|
|
2044
|
+
|
|
2045
|
+
| Attribute | Type | Default | Description |
|
|
2046
|
+
|---|---|---|---|
|
|
2047
|
+
| `name` | string | – | Name. |
|
|
2048
|
+
| `mail` | string | – | Mail. |
|
|
2049
|
+
| `avatar` | string | – | Initials. |
|
|
2050
|
+
| `color` | colour name | CSS | – | Avatar colour: one of the nine names (gray … red) or any CSS background; without it the avatar gradient. |
|
|
2051
|
+
| `last` | boolean | – | No bottom border. |
|
|
2052
|
+
|
|
2053
|
+
**Slots:** `role` – Control on the right. · `avatar` – Custom avatar. · `(default)` – Extra content.
|
|
2054
|
+
|
|
2055
|
+
**Replaces:** `.nk-member-row`
|
|
2056
|
+
|
|
2057
|
+
```html
|
|
2058
|
+
<!-- equivalent class markup -->
|
|
2059
|
+
<div class="nk-member-row last"><span class="nk-avatar green">SL</span><div>Sara Lindt<div class="m-mail">sara@example.com</div></div></div>
|
|
2060
|
+
```
|
|
2061
|
+
|
|
2062
|
+
**Small screens:** Unchanged.
|
|
2063
|
+
|
|
2064
|
+
## Overlays (wave 4)
|
|
2065
|
+
|
|
2066
|
+
### 3.64 `<nk-modal>` – Settings modal
|
|
2067
|
+
|
|
2068
|
+
The settings overlay: backdrop, a 960×640 dialog with a nav column and a content column. The nav rows are rendered by the modal from the panes’ `label`/`icon`/`group`, so the 27px rows and the 860px icon rail come straight from the stylesheet. Escape and the backdrop close it; focus moves in and back; the page behind is scroll-locked and inert. Place it directly under `<body>`.
|
|
2069
|
+
|
|
2070
|
+
```html
|
|
2071
|
+
<nk-modal open>
|
|
2072
|
+
<nk-settings-user slot="user" name="Marcel Karas" mail="marcel@monahilft.de"></nk-settings-user>
|
|
2073
|
+
<nk-settings-pane name="profile" group="Account" icon="👤" label="My profile" title="My profile" active>
|
|
2074
|
+
<nk-profile-row avatar="MK"><nk-btn variant="secondary" small>Change photo</nk-btn></nk-profile-row>
|
|
2075
|
+
<nk-field label="Display name" desc="Shown next to your comments."><nk-input value="Marcel Karas"></nk-input></nk-field>
|
|
2076
|
+
<nk-field label="Email"><nk-input type="email" value="marcel@monahilft.de"></nk-input></nk-field>
|
|
2077
|
+
</nk-settings-pane>
|
|
2078
|
+
<nk-settings-pane name="appearance" group="Account" icon="🎨" label="Appearance" title="Appearance">
|
|
2079
|
+
<nk-field label="Theme"><nk-select><option>Light</option><option>Dark</option><option>System</option></nk-select></nk-field>
|
|
2080
|
+
</nk-settings-pane>
|
|
2081
|
+
<nk-settings-pane name="members" group="Workspace" icon="👥" label="Members" title="Members">
|
|
2082
|
+
<nk-member-list><nk-member-row name="Sara Lindt" mail="sara@example.com" color="#448361"></nk-member-row></nk-member-list>
|
|
2083
|
+
</nk-settings-pane>
|
|
2084
|
+
</nk-modal>
|
|
2085
|
+
```
|
|
2086
|
+
|
|
2087
|
+
| Attribute | Type | Default | Description |
|
|
2088
|
+
|---|---|---|---|
|
|
2089
|
+
| `open` | boolean | – | Shown. |
|
|
2090
|
+
| `pane` | string | – | Name of the active pane (default: the pane with `active`, else the first). |
|
|
2091
|
+
|
|
2092
|
+
**Slots:** `(default)` – `nk-settings-pane` children. · `user` – `nk-settings-user` at the top of the nav. · `nav` – Extra nav content below the generated rows (860px rules do not reach slotted elements).
|
|
2093
|
+
|
|
2094
|
+
**Events:** `nk-toggle` `{ open }` – Opened / closed. · `nk-select` `{ value, label }` – Pane switched.
|
|
2095
|
+
|
|
2096
|
+
**Properties:** `open`, `pane`, `panes` · **Methods:** `show(pane?)`, `close()`, `toggle()`
|
|
2097
|
+
|
|
2098
|
+
**Replaces:** `.nk-modal-backdrop`, `.open`, `.nk-modal`, `.nk-settings-nav`, `.nk-settings-content`
|
|
2099
|
+
|
|
2100
|
+
```html
|
|
2101
|
+
<!-- equivalent class markup -->
|
|
2102
|
+
<div class="nk-modal-backdrop open"><div class="nk-modal">
|
|
2103
|
+
<nav class="nk-settings-nav">
|
|
2104
|
+
<div class="nk-settings-user"><div class="avatar">MK</div><div class="u-text"><div class="name">Marcel Karas</div><div class="mail">marcel@monahilft.de</div></div></div>
|
|
2105
|
+
<div class="nk-section-label">Account</div>
|
|
2106
|
+
<div class="nk-tree-item active"><span class="icon">👤</span><span class="label">My profile</span></div>
|
|
2107
|
+
<div class="nk-tree-item"><span class="icon">🎨</span><span class="label">Appearance</span></div>
|
|
2108
|
+
<div class="nk-section-label">Workspace</div>
|
|
2109
|
+
<div class="nk-tree-item"><span class="icon">👥</span><span class="label">Members</span></div>
|
|
2110
|
+
</nav>
|
|
2111
|
+
<div class="nk-settings-content">
|
|
2112
|
+
<section class="nk-settings-pane active"><h2>My profile</h2>
|
|
2113
|
+
<div class="nk-profile-row"><div class="big-avatar">MK</div><button class="nk-btn secondary small">Change photo</button></div>
|
|
2114
|
+
<div class="nk-field"><div><div class="f-label">Display name</div><div class="f-desc">Shown next to your comments.</div></div><div class="f-control"><input class="nk-input" value="Marcel Karas"></div></div>
|
|
2115
|
+
<div class="nk-field"><div><div class="f-label">Email</div></div><div class="f-control"><input class="nk-input" type="email" value="marcel@monahilft.de"></div></div>
|
|
2116
|
+
</section>
|
|
2117
|
+
</div>
|
|
2118
|
+
</div></div>
|
|
2119
|
+
```
|
|
2120
|
+
|
|
2121
|
+
**Small screens:** Below 860px the nav collapses to a 60px icon rail; the dialog takes 92vw × 86vh.
|
|
2122
|
+
|
|
2123
|
+
### 3.65 `<nk-sheet>` – Sheet
|
|
2124
|
+
|
|
2125
|
+
Notion’s mobile surface for menus, properties and more – the phone’s twin of the modal, with its contract: `show()`, `close()`, `toggle()`; Escape and the backdrop close it; focus moves in and back; the page behind is scroll-locked and inert. The panel rises from the bottom edge with a grabber, `title` sits under it and names the dialog. Rows inside are 40px, a thumb’s height. Choosing a row does not close the sheet – `nk-select` bubbles out and the app decides. For a menu that is a popover on the desktop and a sheet on the phone, use `<nk-menu floating sheet>`. Place it directly under `<body>`.
|
|
2126
|
+
|
|
2127
|
+
```html
|
|
2128
|
+
<nk-sheet open title="More">
|
|
2129
|
+
<nk-tree manual>
|
|
2130
|
+
<nk-section-label>Favourites</nk-section-label>
|
|
2131
|
+
<nk-tree-item icon="🚀">NotionKit MVP</nk-tree-item>
|
|
2132
|
+
<nk-tree-item icon="🎙️">Voice-Office-Hub</nk-tree-item>
|
|
2133
|
+
<nk-section-label>Workspace</nk-section-label>
|
|
2134
|
+
<nk-tree-item icon="🧠">Knowledge base</nk-tree-item>
|
|
2135
|
+
<nk-tree-item icon="🗑️">Trash</nk-tree-item>
|
|
2136
|
+
</nk-tree>
|
|
2137
|
+
</nk-sheet>
|
|
2138
|
+
```
|
|
2139
|
+
|
|
2140
|
+
| Attribute | Type | Default | Description |
|
|
2141
|
+
|---|---|---|---|
|
|
2142
|
+
| `open` | boolean | – | Shown. |
|
|
2143
|
+
| `title` | string | – | Heading under the grabber and the dialog’s name – never a tooltip. |
|
|
2144
|
+
|
|
2145
|
+
**Slots:** `(default)` – The content: an `nk-tree`, menu items, fields.
|
|
2146
|
+
|
|
2147
|
+
**Events:** `nk-toggle` `{ open }` – Opened / closed.
|
|
2148
|
+
|
|
2149
|
+
**Properties:** `open`, `title` · **Methods:** `show()`, `close()`, `toggle()`
|
|
2150
|
+
|
|
2151
|
+
**Replaces:** `.nk-sheet-backdrop`, `.open`, `.nk-sheet`, `.sh-grabber`, `.sh-title`
|
|
2152
|
+
|
|
2153
|
+
```html
|
|
2154
|
+
<!-- equivalent class markup -->
|
|
2155
|
+
<div class="nk-sheet-backdrop open"><div class="nk-sheet" role="dialog" aria-modal="true" aria-label="More">
|
|
2156
|
+
<div class="sh-grabber"></div>
|
|
2157
|
+
<div class="sh-title">More</div>
|
|
2158
|
+
<div class="nk-section-label">Favourites</div>
|
|
2159
|
+
<div class="nk-tree-item"><span class="icon">🚀</span><span class="label">NotionKit MVP</span></div>
|
|
2160
|
+
<div class="nk-tree-item"><span class="icon">🎙️</span><span class="label">Voice-Office-Hub</span></div>
|
|
2161
|
+
<div class="nk-section-label">Workspace</div>
|
|
2162
|
+
<div class="nk-tree-item"><span class="icon">🧠</span><span class="label">Knowledge base</span></div>
|
|
2163
|
+
<div class="nk-tree-item"><span class="icon">🗑️</span><span class="label">Trash</span></div>
|
|
2164
|
+
</div></div>
|
|
2165
|
+
```
|
|
2166
|
+
|
|
2167
|
+
**Small screens:** Made for the phone: full width, above the tab bar, bottom padding from the safe area; the content scrolls inside the sheet. On larger screens at most 640px wide, centred.
|
|
2168
|
+
|
|
2169
|
+
### 3.66 `<nk-peek>` – Side peek
|
|
2170
|
+
|
|
2171
|
+
Notion’s side peek: a database row opens at the right edge, full height, next to the table, which stays usable – no scrim, nothing inert. The bar carries » to close and your actions (`slot="actions"`); the body is the page – `nk-page-title` (32px here), `nk-props`, a `.nk-prose`, `nk-comments`. `show()` slides it in and moves focus to it; », Escape and a click elsewhere close it, and a click that calls `show()` again – another row – only swaps the content. Clicks inside other overlays leave it open. Place it directly under `<body>`. `resizable` gives it Notion’s drag on the left edge, `inset` moves the page aside instead of covering it.
|
|
2172
|
+
|
|
2173
|
+
```html
|
|
2174
|
+
<nk-peek open resizable resize-label="Resize" label="Database Table-View">
|
|
2175
|
+
<nk-btn slot="actions" variant="topbar" aria-label="Open as page"><svg viewBox="0 0 24 24" aria-hidden="true"><path d="M15 3h6v6M9 21H3v-6M21 3l-7 7M3 21l7-7"/></svg></nk-btn>
|
|
2176
|
+
<nk-page-title>🗃️ Database Table-View</nk-page-title>
|
|
2177
|
+
<nk-props>
|
|
2178
|
+
<nk-prop label="Status" icon="◉"><nk-tag color="blue">In progress</nk-tag></nk-prop>
|
|
2179
|
+
<nk-prop label="Due" icon="📅">20.05.2026</nk-prop>
|
|
2180
|
+
</nk-props>
|
|
2181
|
+
<div class="nk-prose"><p>Table, board and list read the same rows; filters and sort act on all three.</p></div>
|
|
2182
|
+
</nk-peek>
|
|
2183
|
+
```
|
|
2184
|
+
|
|
2185
|
+
| Attribute | Type | Default | Description |
|
|
2186
|
+
|---|---|---|---|
|
|
2187
|
+
| `open` | boolean | – | Shown. |
|
|
2188
|
+
| `label` | string | – | The dialog’s name – the entry’s title. |
|
|
2189
|
+
| `close-label` | string | `Close` | Name of ». |
|
|
2190
|
+
| `resizable` | boolean | – | The left edge makes it wider or narrower – pointer and arrow keys; the width is the token `--nk-peek-width` on `:root`. |
|
|
2191
|
+
| `width` | px | `560` | Sets the width, within min and max. |
|
|
2192
|
+
| `min` | px | `380` | Narrowest. |
|
|
2193
|
+
| `max` | px | `window − 320` | Widest. |
|
|
2194
|
+
| `resize-label` | string | `Resize` | Name of the edge. |
|
|
2195
|
+
| `inset` | boolean | – | While open on the desktop, the page’s `nk-app` makes room instead of lying under it – for a chart whose bars must stay visible. |
|
|
2196
|
+
|
|
2197
|
+
**Slots:** `(default)` – The page: title, properties, prose, comments. · `actions` – Buttons beside » – open as page, share.
|
|
2198
|
+
|
|
2199
|
+
**Events:** `nk-toggle` `{ open }` – Opened / closed. · `nk-resize` `{ width }` – A drag or a key changed the width – the moment to keep it.
|
|
2200
|
+
|
|
2201
|
+
**Properties:** `open`, `width` · **Methods:** `show()`, `close()`, `toggle()`
|
|
2202
|
+
|
|
2203
|
+
**Replaces:** `.nk-peek-backdrop`, `.open`, `.nk-peek`, `.pk-resize`, `.active`, `.pk-bar`, `.pk-body`
|
|
2204
|
+
|
|
2205
|
+
```html
|
|
2206
|
+
<!-- equivalent class markup -->
|
|
2207
|
+
<div class="nk-peek-backdrop open"><aside class="nk-peek" role="dialog" aria-label="Database Table-View">
|
|
2208
|
+
<div class="pk-resize" role="separator" aria-orientation="vertical" aria-label="Resize" tabindex="0"></div>
|
|
2209
|
+
<div class="pk-bar"><button class="nk-topbar-btn" aria-label="Close"><svg viewBox="0 0 24 24" aria-hidden="true"><path d="m6 17 5-5-5-5M13 17l5-5-5-5"/></svg></button><button class="nk-topbar-btn" aria-label="Open as page"><svg viewBox="0 0 24 24" aria-hidden="true"><path d="M15 3h6v6M9 21H3v-6M21 3l-7 7M3 21l7-7"/></svg></button></div>
|
|
2210
|
+
<div class="pk-body">
|
|
2211
|
+
<h1 class="nk-page-title">🗃️ Database Table-View</h1>
|
|
2212
|
+
<dl class="nk-props">
|
|
2213
|
+
<div class="nk-prop"><dt class="p-name"><span class="p-icon">◉</span>Status</dt><dd class="p-value"><span class="nk-tag blue">In progress</span></dd></div>
|
|
2214
|
+
<div class="nk-prop"><dt class="p-name"><span class="p-icon">📅</span>Due</dt><dd class="p-value">20.05.2026</dd></div>
|
|
2215
|
+
</dl>
|
|
2216
|
+
<div class="nk-prose"><p>Table, board and list read the same rows; filters and sort act on all three.</p></div>
|
|
2217
|
+
</div>
|
|
2218
|
+
</aside></div>
|
|
2219
|
+
```
|
|
2220
|
+
|
|
2221
|
+
**Small screens:** Below 860px a bottom sheet over a dimmed page, title in 28px – and modal there: the page is inert and scroll-locked, a tap on the dimmed page closes it.
|
|
2222
|
+
|
|
2223
|
+
### 3.67 `<nk-dialog>` – Dialog
|
|
2224
|
+
|
|
2225
|
+
A question or a short form – “Move to trash?”, the name of a new view, the link between two tasks – with the contract of `nk-modal` and `nk-sheet`: `show()`, `close()`, `toggle()`, `nk-toggle`; Escape – captured, before a peek, a menu or a modal behind it – and the backdrop close it; focus moves in, to an `[autofocus]` element or the first field or button, and back; the page behind is inert and scroll-locked. It lies above the modal and the sheet. `title` is the heading, the default slot the text or the fields, `slot="actions"` the buttons, the confirming one last. A button in `slot="actions"` with a `value` closes it with that value, one anywhere inside with `data-close` too – another button with a value, an option of `nk-segmented` say, leaves it open – and so does the submit of a `<form method="dialog">` inside; before it closes, `nk-close` fires and can be cancelled – the place to check an input. `alert` for a question, `wide` (560px) for a form. `show(from)` hands focus back to `from` – the ⋯ of a menu that closed. Place it directly under `<body>`.
|
|
2226
|
+
|
|
2227
|
+
```html
|
|
2228
|
+
<nk-dialog open alert title="Move “NotionKit MVP” to trash?">
|
|
2229
|
+
The page and its sub-pages can be restored from Trash for 30 days.
|
|
2230
|
+
<nk-btn slot="actions" variant="secondary" value="">Cancel</nk-btn>
|
|
2231
|
+
<nk-btn slot="actions" variant="danger-solid" value="trash">Move to trash</nk-btn>
|
|
2232
|
+
</nk-dialog>
|
|
2233
|
+
```
|
|
2234
|
+
|
|
2235
|
+
| Attribute | Type | Default | Description |
|
|
2236
|
+
|---|---|---|---|
|
|
2237
|
+
| `open` | boolean | – | Shown. |
|
|
2238
|
+
| `title` | string | – | Heading and the dialog’s name – never a tooltip. |
|
|
2239
|
+
| `alert` | boolean | – | An alertdialog, described by its text. |
|
|
2240
|
+
| `wide` | boolean | – | 560px instead of 440px. |
|
|
2241
|
+
|
|
2242
|
+
**Slots:** `(default)` – The text or the fields. · `actions` – The buttons, right; a `value` closes with it.
|
|
2243
|
+
|
|
2244
|
+
**Events:** `nk-close` `{ value }` – About to close – cancel it to keep it open. · `nk-toggle` `{ open }` – Opened / closed.
|
|
2245
|
+
|
|
2246
|
+
**Properties:** `open`, `returnValue`, `title` · **Methods:** `show(from)`, `close(value)`, `toggle()`
|
|
2247
|
+
|
|
2248
|
+
**Replaces:** `.nk-dialog-backdrop`, `.open`, `.nk-dialog`, `.wide`, `.dl-title`, `.dl-body`, `.dl-actions`
|
|
2249
|
+
|
|
2250
|
+
```html
|
|
2251
|
+
<!-- equivalent class markup -->
|
|
2252
|
+
<div class="nk-dialog-backdrop open"><div class="nk-dialog" role="alertdialog" aria-modal="true" aria-label="Move to trash">
|
|
2253
|
+
<div class="dl-title">Move “NotionKit MVP” to trash?</div>
|
|
2254
|
+
<div class="dl-body">The page and its sub-pages can be restored from Trash for 30 days.</div>
|
|
2255
|
+
<div class="dl-actions"><button class="nk-btn secondary">Cancel</button><button class="nk-btn danger-solid">Move to trash</button></div>
|
|
2256
|
+
</div></div>
|
|
2257
|
+
```
|
|
2258
|
+
|
|
2259
|
+
**Small screens:** Below 860px a bottom sheet with a grabber, the buttons stacked across the width, the confirming one on top.
|
|
2260
|
+
|
|
2261
|
+
### 3.68 `<nk-settings-pane>` – Settings pane
|
|
2262
|
+
|
|
2263
|
+
One pane of the settings modal. `label`, `icon` and `group` feed the modal’s nav; `title` renders the pane heading. Slotted `<h2>`/`<h3>` are styled too.
|
|
2264
|
+
|
|
2265
|
+
```html
|
|
2266
|
+
<nk-settings-pane title="Notifications" active><h3>Email</h3><nk-field label="Email notifications"><nk-switch checked></nk-switch></nk-field></nk-settings-pane>
|
|
2267
|
+
```
|
|
2268
|
+
|
|
2269
|
+
| Attribute | Type | Default | Description |
|
|
2270
|
+
|---|---|---|---|
|
|
2271
|
+
| `name` | string | – | Identifier used by `pane`. |
|
|
2272
|
+
| `label` | string | – | Nav label (a pane without label gets no nav row). |
|
|
2273
|
+
| `icon` | string | – | Nav icon. |
|
|
2274
|
+
| `group` | string | – | Section label above its nav rows. |
|
|
2275
|
+
| `title` | string | – | Pane heading. Read once and taken off the host, so it never shows as a tooltip. |
|
|
2276
|
+
| `active` | boolean | – | Visible (managed by the modal). |
|
|
2277
|
+
|
|
2278
|
+
**Slots:** `(default)` – Fields, headings, anything.
|
|
2279
|
+
|
|
2280
|
+
**Replaces:** `.nk-settings-pane`, `.active`
|
|
2281
|
+
|
|
2282
|
+
```html
|
|
2283
|
+
<!-- equivalent class markup -->
|
|
2284
|
+
<section class="nk-settings-pane active"><h2>Notifications</h2><h3>Email</h3><div class="nk-field"><div><div class="f-label">Email notifications</div></div><div class="f-control"><button class="nk-switch" role="switch" aria-checked="true"></button></div></div></section>
|
|
2285
|
+
```
|
|
2286
|
+
|
|
2287
|
+
**Small screens:** Content padding drops to 24px below 860px.
|
|
2288
|
+
|
|
2289
|
+
### 3.69 `<nk-settings-user>` – Settings user
|
|
2290
|
+
|
|
2291
|
+
The user card at the top of the settings nav.
|
|
2292
|
+
|
|
2293
|
+
```html
|
|
2294
|
+
<div style="background:var(--nk-bg-sidebar);border-radius:8px;max-width:230px;padding:10px 8px"><nk-settings-user name="Marcel Karas" mail="marcel@monahilft.de"></nk-settings-user></div>
|
|
2295
|
+
```
|
|
2296
|
+
|
|
2297
|
+
| Attribute | Type | Default | Description |
|
|
2298
|
+
|---|---|---|---|
|
|
2299
|
+
| `name` | string | – | Name. |
|
|
2300
|
+
| `mail` | string | – | Mail. |
|
|
2301
|
+
| `avatar` | string | – | Initials (default: from the name). |
|
|
2302
|
+
|
|
2303
|
+
**Slots:** `avatar` – Custom avatar.
|
|
2304
|
+
|
|
2305
|
+
**Replaces:** `.nk-settings-user`, `.avatar`, `.u-text`, `.name`, `.mail`
|
|
2306
|
+
|
|
2307
|
+
```html
|
|
2308
|
+
<!-- equivalent class markup -->
|
|
2309
|
+
<div style="background:var(--nk-bg-sidebar);border-radius:8px;max-width:230px;padding:10px 8px"><div class="nk-settings-user"><div class="avatar">MK</div><div class="u-text"><div class="name">Marcel Karas</div><div class="mail">marcel@monahilft.de</div></div></div></div>
|
|
2310
|
+
```
|
|
2311
|
+
|
|
2312
|
+
**Small screens:** Below 860px only the avatar remains.
|
|
2313
|
+
|
|
2314
|
+
### 3.70 `<nk-cmdk>` – Command palette
|
|
2315
|
+
|
|
2316
|
+
⌘K. Feed it `palette.commands = [{ group, items: [{ id, icon, label, shortcut, keywords, action }] }]`; it searches fuzzily over label and keywords, keeps group order, moves the selection with ↑↓, picks with Enter or click (`nk-command` plus the item’s `action`), and closes on Escape or the backdrop. The hotkey is `mod+k` unless changed. Place it directly under `<body>`.
|
|
2317
|
+
|
|
2318
|
+
```html
|
|
2319
|
+
<nk-cmdk open placeholder="Search or type a command …"></nk-cmdk>
|
|
2320
|
+
<script>
|
|
2321
|
+
document.querySelector('nk-cmdk').commands = [
|
|
2322
|
+
{ group: 'Pages', items: [
|
|
2323
|
+
{ id: 'mvp', icon: '🚀', label: 'NotionKit MVP' },
|
|
2324
|
+
{ id: 'voh', icon: '🎙️', label: 'Voice-Office-Hub' },
|
|
2325
|
+
{ id: 'kb', icon: '🧠', label: 'Knowledge base' },
|
|
2326
|
+
]},
|
|
2327
|
+
{ group: 'Actions', items: [
|
|
2328
|
+
{ id: 'new', icon: '+', label: 'Create new page', shortcut: '⌘N' },
|
|
2329
|
+
{ id: 'theme', icon: '🌙', label: 'Toggle theme', shortcut: '⌘⇧L' },
|
|
2330
|
+
{ id: 'settings', icon: '⚙️', label: 'Open settings', shortcut: '⌘,' },
|
|
2331
|
+
]},
|
|
2332
|
+
];
|
|
2333
|
+
</script>
|
|
2334
|
+
```
|
|
2335
|
+
|
|
2336
|
+
| Attribute | Type | Default | Description |
|
|
2337
|
+
|---|---|---|---|
|
|
2338
|
+
| `open` | boolean | – | Shown. |
|
|
2339
|
+
| `hotkey` | string | `mod+k` | Global shortcut, e.g. `mod+k`, `mod+shift+p`. |
|
|
2340
|
+
| `placeholder` | string | – | Input placeholder. |
|
|
2341
|
+
|
|
2342
|
+
**Slots:** `footer` – Replaces the default key hints.
|
|
2343
|
+
|
|
2344
|
+
**Events:** `nk-command` `{ id, item, query }` – An item was picked; `preventDefault()` skips `item.action`. · `nk-toggle` `{ open }` – Opened / closed.
|
|
2345
|
+
|
|
2346
|
+
**Properties:** `commands`, `open`, `query` · **Methods:** `show()`, `close()`, `toggle()`, `results()`, `pick(index?)`
|
|
2347
|
+
|
|
2348
|
+
**Replaces:** `.nk-cmdk-backdrop`, `.open`, `.nk-cmdk`, `.nk-cmdk-input-row`, `.nk-cmdk-list`, `.nk-cmdk-group`, `.nk-cmdk-item`, `.selected`, `.m-icon`, `.m-shortcut`, `.nk-cmdk-empty`, `.nk-cmdk-footer`
|
|
2349
|
+
|
|
2350
|
+
```html
|
|
2351
|
+
<!-- equivalent class markup -->
|
|
2352
|
+
<div class="nk-cmdk-backdrop open"><div class="nk-cmdk">
|
|
2353
|
+
<div class="nk-cmdk-input-row"><span style="font-size:15px">🔍</span><input placeholder="Search or type a command …"><kbd class="nk-kbd">esc</kbd></div>
|
|
2354
|
+
<div class="nk-cmdk-list">
|
|
2355
|
+
<div class="nk-cmdk-group">Pages</div>
|
|
2356
|
+
<div class="nk-cmdk-item selected"><span class="m-icon">🚀</span><span>NotionKit MVP</span></div>
|
|
2357
|
+
<div class="nk-cmdk-item"><span class="m-icon">🎙️</span><span>Voice-Office-Hub</span></div>
|
|
2358
|
+
<div class="nk-cmdk-item"><span class="m-icon">🧠</span><span>Knowledge base</span></div>
|
|
2359
|
+
<div class="nk-cmdk-group">Actions</div>
|
|
2360
|
+
<div class="nk-cmdk-item"><span class="m-icon">+</span><span>Create new page</span><span class="m-shortcut">⌘N</span></div>
|
|
2361
|
+
<div class="nk-cmdk-item"><span class="m-icon">🌙</span><span>Toggle theme</span><span class="m-shortcut">⌘⇧L</span></div>
|
|
2362
|
+
<div class="nk-cmdk-item"><span class="m-icon">⚙️</span><span>Open settings</span><span class="m-shortcut">⌘,</span></div>
|
|
2363
|
+
</div>
|
|
2364
|
+
<div class="nk-cmdk-footer"><span><kbd class="nk-kbd">↑</kbd><kbd class="nk-kbd">↓</kbd> navigate</span><span><kbd class="nk-kbd">↵</kbd> open</span><span><kbd class="nk-kbd">⌘</kbd><kbd class="nk-kbd">K</kbd> toggle</span></div>
|
|
2365
|
+
</div></div>
|
|
2366
|
+
```
|
|
2367
|
+
|
|
2368
|
+
**Small screens:** Full width (96vw) and closer to the top below 860px.
|
|
2369
|
+
|
|
2370
|
+
### 3.71 `<nk-menu>` – Menu
|
|
2371
|
+
|
|
2372
|
+
A 230px context menu. Items are `nk-menu-item`s (`type="separator"` / `"label"` for the rest); ↑↓ move, Enter selects, `nk-select` bubbles up. Inside `nk-pop` or the workspace switcher it is part of their surface. With `floating` it is a menu over the page of its own, NotionKit’s `.nk-pop.floating`: `menu.show(button)` opens it under the button, right edges aligned (`align="start"`: left edges), and it fades in like the palette. A tap outside closes it and reaches nothing else; Escape and a chosen item close it, a switch row keeps it open. Opened from the keyboard, focus moves to the first item and back when it closes. Put it directly under `<body>`, like the other overlays. Floating, it opens upwards where the window ends below and there is more room above, and a menu longer than the room scrolls inside; in an `nk-modal` or `nk-dialog` it sits right as well.
|
|
2373
|
+
|
|
2374
|
+
```html
|
|
2375
|
+
<nk-menu>
|
|
2376
|
+
<nk-menu-item type="label">Page</nk-menu-item>
|
|
2377
|
+
<nk-menu-item icon="✏️" shortcut="⌘E" value="rename">Rename</nk-menu-item>
|
|
2378
|
+
<nk-menu-item icon="📄" shortcut="⌘D" value="duplicate">Duplicate</nk-menu-item>
|
|
2379
|
+
<nk-menu-item icon="📁" value="move">Move to …</nk-menu-item>
|
|
2380
|
+
<nk-menu-item type="separator"></nk-menu-item>
|
|
2381
|
+
<nk-menu-item icon="🗑️" danger value="delete">Delete</nk-menu-item>
|
|
2382
|
+
</nk-menu>
|
|
2383
|
+
```
|
|
2384
|
+
|
|
2385
|
+
| Attribute | Type | Default | Description |
|
|
2386
|
+
|---|---|---|---|
|
|
2387
|
+
| `floating` | boolean | – | A menu over the page: fixed, closed until `open`, fades in. |
|
|
2388
|
+
| `sheet` | boolean | – | Below 860px a bottom sheet (with `floating`). |
|
|
2389
|
+
| `open` | boolean | – | Shown (with `floating`). |
|
|
2390
|
+
| `align` | end | start | `end` | Which edges `show(anchor)` aligns. |
|
|
2391
|
+
|
|
2392
|
+
**Slots:** `(default)` – `nk-menu-item` children.
|
|
2393
|
+
|
|
2394
|
+
**Events:** `nk-select` `{ value, label, item }` – From the chosen item. · `nk-toggle` `{ open }` – A floating menu opened / closed.
|
|
2395
|
+
|
|
2396
|
+
**Properties:** `open`, `items` · **Methods:** `show(anchor?)`, `close()`, `toggle(anchor?)`, `focusFirst()`
|
|
2397
|
+
|
|
2398
|
+
**Replaces:** `.nk-pop`, `.nk-menu`, `.nk-menu-item`, `.m-icon`, `.m-shortcut`, `.danger`, `.nk-menu-sep`, `.nk-menu-label`, `.floating`, `.sheet`, `.open`
|
|
2399
|
+
|
|
2400
|
+
```html
|
|
2401
|
+
<!-- equivalent class markup -->
|
|
2402
|
+
<div class="nk-pop nk-menu">
|
|
2403
|
+
<div class="nk-menu-label">Page</div>
|
|
2404
|
+
<div class="nk-menu-item"><span class="m-icon">✏️</span>Rename<span class="m-shortcut">⌘E</span></div>
|
|
2405
|
+
<div class="nk-menu-item"><span class="m-icon">📄</span>Duplicate<span class="m-shortcut">⌘D</span></div>
|
|
2406
|
+
<div class="nk-menu-item"><span class="m-icon">📁</span>Move to …</div>
|
|
2407
|
+
<div class="nk-menu-sep"></div>
|
|
2408
|
+
<div class="nk-menu-item danger"><span class="m-icon">🗑️</span>Delete</div>
|
|
2409
|
+
</div>
|
|
2410
|
+
```
|
|
2411
|
+
|
|
2412
|
+
**Small screens:** With `sheet` the floating menu is a bottom sheet below 860px – full width, a grabber, 40px rows, the page dimmed – whatever position `show()` wrote: one markup, two presentations, as Notion’s mobile app opens every menu.
|
|
2413
|
+
|
|
2414
|
+
### 3.72 `<nk-menu-item>` – Menu item
|
|
2415
|
+
|
|
2416
|
+
One row of `nk-menu`: icon, label, shortcut; `danger` for destructive actions. `type` switches to a separator or a group label, or to a row with a switch on the right – “Small text” in Notion’s page menu: a click flips `checked` and fires `nk-change`, so the menu stays open. `type="check"` puts a ✓ where the shortcut stands, as in a filter menu – for a choice of several: a click flips `checked` and fires `nk-change { value, checked }` instead of `nk-select`, and the menu stays open.
|
|
2417
|
+
|
|
2418
|
+
```html
|
|
2419
|
+
<nk-menu><nk-menu-item icon="✏️" shortcut="⌘E" value="rename">Rename</nk-menu-item><nk-menu-item type="switch" icon="🔡" value="small" checked>Small text</nk-menu-item></nk-menu>
|
|
2420
|
+
```
|
|
2421
|
+
|
|
2422
|
+
| Attribute | Type | Default | Description |
|
|
2423
|
+
|---|---|---|---|
|
|
2424
|
+
| `icon` | string | – | Leading icon. |
|
|
2425
|
+
| `shortcut` | string | – | Trailing shortcut text. |
|
|
2426
|
+
| `value` | string | – | Reported value (default: text). |
|
|
2427
|
+
| `danger` | boolean | – | Red text. |
|
|
2428
|
+
| `type` | item | separator | label | switch | check | `item` | Row kind. |
|
|
2429
|
+
| `checked` | boolean | – | The switch is on, the check shows (type="switch" / "check"). |
|
|
2430
|
+
| `disabled` | boolean | – | Not selectable. |
|
|
2431
|
+
|
|
2432
|
+
**Slots:** `(default)` – Label. · `icon` – Icon node.
|
|
2433
|
+
|
|
2434
|
+
**Events:** `nk-select` `{ value, label, item }` – Clicked / Enter. · `nk-change` `{ value, checked, item }` – A switch or check row flipped.
|
|
2435
|
+
|
|
2436
|
+
**Replaces:** `.nk-menu-item`, `.danger`, `.nk-menu-sep`, `.nk-menu-label`
|
|
2437
|
+
|
|
2438
|
+
```html
|
|
2439
|
+
<!-- equivalent class markup -->
|
|
2440
|
+
<div class="nk-pop nk-menu"><div class="nk-menu-item"><span class="m-icon">✏️</span>Rename<span class="m-shortcut">⌘E</span></div><div class="nk-menu-item" role="menuitemcheckbox" aria-checked="true"><span class="m-icon">🔡</span>Small text<span class="nk-switch" aria-hidden="true" aria-checked="true"></span></div></div>
|
|
2441
|
+
```
|
|
2442
|
+
|
|
2443
|
+
**Small screens:** Unchanged.
|
|
2444
|
+
|
|
2445
|
+
### 3.73 `<nk-pop>` – Popover
|
|
2446
|
+
|
|
2447
|
+
Anchors a floating surface to a trigger. The trigger goes in `slot="trigger"` and toggles `open`; outside clicks, Escape and an `nk-select` from inside close it. Content is wrapped in `.nk-pop` unless it brings its own surface (`nk-menu`, `nk-emoji-picker`) or `bare` is set.
|
|
2448
|
+
|
|
2449
|
+
```html
|
|
2450
|
+
<div style="min-height:220px"><nk-pop open>
|
|
2451
|
+
<nk-btn slot="trigger" variant="secondary">Options ▾</nk-btn>
|
|
2452
|
+
<nk-menu><nk-menu-item icon="✏️" value="rename">Rename</nk-menu-item><nk-menu-item icon="📄" value="duplicate">Duplicate</nk-menu-item><nk-menu-item type="separator"></nk-menu-item><nk-menu-item icon="🗑️" danger value="delete">Delete</nk-menu-item></nk-menu>
|
|
2453
|
+
</nk-pop></div>
|
|
2454
|
+
```
|
|
2455
|
+
|
|
2456
|
+
| Attribute | Type | Default | Description |
|
|
2457
|
+
|---|---|---|---|
|
|
2458
|
+
| `open` | boolean | – | Shown. |
|
|
2459
|
+
| `placement` | bottom-start | bottom-end | top-start | top-end | `bottom-start` | Where the surface opens. |
|
|
2460
|
+
| `bare` | boolean | – | No `.nk-pop` wrapper. |
|
|
2461
|
+
|
|
2462
|
+
**Slots:** `trigger` – The button. · `(default)` – The floating content.
|
|
2463
|
+
|
|
2464
|
+
**Events:** `nk-toggle` `{ open }` – Opened / closed.
|
|
2465
|
+
|
|
2466
|
+
**Methods:** `show()`, `close()`, `toggle()`
|
|
2467
|
+
|
|
2468
|
+
**Replaces:** `.nk-pop`
|
|
2469
|
+
|
|
2470
|
+
```html
|
|
2471
|
+
<!-- equivalent class markup -->
|
|
2472
|
+
<div style="min-height:220px"><div style="position:relative;display:inline-block">
|
|
2473
|
+
<button class="nk-btn secondary">Options ▾</button>
|
|
2474
|
+
<div style="position:absolute;top:100%;left:0;margin-top:4px;z-index:50"><div class="nk-pop nk-menu"><div class="nk-menu-item"><span class="m-icon">✏️</span>Rename</div><div class="nk-menu-item"><span class="m-icon">📄</span>Duplicate</div><div class="nk-menu-sep"></div><div class="nk-menu-item danger"><span class="m-icon">🗑️</span>Delete</div></div></div>
|
|
2475
|
+
</div></div>
|
|
2476
|
+
```
|
|
2477
|
+
|
|
2478
|
+
**Small screens:** Positioned relative to the trigger; keep it near the viewport edge in mind.
|
|
2479
|
+
|
|
2480
|
+
### 3.74 `<nk-emoji-picker>` – Emoji picker
|
|
2481
|
+
|
|
2482
|
+
Search field, 8-column grid, category strip. Ships with a built-in set (names for search); `picker.emojis = [{ char, name, cat }]` replaces it. A click fires `nk-select { emoji }`.
|
|
2483
|
+
|
|
2484
|
+
```html
|
|
2485
|
+
<nk-emoji-picker placeholder="Search…"></nk-emoji-picker>
|
|
2486
|
+
```
|
|
2487
|
+
|
|
2488
|
+
| Attribute | Type | Default | Description |
|
|
2489
|
+
|---|---|---|---|
|
|
2490
|
+
| `placeholder` | string | – | Search placeholder. |
|
|
2491
|
+
| `value` | string | – | Last picked emoji. |
|
|
2492
|
+
|
|
2493
|
+
**Events:** `nk-select` `{ emoji, value }` – Emoji picked.
|
|
2494
|
+
|
|
2495
|
+
**Properties:** `emojis`, `value`
|
|
2496
|
+
|
|
2497
|
+
**Replaces:** `.nk-pop`, `.nk-emoji-search`, `.nk-emoji-grid`, `.nk-emoji-cats`, `.active`
|
|
2498
|
+
|
|
2499
|
+
```html
|
|
2500
|
+
<!-- equivalent class markup -->
|
|
2501
|
+
<div class="nk-pop"><input class="nk-emoji-search" placeholder="Search…"><div class="nk-emoji-grid"><span>😀</span><span>😊</span><span>😂</span><span>🙂</span><span>😉</span><span>😍</span><span>🤔</span><span>😎</span><span>🥳</span><span>😴</span><span>🤯</span><span>😅</span><span>🙃</span><span>😇</span><span>🤗</span><span>😢</span></div><div class="nk-emoji-cats"><span class="active">😀</span><span>👋</span><span>🌿</span><span>☕</span><span>🎯</span><span>🚀</span><span>💡</span><span>✅</span></div></div>
|
|
2502
|
+
```
|
|
2503
|
+
|
|
2504
|
+
**Small screens:** 296px wide; fine on any phone.
|
|
2505
|
+
|
|
2506
|
+
### 3.75 `<nk-toast>` – Toast
|
|
2507
|
+
|
|
2508
|
+
One inverted pill at the bottom centre, above every overlay; over a tab bar at the bottom of the screen it rises 12px above the bar. `toast.show("Saved")` shows it and hides it after `duration` ms; `open` is the state.
|
|
2509
|
+
|
|
2510
|
+
```html
|
|
2511
|
+
<nk-toast open duration="0">Settings saved</nk-toast>
|
|
2512
|
+
```
|
|
2513
|
+
|
|
2514
|
+
| Attribute | Type | Default | Description |
|
|
2515
|
+
|---|---|---|---|
|
|
2516
|
+
| `open` | boolean | – | Visible. |
|
|
2517
|
+
| `duration` | ms | `2200` | Auto-hide delay (0 = stay). |
|
|
2518
|
+
| `icon` | string | `✓` | Leading glyph. |
|
|
2519
|
+
|
|
2520
|
+
**Slots:** `(default)` – Static content (when `show()` gets no message).
|
|
2521
|
+
|
|
2522
|
+
**Events:** `nk-toggle` `{ open }` – Shown / hidden.
|
|
2523
|
+
|
|
2524
|
+
**Properties:** `open`, `message` · **Methods:** `show(message?, { duration })`, `close()`
|
|
2525
|
+
|
|
2526
|
+
**Replaces:** `.nk-toast`, `.show`
|
|
2527
|
+
|
|
2528
|
+
```html
|
|
2529
|
+
<!-- equivalent class markup -->
|
|
2530
|
+
<div class="nk-toast show">✓ <span>Settings saved</span></div>
|
|
2531
|
+
```
|
|
2532
|
+
|
|
2533
|
+
**Small screens:** Unchanged.
|
|
2534
|
+
|
|
2535
|
+
### 3.76 `<nk-tooltip>` – Tooltip
|
|
2536
|
+
|
|
2537
|
+
Notion’s hover hint in the toast’s colours, a shortcut muted beside it. One `<nk-tooltip>` without `for` serves every element with `data-tooltip` (and `data-tooltip-key`) on the page, inside shadow roots too – a whole toolbar in one element; with `for` it belongs to one element and shows its own content and `shortcut`. It appears after `delay` ms (400) under the pointer and at once on keyboard focus, never on touch; leaving, a press, blur, scrolling and Escape hide it. It sits 6px below its target and centred, above it where the window ends, 8px inside the window – `placeNear` in `util/floating.js`. `show(target, text, shortcut)` takes an element or a rect, for what has no element of its own: the bars of a chart. The target’s `aria-describedby` names it while it shows. Hover the buttons. A tooltip shown with `show(rect, …)` stays until `hide()`, the pointer on another `[data-tooltip]`, a press or Escape; the wheel hides it too, also inside a shadow root. A line break in the text is kept.
|
|
2538
|
+
|
|
2539
|
+
```html
|
|
2540
|
+
<div style="display:flex;gap:16px;align-items:center;padding:4px 0 44px">
|
|
2541
|
+
<nk-btn variant="topbar" aria-label="Style, export and more" data-tooltip="Style, export and more">⋯</nk-btn>
|
|
2542
|
+
<nk-btn variant="topbar" aria-label="Add to Favourites" data-tooltip="Add to Favourites">⭐</nk-btn>
|
|
2543
|
+
<nk-btn variant="topbar" id="ttSidebar" aria-label="Open sidebar">☰</nk-btn>
|
|
2544
|
+
</div>
|
|
2545
|
+
<nk-tooltip></nk-tooltip>
|
|
2546
|
+
<nk-tooltip for="ttSidebar" shortcut="⌘\">Open sidebar</nk-tooltip>
|
|
2547
|
+
```
|
|
2548
|
+
|
|
2549
|
+
| Attribute | Type | Default | Description |
|
|
2550
|
+
|---|---|---|---|
|
|
2551
|
+
| `for` | id | – | The one element it belongs to; without it, every `[data-tooltip]`. |
|
|
2552
|
+
| `shortcut` | string | – | With `for`: the shortcut beside the text. |
|
|
2553
|
+
| `delay` | ms | `400` | Wait under the pointer. |
|
|
2554
|
+
| `placement` | bottom | top | `bottom` | Preferred side. |
|
|
2555
|
+
|
|
2556
|
+
**Slots:** `(default)` – With `for`: the text.
|
|
2557
|
+
|
|
2558
|
+
**Properties:** `open` · **Methods:** `show(target, text, shortcut)`, `hide()`
|
|
2559
|
+
|
|
2560
|
+
**Replaces:** `.nk-tooltip`, `.open`, `.tt-key`
|
|
2561
|
+
|
|
2562
|
+
**Small screens:** No hover on a phone: it shows nothing on touch.
|
|
2563
|
+
|
|
2564
|
+
## Data & collaboration (wave 5)
|
|
2565
|
+
|
|
2566
|
+
### 3.77 `<nk-database>` – Database
|
|
2567
|
+
|
|
2568
|
+
The view switcher with Notion’s toolbar: child views (`nk-table-view`, `nk-board-view`, `nk-list-view`) become the tabs on the left, `slot="tools"` holds the view’s tools on the right – `<nk-btn variant="tool">` for Filter, Sort and search, then “New” – and `slot="filters"` the `nk-filter-bar` under them. `columns` and `rows` are pushed into every view. `view` selects the active one; `count` on a view shows the row count as badge. No fetching: give it data, listen to events.
|
|
2569
|
+
|
|
2570
|
+
```html
|
|
2571
|
+
<nk-database view="table" add-view>
|
|
2572
|
+
<nk-btn slot="tools" variant="tool" active>Filter</nk-btn>
|
|
2573
|
+
<nk-btn slot="tools" variant="tool">Sort</nk-btn>
|
|
2574
|
+
<nk-btn slot="tools" variant="primary" small>New</nk-btn>
|
|
2575
|
+
<nk-table-view name="table" label="▦ Table" count new-row sortable></nk-table-view>
|
|
2576
|
+
<nk-board-view name="board" label="▤ Board" group-by="status" new-row></nk-board-view>
|
|
2577
|
+
</nk-database>
|
|
2578
|
+
<script>{
|
|
2579
|
+
const db = document.currentScript.previousElementSibling;
|
|
2580
|
+
db.columns = [
|
|
2581
|
+
{ key: 'name', label: 'Name', type: 'text', icon: '📄', title: true },
|
|
2582
|
+
{ key: 'status', label: 'Status', type: 'select', icon: '◉', options: [
|
|
2583
|
+
{ value: 'planned', label: 'Planned', color: 'orange' }, { value: 'progress', label: 'In progress', color: 'blue' }, { value: 'done', label: 'Done', color: 'green' } ] },
|
|
2584
|
+
{ key: 'owner', label: 'Owner', type: 'person', icon: '👤' },
|
|
2585
|
+
{ key: 'due', label: 'Due', type: 'date', icon: '📅' },
|
|
2586
|
+
{ key: 'progress', label: 'Progress', type: 'progress', icon: '▰' },
|
|
2587
|
+
{ key: 'effort', label: 'Effort (h)', type: 'number', icon: '#', locale: 'en', format: { minimumFractionDigits: 1 } },
|
|
2588
|
+
];
|
|
2589
|
+
db.rows = [
|
|
2590
|
+
{ id: 1, icon: '🧭', name: 'App shell & sidebar', status: 'done', owner: { name: 'Marcel', initials: 'MK', color: 'purple' }, due: '08.05.2026', progress: 100, effort: 6 },
|
|
2591
|
+
{ 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 },
|
|
2592
|
+
{ 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 },
|
|
2593
|
+
{ id: 4, icon: '▤', name: 'Board view & drag-and-drop', status: 'planned', due: '02.06.2026', progress: 0, effort: 8 },
|
|
2594
|
+
];
|
|
2595
|
+
}</script>
|
|
2596
|
+
```
|
|
2597
|
+
|
|
2598
|
+
| Attribute | Type | Default | Description |
|
|
2599
|
+
|---|---|---|---|
|
|
2600
|
+
| `view` | string | – | Name of the active view. |
|
|
2601
|
+
| `add-view` | boolean | – | Show a + tab (fires `nk-action`). |
|
|
2602
|
+
|
|
2603
|
+
**Slots:** `(default)` – View elements. · `tools` – The tools right of the tabs: `<nk-btn variant="tool">`, a small primary “New”. · `filters` – Under the toolbar: `nk-filter-bar`.
|
|
2604
|
+
|
|
2605
|
+
**Events:** `nk-view-change` `{ view }` – Tab switched. · `nk-action` `{ action: 'add-view' }` – + clicked. · `nk-select / nk-change / nk-action` `(from the views)` – Bubble up from the active view.
|
|
2606
|
+
|
|
2607
|
+
**Properties:** `columns`, `rows`, `view`, `views` · **Methods:** `refresh()`
|
|
2608
|
+
|
|
2609
|
+
**Replaces:** `.nk-database`, `.nk-db-toolbar`, `.nk-db-tabs`, `.nk-db-tab`, `.active`, `.badge`, `.add`, `.tools`
|
|
2610
|
+
|
|
2611
|
+
```html
|
|
2612
|
+
<!-- equivalent class markup -->
|
|
2613
|
+
<div class="nk-database">
|
|
2614
|
+
<div class="nk-db-toolbar">
|
|
2615
|
+
<div class="nk-db-tabs"><span class="nk-db-tab active">▦ Table <span class="badge">4</span></span><span class="nk-db-tab">▤ Board</span><span class="nk-db-tab add">+</span></div>
|
|
2616
|
+
<div class="tools"><button class="nk-db-tool active">Filter</button><button class="nk-db-tool">Sort</button><button class="nk-btn primary small">New</button></div>
|
|
2617
|
+
</div>
|
|
2618
|
+
<div class="nk-table-wrap"><table class="nk-table">
|
|
2619
|
+
<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></tr></thead>
|
|
2620
|
+
<tbody>
|
|
2621
|
+
<tr><td><span class="row-title">🧭 App shell & sidebar</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></tr>
|
|
2622
|
+
<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></tr>
|
|
2623
|
+
<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></tr>
|
|
2624
|
+
<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></tr>
|
|
2625
|
+
</tbody>
|
|
2626
|
+
</table><div class="nk-new-row">+ New page</div></div>
|
|
2627
|
+
</div>
|
|
2628
|
+
```
|
|
2629
|
+
|
|
2630
|
+
**Small screens:** The tabs scroll sideways when the row gets narrow; the tools keep their place. Tables and boards scroll horizontally; nothing breaks.
|
|
2631
|
+
|
|
2632
|
+
### 3.78 `<nk-table-view>` – Table view
|
|
2633
|
+
|
|
2634
|
+
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.
|
|
2635
|
+
|
|
2636
|
+
```html
|
|
2637
|
+
<nk-table-view new-row sortable></nk-table-view>
|
|
2638
|
+
<script>{
|
|
2639
|
+
const db = document.currentScript.previousElementSibling;
|
|
2640
|
+
db.columns = [
|
|
2641
|
+
{ key: 'name', label: 'Name', type: 'text', icon: '📄', title: true },
|
|
2642
|
+
{ key: 'status', label: 'Status', type: 'select', icon: '◉', options: [
|
|
2643
|
+
{ value: 'planned', label: 'Planned', color: 'orange' }, { value: 'progress', label: 'In progress', color: 'blue' }, { value: 'done', label: 'Done', color: 'green' } ] },
|
|
2644
|
+
{ key: 'owner', label: 'Owner', type: 'person', icon: '👤' },
|
|
2645
|
+
{ key: 'due', label: 'Due', type: 'date', icon: '📅' },
|
|
2646
|
+
{ key: 'progress', label: 'Progress', type: 'progress', icon: '▰' },
|
|
2647
|
+
{ key: 'effort', label: 'Effort (h)', type: 'number', icon: '#', locale: 'en', format: { minimumFractionDigits: 1 } },
|
|
2648
|
+
];
|
|
2649
|
+
db.rows = [
|
|
2650
|
+
{ id: 1, icon: '🧭', name: 'App shell & sidebar', status: 'done', owner: { name: 'Marcel', initials: 'MK', color: 'purple' }, due: '08.05.2026', progress: 100, effort: 6 },
|
|
2651
|
+
{ 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 },
|
|
2652
|
+
{ 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 },
|
|
2653
|
+
{ id: 4, icon: '▤', name: 'Board view & drag-and-drop', status: 'planned', due: '02.06.2026', progress: 0, effort: 8 },
|
|
2654
|
+
];
|
|
2655
|
+
}</script>
|
|
2656
|
+
```
|
|
2657
|
+
|
|
2658
|
+
| Attribute | Type | Default | Description |
|
|
2659
|
+
|---|---|---|---|
|
|
2660
|
+
| `name` | string | – | View name (tab id). |
|
|
2661
|
+
| `label` | string | – | Tab label. |
|
|
2662
|
+
| `badge` | string | – | Tab badge. |
|
|
2663
|
+
| `count` | boolean | – | Row count as badge. |
|
|
2664
|
+
| `new-row` | boolean | – | Show the add row. |
|
|
2665
|
+
| `new-row-label` | string | `+ New page` | Its text. |
|
|
2666
|
+
| `sortable` | boolean | – | Header click sorts locally. |
|
|
2667
|
+
| `sort-key` | string | – | Sorted column. |
|
|
2668
|
+
| `sort-dir` | asc | desc | – | Direction. |
|
|
2669
|
+
| `wrap` | boolean | – | Cell text may break (Notion's "wrap column"). |
|
|
2670
|
+
|
|
2671
|
+
**Events:** `nk-select` `{ row, id }` – Row clicked. · `nk-change` `{ row, key, value }` – Checkbox cell toggled (row updated in place). · `nk-action` `{ action: 'sort' | 'new-row', key?, value? }` – Header or add row clicked.
|
|
2672
|
+
|
|
2673
|
+
**Properties:** `columns`, `rows`, `data` · **Methods:** `refresh()`
|
|
2674
|
+
|
|
2675
|
+
**Replaces:** `.nk-table-wrap`, `.nk-table`, `.wrap`, `.th-icon`, `.row-title`, `.date-cell`, `.person-cell`, `.nk-avatar`, `.num`, `.nk-new-row`
|
|
2676
|
+
|
|
2677
|
+
```html
|
|
2678
|
+
<!-- equivalent class markup -->
|
|
2679
|
+
<div class="nk-table-wrap"><table class="nk-table">
|
|
2680
|
+
<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></tr></thead>
|
|
2681
|
+
<tbody>
|
|
2682
|
+
<tr><td><span class="row-title">🧭 App shell & sidebar</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></tr>
|
|
2683
|
+
<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></tr>
|
|
2684
|
+
<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></tr>
|
|
2685
|
+
<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></tr>
|
|
2686
|
+
</tbody>
|
|
2687
|
+
</table><div class="nk-new-row">+ New page</div></div>
|
|
2688
|
+
```
|
|
2689
|
+
|
|
2690
|
+
**Small screens:** Scrolls horizontally inside `.nk-table-wrap`.
|
|
2691
|
+
|
|
2692
|
+
### 3.79 `<nk-board-view>` – Board view
|
|
2693
|
+
|
|
2694
|
+
Groups rows by a select column (`group-by`, default: the first select column) into one column per option. Cards show the title column and the `meta-keys` (default: dates and progress). Drag a card onto another column: the row’s value changes and `nk-change` fires.
|
|
2695
|
+
|
|
2696
|
+
```html
|
|
2697
|
+
<nk-board-view group-by="status" new-row></nk-board-view>
|
|
2698
|
+
<script>{
|
|
2699
|
+
const db = document.currentScript.previousElementSibling;
|
|
2700
|
+
db.columns = [
|
|
2701
|
+
{ key: 'name', label: 'Name', type: 'text', icon: '📄', title: true },
|
|
2702
|
+
{ key: 'status', label: 'Status', type: 'select', icon: '◉', options: [
|
|
2703
|
+
{ value: 'planned', label: 'Planned', color: 'orange' }, { value: 'progress', label: 'In progress', color: 'blue' }, { value: 'done', label: 'Done', color: 'green' } ] },
|
|
2704
|
+
{ key: 'owner', label: 'Owner', type: 'person', icon: '👤' },
|
|
2705
|
+
{ key: 'due', label: 'Due', type: 'date', icon: '📅' },
|
|
2706
|
+
{ key: 'progress', label: 'Progress', type: 'progress', icon: '▰' },
|
|
2707
|
+
{ key: 'effort', label: 'Effort (h)', type: 'number', icon: '#', locale: 'en', format: { minimumFractionDigits: 1 } },
|
|
2708
|
+
];
|
|
2709
|
+
db.rows = [
|
|
2710
|
+
{ id: 1, icon: '🧭', name: 'App shell & sidebar', status: 'done', owner: { name: 'Marcel', initials: 'MK', color: 'purple' }, due: '08.05.2026', progress: 100, effort: 6 },
|
|
2711
|
+
{ 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 },
|
|
2712
|
+
{ 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 },
|
|
2713
|
+
{ id: 4, icon: '▤', name: 'Board view & drag-and-drop', status: 'planned', due: '02.06.2026', progress: 0, effort: 8 },
|
|
2714
|
+
];
|
|
2715
|
+
}</script>
|
|
2716
|
+
```
|
|
2717
|
+
|
|
2718
|
+
| Attribute | Type | Default | Description |
|
|
2719
|
+
|---|---|---|---|
|
|
2720
|
+
| `name` | string | – | View name. |
|
|
2721
|
+
| `label` | string | – | Tab label. |
|
|
2722
|
+
| `group-by` | string | – | Select column key. |
|
|
2723
|
+
| `title-key` | string | – | Card title column. |
|
|
2724
|
+
| `meta-keys` | list | – | Comma-separated meta columns. |
|
|
2725
|
+
| `new-row` | boolean | – | Show + per column. |
|
|
2726
|
+
|
|
2727
|
+
**Events:** `nk-select` `{ row, id }` – Card clicked. · `nk-change` `{ row, key, value }` – Card dropped into another column. · `nk-action` `{ action: 'new-row', value }` – + clicked (value = column).
|
|
2728
|
+
|
|
2729
|
+
**Properties:** `columns`, `rows`, `data` · **Methods:** `move(id, value)`, `refresh()`
|
|
2730
|
+
|
|
2731
|
+
**Replaces:** `.nk-board`, `.active`, `.nk-board-col`, `.nk-board-col-header`, `.count`, `.nk-card`, `.card-title`, `.card-meta`
|
|
2732
|
+
|
|
2733
|
+
```html
|
|
2734
|
+
<!-- equivalent class markup -->
|
|
2735
|
+
<div class="nk-board active">
|
|
2736
|
+
<div class="nk-board-col"><div class="nk-board-col-header"><span class="nk-tag orange">Planned</span><span class="count">1</span></div><div class="nk-card" draggable="true"><div class="card-title">▤ Board view & drag-and-drop</div><div class="card-meta"><span>📅 02.06.2026</span><span>▰ 0%</span></div></div><div class="nk-new-row" style="padding:6px 10px">+</div></div>
|
|
2737
|
+
<div class="nk-board-col"><div class="nk-board-col-header"><span class="nk-tag blue">In progress</span><span class="count">1</span></div><div class="nk-card" draggable="true"><div class="card-title">🗃️ Database table view</div><div class="card-meta"><span>📅 20.05.2026</span><span>▰ 65%</span></div></div><div class="nk-new-row" style="padding:6px 10px">+</div></div>
|
|
2738
|
+
<div class="nk-board-col"><div class="nk-board-col-header"><span class="nk-tag green">Done</span><span class="count">2</span></div><div class="nk-card" draggable="true"><div class="card-title">🧭 App shell & sidebar</div><div class="card-meta"><span>📅 08.05.2026</span><span>▰ 100%</span></div></div><div class="nk-card" draggable="true"><div class="card-title">📄 Page shell & typography</div><div class="card-meta"><span>📅 10.05.2026</span><span>▰ 100%</span></div></div><div class="nk-new-row" style="padding:6px 10px">+</div></div>
|
|
2739
|
+
</div>
|
|
2740
|
+
```
|
|
2741
|
+
|
|
2742
|
+
**Small screens:** Columns scroll horizontally.
|
|
2743
|
+
|
|
2744
|
+
### 3.80 `<nk-list-view>` – List view
|
|
2745
|
+
|
|
2746
|
+
The third database view: one line per row – icon and title, the `meta-keys` on the right (default: the select and date columns, in column order). Dates and text stand as text, selects as tags, a person as avatar and name. Rows fire `nk-select`; `new-row` adds the add row.
|
|
2747
|
+
|
|
2748
|
+
```html
|
|
2749
|
+
<nk-list-view meta-keys="due,status"></nk-list-view>
|
|
2750
|
+
<script>{
|
|
2751
|
+
const db = document.currentScript.previousElementSibling;
|
|
2752
|
+
db.columns = [
|
|
2753
|
+
{ key: 'name', label: 'Name', type: 'text', icon: '📄', title: true },
|
|
2754
|
+
{ key: 'status', label: 'Status', type: 'select', icon: '◉', options: [
|
|
2755
|
+
{ value: 'planned', label: 'Planned', color: 'orange' }, { value: 'progress', label: 'In progress', color: 'blue' }, { value: 'done', label: 'Done', color: 'green' } ] },
|
|
2756
|
+
{ key: 'owner', label: 'Owner', type: 'person', icon: '👤' },
|
|
2757
|
+
{ key: 'due', label: 'Due', type: 'date', icon: '📅' },
|
|
2758
|
+
{ key: 'progress', label: 'Progress', type: 'progress', icon: '▰' },
|
|
2759
|
+
{ key: 'effort', label: 'Effort (h)', type: 'number', icon: '#', locale: 'en', format: { minimumFractionDigits: 1 } },
|
|
2760
|
+
];
|
|
2761
|
+
db.rows = [
|
|
2762
|
+
{ id: 1, icon: '🧭', name: 'App shell & sidebar', status: 'done', owner: { name: 'Marcel', initials: 'MK', color: 'purple' }, due: '08.05.2026', progress: 100, effort: 6 },
|
|
2763
|
+
{ 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 },
|
|
2764
|
+
{ 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 },
|
|
2765
|
+
{ id: 4, icon: '▤', name: 'Board view & drag-and-drop', status: 'planned', due: '02.06.2026', progress: 0, effort: 8 },
|
|
2766
|
+
];
|
|
2767
|
+
}</script>
|
|
2768
|
+
```
|
|
2769
|
+
|
|
2770
|
+
| Attribute | Type | Default | Description |
|
|
2771
|
+
|---|---|---|---|
|
|
2772
|
+
| `name` | string | – | View name. |
|
|
2773
|
+
| `label` | string | – | Tab label. |
|
|
2774
|
+
| `title-key` | string | – | Title column. |
|
|
2775
|
+
| `meta-keys` | list | – | Comma-separated columns on the right. |
|
|
2776
|
+
| `new-row` | boolean | – | Show the add row. |
|
|
2777
|
+
| `new-row-label` | string | `+ New page` | Its text. |
|
|
2778
|
+
|
|
2779
|
+
**Events:** `nk-select` `{ row, id }` – Row clicked or Enter. · `nk-action` `{ action: 'new-row' }` – Add row clicked.
|
|
2780
|
+
|
|
2781
|
+
**Properties:** `columns`, `rows`, `data` · **Methods:** `refresh()`
|
|
2782
|
+
|
|
2783
|
+
**Replaces:** `.nk-list`, `.nk-list-item`, `.l-icon`, `.l-title`, `.l-meta`
|
|
2784
|
+
|
|
2785
|
+
```html
|
|
2786
|
+
<!-- equivalent class markup -->
|
|
2787
|
+
<div class="nk-list">
|
|
2788
|
+
<div class="nk-list-item"><span class="l-icon">🧭</span><span class="l-title">App shell & sidebar</span><span class="l-meta">08.05.2026<span class="nk-tag green">Done</span></span></div>
|
|
2789
|
+
<div class="nk-list-item"><span class="l-icon">📄</span><span class="l-title">Page shell & typography</span><span class="l-meta">10.05.2026<span class="nk-tag green">Done</span></span></div>
|
|
2790
|
+
<div class="nk-list-item"><span class="l-icon">🗃️</span><span class="l-title">Database table view</span><span class="l-meta">20.05.2026<span class="nk-tag blue">In progress</span></span></div>
|
|
2791
|
+
<div class="nk-list-item"><span class="l-icon">▤</span><span class="l-title">Board view & drag-and-drop</span><span class="l-meta">02.06.2026<span class="nk-tag orange">Planned</span></span></div>
|
|
2792
|
+
</div>
|
|
2793
|
+
```
|
|
2794
|
+
|
|
2795
|
+
**Small screens:** Stays one line per row: the title ends in an ellipsis, the properties keep their place.
|
|
2796
|
+
|
|
2797
|
+
### 3.81 `<nk-calendar-view>` – Calendar view
|
|
2798
|
+
|
|
2799
|
+
The fourth database view (NotionKit 1.9.0): a month, the rows as cards on their dates. `date-key` names the date column (default: the first one) – `YYYY-MM-DD` or `D.M.YYYY`, a range on its start. Today sits on a red pill, days of other months are washed; `weeks` puts the calendar week in front, `weekend` washes the days not worked. A card fires `nk-select` like a row of the table; Today and ‹ › change the month (`nk-month`). In `nk-database` it is a tab like the others and shows the same rows.
|
|
2800
|
+
|
|
2801
|
+
```html
|
|
2802
|
+
<nk-calendar-view date-key="due" month="2026-05" today="2026-05-20" weeks week-start="1" today-label="Today"></nk-calendar-view>
|
|
2803
|
+
<script>{
|
|
2804
|
+
const db = document.currentScript.previousElementSibling;
|
|
2805
|
+
db.columns = [
|
|
2806
|
+
{ key: 'name', label: 'Name', type: 'text', icon: '📄', title: true },
|
|
2807
|
+
{ key: 'status', label: 'Status', type: 'select', icon: '◉', options: [
|
|
2808
|
+
{ value: 'planned', label: 'Planned', color: 'orange' }, { value: 'progress', label: 'In progress', color: 'blue' }, { value: 'done', label: 'Done', color: 'green' } ] },
|
|
2809
|
+
{ key: 'owner', label: 'Owner', type: 'person', icon: '👤' },
|
|
2810
|
+
{ key: 'due', label: 'Due', type: 'date', icon: '📅' },
|
|
2811
|
+
{ key: 'progress', label: 'Progress', type: 'progress', icon: '▰' },
|
|
2812
|
+
{ key: 'effort', label: 'Effort (h)', type: 'number', icon: '#', locale: 'en', format: { minimumFractionDigits: 1 } },
|
|
2813
|
+
];
|
|
2814
|
+
db.rows = [
|
|
2815
|
+
{ id: 1, icon: '🧭', name: 'App shell & sidebar', status: 'done', owner: { name: 'Marcel', initials: 'MK', color: 'purple' }, due: '08.05.2026', progress: 100, effort: 6 },
|
|
2816
|
+
{ 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 },
|
|
2817
|
+
{ 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 },
|
|
2818
|
+
{ id: 4, icon: '▤', name: 'Board view & drag-and-drop', status: 'planned', due: '02.06.2026', progress: 0, effort: 8 },
|
|
2819
|
+
];
|
|
2820
|
+
}</script>
|
|
2821
|
+
```
|
|
2822
|
+
|
|
2823
|
+
| Attribute | Type | Default | Description |
|
|
2824
|
+
|---|---|---|---|
|
|
2825
|
+
| `name` | string | `calendar` | View name. |
|
|
2826
|
+
| `label` | string | – | Tab label. |
|
|
2827
|
+
| `date-key` | string | – | Date column. |
|
|
2828
|
+
| `title-key` | string | – | Title column. |
|
|
2829
|
+
| `month` | YYYY-MM | – | The month shown; default today’s. |
|
|
2830
|
+
| `weeks` | boolean | – | The ISO calendar week in front of each row. |
|
|
2831
|
+
| `week-start` | 0–6 | `Intl` | First day of the week: 0 Sunday, 1 Monday … |
|
|
2832
|
+
| `weekend` | list | – | Weekdays not worked, washed – `6,0`. |
|
|
2833
|
+
| `today` | YYYY-MM-DD | – | Another today – for tests and docs. |
|
|
2834
|
+
| `locale` | BCP 47 | `lang` | Language of the names and the week. |
|
|
2835
|
+
| `today-label` | string | `Today` | Today button. |
|
|
2836
|
+
| `prev-label` | string | `Previous month` | Names ‹. |
|
|
2837
|
+
| `next-label` | string | `Next month` | Names ›. |
|
|
2838
|
+
| `week-label` | string | `W · KW` | Head of the week column. |
|
|
2839
|
+
|
|
2840
|
+
**Events:** `nk-select` `{ row, id }` – Card clicked or Enter. · `nk-month` `{ month }` – Another month shown.
|
|
2841
|
+
|
|
2842
|
+
**Properties:** `columns`, `rows`, `data`, `month` · **Methods:** `refresh()`
|
|
2843
|
+
|
|
2844
|
+
**Replaces:** `.nk-calendar-view`, `.weeks`, `.cv-head`, `.cv-title`, `.cal-nav`, `.cv-grid`, `.cv-wd`, `.cv-week`, `.cv-day`, `.out`, `.off`, `.today`, `.cv-num`, `.cv-item`
|
|
2845
|
+
|
|
2846
|
+
```html
|
|
2847
|
+
<!-- equivalent class markup -->
|
|
2848
|
+
<div class="nk-calendar-view weeks">
|
|
2849
|
+
<div class="cv-head"><div class="cv-title">May 2026</div><button class="cal-nav">Today</button><button class="cal-nav" aria-label="Previous month"><svg viewBox="0 0 24 24" aria-hidden="true"><path d="M15 6l-6 6 6 6"/></svg></button><button class="cal-nav" aria-label="Next month"><svg viewBox="0 0 24 24" aria-hidden="true"><path d="M9 6l6 6-6 6"/></svg></button></div>
|
|
2850
|
+
<div class="cv-grid">
|
|
2851
|
+
<div class="cv-wd">W</div><div class="cv-wd">Mon</div><div class="cv-wd">Tue</div><div class="cv-wd">Wed</div><div class="cv-wd">Thu</div><div class="cv-wd">Fri</div><div class="cv-wd">Sat</div><div class="cv-wd">Sun</div>
|
|
2852
|
+
<div class="cv-week">18</div><div class="cv-day out"><span class="cv-num">27</span></div><div class="cv-day out"><span class="cv-num">28</span></div><div class="cv-day out"><span class="cv-num">29</span></div><div class="cv-day out"><span class="cv-num">30</span></div><div class="cv-day"><span class="cv-num">1</span></div><div class="cv-day"><span class="cv-num">2</span></div><div class="cv-day"><span class="cv-num">3</span></div>
|
|
2853
|
+
<div class="cv-week">19</div><div class="cv-day"><span class="cv-num">4</span></div><div class="cv-day"><span class="cv-num">5</span></div><div class="cv-day"><span class="cv-num">6</span></div><div class="cv-day"><span class="cv-num">7</span></div><div class="cv-day"><span class="cv-num">8</span><button class="cv-item">🧭 App shell & sidebar</button></div><div class="cv-day"><span class="cv-num">9</span></div><div class="cv-day"><span class="cv-num">10</span><button class="cv-item">📄 Page shell & typography</button></div>
|
|
2854
|
+
<div class="cv-week">20</div><div class="cv-day"><span class="cv-num">11</span></div><div class="cv-day"><span class="cv-num">12</span></div><div class="cv-day"><span class="cv-num">13</span></div><div class="cv-day"><span class="cv-num">14</span></div><div class="cv-day"><span class="cv-num">15</span></div><div class="cv-day"><span class="cv-num">16</span></div><div class="cv-day"><span class="cv-num">17</span></div>
|
|
2855
|
+
<div class="cv-week">21</div><div class="cv-day"><span class="cv-num">18</span></div><div class="cv-day"><span class="cv-num">19</span></div><div class="cv-day today"><span class="cv-num">20</span><button class="cv-item">🗃️ Database table view</button></div><div class="cv-day"><span class="cv-num">21</span></div><div class="cv-day"><span class="cv-num">22</span></div><div class="cv-day"><span class="cv-num">23</span></div><div class="cv-day"><span class="cv-num">24</span></div>
|
|
2856
|
+
<div class="cv-week">22</div><div class="cv-day"><span class="cv-num">25</span></div><div class="cv-day"><span class="cv-num">26</span></div><div class="cv-day"><span class="cv-num">27</span></div><div class="cv-day"><span class="cv-num">28</span></div><div class="cv-day"><span class="cv-num">29</span></div><div class="cv-day"><span class="cv-num">30</span></div><div class="cv-day"><span class="cv-num">31</span></div>
|
|
2857
|
+
</div>
|
|
2858
|
+
</div>
|
|
2859
|
+
```
|
|
2860
|
+
|
|
2861
|
+
**Small screens:** Keeps seven columns; the days get lower (64px) and the cards smaller.
|
|
2862
|
+
|
|
2863
|
+
### 3.82 `<nk-filter-bar>` – Filter bar
|
|
2864
|
+
|
|
2865
|
+
The filters in effect as NotionKit’s filter pills – `.active` with an accent tint, a × to remove each, a quiet `add` pill at the end – with no inline style. In `slot="filters"` of `nk-database` the row sits under the toolbar. A pill’s label fires `nk-action { action: "edit" }`, the add pill `{ action: "add" }`, each with the clicked button as `anchor` for `menu.show(anchor)`. `bar.apply(rows)` keeps rows where every filter matches by strict equality (`row[key] === value`, so use the option value) – or differs with `op: "is-not"` – and the search text appears in any string field (a person’s `name`); the data logic stays yours. Its own Filter and Sort tools and the search field are there for a bar without a database toolbar. It keeps its own copy of `filters`: the array you pass is never changed, a removed pill is reported in `nk-change`.
|
|
2866
|
+
|
|
2867
|
+
```html
|
|
2868
|
+
<nk-filter-bar add no-filter no-sort remove-label="Remove filter"></nk-filter-bar>
|
|
2869
|
+
<script>{ document.currentScript.previousElementSibling.filters = [{ key: 'status', value: 'done', op: 'is-not', label: 'Status: Open' }]; }</script>
|
|
2870
|
+
```
|
|
2871
|
+
|
|
2872
|
+
| Attribute | Type | Default | Description |
|
|
2873
|
+
|---|---|---|---|
|
|
2874
|
+
| `add` | boolean | – | Show the add pill. |
|
|
2875
|
+
| `add-label` | string | `+ Filter` | Its text. |
|
|
2876
|
+
| `no-filter` | boolean | – | Hide the Filter tool. |
|
|
2877
|
+
| `no-sort` | boolean | – | Hide the Sort tool. |
|
|
2878
|
+
| `filter-label` | string | `Filter` | Text of the Filter tool. |
|
|
2879
|
+
| `sort-label` | string | `Sort` | Text of the Sort tool. |
|
|
2880
|
+
| `remove-label` | string | `Remove filter` | The ×’s name, followed by the pill’s text. |
|
|
2881
|
+
| `search` | boolean | – | Show the search field. |
|
|
2882
|
+
| `placeholder` | string | – | Search placeholder. |
|
|
2883
|
+
|
|
2884
|
+
**Slots:** `(default)` – Extra pills or controls between the pills and the search.
|
|
2885
|
+
|
|
2886
|
+
**Events:** `nk-change` `{ filters, search }` – A filter removed or the search typed. · `nk-action` `{ action: 'edit' | 'add' | 'filter' | 'sort', index?, filter?, anchor }` – A pill or a tool clicked.
|
|
2887
|
+
|
|
2888
|
+
**Properties:** `filters`, `value` · **Methods:** `apply(rows)`
|
|
2889
|
+
|
|
2890
|
+
**Replaces:** `.nk-filter-row`, `.nk-filter-pill`, `.active`, `.add`, `.fp-remove`, `.nk-db-tool`, `.nk-input`
|
|
2891
|
+
|
|
2892
|
+
```html
|
|
2893
|
+
<!-- equivalent class markup -->
|
|
2894
|
+
<div class="nk-filter-row"><span class="nk-filter-pill active"><button>Status: Open</button><button class="fp-remove" aria-label="Remove filter">×</button></span><button class="nk-filter-pill add">+ Filter</button></div>
|
|
2895
|
+
```
|
|
2896
|
+
|
|
2897
|
+
**Small screens:** The pills wrap onto further rows.
|
|
2898
|
+
|
|
2899
|
+
### 3.83 `<nk-comments>` – Comment thread
|
|
2900
|
+
|
|
2901
|
+
A left-ruled thread of `nk-comment`s with an input row. Enter or the button fires `nk-submit { text }`; appending the new comment is yours.
|
|
2902
|
+
|
|
2903
|
+
```html
|
|
2904
|
+
<nk-comments placeholder="Comment …" send-label="Send">
|
|
2905
|
+
<nk-comment author="Sara Lindt" time="1 hr ago" color="#448361">The board view already feels very close to the original. 👍</nk-comment>
|
|
2906
|
+
<nk-comment author="Mona" time="20 min ago" avatar="✨" color="var(--nk-text-tertiary)"><span slot="head" class="nk-tag blue" style="font-size:10.5px">AI</span>I have flagged the overdue entries and prepared a summary.</nk-comment>
|
|
2907
|
+
</nk-comments>
|
|
2908
|
+
```
|
|
2909
|
+
|
|
2910
|
+
| Attribute | Type | Default | Description |
|
|
2911
|
+
|---|---|---|---|
|
|
2912
|
+
| `placeholder` | string | – | Input placeholder. |
|
|
2913
|
+
| `send-label` | string | `Send` | Button text. |
|
|
2914
|
+
| `no-input` | boolean | – | Read-only thread. |
|
|
2915
|
+
| `disabled` | boolean | – | Input disabled. |
|
|
2916
|
+
|
|
2917
|
+
**Slots:** `(default)` – `nk-comment` children.
|
|
2918
|
+
|
|
2919
|
+
**Events:** `nk-submit` `{ text }` – New comment typed; `preventDefault()` keeps the text.
|
|
2920
|
+
|
|
2921
|
+
**Properties:** `value` · **Methods:** `submit()`, `focus()`
|
|
2922
|
+
|
|
2923
|
+
**Replaces:** `.nk-comments`, `.nk-comment`, `.mini-avatar`, `.c-head`, `.c-body`, `.nk-comment-input`
|
|
2924
|
+
|
|
2925
|
+
```html
|
|
2926
|
+
<!-- equivalent class markup -->
|
|
2927
|
+
<div class="nk-comments">
|
|
2928
|
+
<div class="nk-comment"><span class="mini-avatar" style="background:#448361">SL</span><div><div class="c-head"><b>Sara Lindt</b> · 1 hr ago</div><div class="c-body">The board view already feels very close to the original. 👍</div></div></div>
|
|
2929
|
+
<div class="nk-comment"><span class="mini-avatar" style="background:var(--nk-text-tertiary)">✨</span><div><div class="c-head"><b>Mona</b><span class="nk-tag blue" style="font-size:10.5px">AI</span> · 20 min ago</div><div class="c-body">I have flagged the overdue entries and prepared a summary.</div></div></div>
|
|
2930
|
+
<div class="nk-comment-input"><input class="nk-input" placeholder="Comment …"><button class="nk-btn primary small">Send</button></div>
|
|
2931
|
+
</div>
|
|
2932
|
+
```
|
|
2933
|
+
|
|
2934
|
+
**Small screens:** Unchanged.
|
|
2935
|
+
|
|
2936
|
+
### 3.84 `<nk-comment>` – Comment
|
|
2937
|
+
|
|
2938
|
+
One comment: avatar (initials + `color`), bold author, time, body. `slot="head"` adds content after the name.
|
|
2939
|
+
|
|
2940
|
+
```html
|
|
2941
|
+
<nk-comments no-input><nk-comment author="Sara Lindt" time="1 hr ago" color="green">The board view already feels very close to the original. 👍</nk-comment></nk-comments>
|
|
2942
|
+
```
|
|
2943
|
+
|
|
2944
|
+
| Attribute | Type | Default | Description |
|
|
2945
|
+
|---|---|---|---|
|
|
2946
|
+
| `author` | string | – | Name. |
|
|
2947
|
+
| `time` | string | – | Relative time. |
|
|
2948
|
+
| `avatar` | string | – | Initials/emoji (default: from the author). |
|
|
2949
|
+
| `color` | colour name | CSS | – | Avatar colour: one of the nine names or any CSS background; without it the avatar gradient. |
|
|
2950
|
+
|
|
2951
|
+
**Slots:** `(default)` – Body. · `head` – After the name (tag, badge). · `avatar` – Custom avatar.
|
|
2952
|
+
|
|
2953
|
+
**Replaces:** `.nk-comment`, `.c-head`, `.c-body`
|
|
2954
|
+
|
|
2955
|
+
```html
|
|
2956
|
+
<!-- equivalent class markup -->
|
|
2957
|
+
<div class="nk-comments"><div class="nk-comment"><span class="nk-avatar green">SL</span><div><div class="c-head"><b>Sara Lindt</b> · 1 hr ago</div><div class="c-body">The board view already feels very close to the original. 👍</div></div></div></div>
|
|
2958
|
+
```
|
|
2959
|
+
|
|
2960
|
+
**Small screens:** Unchanged.
|
|
2961
|
+
|
|
2962
|
+
### 3.85 `<nk-ai-thread>` – AI thread
|
|
2963
|
+
|
|
2964
|
+
The conversation column: `nk-ai-msg` children (`role="user"` gets the gradient avatar), followed by an `nk-ai-input-row`. Action buttons in `slot="actions"` fire `nk-action { action, value }` – both carry the button’s `value` (or its text).
|
|
2965
|
+
|
|
2966
|
+
```html
|
|
2967
|
+
<nk-ai-thread>
|
|
2968
|
+
<nk-ai-msg role="user" name="You" avatar="MK">Summarise the open tasks for this project.</nk-ai-msg>
|
|
2969
|
+
<nk-ai-msg role="assistant" name="Mona" badge="· AI">Two tasks are open: the <b>table view</b> sits at 65 % (due 20 May), the <b>board with drag and drop</b> is planned.
|
|
2970
|
+
<button slot="actions" value="copy">📋 Copy</button><button slot="actions" value="rephrase">↻ Rephrase</button><button slot="actions" value="like">👍</button>
|
|
2971
|
+
</nk-ai-msg>
|
|
2972
|
+
</nk-ai-thread>
|
|
2973
|
+
<nk-ai-input-row placeholder="Ask Mona something …"></nk-ai-input-row>
|
|
2974
|
+
```
|
|
2975
|
+
|
|
2976
|
+
_No attributes._
|
|
2977
|
+
|
|
2978
|
+
**Slots:** `(default)` – `nk-ai-msg` children.
|
|
2979
|
+
|
|
2980
|
+
**Events:** `nk-action` `{ action }` – Action button of a message.
|
|
2981
|
+
|
|
2982
|
+
**Replaces:** `.nk-ai-thread`, `.nk-ai-msg`, `.user`, `.a-body`, `.a-name`, `.nk-ai-actions`, `.nk-ai-input-row`, `.nk-ai-send`
|
|
2983
|
+
|
|
2984
|
+
```html
|
|
2985
|
+
<!-- equivalent class markup -->
|
|
2986
|
+
<div class="nk-ai-thread">
|
|
2987
|
+
<div class="nk-ai-msg user"><span class="mini-avatar">MK</span><div class="a-body"><div class="a-name">You</div>Summarise the open tasks for this project.</div></div>
|
|
2988
|
+
<div class="nk-ai-msg"><span class="mini-avatar">✨</span><div class="a-body"><div class="a-name">Mona <span>· AI</span></div>Two tasks are open: the <b>table view</b> sits at 65 % (due 20 May), the <b>board with drag and drop</b> is planned.<div class="nk-ai-actions"><button>📋 Copy</button><button>↻ Rephrase</button><button>👍</button></div></div></div>
|
|
2989
|
+
</div>
|
|
2990
|
+
<div class="nk-ai-input-row"><span style="font-size:14px">✨</span><input placeholder="Ask Mona something …"><button class="nk-ai-send">↑</button></div>
|
|
2991
|
+
```
|
|
2992
|
+
|
|
2993
|
+
**Small screens:** Unchanged.
|
|
2994
|
+
|
|
2995
|
+
### 3.86 `<nk-ai-msg>` – AI message
|
|
2996
|
+
|
|
2997
|
+
One message. `role="user"` flips the avatar to the gradient; `badge` is the grey suffix after the name (“· AI”); plain `<button slot="actions">`s form the action row.
|
|
2998
|
+
|
|
2999
|
+
```html
|
|
3000
|
+
<nk-ai-thread><nk-ai-msg role="user" bubble>What is still open on this page?</nk-ai-msg><nk-ai-msg role="assistant" name="Mona" badge="· AI">Two tasks are open: the <b>table view</b> sits at 65 % (due 20 May), the <b>board with drag and drop</b> is planned.<button slot="actions" value="copy">📋 Copy</button></nk-ai-msg></nk-ai-thread>
|
|
3001
|
+
```
|
|
3002
|
+
|
|
3003
|
+
| Attribute | Type | Default | Description |
|
|
3004
|
+
|---|---|---|---|
|
|
3005
|
+
| `role` | user | assistant | `assistant` | Who speaks. |
|
|
3006
|
+
| `name` | string | – | Name line. |
|
|
3007
|
+
| `badge` | string | – | Grey suffix. |
|
|
3008
|
+
| `avatar` | string | – | Initials/emoji. |
|
|
3009
|
+
| `color` | CSS color | – | Avatar background override. |
|
|
3010
|
+
| `bubble` | boolean | – | The message as a grey bubble without avatar or name; with `role="user"` on the right, as Notion’s AI chat shows your own question. |
|
|
3011
|
+
|
|
3012
|
+
**Slots:** `(default)` – Message body (HTML allowed). · `actions` – `<button value>` children. · `avatar` – Custom avatar.
|
|
3013
|
+
|
|
3014
|
+
**Events:** `nk-action` `{ action, value }` – Action button clicked.
|
|
3015
|
+
|
|
3016
|
+
**Replaces:** `.nk-ai-msg`, `.user`, `.bubble`, `.a-body`, `.a-name`, `.nk-ai-actions`
|
|
3017
|
+
|
|
3018
|
+
```html
|
|
3019
|
+
<!-- equivalent class markup -->
|
|
3020
|
+
<div class="nk-ai-thread"><div class="nk-ai-msg user bubble"><div class="a-body">What is still open on this page?</div></div><div class="nk-ai-msg"><span class="mini-avatar">✨</span><div class="a-body"><div class="a-name">Mona <span>· AI</span></div>Two tasks are open: the <b>table view</b> sits at 65 % (due 20 May), the <b>board with drag and drop</b> is planned.<div class="nk-ai-actions"><button>📋 Copy</button></div></div></div></div>
|
|
3021
|
+
```
|
|
3022
|
+
|
|
3023
|
+
**Small screens:** Unchanged.
|
|
3024
|
+
|
|
3025
|
+
### 3.87 `<nk-ai-input-row>` – AI input row
|
|
3026
|
+
|
|
3027
|
+
The prompt field with ✨ and a send button. Enter or the button fires `nk-submit { text }` and clears the field.
|
|
3028
|
+
|
|
3029
|
+
```html
|
|
3030
|
+
<nk-ai-input-row placeholder="Ask Mona something …"></nk-ai-input-row>
|
|
3031
|
+
```
|
|
3032
|
+
|
|
3033
|
+
| Attribute | Type | Default | Description |
|
|
3034
|
+
|---|---|---|---|
|
|
3035
|
+
| `placeholder` | string | – | Placeholder. |
|
|
3036
|
+
| `value` | string | – | Preset text. |
|
|
3037
|
+
| `disabled` | boolean | – | Disabled while the assistant answers. |
|
|
3038
|
+
| `icon` | string | `✨` | Leading glyph. |
|
|
3039
|
+
|
|
3040
|
+
**Events:** `nk-submit` `{ text }` – Prompt sent.
|
|
3041
|
+
|
|
3042
|
+
**Properties:** `value` · **Methods:** `submit()`, `focus()`
|
|
3043
|
+
|
|
3044
|
+
**Replaces:** `.nk-ai-input-row`, `.nk-ai-send`
|
|
3045
|
+
|
|
3046
|
+
```html
|
|
3047
|
+
<!-- equivalent class markup -->
|
|
3048
|
+
<div class="nk-ai-input-row"><span style="font-size:14px">✨</span><input placeholder="Ask Mona something …"><button class="nk-ai-send">↑</button></div>
|
|
3049
|
+
```
|
|
3050
|
+
|
|
3051
|
+
**Small screens:** Unchanged.
|
|
3052
|
+
|
|
3053
|
+
|
|
3054
|
+
# 4. Composition Patterns (app skeletons)
|
|
3055
|
+
|
|
3056
|
+
Eight skeletons, one per app shape, mirroring the NotionKit CSS SKILL.md. Copy one, delete what you do not need.
|
|
3057
|
+
|
|
3058
|
+
## 4.1 Workspace app
|
|
3059
|
+
|
|
3060
|
+
**When:** the default for Notion-like document apps – pages are the primary object, a tree on the left, one page on the right. A page that is a database row shows its properties under the title and lists its sub-pages.
|
|
3061
|
+
|
|
3062
|
+
```html
|
|
3063
|
+
<!DOCTYPE html>
|
|
3064
|
+
<html lang="en" data-theme="light">
|
|
3065
|
+
<head>
|
|
3066
|
+
<meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
3067
|
+
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@jungherz-de/notionkit@1.11.1/notionkit.min.css">
|
|
3068
|
+
<script src="https://cdn.jsdelivr.net/npm/@jungherz-de/notionkit-elements@1.11.1/dist/notionkit-elements.min.js"></script>
|
|
3069
|
+
</head>
|
|
3070
|
+
<body class="nk-body">
|
|
3071
|
+
<nk-app>
|
|
3072
|
+
<!-- collapsible: the « collapses it on the desktop, the ☰ and ⌘\ bring it back -->
|
|
3073
|
+
<nk-sidebar slot="sidebar" id="sidebar" collapsible>
|
|
3074
|
+
<nk-workspace-switcher slot="workspace" name="MonaHilft"></nk-workspace-switcher>
|
|
3075
|
+
<nk-tree id="tree">
|
|
3076
|
+
<nk-tree-item icon="🔍" value="search" no-actions>Search<span slot="end" class="nk-kbd-hint"><nk-kbd>⌘</nk-kbd><nk-kbd>K</nk-kbd></span></nk-tree-item>
|
|
3077
|
+
<nk-tree-item icon="🏠" value="home">Home</nk-tree-item>
|
|
3078
|
+
<nk-tree-item icon="📥" value="inbox">Inbox</nk-tree-item>
|
|
3079
|
+
<nk-section-label addable>Favourites</nk-section-label>
|
|
3080
|
+
<nk-tree-item icon="📊" value="overview" open>Project overview
|
|
3081
|
+
<nk-tree-item icon="🚀" value="mvp" active>NotionKit MVP</nk-tree-item>
|
|
3082
|
+
<nk-tree-item icon="🎙️" value="voh">Voice-Office-Hub</nk-tree-item>
|
|
3083
|
+
</nk-tree-item>
|
|
3084
|
+
<nk-section-label addable>Workspace</nk-section-label>
|
|
3085
|
+
<nk-tree-item icon="🧠" value="kb">Knowledge base
|
|
3086
|
+
<nk-tree-item icon="📄" value="onboarding">Onboarding</nk-tree-item>
|
|
3087
|
+
</nk-tree-item>
|
|
3088
|
+
<nk-tree-item icon="🎨" value="design">Design system</nk-tree-item>
|
|
3089
|
+
</nk-tree>
|
|
3090
|
+
<nk-tree-item slot="footer" icon="⚙️" value="settings" no-actions>Settings</nk-tree-item>
|
|
3091
|
+
<nk-tree-item slot="footer" icon="🗑️" value="trash" no-actions>Trash</nk-tree-item>
|
|
3092
|
+
</nk-sidebar>
|
|
3093
|
+
|
|
3094
|
+
<nk-topbar>
|
|
3095
|
+
<nk-btn variant="sidebar" aria-label="Menu" data-tooltip="Open sidebar">☰</nk-btn>
|
|
3096
|
+
<nk-breadcrumb><span>📊 Project overview</span><span>🚀 NotionKit MVP</span></nk-breadcrumb>
|
|
3097
|
+
<nk-btn slot="actions" variant="share">Share</nk-btn>
|
|
3098
|
+
<nk-theme-toggle slot="actions"></nk-theme-toggle>
|
|
3099
|
+
</nk-topbar>
|
|
3100
|
+
|
|
3101
|
+
<!-- Page options: add full (full width) or small (14px text) to <nk-page>. -->
|
|
3102
|
+
<nk-page icon="🚀" cover>
|
|
3103
|
+
<nk-page-title editable>NotionKit MVP</nk-page-title>
|
|
3104
|
+
<nk-props>
|
|
3105
|
+
<nk-prop label="Status" icon="◉"><nk-tag color="blue">In progress</nk-tag></nk-prop>
|
|
3106
|
+
<nk-prop label="Owner" icon="👤"><nk-avatar size="small">AL</nk-avatar>Ada Lovelace</nk-prop>
|
|
3107
|
+
<nk-prop label="Due" icon="📅">2 June 2026</nk-prop>
|
|
3108
|
+
</nk-props>
|
|
3109
|
+
<p class="lead">A calm, document-centric workspace app – built from elements only.</p>
|
|
3110
|
+
<nk-heading>Sub-pages</nk-heading>
|
|
3111
|
+
<nk-list-view id="subpages" meta-keys="due,status"></nk-list-view>
|
|
3112
|
+
<!-- The editor: mount TipTap into a light-DOM .nk-block-host (docs-editor.js).
|
|
3113
|
+
Saved HTML shown read-only goes into <div class="nk-prose"> – same look. -->
|
|
3114
|
+
<div class="nk-block-host" id="editor"></div>
|
|
3115
|
+
</nk-page>
|
|
3116
|
+
|
|
3117
|
+
<nk-tab-bar>
|
|
3118
|
+
<nk-tab-bar-item icon="🏠" value="home" active>Home</nk-tab-bar-item>
|
|
3119
|
+
<nk-tab-bar-item icon="📥" value="inbox">Inbox</nk-tab-bar-item>
|
|
3120
|
+
<nk-tab-bar-item icon="🔍" value="search">Search</nk-tab-bar-item>
|
|
3121
|
+
<nk-tab-bar-item icon="☰" drawer>More</nk-tab-bar-item>
|
|
3122
|
+
</nk-tab-bar>
|
|
3123
|
+
</nk-app>
|
|
3124
|
+
<script>
|
|
3125
|
+
tree.addEventListener('nk-select', e => console.log('open page', e.detail.value));
|
|
3126
|
+
tree.addEventListener('nk-action', e => console.log(e.detail.action, 'on', e.detail.value));
|
|
3127
|
+
subpages.columns = [
|
|
3128
|
+
{ key: 'name', label: 'Name', title: true }, { key: 'due', label: 'Due', type: 'date' },
|
|
3129
|
+
{ key: 'status', label: 'Status', type: 'select', options: [{ value: 'done', label: 'Done', color: 'green' }, { value: 'open', label: 'Open', color: 'gray' }] },
|
|
3130
|
+
];
|
|
3131
|
+
subpages.rows = [{ id: 1, icon: '📄', name: 'Hiring plan', due: '12 Aug', status: 'done' }, { id: 2, icon: '📄', name: 'Budget review', due: '2 Sep', status: 'open' }];
|
|
3132
|
+
subpages.addEventListener('nk-select', e => console.log('open sub-page', e.detail.id));
|
|
3133
|
+
</script>
|
|
3134
|
+
</body>
|
|
3135
|
+
</html>
|
|
3136
|
+
```
|
|
3137
|
+
|
|
3138
|
+
Rules of the shell: `nk-sidebar`, `nk-topbar` and `nk-page` are `display: contents` hosts – their inner boxes are direct flex children of `.nk-app` / `.nk-main`, so do not style the hosts. `<nk-btn variant="sidebar">` is the ☰: shown below 860px only, where the sidebar is hidden, it opens it as a drawer – NotionKit’s own drawer rules, no script. For phones and installed PWAs add `<nk-tab-bar>` as the last child of `<nk-app>`: it lands below the page in the main column, is hidden above 860px (the sidebar is the navigation there) and shown below; a `drawer` item opens the sidebar. For Notion’s “More” – the rest of the sidebar as a list from the bottom edge – put an `<nk-sheet>` under `<body>` and open it from the item’s `nk-select` after `e.preventDefault()`. Never give the bar a `view-transition-name` – it stays put between pages.
|
|
3139
|
+
|
|
3140
|
+
## 4.2 Database app
|
|
3141
|
+
|
|
3142
|
+
**When:** structured, data-centric apps – a CRM, a tracker, an editorial calendar. Rows are the primary object; the database is the main room.
|
|
3143
|
+
|
|
3144
|
+
```html
|
|
3145
|
+
<!DOCTYPE html>
|
|
3146
|
+
<html lang="en" data-theme="light">
|
|
3147
|
+
<head>
|
|
3148
|
+
<meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
3149
|
+
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@jungherz-de/notionkit@1.11.1/notionkit.min.css">
|
|
3150
|
+
<script src="https://cdn.jsdelivr.net/npm/@jungherz-de/notionkit-elements@1.11.1/dist/notionkit-elements.min.js"></script>
|
|
3151
|
+
</head>
|
|
3152
|
+
<body class="nk-body">
|
|
3153
|
+
<nk-app>
|
|
3154
|
+
<nk-sidebar slot="sidebar">
|
|
3155
|
+
<nk-workspace-switcher slot="workspace" name="MonaHilft"></nk-workspace-switcher>
|
|
3156
|
+
<nk-tree>
|
|
3157
|
+
<nk-section-label addable>Databases</nk-section-label>
|
|
3158
|
+
<nk-tree-item icon="🗃️" value="projects" active>Projects</nk-tree-item>
|
|
3159
|
+
<nk-tree-item icon="🤝" value="clients">Clients</nk-tree-item>
|
|
3160
|
+
<nk-tree-item icon="🗓️" value="editorial">Editorial plan</nk-tree-item>
|
|
3161
|
+
</nk-tree>
|
|
3162
|
+
</nk-sidebar>
|
|
3163
|
+
<nk-topbar>
|
|
3164
|
+
<nk-breadcrumb><span>🗃️ Projects</span></nk-breadcrumb>
|
|
3165
|
+
<nk-btn slot="actions" variant="share">Share</nk-btn>
|
|
3166
|
+
<nk-theme-toggle slot="actions"></nk-theme-toggle>
|
|
3167
|
+
</nk-topbar>
|
|
3168
|
+
<nk-page icon="🗃️">
|
|
3169
|
+
<nk-page-title>Projects</nk-page-title>
|
|
3170
|
+
<nk-database id="db" view="table" add-view>
|
|
3171
|
+
<nk-btn slot="tools" variant="tool" id="filterBtn" aria-haspopup="menu">Filter</nk-btn>
|
|
3172
|
+
<nk-btn slot="tools" variant="primary" small id="newBtn">New</nk-btn>
|
|
3173
|
+
<nk-filter-bar slot="filters" id="filters" add no-filter no-sort></nk-filter-bar>
|
|
3174
|
+
<nk-table-view name="table" label="▦ Table" count new-row sortable></nk-table-view>
|
|
3175
|
+
<nk-board-view name="board" label="▤ Board" group-by="status" new-row></nk-board-view>
|
|
3176
|
+
<nk-calendar-view name="calendar" label="📅 Calendar" date-key="due" weeks></nk-calendar-view>
|
|
3177
|
+
</nk-database>
|
|
3178
|
+
</nk-page>
|
|
3179
|
+
</nk-app>
|
|
3180
|
+
<!-- a popover on the desktop, a bottom sheet on a phone -->
|
|
3181
|
+
<nk-menu floating sheet id="filterMenu">
|
|
3182
|
+
<nk-menu-item type="label">Filter by</nk-menu-item>
|
|
3183
|
+
<nk-menu-item type="check" icon="◉" value="done">Status: Done</nk-menu-item>
|
|
3184
|
+
</nk-menu>
|
|
3185
|
+
<!-- one date picker for every date: a popover under the cell, a sheet on a phone -->
|
|
3186
|
+
<nk-calendar floating sheet weeks weekend="6,0" id="picker"></nk-calendar>
|
|
3187
|
+
<!-- a row beside the table, a sheet on a phone -->
|
|
3188
|
+
<nk-peek id="peek">
|
|
3189
|
+
<nk-page-title id="peekTitle"></nk-page-title>
|
|
3190
|
+
<div class="nk-prose"><p>Notes on this row – the page behind it.</p></div>
|
|
3191
|
+
</nk-peek>
|
|
3192
|
+
<nk-toast id="toast"></nk-toast>
|
|
3193
|
+
<script>
|
|
3194
|
+
const columns = [
|
|
3195
|
+
{ key: 'name', label: 'Name', type: 'text', icon: '📄', title: true },
|
|
3196
|
+
{ key: 'status', label: 'Status', type: 'select', icon: '◉', options: [
|
|
3197
|
+
{ value: 'planned', label: 'Planned', color: 'orange' },
|
|
3198
|
+
{ value: 'progress', label: 'In progress', color: 'blue' },
|
|
3199
|
+
{ value: 'done', label: 'Done', color: 'green' } ] },
|
|
3200
|
+
{ key: 'owner', label: 'Owner', type: 'person', icon: '👤' },
|
|
3201
|
+
{ key: 'due', label: 'Due', type: 'date', icon: '📅' },
|
|
3202
|
+
{ key: 'progress', label: 'Progress', type: 'progress', icon: '▰' },
|
|
3203
|
+
];
|
|
3204
|
+
const rows = [
|
|
3205
|
+
{ id: 1, icon: '🧭', name: 'App shell & sidebar', status: 'done', owner: { name: 'Marcel', initials: 'MK', color: '#9065b0' }, due: '08.05.2026', progress: 100 },
|
|
3206
|
+
{ id: 2, icon: '🗃️', name: 'Database table view', status: 'progress', owner: { name: 'Marcel', initials: 'MK', color: '#9065b0' }, due: '20.05.2026', progress: 65 },
|
|
3207
|
+
{ id: 3, icon: '▤', name: 'Board view & drag-and-drop', status: 'planned', due: '02.06.2026', progress: 0 },
|
|
3208
|
+
];
|
|
3209
|
+
const FILTERS = { done: { key: 'status', value: 'done', label: 'Status: Done' } };
|
|
3210
|
+
function render() {
|
|
3211
|
+
db.rows = filters.apply(rows);
|
|
3212
|
+
filterBtn.active = filters.filters.length > 0;
|
|
3213
|
+
filterMenu.querySelectorAll('nk-menu-item[type="check"]').forEach(i => { i.checked = filters.filters.includes(FILTERS[i.value]); });
|
|
3214
|
+
}
|
|
3215
|
+
db.columns = columns;
|
|
3216
|
+
render();
|
|
3217
|
+
filterBtn.addEventListener('click', () => filterMenu.toggle(filterBtn));
|
|
3218
|
+
filters.addEventListener('nk-action', e => filterMenu.show(e.detail.anchor)); // a pill or + Filter
|
|
3219
|
+
filterMenu.addEventListener('nk-change', e => {
|
|
3220
|
+
const f = FILTERS[e.detail.value];
|
|
3221
|
+
filters.filters = e.detail.checked ? [...filters.filters, f] : filters.filters.filter(x => x !== f);
|
|
3222
|
+
render();
|
|
3223
|
+
});
|
|
3224
|
+
filters.addEventListener('nk-change', render); // × on a pill
|
|
3225
|
+
newBtn.addEventListener('click', () => { rows.push({ id: Date.now(), icon: '📄', name: 'New page', status: 'planned', due: '—', progress: 0 }); render(); });
|
|
3226
|
+
let editing = null;
|
|
3227
|
+
db.addEventListener('nk-select', e => { // a row, a card, a list item, a calendar card
|
|
3228
|
+
if (e.detail.key === 'due') { // a due date in the table: the picker under its cell
|
|
3229
|
+
editing = e.detail.row;
|
|
3230
|
+
picker.value = editing.due.split('.').reverse().join('-');
|
|
3231
|
+
picker.show(e.detail.cell);
|
|
3232
|
+
return;
|
|
3233
|
+
}
|
|
3234
|
+
peekTitle.textContent = e.detail.row.name;
|
|
3235
|
+
peek.setAttribute('label', e.detail.row.name);
|
|
3236
|
+
peek.show(); // another row only swaps it
|
|
3237
|
+
});
|
|
3238
|
+
picker.addEventListener('nk-change', e => { editing.due = e.detail.value.split('-').reverse().join('.'); render(); });
|
|
3239
|
+
db.addEventListener('nk-change', e => toast.show(`${e.detail.row.name} → ${e.detail.value}`));
|
|
3240
|
+
db.addEventListener('nk-action', e => { if (e.detail.action === 'new-row') { rows.push({ id: Date.now(), icon: '📄', name: 'New page', status: e.detail.value || 'planned', due: '—', progress: 0 }); render(); } });
|
|
3241
|
+
</script>
|
|
3242
|
+
</body>
|
|
3243
|
+
</html>
|
|
3244
|
+
```
|
|
3245
|
+
|
|
3246
|
+
Data contract: `columns` describe the properties (`type`: text | select | multi-select | date | person | checkbox | url | number | progress; a `select` carries `options: [{ value, label, color }]`; the title column has `title: true`), `rows` are plain objects keyed by `column.key` (a `person` is `{ name, initials, color }` or a string; `icon` on a row prefixes the title). The elements render what they get – filtering, sorting on the server, persistence are yours; `filters.apply(rows)` is the local filter, `op: 'is-not'` on a filter keeps the other rows. Assign a new array (`db.rows = …`) or call `db.refresh()` after mutating rows in place.
|
|
3247
|
+
|
|
3248
|
+
## 4.4 AI chat page
|
|
3249
|
+
|
|
3250
|
+
**When:** assistant-centred apps where the conversation is the document.
|
|
3251
|
+
|
|
3252
|
+
```html
|
|
3253
|
+
<!DOCTYPE html>
|
|
3254
|
+
<html lang="en" data-theme="light">
|
|
3255
|
+
<head>
|
|
3256
|
+
<meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
3257
|
+
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@jungherz-de/notionkit@1.11.1/notionkit.min.css">
|
|
3258
|
+
<script src="https://cdn.jsdelivr.net/npm/@jungherz-de/notionkit-elements@1.11.1/dist/notionkit-elements.min.js"></script>
|
|
3259
|
+
</head>
|
|
3260
|
+
<body class="nk-body">
|
|
3261
|
+
<nk-app>
|
|
3262
|
+
<nk-sidebar slot="sidebar">
|
|
3263
|
+
<nk-workspace-switcher slot="workspace" name="MonaHilft"></nk-workspace-switcher>
|
|
3264
|
+
<nk-tree>
|
|
3265
|
+
<nk-tree-item icon="+" value="new" no-actions>New chat</nk-tree-item>
|
|
3266
|
+
<nk-section-label>Threads</nk-section-label>
|
|
3267
|
+
<nk-tree-item icon="✨" value="t1" active>Open tasks</nk-tree-item>
|
|
3268
|
+
<nk-tree-item icon="✨" value="t2">Release notes draft</nk-tree-item>
|
|
3269
|
+
</nk-tree>
|
|
3270
|
+
</nk-sidebar>
|
|
3271
|
+
<nk-topbar>
|
|
3272
|
+
<nk-breadcrumb><span>✨ Open tasks</span></nk-breadcrumb>
|
|
3273
|
+
<nk-theme-toggle slot="actions"></nk-theme-toggle>
|
|
3274
|
+
</nk-topbar>
|
|
3275
|
+
<nk-page icon="✨">
|
|
3276
|
+
<nk-page-title>Open tasks</nk-page-title>
|
|
3277
|
+
<nk-ai-thread id="thread">
|
|
3278
|
+
<nk-ai-msg role="user" name="You" avatar="MK">Summarise the open tasks for this project.</nk-ai-msg>
|
|
3279
|
+
<nk-ai-msg role="assistant" name="Mona" badge="· AI">Two tasks are open: the <b>table view</b> sits at 65 % (due 20 May), the <b>board with drag and drop</b> is planned.
|
|
3280
|
+
<button slot="actions" value="copy">📋 Copy</button>
|
|
3281
|
+
<button slot="actions" value="rephrase">↻ Rephrase</button>
|
|
3282
|
+
</nk-ai-msg>
|
|
3283
|
+
</nk-ai-thread>
|
|
3284
|
+
<nk-ai-input-row id="prompt" placeholder="Ask Mona something …"></nk-ai-input-row>
|
|
3285
|
+
</nk-page>
|
|
3286
|
+
</nk-app>
|
|
3287
|
+
<script>
|
|
3288
|
+
prompt.addEventListener('nk-submit', async e => {
|
|
3289
|
+
const user = document.createElement('nk-ai-msg');
|
|
3290
|
+
user.setAttribute('role', 'user'); user.setAttribute('name', 'You'); user.setAttribute('avatar', 'MK');
|
|
3291
|
+
user.textContent = e.detail.text;
|
|
3292
|
+
thread.appendChild(user);
|
|
3293
|
+
prompt.disabled = true;
|
|
3294
|
+
const reply = document.createElement('nk-ai-msg');
|
|
3295
|
+
reply.setAttribute('name', 'Mona'); reply.setAttribute('badge', '· AI');
|
|
3296
|
+
reply.textContent = await askYourBackend(e.detail.text); // your call
|
|
3297
|
+
thread.appendChild(reply);
|
|
3298
|
+
prompt.disabled = false;
|
|
3299
|
+
prompt.focus();
|
|
3300
|
+
});
|
|
3301
|
+
thread.addEventListener('nk-action', e => console.log(e.detail.action));
|
|
3302
|
+
async function askYourBackend(text) { return 'Echo: ' + text; }
|
|
3303
|
+
</script>
|
|
3304
|
+
</body>
|
|
3305
|
+
</html>
|
|
3306
|
+
```
|
|
3307
|
+
|
|
3308
|
+
## 4.3 Settings modal integration
|
|
3309
|
+
|
|
3310
|
+
**When:** you have an app already and need the settings overlay – plus the command palette and a toast, since they share the "overlay under body" rule (so do `<nk-sheet>` and a floating `<nk-menu>`).
|
|
3311
|
+
|
|
3312
|
+
```html
|
|
3313
|
+
<!DOCTYPE html>
|
|
3314
|
+
<html lang="en" data-theme="light">
|
|
3315
|
+
<head>
|
|
3316
|
+
<meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
3317
|
+
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@jungherz-de/notionkit@1.11.1/notionkit.min.css">
|
|
3318
|
+
<script src="https://cdn.jsdelivr.net/npm/@jungherz-de/notionkit-elements@1.11.1/dist/notionkit-elements.min.js"></script>
|
|
3319
|
+
</head>
|
|
3320
|
+
<body class="nk-body">
|
|
3321
|
+
<!-- your app -->
|
|
3322
|
+
<div class="nk-page" style="padding-top:48px">
|
|
3323
|
+
<nk-page-title>NotionKit MVP</nk-page-title>
|
|
3324
|
+
<p><nk-btn variant="secondary" onclick="settings.show()">⚙️ Open settings</nk-btn> <nk-btn variant="secondary" onclick="palette.show()">🔍 Open palette (⌘K)</nk-btn></p>
|
|
3325
|
+
</div>
|
|
3326
|
+
|
|
3327
|
+
<!-- overlays: direct children of <body> -->
|
|
3328
|
+
<nk-modal id="settings">
|
|
3329
|
+
<nk-settings-user slot="user" name="Marcel Karas" mail="marcel@monahilft.de"></nk-settings-user>
|
|
3330
|
+
|
|
3331
|
+
<nk-settings-pane name="profile" group="Account" icon="👤" label="My profile" title="My profile" active>
|
|
3332
|
+
<nk-image-picker id="photo" initials="MK" label="My profile"></nk-image-picker>
|
|
3333
|
+
<h3>Display name</h3>
|
|
3334
|
+
<nk-field label="Display name" desc="Shown next to your comments."><nk-input name="name" value="Marcel Karas"></nk-input></nk-field>
|
|
3335
|
+
<nk-field label="Email"><nk-input name="email" type="email" value="marcel@monahilft.de"></nk-input></nk-field>
|
|
3336
|
+
<p style="margin-top:16px"><nk-btn variant="primary" small onclick="toast.show('Settings saved')">Save</nk-btn></p>
|
|
3337
|
+
</nk-settings-pane>
|
|
3338
|
+
|
|
3339
|
+
<nk-settings-pane name="appearance" group="Account" icon="🎨" label="Appearance" title="Appearance">
|
|
3340
|
+
<nk-field label="Theme"><nk-select id="themeSelect"><option value="light">Light</option><option value="dark">Dark</option></nk-select></nk-field>
|
|
3341
|
+
<nk-field label="Font size"><nk-slider min="12" max="18" value="14" unit="px" show-value></nk-slider></nk-field>
|
|
3342
|
+
</nk-settings-pane>
|
|
3343
|
+
|
|
3344
|
+
<nk-settings-pane name="ai" group="Account" icon="✨" label="AI assistant" title="AI assistant">
|
|
3345
|
+
<nk-model-card name="model" value="pro" title="Mona Pro" desc="Best for long documents and research." selected></nk-model-card>
|
|
3346
|
+
<nk-model-card name="model" value="fast" title="Mona Fast" desc="Quick answers, lower cost."></nk-model-card>
|
|
3347
|
+
</nk-settings-pane>
|
|
3348
|
+
|
|
3349
|
+
<nk-settings-pane name="general" group="Workspace" icon="⚙️" label="General" title="General">
|
|
3350
|
+
<nk-field label="MonaHilft"><nk-input value="MonaHilft"></nk-input></nk-field>
|
|
3351
|
+
<nk-field label="Icon"><nk-image-picker square initials="A" max="256" type="image/png"></nk-image-picker></nk-field>
|
|
3352
|
+
<nk-field label="Public address"><nk-copy-field value="https://acme.example.com"></nk-copy-field></nk-field>
|
|
3353
|
+
<nk-danger-zone title="Danger zone"><nk-field label="Delete workspace" desc="Deleting the workspace removes every page."><nk-btn variant="danger-solid" small>Delete</nk-btn></nk-field></nk-danger-zone>
|
|
3354
|
+
</nk-settings-pane>
|
|
3355
|
+
|
|
3356
|
+
<nk-settings-pane name="members" group="Workspace" icon="👥" label="Members" title="Members">
|
|
3357
|
+
<nk-member-list>
|
|
3358
|
+
<nk-member-row name="Sara Lindt" mail="sara@example.com" color="#448361"><nk-select slot="role" compact value="editor"><option value="viewer">Viewer</option><option value="editor">Editor</option><option value="admin">Admin</option></nk-select></nk-member-row>
|
|
3359
|
+
<nk-member-row name="Tom Weber" mail="tom@example.com" color="#d9730d"><nk-select slot="role" compact value="viewer"><option value="viewer">Viewer</option><option value="editor">Editor</option><option value="admin">Admin</option></nk-select></nk-member-row>
|
|
3360
|
+
</nk-member-list>
|
|
3361
|
+
</nk-settings-pane>
|
|
3362
|
+
</nk-modal>
|
|
3363
|
+
|
|
3364
|
+
<nk-cmdk id="palette" placeholder="Search or type a command …"></nk-cmdk>
|
|
3365
|
+
<nk-toast id="toast"></nk-toast>
|
|
3366
|
+
|
|
3367
|
+
<script>
|
|
3368
|
+
palette.commands = [
|
|
3369
|
+
{ group: 'Pages', items: [{ id: 'mvp', icon: '🚀', label: 'NotionKit MVP' }, { id: 'kb', icon: '🧠', label: 'Knowledge base' }] },
|
|
3370
|
+
{ group: 'Actions', items: [
|
|
3371
|
+
{ id: 'settings', icon: '⚙️', label: 'Open settings', shortcut: '⌘,', action: () => settings.show() },
|
|
3372
|
+
{ id: 'theme', icon: '🌙', label: 'Toggle theme', shortcut: '⌘⇧L', action: () => document.documentElement.dataset.theme = document.documentElement.dataset.theme === 'dark' ? 'light' : 'dark' },
|
|
3373
|
+
]},
|
|
3374
|
+
];
|
|
3375
|
+
palette.addEventListener('nk-command', e => console.log('command', e.detail.id));
|
|
3376
|
+
themeSelect.addEventListener('nk-change', e => document.documentElement.dataset.theme = e.detail.value);
|
|
3377
|
+
settings.addEventListener('nk-select', e => console.log('pane', e.detail.value));
|
|
3378
|
+
photo.addEventListener('nk-change', e => console.log('upload', e.detail.size, 'bytes')); // a data URL, scaled, EXIF-rotated
|
|
3379
|
+
</script>
|
|
3380
|
+
</body>
|
|
3381
|
+
</html>
|
|
3382
|
+
```
|
|
3383
|
+
|
|
3384
|
+
The open/close contract is one attribute: `settings.open = true`, `settings.show('members')`, `settings.close()`. Never add the class `open` yourself.
|
|
3385
|
+
|
|
3386
|
+
## 4.5 Form / onboarding page
|
|
3387
|
+
|
|
3388
|
+
**When:** an app – or one step of it – made entirely of form elements. No sidebar, no editor.
|
|
3389
|
+
|
|
3390
|
+
```html
|
|
3391
|
+
<!DOCTYPE html>
|
|
3392
|
+
<html lang="en" data-theme="light">
|
|
3393
|
+
<head>
|
|
3394
|
+
<meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
3395
|
+
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@jungherz-de/notionkit@1.11.1/notionkit.min.css">
|
|
3396
|
+
<script src="https://cdn.jsdelivr.net/npm/@jungherz-de/notionkit-elements@1.11.1/dist/notionkit-elements.min.js"></script>
|
|
3397
|
+
</head>
|
|
3398
|
+
<body class="nk-body">
|
|
3399
|
+
<div class="nk-page" style="padding-top:48px">
|
|
3400
|
+
<h1 class="nk-page-title">Set up your workspace</h1>
|
|
3401
|
+
<p class="lead">Three short steps. Everything can be changed later in Settings.</p>
|
|
3402
|
+
<nk-steps id="progress" label="Set up your workspace" current="1" steps="Profile, Notifications, Assistant style"></nk-steps>
|
|
3403
|
+
|
|
3404
|
+
<form id="onboarding">
|
|
3405
|
+
<nk-heading>1 · Profile</nk-heading>
|
|
3406
|
+
<nk-field label="Display name" desc="Shown next to your comments."><nk-input name="name" required></nk-input></nk-field>
|
|
3407
|
+
<nk-field label="Email"><nk-input name="email" type="email" required></nk-input></nk-field>
|
|
3408
|
+
<nk-field label="Short bio" stacked><nk-textarea name="bio" rows="3" placeholder="A sentence about you"></nk-textarea></nk-field>
|
|
3409
|
+
|
|
3410
|
+
<nk-heading>2 · Notifications</nk-heading>
|
|
3411
|
+
<nk-field label="Email notifications"><nk-switch name="notify" checked></nk-switch></nk-field>
|
|
3412
|
+
<nk-check name="digest" value="weekly" checked>Weekly digest</nk-check>
|
|
3413
|
+
<nk-check name="digest" value="mentions">Mentions only</nk-check>
|
|
3414
|
+
|
|
3415
|
+
<nk-heading>3 · Assistant style</nk-heading>
|
|
3416
|
+
<nk-radio name="style" value="concise">Concise</nk-radio>
|
|
3417
|
+
<nk-radio name="style" value="balanced" checked>Balanced</nk-radio>
|
|
3418
|
+
<nk-radio name="style" value="detailed">Detailed</nk-radio>
|
|
3419
|
+
<nk-field label="Font size"><nk-slider name="size" min="12" max="18" value="14" unit="px" show-value></nk-slider></nk-field>
|
|
3420
|
+
|
|
3421
|
+
<nk-divider></nk-divider>
|
|
3422
|
+
<nk-callout icon="🔒">Nothing leaves your browser in this demo.</nk-callout>
|
|
3423
|
+
<p style="margin-top:16px"><nk-btn type="submit" variant="primary">Finish</nk-btn> <nk-btn type="reset" variant="secondary">Reset</nk-btn></p>
|
|
3424
|
+
</form>
|
|
3425
|
+
</div>
|
|
3426
|
+
<script>
|
|
3427
|
+
onboarding.addEventListener('submit', e => { e.preventDefault(); console.log(Object.fromEntries(new FormData(onboarding))); });
|
|
3428
|
+
</script>
|
|
3429
|
+
</body>
|
|
3430
|
+
</html>
|
|
3431
|
+
```
|
|
3432
|
+
|
|
3433
|
+
## 4.6 Landing / documentation page
|
|
3434
|
+
|
|
3435
|
+
**When:** a public page in the NotionKit look – no sidebar, the page *is* the document. For a complete website use [NotionKit Web](https://notionkit-web.jungherz.com), the Astro template on the same foundation.
|
|
3436
|
+
|
|
3437
|
+
```html
|
|
3438
|
+
<!DOCTYPE html>
|
|
3439
|
+
<html lang="en" data-theme="light">
|
|
3440
|
+
<head>
|
|
3441
|
+
<meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
3442
|
+
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@jungherz-de/notionkit@1.11.1/notionkit.min.css">
|
|
3443
|
+
<script src="https://cdn.jsdelivr.net/npm/@jungherz-de/notionkit-elements@1.11.1/dist/notionkit-elements.min.js"></script>
|
|
3444
|
+
</head>
|
|
3445
|
+
<body class="nk-body">
|
|
3446
|
+
<nk-page narrow icon="📘" cover>
|
|
3447
|
+
<nk-page-title>NotionKit Elements</nk-page-title>
|
|
3448
|
+
<nk-page-actions><span>👤 Marcel Karas</span><span>📅 Created 12 May 2026</span><span>🏷️ <nk-tag color="green">Done</nk-tag></span></nk-page-actions>
|
|
3449
|
+
<p class="lead">A calm, document-centric workspace app – built from elements only.</p>
|
|
3450
|
+
|
|
3451
|
+
<nk-banner variant="info">ℹ️ <span>This page is a <b>component preview</b> – every element follows the same design tokens.</span><button slot="action" type="button">View</button></nk-banner>
|
|
3452
|
+
<nk-callout icon="💡"><b>Core idea:</b> A callout carries one thought that must not be missed.</nk-callout>
|
|
3453
|
+
|
|
3454
|
+
<nk-heading>Getting started</nk-heading>
|
|
3455
|
+
<nk-code lang="html" highlight><nk-btn variant="primary">Save</nk-btn></nk-code>
|
|
3456
|
+
|
|
3457
|
+
<nk-heading>Building blocks</nk-heading>
|
|
3458
|
+
<nk-tabs value="notes">
|
|
3459
|
+
<nk-tab value="notes">📝 Notes</nk-tab><nk-tab value="tasks">✅ Tasks</nk-tab>
|
|
3460
|
+
<div slot="panel" data-tab="notes" class="nk-tab-panel">Free-form notes on the project – meeting minutes, ideas, rough drafts.</div>
|
|
3461
|
+
<div slot="panel" data-tab="tasks" class="nk-tab-panel">Tasks for this project, linked to the database below.</div>
|
|
3462
|
+
</nk-tabs>
|
|
3463
|
+
<nk-stats>
|
|
3464
|
+
<nk-stat label="Active pages" value="128" delta="▲ 12 this week" trend="up"></nk-stat>
|
|
3465
|
+
<nk-stat label="Open tasks" value="14" delta="▼ 5 since yesterday" trend="down"></nk-stat>
|
|
3466
|
+
</nk-stats>
|
|
3467
|
+
|
|
3468
|
+
<nk-toggle label="Details" open>Folded content lives here.</nk-toggle>
|
|
3469
|
+
<nk-quote cite="Unknown">The best interface is the one that gets out of the way.</nk-quote>
|
|
3470
|
+
<nk-divider></nk-divider>
|
|
3471
|
+
<nk-empty icon="🗂️" title="No entries yet" desc="Create the first entry or import existing data."><nk-btn variant="primary" small>+ New entry</nk-btn></nk-empty>
|
|
3472
|
+
</nk-page>
|
|
3473
|
+
</body>
|
|
3474
|
+
</html>
|
|
3475
|
+
```
|
|
3476
|
+
|
|
3477
|
+
Note `narrow`: the page is the document, so there is no inner scroll wrapper – the browser scrolls. Inside `<nk-app>` leave it off.
|
|
3478
|
+
## 4.7 Home page
|
|
3479
|
+
|
|
3480
|
+
**When:** the first screen after sign-in – a greeting, the pages someone comes back to, what is due next. Notion calls it Home; LearnHub builds it as “My courses”, Auxdesk as “Overview”. Full width and small text, panels with a picture cover, a list for what is next.
|
|
3481
|
+
|
|
3482
|
+
```html
|
|
3483
|
+
<!DOCTYPE html>
|
|
3484
|
+
<html lang="en" data-theme="light">
|
|
3485
|
+
<head>
|
|
3486
|
+
<meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
3487
|
+
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@jungherz-de/notionkit@1.11.1/notionkit.min.css">
|
|
3488
|
+
<script src="https://cdn.jsdelivr.net/npm/@jungherz-de/notionkit-elements@1.11.1/dist/notionkit-elements.min.js"></script>
|
|
3489
|
+
</head>
|
|
3490
|
+
<body class="nk-body">
|
|
3491
|
+
<nk-app>
|
|
3492
|
+
<nk-sidebar slot="sidebar">
|
|
3493
|
+
<nk-workspace-switcher slot="workspace" name="MonaHilft"></nk-workspace-switcher>
|
|
3494
|
+
<nk-tree>
|
|
3495
|
+
<nk-tree-item icon="🏠" value="home" active>Home</nk-tree-item>
|
|
3496
|
+
<nk-tree-item icon="🚀" value="mvp">NotionKit MVP</nk-tree-item>
|
|
3497
|
+
</nk-tree>
|
|
3498
|
+
</nk-sidebar>
|
|
3499
|
+
<nk-topbar><nk-breadcrumb><span>🏠 Home</span></nk-breadcrumb><nk-theme-toggle slot="actions"></nk-theme-toggle></nk-topbar>
|
|
3500
|
+
|
|
3501
|
+
<!-- An app view, not a document: the whole width, 14px text. -->
|
|
3502
|
+
<nk-page full small>
|
|
3503
|
+
<nk-page-title>Good morning, Ada</nk-page-title>
|
|
3504
|
+
<nk-heading>🕘 Recently visited</nk-heading>
|
|
3505
|
+
<nk-panels>
|
|
3506
|
+
<nk-panel href="/roadmap" cover="covers/roadmap.jpg" icon="🚀" title="Roadmap"><p><nk-avatar size="small">AL</nk-avatar> 2 min ago</p></nk-panel>
|
|
3507
|
+
<nk-panel href="/kb" cover icon="📚" title="Knowledge base"><p>Yesterday</p></nk-panel>
|
|
3508
|
+
<nk-panel href="/onboarding" icon="🧭" title="Onboarding"><p>Monday</p></nk-panel>
|
|
3509
|
+
</nk-panels>
|
|
3510
|
+
<nk-heading>📌 Upcoming</nk-heading>
|
|
3511
|
+
<nk-list-view id="upcoming" meta-keys="due,status"></nk-list-view>
|
|
3512
|
+
<nk-heading>📊 This week</nk-heading>
|
|
3513
|
+
<nk-panels>
|
|
3514
|
+
<nk-panel title="Weekly review"><p>Three pages changed, one comment is waiting for an answer.</p><nk-progress value="60" label="60 %" wide></nk-progress></nk-panel>
|
|
3515
|
+
<nk-panel title="Release notes"><div class="nk-prose"><p>Version 2.4 ships the list view. <a href="/changelog">Read more</a></p></div></nk-panel>
|
|
3516
|
+
</nk-panels>
|
|
3517
|
+
</nk-page>
|
|
3518
|
+
</nk-app>
|
|
3519
|
+
<script>
|
|
3520
|
+
upcoming.columns = [
|
|
3521
|
+
{ key: 'name', label: 'Name', title: true }, { key: 'due', label: 'Due', type: 'date' },
|
|
3522
|
+
{ key: 'status', label: 'Status', type: 'select', options: [{ value: 'progress', label: 'In progress', color: 'blue' }, { value: 'planned', label: 'Planned', color: 'orange' }] },
|
|
3523
|
+
];
|
|
3524
|
+
upcoming.rows = [{ id: 1, icon: '🗃️', name: 'Table view', due: '20 May', status: 'progress' }, { id: 2, icon: '▤', name: 'Board with drag and drop', due: '2 June', status: 'planned' }];
|
|
3525
|
+
upcoming.addEventListener('nk-select', e => location.assign('/tasks/' + e.detail.id));
|
|
3526
|
+
</script>
|
|
3527
|
+
</body>
|
|
3528
|
+
</html>
|
|
3529
|
+
```
|
|
3530
|
+
|
|
3531
|
+
`nk-panels` falls to one column on a phone; the list keeps one line per row and cuts the title first. A slotted `<p>` in a panel is styled by the panel – inside it, `<nk-avatar>` brings its own size.
|
|
3532
|
+
|
|
3533
|
+
## 4.8 Sign-in page
|
|
3534
|
+
|
|
3535
|
+
**When:** the page before the app – sign in with a provider or by email. A narrow centred column in a panel, no sidebar. Not an element on purpose: panel, field and buttons already are one.
|
|
3536
|
+
|
|
3537
|
+
```html
|
|
3538
|
+
<!DOCTYPE html>
|
|
3539
|
+
<html lang="en" data-theme="light">
|
|
3540
|
+
<head>
|
|
3541
|
+
<meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
3542
|
+
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@jungherz-de/notionkit@1.11.1/notionkit.min.css">
|
|
3543
|
+
<script src="https://cdn.jsdelivr.net/npm/@jungherz-de/notionkit-elements@1.11.1/dist/notionkit-elements.min.js"></script>
|
|
3544
|
+
</head>
|
|
3545
|
+
<body class="nk-body">
|
|
3546
|
+
<!-- A narrow column, centred: layout is yours, so it is inline. -->
|
|
3547
|
+
<nk-page narrow>
|
|
3548
|
+
<div style="max-width:420px;margin:12vh auto 0;display:flex;flex-direction:column;gap:14px">
|
|
3549
|
+
<div style="text-align:center">
|
|
3550
|
+
<nk-avatar size="xlarge" square>A</nk-avatar>
|
|
3551
|
+
<nk-page-title>Sign in to Acme</nk-page-title>
|
|
3552
|
+
<div style="color:var(--nk-text-secondary)">Use your work account.</div>
|
|
3553
|
+
</div>
|
|
3554
|
+
<form id="signin">
|
|
3555
|
+
<nk-panel>
|
|
3556
|
+
<nk-btn variant="secondary" type="button">Continue with Google</nk-btn>
|
|
3557
|
+
<nk-btn variant="secondary" type="button">Continue with Microsoft</nk-btn>
|
|
3558
|
+
<nk-field label="Email" stacked><nk-input name="email" type="email" placeholder="ada@acme.com" required></nk-input></nk-field>
|
|
3559
|
+
<nk-btn variant="primary" type="submit">Continue with email</nk-btn>
|
|
3560
|
+
</nk-panel>
|
|
3561
|
+
</form>
|
|
3562
|
+
<nk-banner variant="success" id="sent" hidden>✉️ Check your inbox – we sent you a sign-in link.</nk-banner>
|
|
3563
|
+
</div>
|
|
3564
|
+
</nk-page>
|
|
3565
|
+
<script>
|
|
3566
|
+
signin.addEventListener('submit', e => { e.preventDefault(); sent.hidden = false; });
|
|
3567
|
+
</script>
|
|
3568
|
+
</body>
|
|
3569
|
+
</html>
|
|
3570
|
+
```
|
|
3571
|
+
|
|
3572
|
+
The form takes part in `FormData` through `nk-input`; `hidden` on the banner works on every element.
|
|
3573
|
+
|
|
3574
|
+
|
|
3575
|
+
# 5. State & Event Overview
|
|
3576
|
+
|
|
3577
|
+
| Event | Fired by | `detail` |
|
|
3578
|
+
|---|---|---|
|
|
3579
|
+
| `nk-change` | every form control, `nk-segmented`, `nk-tabs`, `nk-tab-bar`, editable `nk-page-title` | `{ value, name }` – checkables add `checked` |
|
|
3580
|
+
| `nk-input` | `nk-input`, `nk-textarea`, `nk-slider` | `{ value, name }` on every keystroke / drag |
|
|
3581
|
+
| `nk-toggle` | `nk-toggle`, tree branches, overlays | `{ open }` |
|
|
3582
|
+
| `nk-select` | tree items, menu items, breadcrumb, tabs, tab bar items, palette rows | `{ value, label, … }` |
|
|
3583
|
+
| `nk-view-change` | `nk-database` | `{ view }` |
|
|
3584
|
+
| `nk-command` | `nk-cmdk` | `{ id, item, query }` |
|
|
3585
|
+
| `nk-submit` | comment and AI input rows | `{ text }` |
|
|
3586
|
+
| `nk-action` | hover actions (tree +/⋯, section +, new row …) | `{ action, value? }` |
|
|
3587
|
+
|
|
3588
|
+
Form controls additionally re-dispatch a native, bubbling `change` event, so `form.addEventListener('change', …)` keeps working.
|
|
3589
|
+
|
|
3590
|
+
|
|
3591
|
+
# 6. Rules & Common Mistakes
|
|
3592
|
+
|
|
3593
|
+
### Always follow
|
|
3594
|
+
|
|
3595
|
+
1. `notionkit.css` on the document and `class="nk-body"` on `<body>` – the shadow roots inherit from there.
|
|
3596
|
+
2. `data-theme` on `<html>` only – the observer watches nothing else.
|
|
3597
|
+
3. Form controls inside a `<form>` if their value should be submitted; `FormData` reads them like native fields.
|
|
3598
|
+
4. Pass icons as the slotted node itself: `<span slot="icon">📌</span>`.
|
|
3599
|
+
5. Toggle state through attributes or properties (`el.open = true`, `el.setAttribute('active', '')`), never through classes inside the shadow root.
|
|
3600
|
+
6. `<nk-select>` options are direct `<option>`/`<optgroup>` children; change them in the light DOM and the element follows.
|
|
3601
|
+
7. Brand on `:root`, not on a subtree – tokens are inherited into every shadow root from the document.
|
|
3602
|
+
8. Import the bundle once per page. `customElements.define` throws on a second definition.
|
|
3603
|
+
|
|
3604
|
+
### Common mistakes
|
|
3605
|
+
|
|
3606
|
+
| Mistake | Correction |
|
|
3607
|
+
|---|---|
|
|
3608
|
+
| `<span slot="icon"><svg/></span>` (wrapped icon) | `<svg slot="icon">` – `::slotted()` matches only the assigned node |
|
|
3609
|
+
| Declaring `--nk-*` tokens inside a shadow root, or adopting the full `nkSheet` | Tokens go on the document (`:root`); elements adopt `componentsSheet` only |
|
|
3610
|
+
| Injecting your own CSS into `element.shadowRoot` | Restyle through tokens on `:root`; the elements carry no CSS of their own |
|
|
3611
|
+
| `data-theme` on a `<nk-*>` element or a wrapper div | Only `<html data-theme>` is observed |
|
|
3612
|
+
| `el.shadowRoot.querySelector('.nk-btn').classList.add('primary')` | `el.variant = 'primary'` |
|
|
3613
|
+
| `<nk-radio>`s with different `name`s expected to exclude each other | Same `name` in the same tree and form makes the group |
|
|
3614
|
+
| A form control outside `<form>` expected in `FormData` | Put it inside the form (or read `el.value`) |
|
|
3615
|
+
| `<button class="nk-btn">` inside `<nk-btn>` | The element renders the button – slot only the label and icon |
|
|
3616
|
+
| Loading the bundle without `notionkit.css` and wondering about the serif font | The token layer only covers colours and metrics; typography comes from `.nk-body` |
|
|
3617
|
+
| `<nk-btn style="margin-top:16px">` or `nk-callout { margin: … }` | Hosts are `display: contents` and have no box – put spacing on a wrapper you own |
|
|
3618
|
+
| A positioned wrapper around `<nk-menu>` to open it under a button | `<nk-menu floating sheet>` and `menu.show(button)`: it measures the button, closes on a tap outside and is a sheet on a phone |
|
|
3619
|
+
| `<nk-sheet id="more">` opened from `app.html#more` | Give the overlay an id other than the hash: the browser scrolls to the fragment target and takes the focus the overlay just gave |
|
|
3620
|
+
| `<nk-btn variant="topbar" onclick="sidebar.toggle()">☰</nk-btn>` plus a script that hides it on the desktop | `<nk-btn variant="sidebar">☰</nk-btn>` – shown below 860px only, opens the drawer |
|
|
3621
|
+
| A `<pre>` with a Copy button that writes `navigator.clipboard` itself | `<nk-copy-field value="…" mono>` – Copy, the green moment after, the ⌘C fallback; `secret` for keys |
|
|
3622
|
+
| A help or detail panel as a positioned `<aside>` with its own close logic | `<nk-peek>` – beside the page on the desktop, a sheet on a phone, Escape and outside clicks included |
|
|
3623
|
+
| A file input plus canvas code for an avatar or logo | `<nk-image-picker>` – EXIF rotation, scaling, a data URL in `nk-change` |
|
|
3624
|
+
| A positioned `<div>` with a scrim and its own Escape and focus logic for “Are you sure?” | `<nk-dialog alert title="…">` with `<nk-btn slot="actions" value="…">` – `nk-close` says which, and can be cancelled to check an input |
|
|
3625
|
+
| `title="…"` on buttons for hints, or a hand-positioned hint | One `<nk-tooltip>` and `data-tooltip` (and `data-tooltip-key`) on the buttons; `tip.show(rect, text)` for chart bars |
|
|
3626
|
+
| `hidden` on the sidebar plus an own button to widen the page on the desktop | `<nk-sidebar collapsible>` – the «, the ☰ of `<nk-btn variant="sidebar">`, ⌘\; `nk-collapse` to keep the state |
|
|
3627
|
+
| A padding on the page while the side peek is open, or a peek wider by CSS | `<nk-peek resizable inset>` – the width is `--nk-peek-width`, `nk-resize` to keep it |
|
|
3628
|
+
| A hand-built month grid, or `<input type="date">` for a date property | `<nk-calendar floating sheet>` and `picker.show(cell)` – the table's `nk-select` names the `key` and the `cell`; `range` for start and end, `weeks` for calendar weeks, `days` for holidays and marks |
|
|
3629
|
+
| Rows laid out in a table of weeks to show them by date | `<nk-calendar-view date-key="due">` in `<nk-database>` – a tab like table and board |
|
|
3630
|
+
|
|
3631
|
+
|
|
3632
|
+
# 7. Quick Reference
|
|
3633
|
+
|
|
3634
|
+
| Tag | Group | Key attributes | Key slots | Key events |
|
|
3635
|
+
|---|---|---|---|---|
|
|
3636
|
+
| `<nk-btn>` | forms | `variant`, `active`, `small`, `disabled` | `(default)` | `click` |
|
|
3637
|
+
| `<nk-input>` | forms | `value`, `type`, `placeholder`, `name` | – | `nk-change`, `nk-input` |
|
|
3638
|
+
| `<nk-copy-field>` | forms | `value`, `secret`, `mono`, `wrap` | – | `nk-action` |
|
|
3639
|
+
| `<nk-image-picker>` | forms | `src`, `initials`, `square`, `max` | – | `nk-change`, `nk-error` |
|
|
3640
|
+
| `<nk-calendar>` | forms | `value`, `month`, `min`, `max` | – | `nk-change`, `nk-month`, `nk-toggle` |
|
|
3641
|
+
| `<nk-textarea>` | forms | `value`, `placeholder`, `rows`, `name` | `(default)` | `nk-change`, `nk-input` |
|
|
3642
|
+
| `<nk-select>` | forms | `value`, `name`, `disabled`, `required` | `(default)` | `nk-change` |
|
|
3643
|
+
| `<nk-switch>` | forms | `checked`, `name`, `disabled`, `value` | `(default)` | `nk-change` |
|
|
3644
|
+
| `<nk-check>` | forms | `checked`, `indeterminate`, `name`, `disabled` | `(default)` | `nk-change` |
|
|
3645
|
+
| `<nk-radio>` | forms | `checked`, `name`, `disabled`, `value` | `(default)` | `nk-change` |
|
|
3646
|
+
| `<nk-slider>` | forms | `value`, `min`, `max`, `step` | – | `nk-change`, `nk-input` |
|
|
3647
|
+
| `<nk-field>` | forms | `label`, `desc`, `stacked`, `compact` | `(default)`, `label`, `desc` | – |
|
|
3648
|
+
| `<nk-fields>` | forms | `fit` | `(default)` | – |
|
|
3649
|
+
| `<nk-tag>` | content | `color` | `(default)` | – |
|
|
3650
|
+
| `<nk-progress>` | content | `value`, `max`, `label`, `wide` | – | – |
|
|
3651
|
+
| `<nk-callout>` | content | `icon` | `(default)`, `icon` | – |
|
|
3652
|
+
| `<nk-bookmark>` | content | `href`, `title`, `desc`, `favicon` | – | `click` |
|
|
3653
|
+
| `<nk-divider>` | content | – | – | – |
|
|
3654
|
+
| `<nk-heading>` | content | `level` | `(default)` | – |
|
|
3655
|
+
| `<nk-toggle>` | content | `label`, `open` | `(default)`, `label` | `nk-toggle` |
|
|
3656
|
+
| `<nk-todo>` | content | `checked`, `name`, `disabled`, `value` | `(default)` | `nk-change` |
|
|
3657
|
+
| `<nk-kbd>` | content | – | `(default)` | – |
|
|
3658
|
+
| `<nk-code>` | content | `lang`, `highlight` | `(default)` | – |
|
|
3659
|
+
| `<nk-quote>` | content | `cite` | `(default)` | – |
|
|
3660
|
+
| `<nk-app>` | shell | `peek-inset` | `sidebar`, `(default)` | – |
|
|
3661
|
+
| `<nk-sidebar>` | shell | `open`, `collapsible`, `collapsed`, `collapse-label` | `workspace`, `(default)`, `footer` | `nk-toggle`, `nk-collapse` |
|
|
3662
|
+
| `<nk-workspace-switcher>` | shell | `name`, `avatar`, `open` | `avatar`, `menu` | `nk-toggle`, `nk-select` |
|
|
3663
|
+
| `<nk-section-label>` | shell | `addable`, `label` | `(default)` | `nk-action` |
|
|
3664
|
+
| `<nk-tree>` | shell | `manual` | `(default)` | `nk-select`, `nk-toggle`, `nk-action` |
|
|
3665
|
+
| `<nk-tree-item>` | shell | `icon`, `label`, `value`, `href` | `(default)`, `icon`, `end` | `nk-select`, `nk-toggle`, `nk-action` |
|
|
3666
|
+
| `<nk-topbar>` | shell | – | `(default)`, `actions` | – |
|
|
3667
|
+
| `<nk-breadcrumb>` | shell | `separator` | `(default)` | `nk-select` |
|
|
3668
|
+
| `<nk-theme-toggle>` | shell | `storage-key`, `title` | – | `nk-change` |
|
|
3669
|
+
| `<nk-tab-bar>` | shell | `value`, `always`, `fixed`, `floating` | `(default)` | `nk-change`, `nk-select` |
|
|
3670
|
+
| `<nk-tab-bar-item>` | shell | `icon`, `value`, `label`, `href` | `(default)`, `icon` | `nk-select` |
|
|
3671
|
+
| `<nk-page>` | page | `icon`, `full`, `small`, `cover` | `(default)`, `cover`, `icon` | `nk-action` |
|
|
3672
|
+
| `<nk-page-cover>` | page | `src`, `position` | – | – |
|
|
3673
|
+
| `<nk-page-title>` | page | `editable`, `placeholder`, `value` | `(default)` | `nk-change` |
|
|
3674
|
+
| `<nk-page-actions>` | page | – | `(default)` | – |
|
|
3675
|
+
| `<nk-props>` | page | – | `(default)` | – |
|
|
3676
|
+
| `<nk-prop>` | page | `label`, `icon` | `(default)`, `icon` | `nk-action` |
|
|
3677
|
+
| `<nk-panels>` | page | – | `(default)` | – |
|
|
3678
|
+
| `<nk-panel>` | page | `title`, `icon`, `cover`, `href` | `(default)` | – |
|
|
3679
|
+
| `<nk-block-host>` | page | `handle`, `drop-target` | `(default)` | – |
|
|
3680
|
+
| `<nk-banner>` | page | `variant` | `(default)`, `action` | – |
|
|
3681
|
+
| `<nk-empty>` | page | `icon`, `title`, `desc` | `(default)`, `icon`, `title`, `desc` | – |
|
|
3682
|
+
| `<nk-skeleton>` | page | `lines`, `height`, `width`, `widths` | – | – |
|
|
3683
|
+
| `<nk-synced>` | page | `badge` | `(default)` | – |
|
|
3684
|
+
| `<nk-tabs>` | page | `value` | `(default)`, `panel` | `nk-change`, `nk-select` |
|
|
3685
|
+
| `<nk-tab>` | page | `value`, `active`, `disabled` | `(default)` | `nk-select` |
|
|
3686
|
+
| `<nk-segmented>` | page | `value`, `scroll`, `wrap`, `name` | `(default)` | `nk-change` |
|
|
3687
|
+
| `<nk-steps>` | page | `steps`, `current`, `label` | – | – |
|
|
3688
|
+
| `<nk-stats>` | page | `label`, `value`, `delta`, `trend` | `(default)` | – |
|
|
3689
|
+
| `<nk-stat>` | page | `label`, `value`, `delta`, `trend` | `label`, `value`, `delta` | – |
|
|
3690
|
+
| `<nk-avatar-group>` | page | `more` | `(default)` | – |
|
|
3691
|
+
| `<nk-avatar>` | page | `size`, `color`, `square`, `name` | `(default)` | – |
|
|
3692
|
+
| `<nk-mention>` | page | `type` | `avatar`, `(default)` | – |
|
|
3693
|
+
| `<nk-template-btn>` | page | `icon`, `value`, `disabled` | `(default)` | `nk-select` |
|
|
3694
|
+
| `<nk-model-card>` | page | `title`, `desc`, `name`, `disabled` | `title`, `desc` | `nk-change`, `nk-select` |
|
|
3695
|
+
| `<nk-profile-row>` | page | `avatar` | `avatar`, `(default)` | – |
|
|
3696
|
+
| `<nk-danger-zone>` | page | `title` | `(default)` | – |
|
|
3697
|
+
| `<nk-member-list>` | page | `name`, `mail`, `avatar`, `color` | `(default)`, `role`, `avatar` | – |
|
|
3698
|
+
| `<nk-member-row>` | page | `name`, `mail`, `avatar`, `color` | `role`, `avatar`, `(default)` | – |
|
|
3699
|
+
| `<nk-modal>` | overlays | `open`, `pane` | `(default)`, `user`, `nav` | `nk-toggle`, `nk-select` |
|
|
3700
|
+
| `<nk-sheet>` | overlays | `open`, `title` | `(default)` | `nk-toggle` |
|
|
3701
|
+
| `<nk-peek>` | overlays | `open`, `label`, `close-label`, `resizable` | `(default)`, `actions` | `nk-toggle`, `nk-resize` |
|
|
3702
|
+
| `<nk-dialog>` | overlays | `open`, `title`, `alert`, `wide` | `(default)`, `actions` | `nk-close`, `nk-toggle` |
|
|
3703
|
+
| `<nk-settings-pane>` | overlays | `name`, `label`, `icon`, `group` | `(default)` | – |
|
|
3704
|
+
| `<nk-settings-user>` | overlays | `name`, `mail`, `avatar` | `avatar` | – |
|
|
3705
|
+
| `<nk-cmdk>` | overlays | `open`, `hotkey`, `placeholder` | `footer` | `nk-command`, `nk-toggle` |
|
|
3706
|
+
| `<nk-menu>` | overlays | `floating`, `sheet`, `open`, `align` | `(default)` | `nk-select`, `nk-toggle` |
|
|
3707
|
+
| `<nk-menu-item>` | overlays | `icon`, `shortcut`, `value`, `danger` | `(default)`, `icon` | `nk-select`, `nk-change` |
|
|
3708
|
+
| `<nk-pop>` | overlays | `open`, `placement`, `bare` | `trigger`, `(default)` | `nk-toggle` |
|
|
3709
|
+
| `<nk-emoji-picker>` | overlays | `placeholder`, `value` | – | `nk-select` |
|
|
3710
|
+
| `<nk-toast>` | overlays | `open`, `duration`, `icon` | `(default)` | `nk-toggle` |
|
|
3711
|
+
| `<nk-tooltip>` | overlays | `for`, `shortcut`, `delay`, `placement` | `(default)` | – |
|
|
3712
|
+
| `<nk-database>` | data | `view`, `add-view` | `(default)`, `tools`, `filters` | `nk-view-change`, `nk-action`, `nk-select / nk-change / nk-action` |
|
|
3713
|
+
| `<nk-table-view>` | data | `name`, `label`, `badge`, `count` | – | `nk-select`, `nk-change`, `nk-action` |
|
|
3714
|
+
| `<nk-board-view>` | data | `name`, `label`, `group-by`, `title-key` | – | `nk-select`, `nk-change`, `nk-action` |
|
|
3715
|
+
| `<nk-list-view>` | data | `name`, `label`, `title-key`, `meta-keys` | – | `nk-select`, `nk-action` |
|
|
3716
|
+
| `<nk-calendar-view>` | data | `name`, `label`, `date-key`, `title-key` | – | `nk-select`, `nk-month` |
|
|
3717
|
+
| `<nk-filter-bar>` | data | `add`, `add-label`, `no-filter`, `no-sort` | `(default)` | `nk-change`, `nk-action` |
|
|
3718
|
+
| `<nk-comments>` | data | `placeholder`, `send-label`, `no-input`, `disabled` | `(default)` | `nk-submit` |
|
|
3719
|
+
| `<nk-comment>` | data | `author`, `time`, `avatar`, `color` | `(default)`, `head`, `avatar` | – |
|
|
3720
|
+
| `<nk-ai-thread>` | data | – | `(default)` | `nk-action` |
|
|
3721
|
+
| `<nk-ai-msg>` | data | `role`, `name`, `badge`, `avatar` | `(default)`, `actions`, `avatar` | `nk-action` |
|
|
3722
|
+
| `<nk-ai-input-row>` | data | `placeholder`, `value`, `disabled`, `icon` | – | `nk-submit` |
|
|
3723
|
+
|
|
3724
|
+
# 8. Framework Integration
|
|
3725
|
+
|
|
3726
|
+
- **Vanilla:** attributes for static config, properties for data, `addEventListener('nk-change', …)`.
|
|
3727
|
+
- **React:** use `ref` for properties and events (`ref.current.addEventListener('nk-change', …)`); boolean attributes need `checked={true ? '' : undefined}` or property assignment. React 19 sets properties automatically.
|
|
3728
|
+
- **Vue 3:** `app.config.compilerOptions.isCustomElement = tag => tag.startsWith('nk-')`; bind data with `.prop` (`:rows.prop="rows"`), listen with `@nk-change`.
|
|
3729
|
+
- **Svelte:** works out of the box; `on:nk-change`; properties via `bind:this` + assignment.
|
|
3730
|
+
- **SSR:** the elements render client-side. Server-render the page with `.nk-*` class markup where first paint matters and let the elements take over the interactive parts.
|
|
3731
|
+
|
|
3732
|
+
|
|
3733
|
+
# 9. Architecture Notes
|
|
3734
|
+
|
|
3735
|
+
| Concept | Location |
|
|
3736
|
+
|---|---|
|
|
3737
|
+
| Base classes `NkElement` / `NkFormElement` | `src/base.js` – shadow root, adopted `componentsSheet`, theme wrapper, `render/setupEvents/teardownEvents/onAttributeChanged/projectLightDom/refresh`, ElementInternals |
|
|
3738
|
+
| Token injection | `src/base.js` – once per page, `@layer notionkit-defaults { tokensCss }` appended to `document.adoptedStyleSheets` |
|
|
3739
|
+
| Theme sync | one `MutationObserver` on `<html>[data-theme]`, a `Set` of instances, `.nk-wrapper[data-theme]` inside each root |
|
|
3740
|
+
| Components | `src/components/{forms,content,shell,page,overlays,data}/nk-*.js`, one tag per file, `customElements.define` at the bottom |
|
|
3741
|
+
| 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` |
|
|
3742
|
+
| Peer | `@jungherz-de/notionkit >= 1.11.1` – 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 |
|
|
3743
|
+
|
|
3744
|
+
Lifecycle: construct (attach shadow, adopt sheets) → first connect (wrapper + `render()`) → every connect (`setupEvents()`, theme registration, light-DOM observer) → `attributeChangedCallback` → `onAttributeChanged` → disconnect (`teardownEvents()`, unregister).
|
|
3745
|
+
|
|
3746
|
+
|
|
3747
|
+
---
|
|
3748
|
+
*NotionKit Elements v1.11.1 · wrapping NotionKit CSS v1.11.1 · MIT · Jungherz GmbH*
|