@aureuma/svelta 0.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.
Files changed (115) hide show
  1. package/.changeset/README.md +8 -0
  2. package/.changeset/config.json +14 -0
  3. package/.changeset/publish-blogkit.md +5 -0
  4. package/.github/workflows/release.yml +65 -0
  5. package/LICENSE +22 -0
  6. package/README.md +35 -0
  7. package/docs/mintlify-blog-study.md +697 -0
  8. package/package.json +59 -0
  9. package/packages/blogkit/CHANGELOG.md +6 -0
  10. package/packages/blogkit/LICENSE +22 -0
  11. package/packages/blogkit/README.md +93 -0
  12. package/packages/blogkit/dist/components/blog/Avatar.svelte +15 -0
  13. package/packages/blogkit/dist/components/blog/Avatar.svelte.d.ts +22 -0
  14. package/packages/blogkit/dist/components/blog/BackLink.svelte +23 -0
  15. package/packages/blogkit/dist/components/blog/BackLink.svelte.d.ts +21 -0
  16. package/packages/blogkit/dist/components/blog/BlogCard.svelte +37 -0
  17. package/packages/blogkit/dist/components/blog/BlogCard.svelte.d.ts +22 -0
  18. package/packages/blogkit/dist/components/blog/BlogHeroCard.svelte +36 -0
  19. package/packages/blogkit/dist/components/blog/BlogHeroCard.svelte.d.ts +21 -0
  20. package/packages/blogkit/dist/components/blog/Container.svelte +8 -0
  21. package/packages/blogkit/dist/components/blog/Container.svelte.d.ts +29 -0
  22. package/packages/blogkit/dist/components/blog/ImageLightbox.svelte +58 -0
  23. package/packages/blogkit/dist/components/blog/ImageLightbox.svelte.d.ts +24 -0
  24. package/packages/blogkit/dist/components/blog/MorePosts.svelte +15 -0
  25. package/packages/blogkit/dist/components/blog/MorePosts.svelte.d.ts +21 -0
  26. package/packages/blogkit/dist/components/blog/ShareButtons.svelte +113 -0
  27. package/packages/blogkit/dist/components/blog/ShareButtons.svelte.d.ts +23 -0
  28. package/packages/blogkit/dist/components/blog/SummaryCard.svelte +11 -0
  29. package/packages/blogkit/dist/components/blog/SummaryCard.svelte.d.ts +20 -0
  30. package/packages/blogkit/dist/components/blog/TagTabs.svelte +32 -0
  31. package/packages/blogkit/dist/components/blog/TagTabs.svelte.d.ts +23 -0
  32. package/packages/blogkit/dist/index.d.ts +11 -0
  33. package/packages/blogkit/dist/index.js +11 -0
  34. package/packages/blogkit/dist/server/blog.d.ts +39 -0
  35. package/packages/blogkit/dist/server/blog.js +222 -0
  36. package/packages/blogkit/dist/server/index.d.ts +1 -0
  37. package/packages/blogkit/dist/server/index.js +1 -0
  38. package/packages/blogkit/dist/theme/ThemeSwitcher.svelte +34 -0
  39. package/packages/blogkit/dist/theme/ThemeSwitcher.svelte.d.ts +21 -0
  40. package/packages/blogkit/dist/theme/index.d.ts +2 -0
  41. package/packages/blogkit/dist/theme/index.js +2 -0
  42. package/packages/blogkit/dist/theme/store.d.ts +12 -0
  43. package/packages/blogkit/dist/theme/store.js +50 -0
  44. package/packages/blogkit/dist/types/blog.d.ts +31 -0
  45. package/packages/blogkit/dist/types/blog.js +1 -0
  46. package/packages/blogkit/package.json +66 -0
  47. package/packages/blogkit/src/lib/components/blog/Avatar.svelte +15 -0
  48. package/packages/blogkit/src/lib/components/blog/BackLink.svelte +23 -0
  49. package/packages/blogkit/src/lib/components/blog/BlogCard.svelte +37 -0
  50. package/packages/blogkit/src/lib/components/blog/BlogHeroCard.svelte +36 -0
  51. package/packages/blogkit/src/lib/components/blog/Container.svelte +8 -0
  52. package/packages/blogkit/src/lib/components/blog/ImageLightbox.svelte +58 -0
  53. package/packages/blogkit/src/lib/components/blog/MorePosts.svelte +15 -0
  54. package/packages/blogkit/src/lib/components/blog/ShareButtons.svelte +113 -0
  55. package/packages/blogkit/src/lib/components/blog/SummaryCard.svelte +11 -0
  56. package/packages/blogkit/src/lib/components/blog/TagTabs.svelte +32 -0
  57. package/packages/blogkit/src/lib/index.ts +15 -0
  58. package/packages/blogkit/src/lib/server/blog.ts +264 -0
  59. package/packages/blogkit/src/lib/server/index.ts +2 -0
  60. package/packages/blogkit/src/lib/theme/ThemeSwitcher.svelte +34 -0
  61. package/packages/blogkit/src/lib/theme/index.ts +3 -0
  62. package/packages/blogkit/src/lib/theme/store.ts +64 -0
  63. package/packages/blogkit/src/lib/types/blog.ts +36 -0
  64. package/packages/blogkit/svelte.config.js +8 -0
  65. package/packages/blogkit/tsconfig.json +5 -0
  66. package/playwright.config.ts +24 -0
  67. package/postcss.config.cjs +6 -0
  68. package/src/app.css +146 -0
  69. package/src/app.d.ts +13 -0
  70. package/src/app.html +26 -0
  71. package/src/content/blog/ai-summary-cards-with-frontmatter.md +32 -0
  72. package/src/content/blog/announcing-svelta-blog.md +19 -0
  73. package/src/content/blog/best-practices-ship-with-checklists.md +26 -0
  74. package/src/content/blog/building-a-mintlify-inspired-blog.md +49 -0
  75. package/src/content/blog/design-tokens-that-scale.md +47 -0
  76. package/src/content/blog/for-founders-why-speed-matters.md +23 -0
  77. package/src/content/blog/infinite-scroll-with-intersection-observer.md +37 -0
  78. package/src/content/blog/markdown-kitchen-sink.md +101 -0
  79. package/src/content/blog/markdown-pipeline-mdsvex-shiki.md +39 -0
  80. package/src/content/blog/rss-feeds-that-actually-work.md +25 -0
  81. package/src/content/blog/tag-tabs-and-mobile-fade-masks.md +25 -0
  82. package/src/lib/assets/favicon.svg +1 -0
  83. package/src/lib/components/site/SiteFooter.svelte +24 -0
  84. package/src/lib/components/site/SiteHeader.svelte +36 -0
  85. package/src/lib/content/authors.ts +28 -0
  86. package/src/lib/index.ts +1 -0
  87. package/src/lib/server/blog.ts +22 -0
  88. package/src/lib/server/rss.ts +58 -0
  89. package/src/lib/server/seo.ts +31 -0
  90. package/src/lib/stores/theme.ts +10 -0
  91. package/src/lib/types/blog.ts +1 -0
  92. package/src/routes/+layout.svelte +31 -0
  93. package/src/routes/+page.svelte +44 -0
  94. package/src/routes/blog/+page.server.ts +28 -0
  95. package/src/routes/blog/+page.svelte +122 -0
  96. package/src/routes/blog/[slug]/+page.server.ts +39 -0
  97. package/src/routes/blog/[slug]/+page.svelte +118 -0
  98. package/src/routes/blog/posts.json/+server.ts +32 -0
  99. package/src/routes/feed.xml/+server.ts +21 -0
  100. package/static/blog/authors/alex.svg +13 -0
  101. package/static/blog/authors/maria.svg +13 -0
  102. package/static/blog/authors/shawn.svg +13 -0
  103. package/static/blog/covers/ai-summary.svg +38 -0
  104. package/static/blog/covers/design-tokens.svg +37 -0
  105. package/static/blog/covers/infinite-scroll.svg +38 -0
  106. package/static/blog/covers/kitchen-sink.svg +36 -0
  107. package/static/blog/covers/markdown-pipeline.svg +41 -0
  108. package/static/blog/covers/mintlify-style.svg +35 -0
  109. package/static/blog/covers/rss.svg +34 -0
  110. package/static/robots.txt +3 -0
  111. package/svelte.config.js +70 -0
  112. package/tailwind.config.cjs +133 -0
  113. package/tests/blog.spec.ts +63 -0
  114. package/tsconfig.json +21 -0
  115. package/vite.config.ts +14 -0
