slicejs-web-framework 4.0.2 → 4.1.1

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 (73) hide show
  1. package/LICENSE +21 -21
  2. package/README.md +97 -97
  3. package/Slice/Components/Structural/ContextManager/ContextManager.js +422 -422
  4. package/Slice/Components/Structural/ContextManager/ContextManagerDebugger.js +470 -470
  5. package/Slice/Components/Structural/Controller/Controller.js +1406 -1406
  6. package/Slice/Components/Structural/Controller/allowedValuesValidation.js +52 -52
  7. package/Slice/Components/Structural/Debugger/Debugger.html +72 -72
  8. package/Slice/Components/Structural/Debugger/Debugger.js +1505 -1505
  9. package/Slice/Components/Structural/EventManager/EventManager.js +651 -651
  10. package/Slice/Components/Structural/EventManager/EventManagerDebugger.js +985 -985
  11. package/Slice/Components/Structural/LeakInspector/LeakInspector.js +296 -296
  12. package/Slice/Components/Structural/Logger/Log.js +10 -10
  13. package/Slice/Components/Structural/Logger/LogViewer/LogViewer.js +662 -662
  14. package/Slice/Components/Structural/Logger/Logger.js +225 -225
  15. package/Slice/Components/Structural/Router/Router.js +820 -810
  16. package/Slice/Components/Structural/Router/applyRouteMetadata.js +39 -0
  17. package/Slice/Components/Structural/StylesManager/StylesManager.js +82 -82
  18. package/Slice/Components/Structural/StylesManager/ThemeManager/ThemeManager.js +175 -175
  19. package/Slice/Slice.js +711 -710
  20. package/api/framework/devDepsOptimizer.js +335 -335
  21. package/api/framework/express.js +3 -3
  22. package/api/framework/precompressedStatic.js +102 -93
  23. package/api/framework/publicEnvResolver.js +123 -123
  24. package/api/framework/securityMiddleware.js +197 -197
  25. package/api/framework/seo.js +387 -0
  26. package/api/framework/server.js +777 -410
  27. package/api/index.js +14 -4
  28. package/package.json +6 -2
  29. package/sliceConfig.schema.json +122 -122
  30. package/src/App/index.html +69 -69
  31. package/src/App/index.js +20 -20
  32. package/src/App/style.css +11 -11
  33. package/src/Components/AppComponents/AboutSection/AboutSection.css +9 -9
  34. package/src/Components/AppComponents/AboutSection/AboutSection.html +8 -8
  35. package/src/Components/AppComponents/AboutSection/AboutSection.js +12 -12
  36. package/src/Components/AppComponents/AppShell/AppShell.css +10 -10
  37. package/src/Components/AppComponents/AppShell/AppShell.html +4 -4
  38. package/src/Components/AppComponents/AppShell/AppShell.js +36 -36
  39. package/src/Components/AppComponents/HomeSection/HomeSection.css +20 -20
  40. package/src/Components/AppComponents/HomeSection/HomeSection.html +10 -10
  41. package/src/Components/AppComponents/HomeSection/HomeSection.js +19 -19
  42. package/src/Components/components.js +8 -8
  43. package/src/public/Styles/sliceStyles.css +34 -34
  44. package/src/public/Themes/Dark.css +42 -42
  45. package/src/public/Themes/Light.css +31 -31
  46. package/src/public/Themes/Slice.css +47 -47
  47. package/src/public/manifest.json +15 -15
  48. package/src/public/robots.txt +4 -4
  49. package/src/public/sitemap.xml +8 -8
  50. package/src/routes.js +9 -9
  51. package/src/sliceConfig.json +72 -72
  52. package/types/index.d.ts +219 -219
  53. package/.opencode/opencode.json +0 -15
  54. package/Slice/tests/build-bundled-component-without-category.test.js +0 -103
  55. package/Slice/tests/build-js-only-visual-components.test.js +0 -144
  56. package/Slice/tests/build-singleton.test.js +0 -244
  57. package/Slice/tests/bundle-v2-runtime-contract.test.js +0 -747
  58. package/Slice/tests/context-patch-use.test.js +0 -95
  59. package/Slice/tests/destroy-cascade.test.js +0 -215
  60. package/Slice/tests/event-emitters.test.js +0 -79
  61. package/Slice/tests/event-registry.test.js +0 -141
  62. package/Slice/tests/fixtures/real-runtime-loader.mjs +0 -21
  63. package/Slice/tests/leak-orphans.test.js +0 -131
  64. package/Slice/tests/props-allowed-values-validation.test.js +0 -119
  65. package/Slice/tests/public-env-runtime-accessors.test.js +0 -44
  66. package/Slice/tests/public-env-typed-accessors.test.js +0 -66
  67. package/Slice/tests/router-loading-finally.test.js +0 -68
  68. package/api/tests/dev-deps-optimizer.test.js +0 -137
  69. package/api/tests/dev-server-external.test.js +0 -56
  70. package/api/tests/precompressed-static.test.js +0 -119
  71. package/api/tests/public-env-resolver.test.js +0 -193
  72. package/tests/router-build-failure.test.js +0 -125
  73. package/tests/router-emit-ordering.test.js +0 -63
