@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.
Files changed (185) hide show
  1. package/README.md +155 -23
  2. package/dist/components/APITable.svelte.d.ts +21 -0
  3. package/dist/components/Breadcrumbs.svelte.d.ts +14 -0
  4. package/dist/components/Callout.svelte.d.ts +15 -0
  5. package/dist/components/CodeBlock.svelte.d.ts +12 -0
  6. package/{src/lib → dist}/components/DocLayout.svelte +18 -6
  7. package/dist/components/DocLayout.svelte.d.ts +18 -0
  8. package/dist/components/DocsPage.svelte +39 -0
  9. package/dist/components/DocsPage.svelte.d.ts +8 -0
  10. package/dist/components/Documentation.svelte +639 -0
  11. package/dist/components/Footer.svelte.d.ts +10 -0
  12. package/dist/components/Image.svelte.d.ts +15 -0
  13. package/{src/lib → dist}/components/Navbar.svelte +4 -4
  14. package/dist/components/Navbar.svelte.d.ts +10 -0
  15. package/{src/lib → dist}/components/Search.svelte +2 -2
  16. package/dist/components/Search.svelte.d.ts +6 -0
  17. package/{template-starter/src/lib → dist}/components/Sidebar.svelte +2 -2
  18. package/dist/components/Sidebar.svelte.d.ts +9 -0
  19. package/dist/components/Tabs.svelte.d.ts +16 -0
  20. package/dist/config.d.ts +93 -0
  21. package/dist/config.js +89 -0
  22. package/dist/configLoader.d.ts +48 -0
  23. package/dist/configLoader.js +187 -0
  24. package/dist/configParser.d.ts +27 -0
  25. package/dist/configParser.js +208 -0
  26. package/{template-starter/src/lib/index.ts → dist/index.d.ts} +6 -7
  27. package/dist/index.js +18 -0
  28. package/dist/navigationBuilder.d.ts +64 -0
  29. package/dist/navigationBuilder.js +225 -0
  30. package/dist/plugin.d.ts +30 -0
  31. package/dist/plugin.js +172 -0
  32. package/dist/routing.d.ts +48 -0
  33. package/dist/routing.js +92 -0
  34. package/dist/stores/i18n.d.ts +20 -0
  35. package/dist/stores/i18n.js +119 -0
  36. package/dist/stores/nav.d.ts +20 -0
  37. package/dist/stores/nav.js +15 -0
  38. package/dist/stores/search.d.ts +49 -0
  39. package/dist/stores/search.js +127 -0
  40. package/dist/stores/theme.d.ts +7 -0
  41. package/dist/stores/theme.js +152 -0
  42. package/dist/stores/version.d.ts +18 -0
  43. package/dist/stores/version.js +93 -0
  44. package/dist/themeCustomization.d.ts +46 -0
  45. package/dist/themeCustomization.js +188 -0
  46. package/dist/utils/highlight.d.ts +13 -0
  47. package/dist/utils/highlight.js +83 -0
  48. package/dist/utils/index.d.ts +1 -0
  49. package/dist/utils/index.js +1 -0
  50. package/dist/utils/markdown.d.ts +40 -0
  51. package/dist/utils/markdown.js +165 -0
  52. package/package.json +44 -23
  53. package/COMPONENTS.md +0 -365
  54. package/COVERAGE_REPORT.md +0 -663
  55. package/SEARCH_VERIFICATION.md +0 -229
  56. package/TEST_SUMMARY.md +0 -344
  57. package/bin/init.js +0 -821
  58. package/docs/COMPONENT_LIBRARY_INTEGRATION_REPORT.md +0 -153
  59. package/docs/DARK_MODE_AUDIT_REPORT.md +0 -403
  60. package/docs/E2E_TESTS.md +0 -354
  61. package/docs/TESTING.md +0 -754
  62. package/docs/THEME_INHERITANCE.md +0 -192
  63. package/docs/de/index.md +0 -41
  64. package/docs/en/COMPONENTS.md +0 -443
  65. package/docs/en/api/examples.md +0 -100
  66. package/docs/en/api/overview.md +0 -69
  67. package/docs/en/components/index.md +0 -622
  68. package/docs/en/config/navigation.md +0 -505
  69. package/docs/en/config/theme-and-colors.md +0 -395
  70. package/docs/en/getting-started/integration.md +0 -406
  71. package/docs/en/guides/common-setups.md +0 -651
  72. package/docs/en/index.md +0 -243
  73. package/docs/en/markdown.md +0 -102
  74. package/docs/en/routing.md +0 -64
  75. package/docs/en/setup.md +0 -52
  76. package/docs/en/troubleshooting.md +0 -704
  77. package/docs/es/index.md +0 -41
  78. package/docs/fr/index.md +0 -41
  79. package/docs/ja/index.md +0 -41
  80. package/pagefind.toml +0 -8
  81. package/postcss.config.js +0 -5
  82. package/src/app.css +0 -119
  83. package/src/app.d.ts +0 -13
  84. package/src/app.html +0 -11
  85. package/src/lib/components/APITable.test.ts +0 -153
  86. package/src/lib/components/Breadcrumbs.test.ts +0 -148
  87. package/src/lib/components/Callout.test.ts +0 -100
  88. package/src/lib/components/CodeBlock.test.ts +0 -133
  89. package/src/lib/components/Image.test.ts +0 -163
  90. package/src/lib/components/Sidebar.svelte +0 -110
  91. package/src/lib/components/Tabs.test.ts +0 -102
  92. package/src/lib/config.test.ts +0 -140
  93. package/src/lib/config.ts +0 -179
  94. package/src/lib/configIntegration.test.ts +0 -272
  95. package/src/lib/configLoader.ts +0 -231
  96. package/src/lib/configParser.test.ts +0 -217
  97. package/src/lib/configParser.ts +0 -234
  98. package/src/lib/index.ts +0 -37
  99. package/src/lib/integration.test.ts +0 -426
  100. package/src/lib/navigationBuilder.test.ts +0 -338
  101. package/src/lib/navigationBuilder.ts +0 -268
  102. package/src/lib/performance.test.ts +0 -369
  103. package/src/lib/routing.test.ts +0 -202
  104. package/src/lib/routing.ts +0 -127
  105. package/src/lib/search-functionality.test.ts +0 -493
  106. package/src/lib/stores/i18n.test.ts +0 -180
  107. package/src/lib/stores/i18n.ts +0 -143
  108. package/src/lib/stores/nav.ts +0 -36
  109. package/src/lib/stores/search.test.ts +0 -140
  110. package/src/lib/stores/search.ts +0 -162
  111. package/src/lib/stores/theme.test.ts +0 -117
  112. package/src/lib/stores/theme.ts +0 -167
  113. package/src/lib/stores/version.test.ts +0 -139
  114. package/src/lib/stores/version.ts +0 -111
  115. package/src/lib/themeCustomization.test.ts +0 -223
  116. package/src/lib/themeCustomization.ts +0 -212
  117. package/src/lib/utils/highlight.test.ts +0 -136
  118. package/src/lib/utils/highlight.ts +0 -100
  119. package/src/lib/utils/index.ts +0 -7
  120. package/src/lib/utils/markdown.test.ts +0 -357
  121. package/src/lib/utils/markdown.ts +0 -77
  122. package/src/routes/+layout.server.ts +0 -1
  123. package/src/routes/+layout.svelte +0 -29
  124. package/src/routes/+page.svelte +0 -165
  125. package/src/routes/quote-demo/+page.svelte +0 -141
  126. package/static/robots.txt +0 -3
  127. package/svelte.config.js +0 -15
  128. package/tailwind.config.ts +0 -55
  129. package/template-starter/.github/workflows/build.yml +0 -40
  130. package/template-starter/.github/workflows/deploy-github-pages.yml +0 -47
  131. package/template-starter/.github/workflows/deploy-netlify.yml +0 -41
  132. package/template-starter/.github/workflows/deploy-vercel.yml +0 -64
  133. package/template-starter/NPM-PACKAGE-SETUP.md +0 -233
  134. package/template-starter/README.md +0 -320
  135. package/template-starter/docs/_config.json +0 -39
  136. package/template-starter/docs/api/components.md +0 -257
  137. package/template-starter/docs/api/overview.md +0 -169
  138. package/template-starter/docs/guides/configuration.md +0 -145
  139. package/template-starter/docs/guides/github-pages-deployment.md +0 -254
  140. package/template-starter/docs/guides/netlify-deployment.md +0 -159
  141. package/template-starter/docs/guides/vercel-deployment.md +0 -131
  142. package/template-starter/docs/index.md +0 -49
  143. package/template-starter/docs/setup.md +0 -149
  144. package/template-starter/package.json +0 -31
  145. package/template-starter/pagefind.toml +0 -3
  146. package/template-starter/postcss.config.js +0 -5
  147. package/template-starter/src/app.css +0 -34
  148. package/template-starter/src/app.d.ts +0 -13
  149. package/template-starter/src/app.html +0 -11
  150. package/template-starter/src/lib/components/APITable.svelte +0 -120
  151. package/template-starter/src/lib/components/APITable.test.ts +0 -96
  152. package/template-starter/src/lib/components/Breadcrumbs.svelte +0 -85
  153. package/template-starter/src/lib/components/Breadcrumbs.test.ts +0 -82
  154. package/template-starter/src/lib/components/Callout.svelte +0 -60
  155. package/template-starter/src/lib/components/Callout.test.ts +0 -91
  156. package/template-starter/src/lib/components/CodeBlock.svelte +0 -68
  157. package/template-starter/src/lib/components/CodeBlock.test.ts +0 -62
  158. package/template-starter/src/lib/components/DocLayout.svelte +0 -84
  159. package/template-starter/src/lib/components/Footer.svelte +0 -78
  160. package/template-starter/src/lib/components/Image.svelte +0 -100
  161. package/template-starter/src/lib/components/Image.test.ts +0 -81
  162. package/template-starter/src/lib/components/Navbar.svelte +0 -141
  163. package/template-starter/src/lib/components/Search.svelte +0 -248
  164. package/template-starter/src/lib/components/Tabs.svelte +0 -48
  165. package/template-starter/src/lib/components/Tabs.test.ts +0 -89
  166. package/template-starter/src/routes/+layout.svelte +0 -28
  167. package/template-starter/src/routes/+page.svelte +0 -92
  168. package/template-starter/svelte.config.js +0 -17
  169. package/template-starter/tailwind.config.ts +0 -17
  170. package/template-starter/tsconfig.json +0 -13
  171. package/template-starter/vite.config.ts +0 -6
  172. package/tests/e2e/example.spec.ts +0 -345
  173. package/tsconfig.json +0 -20
  174. package/vite.config.ts +0 -6
  175. package/vitest.config.ts +0 -33
  176. package/vitest.setup.ts +0 -21
  177. /package/{src/lib → dist}/assets/favicon.svg +0 -0
  178. /package/{src/lib → dist}/components/APITable.svelte +0 -0
  179. /package/{src/lib → dist}/components/Breadcrumbs.svelte +0 -0
  180. /package/{src/lib → dist}/components/Callout.svelte +0 -0
  181. /package/{src/lib → dist}/components/CodeBlock.svelte +0 -0
  182. /package/{src/lib → dist}/components/Footer.svelte +0 -0
  183. /package/{src/lib → dist}/components/Image.svelte +0 -0
  184. /package/{src/lib → dist}/components/Tabs.svelte +0 -0
  185. /package/{src/lib → dist}/svelte-component-library.d.ts +0 -0
