@jungherz-de/notionkit-elements 1.11.0 → 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 ADDED
@@ -0,0 +1,641 @@
1
+ # Changelog
2
+
3
+ All notable changes to NotionKit Elements are documented here. The format follows
4
+ [Keep a Changelog](https://keepachangelog.com/en/1.1.0/); versions follow
5
+ [Semantic Versioning](https://semver.org/).
6
+
7
+ ## [1.11.1] – 2026-09-24
8
+
9
+ Built against NotionKit CSS 1.11.1 (peer `>= 1.11.0`).
10
+
11
+ ### Fixed
12
+ - **The package carries SKILL.md and CHANGELOG.md.** `files` in package.json listed `dist/`, `src/` and `LICENSE` only, so no release since 1.0.0 had them. LearnHub found them missing while moving to 1.11.0: an agent that reads SKILL.md from `node_modules` had to fetch it from GitHub.
13
+ - **The bundles name no source map.** They embed NotionKit's stylesheet, whose CSS ended in a `sourceMappingURL` comment, so DevTools looked for `notionkit.min.css.map` on the server of every app that loads Elements. NotionKit 1.11.1 drops the comment from the embedded copy.
14
+
15
+ ### Added
16
+ - `npm run check:package`, in CI too: it packs the package without publishing and fails when an entry point of package.json, SKILL.md, CHANGELOG.md or a source map named by a shipped file is missing.
17
+
18
+ ## [1.11.0] – 2026-09-24
19
+
20
+ Built against NotionKit CSS 1.11.0 (peer `>= 1.11.0`). SupaGantt's first weeks on Elements turned up thirteen findings; this release answers all of them. One matters beyond SupaGantt: an `<nk-switch>` without content froze Safari – the demo, the landing page, the docs and the showcase among the pages it hung.
21
+
22
+ ### Fixed
23
+ - **An `<nk-switch>` without content no longer freezes Safari** – since 1.2.0 it did. `_syncText()` wrote the slot's fallback text on every call, WebKit fires `slotchange` for such a write even when the text stays the same, and `slotchange` called `_syncText()` again – an endless loop at 100 % CPU for `<nk-switch></nk-switch>` or `<nk-switch text="…"></nk-switch>`. Chromium was never affected, so no test saw it – and the demo, the landing page, the docs and the showcase all have such switches. It writes on a change only now, and so do `<nk-page>`, `<nk-ai-msg>` and `<nk-tree-item>`, which write fallback text as well.
24
+ - **`<nk-dialog>` closes for its actions only.** Any button with a `value` inside closed it, an option of an `<nk-segmented>` too, with the option's value as the result. Now a button in `slot="actions"` with a `value` closes it, and one anywhere inside with `data-close` – with that attribute's value.
25
+ - **`<nk-select>` keeps a value set before its options.** A framework that sets properties before children – Hybrids – set `value` while the select had no `<option>` yet, and the first option showed. The value now waits and is applied once its option arrives; until then `value` reports it.
26
+ - **A floating menu or date picker inside an open `<nk-modal>` or `<nk-dialog>` sits under its anchor.** Their surfaces kept a transform at rest, which made them the containing block of the fixed menu: it opened off by the surface's position and clipped by its overflow. NotionKit 1.11.0 gives the open surfaces no transform at all, and `placeUnder()` and `placeNear()` measure the frame the host really sits in and take it off, for a transformed ancestor of one's own.
27
+ - **`<nk-menu floating>` and `<nk-calendar floating>` take no room before their first `show()`.** The fixed host stood at its static position in the flow until then – a long page grew by thousands of pixels, and focusing moved it. The host starts at the window's top left corner.
28
+ - **`<nk-tree-item>` takes every text node for its label**, empty and blank ones too: a template engine fills an expression's node after the item is built – `${i} ${title}` read “1Projekte”, and children showed only a “.”.
29
+ - **`<nk-avatar>` initials skip punctuation.** They are the first letter or digit of each word, and a word without one is skipped: “Planer (Dev)” → PD, not P(; “Anna-Lena Groß” → AG. The same goes for every element that draws initials from a name – member rows, comments, people in the database views.
30
+ - **`<nk-filter-bar>` never changes the caller's array.** Removing a pill spliced the array given to `filters`; the bar keeps a copy now, `filters` returns one, and `nk-change` reports the new list.
31
+ - **The banner's action is a button.** `slot="action"` takes a `<button>`, which NotionKit 1.11.0 strips down to underlined text – a button's role and keyboard instead of a span with `role="button"` and a key handler of one's own. Below 860px the action moves under the text, as the docs promised, instead of squeezing the text into a narrow column beside it.
32
+ - **SKILL.md documents `<nk-menu-item type="check">`** – a ✓ where the shortcut stands, `nk-change { value, checked }` instead of `nk-select`, the menu stays open – and the new behaviour of `<nk-dialog>`, `<nk-select>`, `<nk-menu>`, `<nk-tooltip>`, `<nk-avatar>` and `<nk-filter-bar>`.
33
+
34
+ ### Added
35
+ - **`<nk-fields fit>`**: the fields share the row instead of keeping 150px columns – two fields in a wide dialog are two halves, not two thirds and an empty third column. NotionKit's `.nk-fields.fit`.
36
+ - **A floating menu opens upwards and never outgrows the window.** Where the window ends below and there is more room above, `<nk-menu floating>` and `<nk-calendar floating>` open above their anchor; either way they are capped to the room there and a longer menu scrolls – 48 assignees near the bottom of the window.
37
+ - **`<nk-tooltip>` for a rect stays, keeps line breaks and hides on the wheel.** A tooltip shown with `show(rect, text)` – a bar of a Gantt chart – stays until `hide()`, the pointer on another `[data-tooltip]`, a press or Escape; before, one shown in the same `pointerover` that left a `[data-tooltip]` closed at once. A line break in the text is kept (NotionKit's `.nk-tooltip.lines`), a long word breaks, and the wheel hides it – scroll events do not leave a shadow root, so scrolling inside a component left it standing.
38
+
39
+ ### Changed
40
+ - Tests run in WebKit too: every page loads and answers in WebKit, and the settings pane with its empty switches renders – the suite that would have caught the Safari freeze. CI installs Chromium and WebKit.
41
+ - Docs, showcase, SKILL.md and the demo write the banner's action as a `<button>`.
42
+ - Peer `@jungherz-de/notionkit >= 1.11.0`.
43
+
44
+ ## [1.10.1] – 2026-09-24
45
+
46
+ Built against NotionKit CSS 1.10.1 (peer `>= 1.10.1`).
47
+
48
+ ### Fixed
49
+ - **A disabled `<nk-btn>` shows its tooltip and its `title`.** NotionKit gave `.nk-btn:disabled` `pointer-events: none`, so the hint that says why a button is disabled never appeared – with `<nk-tooltip>` and `data-tooltip` no more than with `title` – and a click fell through to the element behind it, a table row say. Since NotionKit 1.10.1 a disabled button takes the pointer and shows the `not-allowed` cursor, hover leaves it alone, and a click reaches nothing. A disabled link button (`<nk-btn href disabled>`) is dimmed as well. Found in Auxdesk.
50
+
51
+ ## [1.10.0] – 2026-09-24
52
+
53
+ Built against NotionKit CSS 1.10.0 (peer `>= 1.10.0`), shell and overlays: two new elements – 87 in all – and two that grow. SupaGantt asked for all four: a Gantt chart at full width, bars that stay visible beside the peek, confirmation and input dialogs, hints on bars and the ribbon.
54
+
55
+ ### Added
56
+ - **`<nk-dialog>`** – a question or a short form with the contract of `<nk-modal>` and `<nk-sheet>`: `show()`, `close()`, `toggle()`, `nk-toggle`; Escape – captured, so it closes 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 and lifts the inertness a modal gave it, so a question can come from inside one. `title` is the heading and the dialog's name, never a tooltip; the default slot takes the text or the fields, `slot="actions"` the buttons. A button with a `value` closes it with that value, so does the submit of a `<form method="dialog">` inside; `nk-close { value }` fires first and can be cancelled – the place to check an input. `returnValue`, `alert` (an alertdialog described by its text), `wide` (560px), `show(from)` to hand focus back to the ⋯ of a menu that has closed. Below 860px a bottom sheet with the buttons stacked, the confirming one on top.
57
+ - **`<nk-tooltip>`** – Notion's hover hint. One element without `for` serves every `[data-tooltip]` (with `data-tooltip-key` for a shortcut) 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`. After `delay` ms (400) under the pointer, at once on keyboard focus, never on touch; leaving, a press, blur, scrolling and Escape hide it. 6px below its target and centred, above it where the window ends (`placement="top"` prefers above), 8px inside the window. `show(target, text, shortcut)` takes an element or a rect – the bars of a chart. The target's `aria-describedby` names it while it shows.
58
+ - **`<nk-sidebar collapsible>`** – Notion's « beside the workspace row, shown while the pointer is over the sidebar: on the desktop it collapses the sidebar, the main column takes the width, nothing in it takes focus; `<nk-btn variant="sidebar">` shows on the desktop too while it is collapsed and brings it back; ⌘\ or Ctrl+\ toggles it, on a phone the drawer. `collapsed`, `collapse()`, `expand()`, `toggleCollapsed()`, `nk-collapse { collapsed }` to keep it, `collapse-label`. Focus moves to the control that is left.
59
+ - **`<nk-peek resizable inset>`** – `resizable` puts Notion's drag on the left edge, with the arrow keys as well (16px a step), from `min` (380) to `max` (all but 320px of the window); the width is NotionKit's new token `--nk-peek-width`, set on `:root`, `width` sets it and `nk-resize { width }` is the moment to keep it. `inset` makes the page's `<nk-app>` move aside while the peek is open on the desktop (`peek-inset`, also an attribute of `<nk-app>`).
60
+ - `placeNear()` in `util/floating.js` – the tooltip's placement, for an element or a rect.
61
+
62
+ ### Changed
63
+ - Demo: « and ⌘\ collapse the sidebar, the ☰ brings it back; the side peek resizes; “Move to trash” in the page menu asks first, and the + view tab asks for a name and a layout; the topbar's buttons and the « have tooltips; `#dialog` opens the question. The app matches the class demo at 0.00 % – the collapsed sidebar, the tooltip, both dialogs, the dialog as a sheet on a phone and a wider peek included.
64
+ - `<nk-workspace-switcher>` fills the new sidebar head beside the «.
65
+ - Peer `@jungherz-de/notionkit >= 1.10.0`.
66
+
67
+ ## [1.9.0] – 2026-09-24
68
+
69
+ Built against NotionKit CSS 1.9.0 (peer `>= 1.9.0`), dates: a date picker
70
+ and a calendar view – 85 elements in all. SupaGantt, a planning tool about
71
+ to start on NotionKit, asked for both: start and end, constraints and
72
+ deadlines, with calendar weeks, working days and holidays.
73
+
74
+ ### Added
75
+ - **`<nk-calendar>`** – Notion's date picker (forms): a month with Today
76
+ and ‹ ›, form-associated. The value is a day (`YYYY-MM-DD`); with `range`
77
+ an interval `start/end`, picked in two clicks in either order; with
78
+ `time` a day and a time (`YYYY-MM-DDTHH:MM`) from a time field under the
79
+ month; `clearable` adds Clear. `weeks` puts the ISO calendar week in front
80
+ of each row – “KW” in German –, `weekend` greys the days not worked, and
81
+ the `days` property (or JSON attribute) adds holidays (`off` with a
82
+ `label`, which is also announced) and up to three `marks` per day in the
83
+ nine colours. Days outside `min`/`max` are `aria-disabled`: in the arrow
84
+ path and announced, never picked. After GlassKit Elements'
85
+ `<glk-calendar>`: arrows move by a day or a week, Home/End to the ends of
86
+ the week, PageUp/PageDown by a month (with Shift a year) – moving picks
87
+ nothing –, Enter or Space picks; one day is in the tab order; month names,
88
+ weekdays and the first day of the week come from `Intl` and the page's
89
+ language, `week-start` overrides; a new value brings its month;
90
+ `nk-change { value, start, end, time }` only when the value changes,
91
+ `nk-month`, `required`, reset. `floating sheet` makes it a popover that
92
+ `show(anchor)` puts under a property or a cell – a bottom sheet with 44px
93
+ cells on a phone – with `<nk-menu floating>`'s contract: a tap outside
94
+ closes it and reaches nothing else, Escape closes it, focus goes in when
95
+ opened from the keyboard and comes back; a pick closes it, the second of a
96
+ range.
97
+ - **`<nk-calendar-view>`** – the fourth database view: a month, the rows as
98
+ cards on their dates (`date-key`, default the first date column;
99
+ `YYYY-MM-DD`, `D.M.YYYY` or a range on its start). Today on a red pill,
100
+ days of other months washed, `weeks`, `weekend`, `week-start`; a card
101
+ fires `nk-select` like a row of the table, Today and ‹ › `nk-month`. In
102
+ `<nk-database>` a tab like the others, with the same rows.
103
+ - `nk-select` of `<nk-table-view>` says which cell was hit: `key` names its
104
+ column and `cell` is the `<td>`, to open an editor there – the date picker
105
+ under a due date.
106
+
107
+ ### Changed
108
+ - Demo: Due under the title and the table's due dates open one
109
+ `<nk-calendar floating sheet weeks>` – on the month of the date, weekends
110
+ and holidays greyed, the projects' due dates dotted –, a new date reaches
111
+ table, board, list and calendar; the database has a 📅 Calendar tab whose
112
+ cards open the side peek; `#date` and `#calendar` open those states. The
113
+ app matches the class demo at 0.00 % – the picker on the desktop and as a
114
+ sheet on a phone, the calendar view in two months included.
115
+ - `<nk-menu floating>` and `<nk-calendar floating>` share their placement
116
+ (`src/util/floating.js`).
117
+ - Peer `@jungherz-de/notionkit >= 1.9.0`.
118
+
119
+ ## [1.8.0] – 2026-09-24
120
+
121
+ Built against NotionKit CSS 1.8.0 (peer `>= 1.8.0`), links and peeks: four
122
+ new elements – 83 in all – for what LearnHub and Auxdesk each built on
123
+ their own: a side peek, a bookmark, a copy field and an image picker.
124
+
125
+ ### Added
126
+ - **`<nk-peek>`** – Notion's side peek: a database row at the right edge,
127
+ full height, next to the table, which stays usable – no scrim, nothing
128
+ inert. The bar carries » to close and `slot="actions"`; the body is the
129
+ page – `nk-page-title` (32px there), `nk-props`, a `.nk-prose`,
130
+ `nk-comments`. `show()` slides it in and moves focus to it; », Escape and
131
+ a click elsewhere close it, and Escape and » hand focus back. A click that
132
+ calls `show()` again – another row – only swaps the content, and clicks
133
+ inside other overlays (a menu opened from the peek) leave it open. Below
134
+ 860px it is a bottom sheet over a dimmed page and modal there: inert page,
135
+ scroll lock, a tap on the dimmed page closes it. `nk-toggle`. LearnHub's
136
+ contextual help is such a panel.
137
+ - **`<nk-bookmark>`** – Notion's link block from `href`, `title`, `desc`,
138
+ `favicon` and `cover` – what `og:title`, `og:description` and `og:image`
139
+ give. `title` is the heading, never a tooltip; without it the host name
140
+ stands in; `url` shows another address than `href`; a part without a
141
+ value is left out. Opens in a new tab unless `target` says otherwise.
142
+ LearnHub shows with it how a shared course link will look.
143
+ - **`<nk-copy-field>`** – a value to take along, as tall as an input, with
144
+ Copy inside: the clipboard, then “Copied” in green for a moment; where the
145
+ clipboard is not allowed, the value is shown and selected for ⌘C.
146
+ `secret` masks it behind Show/Hide and Copy still copies the real value;
147
+ `value` set as a property is not reflected, so a key never lands in the
148
+ markup. `mono`, `wrap`, `wide`; the texts are attributes. Fires
149
+ `nk-action { action: 'copy', value, ok }`. Auxdesk's inbound addresses,
150
+ Notion URL, widget secret and embed code are such values.
151
+ - **`<nk-image-picker>`** – a picture for a person or a workspace on
152
+ NotionKit's profile row, round or `square`, with Upload / Change and
153
+ Remove. Ported from GlassKit Elements' `glk-image-picker`: decoded with
154
+ the EXIF rotation (`createImageBitmap`, `imageOrientation: 'from-image'`),
155
+ drawn no larger than `max` (512), out as `type` at `quality`, handed over
156
+ as a data URL in `nk-change`; an unreadable file fires `nk-error`. `src`
157
+ as a property is not reflected. LearnHub needs it for the customer logo.
158
+
159
+ ### Changed
160
+ - Demo: a row, a card or a list item opens in `<nk-peek>` with its
161
+ properties, notes and a comment (it was a toast); the bookmark follows
162
+ the core-idea callout; the profile picture and a square workspace icon are
163
+ `<nk-image-picker>`s; General shows the public address in an
164
+ `<nk-copy-field>`; `#peek` opens the table row. The app matches the class
165
+ demo at 0.00 % – the open peek on the desktop and as a sheet on a phone
166
+ included.
167
+ - The social card is rendered with the element count and the bundle size
168
+ from the build; it said 68 elements and 33 KB.
169
+ - Peer `@jungherz-de/notionkit >= 1.8.0`.
170
+
171
+ ## [1.7.0] – 2026-09-24
172
+
173
+ Built against NotionKit CSS 1.7.1 (peer `>= 1.7.1`), the mobile-and-filter
174
+ release: menus that float in and become sheets on a phone, a sheet of its
175
+ own, the drawer from the stylesheet, Notion's database toolbar with filter
176
+ pills, and steps. 1.7.1, not 1.7.0: clean-css broke the minified files of
177
+ 1.7.0, and those are what the elements adopt – every phone rule after the
178
+ drawer applied on the desktop too (see NotionKit's changelog).
179
+
180
+ ### Added
181
+ - **`<nk-sheet>`** – Notion's mobile surface, the phone's twin of
182
+ `<nk-modal>` with its contract: `show()`, `close()`, `toggle()`; Escape
183
+ and the backdrop close it; focus moves in and back; the page behind is
184
+ scroll-locked and inert; `nk-toggle`. The panel rises from the bottom edge
185
+ with a grabber, `title` stands under it and names the dialog (taken off
186
+ the host, never a tooltip), rows inside are 40px. A chosen row does not
187
+ close it – `nk-select` bubbles out and the app decides.
188
+ - **`<nk-steps>`** – a short flow, vertical: done steps with a check on the
189
+ green tag, the current one ringed in the accent and marked
190
+ `aria-current="step"`. `current` counts from 1 and `next()` moves on;
191
+ `steps` is a comma-separated list or, as a property, strings and
192
+ `{ label, desc }` objects; `label` names the list.
193
+ - **`<nk-menu floating sheet>`** – a menu over the page of its own:
194
+ `menu.show(button)` opens it under the button, right edges aligned
195
+ (`align="start"`: left edges), and it fades in like the palette. A tap
196
+ outside closes it and reaches nothing else; Escape and a chosen item close
197
+ it, a switch or check row keeps it open; opened from the keyboard, focus
198
+ moves to the first item and back; `aria-expanded` on the button follows.
199
+ With `sheet` it is a bottom sheet below 860px, whatever position `show()`
200
+ wrote. `nk-toggle` when it opens and closes.
201
+ - **`<nk-menu-item type="check">`** – a ✓ where the shortcut stands,
202
+ `menuitemcheckbox`: a click flips `checked` and fires `nk-change`, and the
203
+ menu stays open – the rows of a filter menu.
204
+ - **The database toolbar.** `<nk-database>` renders NotionKit's
205
+ `.nk-db-toolbar`: the view tabs on the left, `slot="tools"` on the right,
206
+ `slot="filters"` under it. `<nk-btn variant="tool">` is a tool, `active`
207
+ gives it the accent. The + tab is `.nk-db-tab.add`, no inline style.
208
+ - **`<nk-btn variant="sidebar">`** – the ☰, `.nk-topbar-btn.nk-sidebar-toggle`:
209
+ shown below 860px only, a click opens the `nk-sidebar` of its app as a
210
+ drawer, and `aria-expanded` follows however the drawer closes.
211
+ - `<nk-segmented scroll>` keeps the chosen option in view – after the first
212
+ layout, on every change and when the row's width changes – by scrolling
213
+ the row, never the page, the least distance, right to left as well.
214
+ - `<nk-btn aria-haspopup>` reaches the button, like `aria-label`.
215
+
216
+ ### Changed
217
+ - **`<nk-filter-bar>` is NotionKit's filter pills** (`.nk-filter-row`,
218
+ `.nk-filter-pill`, `.fp-remove`, `.add`) instead of tags laid out by
219
+ inline styles: a pill per filter with its ×, the `add` pill at the end;
220
+ its own Filter and Sort are `.nk-db-tool`s. A pill's label fires
221
+ `nk-action { action: 'edit', index, filter, anchor }`, the add pill
222
+ `{ action: 'add', anchor }` – `anchor` is the clicked button, for
223
+ `menu.show(anchor)`. A filter takes `op: 'is-not'`; `color` is no longer
224
+ read, a pill has one look. The texts are attributes: `filter-label`,
225
+ `sort-label`, `add-label`, `remove-label`.
226
+ - **The sidebar drawer is the stylesheet's.** `<nk-sidebar open>` sets
227
+ NotionKit 1.7.0's `.nk-sidebar.open` and `.nk-sidebar-backdrop.open`; the
228
+ element's own drawer CSS is gone. Same slide and scrim; with reduced
229
+ motion the stylesheet shortens the transition to .01ms.
230
+ - Overlays return focus to the control that had it, also when it sits in a
231
+ shadow root (`nk-sheet`, `nk-menu`); a floating menu's Escape is handled
232
+ before a modal's or a sheet's around it.
233
+ - Demo: the database toolbar with live filter pills – "Status: Open" set –
234
+ on table, board and list, a filter menu, Sort, search and New; the ⋯ page
235
+ menu is `<nk-menu floating sheet>` (the positioned wrapper is gone); More
236
+ opens an `<nk-sheet>`; the ☰ is `variant="sidebar"`; the steps in the AI
237
+ pane for a custom model; six ranges in a scrolling segmented control;
238
+ `#menu`, `#filter`, `#more` and `#settings` open that state. The modal is
239
+ `id="settingsModal"`, the sheet `id="moreSheet"`: an id equal to the hash
240
+ made the browser scroll to it and take the focus it had just been given.
241
+ The app matches the class demo at 0.00 % on the desktop, in the menus and
242
+ in the phone's sheets and drawer.
243
+ - Peer `@jungherz-de/notionkit >= 1.7.1`.
244
+
245
+ ## [1.6.0] – 2026-09-23
246
+
247
+ Built against NotionKit CSS 1.6.0 (peer `>= 1.6.0`), the app-views release:
248
+ six new elements for the base layer that LearnHub and Auxdesk each built on
249
+ their own, and a per-component build that no longer carries its own copy
250
+ of the stylesheet.
251
+
252
+ ### Added
253
+ - **`<nk-props>` and `<nk-prop>`** – the properties under the title of a
254
+ database page: `label` and `icon` name the row, the content is the value
255
+ (tags, `<nk-avatar>`, a date, `<nk-progress wide>`). Rows are
256
+ `display: contents` hosts, so each renders as a row of the list; a click
257
+ fires `nk-action` with the half that was hit. Stacks below 860px.
258
+ - **`<nk-list-view>`** – the third view of `<nk-database>`: one line per
259
+ row, icon and title, `meta-keys` on the right (default: the select and
260
+ date columns). Rows fire `nk-select`, also on Enter; works standalone
261
+ with `columns` and `rows`.
262
+ - **`<nk-panels>` and `<nk-panel>`** – neutral surfaces in a grid that
263
+ falls to one column on a phone. `title` is the heading (taken off the
264
+ host, never a tooltip), `cover` draws the gradient band or a picture,
265
+ `icon` overlaps it – a page tile as on Notion's Home – and `href` makes
266
+ the panel a link.
267
+ - **`<nk-avatar>`** – initials, an emoji or a photo: `size` small / large /
268
+ xlarge, `color` one of the nine names or any CSS background, `square`,
269
+ initials from `name`, a photo from `src` with `name` as its alt text.
270
+ - `<nk-page full small>` – Notion's page options, full width and small
271
+ text, on the page itself.
272
+ - `<nk-page-cover src position>` draws the picture as an `<img>`, cropped
273
+ rather than stretched; `position` moves the crop.
274
+ - `<nk-ai-msg bubble>` – the message as a grey bubble without avatar or
275
+ name, on the right with `role="user"`, as Notion's AI chat shows your own
276
+ question.
277
+ - `<nk-progress wide>` fills its row and keeps its label beside it.
278
+ - `<nk-menu-item type="switch" checked>` – a row with a switch on the
279
+ right, like “Small text” in Notion's page menu. A click flips `checked`
280
+ and fires `nk-change`, not `nk-select`, so the menu stays open.
281
+ - Number columns stand right-aligned in figures of equal width
282
+ (`td.num`), formatted by the column's `locale` and `format`
283
+ (Intl.NumberFormat options).
284
+ - `componentsSheet` is exported from the bundle
285
+ (`NotionKitElements.componentsSheet` from the `<script>` build): a
286
+ project's own views adopt the same instance as the elements instead of
287
+ loading NotionKit's stylesheet a second time. LearnHub and Auxdesk loaded
288
+ it twice.
289
+ - `@jungherz-de/notionkit-elements/base.js` – `NkElement` and
290
+ `NkFormElement` for per-component setups, from a stable file.
291
+ - `test/app-views.spec.mjs`, 15 tests; six new parity pairs (twelve with
292
+ both themes).
293
+
294
+ ### Changed
295
+ - **The per-component files import NotionKit's stylesheet instead of
296
+ inlining it.** The base chunk carried the whole sheet – 64 KB – under a
297
+ hashed name that changed with every build. It is now
298
+ `dist/components/base.js`, 13 KB, and imports
299
+ `@jungherz-de/notionkit/notionkit-styles.js`: a bundler resolves it from
300
+ `node_modules`, a build-free page adds one import-map entry, and the
301
+ sheet exists once. The full bundles keep inlining it – a `<script>` tag
302
+ has nothing to resolve against. (GlassKit Elements 1.14.0 and 1.15.0
303
+ did the same.)
304
+ - `<nk-member-row>`, `<nk-comment>` and the person cells of the database
305
+ views draw their avatar as `.nk-avatar`. `color` takes the nine colour
306
+ names as classes – no hex value needed in markup – and still any CSS
307
+ background; **without `color` the avatar takes the gradient**, the
308
+ avatar component's default, instead of the tertiary grey.
309
+
310
+ ### Site
311
+ - The reference app shows the same new placements as the NotionKit demo:
312
+ properties under the title, the ⋯ page menu with small text and full
313
+ width, “List” as third view and an “Effort” column, “Edit · Read” for the
314
+ editor, your own question as a grey bubble, members with named avatar
315
+ colours, and the start view behind “Home”. Against the class version at
316
+ 1280px: 0.00 % pixel difference in both themes, the start view included.
317
+ - Landing page: “Same look, a fraction of the markup” gets the page
318
+ properties as its second example; 77 elements.
319
+
320
+ ## [1.5.3] – 2026-09-23
321
+
322
+ Built against NotionKit CSS 1.5.3 (peer `>= 1.5.3`), the phone release.
323
+
324
+ ### Fixed
325
+ - Through NotionKit 1.5.3: on phones `<nk-topbar>` keeps to one row – only
326
+ the last crumb of `<nk-breadcrumb>` stays, ending in an ellipsis, and
327
+ passive text steps aside. `<nk-field>` rows wrap, so the settings modal
328
+ keeps to the screen – five of the six panes in the demo ran up to 66px
329
+ past a 390px screen. `<nk-member-row>` ends a long address in an
330
+ ellipsis instead of pushing the role select out.
331
+ - Demo and docs use `<span class="nk-topbar-meta">` for passive text in the
332
+ topbar, new in NotionKit 1.5.3, instead of an inline-styled
333
+ `nk-topbar-btn`. The topbar is documented as 44px, not 45px.
334
+
335
+ ### Added
336
+ - `test/phone.spec.mjs`: at 390px no page of the site scrolls sideways,
337
+ every settings pane keeps to the screen, and the topbar keeps to one row.
338
+
339
+ ### Site
340
+ - Navigation on phones: the links move into a second row that scrolls
341
+ sideways. The flat row made every page 748px wide on a 390px phone.
342
+ Anchors in the docs land below the taller bar.
343
+ - Docs: attribute and event tables scroll inside their own box; the
344
+ database entry's table made the docs page 437px wide on a phone.
345
+
346
+ ## [1.5.2] – 2026-09-23
347
+
348
+ Built against NotionKit CSS 1.5.2 (peer `>= 1.5.2`). Two fixes GlassKit
349
+ Elements had made before, plus the foundation's five fixes by rebuild.
350
+
351
+ ### Fixed
352
+ - **`title` showed as a browser tooltip.** `<nk-settings-pane>`,
353
+ `<nk-danger-zone>`, `<nk-empty>` and `<nk-model-card>` take their
354
+ heading from `title` – which is also the global HTML attribute, so
355
+ hovering a settings pane floated its heading over the whole pane, and the
356
+ model cards and the danger zone did the same. The elements now read the
357
+ attribute and take it off the host (`NkElement.takeTitle()`): a later
358
+ `setAttribute('title', …)` is taken the same way, `el.title` answers
359
+ from the stored value, and setting it never writes the attribute – so a
360
+ framework that binds `title` as a property (hybrids, lit's `.title`)
361
+ never puts one on the host. The API is unchanged, `title="…"` stays the
362
+ documented attribute; what changes is that `getAttribute('title')`
363
+ returns `null` after upgrade. `<nk-model-card>` still reports its name
364
+ in `nk-select`. (GlassKit Elements 1.16.1.)
365
+ - **Several actions in `<nk-empty>` touched.** The default slot now sits
366
+ in `.e-actions`, a centred row that wraps with 8px between the buttons
367
+ (NotionKit 1.5.2).
368
+ - **`<nk-toast>` lay behind the tab bar on a phone.** notionkit.css lifts a
369
+ class-markup toast above a visible tab bar with `:has()`, which cannot
370
+ see into shadow roots, so the element measures the bar when it opens and
371
+ sits 12px above it – the app's own bar at the bottom of the screen,
372
+ sticky, fixed or floating. A tab bar previewed somewhere inside a page
373
+ does not lift it.
374
+ - Through NotionKit 1.5.2: `hidden` hides every nk- element and slotted
375
+ node, the toast paints above dialog and palette and keeps a short message
376
+ on one line on a phone, date and time fields keep to their column on iOS,
377
+ and checkbox and switch sit beside the first line of a wrapping label.
378
+
379
+ ### Added
380
+ - `test/regressions-152.spec.mjs`: the title handling of all four
381
+ elements, including a title set as a property before upgrade, the
382
+ empty-state action row and the toast over the app's tab bar. Against the
383
+ 1.5.1 bundle seven of the nine tests fail.
384
+ - Demo app: "Import" next to "New entry" in the empty state, and a
385
+ two-line product-news checkbox in the notification settings – the same
386
+ changes as in the NotionKit demo.
387
+
388
+ ## [1.5.1] – 2026-09-14
389
+
390
+ Built against NotionKit CSS 1.5.1 (peer `>= 1.5.1`).
391
+
392
+ ### Fixed
393
+ - **`nk-sidebar` drawer transition.** Below 860px the drawer used to snap
394
+ in and out (a bare `display` switch). It now slides in over 240ms while
395
+ the scrim fades, and closing runs the same way backwards – CSS only:
396
+ `display` transitions with `transition-behavior: allow-discrete`,
397
+ `@starting-style` supplies the first frame, `position: fixed` applies in
398
+ both states so the closing aside does not fall back into the flow.
399
+ Browsers without either feature switch hard as before;
400
+ `prefers-reduced-motion` snaps. Crossing the breakpoint downwards runs the
401
+ slide-out once.
402
+ - Through NotionKit 1.5.1: the tab bar no longer stacks its 6px on the
403
+ home-indicator inset, and topbar, page, tab bar and the drawer honour the
404
+ left/right safe-area insets (Dynamic Island in landscape). Reported by
405
+ Auxdesk.
406
+
407
+ ## [1.5.0] – 2026-09-13
408
+
409
+ Rebuilt against NotionKit CSS 1.5.0 (peer `>= 1.5.0`) – the Notion-2025
410
+ fidelity release: darker text greys and a dedicated sidebar text colour,
411
+ `-webkit-font-smoothing: auto`, filled inputs, white buttons, 36px table
412
+ rows, pill view tabs. From this release on, Elements and the foundation
413
+ share one version number (1.4.x is skipped).
414
+
415
+ ### Added
416
+ - `nk-tag color` accepts all nine Notion select colours: `gray`, `brown`,
417
+ `orange`, `yellow`, `green`, `blue`, `purple`, `pink`, `red`. Without
418
+ `color` the tag is grey, as in Notion – it used to have no fill at all.
419
+ - `nk-banner variant="danger"`.
420
+ - `nk-table-view wrap` lets cell text break (`.nk-table.wrap`), like
421
+ Notion's "wrap column".
422
+
423
+ ### Changed
424
+ - Select and multi-select cells fall back to the grey tag for an option
425
+ without a known colour (was blue).
426
+ - Tags are 20px tall with 3px corners and near-black text on the fill; the
427
+ old mid-tone tag text lives on in the foundation as `--nk-color-*`, the
428
+ old soft backgrounds as `--nk-tint-*`. Banners use those tints under the
429
+ normal text colour.
430
+
431
+ ## [1.3.1] – 2026-09-12
432
+
433
+ Rebuilt against NotionKit CSS 1.4.1 (peer `>= 1.4.1`).
434
+
435
+ ### Fixed
436
+ - `nk-page` without `cover` clipped the top of its icon: the stylesheet
437
+ pulled the icon up by 42px regardless of a cover, and the page had no top
438
+ padding, so half the icon sat outside the scroll container. The element
439
+ now sets the stylesheet's `covered` state only with the `cover` attribute
440
+ or a slotted `nk-page-cover`; otherwise the icon sits in 24px top padding.
441
+ Reported by Auxdesk.
442
+
443
+ ## [1.3.0] – 2026-09-12
444
+
445
+ Built and tested against NotionKit CSS 1.4.0 (peer `>= 1.4.0`).
446
+
447
+ ### Added
448
+ - `nk-segmented scroll` / `wrap`: a long filter row scrolls horizontally
449
+ with the scrollbar hidden, capped at the parent width, or wraps onto
450
+ further rows. Default stays one row.
451
+ - `nk-tab-bar fixed`: pinned to the viewport bottom for standalone PWAs; the
452
+ element renders the `.nk-tab-bar-spacer` itself, so the page still ends
453
+ above the bar without any padding of yours.
454
+
455
+ ### Fixed
456
+ - Through NotionKit 1.4.0: `.nk-app` is `100dvh` (fallback `100vh`), so an
457
+ iOS standalone PWA no longer counts the status bar into the shell and the
458
+ tab bar no longer sits half behind the home indicator. The bar has a fixed
459
+ height now (`--nk-tab-bar-height` + safe area). Reported by Auxdesk.
460
+
461
+ ## [1.2.1] – 2026-09-11
462
+
463
+ Rebuilt against NotionKit CSS 1.3.1 (peer `>= 1.3.1`); the bundle embeds the
464
+ stylesheet, so the fix below needs this release.
465
+
466
+ ### Fixed
467
+ - Inputs inside `nk-fields` (and stacked / compact `nk-field`s) overflowed
468
+ their column by about 20px: the controls' `min-width: 210px` became the
469
+ grid item's automatic minimum. NotionKit 1.3.1 sets `min-width: 0` down
470
+ the chain; a test now measures that every control ends inside its column
471
+ at 150px. Reported by Auxdesk.
472
+
473
+ ## [1.2.0] – 2026-09-11
474
+
475
+ Built and tested against NotionKit CSS 1.3.0; the peer range is now
476
+ `>= 1.3.0` (field layouts and the labelled switch need its rules).
477
+
478
+ ### Added
479
+ - **Visible text on `nk-switch`.** The default slot (or `text`) renders
480
+ beside the switch inside `label.nk-switch-label`, so several switches in
481
+ one row are readable and the text is part of the hit area. Without text
482
+ the element still renders the bare button. `label` stays the accessible
483
+ name for the bare form.
484
+ - **`text` on `nk-check` and `nk-radio`** as the attribute alternative to
485
+ the slotted label text (the slot was always the visible label).
486
+ - **`nk-field stacked` / `compact`** – label above a full-width control,
487
+ small tertiary label without row padding. A stacked field sets `wide` on
488
+ its `nk-input` / `nk-textarea` / `nk-select` itself, because the
489
+ stylesheet cannot reach into the control's shadow root.
490
+ - **`nk-fields`** – the field grid: `minmax(150px, 1fr)` columns that wrap,
491
+ every `nk-field` inside stacked and compact by default.
492
+ - `wide` on `nk-select`. Requested by Auxdesk.
493
+
494
+ ## [1.1.0] – 2026-09-11
495
+
496
+ Built and tested against NotionKit CSS 1.2.0; the peer range is now
497
+ `>= 1.2.0` (the tab bar needs its `.nk-tab-bar` rules, everything else still
498
+ works with 1.0.0).
499
+
500
+ ### Added
501
+ - **`nk-tab-bar` / `nk-tab-bar-item`** – the mobile tab bar for phones and
502
+ installed PWAs. Last child of `nk-app`, it is slotted into the main column
503
+ below the scrolling page, so it never moves and needs no bottom padding.
504
+ Exactly one item is `active` (`value` ↔ `active`, `nk-change`); an item
505
+ emits a cancelable `nk-select`, navigates with `href`, and with `drawer`
506
+ opens the nearest `nk-sidebar` as a drawer instead of becoming active.
507
+ Hidden above 860px by the stylesheet – there the sidebar is the
508
+ navigation – and shown below; `always` shows it at every width (previews,
509
+ phone frames), `floating` makes it a capsule. Icon as attribute or
510
+ `slot="icon"`. Requested by Auxdesk.
511
+ - Demo app and the workspace skeleton in `SKILL.md` carry the tab bar.
512
+
513
+ ### Fixed
514
+ - **`disabled` before the first render threw.** A `disabled` attribute in
515
+ the markup fires `formDisabledCallback` on parse or upgrade, before
516
+ `connectedCallback` has rendered anything; `nk-todo`, `nk-check`,
517
+ `nk-radio`, `nk-switch`, `nk-input`, `nk-textarea`, `nk-select`,
518
+ `nk-slider` and `nk-segmented` wrote into the missing inner control
519
+ (`TypeError: Cannot set properties of undefined`). `NkFormElement` now
520
+ remembers the state and applies it after the first render. The same path
521
+ was hit when a template engine set `checked` and `disabled` as properties
522
+ on a not-yet-connected element. Reported by Auxdesk (hybrids).
523
+ - **Own properties from before the upgrade** – a `checked = true` set on
524
+ the element while it was still a plain `HTMLElement` (a template clone
525
+ before the bundle loaded) shadowed the accessor for good. `NkElement`
526
+ re-applies such properties through their setters on the first connect.
527
+ - `nk-input`, `nk-textarea`, `nk-select`: toggling the `disabled` attribute
528
+ inside a `<fieldset disabled>` no longer re-enables the control.
529
+
530
+ ## [1.0.1] – 2026-09-06
531
+
532
+ Documentation-only release; the bundles are unchanged.
533
+
534
+ ### Changed
535
+ - README: header aligned with GlassKit Elements (centred title, full badge
536
+ row, tagline, link row, "What is" intro with before/after, feature table);
537
+ the family table now lists repository and website for every layer in one
538
+ pattern; Jungherz GmbH links to jungherz.com.
539
+ - NotionKit Web is available and linked from the README, the landing page,
540
+ the site navigation, `SKILL.md` and `llms.txt`.
541
+ - Landing page content centred; German pages link to their German
542
+ counterparts (including the embedded `de/app.html`); page footers link
543
+ Jungherz GmbH.
544
+
545
+ ## [1.0.0] – 2026-09-06
546
+
547
+ First release: the Web-Components layer of the NotionKit family. 68 elements,
548
+ built and tested against NotionKit CSS 1.1.1 (peer range `>= 1.0.0`).
549
+
550
+ ### Added
551
+ - **Base classes.** `NkElement` / `NkFormElement`: open Shadow DOM adopting the
552
+ NotionKit *components* sheet only; design tokens injected once on the
553
+ document inside `@layer notionkit-defaults`; one `MutationObserver` on
554
+ `<html>[data-theme]` for every instance; listeners re-armed on every
555
+ connect; `observesLightDom` / `projectLightDom()` / `refresh()`; manual
556
+ slot assignment for elements that route text and children themselves;
557
+ ElementInternals for form participation. Every host is `display: contents`.
558
+ - **Wave 1 – forms & content:** `nk-btn`, `nk-input`, `nk-textarea`,
559
+ `nk-select`, `nk-switch`, `nk-check`, `nk-radio`, `nk-slider`, `nk-field`,
560
+ `nk-tag`, `nk-progress`, `nk-callout`, `nk-divider`, `nk-heading`,
561
+ `nk-toggle`, `nk-todo`, `nk-kbd`, `nk-code`, `nk-quote`.
562
+ - **Wave 2 – app shell & navigation:** `nk-app`, `nk-sidebar` (off-canvas
563
+ drawer below 860px), `nk-workspace-switcher`, `nk-section-label`, `nk-tree`
564
+ (single `active`, one tab stop, arrow keys, `data`), `nk-tree-item`,
565
+ `nk-topbar`, `nk-breadcrumb`, `nk-theme-toggle`.
566
+ - **Wave 3 – page shell & blocks:** `nk-page`, `nk-page-cover`,
567
+ `nk-page-title` (editable), `nk-page-actions`, `nk-block-host`, `nk-banner`,
568
+ `nk-empty`, `nk-skeleton`, `nk-synced`, `nk-tabs` / `nk-tab`,
569
+ `nk-segmented`, `nk-stats` / `nk-stat`, `nk-avatar-group`, `nk-mention`,
570
+ `nk-template-btn`, `nk-model-card`, `nk-profile-row`, `nk-danger-zone`,
571
+ `nk-member-list` / `nk-member-row`.
572
+ - **Wave 4 – overlays:** `nk-modal` (renders its nav from the panes, focus
573
+ in/out, scroll lock, `inert`), `nk-settings-pane`, `nk-settings-user`,
574
+ `nk-cmdk` (fuzzy search, keyboard, hotkey, `nk-command`), `nk-menu` /
575
+ `nk-menu-item`, `nk-pop`, `nk-emoji-picker`, `nk-toast`.
576
+ - **Wave 5 – data & collaboration:** `nk-database`, `nk-table-view`,
577
+ `nk-board-view` (drag & drop), `nk-filter-bar`, `nk-comments` /
578
+ `nk-comment`, `nk-ai-thread` / `nk-ai-msg` / `nk-ai-input-row`, and the
579
+ exported `renderPropertyCell()` / `tagFor()` / `compareBy()` helpers.
580
+ - **Radio groups across shadow roots.** `<nk-radio>`s with the same `name`
581
+ in the same tree and form clear each other, keep a single tab stop and
582
+ move with arrow keys (wrapping, skipping disabled). Measured: three radios
583
+ in one form put exactly one entry into `FormData`.
584
+ - **Documentation**, generated from one catalog: `docs.html` (live preview,
585
+ before/after toggle against the class markup, attribute / slot / event
586
+ tables, mobile notes), `showcase.html` (brand switch), `index.html`,
587
+ German twins under `de/`, `SKILL.md` with all six app skeletons, `llms.txt`.
588
+ - **Reference app** `app.html`: the NotionKit demo rebuilt from elements only.
589
+ Pixel difference to the class version, measured with Playwright at
590
+ 1280 px: 0.00 %; at 390 px: 0.08 %.
591
+ - **Test suite** (Playwright, 180 tests): pixel parity of every element against
592
+ its class markup in light and dark, branding through `:root` (with and
593
+ without `notionkit.css` on the page, either load order), reconnect,
594
+ radio groups, light-DOM drift (empty string is a valid value), form
595
+ participation, overlays, data views, per-component import through a
596
+ packed tarball.
597
+
598
+ ### Notes
599
+ - Every host is `display: contents`. Inline-block hosts measured up to 22 px
600
+ of layout drift (a hidden toggle arrow keeping its width, a switch host
601
+ 3 px taller than its button, topbar buttons wrapping differently); with
602
+ no host box the inner element sits where the class markup puts it.
603
+ - Assigning a property to a custom element that has not been upgraded yet
604
+ creates an own property that shadows the accessor forever. Containers
605
+ therefore talk to their children through methods (`setTabbable()`,
606
+ `setData()`), and children ask their container to resync once rendered.
607
+ - NotionKit CSS 1.1.0 / 1.1.1 were released alongside: slot-name twins
608
+ (`::slotted([slot="icon"])`), explicit state classes (`.compact`, `.last`),
609
+ disabled optics, `.nk-new-row`, and `!important` on the margin/padding
610
+ declarations of slotted twins – the document's scoped reset would
611
+ otherwise beat them (the outer tree wins over `::slotted()` for normal
612
+ declarations; the inner tree wins for important ones). With 1.0.0 the
613
+ elements still work, with those small deviations.
614
+ - Headless Chromium anti-aliases semi-transparent text inside shadow trees
615
+ slightly brighter in the dark theme (channel delta ≤ 22 on glyph edges,
616
+ geometry identical); the parity test uses a perceptual threshold of 0.25.
617
+
618
+ ### Roadmap
619
+ - `<nk-editor>` (v1.1): a thin TipTap wrapper as an optional per-component
620
+ import, never in the core bundle – shadow-less, adding `nk-block-host` to
621
+ itself so the foundation's editor adapter rules apply.
622
+
623
+ [1.11.1]: https://github.com/JUNGHERZ/NotionKit-Elements/releases/tag/v1.11.1
624
+ [1.11.0]: https://github.com/JUNGHERZ/NotionKit-Elements/releases/tag/v1.11.0
625
+ [1.10.1]: https://github.com/JUNGHERZ/NotionKit-Elements/releases/tag/v1.10.1
626
+ [1.10.0]: https://github.com/JUNGHERZ/NotionKit-Elements/releases/tag/v1.10.0
627
+ [1.9.0]: https://github.com/JUNGHERZ/NotionKit-Elements/releases/tag/v1.9.0
628
+ [1.8.0]: https://github.com/JUNGHERZ/NotionKit-Elements/releases/tag/v1.8.0
629
+ [1.7.0]: https://github.com/JUNGHERZ/NotionKit-Elements/releases/tag/v1.7.0
630
+ [1.6.0]: https://github.com/JUNGHERZ/NotionKit-Elements/releases/tag/v1.6.0
631
+ [1.5.3]: https://github.com/JUNGHERZ/NotionKit-Elements/releases/tag/v1.5.3
632
+ [1.5.2]: https://github.com/JUNGHERZ/NotionKit-Elements/releases/tag/v1.5.2
633
+ [1.5.1]: https://github.com/JUNGHERZ/NotionKit-Elements/releases/tag/v1.5.1
634
+ [1.5.0]: https://github.com/JUNGHERZ/NotionKit-Elements/releases/tag/v1.5.0
635
+ [1.3.1]: https://github.com/JUNGHERZ/NotionKit-Elements/releases/tag/v1.3.1
636
+ [1.3.0]: https://github.com/JUNGHERZ/NotionKit-Elements/releases/tag/v1.3.0
637
+ [1.2.1]: https://github.com/JUNGHERZ/NotionKit-Elements/releases/tag/v1.2.1
638
+ [1.2.0]: https://github.com/JUNGHERZ/NotionKit-Elements/releases/tag/v1.2.0
639
+ [1.1.0]: https://github.com/JUNGHERZ/NotionKit-Elements/releases/tag/v1.1.0
640
+ [1.0.1]: https://github.com/JUNGHERZ/NotionKit-Elements/releases/tag/v1.0.1
641
+ [1.0.0]: https://github.com/JUNGHERZ/NotionKit-Elements/releases/tag/v1.0.0