package/api/index.js CHANGED
@@ -1,7 +1,17 @@
1
- // api/index.js - Punto de entrada del servidor
1
+ // api/index.js — server entrypoint.
2
+ //
3
+ // Everything you add goes between createSliceServer() and start(): ordinary
4
+ // Express middleware, an /api router, auth, request logging. start() mounts the
5
+ // terminal fallback (the only middleware that must be last), prepares SEO when
6
+ // it is configured, and then listens.
7
+ //
8
+ // const { app, start } = createSliceServer();
9
+ // app.use('/api/hooks', hooks);
10
+ // await start();
2
11
  import { createSliceServer } from 'slicejs-web-framework/api/framework/server.js';
3
12
 
4
- const server = createSliceServer();
5
- server.start();
13
+ const { app, start } = createSliceServer();
6
14
 
7
- export default server.app;
15
+ await start();
16
+
17
+ export default app;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "slicejs-web-framework",
3
- "version": "4.0.2",
3
+ "version": "4.1.1",
4
4
  "description": "",
5
5
  "engines": {
6
6
  "node": ">=20"
@@ -17,7 +17,10 @@
17
17
  "slice:start": "node ./node_modules/slicejs-cli/client.js start",
18
18
  "format": "prettier --write \"**/*.js\"",
19
19
  "run": "node ./node_modules/slicejs-cli/client.js dev",
20
- "slice:modify": "node ./node_modules/slicejs-cli/client.js modify"
20
+ "slice:modify": "node ./node_modules/slicejs-cli/client.js modify",
21
+ "test:server": "node --test api/framework/*.test.js api/tests/*.test.js",
22
+ "check:pack": "node scripts/check-pack.mjs",
23
+ "verify:app": "node scripts/verify-app.mjs"
21
24
  },
22
25
  "keywords": [],
23
26
  "author": "",
@@ -27,6 +30,7 @@
27
30
  ".": "./Slice/Slice.js",
28
31
  "./api/framework/express.js": "./api/framework/express.js",
29
32
  "./api/framework/server.js": "./api/framework/server.js",
33
+ "./api/framework/seo.js": "./api/framework/seo.js",
30
34
  "./api/framework/devDepsOptimizer.js": "./api/framework/devDepsOptimizer.js"
31
35
  },
32
36
  "types": "./types/index.d.ts",
