Skip to content

Commit f2bc47b

Browse files
committed
chore: apply progressive hydration to page
1 parent 59fa801 commit f2bc47b

File tree

149 files changed

+3148
-2228
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

149 files changed

+3148
-2228
lines changed

config/rocket.config.js

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,13 @@ export default /** @type {import('@rocket/cli/types/main').RocketCliOptions} */
3535
absoluteBaseUrl: absoluteBaseUrlNetlify('http://localhost:8080'),
3636
longFileHeaderWidth: 100,
3737
longFileHeaderComment: '// prettier-ignore',
38+
// adjustDevServerOptions: (options) => ({
39+
// ...options,
40+
// nodeResolve: {
41+
// ...options.nodeResolve,
42+
// exportConditions: ['development'],
43+
// },
44+
// }),
3845

3946
// buildOpenGraphImages: false,
4047

examples/01-hydration-starter/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
"@rocket/cli": "^0.20.0-alpha.17",
1515
"@rocket/engine": "^0.1.0-alpha.23",
1616
"@webcomponents/template-shadowroot": "^0.1.0",
17-
"lit": "^2.0.0"
17+
"lit": "^2.2.5"
1818
},
1919
"@rocket/template-name": "Hydration Starter",
2020
"imports": {

examples/02-blog-starter/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
"devDependencies": {
1919
"@rocket/cli": "^0.20.0-alpha.17",
2020
"@rocket/engine": "^0.1.0-alpha.23",
21-
"lit": "^2.0.0"
21+
"lit": "^2.2.5"
2222
},
2323
"@rocket/template-name": "Blog Starter"
2424
}

examples/03-minimal-starter/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
"devDependencies": {
1414
"@rocket/cli": "^0.20.0-alpha.17",
1515
"@rocket/engine": "^0.1.0-alpha.23",
16-
"lit": "^2.0.0"
16+
"lit": "^2.2.5"
1717
},
1818
"@rocket/template-name": "Minimal Starter"
1919
}

examples/04-sanity-minimal-starter/frontend/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
"@sanity/client": "^3.1.0",
1919
"@sanity/image-url": "^1.0.1",
2020
"dotenv": "^16.0.0",
21-
"lit": "^2.0.0"
21+
"lit": "^2.2.5"
2222
},
2323
"@rocket/template-name": "Sanity Minimal Starter"
2424
}

