@benev/web 0.1.0-2

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.
Files changed (111) hide show
  1. package/LICENSE +22 -0
  2. package/README.md +67 -0
  3. package/package.json +49 -0
  4. package/s/assets/b.png +0 -0
  5. package/s/assets/b.png.ts +3 -0
  6. package/s/consts.ts +5 -0
  7. package/s/css/benev.csstext.ts +41 -0
  8. package/s/css/demo.css +19 -0
  9. package/s/css/parts/common.csstext.ts +173 -0
  10. package/s/css/parts/core.csstext.ts +56 -0
  11. package/s/css/parts/page.csstext.ts +24 -0
  12. package/s/css/parts/vars.csstext.ts +40 -0
  13. package/s/css/theme.css.ts +9 -0
  14. package/s/dom/header/style.css.ts +40 -0
  15. package/s/dom/header/view.ts +31 -0
  16. package/s/dom/loader/loader.ts +70 -0
  17. package/s/dom/loader/style.css.ts +44 -0
  18. package/s/dom/loader/view.ts +20 -0
  19. package/s/dom/menu/style.css.ts +90 -0
  20. package/s/dom/menu/utils/click-backdrop.ts +8 -0
  21. package/s/dom/menu/utils/on-keypress.ts +22 -0
  22. package/s/dom/menu/utils/use-after-first-render.ts +9 -0
  23. package/s/dom/menu/view.ts +32 -0
  24. package/s/index-ssg.ts +3 -0
  25. package/s/index.html.ts +45 -0
  26. package/s/index.ts +14 -0
  27. package/s/main.bundle.ts +19 -0
  28. package/s/test.ts +5 -0
  29. package/s/vitals/setup.ts +21 -0
  30. package/s/vitals/shell.ts +67 -0
  31. package/x/assets/b.png +0 -0
  32. package/x/assets/b.png.d.ts +1 -0
  33. package/x/assets/b.png.js +2 -0
  34. package/x/assets/b.png.js.map +1 -0
  35. package/x/consts.d.ts +3 -0
  36. package/x/consts.js +4 -0
  37. package/x/consts.js.map +1 -0
  38. package/x/css/benev.csstext.d.ts +1 -0
  39. package/x/css/benev.csstext.js +39 -0
  40. package/x/css/benev.csstext.js.map +1 -0
  41. package/x/css/demo.css +19 -0
  42. package/x/css/parts/common.csstext.d.ts +2 -0
  43. package/x/css/parts/common.csstext.js +172 -0
  44. package/x/css/parts/common.csstext.js.map +1 -0
  45. package/x/css/parts/core.csstext.d.ts +2 -0
  46. package/x/css/parts/core.csstext.js +55 -0
  47. package/x/css/parts/core.csstext.js.map +1 -0
  48. package/x/css/parts/page.csstext.d.ts +2 -0
  49. package/x/css/parts/page.csstext.js +23 -0
  50. package/x/css/parts/page.csstext.js.map +1 -0
  51. package/x/css/parts/vars.csstext.d.ts +2 -0
  52. package/x/css/parts/vars.csstext.js +39 -0
  53. package/x/css/parts/vars.csstext.js.map +1 -0
  54. package/x/css/theme.css.d.ts +1 -0
  55. package/x/css/theme.css.js +7 -0
  56. package/x/css/theme.css.js.map +1 -0
  57. package/x/dom/header/style.css.d.ts +2 -0
  58. package/x/dom/header/style.css.js +39 -0
  59. package/x/dom/header/style.css.js.map +1 -0
  60. package/x/dom/header/view.d.ts +3 -0
  61. package/x/dom/header/view.js +26 -0
  62. package/x/dom/header/view.js.map +1 -0
  63. package/x/dom/loader/loader.d.ts +9 -0
  64. package/x/dom/loader/loader.js +53 -0
  65. package/x/dom/loader/loader.js.map +1 -0
  66. package/x/dom/loader/style.css.d.ts +2 -0
  67. package/x/dom/loader/style.css.js +43 -0
  68. package/x/dom/loader/style.css.js.map +1 -0
  69. package/x/dom/loader/view.d.ts +1 -0
  70. package/x/dom/loader/view.js +17 -0
  71. package/x/dom/loader/view.js.map +1 -0
  72. package/x/dom/menu/style.css.d.ts +2 -0
  73. package/x/dom/menu/style.css.js +89 -0
  74. package/x/dom/menu/style.css.js.map +1 -0
  75. package/x/dom/menu/utils/click-backdrop.d.ts +1 -0
  76. package/x/dom/menu/utils/click-backdrop.js +7 -0
  77. package/x/dom/menu/utils/click-backdrop.js.map +1 -0
  78. package/x/dom/menu/utils/on-keypress.d.ts +1 -0
  79. package/x/dom/menu/utils/on-keypress.js +18 -0
  80. package/x/dom/menu/utils/on-keypress.js.map +1 -0
  81. package/x/dom/menu/utils/use-after-first-render.d.ts +1 -0
  82. package/x/dom/menu/utils/use-after-first-render.js +7 -0
  83. package/x/dom/menu/utils/use-after-first-render.js.map +1 -0
  84. package/x/dom/menu/view.d.ts +2 -0
  85. package/x/dom/menu/view.js +27 -0
  86. package/x/dom/menu/view.js.map +1 -0
  87. package/x/index-ssg.d.ts +1 -0
  88. package/x/index-ssg.js +2 -0
  89. package/x/index-ssg.js.map +1 -0
  90. package/x/index.d.ts +9 -0
  91. package/x/index.html +368 -0
  92. package/x/index.html.d.ts +2 -0
  93. package/x/index.html.js +43 -0
  94. package/x/index.html.js.map +1 -0
  95. package/x/index.js +10 -0
  96. package/x/index.js.map +1 -0
  97. package/x/main.bundle.d.ts +1 -0
  98. package/x/main.bundle.js +12 -0
  99. package/x/main.bundle.js.map +1 -0
  100. package/x/main.bundle.min.js +522 -0
  101. package/x/main.bundle.min.js.LEGAL.txt +33 -0
  102. package/x/main.bundle.min.js.map +7 -0
  103. package/x/test.d.ts +1 -0
  104. package/x/test.js +3 -0
  105. package/x/test.js.map +1 -0
  106. package/x/vitals/setup.d.ts +9 -0
  107. package/x/vitals/setup.js +17 -0
  108. package/x/vitals/setup.js.map +1 -0
  109. package/x/vitals/shell.d.ts +7 -0
  110. package/x/vitals/shell.js +52 -0
  111. package/x/vitals/shell.js.map +1 -0
