tkeron 6.0.0 → 6.0.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.
- package/changelog.md +18 -0
- package/examples/init_sample/websrc/about.html +19 -0
- package/examples/init_sample/websrc/components/content/about-intro.com.md +7 -0
- package/examples/init_sample/websrc/components/layout/hero-section.com.html +88 -0
- package/examples/init_sample/websrc/components/layout/site-footer.com.html +20 -0
- package/examples/init_sample/websrc/components/layout/site-header.com.html +44 -0
- package/examples/init_sample/websrc/components/ui/counter-button.com.html +48 -0
- package/examples/init_sample/websrc/components/ui/crypto-prices-card.com.html +52 -0
- package/examples/init_sample/websrc/{info-card.com.html → components/ui/info-card.com.html} +10 -6
- package/examples/init_sample/websrc/components/ui/markdown-card.com.html +21 -0
- package/examples/init_sample/websrc/{pre-render-card.com.html → components/ui/pre-render-card.com.html} +6 -3
- package/examples/init_sample/websrc/components/ui/quote-card.com.html +32 -0
- package/examples/init_sample/websrc/components/ui/styles-injector.com.ts +5 -0
- package/examples/init_sample/websrc/{ts-components-card.com.html → components/ui/ts-components-card.com.html} +2 -2
- package/examples/init_sample/websrc/components/ui/user-badge.com.ts +30 -0
- package/examples/init_sample/websrc/docs.html +33 -0
- package/examples/init_sample/websrc/index.html +10 -242
- package/examples/init_sample/websrc/index.post.ts +70 -0
- package/examples/init_sample/websrc/index.pre.ts +10 -66
- package/examples/init_sample/websrc/index.ts +9 -7
- package/examples/init_sample/websrc/styles/global-styles.com.ts +5 -0
- package/examples/init_sample/websrc/styles/main.css +112 -0
- package/examples/init_sample/websrc/{api-service.ts → utils/api-service.ts} +32 -37
- package/examples/with_global_styles/websrc/bad.html +23 -0
- package/examples/with_global_styles/websrc/global-styles.com.ts +5 -0
- package/examples/with_global_styles/websrc/good.html +22 -0
- package/examples/with_global_styles/websrc/index.html +25 -0
- package/examples/with_global_styles/websrc/styles.css +24 -0
- package/examples/with_style_dedup/websrc/tag-chip.com.html +15 -0
- package/examples/with_style_dedup/websrc/tag-chip.com.ts +2 -18
- package/package.json +1 -1
- package/skills/tkeron/SKILL.md +4 -3
- package/skills/tkeron-organization/SKILL.md +6 -5
- package/skills/tkeron-patterns/SKILL.md +109 -17
- package/skills/tkeron-troubleshooting/SKILL.md +7 -3
- package/examples/init_sample/websrc/counter-card.com.html +0 -12
- package/examples/init_sample/websrc/favicon.ico +0 -0
- package/examples/init_sample/websrc/hero-section.com.html +0 -53
- package/examples/init_sample/websrc/user-badge.com.ts +0 -17
- /package/examples/init_sample/websrc/{profile.png → assets/profile.png} +0 -0
- /package/examples/init_sample/websrc/{html-components-card.com.html → components/ui/html-components-card.com.html} +0 -0
package/changelog.md
CHANGED
|
@@ -1,3 +1,21 @@
|
|
|
1
|
+
# v6.0.1
|
|
2
|
+
|
|
3
|
+
## Docs: CSS via components pattern
|
|
4
|
+
|
|
5
|
+
- Skills updated to enforce "CSS via components, never `<link rel="stylesheet">`" as a non-negotiable rule (`tkeron`, `tkeron-patterns`, `tkeron-organization`, `tkeron-troubleshooting`)
|
|
6
|
+
- `tkeron-patterns` adds a full "CSS via components" section covering per-component `<style>` in `.com.html` (auto-dedup, tree-shaking) and global CSS inlined through a `.com.ts` loader
|
|
7
|
+
- New anti-pattern entry: `<link rel="stylesheet">` (extra request, no dedup, blocks first paint)
|
|
8
|
+
- `tkeron-organization` clarifies that `styles/` is optional and `.css` files are free to live anywhere — always inlined via a component, never linked
|
|
9
|
+
|
|
10
|
+
## Examples: rewrite `init_sample` + new style examples
|
|
11
|
+
|
|
12
|
+
- `init_sample` reorganized into the canonical structure: multi-page (`index.html`, `about.html`, `docs.html`), shared components under `components/layout/`, `components/ui/`, `components/content/`, build utils under `utils/`, global CSS in `styles/main.css` inlined via `styles-injector.com.ts`
|
|
13
|
+
- New example `with_global_styles/`: demonstrates the global-styles loader component pattern vs the `<link>` anti-pattern
|
|
14
|
+
- New example `with_style_dedup/`: `tag-chip` component proving per-component `<style>` dedup in the build output
|
|
15
|
+
- `tests/init.test.ts` updated to assert the new `init_sample` layout
|
|
16
|
+
|
|
17
|
+
---
|
|
18
|
+
|
|
1
19
|
# v6.0.0
|
|
2
20
|
|
|
3
21
|
## BREAKING: remove MCP server
|
|
@@ -0,0 +1,19 @@
|
|
|
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>About — tkeron</title>
|
|
7
|
+
<styles-injector></styles-injector>
|
|
8
|
+
</head>
|
|
9
|
+
<body>
|
|
10
|
+
<site-header></site-header>
|
|
11
|
+
<main class="container">
|
|
12
|
+
<article class="page">
|
|
13
|
+
<h1>About</h1>
|
|
14
|
+
<about-intro></about-intro>
|
|
15
|
+
</article>
|
|
16
|
+
</main>
|
|
17
|
+
<site-footer></site-footer>
|
|
18
|
+
</body>
|
|
19
|
+
</html>
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
**tkeron** is a build-time TypeScript toolkit for vanilla web development.
|
|
2
|
+
|
|
3
|
+
It compiles `.ts` to `.js`, inlines components, and runs pre/post scripts —
|
|
4
|
+
all at build time. No frameworks, no runtime, no bundler.
|
|
5
|
+
|
|
6
|
+
This Markdown lives in `components/content/about-intro.com.md` and is reused
|
|
7
|
+
on the home page (inside the `<markdown-card>`) and on the **About** page.
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
<style>
|
|
2
|
+
.hero {
|
|
3
|
+
text-align: center;
|
|
4
|
+
color: white;
|
|
5
|
+
display: flex;
|
|
6
|
+
flex-direction: column;
|
|
7
|
+
align-items: center;
|
|
8
|
+
justify-content: center;
|
|
9
|
+
background: rgba(255, 255, 255, 0.1);
|
|
10
|
+
backdrop-filter: blur(10px);
|
|
11
|
+
padding: 1.5rem;
|
|
12
|
+
border-radius: 12px;
|
|
13
|
+
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
|
|
14
|
+
grid-row: span 2;
|
|
15
|
+
}
|
|
16
|
+
.hero .features {
|
|
17
|
+
margin-top: 1rem;
|
|
18
|
+
text-align: left;
|
|
19
|
+
width: 100%;
|
|
20
|
+
}
|
|
21
|
+
.hero .features li {
|
|
22
|
+
margin-bottom: 0.3rem;
|
|
23
|
+
padding-left: 0.5rem;
|
|
24
|
+
opacity: 0.9;
|
|
25
|
+
font-size: 0.85rem;
|
|
26
|
+
}
|
|
27
|
+
.hero .logo {
|
|
28
|
+
width: 200px;
|
|
29
|
+
height: 200px;
|
|
30
|
+
margin-bottom: 1rem;
|
|
31
|
+
filter: drop-shadow(0 4px 6px rgba(0, 0, 0, 0.2));
|
|
32
|
+
animation: hero-float 3s ease-in-out infinite;
|
|
33
|
+
}
|
|
34
|
+
.hero .subtitle {
|
|
35
|
+
font-size: 0.9rem;
|
|
36
|
+
opacity: 0.95;
|
|
37
|
+
}
|
|
38
|
+
.hero .links {
|
|
39
|
+
margin-top: 1.5rem;
|
|
40
|
+
display: flex;
|
|
41
|
+
gap: 0.75rem;
|
|
42
|
+
width: 100%;
|
|
43
|
+
}
|
|
44
|
+
.hero .links a {
|
|
45
|
+
flex: 1;
|
|
46
|
+
padding: 0.65rem;
|
|
47
|
+
color: white;
|
|
48
|
+
text-decoration: none;
|
|
49
|
+
border-radius: 6px;
|
|
50
|
+
text-align: center;
|
|
51
|
+
font-weight: 600;
|
|
52
|
+
font-size: 0.85rem;
|
|
53
|
+
}
|
|
54
|
+
.hero .links .npm {
|
|
55
|
+
background: rgba(203, 56, 55, 0.9);
|
|
56
|
+
}
|
|
57
|
+
.hero .links .github {
|
|
58
|
+
background: rgba(36, 41, 46, 0.9);
|
|
59
|
+
}
|
|
60
|
+
@keyframes hero-float {
|
|
61
|
+
0%,
|
|
62
|
+
100% {
|
|
63
|
+
transform: translateY(0);
|
|
64
|
+
}
|
|
65
|
+
50% {
|
|
66
|
+
transform: translateY(-10px);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
</style>
|
|
70
|
+
<div class="hero">
|
|
71
|
+
<div>
|
|
72
|
+
<img src="./assets/profile.png" alt="tkeron logo" class="logo" />
|
|
73
|
+
<h1>tkeron</h1>
|
|
74
|
+
<p class="subtitle">Build-time TypeScript for modern web development</p>
|
|
75
|
+
</div>
|
|
76
|
+
<div class="features">
|
|
77
|
+
<ul style="list-style: none">
|
|
78
|
+
<li>⚡ Fast builds with Bun</li>
|
|
79
|
+
<li>🎯 Build-time HTML generation</li>
|
|
80
|
+
<li>🧩 HTML & TypeScript components</li>
|
|
81
|
+
<li>🔧 Pure TypeScript & HTML</li>
|
|
82
|
+
</ul>
|
|
83
|
+
</div>
|
|
84
|
+
<div class="links">
|
|
85
|
+
<a href="https://www.npmjs.com/package/tkeron" target="_blank" class="npm">📦 npm</a>
|
|
86
|
+
<a href="https://github.com/tkeron/tkeron" target="_blank" class="github">⭐ GitHub</a>
|
|
87
|
+
</div>
|
|
88
|
+
</div>
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
<style>
|
|
2
|
+
.site-footer {
|
|
3
|
+
width: 100%;
|
|
4
|
+
max-width: 1200px;
|
|
5
|
+
margin: 1rem auto 0;
|
|
6
|
+
padding: 1rem 1.25rem;
|
|
7
|
+
color: rgba(255, 255, 255, 0.85);
|
|
8
|
+
font-size: 0.85rem;
|
|
9
|
+
text-align: center;
|
|
10
|
+
}
|
|
11
|
+
.site-footer a {
|
|
12
|
+
color: white;
|
|
13
|
+
text-decoration: underline;
|
|
14
|
+
}
|
|
15
|
+
</style>
|
|
16
|
+
<footer class="site-footer">
|
|
17
|
+
Built with
|
|
18
|
+
<a href="https://github.com/tkeron/tkeron" target="_blank">tkeron</a>
|
|
19
|
+
— zero runtime, vanilla TypeScript.
|
|
20
|
+
</footer>
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
<style>
|
|
2
|
+
.site-header {
|
|
3
|
+
width: 100%;
|
|
4
|
+
max-width: 1200px;
|
|
5
|
+
margin: 0 auto 1rem;
|
|
6
|
+
padding: 1rem 1.25rem;
|
|
7
|
+
background: rgba(255, 255, 255, 0.12);
|
|
8
|
+
backdrop-filter: blur(10px);
|
|
9
|
+
border-radius: 12px;
|
|
10
|
+
display: flex;
|
|
11
|
+
align-items: center;
|
|
12
|
+
justify-content: space-between;
|
|
13
|
+
color: white;
|
|
14
|
+
}
|
|
15
|
+
.site-header .brand {
|
|
16
|
+
font-weight: 700;
|
|
17
|
+
font-size: 1.1rem;
|
|
18
|
+
text-decoration: none;
|
|
19
|
+
color: white;
|
|
20
|
+
}
|
|
21
|
+
.site-header nav {
|
|
22
|
+
display: flex;
|
|
23
|
+
gap: 0.75rem;
|
|
24
|
+
}
|
|
25
|
+
.site-header nav a {
|
|
26
|
+
color: white;
|
|
27
|
+
text-decoration: none;
|
|
28
|
+
padding: 0.4rem 0.75rem;
|
|
29
|
+
border-radius: 6px;
|
|
30
|
+
font-size: 0.9rem;
|
|
31
|
+
background: rgba(255, 255, 255, 0.1);
|
|
32
|
+
}
|
|
33
|
+
.site-header nav a:hover {
|
|
34
|
+
background: rgba(255, 255, 255, 0.25);
|
|
35
|
+
}
|
|
36
|
+
</style>
|
|
37
|
+
<header class="site-header">
|
|
38
|
+
<a href="./index.html" class="brand">tkeron</a>
|
|
39
|
+
<nav>
|
|
40
|
+
<a href="./index.html">Home</a>
|
|
41
|
+
<a href="./about.html">About</a>
|
|
42
|
+
<a href="./docs.html">Docs</a>
|
|
43
|
+
</nav>
|
|
44
|
+
</header>
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
<style>
|
|
2
|
+
.counter-button-wrap {
|
|
3
|
+
margin-top: 1rem;
|
|
4
|
+
text-align: center;
|
|
5
|
+
}
|
|
6
|
+
.counter-button-wrap button {
|
|
7
|
+
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
|
8
|
+
color: white;
|
|
9
|
+
border: none;
|
|
10
|
+
padding: 0.75rem 2rem;
|
|
11
|
+
border-radius: 8px;
|
|
12
|
+
cursor: pointer;
|
|
13
|
+
font-size: 1rem;
|
|
14
|
+
font-weight: 600;
|
|
15
|
+
transition:
|
|
16
|
+
transform 0.1s,
|
|
17
|
+
box-shadow 0.2s;
|
|
18
|
+
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);
|
|
19
|
+
}
|
|
20
|
+
.counter-button-wrap button:hover {
|
|
21
|
+
transform: scale(1.05);
|
|
22
|
+
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.3);
|
|
23
|
+
}
|
|
24
|
+
.counter-button-wrap button:active {
|
|
25
|
+
transform: scale(0.98);
|
|
26
|
+
}
|
|
27
|
+
.counter-button-wrap .count {
|
|
28
|
+
font-size: 2rem;
|
|
29
|
+
font-weight: bold;
|
|
30
|
+
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
|
31
|
+
-webkit-background-clip: text;
|
|
32
|
+
-webkit-text-fill-color: transparent;
|
|
33
|
+
background-clip: text;
|
|
34
|
+
margin-top: 1rem;
|
|
35
|
+
}
|
|
36
|
+
</style>
|
|
37
|
+
<section class="counter-card">
|
|
38
|
+
<h2>🎯 Client-side TypeScript</h2>
|
|
39
|
+
<p style="margin-bottom: 0.75rem">Interactive features in the browser:</p>
|
|
40
|
+
<div class="counter-button-wrap">
|
|
41
|
+
<button id="increment">Click me!</button>
|
|
42
|
+
<div class="count">Clicks: <span id="count">0</span></div>
|
|
43
|
+
</div>
|
|
44
|
+
<p style="font-size: 0.85rem; color: #666; margin-top: 0.75rem">
|
|
45
|
+
✓ Event handling & DOM manipulation<br />✓ Regular TypeScript for
|
|
46
|
+
interactivity
|
|
47
|
+
</p>
|
|
48
|
+
</section>
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
<style>
|
|
2
|
+
.crypto-prices-container {
|
|
3
|
+
display: grid;
|
|
4
|
+
grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
|
|
5
|
+
gap: 1rem;
|
|
6
|
+
margin-top: 1rem;
|
|
7
|
+
}
|
|
8
|
+
.crypto-card {
|
|
9
|
+
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
|
10
|
+
padding: 1.25rem;
|
|
11
|
+
border-radius: 12px;
|
|
12
|
+
color: white;
|
|
13
|
+
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
|
|
14
|
+
transition: transform 0.2s;
|
|
15
|
+
}
|
|
16
|
+
.crypto-card:hover {
|
|
17
|
+
transform: translateY(-4px);
|
|
18
|
+
}
|
|
19
|
+
.crypto-header {
|
|
20
|
+
display: flex;
|
|
21
|
+
justify-content: space-between;
|
|
22
|
+
align-items: center;
|
|
23
|
+
margin-bottom: 0.75rem;
|
|
24
|
+
}
|
|
25
|
+
.crypto-name {
|
|
26
|
+
font-weight: 600;
|
|
27
|
+
font-size: 1rem;
|
|
28
|
+
}
|
|
29
|
+
.crypto-symbol {
|
|
30
|
+
background: rgba(255, 255, 255, 0.2);
|
|
31
|
+
padding: 0.25rem 0.5rem;
|
|
32
|
+
border-radius: 4px;
|
|
33
|
+
font-size: 0.75rem;
|
|
34
|
+
font-weight: 700;
|
|
35
|
+
}
|
|
36
|
+
.crypto-price {
|
|
37
|
+
font-size: 1.5rem;
|
|
38
|
+
font-weight: 700;
|
|
39
|
+
margin-bottom: 0.5rem;
|
|
40
|
+
}
|
|
41
|
+
.crypto-change {
|
|
42
|
+
font-size: 0.9rem;
|
|
43
|
+
font-weight: 600;
|
|
44
|
+
}
|
|
45
|
+
</style>
|
|
46
|
+
<section style="grid-column: span 3">
|
|
47
|
+
<h2>💰 Asset Prices (Build Time)</h2>
|
|
48
|
+
<p style="font-size: 0.85rem; margin-bottom: 0.75rem">
|
|
49
|
+
Real cryptocurrency prices fetched from CoinGecko API at build time:
|
|
50
|
+
</p>
|
|
51
|
+
<div id="crypto-prices" class="crypto-prices-container"></div>
|
|
52
|
+
</section>
|
|
@@ -1,14 +1,18 @@
|
|
|
1
|
-
<
|
|
2
|
-
|
|
1
|
+
<style>
|
|
2
|
+
.info-card {
|
|
3
3
|
padding: 1rem;
|
|
4
4
|
background: #eff6ff;
|
|
5
5
|
border-left: 4px solid #2563eb;
|
|
6
6
|
border-radius: 4px;
|
|
7
|
-
|
|
8
|
-
|
|
7
|
+
}
|
|
8
|
+
.info-card p {
|
|
9
|
+
margin-top: 0.5rem;
|
|
10
|
+
}
|
|
11
|
+
</style>
|
|
12
|
+
<div class="info-card">
|
|
9
13
|
<strong>This is an HTML component!</strong>
|
|
10
|
-
<p
|
|
14
|
+
<p>
|
|
11
15
|
Defined in <code>info-card.com.html</code> and reused anywhere in your HTML
|
|
12
|
-
as <code>&
|
|
16
|
+
as <code><info-card></info-card></code>.
|
|
13
17
|
</p>
|
|
14
18
|
</div>
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
<style>
|
|
2
|
+
.markdown-card .md-body {
|
|
3
|
+
padding: 0.75rem 1rem;
|
|
4
|
+
background: #fffbea;
|
|
5
|
+
border-left: 4px solid #f59e0b;
|
|
6
|
+
border-radius: 4px;
|
|
7
|
+
font-size: 0.9rem;
|
|
8
|
+
}
|
|
9
|
+
</style>
|
|
10
|
+
<section class="markdown-card">
|
|
11
|
+
<h2>📄 Markdown Components</h2>
|
|
12
|
+
<p style="margin-bottom: 0.75rem">
|
|
13
|
+
Author content with <code>.com.md</code>:
|
|
14
|
+
</p>
|
|
15
|
+
<div class="md-body">
|
|
16
|
+
<about-intro></about-intro>
|
|
17
|
+
</div>
|
|
18
|
+
<p style="font-size: 0.85rem; color: #666; margin-top: 0.75rem">
|
|
19
|
+
✓ Markdown rendered at build time<br />✓ Reusable like any component
|
|
20
|
+
</p>
|
|
21
|
+
</section>
|
|
@@ -1,10 +1,13 @@
|
|
|
1
1
|
<section id="pre-render-card">
|
|
2
|
-
<h2>📝 Pre
|
|
3
|
-
<p>
|
|
2
|
+
<h2>📝 Pre / Post Rendering</h2>
|
|
3
|
+
<p>
|
|
4
|
+
Run code at build time with <code>.pre.ts</code> (before components) and
|
|
5
|
+
<code>.post.ts</code> (after components):
|
|
6
|
+
</p>
|
|
4
7
|
<p
|
|
5
8
|
id="build-time"
|
|
6
9
|
style="font-weight: bold; color: #667eea; margin: 0.75rem 0"
|
|
7
|
-
|
|
10
|
+
>·</p>
|
|
8
11
|
<p style="font-size: 0.85rem; color: #666; margin-top: 0.75rem">
|
|
9
12
|
✓ Manipulate DOM before deployment<br />
|
|
10
13
|
✓ Import any TypeScript module<br />
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
<style>
|
|
2
|
+
.quote-card #pre-rendered-quote {
|
|
3
|
+
margin: 1rem 0;
|
|
4
|
+
padding: 0.75rem;
|
|
5
|
+
background: #f8f9fa;
|
|
6
|
+
border-radius: 8px;
|
|
7
|
+
border-left: 4px solid #667eea;
|
|
8
|
+
}
|
|
9
|
+
.quote-card #build-metadata {
|
|
10
|
+
margin-top: 1rem;
|
|
11
|
+
padding-top: 0.75rem;
|
|
12
|
+
border-top: 1px solid #eee;
|
|
13
|
+
font-size: 0.75rem;
|
|
14
|
+
color: #999;
|
|
15
|
+
}
|
|
16
|
+
.quote-card blockquote p {
|
|
17
|
+
font-style: italic;
|
|
18
|
+
}
|
|
19
|
+
.quote-card blockquote footer {
|
|
20
|
+
margin-top: 0.5rem;
|
|
21
|
+
font-size: 0.85rem;
|
|
22
|
+
color: #666;
|
|
23
|
+
}
|
|
24
|
+
</style>
|
|
25
|
+
<section class="quote-card" style="grid-column: span 3">
|
|
26
|
+
<h2>💬 Quote of the Build</h2>
|
|
27
|
+
<p style="font-size: 0.85rem; margin-bottom: 0.75rem">
|
|
28
|
+
This content was fetched from an external API at build time:
|
|
29
|
+
</p>
|
|
30
|
+
<div id="pre-rendered-quote"></div>
|
|
31
|
+
<div id="build-metadata"></div>
|
|
32
|
+
</section>
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
</p>
|
|
6
6
|
<user-badge count="3"></user-badge>
|
|
7
7
|
<p style="font-size: 0.85rem; color: #666; margin-top: 0.75rem">
|
|
8
|
-
✓ Loops & conditionals<br />✓ Read attributes dynamically<br />✓
|
|
9
|
-
code execution
|
|
8
|
+
✓ Loops & conditionals<br />✓ Read attributes dynamically<br />✓
|
|
9
|
+
Build-time code execution
|
|
10
10
|
</p>
|
|
11
11
|
</section>
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
const count = com.getAttribute("count") || "3";
|
|
2
|
+
const numCount = parseInt(count, 10);
|
|
3
|
+
|
|
4
|
+
const items: string[] = [];
|
|
5
|
+
for (let i = 1; i <= numCount; i++) {
|
|
6
|
+
items.push(`<li>✓ Item ${i}</li>`);
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
com.innerHTML = `
|
|
10
|
+
<div class="user-badge">
|
|
11
|
+
<ul>
|
|
12
|
+
${items.join("")}
|
|
13
|
+
</ul>
|
|
14
|
+
</div>
|
|
15
|
+
<style>
|
|
16
|
+
.user-badge {
|
|
17
|
+
background: #f0fdf4;
|
|
18
|
+
border-left: 3px solid #22c55e;
|
|
19
|
+
padding: 0.75rem;
|
|
20
|
+
border-radius: 4px;
|
|
21
|
+
}
|
|
22
|
+
.user-badge ul {
|
|
23
|
+
list-style: none;
|
|
24
|
+
padding: 0;
|
|
25
|
+
margin: 0;
|
|
26
|
+
font-size: 0.9rem;
|
|
27
|
+
color: #166534;
|
|
28
|
+
}
|
|
29
|
+
</style>
|
|
30
|
+
`;
|
|
@@ -0,0 +1,33 @@
|
|
|
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>Docs — tkeron</title>
|
|
7
|
+
<styles-injector></styles-injector>
|
|
8
|
+
</head>
|
|
9
|
+
<body>
|
|
10
|
+
<site-header></site-header>
|
|
11
|
+
<main class="container">
|
|
12
|
+
<article class="page">
|
|
13
|
+
<h1>Docs</h1>
|
|
14
|
+
<p>Getting started with tkeron:</p>
|
|
15
|
+
<ul style="margin-left: 1.5rem; margin-top: 0.5rem">
|
|
16
|
+
<li><code>tk dev</code> — start the dev server on <code>:3000</code></li>
|
|
17
|
+
<li><code>tk build</code> — compile <code>websrc/</code> into <code>web/</code></li>
|
|
18
|
+
<li><code>tk init <name></code> — scaffold a new project</li>
|
|
19
|
+
</ul>
|
|
20
|
+
<p style="margin-top: 1rem">
|
|
21
|
+
Components live under <code>websrc/components/</code> grouped by domain:
|
|
22
|
+
<code>layout/</code>, <code>ui/</code>, <code>content/</code>.
|
|
23
|
+
</p>
|
|
24
|
+
<p>
|
|
25
|
+
Pages at the root of <code>websrc/</code> map directly to URLs —
|
|
26
|
+
<code>about.html</code> → <code>/about</code>,
|
|
27
|
+
<code>docs.html</code> → <code>/docs</code>.
|
|
28
|
+
</p>
|
|
29
|
+
</article>
|
|
30
|
+
</main>
|
|
31
|
+
<site-footer></site-footer>
|
|
32
|
+
</body>
|
|
33
|
+
</html>
|