@@ -0,0 +1,133 @@
1
+ /** @type {import('tailwindcss').Config} */
2
+ module.exports = {
3
+ darkMode: 'class',
4
+ content: [
5
+ './src/**/*.{html,js,svelte,ts,md}',
6
+ './src/content/**/*.{md}',
7
+ './packages/blogkit/src/**/*.{svelte,ts}',
8
+ './packages/blogkit/dist/**/*.{js,ts,svelte}'
9
+ ],
10
+ theme: {
11
+ extend: {
12
+ colors: {
13
+ background: {
14
+ main: 'rgb(var(--c-background-main) / <alpha-value>)',
15
+ soft: 'rgb(var(--c-background-soft) / <alpha-value>)',
16
+ invert: 'rgb(var(--c-background-invert) / <alpha-value>)'
17
+ },
18
+ text: {
19
+ main: 'rgb(var(--c-text-main) / <alpha-value>)',
20
+ sub: 'rgb(var(--c-text-sub) / <alpha-value>)',
21
+ muted: 'rgb(var(--c-text-muted) / <alpha-value>)',
22
+ invert: 'rgb(var(--c-text-invert) / <alpha-value>)'
23
+ },
24
+ border: {
25
+ soft: 'rgb(var(--c-border-soft) / <alpha-value>)'
26
+ },
27
+ brand: {
28
+ DEFAULT: 'rgb(var(--c-brand) / <alpha-value>)',
29
+ soft: 'rgb(var(--c-brand-soft) / <alpha-value>)'
30
+ }
31
+ },
32
+ fontFamily: {
33
+ sans: [
34
+ 'Inter',
35
+ 'ui-sans-serif',
36
+ 'system-ui',
37
+ '-apple-system',
38
+ 'Segoe UI',
39
+ 'Roboto',
40
+ 'Helvetica',
41
+ 'Arial',
42
+ 'Apple Color Emoji',
43
+ 'Segoe UI Emoji'
44
+ ],
45
+ mono: [
46
+ 'Geist Mono',
47
+ 'ui-monospace',
48
+ 'SFMono-Regular',
49
+ 'Menlo',
50
+ 'Monaco',
51
+ 'Consolas',
52
+ 'Liberation Mono',
53
+ 'Courier New',
54
+ 'monospace'
55
+ ]
56
+ },
57
+ boxShadow: {
58
+ 'drop-md': '0 18px 60px rgba(15, 23, 42, 0.16)'
59
+ },
60
+ typography: () => ({
61
+ DEFAULT: {
62
+ css: {
63
+ '--tw-prose-body': 'rgb(var(--c-text-main))',
64
+ '--tw-prose-headings': 'rgb(var(--c-text-main))',
65
+ '--tw-prose-lead': 'rgb(var(--c-text-sub))',
66
+ '--tw-prose-links': 'rgb(var(--c-text-main))',
67
+ '--tw-prose-bold': 'rgb(var(--c-text-main))',
68
+ '--tw-prose-counters': 'rgb(var(--c-text-muted))',
69
+ '--tw-prose-bullets': 'rgb(var(--c-border-soft) / 0.35)',
70
+ '--tw-prose-hr': 'rgb(var(--c-border-soft) / 0.12)',
71
+ '--tw-prose-quotes': 'rgb(var(--c-text-main))',
72
+ '--tw-prose-quote-borders': 'rgb(var(--c-border-soft) / 0.2)',
73
+ '--tw-prose-captions': 'rgb(var(--c-text-muted))',
74
+ '--tw-prose-code': 'rgb(var(--c-text-main))',
75
+ '--tw-prose-pre-code': 'rgb(var(--c-text-main))',
76
+ '--tw-prose-pre-bg': 'transparent',
77
+ '--tw-prose-th-borders': 'rgb(var(--c-border-soft) / 0.12)',
78
+ '--tw-prose-td-borders': 'rgb(var(--c-border-soft) / 0.12)',
79
+ maxWidth: 'none',
80
+ fontSize: '16px',
81
+ lineHeight: '24px',
82
+ letterSpacing: '-0.01em',
83
+ a: {
84
+ textDecoration: 'underline',
85
+ textDecorationColor: 'rgb(var(--c-border-soft) / 0.35)',
86
+ textUnderlineOffset: '3px'
87
+ },
88
+ 'a:hover': {
89
+ textDecorationColor: 'rgb(var(--c-brand) / 0.85)'
90
+ },
91
+ h2: {
92
+ fontWeight: '500',
93
+ fontSize: '24px',
94
+ lineHeight: '31.2px',
95
+ letterSpacing: '-0.24px',
96
+ scrollMarginTop: '96px'
97
+ },
98
+ h3: {
99
+ fontWeight: '500',
100
+ fontSize: '20px',
101
+ lineHeight: '26px',
102
+ letterSpacing: '-0.24px',
103
+ scrollMarginTop: '96px'
104
+ },
105
+ code: {
106
+ fontWeight: '500',
107
+ backgroundColor: 'rgb(var(--c-background-soft))',
108
+ padding: '0.2em 0.35em',
109
+ borderRadius: '6px'
110
+ },
111
+ 'code::before': { content: '""' },
112
+ 'code::after': { content: '""' },
113
+ pre: {
114
+ background: 'transparent',
115
+ padding: '0',
116
+ margin: '0'
117
+ },
118
+ blockquote: {
119
+ borderLeftColor: 'rgb(var(--c-border-soft) / 0.35)'
120
+ },
121
+ 'blockquote p:first-of-type::before': { content: '""' },
122
+ 'blockquote p:last-of-type::after': { content: '""' },
123
+ img: {
124
+ borderRadius: '10px',
125
+ border: '1px solid rgb(var(--c-border-soft) / 0.07)'
126
+ }
127
+ }
128
+ }
129
+ })
130
+ }
131
+ },
132
+ plugins: [require('@tailwindcss/typography')]
133
+ };
@@ -0,0 +1,63 @@
1
+ import { expect, test } from '@playwright/test';
2
+
3
+ test('blog index renders hero, tags, and paginates', async ({ page }) => {
4
+ await page.goto('/blog');
5
+
6
+ await expect(page.getByTestId('blog-hero')).toBeVisible();
7
+ await expect(page.getByTestId('blog-tags')).toBeVisible();
8
+
9
+ const cards = page.getByTestId('blog-card');
10
+ await expect(cards).toHaveCount(8);
11
+
12
+ // Trigger infinite scroll: scroll near bottom and wait for additional cards.
13
+ await page.evaluate(() => window.scrollTo(0, document.body.scrollHeight));
14
+ await expect.poll(async () => cards.count()).toBeGreaterThan(8);
15
+ });
16
+
17
+ test('post page renders summary, shiki blocks, and more posts', async ({ page }) => {
18
+ await page.goto('/blog/ai-summary-cards-with-frontmatter');
19
+
20
+ await expect(page.getByRole('heading', { level: 1 })).toBeVisible();
21
+ await expect(page.getByTestId('blog-summary')).toBeVisible();
22
+ await expect.poll(async () => page.locator('pre.shiki').count()).toBeGreaterThan(0);
23
+
24
+ // Heading anchors from rehype-autolink-headings should exist.
25
+ await expect
26
+ .poll(async () => page.locator('.blog-prose .heading-anchor').count())
27
+ .toBeGreaterThan(0);
28
+
29
+ await expect(page.getByTestId('blog-more-posts')).toBeVisible();
30
+ });
31
+
32
+ test('theme toggling applies the expected html class', async ({ page }) => {
33
+ await page.goto('/');
34
+ await page.evaluate(() => window.scrollTo(0, document.body.scrollHeight));
35
+ const darkBtn = page.getByRole('button', { name: 'Dark' });
36
+ await darkBtn.click();
37
+
38
+ // If hydration/event binding is broken, this will never flip.
39
+ await expect(darkBtn).toHaveAttribute('aria-pressed', 'true');
40
+ await expect(page.locator('html')).toHaveClass(/dark/);
41
+ });
42
+
43
+ test('rss feed is valid xml-ish and links do not include .md', async ({ request }) => {
44
+ const res = await request.get('/feed.xml');
45
+ expect(res.ok()).toBeTruthy();
46
+
47
+ const ct = res.headers()['content-type'] ?? '';
48
+ expect(ct).toContain('application/rss+xml');
49
+
50
+ const body = await res.text();
51
+ expect(body).toContain('<rss');
52
+ expect(body).toContain('<channel>');
53
+ expect(body).toContain('/blog/ai-summary-cards-with-frontmatter');
54
+ expect(body).not.toContain('.md</link>');
55
+ });
56
+
57
+ test('mobile layout folds share UI into the content column', async ({ page }) => {
58
+ await page.setViewportSize({ width: 390, height: 844 });
59
+ await page.goto('/blog/ai-summary-cards-with-frontmatter');
60
+
61
+ await expect(page.getByTestId('blog-share-mobile')).toBeVisible();
62
+ await expect(page.getByTestId('blog-share-desktop')).toBeHidden();
63
+ });
package/tsconfig.json ADDED
@@ -0,0 +1,21 @@
1
+ {
2
+ "extends": "./.svelte-kit/tsconfig.json",
3
+ "compilerOptions": {
4
+ "rewriteRelativeImportExtensions": true,
5
+ "allowJs": true,
6
+ "checkJs": true,
7
+ "esModuleInterop": true,
8
+ "forceConsistentCasingInFileNames": true,
9
+ "resolveJsonModule": true,
10
+ "skipLibCheck": true,
11
+ "sourceMap": true,
12
+ "strict": true,
13
+ "moduleResolution": "bundler"
14
+ },
15
+ "exclude": ["packages/**/dist/**"]
16
+ // Path aliases are handled by https://svelte.dev/docs/kit/configuration#alias
17
+ // except $lib which is handled by https://svelte.dev/docs/kit/configuration#files
18
+ //
19
+ // To make changes to top-level options such as include and exclude, we recommend extending
20
+ // the generated config; see https://svelte.dev/docs/kit/configuration#typescript
21
+ }
package/vite.config.ts ADDED
@@ -0,0 +1,14 @@
1
+ import { sveltekit } from '@sveltejs/kit/vite';
2
+ import { defineConfig } from 'vite';
3
+ import path from 'node:path';
4
+
5
+ export default defineConfig({
6
+ plugins: [sveltekit()],
7
+ server: {
8
+ fs: {
9
+ // Allow local workspace packages to be served in dev.
10
+ strict: false,
11
+ allow: [path.resolve('./packages'), path.resolve('./src'), path.resolve('./node_modules')]
12
+ }
13
+ }
14
+ });