@beatzball/create-litro 0.2.0 → 0.3.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.
- package/CHANGELOG.md +32 -0
- package/dist/recipes/11ty-blog/template/e2e/index.spec.ts +19 -0
- package/dist/recipes/11ty-blog/template/package.json +4 -2
- package/dist/recipes/11ty-blog/template/playwright.config.ts +20 -0
- package/dist/recipes/fullstack/template/e2e/index.spec.ts +19 -0
- package/dist/recipes/fullstack/template/package.json +4 -2
- package/dist/recipes/fullstack/template/playwright.config.ts +20 -0
- package/dist/recipes/starlight/template/app.ts +14 -0
- package/dist/recipes/starlight/template/e2e/index.spec.ts +32 -0
- package/dist/recipes/starlight/template/nitro.config.ts +2 -0
- package/dist/recipes/starlight/template/package.json +5 -2
- package/dist/recipes/starlight/template/pages/index.ts +6 -6
- package/dist/recipes/starlight/template/playwright.config.ts +20 -0
- package/dist/recipes/starlight/template/public/styles/starlight.css +58 -19
- package/dist/recipes/starlight/template/src/components/{sl-aside.ts → litro-aside.ts} +5 -5
- package/{recipes/starlight/template/src/components/sl-badge.ts → dist/recipes/starlight/template/src/components/litro-badge.ts} +5 -5
- package/{recipes/starlight/template/src/components/sl-card-grid.ts → dist/recipes/starlight/template/src/components/litro-card-grid.ts} +7 -7
- package/{recipes/starlight/template/src/components/sl-card.ts → dist/recipes/starlight/template/src/components/litro-card.ts} +36 -12
- package/dist/recipes/starlight/template/src/components/{sl-tab-item.ts → litro-tab-item.ts} +6 -6
- package/{recipes/starlight/template/src/components/sl-tabs.ts → dist/recipes/starlight/template/src/components/litro-tabs.ts} +12 -12
- package/dist/recipes/starlight/template/src/components/starlight-header.ts +3 -3
- package/dist/recipes/starlight/template/src/components/starlight-page.ts +5 -1
- package/dist/recipes/starlight/template/src/route-meta.ts +3 -1
- package/dist/recipes/starlight/template/vite.config.ts +1 -1
- package/dist/src/scaffold.test.js +6 -6
- package/dist/src/scaffold.test.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +1 -1
- package/recipes/11ty-blog/template/e2e/index.spec.ts +19 -0
- package/recipes/11ty-blog/template/package.json +4 -2
- package/recipes/11ty-blog/template/playwright.config.ts +20 -0
- package/recipes/fullstack/template/e2e/index.spec.ts +19 -0
- package/recipes/fullstack/template/package.json +4 -2
- package/recipes/fullstack/template/playwright.config.ts +20 -0
- package/recipes/starlight/template/app.ts +14 -0
- package/recipes/starlight/template/e2e/index.spec.ts +32 -0
- package/recipes/starlight/template/nitro.config.ts +2 -0
- package/recipes/starlight/template/package.json +5 -2
- package/recipes/starlight/template/pages/index.ts +6 -6
- package/recipes/starlight/template/playwright.config.ts +20 -0
- package/recipes/starlight/template/public/styles/starlight.css +58 -19
- package/recipes/starlight/template/src/components/{sl-aside.ts → litro-aside.ts} +5 -5
- package/{dist/recipes/starlight/template/src/components/sl-badge.ts → recipes/starlight/template/src/components/litro-badge.ts} +5 -5
- package/{dist/recipes/starlight/template/src/components/sl-card-grid.ts → recipes/starlight/template/src/components/litro-card-grid.ts} +7 -7
- package/{dist/recipes/starlight/template/src/components/sl-card.ts → recipes/starlight/template/src/components/litro-card.ts} +36 -12
- package/recipes/starlight/template/src/components/{sl-tab-item.ts → litro-tab-item.ts} +6 -6
- package/{dist/recipes/starlight/template/src/components/sl-tabs.ts → recipes/starlight/template/src/components/litro-tabs.ts} +12 -12
- package/recipes/starlight/template/src/components/starlight-header.ts +3 -3
- package/recipes/starlight/template/src/components/starlight-page.ts +5 -1
- package/recipes/starlight/template/src/route-meta.ts +3 -1
- package/recipes/starlight/template/vite.config.ts +1 -1
- package/src/scaffold.test.ts +6 -6
- package/vitest.config.ts +10 -0
package/package.json
CHANGED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { test, expect } from '@playwright/test';
|
|
2
|
+
|
|
3
|
+
test('home renders page-home component', async ({ page }) => {
|
|
4
|
+
await page.goto('/');
|
|
5
|
+
await page.waitForSelector('page-home');
|
|
6
|
+
await expect(page.locator('page-home')).toBeVisible();
|
|
7
|
+
});
|
|
8
|
+
|
|
9
|
+
test('blog index renders', async ({ page }) => {
|
|
10
|
+
await page.goto('/blog');
|
|
11
|
+
await page.waitForSelector('page-blog');
|
|
12
|
+
await expect(page.locator('page-blog')).toBeVisible();
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
test('blog post renders with h1', async ({ page }) => {
|
|
16
|
+
await page.goto('/blog/hello-world');
|
|
17
|
+
await page.waitForSelector('page-blog-slug');
|
|
18
|
+
await expect(page.locator('page-blog-slug h1')).toBeVisible();
|
|
19
|
+
});
|
|
@@ -9,7 +9,8 @@
|
|
|
9
9
|
"dev": "litro dev",
|
|
10
10
|
"build": "litro build",
|
|
11
11
|
"preview": "litro preview",
|
|
12
|
-
"generate": "litro generate"
|
|
12
|
+
"generate": "litro generate",
|
|
13
|
+
"test:e2e": "playwright test"
|
|
13
14
|
},
|
|
14
15
|
"dependencies": {
|
|
15
16
|
"@beatzball/litro": "latest",
|
|
@@ -21,6 +22,7 @@
|
|
|
21
22
|
"devDependencies": {
|
|
22
23
|
"nitropack": "^2.13.1",
|
|
23
24
|
"vite": "^5.4.11",
|
|
24
|
-
"typescript": "^5.7.3"
|
|
25
|
+
"typescript": "^5.7.3",
|
|
26
|
+
"@playwright/test": "^1.48.0"
|
|
25
27
|
}
|
|
26
28
|
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { defineConfig, devices } from '@playwright/test';
|
|
2
|
+
|
|
3
|
+
export default defineConfig({
|
|
4
|
+
testDir: './e2e',
|
|
5
|
+
fullyParallel: false,
|
|
6
|
+
retries: process.env.CI ? 2 : 0,
|
|
7
|
+
workers: 1,
|
|
8
|
+
reporter: 'html',
|
|
9
|
+
use: {
|
|
10
|
+
baseURL: 'http://localhost:3030',
|
|
11
|
+
trace: 'on-first-retry',
|
|
12
|
+
},
|
|
13
|
+
projects: [{ name: 'chromium', use: { ...devices['Desktop Chrome'] } }],
|
|
14
|
+
webServer: {
|
|
15
|
+
command: 'pnpm dev',
|
|
16
|
+
url: 'http://localhost:3030',
|
|
17
|
+
reuseExistingServer: !process.env.CI,
|
|
18
|
+
timeout: 60000,
|
|
19
|
+
},
|
|
20
|
+
});
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { test, expect } from '@playwright/test';
|
|
2
|
+
|
|
3
|
+
test('SSR renders without JavaScript (DSD in source)', async ({ request }) => {
|
|
4
|
+
const response = await request.get('/');
|
|
5
|
+
const body = await response.text();
|
|
6
|
+
expect(body).toContain('shadowrootmode');
|
|
7
|
+
});
|
|
8
|
+
|
|
9
|
+
test('__litro_data__ is injected into HTML', async ({ request }) => {
|
|
10
|
+
const response = await request.get('/');
|
|
11
|
+
const body = await response.text();
|
|
12
|
+
expect(body).toContain('__litro_data__');
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
test('page-home is visible after hydration', async ({ page }) => {
|
|
16
|
+
await page.goto('/');
|
|
17
|
+
await page.waitForSelector('page-home');
|
|
18
|
+
await expect(page.locator('page-home')).toBeVisible();
|
|
19
|
+
});
|
|
@@ -9,7 +9,8 @@
|
|
|
9
9
|
"dev": "litro dev",
|
|
10
10
|
"build": "litro build",
|
|
11
11
|
"preview": "litro preview",
|
|
12
|
-
"generate": "litro generate"
|
|
12
|
+
"generate": "litro generate",
|
|
13
|
+
"test:e2e": "playwright test"
|
|
13
14
|
},
|
|
14
15
|
"dependencies": {
|
|
15
16
|
"@beatzball/litro": "latest",
|
|
@@ -21,6 +22,7 @@
|
|
|
21
22
|
"devDependencies": {
|
|
22
23
|
"nitropack": "^2.13.1",
|
|
23
24
|
"vite": "^5.4.11",
|
|
24
|
-
"typescript": "^5.7.3"
|
|
25
|
+
"typescript": "^5.7.3",
|
|
26
|
+
"@playwright/test": "^1.48.0"
|
|
25
27
|
}
|
|
26
28
|
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { defineConfig, devices } from '@playwright/test';
|
|
2
|
+
|
|
3
|
+
export default defineConfig({
|
|
4
|
+
testDir: './e2e',
|
|
5
|
+
fullyParallel: false,
|
|
6
|
+
retries: process.env.CI ? 2 : 0,
|
|
7
|
+
workers: 1,
|
|
8
|
+
reporter: 'html',
|
|
9
|
+
use: {
|
|
10
|
+
baseURL: 'http://localhost:3030',
|
|
11
|
+
trace: 'on-first-retry',
|
|
12
|
+
},
|
|
13
|
+
projects: [{ name: 'chromium', use: { ...devices['Desktop Chrome'] } }],
|
|
14
|
+
webServer: {
|
|
15
|
+
command: 'pnpm dev',
|
|
16
|
+
url: 'http://localhost:3030',
|
|
17
|
+
reuseExistingServer: !process.env.CI,
|
|
18
|
+
timeout: 60000,
|
|
19
|
+
},
|
|
20
|
+
});
|
|
@@ -5,6 +5,20 @@ import '@lit-labs/ssr-client/lit-element-hydrate-support.js';
|
|
|
5
5
|
import '@beatzball/litro/runtime/LitroOutlet.js';
|
|
6
6
|
import '@beatzball/litro/runtime/LitroLink.js';
|
|
7
7
|
|
|
8
|
+
// Shoelace components (tree-shaken — only what the template uses)
|
|
9
|
+
import '@shoelace-style/shoelace/dist/components/button/button.js';
|
|
10
|
+
import '@shoelace-style/shoelace/dist/components/icon/icon.js';
|
|
11
|
+
import '@shoelace-style/shoelace/dist/components/badge/badge.js';
|
|
12
|
+
import '@shoelace-style/shoelace/dist/components/copy-button/copy-button.js';
|
|
13
|
+
import '@shoelace-style/shoelace/dist/components/details/details.js';
|
|
14
|
+
import '@shoelace-style/shoelace/dist/components/tab-group/tab-group.js';
|
|
15
|
+
import '@shoelace-style/shoelace/dist/components/tab/tab.js';
|
|
16
|
+
import '@shoelace-style/shoelace/dist/components/tab-panel/tab-panel.js';
|
|
17
|
+
import { setBasePath } from '@shoelace-style/shoelace/dist/utilities/base-path.js';
|
|
18
|
+
|
|
19
|
+
// Point Shoelace's icon loader at the served assets directory
|
|
20
|
+
setBasePath('/shoelace/');
|
|
21
|
+
|
|
8
22
|
// Routes generated by the page scanner before each vite build.
|
|
9
23
|
import { routes } from './routes.generated.js';
|
|
10
24
|
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { test, expect } from '@playwright/test';
|
|
2
|
+
|
|
3
|
+
const PRERENDERED_ROUTES = [
|
|
4
|
+
'/',
|
|
5
|
+
'/docs/getting-started',
|
|
6
|
+
'/docs/installation',
|
|
7
|
+
'/docs/configuration',
|
|
8
|
+
'/docs/guides-first-page',
|
|
9
|
+
'/docs/guides-deploying',
|
|
10
|
+
'/blog',
|
|
11
|
+
'/blog/welcome',
|
|
12
|
+
'/blog/release-notes',
|
|
13
|
+
];
|
|
14
|
+
|
|
15
|
+
test('home renders page-home component', async ({ page }) => {
|
|
16
|
+
await page.goto('/');
|
|
17
|
+
await page.waitForSelector('page-home');
|
|
18
|
+
await expect(page.locator('page-home')).toBeVisible();
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
test('/docs/getting-started renders', async ({ page }) => {
|
|
22
|
+
await page.goto('/docs/getting-started');
|
|
23
|
+
await page.waitForSelector('page-docs-slug');
|
|
24
|
+
await expect(page.locator('page-docs-slug')).toBeVisible();
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
test('all prerendered routes return 200', async ({ request }) => {
|
|
28
|
+
for (const route of PRERENDERED_ROUTES) {
|
|
29
|
+
const response = await request.get(route);
|
|
30
|
+
expect(response.status(), `Expected 200 for ${route}`).toBe(200);
|
|
31
|
+
}
|
|
32
|
+
});
|
|
@@ -15,6 +15,8 @@ export default defineNitroConfig({
|
|
|
15
15
|
{ dir: '../dist/client', baseURL: '/_litro/', maxAge: 31536000 },
|
|
16
16
|
{ dir: '../public', baseURL: '/', maxAge: 0 },
|
|
17
17
|
{ dir: '../content', baseURL: '/content/', maxAge: 86400 },
|
|
18
|
+
{ dir: '../node_modules/@shoelace-style/shoelace/dist/assets', baseURL: '/shoelace/assets/', maxAge: 604800 },
|
|
19
|
+
{ dir: '../node_modules/@shoelace-style/shoelace/dist/themes', baseURL: '/shoelace/themes/', maxAge: 604800 },
|
|
18
20
|
],
|
|
19
21
|
|
|
20
22
|
externals: { inline: ['@lit-labs/ssr', '@lit-labs/ssr-client'] },
|
|
@@ -9,10 +9,12 @@
|
|
|
9
9
|
"dev": "litro dev",
|
|
10
10
|
"build": "litro build",
|
|
11
11
|
"preview": "litro preview",
|
|
12
|
-
"generate": "litro generate"
|
|
12
|
+
"generate": "litro generate",
|
|
13
|
+
"test:e2e": "playwright test"
|
|
13
14
|
},
|
|
14
15
|
"dependencies": {
|
|
15
16
|
"@beatzball/litro": "latest",
|
|
17
|
+
"@shoelace-style/shoelace": "^2.19.0",
|
|
16
18
|
"lit": "^3.2.1",
|
|
17
19
|
"@lit-labs/ssr": "^3.3.0",
|
|
18
20
|
"@lit-labs/ssr-client": "^1.1.7",
|
|
@@ -21,6 +23,7 @@
|
|
|
21
23
|
"devDependencies": {
|
|
22
24
|
"nitropack": "^2.13.1",
|
|
23
25
|
"vite": "^5.4.11",
|
|
24
|
-
"typescript": "^5.7.3"
|
|
26
|
+
"typescript": "^5.7.3",
|
|
27
|
+
"@playwright/test": "^1.48.0"
|
|
25
28
|
}
|
|
26
29
|
}
|
|
@@ -8,8 +8,8 @@ import { starlightHead } from '../src/route-meta.js';
|
|
|
8
8
|
|
|
9
9
|
// Register components used in render()
|
|
10
10
|
import '../src/components/starlight-header.js';
|
|
11
|
-
import '../src/components/
|
|
12
|
-
import '../src/components/
|
|
11
|
+
import '../src/components/litro-card.js';
|
|
12
|
+
import '../src/components/litro-card-grid.js';
|
|
13
13
|
|
|
14
14
|
export interface SplashData {
|
|
15
15
|
siteTitle: string;
|
|
@@ -116,15 +116,15 @@ export class SplashPage extends LitroPage {
|
|
|
116
116
|
</section>
|
|
117
117
|
|
|
118
118
|
<section>
|
|
119
|
-
<
|
|
119
|
+
<litro-card-grid>
|
|
120
120
|
${features.map(f => html`
|
|
121
|
-
<
|
|
121
|
+
<litro-card
|
|
122
122
|
icon="${f.icon ?? ''}"
|
|
123
123
|
title="${f.title}"
|
|
124
124
|
description="${f.description}"
|
|
125
|
-
></
|
|
125
|
+
></litro-card>
|
|
126
126
|
`)}
|
|
127
|
-
</
|
|
127
|
+
</litro-card-grid>
|
|
128
128
|
</section>
|
|
129
129
|
</main>
|
|
130
130
|
</div>
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { defineConfig, devices } from '@playwright/test';
|
|
2
|
+
|
|
3
|
+
export default defineConfig({
|
|
4
|
+
testDir: './e2e',
|
|
5
|
+
fullyParallel: false,
|
|
6
|
+
retries: process.env.CI ? 2 : 0,
|
|
7
|
+
workers: 1,
|
|
8
|
+
reporter: 'html',
|
|
9
|
+
use: {
|
|
10
|
+
baseURL: 'http://localhost:3030',
|
|
11
|
+
trace: 'on-first-retry',
|
|
12
|
+
},
|
|
13
|
+
projects: [{ name: 'chromium', use: { ...devices['Desktop Chrome'] } }],
|
|
14
|
+
webServer: {
|
|
15
|
+
command: 'pnpm dev',
|
|
16
|
+
url: 'http://localhost:3030',
|
|
17
|
+
reuseExistingServer: !process.env.CI,
|
|
18
|
+
timeout: 60000,
|
|
19
|
+
},
|
|
20
|
+
});
|
|
@@ -1,3 +1,23 @@
|
|
|
1
|
+
/* FOUCE - https://www.abeautifulsite.net/posts/flash-of-undefined-custom-elements/ */
|
|
2
|
+
:not(:defined) {
|
|
3
|
+
visibility: hidden;
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
/* Shoelace theme bridge — map sl-color-primary-* to Litro's accent palette */
|
|
7
|
+
:root {
|
|
8
|
+
--sl-color-primary-50: #f5f3ff;
|
|
9
|
+
--sl-color-primary-100: #ede9fe;
|
|
10
|
+
--sl-color-primary-200: #ddd6fe;
|
|
11
|
+
--sl-color-primary-300: #c4b5fd;
|
|
12
|
+
--sl-color-primary-400: #a78bfa;
|
|
13
|
+
--sl-color-primary-500: #8b5cf6;
|
|
14
|
+
--sl-color-primary-600: #7c3aed;
|
|
15
|
+
--sl-color-primary-700: #6d28d9;
|
|
16
|
+
--sl-color-primary-800: #5b21b6;
|
|
17
|
+
--sl-color-primary-900: #4c1d95;
|
|
18
|
+
--sl-color-primary-950: #2e1065;
|
|
19
|
+
}
|
|
20
|
+
|
|
1
21
|
/* Starlight design tokens — light mode defaults */
|
|
2
22
|
:root {
|
|
3
23
|
--sl-color-white: #fff;
|
|
@@ -30,14 +50,14 @@
|
|
|
30
50
|
--sl-font-sans: ui-sans-serif, system-ui, -apple-system, sans-serif;
|
|
31
51
|
--sl-font-mono: ui-monospace, "Cascadia Code", "Fira Code", monospace;
|
|
32
52
|
|
|
33
|
-
--sl-text-xs:
|
|
34
|
-
--sl-text-sm:
|
|
53
|
+
--sl-text-xs: 0.75rem;
|
|
54
|
+
--sl-text-sm: 0.875rem;
|
|
35
55
|
--sl-text-base: 1rem;
|
|
36
|
-
--sl-text-lg:
|
|
37
|
-
--sl-text-xl:
|
|
38
|
-
--sl-text-2xl:
|
|
39
|
-
--sl-text-3xl:
|
|
40
|
-
--sl-text-4xl:
|
|
56
|
+
--sl-text-lg: 1.125rem;
|
|
57
|
+
--sl-text-xl: 1.25rem;
|
|
58
|
+
--sl-text-2xl: 1.5rem;
|
|
59
|
+
--sl-text-3xl: 1.875rem;
|
|
60
|
+
--sl-text-4xl: 2.25rem;
|
|
41
61
|
|
|
42
62
|
--sl-nav-height: 3.5rem;
|
|
43
63
|
--sl-sidebar-width: 16rem;
|
|
@@ -54,7 +74,7 @@
|
|
|
54
74
|
}
|
|
55
75
|
|
|
56
76
|
/* Dark mode overrides */
|
|
57
|
-
[data-theme=
|
|
77
|
+
[data-theme="dark"] {
|
|
58
78
|
--sl-color-text: #f0f0f0;
|
|
59
79
|
--sl-color-bg: #17181c;
|
|
60
80
|
--sl-color-bg-sidebar: #1e1f24;
|
|
@@ -80,7 +100,9 @@
|
|
|
80
100
|
}
|
|
81
101
|
|
|
82
102
|
/* Base reset */
|
|
83
|
-
*,
|
|
103
|
+
*,
|
|
104
|
+
*::before,
|
|
105
|
+
*::after {
|
|
84
106
|
box-sizing: border-box;
|
|
85
107
|
}
|
|
86
108
|
|
|
@@ -99,7 +121,12 @@ body {
|
|
|
99
121
|
}
|
|
100
122
|
|
|
101
123
|
/* Typography reset for content areas */
|
|
102
|
-
h1,
|
|
124
|
+
h1,
|
|
125
|
+
h2,
|
|
126
|
+
h3,
|
|
127
|
+
h4,
|
|
128
|
+
h5,
|
|
129
|
+
h6 {
|
|
103
130
|
margin-top: 1.5em;
|
|
104
131
|
margin-bottom: 0.5em;
|
|
105
132
|
font-weight: 600;
|
|
@@ -107,10 +134,20 @@ h1, h2, h3, h4, h5, h6 {
|
|
|
107
134
|
color: var(--sl-color-text);
|
|
108
135
|
}
|
|
109
136
|
|
|
110
|
-
h1 {
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
137
|
+
h1 {
|
|
138
|
+
font-size: var(--sl-text-4xl);
|
|
139
|
+
}
|
|
140
|
+
h2 {
|
|
141
|
+
font-size: var(--sl-text-2xl);
|
|
142
|
+
border-bottom: 1px solid var(--sl-color-border);
|
|
143
|
+
padding-bottom: 0.25em;
|
|
144
|
+
}
|
|
145
|
+
h3 {
|
|
146
|
+
font-size: var(--sl-text-xl);
|
|
147
|
+
}
|
|
148
|
+
h4 {
|
|
149
|
+
font-size: var(--sl-text-lg);
|
|
150
|
+
}
|
|
114
151
|
|
|
115
152
|
p {
|
|
116
153
|
margin-top: 0;
|
|
@@ -147,7 +184,7 @@ pre {
|
|
|
147
184
|
line-height: 1.6;
|
|
148
185
|
}
|
|
149
186
|
|
|
150
|
-
[data-theme=
|
|
187
|
+
[data-theme="dark"] pre {
|
|
151
188
|
background-color: #0d0e11;
|
|
152
189
|
color: #e2e4e9;
|
|
153
190
|
}
|
|
@@ -166,7 +203,8 @@ table {
|
|
|
166
203
|
font-size: var(--sl-text-sm);
|
|
167
204
|
}
|
|
168
205
|
|
|
169
|
-
th,
|
|
206
|
+
th,
|
|
207
|
+
td {
|
|
170
208
|
border: 1px solid var(--sl-color-border);
|
|
171
209
|
padding: 0.5rem 0.75rem;
|
|
172
210
|
text-align: left;
|
|
@@ -177,11 +215,12 @@ th {
|
|
|
177
215
|
font-weight: 600;
|
|
178
216
|
}
|
|
179
217
|
|
|
180
|
-
[data-theme=
|
|
218
|
+
[data-theme="dark"] th {
|
|
181
219
|
background-color: var(--sl-color-gray-1);
|
|
182
220
|
}
|
|
183
221
|
|
|
184
|
-
ul,
|
|
222
|
+
ul,
|
|
223
|
+
ol {
|
|
185
224
|
padding-left: 1.5rem;
|
|
186
225
|
margin: 0 0 1rem;
|
|
187
226
|
}
|
|
@@ -199,7 +238,7 @@ blockquote {
|
|
|
199
238
|
border-radius: 0 var(--sl-border-radius) var(--sl-border-radius) 0;
|
|
200
239
|
}
|
|
201
240
|
|
|
202
|
-
[data-theme=
|
|
241
|
+
[data-theme="dark"] blockquote {
|
|
203
242
|
background-color: var(--sl-color-accent-low);
|
|
204
243
|
}
|
|
205
244
|
|
|
@@ -18,13 +18,13 @@ const LABELS: Record<AsideType, string> = {
|
|
|
18
18
|
};
|
|
19
19
|
|
|
20
20
|
/**
|
|
21
|
-
* <
|
|
21
|
+
* <litro-aside type="tip" title="Custom Title">
|
|
22
22
|
* Callout box with an icon and colored left border.
|
|
23
23
|
* Slot content is the body.
|
|
24
|
-
* </
|
|
24
|
+
* </litro-aside>
|
|
25
25
|
*/
|
|
26
|
-
@customElement('
|
|
27
|
-
export class
|
|
26
|
+
@customElement('litro-aside')
|
|
27
|
+
export class LitroAside extends LitElement {
|
|
28
28
|
static override properties = {
|
|
29
29
|
type: { type: String },
|
|
30
30
|
title: { type: String },
|
|
@@ -88,4 +88,4 @@ export class SlAside extends LitElement {
|
|
|
88
88
|
}
|
|
89
89
|
}
|
|
90
90
|
|
|
91
|
-
export default
|
|
91
|
+
export default LitroAside;
|
|
@@ -4,12 +4,12 @@ import { customElement } from 'lit/decorators.js';
|
|
|
4
4
|
type BadgeVariant = 'note' | 'tip' | 'caution' | 'danger' | 'default';
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
|
-
* <
|
|
7
|
+
* <litro-badge variant="tip" text="New">
|
|
8
8
|
* Inline color-coded chip. Use `text` attribute or slot content.
|
|
9
|
-
* </
|
|
9
|
+
* </litro-badge>
|
|
10
10
|
*/
|
|
11
|
-
@customElement('
|
|
12
|
-
export class
|
|
11
|
+
@customElement('litro-badge')
|
|
12
|
+
export class LitroBadge extends LitElement {
|
|
13
13
|
static override properties = {
|
|
14
14
|
variant: { type: String },
|
|
15
15
|
text: { type: String },
|
|
@@ -73,4 +73,4 @@ export class SlBadge extends LitElement {
|
|
|
73
73
|
}
|
|
74
74
|
}
|
|
75
75
|
|
|
76
|
-
export default
|
|
76
|
+
export default LitroBadge;
|
|
@@ -2,13 +2,13 @@ import { LitElement, html, css } from 'lit';
|
|
|
2
2
|
import { customElement } from 'lit/decorators.js';
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
|
-
* <
|
|
6
|
-
* Responsive auto-fit grid for <
|
|
7
|
-
* Single slot — place <
|
|
8
|
-
* </
|
|
5
|
+
* <litro-card-grid>
|
|
6
|
+
* Responsive auto-fit grid for <litro-card> elements.
|
|
7
|
+
* Single slot — place <litro-card> elements directly inside.
|
|
8
|
+
* </litro-card-grid>
|
|
9
9
|
*/
|
|
10
|
-
@customElement('
|
|
11
|
-
export class
|
|
10
|
+
@customElement('litro-card-grid')
|
|
11
|
+
export class LitroCardGrid extends LitElement {
|
|
12
12
|
static override styles = css`
|
|
13
13
|
:host {
|
|
14
14
|
display: block;
|
|
@@ -31,4 +31,4 @@ export class SlCardGrid extends LitElement {
|
|
|
31
31
|
}
|
|
32
32
|
}
|
|
33
33
|
|
|
34
|
-
export default
|
|
34
|
+
export default LitroCardGrid;
|
|
@@ -2,28 +2,32 @@ import { LitElement, html, css } from 'lit';
|
|
|
2
2
|
import { customElement } from 'lit/decorators.js';
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
|
-
* <
|
|
5
|
+
* <litro-card title="Feature" description="Short desc" href="/docs/feature">
|
|
6
6
|
* Renders as an <a> when `href` is set, otherwise a <div>.
|
|
7
7
|
* Rotating accent color per nth-card via CSS counter.
|
|
8
|
-
* </
|
|
8
|
+
* </litro-card>
|
|
9
9
|
*/
|
|
10
|
-
@customElement('
|
|
11
|
-
export class
|
|
10
|
+
@customElement('litro-card')
|
|
11
|
+
export class LitroCard extends LitElement {
|
|
12
12
|
static override properties = {
|
|
13
13
|
title: { type: String },
|
|
14
14
|
description: { type: String },
|
|
15
15
|
icon: { type: String },
|
|
16
|
+
iconSrc: { type: String },
|
|
16
17
|
href: { type: String },
|
|
17
18
|
};
|
|
18
19
|
|
|
19
20
|
static override styles = css`
|
|
20
21
|
:host {
|
|
21
|
-
display:
|
|
22
|
+
display: flex;
|
|
23
|
+
flex-direction: column;
|
|
22
24
|
counter-increment: card;
|
|
23
25
|
}
|
|
24
26
|
|
|
25
27
|
.card {
|
|
26
|
-
display:
|
|
28
|
+
display: flex;
|
|
29
|
+
flex-direction: column;
|
|
30
|
+
flex: 1;
|
|
27
31
|
padding: 1.25rem 1.5rem;
|
|
28
32
|
border: 1px solid var(--sl-color-border, #e8e8e8);
|
|
29
33
|
border-radius: var(--sl-border-radius, 0.375rem);
|
|
@@ -45,16 +49,31 @@ export class SlCard extends LitElement {
|
|
|
45
49
|
transform: translateY(-2px);
|
|
46
50
|
}
|
|
47
51
|
|
|
52
|
+
.card-header {
|
|
53
|
+
display: flex;
|
|
54
|
+
align-items: center;
|
|
55
|
+
gap: 0.6rem;
|
|
56
|
+
margin-bottom: 0.4rem;
|
|
57
|
+
}
|
|
58
|
+
|
|
48
59
|
.card-icon {
|
|
49
|
-
font-size: 1.
|
|
50
|
-
|
|
60
|
+
font-size: 1.5rem;
|
|
61
|
+
flex-shrink: 0;
|
|
62
|
+
line-height: 1;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
.card-icon-img {
|
|
66
|
+
width: 1.5rem;
|
|
67
|
+
height: 1.5rem;
|
|
68
|
+
object-fit: contain;
|
|
69
|
+
flex-shrink: 0;
|
|
51
70
|
}
|
|
52
71
|
|
|
53
72
|
.card-title {
|
|
54
73
|
font-size: var(--sl-text-lg, 1.125rem);
|
|
55
74
|
font-weight: 600;
|
|
56
75
|
color: var(--sl-color-text, #23262f);
|
|
57
|
-
margin: 0
|
|
76
|
+
margin: 0;
|
|
58
77
|
}
|
|
59
78
|
|
|
60
79
|
.card-desc {
|
|
@@ -72,12 +91,17 @@ export class SlCard extends LitElement {
|
|
|
72
91
|
title = '';
|
|
73
92
|
description = '';
|
|
74
93
|
icon = '';
|
|
94
|
+
iconSrc = '';
|
|
75
95
|
href = '';
|
|
76
96
|
|
|
77
97
|
override render() {
|
|
78
98
|
const inner = html`
|
|
79
|
-
|
|
80
|
-
|
|
99
|
+
<div class="card-header">
|
|
100
|
+
${this.iconSrc
|
|
101
|
+
? html`<img class="card-icon-img" src="${this.iconSrc}" alt="" aria-hidden="true" />`
|
|
102
|
+
: this.icon ? html`<span class="card-icon">${this.icon}</span>` : ''}
|
|
103
|
+
<p class="card-title">${this.title}</p>
|
|
104
|
+
</div>
|
|
81
105
|
${this.description ? html`<p class="card-desc">${this.description}</p>` : ''}
|
|
82
106
|
<div class="card-slot"><slot></slot></div>
|
|
83
107
|
`;
|
|
@@ -88,4 +112,4 @@ export class SlCard extends LitElement {
|
|
|
88
112
|
}
|
|
89
113
|
}
|
|
90
114
|
|
|
91
|
-
export default
|
|
115
|
+
export default LitroCard;
|
|
@@ -2,13 +2,13 @@ import { LitElement, html, css } from 'lit';
|
|
|
2
2
|
import { customElement } from 'lit/decorators.js';
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
|
-
* <
|
|
6
|
-
* A single tab panel managed by a parent <
|
|
5
|
+
* <litro-tab-item label="Tab Label">
|
|
6
|
+
* A single tab panel managed by a parent <litro-tabs> element.
|
|
7
7
|
* Hidden automatically when not selected.
|
|
8
|
-
* </
|
|
8
|
+
* </litro-tab-item>
|
|
9
9
|
*/
|
|
10
|
-
@customElement('
|
|
11
|
-
export class
|
|
10
|
+
@customElement('litro-tab-item')
|
|
11
|
+
export class LitroTabItem extends LitElement {
|
|
12
12
|
static override properties = {
|
|
13
13
|
label: { type: String },
|
|
14
14
|
selected: { type: Boolean, reflect: true },
|
|
@@ -32,4 +32,4 @@ export class SlTabItem extends LitElement {
|
|
|
32
32
|
}
|
|
33
33
|
}
|
|
34
34
|
|
|
35
|
-
export default
|
|
35
|
+
export default LitroTabItem;
|
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
import { LitElement, html, css } from 'lit';
|
|
2
2
|
import { customElement } from 'lit/decorators.js';
|
|
3
|
-
import type {
|
|
3
|
+
import type { LitroTabItem } from './litro-tab-item.js';
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
|
-
* <
|
|
7
|
-
* <
|
|
8
|
-
* <
|
|
9
|
-
* </
|
|
6
|
+
* <litro-tabs>
|
|
7
|
+
* <litro-tab-item label="First">Content A</litro-tab-item>
|
|
8
|
+
* <litro-tab-item label="Second">Content B</litro-tab-item>
|
|
9
|
+
* </litro-tabs>
|
|
10
10
|
*
|
|
11
|
-
* Reads slotted <
|
|
11
|
+
* Reads slotted <litro-tab-item> elements via the slotchange event.
|
|
12
12
|
* Renders a tab bar in Shadow DOM; clicking selects the tab.
|
|
13
13
|
*/
|
|
14
|
-
@customElement('
|
|
15
|
-
export class
|
|
14
|
+
@customElement('litro-tabs')
|
|
15
|
+
export class LitroTabs extends LitElement {
|
|
16
16
|
static override properties = {
|
|
17
17
|
_labels: { type: Array, state: true },
|
|
18
18
|
_selectedIndex: { type: Number, state: true },
|
|
@@ -64,11 +64,11 @@ export class SlTabs extends LitElement {
|
|
|
64
64
|
_labels: string[] = [];
|
|
65
65
|
_selectedIndex = 0;
|
|
66
66
|
|
|
67
|
-
private _items():
|
|
67
|
+
private _items(): LitroTabItem[] {
|
|
68
68
|
const slot = this.shadowRoot?.querySelector('slot');
|
|
69
69
|
if (!slot) return [];
|
|
70
70
|
return slot.assignedElements().filter(
|
|
71
|
-
(el): el is
|
|
71
|
+
(el): el is LitroTabItem => el.tagName.toLowerCase() === 'litro-tab-item',
|
|
72
72
|
);
|
|
73
73
|
}
|
|
74
74
|
|
|
@@ -78,7 +78,7 @@ export class SlTabs extends LitElement {
|
|
|
78
78
|
this._selectIndex(this._selectedIndex < items.length ? this._selectedIndex : 0, items);
|
|
79
79
|
}
|
|
80
80
|
|
|
81
|
-
private _selectIndex(index: number, items?:
|
|
81
|
+
private _selectIndex(index: number, items?: LitroTabItem[]) {
|
|
82
82
|
const all = items ?? this._items();
|
|
83
83
|
this._selectedIndex = index;
|
|
84
84
|
all.forEach((item, i) => {
|
|
@@ -105,4 +105,4 @@ export class SlTabs extends LitElement {
|
|
|
105
105
|
}
|
|
106
106
|
}
|
|
107
107
|
|
|
108
|
-
export default
|
|
108
|
+
export default LitroTabs;
|