@alliance-droid/svelte-docs-system 0.0.2 → 0.1.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/README.md +155 -23
- package/dist/components/APITable.svelte.d.ts +21 -0
- package/dist/components/Breadcrumbs.svelte.d.ts +14 -0
- package/dist/components/Callout.svelte.d.ts +15 -0
- package/dist/components/CodeBlock.svelte.d.ts +12 -0
- package/{src/lib → dist}/components/DocLayout.svelte +18 -6
- package/dist/components/DocLayout.svelte.d.ts +18 -0
- package/dist/components/DocsPage.svelte +39 -0
- package/dist/components/DocsPage.svelte.d.ts +8 -0
- package/dist/components/Documentation.svelte +639 -0
- package/dist/components/Footer.svelte.d.ts +10 -0
- package/dist/components/Image.svelte.d.ts +15 -0
- package/{src/lib → dist}/components/Navbar.svelte +4 -4
- package/dist/components/Navbar.svelte.d.ts +10 -0
- package/{src/lib → dist}/components/Search.svelte +2 -2
- package/dist/components/Search.svelte.d.ts +6 -0
- package/{template-starter/src/lib → dist}/components/Sidebar.svelte +2 -2
- package/dist/components/Sidebar.svelte.d.ts +9 -0
- package/dist/components/Tabs.svelte.d.ts +16 -0
- package/dist/config.d.ts +93 -0
- package/dist/config.js +89 -0
- package/dist/configLoader.d.ts +48 -0
- package/dist/configLoader.js +187 -0
- package/dist/configParser.d.ts +27 -0
- package/dist/configParser.js +208 -0
- package/{template-starter/src/lib/index.ts → dist/index.d.ts} +6 -7
- package/dist/index.js +18 -0
- package/dist/navigationBuilder.d.ts +64 -0
- package/dist/navigationBuilder.js +225 -0
- package/dist/plugin.d.ts +30 -0
- package/dist/plugin.js +172 -0
- package/dist/routing.d.ts +48 -0
- package/dist/routing.js +92 -0
- package/dist/stores/i18n.d.ts +20 -0
- package/dist/stores/i18n.js +119 -0
- package/dist/stores/nav.d.ts +20 -0
- package/dist/stores/nav.js +15 -0
- package/dist/stores/search.d.ts +49 -0
- package/dist/stores/search.js +127 -0
- package/dist/stores/theme.d.ts +7 -0
- package/dist/stores/theme.js +152 -0
- package/dist/stores/version.d.ts +18 -0
- package/dist/stores/version.js +93 -0
- package/dist/themeCustomization.d.ts +46 -0
- package/dist/themeCustomization.js +188 -0
- package/dist/utils/highlight.d.ts +13 -0
- package/dist/utils/highlight.js +83 -0
- package/dist/utils/index.d.ts +1 -0
- package/dist/utils/index.js +1 -0
- package/dist/utils/markdown.d.ts +40 -0
- package/dist/utils/markdown.js +165 -0
- package/package.json +44 -23
- package/COMPONENTS.md +0 -365
- package/COVERAGE_REPORT.md +0 -663
- package/SEARCH_VERIFICATION.md +0 -229
- package/TEST_SUMMARY.md +0 -344
- package/bin/init.js +0 -821
- package/docs/COMPONENT_LIBRARY_INTEGRATION_REPORT.md +0 -153
- package/docs/DARK_MODE_AUDIT_REPORT.md +0 -403
- package/docs/E2E_TESTS.md +0 -354
- package/docs/TESTING.md +0 -754
- package/docs/THEME_INHERITANCE.md +0 -192
- package/docs/de/index.md +0 -41
- package/docs/en/COMPONENTS.md +0 -443
- package/docs/en/api/examples.md +0 -100
- package/docs/en/api/overview.md +0 -69
- package/docs/en/components/index.md +0 -622
- package/docs/en/config/navigation.md +0 -505
- package/docs/en/config/theme-and-colors.md +0 -395
- package/docs/en/getting-started/integration.md +0 -406
- package/docs/en/guides/common-setups.md +0 -651
- package/docs/en/index.md +0 -243
- package/docs/en/markdown.md +0 -102
- package/docs/en/routing.md +0 -64
- package/docs/en/setup.md +0 -52
- package/docs/en/troubleshooting.md +0 -704
- package/docs/es/index.md +0 -41
- package/docs/fr/index.md +0 -41
- package/docs/ja/index.md +0 -41
- package/pagefind.toml +0 -8
- package/postcss.config.js +0 -5
- package/src/app.css +0 -119
- package/src/app.d.ts +0 -13
- package/src/app.html +0 -11
- package/src/lib/components/APITable.test.ts +0 -153
- package/src/lib/components/Breadcrumbs.test.ts +0 -148
- package/src/lib/components/Callout.test.ts +0 -100
- package/src/lib/components/CodeBlock.test.ts +0 -133
- package/src/lib/components/Image.test.ts +0 -163
- package/src/lib/components/Sidebar.svelte +0 -110
- package/src/lib/components/Tabs.test.ts +0 -102
- package/src/lib/config.test.ts +0 -140
- package/src/lib/config.ts +0 -179
- package/src/lib/configIntegration.test.ts +0 -272
- package/src/lib/configLoader.ts +0 -231
- package/src/lib/configParser.test.ts +0 -217
- package/src/lib/configParser.ts +0 -234
- package/src/lib/index.ts +0 -37
- package/src/lib/integration.test.ts +0 -426
- package/src/lib/navigationBuilder.test.ts +0 -338
- package/src/lib/navigationBuilder.ts +0 -268
- package/src/lib/performance.test.ts +0 -369
- package/src/lib/routing.test.ts +0 -202
- package/src/lib/routing.ts +0 -127
- package/src/lib/search-functionality.test.ts +0 -493
- package/src/lib/stores/i18n.test.ts +0 -180
- package/src/lib/stores/i18n.ts +0 -143
- package/src/lib/stores/nav.ts +0 -36
- package/src/lib/stores/search.test.ts +0 -140
- package/src/lib/stores/search.ts +0 -162
- package/src/lib/stores/theme.test.ts +0 -117
- package/src/lib/stores/theme.ts +0 -167
- package/src/lib/stores/version.test.ts +0 -139
- package/src/lib/stores/version.ts +0 -111
- package/src/lib/themeCustomization.test.ts +0 -223
- package/src/lib/themeCustomization.ts +0 -212
- package/src/lib/utils/highlight.test.ts +0 -136
- package/src/lib/utils/highlight.ts +0 -100
- package/src/lib/utils/index.ts +0 -7
- package/src/lib/utils/markdown.test.ts +0 -357
- package/src/lib/utils/markdown.ts +0 -77
- package/src/routes/+layout.server.ts +0 -1
- package/src/routes/+layout.svelte +0 -29
- package/src/routes/+page.svelte +0 -165
- package/src/routes/quote-demo/+page.svelte +0 -141
- package/static/robots.txt +0 -3
- package/svelte.config.js +0 -15
- package/tailwind.config.ts +0 -55
- package/template-starter/.github/workflows/build.yml +0 -40
- package/template-starter/.github/workflows/deploy-github-pages.yml +0 -47
- package/template-starter/.github/workflows/deploy-netlify.yml +0 -41
- package/template-starter/.github/workflows/deploy-vercel.yml +0 -64
- package/template-starter/NPM-PACKAGE-SETUP.md +0 -233
- package/template-starter/README.md +0 -320
- package/template-starter/docs/_config.json +0 -39
- package/template-starter/docs/api/components.md +0 -257
- package/template-starter/docs/api/overview.md +0 -169
- package/template-starter/docs/guides/configuration.md +0 -145
- package/template-starter/docs/guides/github-pages-deployment.md +0 -254
- package/template-starter/docs/guides/netlify-deployment.md +0 -159
- package/template-starter/docs/guides/vercel-deployment.md +0 -131
- package/template-starter/docs/index.md +0 -49
- package/template-starter/docs/setup.md +0 -149
- package/template-starter/package.json +0 -31
- package/template-starter/pagefind.toml +0 -3
- package/template-starter/postcss.config.js +0 -5
- package/template-starter/src/app.css +0 -34
- package/template-starter/src/app.d.ts +0 -13
- package/template-starter/src/app.html +0 -11
- package/template-starter/src/lib/components/APITable.svelte +0 -120
- package/template-starter/src/lib/components/APITable.test.ts +0 -96
- package/template-starter/src/lib/components/Breadcrumbs.svelte +0 -85
- package/template-starter/src/lib/components/Breadcrumbs.test.ts +0 -82
- package/template-starter/src/lib/components/Callout.svelte +0 -60
- package/template-starter/src/lib/components/Callout.test.ts +0 -91
- package/template-starter/src/lib/components/CodeBlock.svelte +0 -68
- package/template-starter/src/lib/components/CodeBlock.test.ts +0 -62
- package/template-starter/src/lib/components/DocLayout.svelte +0 -84
- package/template-starter/src/lib/components/Footer.svelte +0 -78
- package/template-starter/src/lib/components/Image.svelte +0 -100
- package/template-starter/src/lib/components/Image.test.ts +0 -81
- package/template-starter/src/lib/components/Navbar.svelte +0 -141
- package/template-starter/src/lib/components/Search.svelte +0 -248
- package/template-starter/src/lib/components/Tabs.svelte +0 -48
- package/template-starter/src/lib/components/Tabs.test.ts +0 -89
- package/template-starter/src/routes/+layout.svelte +0 -28
- package/template-starter/src/routes/+page.svelte +0 -92
- package/template-starter/svelte.config.js +0 -17
- package/template-starter/tailwind.config.ts +0 -17
- package/template-starter/tsconfig.json +0 -13
- package/template-starter/vite.config.ts +0 -6
- package/tests/e2e/example.spec.ts +0 -345
- package/tsconfig.json +0 -20
- package/vite.config.ts +0 -6
- package/vitest.config.ts +0 -33
- package/vitest.setup.ts +0 -21
- /package/{src/lib → dist}/assets/favicon.svg +0 -0
- /package/{src/lib → dist}/components/APITable.svelte +0 -0
- /package/{src/lib → dist}/components/Breadcrumbs.svelte +0 -0
- /package/{src/lib → dist}/components/Callout.svelte +0 -0
- /package/{src/lib → dist}/components/CodeBlock.svelte +0 -0
- /package/{src/lib → dist}/components/Footer.svelte +0 -0
- /package/{src/lib → dist}/components/Image.svelte +0 -0
- /package/{src/lib → dist}/components/Tabs.svelte +0 -0
- /package/{src/lib → dist}/svelte-component-library.d.ts +0 -0
|
@@ -1,85 +0,0 @@
|
|
|
1
|
-
<script lang="ts">
|
|
2
|
-
/**
|
|
3
|
-
* Breadcrumbs navigation component
|
|
4
|
-
* Shows the current page path for easy navigation
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
interface BreadcrumbItem {
|
|
8
|
-
label: string;
|
|
9
|
-
href?: string;
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
interface Props {
|
|
13
|
-
items: BreadcrumbItem[];
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
let { items }: Props = $props();
|
|
17
|
-
</script>
|
|
18
|
-
|
|
19
|
-
<nav aria-label="Breadcrumb" class="mb-6">
|
|
20
|
-
<ol class="flex items-center gap-2 text-sm">
|
|
21
|
-
{#each items as item, index}
|
|
22
|
-
<li class="flex items-center gap-2">
|
|
23
|
-
{#if item.href && index < items.length - 1}
|
|
24
|
-
<a
|
|
25
|
-
href={item.href}
|
|
26
|
-
class="text-blue-600 hover:text-blue-700 dark:text-blue-400 dark:hover:text-blue-300"
|
|
27
|
-
>
|
|
28
|
-
{item.label}
|
|
29
|
-
</a>
|
|
30
|
-
{:else}
|
|
31
|
-
<span class={index === items.length - 1 ? 'font-semibold text-gray-900 dark:text-white' : 'text-gray-600 dark:text-gray-400'}>
|
|
32
|
-
{item.label}
|
|
33
|
-
</span>
|
|
34
|
-
{/if}
|
|
35
|
-
|
|
36
|
-
{#if index < items.length - 1}
|
|
37
|
-
<i class="fa-solid fa-chevron-right text-gray-400 dark:text-gray-500"></i>
|
|
38
|
-
{/if}
|
|
39
|
-
</li>
|
|
40
|
-
{/each}
|
|
41
|
-
</ol>
|
|
42
|
-
</nav>
|
|
43
|
-
|
|
44
|
-
<style>
|
|
45
|
-
nav {
|
|
46
|
-
margin-bottom: 1.5rem;
|
|
47
|
-
font-size: 0.875rem;
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
ol {
|
|
51
|
-
display: flex;
|
|
52
|
-
align-items: center;
|
|
53
|
-
gap: 0.5rem;
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
li {
|
|
57
|
-
display: flex;
|
|
58
|
-
align-items: center;
|
|
59
|
-
gap: 0.5rem;
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
a {
|
|
63
|
-
color: #2563eb;
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
a:hover {
|
|
67
|
-
color: #1d4ed8;
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
:global(.dark) a {
|
|
71
|
-
color: #60a5fa;
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
:global(.dark) a:hover {
|
|
75
|
-
color: #93c5fd;
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
span {
|
|
79
|
-
color: #4b5563;
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
:global(.dark) span {
|
|
83
|
-
color: #9ca3af;
|
|
84
|
-
}
|
|
85
|
-
</style>
|
|
@@ -1,82 +0,0 @@
|
|
|
1
|
-
import { describe, it, expect } from 'vitest';
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Unit tests for Breadcrumbs component
|
|
5
|
-
* Tests component configuration and prop handling
|
|
6
|
-
*/
|
|
7
|
-
|
|
8
|
-
describe('Breadcrumbs Component', () => {
|
|
9
|
-
describe('Props', () => {
|
|
10
|
-
it('renders all breadcrumb items', () => {
|
|
11
|
-
const items = [
|
|
12
|
-
{ label: 'Home', href: '/' },
|
|
13
|
-
{ label: 'Docs', href: '/docs' },
|
|
14
|
-
{ label: 'API' }
|
|
15
|
-
];
|
|
16
|
-
|
|
17
|
-
expect(items.length).toBe(3);
|
|
18
|
-
expect(items[0].label).toBe('Home');
|
|
19
|
-
expect(items[1].label).toBe('Docs');
|
|
20
|
-
expect(items[2].label).toBe('API');
|
|
21
|
-
});
|
|
22
|
-
|
|
23
|
-
it('should accept items array prop', () => {
|
|
24
|
-
const items = [
|
|
25
|
-
{ label: 'Home', href: '/' },
|
|
26
|
-
{ label: 'Section', href: '/section' }
|
|
27
|
-
];
|
|
28
|
-
expect(Array.isArray(items)).toBe(true);
|
|
29
|
-
expect(items.length).toBeGreaterThan(0);
|
|
30
|
-
});
|
|
31
|
-
|
|
32
|
-
it('should handle breadcrumb items with and without href', () => {
|
|
33
|
-
const items = [
|
|
34
|
-
{ label: 'Home', href: '/' },
|
|
35
|
-
{ label: 'Current Page' } // No href for current page
|
|
36
|
-
];
|
|
37
|
-
expect(items[0].href).toBeDefined();
|
|
38
|
-
expect(items[1].href).toBeUndefined();
|
|
39
|
-
});
|
|
40
|
-
|
|
41
|
-
it('should display correct breadcrumb text', () => {
|
|
42
|
-
const items = [
|
|
43
|
-
{ label: 'Docs', href: '/docs' },
|
|
44
|
-
{ label: 'Guides', href: '/docs/guides' },
|
|
45
|
-
{ label: 'Getting Started' }
|
|
46
|
-
];
|
|
47
|
-
const labels = items.map((item) => item.label);
|
|
48
|
-
expect(labels).toContain('Docs');
|
|
49
|
-
expect(labels).toContain('Guides');
|
|
50
|
-
expect(labels).toContain('Getting Started');
|
|
51
|
-
});
|
|
52
|
-
});
|
|
53
|
-
|
|
54
|
-
describe('Functionality', () => {
|
|
55
|
-
it('should have separator between items', () => {
|
|
56
|
-
const separatorConfig = {
|
|
57
|
-
text: '/',
|
|
58
|
-
ariaLabel: 'separator'
|
|
59
|
-
};
|
|
60
|
-
expect(separatorConfig.text).toBeTruthy();
|
|
61
|
-
expect(separatorConfig.ariaLabel).toBeTruthy();
|
|
62
|
-
});
|
|
63
|
-
|
|
64
|
-
it('should mark last item as current page', () => {
|
|
65
|
-
const items = [
|
|
66
|
-
{ label: 'Home', href: '/' },
|
|
67
|
-
{ label: 'Documentation' } // Last item, no href
|
|
68
|
-
];
|
|
69
|
-
const lastItem = items[items.length - 1];
|
|
70
|
-
expect(lastItem.href).toBeUndefined();
|
|
71
|
-
});
|
|
72
|
-
|
|
73
|
-
it('should be accessible with proper structure', () => {
|
|
74
|
-
const items = [
|
|
75
|
-
{ label: 'Home', href: '/' },
|
|
76
|
-
{ label: 'Docs', href: '/docs' },
|
|
77
|
-
{ label: 'API' }
|
|
78
|
-
];
|
|
79
|
-
expect(items.every((item) => item.label)).toBe(true);
|
|
80
|
-
});
|
|
81
|
-
});
|
|
82
|
-
});
|
|
@@ -1,60 +0,0 @@
|
|
|
1
|
-
<script lang="ts">
|
|
2
|
-
/**
|
|
3
|
-
* Callout component for documentation
|
|
4
|
-
* Displays alert boxes with different variants: info, warning, success, error
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
type Variant = 'info' | 'warning' | 'success' | 'error';
|
|
8
|
-
|
|
9
|
-
interface Props {
|
|
10
|
-
variant?: Variant;
|
|
11
|
-
title?: string;
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
let { variant = 'info', title, children }: Props & { children?: any } = $props();
|
|
15
|
-
|
|
16
|
-
const variantConfig: Record<Variant, { bgColor: string; borderColor: string; textColor: string; iconClass: string }> = {
|
|
17
|
-
info: {
|
|
18
|
-
bgColor: 'bg-blue-50 dark:bg-blue-900/20',
|
|
19
|
-
borderColor: 'border-blue-200 dark:border-blue-700',
|
|
20
|
-
textColor: 'text-blue-900 dark:text-blue-100',
|
|
21
|
-
iconClass: 'fa-circle-info text-blue-500'
|
|
22
|
-
},
|
|
23
|
-
warning: {
|
|
24
|
-
bgColor: 'bg-amber-50 dark:bg-amber-900/20',
|
|
25
|
-
borderColor: 'border-amber-200 dark:border-amber-700',
|
|
26
|
-
textColor: 'text-amber-900 dark:text-amber-100',
|
|
27
|
-
iconClass: 'fa-triangle-exclamation text-amber-500'
|
|
28
|
-
},
|
|
29
|
-
success: {
|
|
30
|
-
bgColor: 'bg-green-50 dark:bg-green-900/20',
|
|
31
|
-
borderColor: 'border-green-200 dark:border-green-700',
|
|
32
|
-
textColor: 'text-green-900 dark:text-green-100',
|
|
33
|
-
iconClass: 'fa-circle-check text-green-500'
|
|
34
|
-
},
|
|
35
|
-
error: {
|
|
36
|
-
bgColor: 'bg-red-50 dark:bg-red-900/20',
|
|
37
|
-
borderColor: 'border-red-200 dark:border-red-700',
|
|
38
|
-
textColor: 'text-red-900 dark:text-red-100',
|
|
39
|
-
iconClass: 'fa-circle-xmark text-red-500'
|
|
40
|
-
}
|
|
41
|
-
};
|
|
42
|
-
|
|
43
|
-
const config = $derived(variantConfig[variant]);
|
|
44
|
-
</script>
|
|
45
|
-
|
|
46
|
-
<div class="my-4 rounded-lg border-l-4 p-4 {config.bgColor} {config.borderColor} {config.textColor}">
|
|
47
|
-
<div class="flex items-start gap-3">
|
|
48
|
-
<i class="fa-solid {config.iconClass} mt-0.5 flex-shrink-0"></i>
|
|
49
|
-
<div class="flex-1">
|
|
50
|
-
{#if title}
|
|
51
|
-
<h4 class="font-semibold">{title}</h4>
|
|
52
|
-
{/if}
|
|
53
|
-
<div class="text-sm">
|
|
54
|
-
{#if children}
|
|
55
|
-
{@render children()}
|
|
56
|
-
{/if}
|
|
57
|
-
</div>
|
|
58
|
-
</div>
|
|
59
|
-
</div>
|
|
60
|
-
</div>
|
|
@@ -1,91 +0,0 @@
|
|
|
1
|
-
import { describe, it, expect } from 'vitest';
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Unit tests for Callout component
|
|
5
|
-
* Tests component configuration and prop handling
|
|
6
|
-
*/
|
|
7
|
-
|
|
8
|
-
describe('Callout Component', () => {
|
|
9
|
-
describe('Variant Configuration', () => {
|
|
10
|
-
const variantConfig = {
|
|
11
|
-
info: {
|
|
12
|
-
bgColor: 'bg-blue-50 dark:bg-blue-900/20',
|
|
13
|
-
borderColor: 'border-blue-200 dark:border-blue-700',
|
|
14
|
-
textColor: 'text-blue-900 dark:text-blue-100',
|
|
15
|
-
iconClass: 'fa-circle-info text-blue-500'
|
|
16
|
-
},
|
|
17
|
-
warning: {
|
|
18
|
-
bgColor: 'bg-amber-50 dark:bg-amber-900/20',
|
|
19
|
-
borderColor: 'border-amber-200 dark:border-amber-700',
|
|
20
|
-
textColor: 'text-amber-900 dark:text-amber-100',
|
|
21
|
-
iconClass: 'fa-triangle-exclamation text-amber-500'
|
|
22
|
-
},
|
|
23
|
-
success: {
|
|
24
|
-
bgColor: 'bg-green-50 dark:bg-green-900/20',
|
|
25
|
-
borderColor: 'border-green-200 dark:border-green-700',
|
|
26
|
-
textColor: 'text-green-900 dark:text-green-100',
|
|
27
|
-
iconClass: 'fa-circle-check text-green-500'
|
|
28
|
-
},
|
|
29
|
-
error: {
|
|
30
|
-
bgColor: 'bg-red-50 dark:bg-red-900/20',
|
|
31
|
-
borderColor: 'border-red-200 dark:border-red-700',
|
|
32
|
-
textColor: 'text-red-900 dark:text-red-100',
|
|
33
|
-
iconClass: 'fa-circle-xmark text-red-500'
|
|
34
|
-
}
|
|
35
|
-
};
|
|
36
|
-
|
|
37
|
-
it('renders with info variant by default', () => {
|
|
38
|
-
expect(variantConfig.info).toBeDefined();
|
|
39
|
-
expect(variantConfig.info.bgColor).toBe('bg-blue-50 dark:bg-blue-900/20');
|
|
40
|
-
expect(variantConfig.info.iconClass).toContain('circle-info');
|
|
41
|
-
});
|
|
42
|
-
|
|
43
|
-
it('supports all variant types', () => {
|
|
44
|
-
const variants = ['info', 'warning', 'success', 'error'] as const;
|
|
45
|
-
variants.forEach((variant) => {
|
|
46
|
-
expect(variantConfig[variant]).toBeDefined();
|
|
47
|
-
expect(variantConfig[variant].bgColor).toBeTruthy();
|
|
48
|
-
expect(variantConfig[variant].borderColor).toBeTruthy();
|
|
49
|
-
expect(variantConfig[variant].textColor).toBeTruthy();
|
|
50
|
-
expect(variantConfig[variant].iconClass).toBeTruthy();
|
|
51
|
-
});
|
|
52
|
-
});
|
|
53
|
-
|
|
54
|
-
it('has correct icon classes for each variant', () => {
|
|
55
|
-
expect(variantConfig.info.iconClass).toContain('circle-info');
|
|
56
|
-
expect(variantConfig.warning.iconClass).toContain('triangle-exclamation');
|
|
57
|
-
expect(variantConfig.success.iconClass).toContain('circle-check');
|
|
58
|
-
expect(variantConfig.error.iconClass).toContain('circle-xmark');
|
|
59
|
-
});
|
|
60
|
-
|
|
61
|
-
it('includes dark mode support in all styles', () => {
|
|
62
|
-
Object.values(variantConfig).forEach((config) => {
|
|
63
|
-
expect(config.bgColor).toMatch(/dark:/);
|
|
64
|
-
expect(config.borderColor).toMatch(/dark:/);
|
|
65
|
-
expect(config.textColor).toMatch(/dark:/);
|
|
66
|
-
});
|
|
67
|
-
});
|
|
68
|
-
});
|
|
69
|
-
|
|
70
|
-
describe('Props', () => {
|
|
71
|
-
it('should accept optional title prop', () => {
|
|
72
|
-
const props = {
|
|
73
|
-
title: 'Important Note',
|
|
74
|
-
variant: 'info' as const
|
|
75
|
-
};
|
|
76
|
-
expect(props.title).toBeDefined();
|
|
77
|
-
expect(typeof props.title).toBe('string');
|
|
78
|
-
});
|
|
79
|
-
|
|
80
|
-
it('should accept children slot', () => {
|
|
81
|
-
const hasChildren = true;
|
|
82
|
-
expect(hasChildren).toBe(true);
|
|
83
|
-
});
|
|
84
|
-
|
|
85
|
-
it('should accept variant prop', () => {
|
|
86
|
-
const validVariants = ['info', 'warning', 'success', 'error'] as const;
|
|
87
|
-
const variant: typeof validVariants[number] = 'warning';
|
|
88
|
-
expect(validVariants).toContain(variant);
|
|
89
|
-
});
|
|
90
|
-
});
|
|
91
|
-
});
|
|
@@ -1,68 +0,0 @@
|
|
|
1
|
-
<script lang="ts">
|
|
2
|
-
/**
|
|
3
|
-
* CodeBlock component with copy button
|
|
4
|
-
* Shows code with optional language label
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
interface Props {
|
|
8
|
-
code: string;
|
|
9
|
-
language?: string;
|
|
10
|
-
filename?: string;
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
let { code, language = 'plaintext', filename }: Props = $props();
|
|
14
|
-
|
|
15
|
-
let copied = $state(false);
|
|
16
|
-
|
|
17
|
-
function copyToClipboard() {
|
|
18
|
-
navigator.clipboard.writeText(code);
|
|
19
|
-
copied = true;
|
|
20
|
-
setTimeout(() => {
|
|
21
|
-
copied = false;
|
|
22
|
-
}, 2000);
|
|
23
|
-
}
|
|
24
|
-
</script>
|
|
25
|
-
|
|
26
|
-
<div class="my-4 overflow-hidden rounded-lg border border-gray-200 bg-gray-50 dark:border-gray-700 dark:bg-gray-900">
|
|
27
|
-
{#if filename}
|
|
28
|
-
<div class="flex items-center justify-between bg-gray-200 px-4 py-2 dark:bg-gray-800">
|
|
29
|
-
<span class="text-sm font-mono font-semibold text-gray-700 dark:text-gray-300">{filename}</span>
|
|
30
|
-
{#if language}
|
|
31
|
-
<span class="text-xs text-gray-600 dark:text-gray-400">{language}</span>
|
|
32
|
-
{/if}
|
|
33
|
-
</div>
|
|
34
|
-
{/if}
|
|
35
|
-
|
|
36
|
-
<div class="relative">
|
|
37
|
-
<button
|
|
38
|
-
onclick={copyToClipboard}
|
|
39
|
-
class="absolute right-2 top-2 rounded bg-gray-300 px-3 py-1 text-xs font-semibold text-gray-700 hover:bg-gray-400 dark:bg-gray-700 dark:text-gray-200 dark:hover:bg-gray-600 transition-colors"
|
|
40
|
-
>
|
|
41
|
-
{#if copied}
|
|
42
|
-
<i class="fa-solid fa-check mr-1"></i>Copied!
|
|
43
|
-
{:else}
|
|
44
|
-
<i class="fa-solid fa-copy mr-1"></i>Copy
|
|
45
|
-
{/if}
|
|
46
|
-
</button>
|
|
47
|
-
|
|
48
|
-
<pre class="overflow-x-auto p-4 font-mono text-sm text-gray-800 dark:text-gray-100"><code>{code}</code></pre>
|
|
49
|
-
</div>
|
|
50
|
-
</div>
|
|
51
|
-
|
|
52
|
-
<style>
|
|
53
|
-
pre {
|
|
54
|
-
background-color: transparent;
|
|
55
|
-
padding: 1rem;
|
|
56
|
-
overflow-x: auto;
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
code {
|
|
60
|
-
font-family: 'Courier New', monospace;
|
|
61
|
-
font-size: 0.875rem;
|
|
62
|
-
color: #1f2937;
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
:global(.dark) code {
|
|
66
|
-
color: #f3f4f6;
|
|
67
|
-
}
|
|
68
|
-
</style>
|
|
@@ -1,62 +0,0 @@
|
|
|
1
|
-
import { describe, it, expect } from 'vitest';
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Unit tests for CodeBlock component
|
|
5
|
-
* Tests component configuration and prop handling
|
|
6
|
-
*/
|
|
7
|
-
|
|
8
|
-
describe('CodeBlock Component', () => {
|
|
9
|
-
describe('Props', () => {
|
|
10
|
-
it('renders code content', () => {
|
|
11
|
-
const code = 'console.log("Hello");';
|
|
12
|
-
expect(code).toContain('Hello');
|
|
13
|
-
});
|
|
14
|
-
|
|
15
|
-
it('should accept code prop', () => {
|
|
16
|
-
const code = 'const x = 42;';
|
|
17
|
-
expect(typeof code).toBe('string');
|
|
18
|
-
expect(code).toBeTruthy();
|
|
19
|
-
});
|
|
20
|
-
|
|
21
|
-
it('should accept optional language prop', () => {
|
|
22
|
-
const language = 'javascript';
|
|
23
|
-
expect(['plaintext', 'javascript', 'typescript', 'python', 'html', 'css']).toContain(language);
|
|
24
|
-
});
|
|
25
|
-
|
|
26
|
-
it('should accept optional filename prop', () => {
|
|
27
|
-
const filename = 'example.js';
|
|
28
|
-
expect(typeof filename).toBe('string');
|
|
29
|
-
expect(filename).toMatch(/\.\w+$/);
|
|
30
|
-
});
|
|
31
|
-
|
|
32
|
-
it('should have default language as plaintext', () => {
|
|
33
|
-
const defaultLanguage = 'plaintext';
|
|
34
|
-
expect(defaultLanguage).toBe('plaintext');
|
|
35
|
-
});
|
|
36
|
-
});
|
|
37
|
-
|
|
38
|
-
describe('Functionality', () => {
|
|
39
|
-
it('should support copy to clipboard functionality', () => {
|
|
40
|
-
const code = 'console.log("test");';
|
|
41
|
-
expect(code).toBeTruthy();
|
|
42
|
-
// Copy functionality is client-side only
|
|
43
|
-
});
|
|
44
|
-
|
|
45
|
-
it('should handle code with special characters', () => {
|
|
46
|
-
const code = 'const obj = { key: "value" };';
|
|
47
|
-
expect(code).toContain('key');
|
|
48
|
-
expect(code).toContain('value');
|
|
49
|
-
});
|
|
50
|
-
|
|
51
|
-
it('should display filename and language', () => {
|
|
52
|
-
const props = {
|
|
53
|
-
code: 'import React from "react";',
|
|
54
|
-
language: 'jsx',
|
|
55
|
-
filename: 'App.jsx'
|
|
56
|
-
};
|
|
57
|
-
expect(props.filename).toBe('App.jsx');
|
|
58
|
-
expect(props.language).toBe('jsx');
|
|
59
|
-
expect(props.code).toBeTruthy();
|
|
60
|
-
});
|
|
61
|
-
});
|
|
62
|
-
});
|
|
@@ -1,84 +0,0 @@
|
|
|
1
|
-
<script lang="ts">
|
|
2
|
-
import { onMount } from 'svelte';
|
|
3
|
-
import { theme } from '$lib/stores/theme';
|
|
4
|
-
import Navbar from './Navbar.svelte';
|
|
5
|
-
import Sidebar from './Sidebar.svelte';
|
|
6
|
-
import Footer from './Footer.svelte';
|
|
7
|
-
import type { NavSection } from '$lib/stores/nav';
|
|
8
|
-
|
|
9
|
-
let {
|
|
10
|
-
title = 'Documentation',
|
|
11
|
-
logo = null,
|
|
12
|
-
sections = [] as NavSection[],
|
|
13
|
-
copyright = '© 2026 Documentation System',
|
|
14
|
-
footerLinks = [] as { label: string; href: string }[],
|
|
15
|
-
children,
|
|
16
|
-
}: {
|
|
17
|
-
title?: string;
|
|
18
|
-
logo?: string | null;
|
|
19
|
-
sections?: NavSection[];
|
|
20
|
-
copyright?: string;
|
|
21
|
-
footerLinks?: { label: string; href: string }[];
|
|
22
|
-
children: any;
|
|
23
|
-
} = $props();
|
|
24
|
-
|
|
25
|
-
let currentPath = $state('/');
|
|
26
|
-
let isMounted = $state(false);
|
|
27
|
-
|
|
28
|
-
onMount(() => {
|
|
29
|
-
// Initialize theme on mount
|
|
30
|
-
const storedTheme = localStorage.getItem('theme') as 'light' | 'dark' | null;
|
|
31
|
-
if (storedTheme) {
|
|
32
|
-
theme.set(storedTheme);
|
|
33
|
-
} else if (window.matchMedia('(prefers-color-scheme: dark)').matches) {
|
|
34
|
-
theme.set('dark');
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
isMounted = true;
|
|
38
|
-
|
|
39
|
-
// Update currentPath
|
|
40
|
-
currentPath = window.location.pathname;
|
|
41
|
-
|
|
42
|
-
// Listen to route changes
|
|
43
|
-
const handleNavigation = () => {
|
|
44
|
-
currentPath = window.location.pathname;
|
|
45
|
-
};
|
|
46
|
-
|
|
47
|
-
window.addEventListener('popstate', handleNavigation);
|
|
48
|
-
return () => {
|
|
49
|
-
window.removeEventListener('popstate', handleNavigation);
|
|
50
|
-
};
|
|
51
|
-
});
|
|
52
|
-
|
|
53
|
-
function handleNavigate(path: string) {
|
|
54
|
-
currentPath = path;
|
|
55
|
-
window.history.pushState(null, '', path);
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
function handleLogoClick() {
|
|
59
|
-
handleNavigate('/');
|
|
60
|
-
}
|
|
61
|
-
</script>
|
|
62
|
-
|
|
63
|
-
<div class="min-h-screen flex flex-col bg-white dark:bg-claude-dark-bg text-claude-text dark:text-claude-dark-text transition-colors">
|
|
64
|
-
<!-- Navbar -->
|
|
65
|
-
<Navbar {title} {logo} onLogoClick={handleLogoClick} />
|
|
66
|
-
|
|
67
|
-
<!-- Main Content Area -->
|
|
68
|
-
<div class="flex flex-1 overflow-hidden">
|
|
69
|
-
<!-- Sidebar -->
|
|
70
|
-
<Sidebar {sections} {currentPath} onNavigate={handleNavigate} />
|
|
71
|
-
|
|
72
|
-
<!-- Main Content -->
|
|
73
|
-
<main class="flex-1 overflow-y-auto">
|
|
74
|
-
<div class="doc-container max-w-4xl mx-auto px-4 sm:px-6 py-8">
|
|
75
|
-
<article class="doc-content">
|
|
76
|
-
{@render children()}
|
|
77
|
-
</article>
|
|
78
|
-
</div>
|
|
79
|
-
</main>
|
|
80
|
-
</div>
|
|
81
|
-
|
|
82
|
-
<!-- Footer -->
|
|
83
|
-
<Footer {copyright} links={footerLinks} />
|
|
84
|
-
</div>
|
|
@@ -1,78 +0,0 @@
|
|
|
1
|
-
<script lang="ts">
|
|
2
|
-
let {
|
|
3
|
-
copyright = '© 2026 Documentation System',
|
|
4
|
-
links = [] as { label: string; href: string }[],
|
|
5
|
-
}: {
|
|
6
|
-
copyright?: string;
|
|
7
|
-
links?: { label: string; href: string }[];
|
|
8
|
-
} = $props();
|
|
9
|
-
</script>
|
|
10
|
-
|
|
11
|
-
<footer class="border-t border-claude-border dark:border-claude-dark-border bg-white dark:bg-claude-dark-bg-secondary mt-12">
|
|
12
|
-
<div class="doc-container px-4 sm:px-6 py-8">
|
|
13
|
-
<div class="grid grid-cols-1 md:grid-cols-3 gap-8 mb-8">
|
|
14
|
-
<!-- About Section -->
|
|
15
|
-
<div>
|
|
16
|
-
<h3 class="font-semibold text-claude-text dark:text-claude-dark-text mb-4">About</h3>
|
|
17
|
-
<p class="text-sm text-claude-text-secondary dark:text-claude-dark-text-secondary">
|
|
18
|
-
Professional documentation system built with SvelteKit and Tailwind CSS.
|
|
19
|
-
</p>
|
|
20
|
-
</div>
|
|
21
|
-
|
|
22
|
-
<!-- Links Section -->
|
|
23
|
-
{#if links.length > 0}
|
|
24
|
-
<div>
|
|
25
|
-
<h3 class="font-semibold text-claude-text dark:text-claude-dark-text mb-4">Resources</h3>
|
|
26
|
-
<ul class="space-y-2">
|
|
27
|
-
{#each links as link (link.label)}
|
|
28
|
-
<li>
|
|
29
|
-
<a
|
|
30
|
-
href={link.href}
|
|
31
|
-
class="text-sm text-claude-accent dark:text-claude-dark-accent hover:underline transition-colors"
|
|
32
|
-
>
|
|
33
|
-
{link.label}
|
|
34
|
-
</a>
|
|
35
|
-
</li>
|
|
36
|
-
{/each}
|
|
37
|
-
</ul>
|
|
38
|
-
</div>
|
|
39
|
-
{/if}
|
|
40
|
-
|
|
41
|
-
<!-- Social / Contact -->
|
|
42
|
-
<div>
|
|
43
|
-
<h3 class="font-semibold text-claude-text dark:text-claude-dark-text mb-4">Connect</h3>
|
|
44
|
-
<div class="flex gap-4">
|
|
45
|
-
<a
|
|
46
|
-
href="https://github.com"
|
|
47
|
-
target="_blank"
|
|
48
|
-
rel="noopener noreferrer"
|
|
49
|
-
class="text-claude-text-secondary dark:text-claude-dark-text-secondary hover:text-claude-accent dark:hover:text-claude-dark-accent transition-colors"
|
|
50
|
-
aria-label="GitHub"
|
|
51
|
-
>
|
|
52
|
-
<svg class="w-5 h-5" fill="currentColor" viewBox="0 0 24 24">
|
|
53
|
-
<path d="M12 0C5.37 0 0 5.37 0 12c0 5.31 3.435 9.795 8.205 11.385.6.105.825-.255.825-.57 0-.285-.015-1.23-.015-2.235-3.015.555-3.795-.735-4.035-1.41-.135-.345-.72-1.41-1.23-1.695-.42-.225-1.02-.78-.015-.795.945-.015 1.62.87 1.845 1.23 1.08 1.815 2.805 1.305 3.495.99.105-.78.42-1.305.765-1.605-2.67-.3-5.46-1.335-5.46-5.925 0-1.305.465-2.385 1.23-3.225-.12-.3-.54-1.53.12-3.18 0 0 1.005-.315 3.3 1.23.96-.27 1.98-.405 3-.405s2.04.135 3 .405c2.295-1.56 3.3-1.23 3.3-1.23.66 1.65.24 2.88.12 3.18.765.84 1.23 1.905 1.23 3.225 0 4.605-2.805 5.625-5.475 5.925.435.375.81 1.095.81 2.22 0 1.605-.015 2.895-.015 3.3 0 .315.225.69.825.57A12.01 12.01 0 0024 12c0-6.63-5.37-12-12-12z" />
|
|
54
|
-
</svg>
|
|
55
|
-
</a>
|
|
56
|
-
<a
|
|
57
|
-
href="https://twitter.com"
|
|
58
|
-
target="_blank"
|
|
59
|
-
rel="noopener noreferrer"
|
|
60
|
-
class="text-claude-text-secondary dark:text-claude-dark-text-secondary hover:text-claude-accent dark:hover:text-claude-dark-accent transition-colors"
|
|
61
|
-
aria-label="Twitter"
|
|
62
|
-
>
|
|
63
|
-
<svg class="w-5 h-5" fill="currentColor" viewBox="0 0 24 24">
|
|
64
|
-
<path d="M23.953 4.57a10 10 0 01-2.825.775 4.958 4.958 0 002.163-2.723c-.951.555-2.005.959-3.127 1.184a4.92 4.92 0 00-8.384 4.482C7.69 8.095 4.067 6.13 1.64 3.162a4.822 4.822 0 00-.666 2.475c0 1.71.87 3.213 2.188 4.096a4.904 4.904 0 01-2.228-.616v.06a4.923 4.923 0 003.946 4.827 4.996 4.996 0 01-2.212.085 4.936 4.936 0 004.604 3.417a9.867 9.867 0 01-6.102 2.105c-.39 0-.779-.023-1.17-.067a13.995 13.995 0 007.557 2.209c9.053 0 13.998-7.496 13.998-13.985 0-.21 0-.42-.015-.63A9.935 9.935 0 0024 4.59z" />
|
|
65
|
-
</svg>
|
|
66
|
-
</a>
|
|
67
|
-
</div>
|
|
68
|
-
</div>
|
|
69
|
-
</div>
|
|
70
|
-
|
|
71
|
-
<!-- Copyright -->
|
|
72
|
-
<div class="border-t border-claude-border dark:border-claude-dark-border pt-8">
|
|
73
|
-
<p class="text-sm text-claude-text-secondary dark:text-claude-dark-text-secondary text-center">
|
|
74
|
-
{copyright}
|
|
75
|
-
</p>
|
|
76
|
-
</div>
|
|
77
|
-
</div>
|
|
78
|
-
</footer>
|