astro 3.3.3 → 3.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.
Files changed (48) hide show
  1. package/dist/@types/astro.d.ts +34 -0
  2. package/dist/assets/build/generate.d.ts +20 -16
  3. package/dist/assets/build/generate.js +125 -72
  4. package/dist/assets/types.d.ts +5 -4
  5. package/dist/assets/vite-plugin-assets.js +15 -7
  6. package/dist/cli/add/babel.d.ts +1 -1
  7. package/dist/core/build/generate.js +21 -33
  8. package/dist/core/config/schema.d.ts +14 -0
  9. package/dist/core/config/schema.js +4 -2
  10. package/dist/core/config/settings.js +1 -0
  11. package/dist/core/constants.js +1 -1
  12. package/dist/core/create-vite.js +3 -1
  13. package/dist/core/dev/dev.js +1 -1
  14. package/dist/core/messages.js +2 -2
  15. package/dist/core/render/core.js +1 -0
  16. package/dist/core/render/result.d.ts +1 -0
  17. package/dist/core/render/result.js +1 -0
  18. package/dist/integrations/index.js +3 -10
  19. package/dist/runtime/client/dev-overlay/overlay.d.ts +1 -0
  20. package/dist/runtime/client/dev-overlay/overlay.js +446 -0
  21. package/dist/runtime/client/dev-overlay/plugins/astro.d.ts +7 -0
  22. package/dist/runtime/client/dev-overlay/plugins/astro.js +66 -0
  23. package/dist/runtime/client/dev-overlay/plugins/audit.d.ts +7 -0
  24. package/dist/runtime/client/dev-overlay/plugins/audit.js +75 -0
  25. package/dist/runtime/client/dev-overlay/plugins/utils/highlight.d.ts +5 -0
  26. package/dist/runtime/client/dev-overlay/plugins/utils/highlight.js +39 -0
  27. package/dist/runtime/client/dev-overlay/plugins/xray.d.ts +7 -0
  28. package/dist/runtime/client/dev-overlay/plugins/xray.js +75 -0
  29. package/dist/runtime/client/dev-overlay/ui-library/card.d.ts +9 -0
  30. package/dist/runtime/client/dev-overlay/ui-library/card.js +67 -0
  31. package/dist/runtime/client/dev-overlay/ui-library/highlight.d.ts +7 -0
  32. package/dist/runtime/client/dev-overlay/ui-library/highlight.js +60 -0
  33. package/dist/runtime/client/dev-overlay/ui-library/icons.d.ts +10 -0
  34. package/dist/runtime/client/dev-overlay/ui-library/icons.js +21 -0
  35. package/dist/runtime/client/dev-overlay/ui-library/tooltip.d.ts +16 -0
  36. package/dist/runtime/client/dev-overlay/ui-library/tooltip.js +132 -0
  37. package/dist/runtime/client/dev-overlay/ui-library/window.d.ts +9 -0
  38. package/dist/runtime/client/dev-overlay/ui-library/window.js +70 -0
  39. package/dist/runtime/server/render/astro/render.js +2 -2
  40. package/dist/runtime/server/render/common.js +2 -2
  41. package/dist/runtime/server/render/component.js +1 -1
  42. package/dist/runtime/server/render/head.js +1 -1
  43. package/dist/transitions/router.js +39 -44
  44. package/dist/type-utils.d.ts +1 -0
  45. package/dist/vite-plugin-astro-server/route.js +17 -1
  46. package/dist/vite-plugin-dev-overlay/vite-plugin-dev-overlay.d.ts +3 -0
  47. package/dist/vite-plugin-dev-overlay/vite-plugin-dev-overlay.js +24 -0
  48. package/package.json +3 -2
