opentwig 1.1.0 → 1.1.2

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 (56) hide show
  1. package/AGENTS.md +49 -200
  2. package/package.json +2 -3
  3. package/src/live-ui/editor.js +1 -0
  4. package/src/live-ui/index.html +94 -0
  5. package/src/live-ui/sidebar.js +2 -0
  6. package/src/live-ui/styles.css +578 -0
  7. package/src/utils/favicon.js +20 -0
  8. package/src/utils/loadConfig.js +3 -1
  9. package/src/utils/setupWatcher.js +2 -2
  10. package/src/utils/startLiveServer.js +11 -8
  11. package/theme/default/index.js +2 -0
  12. package/vitest.config.js +19 -10
  13. package/website/README.md +42 -0
  14. package/website/components.json +16 -0
  15. package/website/eslint.config.js +36 -0
  16. package/website/package-lock.json +4136 -0
  17. package/website/package.json +41 -0
  18. package/website/shadcn-svelte.md +118 -0
  19. package/website/src/app.d.ts +13 -0
  20. package/website/src/app.html +11 -0
  21. package/website/src/lib/assets/favicon.svg +4 -0
  22. package/website/src/lib/components/ui/badge/badge.svelte +50 -0
  23. package/website/src/lib/components/ui/badge/index.ts +2 -0
  24. package/website/src/lib/components/ui/button/button.svelte +82 -0
  25. package/website/src/lib/components/ui/button/index.ts +17 -0
  26. package/website/src/lib/components/ui/card/card-action.svelte +20 -0
  27. package/website/src/lib/components/ui/card/card-content.svelte +15 -0
  28. package/website/src/lib/components/ui/card/card-description.svelte +20 -0
  29. package/website/src/lib/components/ui/card/card-footer.svelte +20 -0
  30. package/website/src/lib/components/ui/card/card-header.svelte +23 -0
  31. package/website/src/lib/components/ui/card/card-title.svelte +20 -0
  32. package/website/src/lib/components/ui/card/card.svelte +23 -0
  33. package/website/src/lib/components/ui/card/index.ts +25 -0
  34. package/website/src/lib/components/ui/separator/index.ts +7 -0
  35. package/website/src/lib/components/ui/separator/separator.svelte +21 -0
  36. package/website/src/lib/components/ui/tooltip/index.ts +19 -0
  37. package/website/src/lib/components/ui/tooltip/tooltip-content.svelte +52 -0
  38. package/website/src/lib/components/ui/tooltip/tooltip-portal.svelte +7 -0
  39. package/website/src/lib/components/ui/tooltip/tooltip-provider.svelte +7 -0
  40. package/website/src/lib/components/ui/tooltip/tooltip-trigger.svelte +7 -0
  41. package/website/src/lib/components/ui/tooltip/tooltip.svelte +7 -0
  42. package/website/src/lib/index.ts +1 -0
  43. package/website/src/lib/utils.ts +13 -0
  44. package/website/src/routes/+layout.svelte +23 -0
  45. package/website/src/routes/+page.server.ts +82 -0
  46. package/website/src/routes/+page.svelte +892 -0
  47. package/website/src/routes/layout.css +199 -0
  48. package/website/static/live-editor.png +0 -0
  49. package/website/static/robots.txt +3 -0
  50. package/website/static/theme-colorful.png +0 -0
  51. package/website/static/theme-dark.png +0 -0
  52. package/website/static/theme-default.png +0 -0
  53. package/website/static/theme-minimal.png +0 -0
  54. package/website/svelte.config.js +31 -0
  55. package/website/vite.config.ts +5 -0
  56. package/test-og.js +0 -40