package/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+
2
+ MIT License
3
+
4
+ Copyright (c) 2026 Chase Moskal
5
+
6
+ Permission is hereby granted, free of charge, to any person obtaining a copy
7
+ of this software and associated documentation files (the "Software"), to deal
8
+ in the Software without restriction, including without limitation the rights
9
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10
+ copies of the Software, and to permit persons to whom the Software is
11
+ furnished to do so, subject to the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be included in all
14
+ copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,67 @@
1
+
2
+ # @benev/web
3
+
4
+ sdk toolkit for making an official benev website.
5
+
6
+ 1. **install npm package**
7
+ ```bash
8
+ npm i @benev/web
9
+ ```
10
+ - note that imports from `@benev/web` are browser-centric
11
+ - note that imports from `@benev/web/ssg` are node-safe
12
+ 1. **scute index.html.ts: install css from `ssg` entrypoint**
13
+ - import benev css
14
+ ```ts
15
+ import {benevCssText} from "@benev/web/ssg"
16
+ ```
17
+ - inject the css into your `<head>` (along with your own styles)
18
+ ```ts
19
+ html`
20
+ <style data-theme>
21
+ @layer benev, app;
22
+ @layer app {
23
+ :root {
24
+ color: #aaa;
25
+ background: #000;
26
+ }
27
+ }
28
+ ${html.raw(benevCssText)}
29
+ ${orb.inject("css/app.css")}
30
+ </style>
31
+ `
32
+ ```
33
+ - benev styles are on the `benev` layer
34
+ - the `app` layer is an example of your own app's styles
35
+ 1. **html: add `benev` html attribute wherever you want benev styles to apply**
36
+ ```html
37
+ <html benev>
38
+ ...
39
+ </html>
40
+ ```
41
+ 1. **typescript: install custom elements**
42
+ ```ts
43
+ import {dom} from "@e280/sly"
44
+ import {setupBenev} from "@benev/web"
45
+
46
+ const benev = await setupBenev()
47
+ dom.register(benev.elements)
48
+ ```
49
+ - menu (the benev overlay menu)
50
+ ```html
51
+ <benev-menu></benev-menu>
52
+ ```
53
+ - you can control the menu via `benev.shell`, eg, `benev.shell.toggle()`
54
+ - header (standard header with `b` button that opens menu)
55
+ ```html
56
+ <benev-header>
57
+ <a href="https://benev.gg/">benev.gg</a>
58
+ </benev-header>
59
+ ```
60
+ - loader (loading screens)
61
+ ```html
62
+ <benev-loader>
63
+ hello world
64
+ </benev-loader>
65
+ ```
66
+ - you control it by creating a `new Loader(dom("benev-loader"))`
67
+
package/package.json ADDED
@@ -0,0 +1,49 @@
1
+ {
2
+ "name": "@benev/web",
3
+ "version": "0.1.0-2",
4
+ "description": "✨ benev web sdk",
5
+ "license": "MIT",
6
+ "type": "module",
7
+ "main": "./x/index.js",
8
+ "exports": {
9
+ ".": "./x/index.js",
10
+ "./ssg": "./x/index-ssg.js"
11
+ },
12
+ "files": [
13
+ "x",
14
+ "s"
15
+ ],
16
+ "scripts": {
17
+ "build": "rm -rf x && mkdir x && tsc && scute -v",
18
+ "dev": "octo 'tsc -w' 'scute -vw' 'node --watch x/test.js' 'hottie x --port=8081'",
19
+ "test": "node x/test.js",
20
+ "count": "find s -path '*/_archive' -prune -o -name '*.ts' -exec wc -l {} +"
21
+ },
22
+ "allowScripts": {
23
+ "esbuild@0.28.1": true
24
+ },
25
+ "peerDependencies": {
26
+ "@e280/sly": "^0.4.4",
27
+ "@e280/strata": "^0.4.3",
28
+ "lit": "^3.3.2"
29
+ },
30
+ "dependencies": {
31
+ "@e280/stz": "^0.3.7"
32
+ },
33
+ "devDependencies": {
34
+ "@e280/hottie": "^0.1.2",
35
+ "@e280/octo": "^0.1.3",
36
+ "@e280/science": "^0.1.11",
37
+ "@e280/scute": "^0.5.0",
38
+ "typescript": "^7.0.2"
39
+ },
40
+ "author": "Chase Moskal <chasemoskal@gmail.com>",
41
+ "homepage": "https://github.com/benev-gg/web#readme",
42
+ "repository": {
43
+ "type": "git",
44
+ "url": "git+https://github.com/benev-gg/web.git"
45
+ },
46
+ "bugs": {
47
+ "url": "https://github.com/benev-gg/web/issues"
48
+ }
49
+ }
package/s/assets/b.png ADDED
Binary file
@@ -0,0 +1,3 @@
1
+
2
+ export const bDataPng = `data:image/png;base64,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`
3
+
package/s/consts.ts ADDED
@@ -0,0 +1,5 @@
1
+
2
+ export const consts = {
3
+ anim: 300,
4
+ }
5
+
@@ -0,0 +1,41 @@
1
+
2
+ import {templateString as css} from "@e280/stz"
3
+ import varsCsstext from "./parts/vars.csstext.js"
4
+ import coreCsstext from "./parts/core.csstext.js"
5
+ import pageCsstext from "./parts/page.csstext.js"
6
+ import commonCsstext from "./parts/common.csstext.js"
7
+
8
+ export const benevCssText = css`
9
+
10
+ @layer
11
+ benev.vars,
12
+ benev.core,
13
+ benev.common,
14
+ benev.page;
15
+
16
+ @layer benev.vars {
17
+ [benev], :host {
18
+ ${varsCsstext}
19
+ }
20
+ }
21
+
22
+ @layer benev.core {
23
+ [benev], :host {
24
+ ${coreCsstext}
25
+ }
26
+ }
27
+
28
+ @layer benev.common {
29
+ [benev], :host {
30
+ ${commonCsstext}
31
+ }
32
+ }
33
+
34
+ @layer benev.page {
35
+ [benev], :host {
36
+ ${pageCsstext}
37
+ }
38
+ }
39
+
40
+ `
41
+
package/s/css/demo.css ADDED
@@ -0,0 +1,19 @@
1
+
2
+ @layer demo {
3
+ benev-header {
4
+ z-index: 2;
5
+ position: absolute;
6
+ inset: 0 0 auto;
7
+ }
8
+
9
+ benev-loader {
10
+ position: absolute;
11
+ inset: 0;
12
+ }
13
+
14
+ main {
15
+ padding: var(--benev-pad);
16
+ padding-top: var(--benev-headroom);
17
+ }
18
+ }
19
+
@@ -0,0 +1,173 @@
1
+
2
+ import {templateString as css} from "@e280/stz"
3
+ export default css`
4
+
5
+ button, [benev-button] {
6
+ font: inherit;
7
+ text-decoration: none;
8
+
9
+ display: inline-flex;
10
+ align-items: center;
11
+ flex-wrap: wrap;
12
+ padding: var(--benev-pad) var(--benev-space);
13
+
14
+ font-weight: bold;
15
+ text-transform: uppercase;
16
+ color: var(--benev-prime);
17
+ background: oklch(from var(--benev-bg) l c h / 50%);
18
+ backdrop-filter: var(--benev-blur);
19
+ box-shadow: var(--benev-box-shadow);
20
+ border: var(--benev-thick) solid currentColor;
21
+ border-radius: var(--benev-round);
22
+
23
+ &[disabled] {
24
+ opacity: 0.3;
25
+ }
26
+
27
+ &:not([disabled]) {
28
+ cursor: pointer;
29
+ transform: scale(100%);
30
+ transition: all var(--benev-anim) ease;
31
+ &:hover, &:focus-visible { transform: scale(105%); filter: brightness(120%); }
32
+ &:active { transform: scale(100%); filter: brightness(100%); }
33
+ }
34
+
35
+ &[benev-button="naked"] {
36
+ color: inherit;
37
+ background: transparent;
38
+ backdrop-filter: none;
39
+ box-shadow: none;
40
+ padding: 0;
41
+ border-radius: 0;
42
+ border: none;
43
+ text-transform: unset;
44
+ font-weight: inherit;
45
+ text-transform: inherit;
46
+ }
47
+
48
+ &[benev-button="juicy"] {
49
+ opacity: 1;
50
+ color: black;
51
+ border: var(--benev-thick) solid var(--benev-prime);
52
+ background: linear-gradient(
53
+ to bottom,
54
+ oklch(from var(--benev-prime) calc(l * 1.5) c h),
55
+ oklch(from var(--benev-prime) l calc(c * 1.5) h)
56
+ );
57
+ &:is(:hover, :focus-visible) {
58
+ box-shadow: 0 0 2em color-mix(in oklch, transparent, var(--benev-prime));
59
+ }
60
+ }
61
+ }
62
+
63
+ [benev-slice] {
64
+ width: 100%;
65
+ max-width: var(--benev-site-width);
66
+ margin-left: auto;
67
+ margin-right: auto;
68
+ }
69
+
70
+ benev-menu:not(:defined) {
71
+ display: none;
72
+ }
73
+
74
+ benev-header {
75
+ display: flex;
76
+ justify-content: end;
77
+ align-items: center;
78
+ width: 100%;
79
+ max-width: var(--benev-site-width);
80
+ margin: 0 auto;
81
+
82
+ &:not(:defined) {
83
+ padding: var(--benev-pad);
84
+ gap: var(--benev-space);
85
+
86
+ &::before {
87
+ content: "";
88
+ display: inline-block;
89
+ margin-right: auto;
90
+ width: var(--benev-b-size);
91
+ height: var(--benev-b-size);
92
+ }
93
+ }
94
+ }
95
+
96
+ [benev-prose] {
97
+ display: flex;
98
+ flex-direction: column;
99
+ gap: var(--benev-pad);
100
+
101
+ h1 {
102
+ font-size: 2.5em;
103
+ color: var(--benev-intense);
104
+ a { color: inherit; }
105
+ }
106
+
107
+ h2 {
108
+ font-size: 1.5em;
109
+ color: var(--benev-prime);
110
+ }
111
+
112
+ h3, h4, h5, h6 {
113
+ color: var(--benev-prime);
114
+ }
115
+
116
+ h1, h2, h3, h4, h5, h6 {
117
+ margin-top: var(--benev-space);
118
+ }
119
+
120
+ p {
121
+ max-width: var(--benev-copy-width);
122
+ }
123
+
124
+ p:has(> img) {
125
+ max-width: 100%;
126
+ }
127
+
128
+ ul, ol {
129
+ padding-left: 1.5em;
130
+ }
131
+
132
+ img {
133
+ max-width: 100%;
134
+ background: #0004;
135
+ border-radius: var(--benev-round);
136
+ box-shadow: var(--benev-box-shadow);
137
+ }
138
+
139
+ blockquote {
140
+ color: oklch(from currentColor l 0 h / 50%);
141
+ padding-left: var(--benev-pad);
142
+ margin-left: var(--benev-pad);
143
+ font-style: italic;
144
+ border-left: var(--benev-thick) solid currentColor;
145
+ }
146
+
147
+ hr {
148
+ border: none;
149
+ display: block;
150
+ height: var(--benev-thick);
151
+ background: oklch(from var(--benev-text) l c h / 25%);
152
+ margin: var(--benev-space) 0;
153
+ }
154
+
155
+ code {
156
+ font-size: 0.8em;
157
+
158
+ display: block;
159
+ width: 100%;
160
+ overflow: auto;
161
+
162
+ padding: var(--benev-space);
163
+ color: var(--benev-code);
164
+ background: var(--benev-backdrop);
165
+ border-radius: var(--benev-round);
166
+ border: var(--benev-border);
167
+ border-color: oklch(from var(--benev-code) l c h / 33%);
168
+ box-shadow: var(--benev-box-shadow);
169
+ }
170
+ }
171
+
172
+ `
173
+
@@ -0,0 +1,56 @@
1
+
2
+ import {templateString as css} from "@e280/stz"
3
+ export default css`
4
+
5
+ &, *, ::before, ::after {
6
+ margin: 0;
7
+ padding: 0;
8
+ box-sizing: border-box;
9
+ scrollbar-width: thin;
10
+ }
11
+
12
+ :focus-visible {
13
+ outline: var(--benev-focus);
14
+ outline-offset: 0.2em;
15
+ }
16
+
17
+ ::selection {
18
+ color: var(--benev-select-color);
19
+ background: var(--benev-select-bg);
20
+ }
21
+
22
+ a {
23
+ color: var(--benev-link);
24
+ text-decoration: none;
25
+
26
+ &:visited {
27
+ color: var(--benev-link);
28
+ }
29
+
30
+ &:hover, &:focus-visible {
31
+ color: color-mix(in srgb, var(--benev-link), white 15%);
32
+ text-decoration: underline;
33
+ }
34
+
35
+ &:active {
36
+ color: color-mix(in srgb, var(--benev-link), white 50%);
37
+ }
38
+
39
+ &[benev-cardlink] {
40
+ color: inherit;
41
+
42
+ &:hover, &:focus-visible {
43
+ color: inherit;
44
+ text-decoration: none;
45
+ filter: brightness(105%);
46
+ }
47
+
48
+ &:active {
49
+ color: inherit;
50
+ filter: brightness(95%);
51
+ }
52
+ }
53
+ }
54
+
55
+ `
56
+
@@ -0,0 +1,24 @@
1
+
2
+ import {templateString as css} from "@e280/stz"
3
+ export default css`
4
+
5
+ color-scheme: dark;
6
+
7
+ &:is(html) {
8
+ font-family: sans-serif;
9
+ font-size: var(--benev-font-size);
10
+
11
+ scrollbar-gutter: stable;
12
+ scrollbar-width: thin;
13
+
14
+ color: var(--benev-text);
15
+ background: var(--benev-bg);
16
+ text-shadow: var(--benev-text-shadow);
17
+ }
18
+
19
+ body {
20
+ min-height: 100dvh;
21
+ }
22
+
23
+ `
24
+
@@ -0,0 +1,40 @@
1
+
2
+ import {templateString as css} from "@e280/stz"
3
+ import {consts} from "../../consts.js"
4
+ export default css`
5
+
6
+ --benev-font-size: 18px;
7
+ --benev-site-width: 62em;
8
+ --benev-copy-width: 70ch;
9
+ --benev-headroom: 2.5em;
10
+
11
+ --benev-bg: #111;
12
+ --benev-prime: #ebb935;
13
+ --benev-tray: #453e2ca8;
14
+ --benev-text: color-mix(in oklch, var(--benev-prime), #fffc 90%);
15
+ --benev-intense: white;
16
+ --benev-focus: 2px solid cyan;
17
+ --benev-link: aqua;
18
+ --benev-b-size: 1.5em;
19
+ --benev-code: #0f0;
20
+
21
+ --benev-select-bg: #f60;
22
+ --benev-select-color: #ff8;
23
+
24
+ --benev-line: #ebb93588;
25
+ --benev-thin: 1px;
26
+ --benev-thick: 3px;
27
+ --benev-border: var(--benev-thin) solid color-mix(in oklch, transparent, var(--benev-line) 50%);
28
+
29
+ --benev-pad: 0.5em;
30
+ --benev-space: 1em;
31
+ --benev-anim: ${consts.anim}ms;
32
+ --benev-round: 0.5em;
33
+ --benev-blur: blur(1em);
34
+ --benev-backdrop: #0008;
35
+
36
+ --benev-box-shadow: 0 0.5em 2em #0008;
37
+ --benev-text-shadow: 0.04em 0.08em 0.1em #0008;
38
+
39
+ `
40
+
@@ -0,0 +1,9 @@
1
+
2
+ import {benevCssText} from "./benev.csstext.js"
3
+
4
+ export const themeCss = [benevCssText].map(text => {
5
+ const sheet = new CSSStyleSheet()
6
+ sheet.replaceSync(text)
7
+ return sheet
8
+ })
9
+
@@ -0,0 +1,40 @@
1
+
2
+ import {css} from "lit"
3
+ export default css`@layer benev.view {
4
+
5
+ :host {
6
+ width: 100%;
7
+ pointer-events: none;
8
+ }
9
+
10
+ nav > *, ::slotted(*) {
11
+ pointer-events: all;
12
+ }
13
+
14
+ nav {
15
+ width: 100%;
16
+ display: flex;
17
+ flex-wrap: wrap;
18
+ justify-content: end;
19
+ align-items: center;
20
+ gap: var(--benev-space);
21
+ padding: var(--benev-pad);
22
+ }
23
+
24
+ button {
25
+ display: block;
26
+ margin-right: auto;
27
+
28
+ img {
29
+ display: block;
30
+ width: var(--benev-b-size);
31
+ height: var(--benev-b-size);
32
+ }
33
+ }
34
+
35
+ slot {
36
+ display: contents;
37
+ }
38
+
39
+ }`
40
+
@@ -0,0 +1,31 @@
1
+
2
+ import {html} from "lit"
3
+ import {shadow, shadowElement, useCss, useName} from "@e280/sly"
4
+ import {Shell} from "../../vitals/shell.js"
5
+ import {bDataPng} from "../../assets/b.png.js"
6
+ import {themeCss} from "../../css/theme.css.js"
7
+ import styleCss from "./style.css.js"
8
+
9
+ const Header = (shell: Shell) => {
10
+ const click = () => shell.toggle()
11
+ return html`
12
+ <nav part=nav ?data-opened=${shell.open} ?data-closed=${!shell.open}>
13
+ <button benev-button=naked title="b menu" @click=${click}>
14
+ <img part=img src="${bDataPng}" alt=""/>
15
+ </button>
16
+ <slot></slot>
17
+ </nav>
18
+ `
19
+ }
20
+
21
+ export const HeaderView = shadow((shell: Shell) => {
22
+ useName("header")
23
+ useCss(themeCss, styleCss)
24
+ return Header(shell)
25
+ })
26
+
27
+ export const headerElement = (shell: Shell) => shadowElement(() => {
28
+ useCss(themeCss, styleCss)
29
+ return Header(shell)
30
+ })
31
+
@@ -0,0 +1,70 @@
1
+
2
+ import {nap} from "@e280/stz"
3
+ import {Content, dom} from "@e280/sly"
4
+ import {consts} from "../../consts.js"
5
+
6
+ export class Loader {
7
+ original
8
+
9
+ #loading
10
+ #content
11
+ #operation = 0
12
+
13
+ constructor(
14
+ public element: HTMLElement,
15
+ public anim = consts.anim,
16
+ ) {
17
+
18
+ this.original = document.createElement("template")
19
+ this.original.innerHTML = element.innerHTML
20
+
21
+ this.#loading = document.createElement("div")
22
+ this.#loading.style.display = "contents"
23
+ this.#loading.slot = "loading"
24
+
25
+ this.#content = document.createElement("div")
26
+ this.#content.style.display = "contents"
27
+ dom.render(this.#content, Array.from(element.childNodes))
28
+
29
+ this.element.replaceChildren()
30
+ this.element.append(
31
+ this.#loading,
32
+ this.#content,
33
+ )
34
+ }
35
+
36
+ async load(
37
+ getLoading: () => Content,
38
+ getContent: () => Promise<Content>,
39
+ ) {
40
+
41
+ this.#operation += 1
42
+ const operation = this.#operation
43
+ const isLatest = () => (this.#operation === operation)
44
+ this.element.inert = true
45
+ this.element.toggleAttribute("loading", true)
46
+ dom.render(this.#loading, getLoading())
47
+
48
+ try {
49
+ const [content] = await Promise.all([
50
+ getContent(),
51
+ nap(this.anim * 2),
52
+ ])
53
+
54
+ if (isLatest()) {
55
+ this.element.toggleAttribute("loading", false)
56
+ this.element.inert = false
57
+ dom.render(this.#content, content)
58
+ await nap(this.anim)
59
+ }
60
+ }
61
+ finally {
62
+ if (isLatest()) {
63
+ this.element.toggleAttribute("loading", false)
64
+ this.element.inert = false
65
+ dom.render(this.#loading, null)
66
+ }
67
+ }
68
+ }
69
+ }
70
+