@@ -1,133 +0,0 @@
1
- import { describe, it, expect } from 'vitest';
2
-
3
- /**
4
- * Unit tests for CodeBlock component
5
- * Tests code formatting and syntax highlighting
6
- */
7
-
8
- describe('CodeBlock Component', () => {
9
- describe('Code Input', () => {
10
- it('should accept code as string', () => {
11
- const code = 'console.log("hello")';
12
- expect(typeof code).toBe('string');
13
- });
14
-
15
- it('should accept empty code string', () => {
16
- const code = '';
17
- expect(code.length).toBe(0);
18
- });
19
-
20
- it('should preserve whitespace and indentation', () => {
21
- const code = `function example() {
22
- return true;
23
- }`;
24
- expect(code).toContain(' ');
25
- expect(code).toContain('\n');
26
- });
27
-
28
- it('should handle special characters', () => {
29
- const code = 'const str = "hello<world>&friends";';
30
- expect(code).toContain('<');
31
- expect(code).toContain('>');
32
- expect(code).toContain('&');
33
- });
34
- });
35
-
36
- describe('Language Detection', () => {
37
- it('should support common programming languages', () => {
38
- const languages = ['javascript', 'typescript', 'python', 'rust', 'bash', 'json', 'html', 'css'];
39
- languages.forEach((lang) => {
40
- expect(typeof lang).toBe('string');
41
- expect(lang.length).toBeGreaterThan(0);
42
- });
43
- });
44
-
45
- it('should accept language as prop', () => {
46
- const language = 'typescript';
47
- expect(typeof language).toBe('string');
48
- });
49
-
50
- it('should default to plain text if language not provided', () => {
51
- const defaultLanguage = 'plaintext';
52
- expect(defaultLanguage).toBeDefined();
53
- });
54
-
55
- it('should detect language from code fence', () => {
56
- const fence = '```javascript';
57
- const match = fence.match(/```(\w+)?/);
58
- expect(match).toBeTruthy();
59
- if (match && match[1]) {
60
- expect(match[1]).toBe('javascript');
61
- }
62
- });
63
- });
64
-
65
- describe('Syntax Highlighting', () => {
66
- it('should apply syntax highlighting tokens', () => {
67
- const token = {
68
- type: 'keyword',
69
- content: 'function',
70
- class: 'hljs-keyword'
71
- };
72
- expect(token.type).toBeDefined();
73
- expect(token.content).toBeDefined();
74
- expect(token.class).toBeTruthy();
75
- });
76
-
77
- it('should support dark mode highlighting', () => {
78
- const colorSchemes = ['light', 'dark'];
79
- colorSchemes.forEach((scheme) => {
80
- expect(['light', 'dark']).toContain(scheme);
81
- });
82
- });
83
- });
84
-
85
- describe('Copy Button', () => {
86
- it('should have copy functionality', () => {
87
- const hasCopyButton = true;
88
- expect(hasCopyButton).toBe(true);
89
- });
90
-
91
- it('should copy entire code block', () => {
92
- const code = 'const x = 42;';
93
- const copied = code;
94
- expect(copied).toBe(code);
95
- });
96
- });
97
-
98
- describe('Line Numbers', () => {
99
- it('should support optional line numbers', () => {
100
- const showLineNumbers = true;
101
- expect(typeof showLineNumbers).toBe('boolean');
102
- });
103
-
104
- it('should number lines correctly', () => {
105
- const lines = [
106
- 'line 1',
107
- 'line 2',
108
- 'line 3'
109
- ];
110
- lines.forEach((line, index) => {
111
- expect(index + 1).toBeGreaterThan(0);
112
- });
113
- });
114
- });
115
-
116
- describe('Accessibility', () => {
117
- it('should be keyboard accessible', () => {
118
- const canCopyWithKeyboard = true;
119
- expect(canCopyWithKeyboard).toBe(true);
120
- });
121
-
122
- it('should have proper ARIA labels', () => {
123
- const ariaLabel = 'Code block, javascript';
124
- expect(ariaLabel).toBeTruthy();
125
- expect(typeof ariaLabel).toBe('string');
126
- });
127
-
128
- it('should announce copy feedback to screen readers', () => {
129
- const announcement = 'Code copied to clipboard';
130
- expect(announcement).toBeTruthy();
131
- });
132
- });
133
- });
@@ -1,163 +0,0 @@
1
- import { describe, it, expect } from 'vitest';
2
-
3
- /**
4
- * Unit tests for Image component
5
- * Tests image rendering, optimization, and accessibility
6
- */
7
-
8
- describe('Image Component', () => {
9
- describe('Image Props', () => {
10
- it('should require src attribute', () => {
11
- const src = '/images/example.png';
12
- expect(src).toBeDefined();
13
- expect(typeof src).toBe('string');
14
- expect(src.startsWith('/')).toBe(true);
15
- });
16
-
17
- it('should require alt text for accessibility', () => {
18
- const alt = 'A description of the image';
19
- expect(alt).toBeDefined();
20
- expect(typeof alt).toBe('string');
21
- expect(alt.length).toBeGreaterThan(0);
22
- });
23
-
24
- it('should accept various image formats', () => {
25
- const formats = ['.png', '.jpg', '.jpeg', '.gif', '.webp', '.svg'];
26
- const validSrc = 'image.webp';
27
- expect(formats.some((fmt) => validSrc.endsWith(fmt))).toBe(true);
28
- });
29
-
30
- it('should accept optional width and height', () => {
31
- const width = 800;
32
- const height = 600;
33
- expect(typeof width).toBe('number');
34
- expect(typeof height).toBe('number');
35
- expect(width).toBeGreaterThan(0);
36
- expect(height).toBeGreaterThan(0);
37
- });
38
-
39
- it('should accept optional caption', () => {
40
- const caption = 'Figure 1: Example screenshot';
41
- expect(typeof caption).toBe('string');
42
- });
43
- });
44
-
45
- describe('Image Optimization', () => {
46
- it('should support responsive images with srcset', () => {
47
- const srcset =
48
- '/img/small.webp 640w, /img/medium.webp 1024w, /img/large.webp 1920w';
49
- expect(srcset).toContain('640w');
50
- expect(srcset).toContain('1024w');
51
- expect(srcset).toContain('1920w');
52
- });
53
-
54
- it('should support multiple image formats with picture element', () => {
55
- const formats = ['webp', 'jpg', 'png'];
56
- formats.forEach((fmt) => {
57
- expect(['webp', 'jpg', 'png']).toContain(fmt);
58
- });
59
- });
60
-
61
- it('should lazy load images by default', () => {
62
- const loading = 'lazy';
63
- expect(['lazy', 'eager']).toContain(loading);
64
- });
65
-
66
- it('should support eager loading when needed', () => {
67
- const loading = 'eager';
68
- expect(['lazy', 'eager']).toContain(loading);
69
- });
70
- });
71
-
72
- describe('Responsive Behavior', () => {
73
- it('should support CSS aspect ratio', () => {
74
- const aspectRatio = '16/9';
75
- expect(aspectRatio).toContain('/');
76
- });
77
-
78
- it('should preserve aspect ratio', () => {
79
- const width = 800;
80
- const height = 600;
81
- const aspectRatio = width / height;
82
- expect(aspectRatio).toBeCloseTo(1.33, 1);
83
- });
84
-
85
- it('should scale to container width', () => {
86
- const maxWidth = '100%';
87
- expect(maxWidth).toBe('100%');
88
- });
89
- });
90
-
91
- describe('Figure and Caption', () => {
92
- it('should wrap in figure element', () => {
93
- const element = 'figure';
94
- expect(element).toBe('figure');
95
- });
96
-
97
- it('should support caption with figcaption', () => {
98
- const caption = 'Example figure caption';
99
- expect(caption).toBeTruthy();
100
- });
101
-
102
- it('should associate caption with image', () => {
103
- const figcaptionId = 'img-caption-1';
104
- const ariaDescribedBy = 'img-caption-1';
105
- expect(ariaDescribedBy).toBe(figcaptionId);
106
- });
107
- });
108
-
109
- describe('Accessibility', () => {
110
- it('should have descriptive alt text', () => {
111
- const alt = 'A screenshot showing the dashboard with user metrics';
112
- expect(alt.length).toBeGreaterThan(10);
113
- });
114
-
115
- it('should not have empty alt text', () => {
116
- const alt = 'Important diagram';
117
- expect(alt.length).toBeGreaterThan(0);
118
- });
119
-
120
- it('should avoid decorative image alt text', () => {
121
- const decorativeAlt = 'spacer';
122
- const meaningfulAlt = 'Navigation menu icon';
123
- expect(meaningfulAlt.length).toBeGreaterThan(decorativeAlt.length);
124
- });
125
-
126
- it('should have proper figure structure', () => {
127
- const figureElement = 'figure';
128
- const figcaptionElement = 'figcaption';
129
- expect(figureElement).toBeDefined();
130
- expect(figcaptionElement).toBeDefined();
131
- });
132
-
133
- it('should support extended descriptions for complex images', () => {
134
- const longdesc = '/docs/image-description.html';
135
- expect(longdesc).toBeTruthy();
136
- });
137
- });
138
-
139
- describe('Dark Mode Support', () => {
140
- it('should support dark mode styling', () => {
141
- const lightClass = 'border-gray-200';
142
- const darkClass = 'dark:border-gray-700';
143
- expect(darkClass).toContain('dark:');
144
- });
145
-
146
- it('should maintain contrast in dark mode', () => {
147
- const darkModeEnabled = true;
148
- expect(darkModeEnabled).toBe(true);
149
- });
150
- });
151
-
152
- describe('Browser Support', () => {
153
- it('should provide fallback for old browsers', () => {
154
- const hasFallback = true;
155
- expect(hasFallback).toBe(true);
156
- });
157
-
158
- it('should support webp with fallback', () => {
159
- const hasPicture = true;
160
- expect(hasPicture).toBe(true);
161
- });
162
- });
163
- });
@@ -1,110 +0,0 @@
1
- <script lang="ts">
2
- import type { NavSection, NavItem } from '$lib/stores/nav';
3
- import { sidebarOpen } from '$lib/stores/nav';
4
-
5
- let {
6
- sections = [] as NavSection[],
7
- currentPath = '',
8
- onNavigate = () => {},
9
- }: {
10
- sections?: NavSection[];
11
- currentPath?: string;
12
- onNavigate?: (path: string) => void;
13
- } = $props();
14
-
15
- function handleNavClick(path: string) {
16
- onNavigate(path);
17
- sidebarOpen.set(false);
18
- }
19
-
20
- function isActive(href: string | undefined): boolean {
21
- if (!href) return false;
22
- return currentPath === href || currentPath.startsWith(href + '/');
23
- }
24
-
25
- function renderNavItem(item: NavItem) {
26
- const active = isActive(item.href);
27
- return {
28
- label: item.label,
29
- href: item.href,
30
- children: item.children,
31
- active,
32
- icon: item.icon,
33
- };
34
- }
35
- </script>
36
-
37
- <!-- Sidebar Overlay for Mobile -->
38
- {#if $sidebarOpen}
39
- <button
40
- class="fixed inset-0 z-30 bg-black/20 md:hidden"
41
- onclick={() => sidebarOpen.set(false)}
42
- aria-label="Close menu"
43
- ></button>
44
- {/if}
45
-
46
- <!-- Sidebar -->
47
- <aside
48
- class="fixed left-0 top-16 bottom-0 w-64 overflow-y-auto border-r border-claude-border dark:border-claude-dark-border bg-white dark:bg-claude-dark-bg-secondary transition-transform md:relative md:top-0 {$sidebarOpen
49
- ? 'translate-x-0'
50
- : '-translate-x-full md:translate-x-0'} z-30 md:z-auto"
51
- >
52
- <div class="p-6 space-y-8">
53
- {#each sections as section (section.title)}
54
- <div>
55
- <h3 class="text-sm font-semibold text-claude-text dark:text-claude-dark-text uppercase tracking-wide mb-3 opacity-60">
56
- {section.title}
57
- </h3>
58
- <nav class="space-y-2">
59
- {#each section.items as item (item.label)}
60
- <a
61
- href={item.href || '#'}
62
- onclick={(e) => {
63
- if (item.href) {
64
- e.preventDefault();
65
- handleNavClick(item.href);
66
- }
67
- }}
68
- class="block px-3 py-2 rounded-lg transition-colors {isActive(
69
- item.href
70
- )
71
- ? 'bg-claude-accent text-white dark:bg-claude-dark-accent'
72
- : 'text-claude-text dark:text-claude-dark-text hover:bg-claude-bg-secondary dark:hover:bg-claude-dark-bg'}"
73
- >
74
- <span class="flex items-center gap-2">
75
- {#if item.icon}
76
- <span class="text-sm">{item.icon}</span>
77
- {/if}
78
- <span class="text-sm font-medium">{item.label}</span>
79
- </span>
80
- </a>
81
-
82
- <!-- Nested Items -->
83
- {#if item.children && item.children.length > 0}
84
- <div class="ml-3 space-y-1 border-l border-claude-border dark:border-claude-dark-border pl-3">
85
- {#each item.children as child (child.label)}
86
- <a
87
- href={child.href || '#'}
88
- onclick={(e) => {
89
- if (child.href) {
90
- e.preventDefault();
91
- handleNavClick(child.href);
92
- }
93
- }}
94
- class="block px-3 py-1 text-xs rounded transition-colors {isActive(
95
- child.href
96
- )
97
- ? 'bg-claude-accent text-white dark:bg-claude-dark-accent'
98
- : 'text-claude-text-secondary dark:text-claude-dark-text-secondary hover:text-claude-text dark:hover:text-claude-dark-text'}"
99
- >
100
- {child.label}
101
- </a>
102
- {/each}
103
- </div>
104
- {/if}
105
- {/each}
106
- </nav>
107
- </div>
108
- {/each}
109
- </div>
110
- </aside>
@@ -1,102 +0,0 @@
1
- import { describe, it, expect } from 'vitest';
2
-
3
- /**
4
- * Unit tests for Tabs component
5
- * Tests component structure and tab handling logic
6
- */
7
-
8
- describe('Tabs Component', () => {
9
- describe('Tab Props', () => {
10
- it('should accept array of tabs', () => {
11
- const tabs = [
12
- { label: 'Tab 1', content: 'Content 1' },
13
- { label: 'Tab 2', content: 'Content 2' }
14
- ];
15
- expect(Array.isArray(tabs)).toBe(true);
16
- expect(tabs.length).toBe(2);
17
- });
18
-
19
- it('should require label for each tab', () => {
20
- const tab = { label: 'TypeScript', content: 'code' };
21
- expect(tab.label).toBeDefined();
22
- expect(typeof tab.label).toBe('string');
23
- });
24
-
25
- it('should accept optional default active tab index', () => {
26
- const defaultActive = 0;
27
- expect(typeof defaultActive).toBe('number');
28
- expect(defaultActive).toBeGreaterThanOrEqual(0);
29
- });
30
- });
31
-
32
- describe('Tab Structure', () => {
33
- it('should maintain tab order', () => {
34
- const tabs = [
35
- { label: 'First', content: 'First content' },
36
- { label: 'Second', content: 'Second content' },
37
- { label: 'Third', content: 'Third content' }
38
- ];
39
- expect(tabs[0].label).toBe('First');
40
- expect(tabs[1].label).toBe('Second');
41
- expect(tabs[2].label).toBe('Third');
42
- });
43
-
44
- it('should allow empty tab list', () => {
45
- const tabs: any[] = [];
46
- expect(tabs.length).toBe(0);
47
- });
48
-
49
- it('should support single tab', () => {
50
- const tabs = [{ label: 'Only Tab', content: 'Content' }];
51
- expect(tabs.length).toBe(1);
52
- });
53
- });
54
-
55
- describe('Tab Content', () => {
56
- it('should support text content', () => {
57
- const tab = { label: 'Info', content: 'This is text content' };
58
- expect(typeof tab.content).toBe('string');
59
- });
60
-
61
- it('should support HTML content', () => {
62
- const tab = { label: 'Code', content: '<pre>code</pre>' };
63
- expect(tab.content).toContain('<');
64
- expect(tab.content).toContain('>');
65
- });
66
-
67
- it('should support code blocks', () => {
68
- const tab = {
69
- label: 'JavaScript',
70
- content: 'console.log("hello")'
71
- };
72
- expect(tab.label).toBeTruthy();
73
- expect(tab.content).toBeTruthy();
74
- });
75
- });
76
-
77
- describe('Keyboard Navigation', () => {
78
- it('should support keyboard navigation', () => {
79
- const supportedKeys = ['ArrowLeft', 'ArrowRight', 'Home', 'End'];
80
- supportedKeys.forEach((key) => {
81
- expect(supportedKeys).toContain(key);
82
- });
83
- });
84
- });
85
-
86
- describe('Accessibility', () => {
87
- it('should have proper ARIA attributes', () => {
88
- const role = 'tablist';
89
- const tabRole = 'tab';
90
- const panelRole = 'tabpanel';
91
-
92
- expect(role).toBe('tablist');
93
- expect(tabRole).toBe('tab');
94
- expect(panelRole).toBe('tabpanel');
95
- });
96
-
97
- it('should maintain tab index', () => {
98
- const tabIndex = -1; // initially not in tab order
99
- expect(typeof tabIndex).toBe('number');
100
- });
101
- });
102
- });
@@ -1,140 +0,0 @@
1
- import { describe, it, expect } from 'vitest';
2
- import { validateConfig, mergeConfig, DEFAULT_CONFIG } from './config';
3
-
4
- describe('Config Validation', () => {
5
- it('should validate a valid config', () => {
6
- const config = {
7
- name: 'My Docs',
8
- docsRoute: '/docs',
9
- enableSearch: true,
10
- };
11
-
12
- const result = validateConfig(config);
13
- expect(result.valid).toBe(true);
14
- expect(result.errors).toHaveLength(0);
15
- });
16
-
17
- it('should reject non-object config', () => {
18
- const result = validateConfig('invalid');
19
- expect(result.valid).toBe(false);
20
- expect(result.errors.length).toBeGreaterThan(0);
21
- });
22
-
23
- it('should validate docsRoute must be a string', () => {
24
- const config = { docsRoute: 123 };
25
- const result = validateConfig(config);
26
- expect(result.valid).toBe(false);
27
- expect(result.errors.some((e) => e.includes('docsRoute'))).toBe(true);
28
- });
29
-
30
- it('should validate docsRoute must start with /', () => {
31
- const config = { docsRoute: 'docs' };
32
- const result = validateConfig(config);
33
- expect(result.valid).toBe(false);
34
- });
35
-
36
- it('should validate layout is one of the allowed values', () => {
37
- const config = { layout: 'invalid' };
38
- const result = validateConfig(config);
39
- expect(result.valid).toBe(false);
40
- expect(result.errors.some((e) => e.includes('layout'))).toBe(true);
41
- });
42
-
43
- it('should validate defaultTheme is light or dark', () => {
44
- const config = { defaultTheme: 'blue' };
45
- const result = validateConfig(config);
46
- expect(result.valid).toBe(false);
47
- expect(result.errors.some((e) => e.includes('defaultTheme'))).toBe(true);
48
- });
49
-
50
- it('should accept valid theme object', () => {
51
- const config = {
52
- theme: {
53
- primary: '#ff0000',
54
- secondary: '#00ff00',
55
- },
56
- };
57
-
58
- const result = validateConfig(config);
59
- expect(result.valid).toBe(true);
60
- });
61
-
62
- it('should reject invalid theme object', () => {
63
- const config = { theme: 'not-an-object' };
64
- const result = validateConfig(config);
65
- expect(result.valid).toBe(false);
66
- });
67
- });
68
-
69
- describe('Config Merging', () => {
70
- it('should merge user config with defaults', () => {
71
- const userConfig = { name: 'Custom Docs' };
72
- const merged = mergeConfig(userConfig);
73
-
74
- expect(merged.name).toBe('Custom Docs');
75
- expect(merged.docsRoute).toBe(DEFAULT_CONFIG.docsRoute);
76
- expect(merged.enableSearch).toBe(DEFAULT_CONFIG.enableSearch);
77
- });
78
-
79
- it('should override defaults with user values', () => {
80
- const userConfig = {
81
- docsRoute: '/help',
82
- enableSearch: false,
83
- };
84
-
85
- const merged = mergeConfig(userConfig);
86
- expect(merged.docsRoute).toBe('/help');
87
- expect(merged.enableSearch).toBe(false);
88
- });
89
-
90
- it('should merge nested theme objects', () => {
91
- const userConfig = {
92
- theme: {
93
- primary: '#ff0000',
94
- },
95
- };
96
-
97
- const merged = mergeConfig(userConfig);
98
- expect(merged.theme?.primary).toBe('#ff0000');
99
- expect(merged.theme?.secondary).toBe(DEFAULT_CONFIG.theme?.secondary);
100
- });
101
-
102
- it('should merge nested navigation objects', () => {
103
- const userConfig = {
104
- navigation: {
105
- title: 'Custom Nav',
106
- },
107
- };
108
-
109
- const merged = mergeConfig(userConfig);
110
- expect(merged.navigation?.title).toBe('Custom Nav');
111
- expect(merged.navigation?.autoGenerate).toBe(DEFAULT_CONFIG.navigation?.autoGenerate);
112
- });
113
-
114
- it('should handle null/undefined values correctly', () => {
115
- const userConfig: any = {
116
- name: null,
117
- docsRoute: undefined,
118
- };
119
-
120
- const merged = mergeConfig(userConfig);
121
- expect(merged.name).toBeNull();
122
- expect(merged.docsRoute).toBeUndefined();
123
- });
124
- });
125
-
126
- describe('DEFAULT_CONFIG', () => {
127
- it('should have a valid default configuration', () => {
128
- const result = validateConfig(DEFAULT_CONFIG);
129
- expect(result.valid).toBe(true);
130
- expect(result.errors).toHaveLength(0);
131
- });
132
-
133
- it('should have sensible default values', () => {
134
- expect(DEFAULT_CONFIG.docsRoute).toBe('/docs');
135
- expect(DEFAULT_CONFIG.enableSearch).toBe(true);
136
- expect(DEFAULT_CONFIG.darkMode).toBe(true);
137
- expect(DEFAULT_CONFIG.breadcrumbs).toBe(true);
138
- expect(DEFAULT_CONFIG.prevNext).toBe(true);
139
- });
140
- });