examples/50-landing-theme-spark/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
"@rocket/components": "^0.1.0-alpha.1",
1616
"@rocket/engine": "^0.1.0-alpha.23",
1717
"@rocket/spark": "^0.1.0-alpha.1",
18-
"lit": "^2.0.0"
18+
"lit": "^2.2.5"
1919
},
2020
"@rocket/template-name": "Landing Page (Spark Theme)",
2121
"imports": {

packages/components/dialog/RocketDialog.js

Lines changed: 304 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,319 @@
11
import { LitElement, html, css } from 'lit';
22

3+
// wait for all dialog animations to complete their promises
4+
const animationsComplete = element =>
5+
Promise.allSettled(element.getAnimations().map(animation => animation.finished));
6+
37
export class RocketDialog extends LitElement {
8+
static properties = {
9+
open: { type: Boolean, reflect: true },
10+
};
11+
12+
open = false;
13+
414
render() {
515
return html`
6-
<div class="dialog">
7-
<h2>hey</h2>
8-
<slot></slot>
9-
</div>
16+
<slot name="invoker" @click=${this.toggle}></slot>
17+
<dialog>
18+
<form method="dialog">
19+
<article>
20+
<section class="warning-message">
21+
<slot name="content"></slot>
22+
</section>
23+
</article>
24+
<footer>
25+
<menu>
26+
<slot name="buttons" @click=${this._submit}></slot>
27+
</menu>
28+
</footer>
29+
</form>
30+
</dialog>
1031
`;
1132
}
1233

34+
async _submit(ev) {
35+
ev.preventDefault();
36+
if (ev.target?.value) {
37+
this.dispatchEvent(new Event(ev.target.value));
38+
}
39+
await this.close();
40+
}
41+
42+
firstUpdated() {
43+
this._dialog = this.shadowRoot.querySelector('dialog');
44+
this._invoker = this.shadowRoot.querySelector('slot[name="invoker"]')?.assignedElements()[0];
45+
}
46+
47+
async close() {
48+
if (this.open === true && this._dialog) {
49+
this._dialog.setAttribute('inert', '');
50+
this._dialog.dispatchEvent(new Event('closing'));
51+
await animationsComplete(this._dialog);
52+
this._dialog.dispatchEvent(new Event('closed'));
53+
this._dialog.close();
54+
this.open = false;
55+
}
56+
}
57+
58+
async showModal() {
59+
if (this.open === false && this._dialog) {
60+
this.alignDialogToInvoker();
61+
this._dialog.showModal();
62+
this._dialog.dispatchEvent(new Event('opening'));
63+
await animationsComplete(this._dialog);
64+
this._dialog.dispatchEvent(new Event('opened'));
65+
this._dialog.removeAttribute('inert');
66+
this.open = true;
67+
68+
const focusTarget = this.querySelector('[autofocus]');
69+
focusTarget ? focusTarget.focus() : this.querySelector('button').focus();
70+
}
71+
}
72+
73+
alignDialogToInvoker() {
74+
const bounds = this._invoker.getBoundingClientRect();
75+
const miniModalHeight = this._dialog.clientHeight - 15;
76+
const miniModalWidth = this._dialog.clientWidth / 2;
77+
78+
let left = bounds.left - miniModalWidth;
79+
if (left < 0) {
80+
left = 10;
81+
}
82+
83+
this._dialog.style.marginTop = bounds.y - miniModalHeight + 'px';
84+
this._dialog.style.marginLeft = null;
85+
if (window.innerWidth >= 768) {
86+
this._dialog.style.marginLeft = left + 'px';
87+
}
88+
}
89+
90+
async toggle() {
91+
if (this._dialog) {
92+
if (this.open) {
93+
await this.close();
94+
} else {
95+
await this.showModal();
96+
}
97+
}
98+
}
99+
13100
static styles = [
14101
css`
15102
:host {
16103
display: block;
104+
--rd-surface-1: var(--surface-1, #f8f9fa);
105+
--rd-surface-2: var(--surface-2, #e9ecef);
106+
--rd-surface-3: var(--surface-3, #dee2e6);
107+
--rd-text-1: var(--text-1, #212529);
108+
/* shadow */
109+
--rd-shadow-color: 220 3% 15%;
110+
--rd-shadow-strength: 1%;
111+
--rd-shadow-2: 0 3px 5px -2px hsl(var(--rd-shadow-color) /
112+
calc(var(--rd-shadow-strength) + 3%)),
113+
0 7px 14px -5px hsl(var(--rd-shadow-color) / calc(var(--rd-shadow-strength) + 5%));
114+
--rd-shadow-6: 0 -1px 2px 0 hsl(var(--rd-shadow-color) /
115+
calc(var(--rd-shadow-strength) + 2%)),
116+
0 3px 2px -2px hsl(var(--rd-shadow-color) / calc(var(--rd-shadow-strength) + 3%)),
117+
0 7px 5px -2px hsl(var(--rd-shadow-color) / calc(var(--rd-shadow-strength) + 3%)),
118+
0 12px 10px -2px hsl(var(--rd-shadow-color) / calc(var(--rd-shadow-strength) + 4%)),
119+
0 22px 18px -2px hsl(var(--rd-shadow-color) / calc(var(--rd-shadow-strength) + 5%)),
120+
0 41px 33px -2px hsl(var(--rd-shadow-color) / calc(var(--rd-shadow-strength) + 6%)),
121+
0 100px 80px -2px hsl(var(--rd-shadow-color) / calc(var(--rd-shadow-strength) + 7%));
122+
/* size */
123+
--rd-size-3: var(--size-3, 1rem);
124+
--rd-size-5: var(--size-5, 1.5rem);
125+
/* animations */
126+
--rd-ease-3: cubic-bezier(0.25, 0, 0.3, 1);
127+
--rd-animation-scale-down: var(--animation-scale-down, scale-down 0.5s var(--rd-ease-3));
128+
--rd-animation-slide-in-up: var(--animation-in-up, slide-in-up 0.5s var(--rd-ease-3));
129+
}
130+
131+
@media (prefers-color-scheme: dark) {
132+
:host {
133+
--rd-surface-1: var(--surface-1, #212529);
134+
--rd-surface-2: var(--surface-2, #343a40);
135+
--rd-surface-3: var(--surface-3, #495057);
136+
--rd-text-1: var(--text-1, #f1f3f5);
137+
--rd-shadow-color: 220 40% 2%;
138+
--rd-shadow-strength: 25%;
139+
}
140+
}
141+
142+
dialog {
143+
display: grid;
144+
background: var(--rd-surface-2);
145+
color: var(--rd-text-1);
146+
max-inline-size: min(90vw, 60ch);
147+
max-block-size: min(80vh, 100%);
148+
max-block-size: min(80dvb, 100%);
149+
margin: auto;
150+
padding: 0;
151+
position: fixed;
152+
inset: 0;
153+
border-radius: 1rem;
154+
border: none;
155+
box-shadow: var(--rd-shadow-6);
156+
z-index: 2147483647;
157+
overflow: hidden;
158+
transition: opacity 0.5s var(--rd-ease-3);
159+
}
160+
161+
@media (prefers-reduced-motion: no-preference) {
162+
dialog {
163+
animation: var(--rd-animation-scale-down) forwards;
164+
animation-timing-function: var(--ease-squish-3);
165+
}
166+
}
167+
168+
@media (prefers-color-scheme: dark) {
169+
dialog {
170+
-webkit-border-before: 1px solid var(--_rg-surface-3);
171+
border-block-start: 1px solid var(--_rg-surface-3);
172+
}
173+
}
174+
175+
dialog:not([open]) {
176+
pointer-events: none;
177+
opacity: 0;
178+
}
179+
180+
dialog::-webkit-backdrop {
181+
-webkit-backdrop-filter: none;
182+
backdrop-filter: none;
183+
}
184+
185+
dialog::backdrop {
186+
-webkit-backdrop-filter: none;
187+
backdrop-filter: none;
188+
}
189+
190+
dialog::-webkit-backdrop {
191+
-webkit-transition: -webkit-backdrop-filter 0.5s ease;
192+
transition: -webkit-backdrop-filter 0.5s ease;
193+
transition: backdrop-filter 0.5s ease;
194+
transition: backdrop-filter 0.5s ease, -webkit-backdrop-filter 0.5s ease;
195+
}
196+
197+
dialog::backdrop {
198+
transition: -webkit-backdrop-filter 0.5s ease;
199+
transition: backdrop-filter 0.5s ease;
200+
transition: backdrop-filter 0.5s ease, -webkit-backdrop-filter 0.5s ease;
201+
}
202+
203+
@media (prefers-reduced-motion: no-preference) {
204+
dialog[open] {
205+
animation: var(--rd-animation-slide-in-up) forwards;
206+
}
207+
}
208+
209+
dialog > form {
210+
display: grid;
211+
grid-template-rows: auto 1fr auto;
212+
align-items: start;
213+
max-block-size: 80vh;
214+
max-block-size: 80dvb;
215+
}
216+
217+
dialog > form > article {
218+
overflow-y: auto;
219+
max-block-size: 100%;
220+
overscroll-behavior-y: contain;
221+
display: grid;
222+
justify-items: flex-start;
223+
gap: var(--rd-size-3);
224+
box-shadow: var(--shadow-2);
225+
z-index: var(--layer-1);
226+
padding-inline: var(--rd-size-5);
227+
padding-block: var(--rd-size-3);
228+
}
229+
230+
@media (prefers-color-scheme: light) {
231+
dialog > form > article {
232+
background: var(--rd-surface-1);
233+
}
234+
235+
dialog > form > article::-webkit-scrollbar {
236+
background: var(--rd-surface-1);
237+
}
238+
}
239+
240+
@media (prefers-color-scheme: dark) {
241+
dialog > form > article {
242+
-webkit-border-before: 1px solid var(--_rg-surface-3);
243+
border-block-start: 1px solid var(--_rg-surface-3);
244+
}
245+
}
246+
247+
dialog > form > header {
248+
display: flex;
249+
gap: var(--rd-size-3);
250+
justify-content: space-between;
251+
align-items: flex-start;
252+
padding-block: var(--rd-size-3);
253+
padding-inline: var(--rd-size-5);
254+
}
255+
256+
dialog > form > header > button {
257+
border-radius: var(--radius-round);
258+
padding: 0.75ch;
259+
aspect-ratio: 1;
260+
flex-shrink: 0;
261+
align-items: center;
262+
justify-items: center;
263+
place-items: center;
264+
stroke: currentColor;
265+
stroke-width: 3px;
266+
}
267+
268+
dialog > form > footer {
269+
display: flex;
270+
flex-wrap: wrap;
271+
gap: var(--rd-size-3);
272+
justify-content: space-between;
273+
align-items: flex-start;
274+
padding-inline: var(--rd-size-5);
275+
padding-block: var(--rd-size-3);
276+
}
277+
278+
dialog > form > footer > menu {
279+
display: flex;
280+
flex-wrap: wrap;
281+
gap: var(--rd-size-3);
282+
-webkit-padding-start: 0;
283+
padding-inline-start: 0;
284+
}
285+
286+
dialog > form > footer > menu:only-child {
287+
-webkit-margin-start: auto;
288+
margin-inline-start: auto;
289+
}
290+
291+
@media (max-width: 410px) {
292+
dialog > form > footer > menu button[type='reset'] {
293+
display: none;
294+
}
295+
}
296+
297+
dialog > form > :is(header, footer) {
298+
background-color: var(--rd-surface-2);
299+
}
300+
301+
@media (prefers-color-scheme: dark) {
302+
dialog > form > :is(header, footer) {
303+
background-color: var(--rd-surface-1);
304+
}
305+
}
306+
307+
@keyframes scale-down {
308+
to {
309+
transform: scale(0.75);
310+
}
311+
}
312+
313+
@keyframes slide-in-up {
314+
from {
315+
transform: translateY(100%);
316+
}
17317
}
18318
`,
19319
];

0 commit comments

Comments
 (0)