@@ -0,0 +1,75 @@
1
+ import { attachTooltipToHighlight, createHighlight, positionHighlight } from "./utils/highlight.js";
2
+ const icon = '<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 16"><path fill="#fff" d="M.6 2A1.1 1.1 0 0 1 1.7.9h16.6a1.1 1.1 0 1 1 0 2.2H1.6A1.1 1.1 0 0 1 .8 2Zm1.1 7.1h6a1.1 1.1 0 0 0 0-2.2h-6a1.1 1.1 0 0 0 0 2.2ZM9.3 13H1.8a1.1 1.1 0 1 0 0 2.2h7.5a1.1 1.1 0 1 0 0-2.2Zm11.3 1.9a1.1 1.1 0 0 1-1.5 0l-1.7-1.7a4.1 4.1 0 1 1 1.6-1.6l1.6 1.7a1.1 1.1 0 0 1 0 1.6Zm-5.3-3.4a1.9 1.9 0 1 0 0-3.8 1.9 1.9 0 0 0 0 3.8Z"/></svg>';
3
+ const selectorBasedRules = [
4
+ {
5
+ title: "Missing `alt` tag",
6
+ message: "The alt attribute is important for accessibility.",
7
+ selector: "img:not([alt])"
8
+ }
9
+ ];
10
+ var audit_default = {
11
+ id: "astro:audit",
12
+ name: "Audit",
13
+ icon,
14
+ init(canvas, eventTarget) {
15
+ let audits = [];
16
+ selectorBasedRules.forEach((rule) => {
17
+ document.querySelectorAll(rule.selector).forEach((el) => {
18
+ createAuditProblem(rule, el);
19
+ });
20
+ });
21
+ if (audits.length > 0) {
22
+ eventTarget.dispatchEvent(
23
+ new CustomEvent("plugin-notification", {
24
+ detail: {
25
+ state: true
26
+ }
27
+ })
28
+ );
29
+ }
30
+ function createAuditProblem(rule, originalElement) {
31
+ const computedStyle = window.getComputedStyle(originalElement);
32
+ const targetedElement = originalElement.children[0] || originalElement;
33
+ if (targetedElement.offsetParent === null || computedStyle.display === "none") {
34
+ return;
35
+ }
36
+ const rect = originalElement.getBoundingClientRect();
37
+ const highlight = createHighlight(rect, "warning");
38
+ const tooltip = buildAuditTooltip(rule);
39
+ attachTooltipToHighlight(highlight, tooltip, originalElement);
40
+ canvas.append(highlight);
41
+ audits.push({ highlightElement: highlight, auditedElement: originalElement });
42
+ ["scroll", "resize"].forEach((event) => {
43
+ window.addEventListener(event, () => {
44
+ audits.forEach(({ highlightElement, auditedElement }) => {
45
+ const newRect = auditedElement.getBoundingClientRect();
46
+ positionHighlight(highlightElement, newRect);
47
+ });
48
+ });
49
+ });
50
+ }
51
+ function buildAuditTooltip(rule) {
52
+ const tooltip = document.createElement("astro-overlay-tooltip");
53
+ tooltip.sections = [
54
+ {
55
+ icon: "warning",
56
+ title: rule.title
57
+ },
58
+ {
59
+ content: rule.message
60
+ }
61
+ // TODO: Add a link to the file
62
+ // Needs https://github.com/withastro/compiler/pull/375
63
+ // {
64
+ // content: '/src/somewhere/component.astro',
65
+ // clickDescription: 'Click to go to file',
66
+ // clickAction() {},
67
+ // },
68
+ ];
69
+ return tooltip;
70
+ }
71
+ }
72
+ };
73
+ export {
74
+ audit_default as default
75
+ };
@@ -0,0 +1,5 @@
1
+ import type { DevOverlayHighlight } from '../../ui-library/highlight.js';
2
+ import type { Icon } from '../../ui-library/icons.js';
3
+ export declare function createHighlight(rect: DOMRect, icon?: Icon): DevOverlayHighlight;
4
+ export declare function positionHighlight(highlight: DevOverlayHighlight, rect: DOMRect): void;
5
+ export declare function attachTooltipToHighlight(highlight: DevOverlayHighlight, tooltip: HTMLElement, originalElement: Element): void;
@@ -0,0 +1,39 @@
1
+ function createHighlight(rect, icon) {
2
+ const highlight = document.createElement("astro-overlay-highlight");
3
+ if (icon)
4
+ highlight.icon = icon;
5
+ highlight.tabIndex = 0;
6
+ positionHighlight(highlight, rect);
7
+ return highlight;
8
+ }
9
+ function positionHighlight(highlight, rect) {
10
+ highlight.style.top = `${Math.max(rect.top + window.scrollY - 10, 0)}px`;
11
+ highlight.style.left = `${Math.max(rect.left + window.scrollX - 10, 0)}px`;
12
+ highlight.style.width = `${rect.width + 15}px`;
13
+ highlight.style.height = `${rect.height + 15}px`;
14
+ }
15
+ function attachTooltipToHighlight(highlight, tooltip, originalElement) {
16
+ highlight.shadowRoot.append(tooltip);
17
+ ["mouseover", "focus"].forEach((event) => {
18
+ highlight.addEventListener(event, () => {
19
+ tooltip.dataset.show = "true";
20
+ const originalRect = originalElement.getBoundingClientRect();
21
+ const dialogRect = tooltip.getBoundingClientRect();
22
+ if (originalRect.top < dialogRect.height) {
23
+ tooltip.style.top = `${originalRect.height + 15}px`;
24
+ } else {
25
+ tooltip.style.top = `-${tooltip.offsetHeight}px`;
26
+ }
27
+ });
28
+ });
29
+ ["mouseout", "blur"].forEach((event) => {
30
+ highlight.addEventListener(event, () => {
31
+ tooltip.dataset.show = "false";
32
+ });
33
+ });
34
+ }
35
+ export {
36
+ attachTooltipToHighlight,
37
+ createHighlight,
38
+ positionHighlight
39
+ };
@@ -0,0 +1,7 @@
1
+ declare const _default: {
2
+ id: string;
3
+ name: string;
4
+ icon: "<svg xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" viewBox=\"0 0 24 24\"><path fill=\"#fff\" d=\"M7.9 1.5v-.4a1.1 1.1 0 0 1 2.2 0v.4a1.1 1.1 0 1 1-2.2 0Zm-6.4 8.6a1.1 1.1 0 1 0 0-2.2h-.4a1.1 1.1 0 0 0 0 2.2h.4ZM12 3.7a1.1 1.1 0 0 0 1.4-.7l.4-1.1a1.1 1.1 0 0 0-2.1-.8l-.4 1.2a1.1 1.1 0 0 0 .7 1.4Zm-9.7 7.6-1.2.4a1.1 1.1 0 1 0 .8 2.1l1-.4a1.1 1.1 0 1 0-.6-2ZM20.8 17a1.9 1.9 0 0 1 0 2.6l-1.2 1.2a1.9 1.9 0 0 1-2.6 0l-4.3-4.2-1.6 3.6a1.9 1.9 0 0 1-1.7 1.2A1.9 1.9 0 0 1 7.5 20L2.7 5a1.9 1.9 0 0 1 2.4-2.4l15 5a1.9 1.9 0 0 1 .2 3.4l-3.7 1.6 4.2 4.3ZM19 18.3 14.6 14a1.9 1.9 0 0 1 .6-3l3.2-1.5L5.1 5.1l4.3 13.3 1.5-3.2a1.9 1.9 0 0 1 3-.6l4.4 4.4.7-.7Z\"/></svg>";
5
+ init(canvas: ShadowRoot): void;
6
+ };
7
+ export default _default;
@@ -0,0 +1,75 @@
1
+ import { attachTooltipToHighlight, createHighlight, positionHighlight } from "./utils/highlight.js";
2
+ const icon = '<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"><path fill="#fff" d="M7.9 1.5v-.4a1.1 1.1 0 0 1 2.2 0v.4a1.1 1.1 0 1 1-2.2 0Zm-6.4 8.6a1.1 1.1 0 1 0 0-2.2h-.4a1.1 1.1 0 0 0 0 2.2h.4ZM12 3.7a1.1 1.1 0 0 0 1.4-.7l.4-1.1a1.1 1.1 0 0 0-2.1-.8l-.4 1.2a1.1 1.1 0 0 0 .7 1.4Zm-9.7 7.6-1.2.4a1.1 1.1 0 1 0 .8 2.1l1-.4a1.1 1.1 0 1 0-.6-2ZM20.8 17a1.9 1.9 0 0 1 0 2.6l-1.2 1.2a1.9 1.9 0 0 1-2.6 0l-4.3-4.2-1.6 3.6a1.9 1.9 0 0 1-1.7 1.2A1.9 1.9 0 0 1 7.5 20L2.7 5a1.9 1.9 0 0 1 2.4-2.4l15 5a1.9 1.9 0 0 1 .2 3.4l-3.7 1.6 4.2 4.3ZM19 18.3 14.6 14a1.9 1.9 0 0 1 .6-3l3.2-1.5L5.1 5.1l4.3 13.3 1.5-3.2a1.9 1.9 0 0 1 3-.6l4.4 4.4.7-.7Z"/></svg>';
3
+ var xray_default = {
4
+ id: "astro:xray",
5
+ name: "Xray",
6
+ icon,
7
+ init(canvas) {
8
+ let islandsOverlays = [];
9
+ addIslandsOverlay();
10
+ function addIslandsOverlay() {
11
+ const islands = document.querySelectorAll("astro-island");
12
+ islands.forEach((island) => {
13
+ const computedStyle = window.getComputedStyle(island);
14
+ const islandElement = island.children[0] || island;
15
+ if (islandElement.offsetParent === null || computedStyle.display === "none") {
16
+ return;
17
+ }
18
+ const rect = islandElement.getBoundingClientRect();
19
+ const highlight = createHighlight(rect);
20
+ const tooltip = buildIslandTooltip(island);
21
+ attachTooltipToHighlight(highlight, tooltip, islandElement);
22
+ canvas.append(highlight);
23
+ islandsOverlays.push({ highlightElement: highlight, island: islandElement });
24
+ });
25
+ ["scroll", "resize"].forEach((event) => {
26
+ window.addEventListener(event, () => {
27
+ islandsOverlays.forEach(({ highlightElement, island: islandElement }) => {
28
+ const newRect = islandElement.getBoundingClientRect();
29
+ positionHighlight(highlightElement, newRect);
30
+ });
31
+ });
32
+ });
33
+ }
34
+ function buildIslandTooltip(island) {
35
+ const tooltip = document.createElement("astro-overlay-tooltip");
36
+ tooltip.sections = [];
37
+ const islandProps = island.getAttribute("props") ? JSON.parse(island.getAttribute("props")) : {};
38
+ const islandClientDirective = island.getAttribute("client");
39
+ if (islandClientDirective) {
40
+ tooltip.sections.push({
41
+ title: "Client directive",
42
+ inlineTitle: `<code>client:${islandClientDirective}</code>`
43
+ });
44
+ }
45
+ if (Object.keys(islandProps).length > 0) {
46
+ tooltip.sections.push({
47
+ title: "Props",
48
+ content: `${Object.entries(islandProps).map((prop) => `<code>${prop[0]}=${getPropValue(prop[1])}</code>`).join(", ")}`
49
+ });
50
+ }
51
+ const islandComponentPath = island.getAttribute("component-url");
52
+ if (islandComponentPath) {
53
+ tooltip.sections.push({
54
+ content: islandComponentPath,
55
+ clickDescription: "Click to go to file",
56
+ async clickAction() {
57
+ await fetch(
58
+ "/__open-in-editor?file=" + encodeURIComponent(
59
+ window.__astro_dev_overlay__.root + islandComponentPath.slice(1)
60
+ )
61
+ );
62
+ }
63
+ });
64
+ }
65
+ return tooltip;
66
+ }
67
+ function getPropValue(prop) {
68
+ const [_, value] = prop;
69
+ return JSON.stringify(value, null, 2);
70
+ }
71
+ }
72
+ };
73
+ export {
74
+ xray_default as default
75
+ };
@@ -0,0 +1,9 @@
1
+ import { type Icon } from './icons.js';
2
+ export declare class DevOverlayCard extends HTMLElement {
3
+ icon?: Icon;
4
+ link?: string | undefined | null;
5
+ shadowRoot: ShadowRoot;
6
+ constructor();
7
+ connectedCallback(): void;
8
+ getElementForIcon(icon: Icon): string;
9
+ }
@@ -0,0 +1,67 @@
1
+ import { getIconElement, isDefinedIcon } from "./icons.js";
2
+ class DevOverlayCard extends HTMLElement {
3
+ icon;
4
+ link;
5
+ shadowRoot;
6
+ constructor() {
7
+ super();
8
+ this.shadowRoot = this.attachShadow({ mode: "open" });
9
+ this.link = this.getAttribute("link");
10
+ this.icon = this.hasAttribute("icon") ? this.getAttribute("icon") : void 0;
11
+ }
12
+ connectedCallback() {
13
+ const element = this.link ? "a" : "button";
14
+ this.shadowRoot.innerHTML = `
15
+ <style>
16
+ a, button {
17
+ display: block;
18
+ padding: 40px 16px;
19
+ border-radius: 8px;
20
+ border: 1px solid rgba(35, 38, 45, 1);
21
+ color: #fff;
22
+ font-size: 16px;
23
+ font-weight: 600;
24
+ line-height: 19px;
25
+ text-decoration: none;
26
+ }
27
+
28
+ a:hover, button:hover {
29
+ background: rgba(136, 58, 234, 0.33);
30
+ border: 1px solid rgba(113, 24, 226, 1)
31
+ }
32
+
33
+ svg {
34
+ display: block;
35
+ margin: 0 auto;
36
+ }
37
+
38
+ span {
39
+ margin-top: 8px;
40
+ display: block;
41
+ text-align: center;
42
+ }
43
+ </style>
44
+
45
+ <${element}${this.link ? ` href="${this.link}" target="_blank"` : ``}>
46
+ ${this.icon ? this.getElementForIcon(this.icon) : ""}
47
+ <span><slot /></span>
48
+ </${element}>
49
+ `;
50
+ }
51
+ getElementForIcon(icon) {
52
+ let iconElement;
53
+ if (isDefinedIcon(icon)) {
54
+ iconElement = getIconElement(icon);
55
+ } else {
56
+ iconElement = document.createElementNS("http://www.w3.org/2000/svg", "svg");
57
+ iconElement.setAttribute("viewBox", "0 0 16 16");
58
+ iconElement.innerHTML = icon;
59
+ }
60
+ iconElement?.style.setProperty("height", "24px");
61
+ iconElement?.style.setProperty("width", "24px");
62
+ return iconElement?.outerHTML ?? "";
63
+ }
64
+ }
65
+ export {
66
+ DevOverlayCard
67
+ };
@@ -0,0 +1,7 @@
1
+ import { type Icon } from './icons.js';
2
+ export declare class DevOverlayHighlight extends HTMLElement {
3
+ icon?: Icon | undefined | null;
4
+ shadowRoot: ShadowRoot;
5
+ constructor();
6
+ connectedCallback(): void;
7
+ }
@@ -0,0 +1,60 @@
1
+ import { getIconElement, isDefinedIcon } from "./icons.js";
2
+ class DevOverlayHighlight extends HTMLElement {
3
+ icon;
4
+ shadowRoot;
5
+ constructor() {
6
+ super();
7
+ this.shadowRoot = this.attachShadow({ mode: "open" });
8
+ this.icon = this.hasAttribute("icon") ? this.getAttribute("icon") : void 0;
9
+ this.shadowRoot.innerHTML = `
10
+ <style>
11
+ :host {
12
+ background: linear-gradient(180deg, rgba(224, 204, 250, 0.33) 0%, rgba(224, 204, 250, 0.0825) 100%);
13
+ border: 1px solid rgba(113, 24, 226, 1);
14
+ border-radius: 4px;
15
+ display: block;
16
+ width: 100%;
17
+ height: 100%;
18
+ position: absolute;
19
+ }
20
+
21
+ .icon {
22
+ width: 24px;
23
+ height: 24px;
24
+ background: linear-gradient(0deg, #B33E66, #B33E66), linear-gradient(0deg, #351722, #351722);
25
+ border: 1px solid rgba(53, 23, 34, 1);
26
+ border-radius: 9999px;
27
+ display: flex;
28
+ justify-content: center;
29
+ align-items: center;
30
+ position: absolute;
31
+ top: -15px;
32
+ right: -15px;
33
+ }
34
+ </style>
35
+ `;
36
+ }
37
+ connectedCallback() {
38
+ if (this.icon) {
39
+ let iconContainer = document.createElement("div");
40
+ iconContainer.classList.add("icon");
41
+ let iconElement;
42
+ if (isDefinedIcon(this.icon)) {
43
+ iconElement = getIconElement(this.icon);
44
+ } else {
45
+ iconElement = document.createElementNS("http://www.w3.org/2000/svg", "svg");
46
+ iconElement.setAttribute("viewBox", "0 0 16 16");
47
+ iconElement.innerHTML = this.icon;
48
+ }
49
+ if (iconElement) {
50
+ iconElement?.style.setProperty("width", "16px");
51
+ iconElement?.style.setProperty("height", "16px");
52
+ iconContainer.append(iconElement);
53
+ this.shadowRoot.append(iconContainer);
54
+ }
55
+ }
56
+ }
57
+ }
58
+ export {
59
+ DevOverlayHighlight
60
+ };
@@ -0,0 +1,10 @@
1
+ export type DefinedIcon = keyof typeof icons;
2
+ export type Icon = DefinedIcon | (string & NonNullable<unknown>);
3
+ export declare function isDefinedIcon(icon: Icon): icon is DefinedIcon;
4
+ export declare function getIconElement(name: keyof typeof icons | (string & NonNullable<unknown>)): SVGElement | undefined;
5
+ declare const icons: {
6
+ readonly 'astro:logo': "<svg xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" viewBox=\"0 0 85 107\"><path fill=\"#fff\" d=\"M27.6 91.1c-4.8-4.4-6.3-13.7-4.2-20.4 3.5 4.2 8.3 5.6 13.3 6.3 7.7 1.2 15.3.8 22.5-2.8l2.5-1.4c.7 2 .9 3.9.6 5.9-.6 4.9-3 8.7-6.9 11.5-1.5 1.2-3.2 2.2-4.8 3.3-4.9 3.3-6.2 7.2-4.4 12.9l.2.6a13 13 0 0 1-5.7-5 13.8 13.8 0 0 1-2.2-7.4c0-1.3 0-2.7-.2-4-.5-3.1-2-4.6-4.8-4.7a5.5 5.5 0 0 0-5.7 4.6l-.2.6Z\"/><path fill=\"url(#a)\" d=\"M27.6 91.1c-4.8-4.4-6.3-13.7-4.2-20.4 3.5 4.2 8.3 5.6 13.3 6.3 7.7 1.2 15.3.8 22.5-2.8l2.5-1.4c.7 2 .9 3.9.6 5.9-.6 4.9-3 8.7-6.9 11.5-1.5 1.2-3.2 2.2-4.8 3.3-4.9 3.3-6.2 7.2-4.4 12.9l.2.6a13 13 0 0 1-5.7-5 13.8 13.8 0 0 1-2.2-7.4c0-1.3 0-2.7-.2-4-.5-3.1-2-4.6-4.8-4.7a5.5 5.5 0 0 0-5.7 4.6l-.2.6Z\"/><path fill=\"#fff\" d=\"M0 69.6s14.3-7 28.7-7l10.8-33.5c.4-1.6 1.6-2.7 3-2.7 1.2 0 2.4 1.1 2.8 2.7l10.9 33.5c17 0 28.6 7 28.6 7L60.5 3.2c-.7-2-2-3.2-3.5-3.2H27.8c-1.6 0-2.7 1.3-3.4 3.2L0 69.6Z\"/><defs><linearGradient id=\"a\" x1=\"22.5\" x2=\"69.1\" y1=\"107\" y2=\"84.9\" gradientUnits=\"userSpaceOnUse\"><stop stop-color=\"#D83333\"/><stop offset=\"1\" stop-color=\"#F041FF\"/></linearGradient></defs></svg>";
7
+ readonly warning: "<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 16 16\"><path fill=\"#fff\" d=\"M8 .40625c-1.5019 0-2.97007.445366-4.21886 1.27978C2.53236 2.52044 1.55905 3.70642.984293 5.094.40954 6.48157.259159 8.00842.552165 9.48147.845172 10.9545 1.56841 12.3076 2.63041 13.3696c1.06201 1.062 2.41508 1.7852 3.88813 2.0782 1.47304.293 2.99989.1427 4.38746-.4321 1.3876-.5747 2.5736-1.5481 3.408-2.7968.8344-1.2488 1.2798-2.717 1.2798-4.2189-.0023-2.0133-.8031-3.9435-2.2267-5.36713C11.9435 1.20925 10.0133.408483 8 .40625ZM8 13.9062c-1.16814 0-2.31006-.3463-3.28133-.9953-.97128-.649-1.7283-1.5715-2.17533-2.6507-.44703-1.0792-.56399-2.26675-.3361-3.41245.22789-1.1457.79041-2.1981 1.61641-3.0241.82601-.826 1.8784-1.38852 3.0241-1.61641 1.1457-.2279 2.33325-.11093 3.41245.3361 1.0793.44703 2.0017 1.20405 2.6507 2.17532.649.97128.9954 2.11319.9954 3.28134-.0017 1.56592-.6245 3.0672-1.7318 4.1745S9.56592 13.9046 8 13.9062Zm-.84375-5.62495V4.625c0-.22378.0889-.43839.24713-.59662.15824-.15824.37285-.24713.59662-.24713.22378 0 .43839.08889.59662.24713.15824.15823.24713.37284.24713.59662v3.65625c0 .22378-.08889.43839-.24713.59662C8.43839 9.03611 8.22378 9.125 8 9.125c-.22377 0-.43838-.08889-.59662-.24713-.15823-.15823-.24713-.37284-.24713-.59662ZM9.125 11.0938c0 .2225-.06598.44-.18959.625-.12362.185-.29932.3292-.50489.4143-.20556.0852-.43176.1074-.64999.064-.21823-.0434-.41869-.1505-.57602-.3079-.15734-.1573-.26448-.3577-.30789-.576-.04341-.2182-.02113-.4444.06402-.65.08515-.2055.22934-.3812.41435-.5049.185-.1236.40251-.18955.62501-.18955.29837 0 .58452.11855.7955.32955.21098.2109.3295.4971.3295.7955Z\"/></svg>";
8
+ readonly 'arrow-down': "<svg xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" viewBox=\"0 0 12 14\"><path fill=\"#13151A\" d=\"m11.0306 8.53063-4.5 4.49997c-.06968.0699-.15247.1254-.24364.1633-.09116.0378-.1889.0573-.28761.0573-.09871 0-.19645-.0195-.28762-.0573-.09116-.0379-.17395-.0934-.24363-.1633L.968098 8.53063c-.140896-.1409-.220051-.332-.220051-.53125 0-.19926.079155-.39036.220051-.53125.140892-.1409.331992-.22006.531252-.22006.19926 0 .39035.07916.53125.22006l3.21937 3.21937V1.5c0-.19891.07902-.38968.21967-.53033C5.61029.829018 5.80106.75 5.99997.75c.19891 0 .38968.079018.53033.21967.14065.14065.21967.33142.21967.53033v9.1875l3.21938-3.22c.14085-.1409.33195-.22005.53125-.22005.1993 0 .3904.07915.5312.22005.1409.1409.2201.33199.2201.53125s-.0792.39035-.2201.53125l-.0012.00063Z\"/></svg>";
9
+ };
10
+ export {};
@@ -0,0 +1,21 @@
1
+ function isDefinedIcon(icon) {
2
+ return icon in icons;
3
+ }
4
+ function getIconElement(name) {
5
+ const icon = icons[name];
6
+ if (!icon) {
7
+ return void 0;
8
+ }
9
+ const svgFragment = new DocumentFragment();
10
+ svgFragment.append(document.createRange().createContextualFragment(icon));
11
+ return svgFragment.firstElementChild;
12
+ }
13
+ const icons = {
14
+ "astro:logo": `<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 85 107"><path fill="#fff" d="M27.6 91.1c-4.8-4.4-6.3-13.7-4.2-20.4 3.5 4.2 8.3 5.6 13.3 6.3 7.7 1.2 15.3.8 22.5-2.8l2.5-1.4c.7 2 .9 3.9.6 5.9-.6 4.9-3 8.7-6.9 11.5-1.5 1.2-3.2 2.2-4.8 3.3-4.9 3.3-6.2 7.2-4.4 12.9l.2.6a13 13 0 0 1-5.7-5 13.8 13.8 0 0 1-2.2-7.4c0-1.3 0-2.7-.2-4-.5-3.1-2-4.6-4.8-4.7a5.5 5.5 0 0 0-5.7 4.6l-.2.6Z"/><path fill="url(#a)" d="M27.6 91.1c-4.8-4.4-6.3-13.7-4.2-20.4 3.5 4.2 8.3 5.6 13.3 6.3 7.7 1.2 15.3.8 22.5-2.8l2.5-1.4c.7 2 .9 3.9.6 5.9-.6 4.9-3 8.7-6.9 11.5-1.5 1.2-3.2 2.2-4.8 3.3-4.9 3.3-6.2 7.2-4.4 12.9l.2.6a13 13 0 0 1-5.7-5 13.8 13.8 0 0 1-2.2-7.4c0-1.3 0-2.7-.2-4-.5-3.1-2-4.6-4.8-4.7a5.5 5.5 0 0 0-5.7 4.6l-.2.6Z"/><path fill="#fff" d="M0 69.6s14.3-7 28.7-7l10.8-33.5c.4-1.6 1.6-2.7 3-2.7 1.2 0 2.4 1.1 2.8 2.7l10.9 33.5c17 0 28.6 7 28.6 7L60.5 3.2c-.7-2-2-3.2-3.5-3.2H27.8c-1.6 0-2.7 1.3-3.4 3.2L0 69.6Z"/><defs><linearGradient id="a" x1="22.5" x2="69.1" y1="107" y2="84.9" gradientUnits="userSpaceOnUse"><stop stop-color="#D83333"/><stop offset="1" stop-color="#F041FF"/></linearGradient></defs></svg>`,
15
+ warning: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><path fill="#fff" d="M8 .40625c-1.5019 0-2.97007.445366-4.21886 1.27978C2.53236 2.52044 1.55905 3.70642.984293 5.094.40954 6.48157.259159 8.00842.552165 9.48147.845172 10.9545 1.56841 12.3076 2.63041 13.3696c1.06201 1.062 2.41508 1.7852 3.88813 2.0782 1.47304.293 2.99989.1427 4.38746-.4321 1.3876-.5747 2.5736-1.5481 3.408-2.7968.8344-1.2488 1.2798-2.717 1.2798-4.2189-.0023-2.0133-.8031-3.9435-2.2267-5.36713C11.9435 1.20925 10.0133.408483 8 .40625ZM8 13.9062c-1.16814 0-2.31006-.3463-3.28133-.9953-.97128-.649-1.7283-1.5715-2.17533-2.6507-.44703-1.0792-.56399-2.26675-.3361-3.41245.22789-1.1457.79041-2.1981 1.61641-3.0241.82601-.826 1.8784-1.38852 3.0241-1.61641 1.1457-.2279 2.33325-.11093 3.41245.3361 1.0793.44703 2.0017 1.20405 2.6507 2.17532.649.97128.9954 2.11319.9954 3.28134-.0017 1.56592-.6245 3.0672-1.7318 4.1745S9.56592 13.9046 8 13.9062Zm-.84375-5.62495V4.625c0-.22378.0889-.43839.24713-.59662.15824-.15824.37285-.24713.59662-.24713.22378 0 .43839.08889.59662.24713.15824.15823.24713.37284.24713.59662v3.65625c0 .22378-.08889.43839-.24713.59662C8.43839 9.03611 8.22378 9.125 8 9.125c-.22377 0-.43838-.08889-.59662-.24713-.15823-.15823-.24713-.37284-.24713-.59662ZM9.125 11.0938c0 .2225-.06598.44-.18959.625-.12362.185-.29932.3292-.50489.4143-.20556.0852-.43176.1074-.64999.064-.21823-.0434-.41869-.1505-.57602-.3079-.15734-.1573-.26448-.3577-.30789-.576-.04341-.2182-.02113-.4444.06402-.65.08515-.2055.22934-.3812.41435-.5049.185-.1236.40251-.18955.62501-.18955.29837 0 .58452.11855.7955.32955.21098.2109.3295.4971.3295.7955Z"/></svg>`,
16
+ "arrow-down": '<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 12 14"><path fill="#13151A" d="m11.0306 8.53063-4.5 4.49997c-.06968.0699-.15247.1254-.24364.1633-.09116.0378-.1889.0573-.28761.0573-.09871 0-.19645-.0195-.28762-.0573-.09116-.0379-.17395-.0934-.24363-.1633L.968098 8.53063c-.140896-.1409-.220051-.332-.220051-.53125 0-.19926.079155-.39036.220051-.53125.140892-.1409.331992-.22006.531252-.22006.19926 0 .39035.07916.53125.22006l3.21937 3.21937V1.5c0-.19891.07902-.38968.21967-.53033C5.61029.829018 5.80106.75 5.99997.75c.19891 0 .38968.079018.53033.21967.14065.14065.21967.33142.21967.53033v9.1875l3.21938-3.22c.14085-.1409.33195-.22005.53125-.22005.1993 0 .3904.07915.5312.22005.1409.1409.2201.33199.2201.53125s-.0792.39035-.2201.53125l-.0012.00063Z"/></svg>'
17
+ };
18
+ export {
19
+ getIconElement,
20
+ isDefinedIcon
21
+ };
@@ -0,0 +1,16 @@
1
+ import { type Icon } from './icons.js';
2
+ export interface DevOverlayTooltipSection {
3
+ title?: string;
4
+ inlineTitle?: string;
5
+ icon?: Icon;
6
+ content?: string;
7
+ clickAction?: () => void | Promise<void>;
8
+ clickDescription?: string;
9
+ }
10
+ export declare class DevOverlayTooltip extends HTMLElement {
11
+ sections: DevOverlayTooltipSection[];
12
+ shadowRoot: ShadowRoot;
13
+ constructor();
14
+ connectedCallback(): void;
15
+ getElementForIcon(icon: Icon | (string & NonNullable<unknown>)): string;
16
+ }
@@ -0,0 +1,132 @@
1
+ import { getIconElement, isDefinedIcon } from "./icons.js";
2
+ class DevOverlayTooltip extends HTMLElement {
3
+ sections = [];
4
+ shadowRoot;
5
+ constructor() {
6
+ super();
7
+ this.shadowRoot = this.attachShadow({ mode: "open" });
8
+ }
9
+ connectedCallback() {
10
+ this.shadowRoot.innerHTML = `
11
+ <style>
12
+ :host {
13
+ position: absolute;
14
+ display: none;
15
+ color: white;
16
+ background: linear-gradient(0deg, #310A65, #310A65), linear-gradient(0deg, #7118E2, #7118E2);
17
+ border: 1px solid rgba(113, 24, 226, 1);
18
+ border-radius: 4px;
19
+ padding: 0;
20
+ font-family: ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
21
+ font-size: 14px;
22
+ margin: 0;
23
+ z-index: 9999999;
24
+ max-width: 45ch;
25
+ width: fit-content;
26
+ min-width: 27ch;
27
+ }
28
+
29
+ :host([data-show="true"]) {
30
+ display: block;
31
+ }
32
+
33
+ svg {
34
+ vertical-align: bottom;
35
+ margin-right: 4px;
36
+ }
37
+
38
+ hr {
39
+ border: 1px solid rgba(136, 58, 234, 0.33);
40
+ padding: 0;
41
+ margin: 0;
42
+ }
43
+
44
+ section {
45
+ padding: 8px;
46
+ }
47
+
48
+ .modal-title {
49
+ display: flex;
50
+ justify-content: space-between;
51
+ align-items: center;
52
+ }
53
+
54
+ .modal-main-title {
55
+ font-weight: bold;
56
+ }
57
+
58
+ .modal-title + div {
59
+ margin-top: 8px;
60
+ }
61
+
62
+ .modal-cta {
63
+ display: block;
64
+ font-weight: bold;
65
+ font-size: 0.9em;
66
+ }
67
+
68
+ .clickable-section {
69
+ background: rgba(113, 24, 226, 1);
70
+ padding: 8px;
71
+ border: 0;
72
+ color: white;
73
+ font-family: system-ui, sans-serif;
74
+ text-align: left;
75
+ line-height: 1.2;
76
+ white-space: nowrap;
77
+ text-decoration: none;
78
+ margin: 0;
79
+ width: 100%;
80
+ }
81
+
82
+ .clickable-section:hover {
83
+ cursor: pointer;
84
+ }
85
+
86
+ code {
87
+ background: rgba(136, 58, 234, 0.33);
88
+ font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
89
+ border-radius: 2px;
90
+ font-size: 14px;
91
+ padding: 2px;
92
+ }
93
+ `;
94
+ const fragment = new DocumentFragment();
95
+ this.sections.forEach((section, index) => {
96
+ const sectionElement = section.clickAction ? document.createElement("button") : document.createElement("section");
97
+ if (section.clickAction) {
98
+ sectionElement.classList.add("clickable-section");
99
+ sectionElement.addEventListener("click", async () => {
100
+ await section.clickAction();
101
+ });
102
+ }
103
+ sectionElement.innerHTML = `
104
+ ${section.title ? `<div class="modal-title"><span class="modal-main-title">
105
+ ${section.icon ? this.getElementForIcon(section.icon) : ""}${section.title}</span>${section.inlineTitle ?? ""}</div>` : ""}
106
+ ${section.content ? `<div>${section.content}</div>` : ""}
107
+ ${section.clickDescription ? `<span class="modal-cta">${section.clickDescription}</span>` : ""}
108
+ `;
109
+ fragment.append(sectionElement);
110
+ if (index < this.sections.length - 1) {
111
+ fragment.append(document.createElement("hr"));
112
+ }
113
+ });
114
+ this.shadowRoot.append(fragment);
115
+ }
116
+ getElementForIcon(icon) {
117
+ let iconElement;
118
+ if (isDefinedIcon(icon)) {
119
+ iconElement = getIconElement(icon);
120
+ } else {
121
+ iconElement = document.createElementNS("http://www.w3.org/2000/svg", "svg");
122
+ iconElement.setAttribute("viewBox", "0 0 16 16");
123
+ iconElement.innerHTML = icon;
124
+ }
125
+ iconElement?.style.setProperty("width", "16px");
126
+ iconElement?.style.setProperty("height", "16px");
127
+ return iconElement?.outerHTML ?? "";
128
+ }
129
+ }
130
+ export {
131
+ DevOverlayTooltip
132
+ };
@@ -0,0 +1,9 @@
1
+ import { type Icon } from './icons.js';
2
+ export declare class DevOverlayWindow extends HTMLElement {
3
+ windowTitle?: string | undefined | null;
4
+ windowIcon?: Icon | undefined | null;
5
+ shadowRoot: ShadowRoot;
6
+ constructor();
7
+ connectedCallback(): Promise<void>;
8
+ getElementForIcon(icon: Icon): string | undefined;
9
+ }
@@ -0,0 +1,70 @@
1
+ import { getIconElement, isDefinedIcon } from "./icons.js";
2
+ class DevOverlayWindow extends HTMLElement {
3
+ windowTitle;
4
+ windowIcon;
5
+ shadowRoot;
6
+ constructor() {
7
+ super();
8
+ this.shadowRoot = this.attachShadow({ mode: "open" });
9
+ this.windowTitle = this.getAttribute("window-title");
10
+ this.windowIcon = this.hasAttribute("window-icon") ? this.getAttribute("window-icon") : void 0;
11
+ }
12
+ async connectedCallback() {
13
+ this.shadowRoot.innerHTML = `
14
+ <style>
15
+ :host {
16
+ display: flex;
17
+ flex-direction: column;
18
+ background: linear-gradient(0deg, #13151A, #13151A), linear-gradient(0deg, #343841, #343841);
19
+ border: 1px solid rgba(52, 56, 65, 1);
20
+ width: 640px;
21
+ height: 480px;
22
+ border-radius: 12px;
23
+ padding: 24px;
24
+ font-family: ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
25
+ color: rgba(204, 206, 216, 1);
26
+ position: fixed;
27
+ z-index: 9999999999;
28
+ top: 55%;
29
+ left: 50%;
30
+ transform: translate(-50%, -50%);
31
+ }
32
+
33
+ h1 {
34
+ margin: 0;
35
+ font-weight: 600;
36
+ color: #fff;
37
+ }
38
+
39
+ h1 svg {
40
+ vertical-align: text-bottom;
41
+ margin-right: 8px;
42
+ }
43
+
44
+ hr {
45
+ border: 1px solid rgba(27, 30, 36, 1);
46
+ margin: 1em 0;
47
+ }
48
+ </style>
49
+
50
+ <h1>${this.windowIcon ? this.getElementForIcon(this.windowIcon) : ""}${this.windowTitle ?? ""}</h1>
51
+ <hr />
52
+ <slot />
53
+ `;
54
+ }
55
+ getElementForIcon(icon) {
56
+ if (isDefinedIcon(icon)) {
57
+ const iconElement = getIconElement(icon);
58
+ iconElement?.style.setProperty("height", "1em");
59
+ return iconElement?.outerHTML;
60
+ } else {
61
+ const iconElement = document.createElementNS("http://www.w3.org/2000/svg", "svg");
62
+ iconElement.setAttribute("viewBox", "0 0 16 16");
63
+ iconElement.innerHTML = icon;
64
+ return iconElement.outerHTML;
65
+ }
66
+ }
67
+ }
68
+ export {
69
+ DevOverlayWindow
70
+ };
@@ -18,7 +18,7 @@ async function renderToString(result, componentFactory, props, children, isPage
18
18
  write(chunk) {
19
19
  if (isPage && !renderedFirstPageChunk) {
20
20
  renderedFirstPageChunk = true;
21
- if (!/<!doctype html/i.test(String(chunk))) {
21
+ if (!result.partial && !/<!doctype html/i.test(String(chunk))) {
22
22
  const doctype = result.compressHTML ? "<!DOCTYPE html>" : "<!DOCTYPE html>\n";
23
23
  str += doctype;
24
24
  }
@@ -51,7 +51,7 @@ async function renderToReadableStream(result, componentFactory, props, children,
51
51
  write(chunk) {
52
52
  if (isPage && !renderedFirstPageChunk) {
53
53
  renderedFirstPageChunk = true;
54
- if (!/<!doctype html/i.test(String(chunk))) {
54
+ if (!result.partial && !/<!doctype html/i.test(String(chunk))) {
55
55
  const doctype = result.compressHTML ? "<!DOCTYPE html>" : "<!DOCTYPE html>\n";
56
56
  controller.enqueue(encoder.encode(doctype));
57
57
  }
@@ -28,13 +28,13 @@ function stringifyChunk(result, chunk) {
28
28
  }
29
29
  }
30
30
  case "head": {
31
- if (result._metadata.hasRenderedHead) {
31
+ if (result._metadata.hasRenderedHead || result.partial) {
32
32
  return "";
33
33
  }
34
34
  return renderAllHeadContent(result);
35
35
  }
36
36
  case "maybe-head": {
37
- if (result._metadata.hasRenderedHead || result._metadata.headInTree) {
37
+ if (result._metadata.hasRenderedHead || result._metadata.headInTree || result.partial) {
38
38
  return "";
39
39
  }
40
40
  return renderAllHeadContent(result);