@@ -1,122 +1,122 @@
1
- {
2
- "$schema": "https://json-schema.org/draft/2020-12/schema",
3
- "$id": "https://slicejs.local/sliceConfig.schema.json",
4
- "title": "Slice.js Config",
5
- "type": "object",
6
- "additionalProperties": true,
7
- "properties": {
8
- "debugger": {
9
- "type": "object",
10
- "additionalProperties": true,
11
- "properties": {
12
- "enabled": { "type": "boolean" },
13
- "click": { "type": "string", "enum": ["right", "left"] },
14
- "leakInspector": {
15
- "type": "object",
16
- "additionalProperties": true,
17
- "description": "Dev-only memory-leak panel. Disabled in production regardless of this flag.",
18
- "properties": {
19
- "enabled": { "type": "boolean" },
20
- "shortcut": { "type": "string" }
21
- }
22
- }
23
- }
24
- },
25
- "stylesManager": {
26
- "type": "object",
27
- "additionalProperties": true,
28
- "properties": {
29
- "requestedStyles": { "type": "array", "items": { "type": "string" } }
30
- }
31
- },
32
- "themeManager": {
33
- "type": "object",
34
- "additionalProperties": true,
35
- "properties": {
36
- "enabled": { "type": "boolean" },
37
- "defaultTheme": { "type": "string" },
38
- "saveThemeLocally": { "type": "boolean" },
39
- "useBrowserTheme": { "type": "boolean" }
40
- }
41
- },
42
- "logger": {
43
- "type": "object",
44
- "additionalProperties": true,
45
- "properties": {
46
- "enabled": { "type": "boolean" },
47
- "showLogs": { "type": "object", "additionalProperties": true },
48
- "ui": {
49
- "type": "object",
50
- "additionalProperties": true,
51
- "properties": {
52
- "enabled": { "type": "boolean" },
53
- "shortcut": { "type": "string" }
54
- }
55
- }
56
- }
57
- },
58
- "events": {
59
- "type": "object",
60
- "additionalProperties": true,
61
- "properties": {
62
- "enabled": { "type": "boolean" },
63
- "ui": {
64
- "type": "object",
65
- "additionalProperties": true,
66
- "properties": {
67
- "enabled": { "type": "boolean" },
68
- "shortcut": { "type": "string" }
69
- }
70
- }
71
- }
72
- },
73
- "context": {
74
- "type": "object",
75
- "additionalProperties": true,
76
- "properties": {
77
- "enabled": { "type": "boolean" },
78
- "ui": {
79
- "type": "object",
80
- "additionalProperties": true,
81
- "properties": {
82
- "enabled": { "type": "boolean" },
83
- "shortcut": { "type": "string" }
84
- }
85
- }
86
- }
87
- },
88
- "paths": {
89
- "type": "object",
90
- "additionalProperties": true,
91
- "properties": {
92
- "components": { "type": "object", "additionalProperties": true },
93
- "themes": { "type": "string" },
94
- "styles": { "type": "string" },
95
- "routesFile": { "type": "string" }
96
- },
97
- "required": ["components", "themes", "styles", "routesFile"]
98
- },
99
- "router": {
100
- "type": "object",
101
- "additionalProperties": true,
102
- "properties": {
103
- "defaultRoute": { "type": "string" }
104
- }
105
- },
106
- "loading": {
107
- "type": "object",
108
- "additionalProperties": true,
109
- "properties": {
110
- "enabled": { "type": "boolean" }
111
- }
112
- },
113
- "server": {
114
- "type": "object",
115
- "additionalProperties": true,
116
- "properties": {
117
- "port": { "type": "number" },
118
- "host": { "type": "string" }
119
- }
120
- }
121
- }
122
- }
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://slicejs.local/sliceConfig.schema.json",
4
+ "title": "Slice.js Config",
5
+ "type": "object",
6
+ "additionalProperties": true,
7
+ "properties": {
8
+ "debugger": {
9
+ "type": "object",
10
+ "additionalProperties": true,
11
+ "properties": {
12
+ "enabled": { "type": "boolean" },
13
+ "click": { "type": "string", "enum": ["right", "left"] },
14
+ "leakInspector": {
15
+ "type": "object",
16
+ "additionalProperties": true,
17
+ "description": "Dev-only memory-leak panel. Disabled in production regardless of this flag.",
18
+ "properties": {
19
+ "enabled": { "type": "boolean" },
20
+ "shortcut": { "type": "string" }
21
+ }
22
+ }
23
+ }
24
+ },
25
+ "stylesManager": {
26
+ "type": "object",
27
+ "additionalProperties": true,
28
+ "properties": {
29
+ "requestedStyles": { "type": "array", "items": { "type": "string" } }
30
+ }
31
+ },
32
+ "themeManager": {
33
+ "type": "object",
34
+ "additionalProperties": true,
35
+ "properties": {
36
+ "enabled": { "type": "boolean" },
37
+ "defaultTheme": { "type": "string" },
38
+ "saveThemeLocally": { "type": "boolean" },
39
+ "useBrowserTheme": { "type": "boolean" }
40
+ }
41
+ },
42
+ "logger": {
43
+ "type": "object",
44
+ "additionalProperties": true,
45
+ "properties": {
46
+ "enabled": { "type": "boolean" },
47
+ "showLogs": { "type": "object", "additionalProperties": true },
48
+ "ui": {
49
+ "type": "object",
50
+ "additionalProperties": true,
51
+ "properties": {
52
+ "enabled": { "type": "boolean" },
53
+ "shortcut": { "type": "string" }
54
+ }
55
+ }
56
+ }
57
+ },
58
+ "events": {
59
+ "type": "object",
60
+ "additionalProperties": true,
61
+ "properties": {
62
+ "enabled": { "type": "boolean" },
63
+ "ui": {
64
+ "type": "object",
65
+ "additionalProperties": true,
66
+ "properties": {
67
+ "enabled": { "type": "boolean" },
68
+ "shortcut": { "type": "string" }
69
+ }
70
+ }
71
+ }
72
+ },
73
+ "context": {
74
+ "type": "object",
75
+ "additionalProperties": true,
76
+ "properties": {
77
+ "enabled": { "type": "boolean" },
78
+ "ui": {
79
+ "type": "object",
80
+ "additionalProperties": true,
81
+ "properties": {
82
+ "enabled": { "type": "boolean" },
83
+ "shortcut": { "type": "string" }
84
+ }
85
+ }
86
+ }
87
+ },
88
+ "paths": {
89
+ "type": "object",
90
+ "additionalProperties": true,
91
+ "properties": {
92
+ "components": { "type": "object", "additionalProperties": true },
93
+ "themes": { "type": "string" },
94
+ "styles": { "type": "string" },
95
+ "routesFile": { "type": "string" }
96
+ },
97
+ "required": ["components", "themes", "styles", "routesFile"]
98
+ },
99
+ "router": {
100
+ "type": "object",
101
+ "additionalProperties": true,
102
+ "properties": {
103
+ "defaultRoute": { "type": "string" }
104
+ }
105
+ },
106
+ "loading": {
107
+ "type": "object",
108
+ "additionalProperties": true,
109
+ "properties": {
110
+ "enabled": { "type": "boolean" }
111
+ }
112
+ },
113
+ "server": {
114
+ "type": "object",
115
+ "additionalProperties": true,
116
+ "properties": {
117
+ "port": { "type": "number" },
118
+ "host": { "type": "string" }
119
+ }
120
+ }
121
+ }
122
+ }
@@ -1,69 +1,69 @@
1
- <!DOCTYPE html>
2
- <html lang="en">
3
- <head>
4
- <meta charset="UTF-8" />
5
- <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
- <title>Slice.js Web Framework</title>
7
- <meta name="description" content="Slice.js — a lightweight web framework built on native Web Components. Build web apps one slice at a time. No build step required." />
8
- <meta name="robots" content="index, follow" />
9
- <meta name="author" content="vkneider.dev" />
10
- <link rel="canonical" href="https://slicejs.com" />
11
- <link rel="icon" type="image/x-icon" href="/images/favicon.ico" />
12
- <link rel="apple-touch-icon" href="/images/og-image.png" />
13
- <link rel="manifest" href="/manifest.json" />
14
- <meta name="theme-color" content="#F8F4FF" />
15
- <meta name="color-scheme" content="light dark" />
16
- <meta property="og:type" content="website" />
17
- <meta property="og:title" content="Slice.js Web Framework" />
18
- <meta property="og:description" content="Slice.js — a lightweight web framework built on native Web Components. Build web apps one slice at a time. No build step required." />
19
- <meta property="og:url" content="https://slicejs.com" />
20
- <meta property="og:image" content="https://slicejs.com/images/og-image.png" />
21
- <meta name="twitter:card" content="summary_large_image" />
22
- <meta name="twitter:title" content="Slice.js Web Framework" />
23
- <meta name="twitter:description" content="Slice.js — a lightweight web framework built on native Web Components." />
24
- <meta name="twitter:image" content="https://slicejs.com/images/og-image.png" />
25
- <link rel="stylesheet" type="text/css" href="/App/style.css" />
26
- <script type="application/ld+json">
27
- {
28
- "@context": "https://schema.org",
29
- "@type": "WebSite",
30
- "name": "Slice.js Web Framework",
31
- "url": "https://slicejs.com",
32
- "description": "Slice.js — a lightweight web framework built on native Web Components. Build web apps one slice at a time.",
33
- "author": {
34
- "@type": "Organization",
35
- "name": "VKneider",
36
- "url": "https://github.com/VKneider"
37
- },
38
- "potentialAction": {
39
- "@type": "SearchAction",
40
- "target": {
41
- "@type": "EntryPoint",
42
- "urlTemplate": "https://slicejs.com/?q={search_term_string}"
43
- },
44
- "query-input": "required name=search_term_string"
45
- }
46
- }
47
- </script>
48
- <script type="application/ld+json">
49
- {
50
- "@context": "https://schema.org",
51
- "@type": "BreadcrumbList",
52
- "itemListElement": [
53
- {
54
- "@type": "ListItem",
55
- "position": 1,
56
- "name": "Home",
57
- "item": "https://slicejs.com/"
58
- }
59
- ]
60
- }
61
- </script>
62
- </head>
63
-
64
- <body>
65
- <div id="app">
66
- <script src="/App/index.js" type="module"></script>
67
- </div>
68
- </body>
69
- </html>
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8" />
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
+ <title>Slice.js Web Framework</title>
7
+ <meta name="description" content="Slice.js — a lightweight web framework built on native Web Components. Build web apps one slice at a time. No build step required." />
8
+ <meta name="robots" content="index, follow" />
9
+ <meta name="author" content="vkneider.dev" />
10
+ <link rel="canonical" href="https://slicejs.com" />
11
+ <link rel="icon" type="image/x-icon" href="/images/favicon.ico" />
12
+ <link rel="apple-touch-icon" href="/images/og-image.png" />
13
+ <link rel="manifest" href="/manifest.json" />
14
+ <meta name="theme-color" content="#F8F4FF" />
15
+ <meta name="color-scheme" content="light dark" />
16
+ <meta property="og:type" content="website" />
17
+ <meta property="og:title" content="Slice.js Web Framework" />
18
+ <meta property="og:description" content="Slice.js — a lightweight web framework built on native Web Components. Build web apps one slice at a time. No build step required." />
19
+ <meta property="og:url" content="https://slicejs.com" />
20
+ <meta property="og:image" content="https://slicejs.com/images/og-image.png" />
21
+ <meta name="twitter:card" content="summary_large_image" />
22
+ <meta name="twitter:title" content="Slice.js Web Framework" />
23
+ <meta name="twitter:description" content="Slice.js — a lightweight web framework built on native Web Components." />
24
+ <meta name="twitter:image" content="https://slicejs.com/images/og-image.png" />
25
+ <link rel="stylesheet" type="text/css" href="/App/style.css" />
26
+ <script type="application/ld+json">
27
+ {
28
+ "@context": "https://schema.org",
29
+ "@type": "WebSite",
30
+ "name": "Slice.js Web Framework",
31
+ "url": "https://slicejs.com",
32
+ "description": "Slice.js — a lightweight web framework built on native Web Components. Build web apps one slice at a time.",
33
+ "author": {
34
+ "@type": "Organization",
35
+ "name": "VKneider",
36
+ "url": "https://github.com/VKneider"
37
+ },
38
+ "potentialAction": {
39
+ "@type": "SearchAction",
40
+ "target": {
41
+ "@type": "EntryPoint",
42
+ "urlTemplate": "https://slicejs.com/?q={search_term_string}"
43
+ },
44
+ "query-input": "required name=search_term_string"
45
+ }
46
+ }
47
+ </script>
48
+ <script type="application/ld+json">
49
+ {
50
+ "@context": "https://schema.org",
51
+ "@type": "BreadcrumbList",
52
+ "itemListElement": [
53
+ {
54
+ "@type": "ListItem",
55
+ "position": 1,
56
+ "name": "Home",
57
+ "item": "https://slicejs.com/"
58
+ }
59
+ ]
60
+ }
61
+ </script>
62
+ </head>
63
+
64
+ <body>
65
+ <div id="app">
66
+ <script src="/App/index.js" type="module"></script>
67
+ </div>
68
+ </body>
69
+ </html>
package/src/App/index.js CHANGED
@@ -1,20 +1,20 @@
1
- import Slice from '/Slice/Slice.js';
2
-
3
- // `slice` is now a global. Routes are declared in /routes.js and the router
4
- // auto-starts shortly after load, so this file can stay almost empty.
5
- //
6
- // If you need navigation guards (auth, page titles, analytics), define them
7
- // here and then start the router EXPLICITLY (this cancels the auto-start):
8
- //
9
- // slice.router.beforeEach(async (to, from, next) => {
10
- // if (to.metadata?.private && !slice.context.getState('auth')?.isLoggedIn) {
11
- // return next({ path: '/login', replace: true });
12
- // }
13
- // next();
14
- // });
15
- //
16
- // slice.router.afterEach((to) => {
17
- // document.title = to.metadata?.title ?? 'Slice App';
18
- // });
19
- //
20
- // await slice.router.start();
1
+ import Slice from '/Slice/Slice.js';
2
+
3
+ // `slice` is now a global. Routes are declared in /routes.js and the router
4
+ // auto-starts shortly after load, so this file can stay almost empty.
5
+ //
6
+ // If you need navigation guards (auth, page titles, analytics), define them
7
+ // here and then start the router EXPLICITLY (this cancels the auto-start):
8
+ //
9
+ // slice.router.beforeEach(async (to, from, next) => {
10
+ // if (to.metadata?.private && !slice.context.getState('auth')?.isLoggedIn) {
11
+ // return next({ path: '/login', replace: true });
12
+ // }
13
+ // next();
14
+ // });
15
+ //
16
+ // slice.router.afterEach((to) => {
17
+ // document.title = to.metadata?.title ?? 'Slice App';
18
+ // });
19
+ //
20
+ // await slice.router.start();
package/src/App/style.css CHANGED
@@ -1,11 +1,11 @@
1
- /* App-level base styles. Component styles live in each component's own .css. */
2
- * {
3
- box-sizing: border-box;
4
- font-family: var(--font-family, system-ui, -apple-system, Segoe UI, Roboto, sans-serif);
5
- }
6
-
7
- body {
8
- margin: 0;
9
- background: var(--primary-background-color);
10
- color: var(--font-primary-color);
11
- }
1
+ /* App-level base styles. Component styles live in each component's own .css. */
2
+ * {
3
+ box-sizing: border-box;
4
+ font-family: var(--font-family, system-ui, -apple-system, Segoe UI, Roboto, sans-serif);
5
+ }
6
+
7
+ body {
8
+ margin: 0;
9
+ background: var(--primary-background-color);
10
+ color: var(--font-primary-color);
11
+ }
@@ -1,9 +1,9 @@
1
- .about {
2
- padding: 16px 0;
3
- }
4
-
5
- .about p {
6
- color: var(--font-secondary-color);
7
- max-width: 65ch;
8
- line-height: 1.6;
9
- }
1
+ .about {
2
+ padding: 16px 0;
3
+ }
4
+
5
+ .about p {
6
+ color: var(--font-secondary-color);
7
+ max-width: 65ch;
8
+ line-height: 1.6;
9
+ }
@@ -1,8 +1,8 @@
1
- <section class="about">
2
- <h1>About</h1>
3
- <p>
4
- This starter uses the App Shell + MultiRoute pattern: a persistent shell (the navbar)
5
- wraps a content area that swaps sections by URL. See the docs — Project Anatomy,
6
- Your First Page, and The Development Loop — to learn the recommended workflow.
7
- </p>
8
- </section>
1
+ <section class="about">
2
+ <h1>About</h1>
3
+ <p>
4
+ This starter uses the App Shell + MultiRoute pattern: a persistent shell (the navbar)
5
+ wraps a content area that swaps sections by URL. See the docs — Project Anatomy,
6
+ Your First Page, and The Development Loop — to learn the recommended workflow.
7
+ </p>
8
+ </section>
@@ -1,12 +1,12 @@
1
- export default class AboutSection extends HTMLElement {
2
- constructor(props) {
3
- super();
4
- slice.attachTemplate(this);
5
- slice.controller.setComponentProps(this, props);
6
- }
7
-
8
- // A static section needs no init(). Add async init() if it fetches data,
9
- // and update() if it should refresh when revisited (MultiRoute caches it).
10
- }
11
-
12
- customElements.define('slice-about-section', AboutSection);
1
+ export default class AboutSection extends HTMLElement {
2
+ constructor(props) {
3
+ super();
4
+ slice.attachTemplate(this);
5
+ slice.controller.setComponentProps(this, props);
6
+ }
7
+
8
+ // A static section needs no init(). Add async init() if it fetches data,
9
+ // and update() if it should refresh when revisited (MultiRoute caches it).
10
+ }
11
+
12
+ customElements.define('slice-about-section', AboutSection);
@@ -1,10 +1,10 @@
1
- .app-shell {
2
- min-height: 100vh;
3
- }
4
-
5
- .app-shell__content {
6
- max-width: 960px;
7
- margin: 0 auto;
8
- /* top padding clears the fixed navbar */
9
- padding: 96px 24px 48px;
10
- }
1
+ .app-shell {
2
+ min-height: 100vh;
3
+ }
4
+
5
+ .app-shell__content {
6
+ max-width: 960px;
7
+ margin: 0 auto;
8
+ /* top padding clears the fixed navbar */
9
+ padding: 96px 24px 48px;
10
+ }
@@ -1,4 +1,4 @@
1
- <div class="app-shell">
2
- <header class="app-shell__header"></header>
3
- <main class="app-shell__content"></main>
4
- </div>
1
+ <div class="app-shell">
2
+ <header class="app-shell__header"></header>
3
+ <main class="app-shell__content"></main>
4
+ </div>