@@ -0,0 +1,199 @@
1
+ @import "tailwindcss";
2
+
3
+ @import "tw-animate-css";
4
+
5
+ @custom-variant dark (&:is(.dark *));
6
+
7
+ :root {
8
+ --radius: 0.75rem;
9
+ --background: #f8faf8;
10
+ --foreground: #1a2e1a;
11
+ --card: #ffffff;
12
+ --card-foreground: #1a2e1a;
13
+ --popover: #ffffff;
14
+ --popover-foreground: #1a2e1a;
15
+ --primary: #2d5a3d;
16
+ --primary-foreground: #ffffff;
17
+ --secondary: #e8f0e8;
18
+ --secondary-foreground: #2d5a3d;
19
+ --muted: #e8f0e8;
20
+ --muted-foreground: #5a7a5a;
21
+ --accent: #4a7c59;
22
+ --accent-foreground: #ffffff;
23
+ --destructive: #dc2626;
24
+ --border: #d4e4d4;
25
+ --input: #d4e4d4;
26
+ --ring: #4a7c59;
27
+ --chart-1: #2d5a3d;
28
+ --chart-2: #4a7c59;
29
+ --chart-3: #6b9b7a;
30
+ --chart-4: #8cb89a;
31
+ --chart-5: #c8e0c8;
32
+ --sidebar: #f0f7f0;
33
+ --sidebar-foreground: #1a2e1a;
34
+ --sidebar-primary: #2d5a3d;
35
+ --sidebar-primary-foreground: #ffffff;
36
+ --sidebar-accent: #e8f0e8;
37
+ --sidebar-accent-foreground: #2d5a3d;
38
+ --sidebar-border: #d4e4d4;
39
+ --sidebar-ring: #4a7c59;
40
+ }
41
+
42
+ .dark {
43
+ --background: #0d1f12;
44
+ --foreground: #e8f0e8;
45
+ --card: #1a3320;
46
+ --card-foreground: #e8f0e8;
47
+ --popover: #1a3320;
48
+ --popover-foreground: #e8f0e8;
49
+ --primary: #6b9b7a;
50
+ --primary-foreground: #0d1f12;
51
+ --secondary: #2d4a35;
52
+ --secondary-foreground: #e8f0e8;
53
+ --muted: #2d4a35;
54
+ --muted-foreground: #8cb89a;
55
+ --accent: #4a7c59;
56
+ --accent-foreground: #ffffff;
57
+ --destructive: #ef4444;
58
+ --border: #2d4a35;
59
+ --input: #2d4a35;
60
+ --ring: #6b9b7a;
61
+ --chart-1: #6b9b7a;
62
+ --chart-2: #4a7c59;
63
+ --chart-3: #8cb89a;
64
+ --chart-4: #a8d4a8;
65
+ --chart-5: #2d5a3d;
66
+ --sidebar: #1a3320;
67
+ --sidebar-foreground: #e8f0e8;
68
+ --sidebar-primary: #6b9b7a;
69
+ --sidebar-primary-foreground: #0d1f12;
70
+ --sidebar-accent: #2d4a35;
71
+ --sidebar-accent-foreground: #e8f0e8;
72
+ --sidebar-border: #2d4a35;
73
+ --sidebar-ring: #6b9b7a;
74
+ }
75
+
76
+ @theme inline {
77
+ --radius-sm: calc(var(--radius) - 4px);
78
+ --radius-md: calc(var(--radius) - 2px);
79
+ --radius-lg: var(--radius);
80
+ --radius-xl: calc(var(--radius) + 4px);
81
+ --color-background: var(--background);
82
+ --color-foreground: var(--foreground);
83
+ --color-card: var(--card);
84
+ --color-card-foreground: var(--card-foreground);
85
+ --color-popover: var(--popover);
86
+ --color-popover-foreground: var(--popover-foreground);
87
+ --color-primary: var(--primary);
88
+ --color-primary-foreground: var(--primary-foreground);
89
+ --color-secondary: var(--secondary);
90
+ --color-secondary-foreground: var(--secondary-foreground);
91
+ --color-muted: var(--muted);
92
+ --color-muted-foreground: var(--muted-foreground);
93
+ --color-accent: var(--accent);
94
+ --color-accent-foreground: var(--accent-foreground);
95
+ --color-destructive: var(--destructive);
96
+ --color-border: var(--border);
97
+ --color-input: var(--input);
98
+ --color-ring: var(--ring);
99
+ --color-chart-1: var(--chart-1);
100
+ --color-chart-2: var(--chart-2);
101
+ --color-chart-3: var(--chart-3);
102
+ --color-chart-4: var(--chart-4);
103
+ --color-chart-5: var(--chart-5);
104
+ --color-sidebar: var(--sidebar);
105
+ --color-sidebar-foreground: var(--sidebar-foreground);
106
+ --color-sidebar-primary: var(--sidebar-primary);
107
+ --color-sidebar-primary-foreground: var(--sidebar-primary-foreground);
108
+ --color-sidebar-accent: var(--sidebar-accent);
109
+ --color-sidebar-accent-foreground: var(--sidebar-accent-foreground);
110
+ --color-sidebar-border: var(--sidebar-border);
111
+ --color-sidebar-ring: var(--sidebar-ring);
112
+ }
113
+
114
+ @layer base {
115
+ * {
116
+ @apply border-border outline-ring/50;
117
+ }
118
+ body {
119
+ @apply bg-background text-foreground antialiased;
120
+ font-feature-settings: "rlig" 1, "calt" 1;
121
+ }
122
+ html {
123
+ scroll-behavior: smooth;
124
+ }
125
+ }
126
+
127
+ @layer utilities {
128
+ .text-balance {
129
+ text-wrap: balance;
130
+ }
131
+ .gradient-text {
132
+ background: linear-gradient(135deg, #2d5a3d 0%, #4a7c59 50%, #6b9b7a 100%);
133
+ -webkit-background-clip: text;
134
+ -webkit-text-fill-color: transparent;
135
+ background-clip: text;
136
+ }
137
+ .gradient-border {
138
+ background: linear-gradient(135deg, #d4e4d4 0%, #c8e0c8 50%, #b8d4b8 100%);
139
+ padding: 1px;
140
+ border-radius: var(--radius);
141
+ }
142
+ .leaf-pattern {
143
+ background-image: url("data:image/svg+xml,%3Csvg width='60' height='60' viewBox='0 0 60 60' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M30 5c-2 5-8 10-15 10 7 0 13 5 15 10 2-5 8-10 15-10-7 0-13-5-15-10z' fill='%234a7c59' fill-opacity='0.03'/%3E%3C/svg%3E");
144
+ }
145
+ .animate-float {
146
+ animation: float 6s ease-in-out infinite;
147
+ }
148
+ .animate-float-delayed {
149
+ animation: float 6s ease-in-out infinite;
150
+ animation-delay: 2s;
151
+ }
152
+ .animate-float-delayed-2 {
153
+ animation: float 6s ease-in-out infinite;
154
+ animation-delay: 4s;
155
+ }
156
+ @keyframes float {
157
+ 0%, 100% { transform: translateY(0px); }
158
+ 50% { transform: translateY(-20px); }
159
+ }
160
+ }
161
+
162
+ /* Custom scrollbar */
163
+ ::-webkit-scrollbar {
164
+ width: 8px;
165
+ height: 8px;
166
+ }
167
+
168
+ ::-webkit-scrollbar-track {
169
+ background: var(--secondary);
170
+ }
171
+
172
+ ::-webkit-scrollbar-thumb {
173
+ background: var(--muted-foreground);
174
+ border-radius: 4px;
175
+ }
176
+
177
+ ::-webkit-scrollbar-thumb:hover {
178
+ background: var(--primary);
179
+ }
180
+
181
+ /* Code block styling */
182
+ pre {
183
+ background: #1a3320 !important;
184
+ border-radius: var(--radius);
185
+ padding: 1.5rem;
186
+ overflow-x: auto;
187
+ }
188
+
189
+ code {
190
+ font-family: 'JetBrains Mono', 'Fira Code', monospace;
191
+ font-size: 0.875rem;
192
+ line-height: 1.7;
193
+ }
194
+
195
+ /* Selection styling */
196
+ ::selection {
197
+ background: rgba(74, 124, 89, 0.3);
198
+ color: inherit;
199
+ }
Binary file
@@ -0,0 +1,3 @@
1
+ # allow crawling everything by default
2
+ User-agent: *
3
+ Disallow:
Binary file
Binary file
Binary file
@@ -0,0 +1,31 @@
1
+ import adapter from '@sveltejs/adapter-static';
2
+ import { vitePreprocess } from '@sveltejs/vite-plugin-svelte';
3
+
4
+ /** @type {import('@sveltejs/kit').Config} */
5
+ const config = {
6
+ preprocess: vitePreprocess(),
7
+ kit: {
8
+ adapter: adapter({
9
+ pages: 'build',
10
+ assets: 'build',
11
+ precompress: false,
12
+ strict: true
13
+ }),
14
+ paths: {
15
+ base: ''
16
+ },
17
+ prerender: {
18
+ entries: ['*'],
19
+ handleHttpError: ({ path, referrer, message }) => {
20
+ // Ignore warnings about external links
21
+ if (message.includes('Not found')) {
22
+ console.warn(`Warning: ${path} not found (referrer: ${referrer})`);
23
+ return;
24
+ }
25
+ throw new Error(message);
26
+ }
27
+ }
28
+ }
29
+ };
30
+
31
+ export default config;
@@ -0,0 +1,5 @@
1
+ import tailwindcss from '@tailwindcss/vite';
2
+ import { sveltekit } from '@sveltejs/kit/vite';
3
+ import { defineConfig } from 'vite';
4
+
5
+ export default defineConfig({ plugins: [tailwindcss(), sveltekit()] });
package/test-og.js DELETED
@@ -1,40 +0,0 @@
1
- const fs = require('fs');
2
- const path = require('path');
3
-
4
- const render = require('./theme/default');
5
-
6
- const sample = {
7
- title: 'A <Title> & Test "Quote"',
8
- url: 'https://example.com/page?arg=1&other=<bad>',
9
- name: "O'Connor & Co <dev>",
10
- content: 'This is a description with <tags> & special "characters" and \'quotes\'.',
11
- avatar: null,
12
- links: [],
13
- footerLinks: [],
14
- share: {}
15
- };
16
-
17
- const out = render(sample);
18
- const outPath = path.join(__dirname, 'test-output.html');
19
- fs.writeFileSync(outPath, out);
20
- console.log('Wrote', outPath);
21
-
22
- // Basic assertions
23
- function assertContainsEscaped(haystack, raw, escaped) {
24
- if (haystack.includes(raw)) {
25
- throw new Error(`Found unescaped string: ${raw}`);
26
- }
27
- if (!haystack.includes(escaped)) {
28
- throw new Error(`Did not find escaped string: ${escaped}`);
29
- }
30
- }
31
-
32
- // Check several values
33
- assertContainsEscaped(out, '<Title>', '&lt;Title&gt;');
34
- // URL should have ampersand escaped and angle brackets escaped
35
- assertContainsEscaped(out, '&other=<bad>', '&amp;other=&lt;bad&gt;');
36
- assertContainsEscaped(out, "O'Connor", "O&#39;Connor");
37
- assertContainsEscaped(out, '"Quote"', '&quot;Quote&quot;');
38
- assertContainsEscaped(out, "<tags>", '&lt;tags&gt;');
39
-
40
- console.log('All assertions passed.');