@jungherz-de/notionkit-elements 1.0.1 → 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +11 -11
- package/dist/components/nk-ai-input-row.js +1 -1
- package/dist/components/nk-ai-msg.js +1 -1
- package/dist/components/nk-ai-thread.js +1 -1
- package/dist/components/nk-app.js +1 -1
- package/dist/components/nk-avatar-group.js +1 -1
- package/dist/components/nk-banner.js +1 -1
- package/dist/components/nk-block-host.js +1 -1
- package/dist/components/nk-board-view.js +1 -1
- package/dist/components/nk-breadcrumb.js +1 -1
- package/dist/components/nk-btn.js +1 -1
- package/dist/components/nk-callout.js +1 -1
- package/dist/components/nk-check.js +9 -3
- package/dist/components/nk-cmdk.js +1 -1
- package/dist/components/nk-code.js +1 -1
- package/dist/components/nk-comment.js +1 -1
- package/dist/components/nk-comments.js +1 -1
- package/dist/components/nk-danger-zone.js +1 -1
- package/dist/components/nk-database.js +1 -1
- package/dist/components/nk-divider.js +1 -1
- package/dist/components/nk-emoji-picker.js +1 -1
- package/dist/components/nk-empty.js +1 -1
- package/dist/components/nk-field.js +45 -7
- package/dist/components/nk-fields.js +22 -0
- package/dist/components/nk-filter-bar.js +1 -1
- package/dist/components/nk-heading.js +1 -1
- package/dist/components/nk-input.js +2 -2
- package/dist/components/nk-kbd.js +1 -1
- package/dist/components/nk-member-list.js +1 -1
- package/dist/components/nk-member-row.js +1 -1
- package/dist/components/nk-mention.js +1 -1
- package/dist/components/nk-menu-item.js +1 -1
- package/dist/components/nk-menu.js +1 -1
- package/dist/components/nk-modal.js +1 -1
- package/dist/components/nk-model-card.js +1 -1
- package/dist/components/nk-page-actions.js +1 -1
- package/dist/components/nk-page-cover.js +1 -1
- package/dist/components/nk-page-title.js +1 -1
- package/dist/components/nk-page.js +1 -1
- package/dist/components/nk-pop.js +1 -1
- package/dist/components/nk-profile-row.js +1 -1
- package/dist/components/nk-progress.js +1 -1
- package/dist/components/nk-quote.js +1 -1
- package/dist/components/nk-radio.js +9 -3
- package/dist/components/nk-section-label.js +1 -1
- package/dist/components/nk-segmented.js +1 -1
- package/dist/components/nk-select.js +6 -3
- package/dist/components/nk-settings-pane.js +1 -1
- package/dist/components/nk-settings-user.js +1 -1
- package/dist/components/nk-sidebar.js +1 -1
- package/dist/components/nk-skeleton.js +1 -1
- package/dist/components/nk-slider.js +1 -1
- package/dist/components/nk-stat.js +1 -1
- package/dist/components/nk-stats.js +1 -1
- package/dist/components/nk-switch.js +32 -4
- package/dist/components/nk-synced.js +1 -1
- package/dist/components/nk-tab-bar-item.js +83 -0
- package/dist/components/nk-tab-bar.js +83 -0
- package/dist/components/nk-tab.js +1 -1
- package/dist/components/nk-table-view.js +1 -1
- package/dist/components/nk-tabs.js +1 -1
- package/dist/components/nk-tag.js +1 -1
- package/dist/components/nk-template-btn.js +1 -1
- package/dist/components/nk-textarea.js +2 -2
- package/dist/components/nk-theme-toggle.js +1 -1
- package/dist/components/nk-toast.js +1 -1
- package/dist/components/nk-todo.js +1 -1
- package/dist/components/nk-toggle.js +1 -1
- package/dist/components/nk-topbar.js +1 -1
- package/dist/components/nk-tree-item.js +1 -1
- package/dist/components/nk-tree.js +1 -1
- package/dist/components/nk-workspace-switcher.js +1 -1
- package/dist/components/shared/base-EVtzqKmc.js +347 -0
- package/dist/notionkit-elements.esm.js +311 -21
- package/dist/notionkit-elements.js +313 -20
- package/dist/notionkit-elements.min.js +1 -1
- package/package.json +3 -3
- package/src/base.js +31 -1
- package/src/components/forms/nk-check.js +8 -2
- package/src/components/forms/nk-field.js +44 -6
- package/src/components/forms/nk-fields.js +21 -0
- package/src/components/forms/nk-input.js +1 -1
- package/src/components/forms/nk-radio.js +8 -2
- package/src/components/forms/nk-select.js +5 -2
- package/src/components/forms/nk-switch.js +31 -3
- package/src/components/forms/nk-textarea.js +1 -1
- package/src/components/shell/nk-tab-bar-item.js +82 -0
- package/src/components/shell/nk-tab-bar.js +82 -0
- package/src/index.js +3 -0
- package/dist/components/shared/base-6gEcoatG.js +0 -317
package/README.md
CHANGED
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
<h1 align="center">🧩 NotionKit Elements</h1>
|
|
2
2
|
|
|
3
3
|
<p align="center">
|
|
4
|
-
<a href="https://www.npmjs.com/package/@jungherz-de/notionkit-elements"><img src="https://img.shields.io/badge/version-1.0
|
|
4
|
+
<a href="https://www.npmjs.com/package/@jungherz-de/notionkit-elements"><img src="https://img.shields.io/badge/version-1.2.0-2383e2?style=flat-square" alt="Version"></a>
|
|
5
5
|
<a href="#"><img src="https://img.shields.io/badge/vanilla_JS-no_dependencies-448361?style=flat-square" alt="Vanilla JS"></a>
|
|
6
|
-
<a href="#"><img src="https://img.shields.io/badge/elements-
|
|
6
|
+
<a href="#"><img src="https://img.shields.io/badge/elements-71-529cca?style=flat-square" alt="71 Elements"></a>
|
|
7
7
|
<a href="LICENSE"><img src="https://img.shields.io/badge/license-MIT-9065b0?style=flat-square" alt="MIT License"></a>
|
|
8
|
-
<a href="CHANGELOG.md"><img src="https://img.shields.io/badge/changelog-v1.0
|
|
8
|
+
<a href="CHANGELOG.md"><img src="https://img.shields.io/badge/changelog-v1.2.0-lightgrey?style=flat-square" alt="Changelog"></a>
|
|
9
9
|
<a href="https://www.npmjs.com/package/@jungherz-de/notionkit-elements"><img src="https://img.shields.io/badge/npm-%40jungherz--de%2Fnotionkit--elements-cb3837?style=flat-square&logo=npm" alt="npm"></a>
|
|
10
10
|
</p>
|
|
11
11
|
|
|
12
12
|
<p align="center">
|
|
13
13
|
<strong>Drop-in Web Components for <a href="https://github.com/JUNGHERZ/NotionKit">NotionKit CSS</a></strong><br>
|
|
14
|
-
|
|
14
|
+
71 vanilla JavaScript custom elements wrapping NotionKit's calm, document-centric workspace look.<br>
|
|
15
15
|
Shadow DOM · Native form participation · Pixel parity with the class markup · Zero dependencies.
|
|
16
16
|
</p>
|
|
17
17
|
|
|
@@ -28,7 +28,7 @@
|
|
|
28
28
|
|
|
29
29
|
## ✨ What is NotionKit Elements?
|
|
30
30
|
|
|
31
|
-
NotionKit Elements is the companion library to [NotionKit CSS](https://github.com/JUNGHERZ/NotionKit). It provides **
|
|
31
|
+
NotionKit Elements is the companion library to [NotionKit CSS](https://github.com/JUNGHERZ/NotionKit). It provides **71 Web Components** – from buttons and form controls over the sidebar, page tree and page shell to the settings modal, ⌘K palette, database views and AI thread – that encapsulate the class markup of the foundation into simple, declarative custom elements.
|
|
32
32
|
|
|
33
33
|
It is the **app layer** of the NotionKit family – three layers, one design language: [NotionKit](https://notionkit.jungherz.com) is the pure-CSS foundation, NotionKit Elements wraps it into web components for application UIs, and [NotionKit Web](https://notionkit-web.jungherz.com) is the Astro template for complete websites on top of the same foundation. The word stem stays the same across the layers: `.nk-callout` becomes `<nk-callout>`, a modifier class becomes an attribute, a state class becomes a boolean attribute.
|
|
34
34
|
|
|
@@ -56,7 +56,7 @@ It is the **app layer** of the NotionKit family – three layers, one design lan
|
|
|
56
56
|
|---|---|
|
|
57
57
|
| 🎯 **Pixel parity** | Every element renders identically to its class markup – verified by a Playwright pixel test in light and dark; the reference app differs by 0.00 % from the class version |
|
|
58
58
|
| 🔌 **Shadow DOM** | Each root adopts the NotionKit *components* sheet via `adoptedStyleSheets`; tokens are inherited from the document, so one `:root { --nk-accent: … }` re-brands everything |
|
|
59
|
-
| 🧩 **
|
|
59
|
+
| 🧩 **71 Elements** | Forms, content blocks, app shell & tree, page shell, overlays (modal, ⌘K palette, menus, popover, emoji picker, toast), database table & board, comments, AI thread |
|
|
60
60
|
| 🎛️ **Form participation** | Input, textarea, select, switch, check, radio, slider, segmented and model card work natively with `<form>` via `ElementInternals`; radios group across shadow roots |
|
|
61
61
|
| 🌗 **Theme sync** | One observer mirrors `data-theme` on `<html>` into every element |
|
|
62
62
|
| 🪶 **Lightweight** | 167 KB minified / 33 KB gzipped (IIFE, foundation sheet included), no external dependencies |
|
|
@@ -71,8 +71,8 @@ It is the **app layer** of the NotionKit family – three layers, one design lan
|
|
|
71
71
|
<!DOCTYPE html>
|
|
72
72
|
<html lang="en" data-theme="light">
|
|
73
73
|
<head>
|
|
74
|
-
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@jungherz-de/notionkit@1.
|
|
75
|
-
<script src="https://cdn.jsdelivr.net/npm/@jungherz-de/notionkit-elements@1.0
|
|
74
|
+
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@jungherz-de/notionkit@1.3.0/notionkit.min.css">
|
|
75
|
+
<script src="https://cdn.jsdelivr.net/npm/@jungherz-de/notionkit-elements@1.2.0/dist/notionkit-elements.min.js"></script>
|
|
76
76
|
</head>
|
|
77
77
|
<body class="nk-body">
|
|
78
78
|
<nk-field label="Display name" desc="Shown next to your comments">
|
|
@@ -93,15 +93,15 @@ import '@jungherz-de/notionkit-elements'; // everyt
|
|
|
93
93
|
import '@jungherz-de/notionkit-elements/components/nk-btn.js'; // or one element (shared code is one extra chunk)
|
|
94
94
|
```
|
|
95
95
|
|
|
96
|
-
Two prerequisites, always: `notionkit.css` on the document (the peer dependency, `>= 1.
|
|
96
|
+
Two prerequisites, always: `notionkit.css` on the document (the peer dependency, `>= 1.3.0`; 1.3.0 brings the field layouts and the labelled switch, 1.2.0 the tab bar, and is what the elements are built and tested against) and `class="nk-body"` on `<body>`. The elements ship no visual CSS of their own – every rule comes from the foundation. The bundle injects the design tokens once as `@layer notionkit-defaults`, so any plain `:root { --nk-accent: … }` of yours re-brands every element in both themes.
|
|
97
97
|
|
|
98
98
|
## Elements
|
|
99
99
|
|
|
100
100
|
| Group | Elements |
|
|
101
101
|
|---|---|
|
|
102
|
-
| Forms & controls | `nk-btn` `nk-input` `nk-textarea` `nk-select` `nk-switch` `nk-check` `nk-radio` `nk-slider` `nk-field` |
|
|
102
|
+
| Forms & controls | `nk-btn` `nk-input` `nk-textarea` `nk-select` `nk-switch` `nk-check` `nk-radio` `nk-slider` `nk-field` `nk-fields` |
|
|
103
103
|
| Content | `nk-tag` `nk-progress` `nk-callout` `nk-divider` `nk-heading` `nk-toggle` `nk-todo` `nk-kbd` `nk-code` `nk-quote` |
|
|
104
|
-
| App shell & navigation | `nk-app` `nk-sidebar` `nk-workspace-switcher` `nk-section-label` `nk-tree` `nk-tree-item` `nk-topbar` `nk-breadcrumb` `nk-theme-toggle` |
|
|
104
|
+
| App shell & navigation | `nk-app` `nk-sidebar` `nk-workspace-switcher` `nk-section-label` `nk-tree` `nk-tree-item` `nk-topbar` `nk-breadcrumb` `nk-theme-toggle` `nk-tab-bar` `nk-tab-bar-item` |
|
|
105
105
|
| Page shell & blocks | `nk-page` `nk-page-cover` `nk-page-title` `nk-page-actions` `nk-block-host` `nk-banner` `nk-empty` `nk-skeleton` `nk-synced` `nk-tabs` `nk-tab` `nk-segmented` `nk-stats` `nk-stat` `nk-avatar-group` `nk-mention` `nk-template-btn` `nk-model-card` `nk-profile-row` `nk-danger-zone` `nk-member-list` `nk-member-row` |
|
|
106
106
|
| Overlays | `nk-modal` `nk-settings-pane` `nk-settings-user` `nk-cmdk` `nk-menu` `nk-menu-item` `nk-pop` `nk-emoji-picker` `nk-toast` |
|
|
107
107
|
| Data & collaboration | `nk-database` `nk-table-view` `nk-board-view` `nk-filter-bar` `nk-comments` `nk-comment` `nk-ai-thread` `nk-ai-msg` `nk-ai-input-row` (+ the exported `renderPropertyCell()`) |
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { N as NkElement } from './shared/base-
|
|
1
|
+
import { N as NkElement } from './shared/base-EVtzqKmc.js';
|
|
2
2
|
|
|
3
3
|
// <nk-ai-input-row placeholder="Ask Mona something …"></nk-ai-input-row>
|
|
4
4
|
// → <div class="nk-ai-input-row"><span>✨</span><input><button class="nk-ai-send">↑</button></div>
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { N as NkElement } from './shared/base-
|
|
1
|
+
import { N as NkElement } from './shared/base-EVtzqKmc.js';
|
|
2
2
|
|
|
3
3
|
// <nk-ai-msg role="user" name="You" avatar="MK">Summarise the open tasks.</nk-ai-msg>
|
|
4
4
|
// <nk-ai-msg role="assistant" name="Mona" badge="· AI" avatar="✨">
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { N as NkElement } from './shared/base-
|
|
1
|
+
import { N as NkElement } from './shared/base-EVtzqKmc.js';
|
|
2
2
|
|
|
3
3
|
// <nk-banner variant="info">ℹ️ <span>Text</span><span slot="action">Open</span></nk-banner>
|
|
4
4
|
// → <div class="nk-banner info">…<span class="b-action">Open</span></div>
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { N as NkElement } from './shared/base-
|
|
1
|
+
import { N as NkElement } from './shared/base-EVtzqKmc.js';
|
|
2
2
|
|
|
3
3
|
// <nk-block-host handle><p>Editable content lives here.</p></nk-block-host>
|
|
4
4
|
// → <div class="nk-block-host"><span class="nk-block-handle">⠿</span>…</div>
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { N as NkElement } from './shared/base-
|
|
1
|
+
import { N as NkElement } from './shared/base-EVtzqKmc.js';
|
|
2
2
|
import { t as tagFor, r as renderPropertyCell } from './shared/property-cell-Dn91uFkf.js';
|
|
3
3
|
|
|
4
4
|
// <nk-board-view name="board" label="▤ Board" group-by="status" new-row></nk-board-view>
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { N as NkElement } from './shared/base-
|
|
1
|
+
import { N as NkElement } from './shared/base-EVtzqKmc.js';
|
|
2
2
|
|
|
3
3
|
// <nk-btn variant="primary" small>Save</nk-btn> → <button class="nk-btn primary small">
|
|
4
4
|
// <nk-btn href="/docs" variant="secondary">Docs</nk-btn> → <a class="nk-btn secondary">
|
|
@@ -1,17 +1,20 @@
|
|
|
1
|
-
import { a as NkFormElement } from './shared/base-
|
|
1
|
+
import { a as NkFormElement } from './shared/base-EVtzqKmc.js';
|
|
2
2
|
|
|
3
3
|
// <nk-check name="mail" value="weekly" checked>Weekly digest</nk-check>
|
|
4
4
|
// → <label class="nk-check"><input type="checkbox"> Weekly digest</label>
|
|
5
5
|
class NkCheck extends NkFormElement {
|
|
6
|
-
static get observedAttributes() { return ['checked', 'disabled', 'name', 'value', 'indeterminate', 'required']; }
|
|
6
|
+
static get observedAttributes() { return ['checked', 'disabled', 'name', 'value', 'text', 'indeterminate', 'required']; }
|
|
7
7
|
|
|
8
8
|
render() {
|
|
9
9
|
const label = this.createElement('label', ['nk-check']);
|
|
10
10
|
this._input = this.createElement('input', [], { type: 'checkbox' });
|
|
11
|
+
const slot = document.createElement('slot');
|
|
12
|
+
this._text = document.createTextNode('');
|
|
13
|
+
slot.appendChild(this._text);
|
|
11
14
|
this._apply();
|
|
12
15
|
this._defaultChecked = this.getBoolAttr('checked');
|
|
13
16
|
label.appendChild(this._input);
|
|
14
|
-
label.appendChild(
|
|
17
|
+
label.appendChild(slot);
|
|
15
18
|
this._wrapper.appendChild(label);
|
|
16
19
|
this._syncFormValue();
|
|
17
20
|
}
|
|
@@ -24,6 +27,7 @@ class NkCheck extends NkFormElement {
|
|
|
24
27
|
const name = this.getAttribute('name');
|
|
25
28
|
name ? this._input.setAttribute('name', name) : this._input.removeAttribute('name');
|
|
26
29
|
this._input.value = this.getAttribute('value') || 'on';
|
|
30
|
+
if (this._text) this._text.data = this.getAttribute('text') ?? '';
|
|
27
31
|
}
|
|
28
32
|
|
|
29
33
|
setupEvents() {
|
|
@@ -68,6 +72,8 @@ class NkCheck extends NkFormElement {
|
|
|
68
72
|
set disabled(v) { this.setBoolAttr('disabled', v); }
|
|
69
73
|
get name() { return this.getAttribute('name'); }
|
|
70
74
|
set name(v) { this.setAttribute('name', v); }
|
|
75
|
+
get text() { return this.getAttribute('text'); }
|
|
76
|
+
set text(v) { v == null ? this.removeAttribute('text') : this.setAttribute('text', v); }
|
|
71
77
|
get value() { return this.getAttribute('value') || 'on'; }
|
|
72
78
|
set value(v) { this.setAttribute('value', v); }
|
|
73
79
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { N as NkElement } from './shared/base-
|
|
1
|
+
import { N as NkElement } from './shared/base-EVtzqKmc.js';
|
|
2
2
|
import { l as lockScroll, i as inertOutside, u as unlockScroll } from './shared/focus-DXrK9oLe.js';
|
|
3
3
|
|
|
4
4
|
// Subsequence scoring for the command palette: every query character must
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { N as NkElement } from './shared/base-
|
|
1
|
+
import { N as NkElement } from './shared/base-EVtzqKmc.js';
|
|
2
2
|
|
|
3
3
|
// Minimal HTML highlighter emitting the .tag / .attr hooks .nk-code styles.
|
|
4
4
|
// Mirrors tools/highlight.mjs in the NotionKit foundation – no third-party
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { N as NkElement } from './shared/base-
|
|
1
|
+
import { N as NkElement } from './shared/base-EVtzqKmc.js';
|
|
2
2
|
|
|
3
3
|
// <nk-comment author="Sara Lindt" time="1 hr ago" avatar="SL" color="#448361">The board view feels close.</nk-comment>
|
|
4
4
|
// → <div class="nk-comment"><span class="mini-avatar">SL</span><div><div class="c-head"><b>Sara Lindt</b> · 1 hr ago</div><div class="c-body">…</div></div></div>
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { N as NkElement } from './shared/base-
|
|
1
|
+
import { N as NkElement } from './shared/base-EVtzqKmc.js';
|
|
2
2
|
|
|
3
3
|
// <nk-empty icon="🗂️" title="No entries yet" desc="Create the first one."><nk-btn variant="primary" small>+ New</nk-btn></nk-empty>
|
|
4
4
|
// → <div class="nk-empty"><div class="e-icon">🗂️</div><div class="e-title">…</div><div class="e-desc">…</div>…</div>
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { N as NkElement } from './shared/base-
|
|
1
|
+
import { N as NkElement } from './shared/base-EVtzqKmc.js';
|
|
2
2
|
|
|
3
3
|
// <nk-field label="Display name" desc="Shown next to your comments">
|
|
4
4
|
// <nk-input value="Marcel"></nk-input>
|
|
@@ -7,11 +7,19 @@ import { N as NkElement } from './shared/base-6gEcoatG.js';
|
|
|
7
7
|
// <div class="f-control">…</div></div>
|
|
8
8
|
// Rich label / description content goes through slot="label" / slot="desc"
|
|
9
9
|
// (twins `.nk-field ::slotted([slot="label"])` etc. in notionkit.css).
|
|
10
|
+
//
|
|
11
|
+
// `stacked` puts the label above a full-width control, `compact` shrinks the
|
|
12
|
+
// label and drops the row padding; inside <nk-fields> both are on by
|
|
13
|
+
// default. A stacked field sets `wide` on its nk-input / nk-textarea /
|
|
14
|
+
// nk-select, since the stylesheet's `.nk-field.stacked .nk-input` cannot
|
|
15
|
+
// reach into the control's shadow root.
|
|
16
|
+
const WIDE = ['nk-input', 'nk-textarea', 'nk-select'];
|
|
17
|
+
|
|
10
18
|
class NkField extends NkElement {
|
|
11
|
-
static get observedAttributes() { return ['label', 'desc']; }
|
|
19
|
+
static get observedAttributes() { return ['label', 'desc', 'stacked', 'compact']; }
|
|
12
20
|
|
|
13
21
|
render() {
|
|
14
|
-
|
|
22
|
+
this._field = this.createElement('div', ['nk-field']);
|
|
15
23
|
const text = document.createElement('div');
|
|
16
24
|
this._label = this.createElement('div', ['f-label']);
|
|
17
25
|
const labelSlot = this.createElement('slot', [], { name: 'label' });
|
|
@@ -22,21 +30,51 @@ class NkField extends NkElement {
|
|
|
22
30
|
text.appendChild(labelSlot);
|
|
23
31
|
text.appendChild(descSlot);
|
|
24
32
|
const control = this.createElement('div', ['f-control']);
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
this.
|
|
33
|
+
this._slot = document.createElement('slot');
|
|
34
|
+
control.appendChild(this._slot);
|
|
35
|
+
this._field.appendChild(text);
|
|
36
|
+
this._field.appendChild(control);
|
|
37
|
+
this._wrapper.appendChild(this._field);
|
|
38
|
+
this._widened = new Set();
|
|
29
39
|
this._sync();
|
|
30
40
|
}
|
|
31
41
|
|
|
42
|
+
setupEvents() {
|
|
43
|
+
this._onSlot = () => this._syncWide();
|
|
44
|
+
this._slot.addEventListener('slotchange', this._onSlot);
|
|
45
|
+
this._sync();
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
teardownEvents() {
|
|
49
|
+
this._slot?.removeEventListener('slotchange', this._onSlot);
|
|
50
|
+
}
|
|
51
|
+
|
|
32
52
|
onAttributeChanged() { this._sync(); }
|
|
33
53
|
|
|
54
|
+
get stacked() { return this.getBoolAttr('stacked') || !!this.closest('nk-fields'); }
|
|
55
|
+
set stacked(v) { this.setBoolAttr('stacked', v); }
|
|
56
|
+
get compact() { return this.getBoolAttr('compact') || !!this.closest('nk-fields'); }
|
|
57
|
+
set compact(v) { this.setBoolAttr('compact', v); }
|
|
58
|
+
|
|
34
59
|
_sync() {
|
|
35
60
|
if (!this._label) return;
|
|
36
61
|
this._label.textContent = this.getAttribute('label') || '';
|
|
37
62
|
const desc = this.getAttribute('desc');
|
|
38
63
|
this._desc.textContent = desc || '';
|
|
39
64
|
this._desc.style.display = desc ? '' : 'none';
|
|
65
|
+
this._field.classList.toggle('stacked', this.stacked);
|
|
66
|
+
this._field.classList.toggle('compact', this.compact);
|
|
67
|
+
this._syncWide();
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
_syncWide() {
|
|
71
|
+
if (!this._slot) return;
|
|
72
|
+
const stacked = this.stacked;
|
|
73
|
+
for (const el of this._slot.assignedElements()) {
|
|
74
|
+
if (!WIDE.includes(el.localName)) continue;
|
|
75
|
+
if (stacked && !el.hasAttribute('wide')) { el.setAttribute('wide', ''); this._widened.add(el); }
|
|
76
|
+
else if (!stacked && this._widened.has(el)) { el.removeAttribute('wide'); this._widened.delete(el); }
|
|
77
|
+
}
|
|
40
78
|
}
|
|
41
79
|
|
|
42
80
|
get label() { return this.getAttribute('label'); }
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { N as NkElement } from './shared/base-EVtzqKmc.js';
|
|
2
|
+
|
|
3
|
+
// <nk-fields>
|
|
4
|
+
// <nk-field label="Name"><nk-input name="name"></nk-input></nk-field>
|
|
5
|
+
// <nk-field label="Email"><nk-input name="email"></nk-input></nk-field>
|
|
6
|
+
// </nk-fields>
|
|
7
|
+
// → <div class="nk-fields">…</div>
|
|
8
|
+
// A grid of short fields side by side, wrapping as the width allows. Every
|
|
9
|
+
// nk-field inside renders itself stacked and compact (12px label above a
|
|
10
|
+
// full-width control) – the class markup does the same through
|
|
11
|
+
// `.nk-fields > .nk-field`, which cannot cross the shadow boundary here.
|
|
12
|
+
class NkFields extends NkElement {
|
|
13
|
+
render() {
|
|
14
|
+
const grid = this.createElement('div', ['nk-fields']);
|
|
15
|
+
grid.appendChild(document.createElement('slot'));
|
|
16
|
+
this._wrapper.appendChild(grid);
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
customElements.define('nk-fields', NkFields);
|
|
21
|
+
|
|
22
|
+
export { NkFields };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { N as NkElement } from './shared/base-
|
|
1
|
+
import { N as NkElement } from './shared/base-EVtzqKmc.js';
|
|
2
2
|
|
|
3
3
|
// <nk-filter-bar search placeholder="Search rows …"></nk-filter-bar>
|
|
4
4
|
// bar.filters = [{ key: 'status', label: 'Status: Done', value: 'done' }];
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { N as NkElement } from './shared/base-
|
|
1
|
+
import { N as NkElement } from './shared/base-EVtzqKmc.js';
|
|
2
2
|
|
|
3
3
|
// <nk-heading level="2">Section</nk-heading> → <h2 class="nk-heading">
|
|
4
4
|
// The heading level is real markup (h1–h4), so the outline stays honest.
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { a as NkFormElement } from './shared/base-
|
|
1
|
+
import { a as NkFormElement } from './shared/base-EVtzqKmc.js';
|
|
2
2
|
|
|
3
3
|
// <nk-input name="title" value="…" placeholder="…" wide></nk-input> → <input class="nk-input wide">
|
|
4
4
|
// Takes part in the surrounding <form> through ElementInternals.
|
|
@@ -21,7 +21,7 @@ class NkInput extends NkFormElement {
|
|
|
21
21
|
|
|
22
22
|
_forward(attr) {
|
|
23
23
|
if (BOOLEANS.includes(attr)) {
|
|
24
|
-
this._input[attr === 'readonly' ? 'readOnly' : attr] = this.getBoolAttr(attr);
|
|
24
|
+
this._input[attr === 'readonly' ? 'readOnly' : attr] = this.getBoolAttr(attr) || (attr === 'disabled' && !!this._formDisabled);
|
|
25
25
|
return;
|
|
26
26
|
}
|
|
27
27
|
const v = this.getAttribute(attr);
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { N as NkElement } from './shared/base-
|
|
1
|
+
import { N as NkElement } from './shared/base-EVtzqKmc.js';
|
|
2
2
|
|
|
3
3
|
// <nk-member-list><nk-member-row …></nk-member-row>…</nk-member-list>
|
|
4
4
|
// → <div class="nk-member-list">…</div>; the last row gets `last` (no border).
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { N as NkElement } from './shared/base-
|
|
1
|
+
import { N as NkElement } from './shared/base-EVtzqKmc.js';
|
|
2
2
|
|
|
3
3
|
// <nk-mention type="person"><span slot="avatar" class="mini-avatar" style="background:#448361">SL</span>Sara Lindt</nk-mention>
|
|
4
4
|
// <nk-mention type="page">📄 Onboarding</nk-mention> <nk-mention type="date">📅 May 20</nk-mention>
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { N as NkElement } from './shared/base-
|
|
1
|
+
import { N as NkElement } from './shared/base-EVtzqKmc.js';
|
|
2
2
|
|
|
3
3
|
// <nk-menu-item icon="✏️" shortcut="⌘E" value="rename">Rename</nk-menu-item>
|
|
4
4
|
// <nk-menu-item type="separator"></nk-menu-item> <nk-menu-item type="label">Danger</nk-menu-item>
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { N as NkElement } from './shared/base-
|
|
1
|
+
import { N as NkElement } from './shared/base-EVtzqKmc.js';
|
|
2
2
|
import { l as lockScroll, i as inertOutside, f as firstFocusable, u as unlockScroll } from './shared/focus-DXrK9oLe.js';
|
|
3
3
|
|
|
4
4
|
// <nk-modal id="settings">
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { a as NkFormElement } from './shared/base-
|
|
1
|
+
import { a as NkFormElement } from './shared/base-EVtzqKmc.js';
|
|
2
2
|
|
|
3
3
|
// <nk-model-card name="model" value="gpt" title="Mona Pro" desc="Best for long documents" selected></nk-model-card>
|
|
4
4
|
// → <div class="nk-model-card selected"><div class="m-radio"></div><div><div class="m-name">…</div><div class="m-desc">…</div></div></div>
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { N as NkElement } from './shared/base-
|
|
1
|
+
import { N as NkElement } from './shared/base-EVtzqKmc.js';
|
|
2
2
|
|
|
3
3
|
// <nk-page-actions><span>👤 Ada</span><span>📅 12 May</span><span>🏷️ <nk-tag color="purple">Design</nk-tag></span></nk-page-actions>
|
|
4
4
|
// → <div class="nk-page-meta">…</div> – the meta row under the title
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { N as NkElement } from './shared/base-
|
|
1
|
+
import { N as NkElement } from './shared/base-EVtzqKmc.js';
|
|
2
2
|
|
|
3
3
|
// <nk-page-title>NotionKit MVP</nk-page-title> → <h1 class="nk-page-title">
|
|
4
4
|
// <nk-page-title editable placeholder="Untitled">…</nk-page-title>
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { N as NkElement } from './shared/base-
|
|
1
|
+
import { N as NkElement } from './shared/base-EVtzqKmc.js';
|
|
2
2
|
|
|
3
3
|
// <nk-profile-row avatar="MK"><nk-btn variant="secondary" small>Change photo</nk-btn></nk-profile-row>
|
|
4
4
|
// → <div class="nk-profile-row"><div class="big-avatar">MK</div>…</div>
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { a as NkFormElement } from './shared/base-
|
|
1
|
+
import { a as NkFormElement } from './shared/base-EVtzqKmc.js';
|
|
2
2
|
|
|
3
3
|
// <nk-radio name="style" value="concise" checked>Concise</nk-radio>
|
|
4
4
|
// → <label class="nk-check"><input type="radio"> Concise</label>
|
|
@@ -29,17 +29,20 @@ function syncGroupTabIndex(group) {
|
|
|
29
29
|
}
|
|
30
30
|
|
|
31
31
|
class NkRadio extends NkFormElement {
|
|
32
|
-
static get observedAttributes() { return ['checked', 'disabled', 'name', 'value', 'required']; }
|
|
32
|
+
static get observedAttributes() { return ['checked', 'disabled', 'name', 'value', 'text', 'required']; }
|
|
33
33
|
|
|
34
34
|
render() {
|
|
35
35
|
const label = this.createElement('label', ['nk-check']);
|
|
36
36
|
this._input = this.createElement('input', [], { type: 'radio' });
|
|
37
|
+
const slot = document.createElement('slot');
|
|
38
|
+
this._text = document.createTextNode('');
|
|
39
|
+
slot.appendChild(this._text);
|
|
37
40
|
// `name` on the inner input is inert (it is alone in its tree); it stays
|
|
38
41
|
// as a devtools courtesy. The group above is the real one.
|
|
39
42
|
this._apply();
|
|
40
43
|
this._defaultChecked = this.getBoolAttr('checked');
|
|
41
44
|
label.appendChild(this._input);
|
|
42
|
-
label.appendChild(
|
|
45
|
+
label.appendChild(slot);
|
|
43
46
|
this._wrapper.appendChild(label);
|
|
44
47
|
this._syncFormValue();
|
|
45
48
|
// Elements upgrade in document order, so the last `checked` one in the
|
|
@@ -55,6 +58,7 @@ class NkRadio extends NkFormElement {
|
|
|
55
58
|
const name = this.getAttribute('name');
|
|
56
59
|
name ? this._input.setAttribute('name', name) : this._input.removeAttribute('name');
|
|
57
60
|
this._input.value = this.getAttribute('value') || '';
|
|
61
|
+
if (this._text) this._text.data = this.getAttribute('text') ?? '';
|
|
58
62
|
}
|
|
59
63
|
|
|
60
64
|
setupEvents() {
|
|
@@ -151,6 +155,8 @@ class NkRadio extends NkFormElement {
|
|
|
151
155
|
set disabled(v) { this.setBoolAttr('disabled', v); }
|
|
152
156
|
get name() { return this.getAttribute('name'); }
|
|
153
157
|
set name(v) { this.setAttribute('name', v); }
|
|
158
|
+
get text() { return this.getAttribute('text'); }
|
|
159
|
+
set text(v) { v == null ? this.removeAttribute('text') : this.setAttribute('text', v); }
|
|
154
160
|
get value() { return this.getAttribute('value') || ''; }
|
|
155
161
|
set value(v) { this.setAttribute('value', v); }
|
|
156
162
|
}
|