@iyulab/desktop-patterns 0.3.4 → 0.4.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 +13 -4
- package/dist/breakpoints-BjS_v3PV.js +5 -0
- package/dist/breakpoints.d.ts +8 -0
- package/dist/components/page/dp-page.d.ts +7 -0
- package/dist/components/shell/dp-shell.d.ts +9 -0
- package/dist/components/toolbar/dp-toolbar.d.ts +4 -2
- package/dist/index.d.ts +1 -0
- package/dist/index.js +7 -6
- package/dist/page.js +13 -2
- package/dist/shell.js +22 -13
- package/dist/toolbar.js +22 -14
- package/package.json +9 -2
package/README.md
CHANGED
|
@@ -33,7 +33,7 @@ import '@iyulab/desktop-patterns'
|
|
|
33
33
|
## Usage
|
|
34
34
|
|
|
35
35
|
```html
|
|
36
|
-
<dp-shell
|
|
36
|
+
<dp-shell>
|
|
37
37
|
<dp-sidebar slot="sidebar" active-id="overview" header="My App" id="nav"></dp-sidebar>
|
|
38
38
|
<dp-toolbar slot="toolbar" heading="My App" show-toggle></dp-toolbar>
|
|
39
39
|
<dp-page>
|
|
@@ -51,14 +51,23 @@ document.querySelector<HTMLElementTagNameMap['dp-sidebar']>('#nav')!.items = [
|
|
|
51
51
|
{ id: 'overview', icon: '■', label: 'Overview' },
|
|
52
52
|
]
|
|
53
53
|
|
|
54
|
+
const shell = document.querySelector('dp-shell')!
|
|
54
55
|
document.querySelector('dp-sidebar')!.addEventListener('dp-sidebar-select', (e) => {
|
|
55
56
|
// consumer owns activeId / routing
|
|
57
|
+
shell.sidebarOpen = false // a drawer gives way to what was picked
|
|
56
58
|
})
|
|
57
59
|
document.querySelector('dp-toolbar')!.addEventListener('dp-toolbar-toggle', () => {
|
|
58
|
-
|
|
60
|
+
shell.sidebarOpen = !shell.sidebarOpen
|
|
59
61
|
})
|
|
62
|
+
shell.addEventListener('dp-shell-sidebar-close', () => (shell.sidebarOpen = false)) // backdrop, Escape
|
|
60
63
|
```
|
|
61
64
|
|
|
65
|
+
Below the desktop breakpoint (1024px) the sidebar is a drawer over the content, open while
|
|
66
|
+
`sidebar-open` is set; at and above it the sidebar always sits beside the content and `sidebar-open`
|
|
67
|
+
changes nothing, and `dp-toolbar` hides its toggle there. The breakpoint is exported as
|
|
68
|
+
`desktopMinWidth` (and `desktopMedia` for a component's styles). The consumer owns that state — start it closed, and close it when the shell asks
|
|
69
|
+
(backdrop click, Escape) and when a place is picked, or a narrow window stays covered.
|
|
70
|
+
|
|
62
71
|
### Sidebar items: links, groups, icons, actions
|
|
63
72
|
|
|
64
73
|
```ts
|
|
@@ -125,9 +134,9 @@ dp-toolbar[drag-region]::part(drag-handle) {
|
|
|
125
134
|
|
|
126
135
|
| Component | Description |
|
|
127
136
|
|---|---|
|
|
128
|
-
| `dp-page` | Scrollable content region with a centered, max-width column — the page-body every view renders into |
|
|
137
|
+
| `dp-page` | Scrollable content region with a centered, max-width column — the page-body every view renders into. With `fill` it does not scroll and its column is as tall as the region, for a view that scrolls its own parts (a list beside the item open) |
|
|
129
138
|
| `dp-sidebar` | App-shell navigation rail — expanded/collapsed states, an optional pinned bottom group, a `footer` slot for whatever a consumer wants to anchor there |
|
|
130
|
-
| `dp-toolbar` | App-shell header bar — `heading`/`subtitle`, an optional
|
|
139
|
+
| `dp-toolbar` | App-shell header bar — `heading`/`subtitle`, an optional sidebar drawer toggle (below the desktop breakpoint only), a right-side `actions` slot |
|
|
131
140
|
| `dp-shell` | Top-level layout composing `sidebar`/`toolbar`/`banner`/main-content regions, with a responsive drawer (backdrop + overlay sidebar) below a 1024px breakpoint |
|
|
132
141
|
| `dp-shortcut-overlay` | Display-only keyboard-shortcuts help panel — a `shortcuts` list + `open` flag; no registration/binding infrastructure (that stays the consumer's) |
|
|
133
142
|
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The desktop breakpoint, in CSS pixels. Below it `dp-shell`'s sidebar is a drawer over the
|
|
3
|
+
* content; at and above it the sidebar always sits beside the content, so `dp-toolbar` hides the
|
|
4
|
+
* toggle that opens the drawer.
|
|
5
|
+
*/
|
|
6
|
+
export declare const desktopMinWidth = 1024;
|
|
7
|
+
/** The media query for {@link desktopMinWidth}, for a component's styles. */
|
|
8
|
+
export declare const desktopMedia: import('lit').CSSResult;
|
|
@@ -4,10 +4,17 @@ export type PageMaxWidth = 'sm' | 'md' | 'lg' | 'xl' | 'full';
|
|
|
4
4
|
* Scrollable content region with a centered, max-width column — the page-body
|
|
5
5
|
* pattern every view in an app shell renders into. Pure layout: it has no
|
|
6
6
|
* opinion on what it contains (default slot only).
|
|
7
|
+
*
|
|
8
|
+
* With `fill`, the page does not scroll: its column fills the region's height
|
|
9
|
+
* (a flex column), for a view that divides its own scrolling — a list beside
|
|
10
|
+
* the item open, where the list scrolls and the item stays in view. The
|
|
11
|
+
* slotted view sizes itself within that height (e.g. `flex: 1; min-height: 0`).
|
|
7
12
|
*/
|
|
8
13
|
export declare class DpPage extends LitElement {
|
|
9
14
|
static styles: import('lit').CSSResult;
|
|
10
15
|
maxWidth: PageMaxWidth;
|
|
16
|
+
/** Fill the region's height instead of scrolling: the view inside divides its own scrolling. */
|
|
17
|
+
fill: boolean;
|
|
11
18
|
render(): import('lit-html').TemplateResult<1>;
|
|
12
19
|
}
|
|
13
20
|
declare global {
|
|
@@ -28,7 +28,16 @@ export declare class DpShellSidebarCloseEvent extends Event {
|
|
|
28
28
|
*/
|
|
29
29
|
export declare class DpShell extends LitElement {
|
|
30
30
|
static styles: import('lit').CSSResult;
|
|
31
|
+
/**
|
|
32
|
+
* Whether the sidebar is open as a drawer below the desktop breakpoint. Above it the sidebar is
|
|
33
|
+
* always shown beside the content and this changes nothing. The consumer owns it: start it closed,
|
|
34
|
+
* and set it back to false on `dp-shell-sidebar-close` (backdrop click or Escape) and after a
|
|
35
|
+
* place is picked in the drawer.
|
|
36
|
+
*/
|
|
31
37
|
sidebarOpen: boolean;
|
|
38
|
+
private readonly onKeydown;
|
|
39
|
+
connectedCallback(): void;
|
|
40
|
+
disconnectedCallback(): void;
|
|
32
41
|
render(): import('lit-html').TemplateResult<1>;
|
|
33
42
|
}
|
|
34
43
|
declare global {
|
|
@@ -4,8 +4,9 @@ export declare class DpToolbarToggleEvent extends Event {
|
|
|
4
4
|
}
|
|
5
5
|
/**
|
|
6
6
|
* App-shell header bar: a `heading` (optionally overridden per-view by
|
|
7
|
-
* `subtitle`), an optional
|
|
8
|
-
*
|
|
7
|
+
* `subtitle`), an optional toggle for `dp-shell`'s sidebar drawer — shown
|
|
8
|
+
* only below the desktop breakpoint, where the sidebar is a drawer — and a
|
|
9
|
+
* right-side `actions` slot. Pure layout — this repo does not call any platform API.
|
|
9
10
|
*
|
|
10
11
|
* Named `heading`, not `title` — matches dc-section-heading's own
|
|
11
12
|
* established convention for this kind of headline text, and avoids
|
|
@@ -41,6 +42,7 @@ export declare class DpToolbar extends LitElement {
|
|
|
41
42
|
static styles: import('lit').CSSResult;
|
|
42
43
|
heading: string;
|
|
43
44
|
subtitle: string;
|
|
45
|
+
/** Shows the sidebar drawer toggle. It is hidden at and above the desktop breakpoint. */
|
|
44
46
|
showToggle: boolean;
|
|
45
47
|
/** Accessible name of the sidebar toggle — supply one in the app's language. */
|
|
46
48
|
toggleLabel: string;
|
package/dist/index.d.ts
CHANGED
package/dist/index.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
|
|
1
|
+
import { n as e, t } from "./breakpoints-BjS_v3PV.js";
|
|
2
|
+
import { DpPage as n } from "./page.js";
|
|
3
|
+
import { DpSidebar as r, DpSidebarActionEvent as i, DpSidebarSelectEvent as a } from "./sidebar.js";
|
|
4
|
+
import { DpToolbar as o, DpToolbarToggleEvent as s } from "./toolbar.js";
|
|
5
|
+
import { DpShell as c, DpShellSidebarCloseEvent as l } from "./shell.js";
|
|
6
|
+
import { DpShortcutOverlay as u, DpShortcutOverlayDismissEvent as d } from "./shortcut-overlay.js";
|
|
7
|
+
export { n as DpPage, c as DpShell, l as DpShellSidebarCloseEvent, u as DpShortcutOverlay, d as DpShortcutOverlayDismissEvent, r as DpSidebar, i as DpSidebarActionEvent, a as DpSidebarSelectEvent, o as DpToolbar, s as DpToolbarToggleEvent, t as desktopMedia, e as desktopMinWidth };
|
package/dist/page.js
CHANGED
|
@@ -10,7 +10,7 @@ var o = {
|
|
|
10
10
|
full: "none"
|
|
11
11
|
}, s = class extends t {
|
|
12
12
|
constructor(...e) {
|
|
13
|
-
super(...e), this.maxWidth = "md";
|
|
13
|
+
super(...e), this.maxWidth = "md", this.fill = !1;
|
|
14
14
|
}
|
|
15
15
|
static {
|
|
16
16
|
this.styles = n`
|
|
@@ -25,6 +25,14 @@ var o = {
|
|
|
25
25
|
padding: var(--dc-space-6, 24px);
|
|
26
26
|
box-sizing: border-box;
|
|
27
27
|
}
|
|
28
|
+
:host([fill]) {
|
|
29
|
+
overflow: hidden;
|
|
30
|
+
}
|
|
31
|
+
:host([fill]) .inner {
|
|
32
|
+
display: flex;
|
|
33
|
+
flex-direction: column;
|
|
34
|
+
height: 100%;
|
|
35
|
+
}
|
|
28
36
|
`;
|
|
29
37
|
}
|
|
30
38
|
render() {
|
|
@@ -38,6 +46,9 @@ var o = {
|
|
|
38
46
|
e([a({
|
|
39
47
|
attribute: "max-width",
|
|
40
48
|
reflect: !0
|
|
41
|
-
})], s.prototype, "maxWidth", void 0),
|
|
49
|
+
})], s.prototype, "maxWidth", void 0), e([a({
|
|
50
|
+
type: Boolean,
|
|
51
|
+
reflect: !0
|
|
52
|
+
})], s.prototype, "fill", void 0), s = e([i("dp-page")], s);
|
|
42
53
|
//#endregion
|
|
43
54
|
export { s as DpPage };
|
package/dist/shell.js
CHANGED
|
@@ -1,20 +1,23 @@
|
|
|
1
|
-
import { t as e } from "./
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
1
|
+
import { t as e } from "./breakpoints-BjS_v3PV.js";
|
|
2
|
+
import { t } from "./decorate-CafwLXg5.js";
|
|
3
|
+
import { LitElement as n, css as r, html as i, nothing as a } from "lit";
|
|
4
|
+
import { customElement as o, property as s } from "lit/decorators.js";
|
|
4
5
|
//#region src/components/shell/dp-shell.ts
|
|
5
|
-
var
|
|
6
|
+
var c = class extends Event {
|
|
6
7
|
constructor() {
|
|
7
8
|
super("dp-shell-sidebar-close", {
|
|
8
9
|
bubbles: !0,
|
|
9
10
|
composed: !0
|
|
10
11
|
});
|
|
11
12
|
}
|
|
12
|
-
},
|
|
13
|
+
}, l = class extends n {
|
|
13
14
|
constructor(...e) {
|
|
14
|
-
super(...e), this.sidebarOpen = !1
|
|
15
|
+
super(...e), this.sidebarOpen = !1, this.onKeydown = (e) => {
|
|
16
|
+
e.key === "Escape" && !e.defaultPrevented && this.sidebarOpen && this.dispatchEvent(new c());
|
|
17
|
+
};
|
|
15
18
|
}
|
|
16
19
|
static {
|
|
17
|
-
this.styles =
|
|
20
|
+
this.styles = r`
|
|
18
21
|
:host {
|
|
19
22
|
display: flex;
|
|
20
23
|
width: 100vw;
|
|
@@ -42,7 +45,7 @@ var s = class extends Event {
|
|
|
42
45
|
inset-inline-start: 0;
|
|
43
46
|
z-index: 40;
|
|
44
47
|
}
|
|
45
|
-
@media
|
|
48
|
+
@media ${e} {
|
|
46
49
|
/* Must match (or exceed) \`:host([sidebar-open]) .sidebar-region\`'s
|
|
47
50
|
specificity above (0,3,0) — a bare \`.sidebar-region\` here is only
|
|
48
51
|
(0,1,0), so on equal-or-narrower cascades the desktop override would
|
|
@@ -77,9 +80,15 @@ var s = class extends Event {
|
|
|
77
80
|
}
|
|
78
81
|
`;
|
|
79
82
|
}
|
|
83
|
+
connectedCallback() {
|
|
84
|
+
super.connectedCallback(), document.addEventListener("keydown", this.onKeydown);
|
|
85
|
+
}
|
|
86
|
+
disconnectedCallback() {
|
|
87
|
+
document.removeEventListener("keydown", this.onKeydown), super.disconnectedCallback();
|
|
88
|
+
}
|
|
80
89
|
render() {
|
|
81
|
-
return
|
|
82
|
-
${this.sidebarOpen ?
|
|
90
|
+
return i`
|
|
91
|
+
${this.sidebarOpen ? i`<div class="backdrop" @click=${() => this.dispatchEvent(new c())}></div>` : a}
|
|
83
92
|
<div class="sidebar-region"><slot name="sidebar"></slot></div>
|
|
84
93
|
<div class="main-column">
|
|
85
94
|
<div class="toolbar-row">
|
|
@@ -91,10 +100,10 @@ var s = class extends Event {
|
|
|
91
100
|
`;
|
|
92
101
|
}
|
|
93
102
|
};
|
|
94
|
-
|
|
103
|
+
t([s({
|
|
95
104
|
type: Boolean,
|
|
96
105
|
reflect: !0,
|
|
97
106
|
attribute: "sidebar-open"
|
|
98
|
-
})],
|
|
107
|
+
})], l.prototype, "sidebarOpen", void 0), l = t([o("dp-shell")], l);
|
|
99
108
|
//#endregion
|
|
100
|
-
export {
|
|
109
|
+
export { l as DpShell, c as DpShellSidebarCloseEvent };
|
package/dist/toolbar.js
CHANGED
|
@@ -1,20 +1,21 @@
|
|
|
1
|
-
import { t as e } from "./
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
1
|
+
import { t as e } from "./breakpoints-BjS_v3PV.js";
|
|
2
|
+
import { t } from "./decorate-CafwLXg5.js";
|
|
3
|
+
import { LitElement as n, css as r, html as i, nothing as a } from "lit";
|
|
4
|
+
import { customElement as o, property as s } from "lit/decorators.js";
|
|
4
5
|
//#region src/components/toolbar/dp-toolbar.ts
|
|
5
|
-
var
|
|
6
|
+
var c = class extends Event {
|
|
6
7
|
constructor() {
|
|
7
8
|
super("dp-toolbar-toggle", {
|
|
8
9
|
bubbles: !0,
|
|
9
10
|
composed: !0
|
|
10
11
|
});
|
|
11
12
|
}
|
|
12
|
-
},
|
|
13
|
+
}, l = class extends n {
|
|
13
14
|
constructor(...e) {
|
|
14
15
|
super(...e), this.heading = "", this.subtitle = "", this.showToggle = !1, this.toggleLabel = "Toggle sidebar", this.dragRegion = !1;
|
|
15
16
|
}
|
|
16
17
|
static {
|
|
17
|
-
this.styles =
|
|
18
|
+
this.styles = r`
|
|
18
19
|
:host {
|
|
19
20
|
display: flex;
|
|
20
21
|
align-items: center;
|
|
@@ -59,6 +60,13 @@ var s = class extends Event {
|
|
|
59
60
|
outline: 2px solid var(--dc-color-accent, #2563eb);
|
|
60
61
|
outline-offset: 2px;
|
|
61
62
|
}
|
|
63
|
+
/* At desktop width dp-shell's sidebar is always beside the content: a drawer toggle there
|
|
64
|
+
would do nothing. */
|
|
65
|
+
@media ${e} {
|
|
66
|
+
.toggle {
|
|
67
|
+
display: none;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
62
70
|
.drag-handle {
|
|
63
71
|
flex: 1;
|
|
64
72
|
align-self: stretch;
|
|
@@ -75,15 +83,15 @@ var s = class extends Event {
|
|
|
75
83
|
super.connectedCallback(), this.setAttribute("role", "banner");
|
|
76
84
|
}
|
|
77
85
|
render() {
|
|
78
|
-
return
|
|
86
|
+
return i`
|
|
79
87
|
<div class="start">
|
|
80
|
-
${this.showToggle ?
|
|
88
|
+
${this.showToggle ? i`<button
|
|
81
89
|
class="toggle"
|
|
82
90
|
aria-label=${this.toggleLabel}
|
|
83
|
-
@click=${() => this.dispatchEvent(new
|
|
91
|
+
@click=${() => this.dispatchEvent(new c())}
|
|
84
92
|
>
|
|
85
93
|
☰
|
|
86
|
-
</button>` :
|
|
94
|
+
</button>` : a}
|
|
87
95
|
<span class="title">${this.subtitle || this.heading}</span>
|
|
88
96
|
</div>
|
|
89
97
|
<div class="drag-handle" part="drag-handle"></div>
|
|
@@ -91,13 +99,13 @@ var s = class extends Event {
|
|
|
91
99
|
`;
|
|
92
100
|
}
|
|
93
101
|
};
|
|
94
|
-
|
|
102
|
+
t([s()], l.prototype, "heading", void 0), t([s()], l.prototype, "subtitle", void 0), t([s({
|
|
95
103
|
type: Boolean,
|
|
96
104
|
attribute: "show-toggle"
|
|
97
|
-
})],
|
|
105
|
+
})], l.prototype, "showToggle", void 0), t([s({ attribute: "toggle-label" })], l.prototype, "toggleLabel", void 0), t([s({
|
|
98
106
|
type: Boolean,
|
|
99
107
|
reflect: !0,
|
|
100
108
|
attribute: "drag-region"
|
|
101
|
-
})],
|
|
109
|
+
})], l.prototype, "dragRegion", void 0), l = t([o("dp-toolbar")], l);
|
|
102
110
|
//#endregion
|
|
103
|
-
export {
|
|
111
|
+
export { l as DpToolbar, c as DpToolbarToggleEvent };
|
package/package.json
CHANGED
|
@@ -1,8 +1,14 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@iyulab/desktop-patterns",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"license": "MIT",
|
|
6
|
+
"repository": {
|
|
7
|
+
"type": "git",
|
|
8
|
+
"url": "git+https://github.com/iyulab/desktop-patterns.git"
|
|
9
|
+
},
|
|
10
|
+
"homepage": "https://github.com/iyulab/desktop-patterns#readme",
|
|
11
|
+
"bugs": "https://github.com/iyulab/desktop-patterns/issues",
|
|
6
12
|
"engines": {
|
|
7
13
|
"node": ">=22"
|
|
8
14
|
},
|
|
@@ -48,6 +54,7 @@
|
|
|
48
54
|
},
|
|
49
55
|
"scripts": {
|
|
50
56
|
"build": "vite build",
|
|
57
|
+
"prepack": "npm run build",
|
|
51
58
|
"typecheck": "tsc --noEmit",
|
|
52
59
|
"test": "web-test-runner \"src/**/*.test.ts\"",
|
|
53
60
|
"test:watch": "web-test-runner \"src/**/*.test.ts\" --watch",
|
|
@@ -63,7 +70,7 @@
|
|
|
63
70
|
"@iyulab/desktop-compact": "^0.2.0 || ^0.3.0 || ^0.4.0 || ^0.5.0 || ^0.6.0 || ^0.7.0 || ^0.8.0"
|
|
64
71
|
},
|
|
65
72
|
"devDependencies": {
|
|
66
|
-
"@iyulab/desktop-compact": "^0.8.
|
|
73
|
+
"@iyulab/desktop-compact": "^0.8.2",
|
|
67
74
|
"@open-wc/testing": "^5.0.0",
|
|
68
75
|
"@storybook/web-components": "^10.6.0",
|
|
69
76
|
"@storybook/web-components-vite": "^10.6.0",
|