sv5ui-plus 5.0.4 → 5.0.6

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 (215) hide show
  1. package/README.md +6 -6
  2. package/dist/adapters/notify.d.ts +1 -1
  3. package/dist/adapters/notify.js +18 -18
  4. package/dist/compat.d.ts +2 -2
  5. package/dist/compat.js +2 -2
  6. package/dist/components/BentoGrid/BentoCard.svelte +33 -33
  7. package/dist/components/BentoGrid/BentoCard.svelte.d.ts +1 -1
  8. package/dist/components/BentoGrid/BentoGrid.svelte +1 -1
  9. package/dist/components/BentoGrid/BentoGrid.svelte.d.ts +1 -1
  10. package/dist/components/BentoGrid/bento-grid.types.d.ts +2 -2
  11. package/dist/components/BentoGrid/bento-grid.variants.d.ts +1 -1
  12. package/dist/components/BentoGrid/bento-grid.variants.js +10 -10
  13. package/dist/components/BentoGrid/index.d.ts +4 -4
  14. package/dist/components/BentoGrid/index.js +4 -4
  15. package/dist/components/Chart/Chart.svelte +1 -1
  16. package/dist/components/Chart/Chart.svelte.d.ts +1 -1
  17. package/dist/components/Chart/chart.types.d.ts +3 -3
  18. package/dist/components/Chart/index.d.ts +2 -2
  19. package/dist/components/Chart/index.js +2 -2
  20. package/dist/components/Chat/ChatBubble.svelte +19 -19
  21. package/dist/components/Chat/ChatBubble.svelte.d.ts +1 -1
  22. package/dist/components/Chat/ChatInput.svelte +26 -27
  23. package/dist/components/Chat/ChatInput.svelte.d.ts +1 -1
  24. package/dist/components/Chat/ChatMessage.svelte +1 -1
  25. package/dist/components/Chat/ChatMessage.svelte.d.ts +1 -1
  26. package/dist/components/Chat/chat.types.d.ts +6 -6
  27. package/dist/components/Chat/chat.variants.d.ts +1 -1
  28. package/dist/components/Chat/chat.variants.js +29 -29
  29. package/dist/components/Chat/index.d.ts +5 -5
  30. package/dist/components/Chat/index.js +5 -5
  31. package/dist/components/CodeBlock/CodeBlock.svelte +15 -15
  32. package/dist/components/CodeBlock/CodeBlock.svelte.d.ts +1 -1
  33. package/dist/components/CodeBlock/code-block.types.d.ts +5 -5
  34. package/dist/components/CodeBlock/code-block.variants.d.ts +1 -1
  35. package/dist/components/CodeBlock/code-block.variants.js +40 -40
  36. package/dist/components/CodeBlock/index.d.ts +2 -2
  37. package/dist/components/CodeBlock/index.js +1 -1
  38. package/dist/components/ConfirmDialog/ConfirmDialog.svelte +93 -97
  39. package/dist/components/ConfirmDialog/ConfirmDialog.svelte.d.ts +1 -1
  40. package/dist/components/ConfirmDialog/confirm.d.ts +1 -1
  41. package/dist/components/ConfirmDialog/confirm.js +9 -9
  42. package/dist/components/ConfirmDialog/confirm.types.d.ts +4 -4
  43. package/dist/components/ConfirmDialog/index.d.ts +4 -4
  44. package/dist/components/ConfirmDialog/index.js +2 -2
  45. package/dist/components/DatePickerField/DatePickerField.svelte +11 -11
  46. package/dist/components/DatePickerField/DatePickerField.svelte.d.ts +2 -2
  47. package/dist/components/DatePickerField/date-picker-field.types.d.ts +1 -1
  48. package/dist/components/DatePickerField/index.d.ts +2 -2
  49. package/dist/components/DatePickerField/index.js +1 -1
  50. package/dist/components/DateRangePickerField/DateRangePickerField.svelte +26 -26
  51. package/dist/components/DateRangePickerField/DateRangePickerField.svelte.d.ts +2 -2
  52. package/dist/components/DateRangePickerField/date-range-picker-field.types.d.ts +1 -1
  53. package/dist/components/DateRangePickerField/index.d.ts +2 -2
  54. package/dist/components/DateRangePickerField/index.js +1 -1
  55. package/dist/components/Fonts/Fonts.svelte +12 -12
  56. package/dist/components/Fonts/Fonts.svelte.d.ts +1 -1
  57. package/dist/components/Fonts/fonts.d.ts +1 -1
  58. package/dist/components/Fonts/fonts.js +42 -42
  59. package/dist/components/Fonts/fonts.types.d.ts +6 -6
  60. package/dist/components/Fonts/index.d.ts +3 -3
  61. package/dist/components/Fonts/index.js +2 -2
  62. package/dist/components/FormSelect/FormSelect.svelte +4 -4
  63. package/dist/components/FormSelect/FormSelect.svelte.d.ts +2 -2
  64. package/dist/components/FormSelect/form-select.types.d.ts +3 -3
  65. package/dist/components/FormSelect/index.d.ts +2 -2
  66. package/dist/components/FormSelect/index.js +1 -1
  67. package/dist/components/List/List.svelte +1 -1
  68. package/dist/components/List/List.svelte.d.ts +1 -1
  69. package/dist/components/List/ListItem.svelte +31 -39
  70. package/dist/components/List/ListItem.svelte.d.ts +1 -1
  71. package/dist/components/List/index.d.ts +4 -4
  72. package/dist/components/List/index.js +4 -4
  73. package/dist/components/List/list.types.d.ts +4 -4
  74. package/dist/components/List/list.variants.d.ts +1 -1
  75. package/dist/components/List/list.variants.js +22 -22
  76. package/dist/components/LocaleButton/LocaleButton.svelte +104 -108
  77. package/dist/components/LocaleButton/LocaleButton.svelte.d.ts +1 -1
  78. package/dist/components/LocaleButton/index.d.ts +2 -2
  79. package/dist/components/LocaleButton/index.js +1 -1
  80. package/dist/components/LocaleButton/locale-button.types.d.ts +12 -12
  81. package/dist/components/LocaleButton/locale-button.variants.d.ts +2 -2
  82. package/dist/components/LocaleButton/locale-button.variants.js +68 -68
  83. package/dist/components/Marquee/Marquee.svelte +34 -34
  84. package/dist/components/Marquee/Marquee.svelte.d.ts +1 -1
  85. package/dist/components/Marquee/index.d.ts +3 -3
  86. package/dist/components/Marquee/index.js +3 -3
  87. package/dist/components/Marquee/marquee.types.d.ts +4 -4
  88. package/dist/components/Marquee/marquee.variants.d.ts +1 -1
  89. package/dist/components/Marquee/marquee.variants.js +15 -15
  90. package/dist/components/NavigationMenu/NavigationMenu.svelte +366 -379
  91. package/dist/components/NavigationMenu/NavigationMenu.svelte.d.ts +1 -1
  92. package/dist/components/NavigationMenu/index.d.ts +2 -2
  93. package/dist/components/NavigationMenu/index.js +1 -1
  94. package/dist/components/NavigationMenu/navigation-menu.types.d.ts +17 -17
  95. package/dist/components/NavigationMenu/navigation-menu.variants.d.ts +1 -1
  96. package/dist/components/NavigationMenu/navigation-menu.variants.js +177 -177
  97. package/dist/components/NumberTicker/NumberTicker.svelte +1 -5
  98. package/dist/components/NumberTicker/NumberTicker.svelte.d.ts +1 -1
  99. package/dist/components/NumberTicker/index.d.ts +3 -3
  100. package/dist/components/NumberTicker/index.js +3 -3
  101. package/dist/components/NumberTicker/number-ticker.types.d.ts +1 -1
  102. package/dist/components/NumberTicker/number-ticker.variants.d.ts +1 -1
  103. package/dist/components/NumberTicker/number-ticker.variants.js +3 -3
  104. package/dist/components/PasswordInput/PasswordInput.svelte +58 -58
  105. package/dist/components/PasswordInput/PasswordInput.svelte.d.ts +1 -1
  106. package/dist/components/PasswordInput/index.d.ts +2 -2
  107. package/dist/components/PasswordInput/index.js +1 -1
  108. package/dist/components/PasswordInput/password-input.types.d.ts +9 -9
  109. package/dist/components/PasswordInput/password-input.variants.d.ts +2 -2
  110. package/dist/components/PasswordInput/password-input.variants.js +62 -62
  111. package/dist/components/Prose/Prose.svelte +5 -5
  112. package/dist/components/Prose/Prose.svelte.d.ts +1 -1
  113. package/dist/components/Prose/index.d.ts +3 -3
  114. package/dist/components/Prose/index.js +3 -3
  115. package/dist/components/Prose/prose.types.d.ts +4 -4
  116. package/dist/components/Prose/prose.variants.d.ts +1 -1
  117. package/dist/components/Prose/prose.variants.js +27 -27
  118. package/dist/components/{Resizable/Resizable.svelte → ResizeContainer/ResizeContainer.svelte} +3 -3
  119. package/dist/components/ResizeContainer/ResizeContainer.svelte.d.ts +4 -0
  120. package/dist/components/ResizeContainer/index.d.ts +4 -0
  121. package/dist/components/ResizeContainer/index.js +4 -0
  122. package/dist/components/ResizeContainer/resize-container.types.d.ts +18 -0
  123. package/dist/components/ResizeContainer/resize-container.variants.d.ts +30 -0
  124. package/dist/components/ResizeContainer/resize-container.variants.js +17 -0
  125. package/dist/components/SafeTable/SafeTable.svelte +74 -74
  126. package/dist/components/SafeTable/SafeTable.svelte.d.ts +2 -2
  127. package/dist/components/SafeTable/index.d.ts +2 -2
  128. package/dist/components/SafeTable/index.js +1 -1
  129. package/dist/components/SafeTable/safe-table.types.d.ts +1 -1
  130. package/dist/components/Search/Search.svelte +63 -63
  131. package/dist/components/Search/Search.svelte.d.ts +1 -1
  132. package/dist/components/Search/index.d.ts +2 -2
  133. package/dist/components/Search/index.js +1 -1
  134. package/dist/components/Search/search.types.d.ts +5 -5
  135. package/dist/components/SortableGroup/SortableGroup.svelte +16 -10
  136. package/dist/components/SortableGroup/SortableGroup.svelte.d.ts +3 -3
  137. package/dist/components/SortableGroup/index.d.ts +1 -1
  138. package/dist/components/SortableGroup/index.js +1 -1
  139. package/dist/components/SortableList/SortableList.svelte +49 -46
  140. package/dist/components/SortableList/SortableList.svelte.d.ts +2 -2
  141. package/dist/components/SortableList/index.d.ts +2 -2
  142. package/dist/components/SortableList/index.js +1 -1
  143. package/dist/components/SortableList/sortable-list.types.d.ts +3 -3
  144. package/dist/components/Spotlight/Spotlight.svelte +13 -13
  145. package/dist/components/Spotlight/Spotlight.svelte.d.ts +1 -1
  146. package/dist/components/Spotlight/index.d.ts +3 -3
  147. package/dist/components/Spotlight/index.js +3 -3
  148. package/dist/components/Spotlight/spotlight.types.d.ts +2 -2
  149. package/dist/components/Spotlight/spotlight.variants.d.ts +1 -1
  150. package/dist/components/Spotlight/spotlight.variants.js +5 -5
  151. package/dist/components/TableBulkActionBar/TableBulkActionBar.svelte +23 -23
  152. package/dist/components/TableBulkActionBar/TableBulkActionBar.svelte.d.ts +1 -1
  153. package/dist/components/TableBulkActionBar/index.d.ts +2 -2
  154. package/dist/components/TableBulkActionBar/index.js +1 -1
  155. package/dist/components/TableBulkActionBar/table-bulk-action-bar.types.d.ts +3 -3
  156. package/dist/components/TableBulkActionBar/table-bulk-action-bar.variants.d.ts +1 -1
  157. package/dist/components/TableBulkActionBar/table-bulk-action-bar.variants.js +7 -7
  158. package/dist/components/TreeView/TreeView.svelte +59 -59
  159. package/dist/components/TreeView/TreeView.svelte.d.ts +1 -1
  160. package/dist/components/TreeView/index.d.ts +3 -3
  161. package/dist/components/TreeView/index.js +2 -2
  162. package/dist/components/TreeView/tree-view.types.d.ts +4 -4
  163. package/dist/components/TreeView/tree-view.variants.d.ts +1 -1
  164. package/dist/components/TreeView/tree-view.variants.js +19 -19
  165. package/dist/config.d.ts +1 -1
  166. package/dist/config.js +28 -28
  167. package/dist/editor.d.ts +1 -1
  168. package/dist/editor.js +1 -1
  169. package/dist/form/resolve-form-field-name.js +1 -1
  170. package/dist/hooks/internal/DragDropProviderScope.svelte +1 -1
  171. package/dist/hooks/internal/DragDropProviderScope.svelte.d.ts +1 -1
  172. package/dist/hooks/internal/SortableProvider.svelte +16 -11
  173. package/dist/hooks/internal/SortableProvider.svelte.d.ts +1 -1
  174. package/dist/hooks/internal/drag-drop-context.d.ts +1 -1
  175. package/dist/hooks/internal/drag-drop-context.js +1 -1
  176. package/dist/hooks/internal/sortable-context.d.ts +6 -6
  177. package/dist/hooks/internal/sortable-context.js +2 -2
  178. package/dist/hooks/useDragDrop/index.d.ts +1 -1
  179. package/dist/hooks/useDragDrop/index.js +1 -1
  180. package/dist/hooks/useDragDrop/useDragDrop.svelte.d.ts +3 -3
  181. package/dist/hooks/useDragDrop/useDragDrop.svelte.js +15 -15
  182. package/dist/hooks/useSortable/index.d.ts +2 -2
  183. package/dist/hooks/useSortable/index.js +2 -2
  184. package/dist/hooks/useSortable/useSortable.svelte.d.ts +4 -4
  185. package/dist/hooks/useSortable/useSortable.svelte.js +23 -23
  186. package/dist/hooks/utils.js +1 -1
  187. package/dist/index.d.ts +29 -31
  188. package/dist/index.js +28 -30
  189. package/dist/mcp/install-template.mjs +44 -44
  190. package/dist/mcp/server.mjs +262 -263
  191. package/dist/mcp/sv5ui-plus-docs.data.json +4 -10
  192. package/package.json +17 -14
  193. package/dist/components/ColorPicker/ColorPicker.svelte +0 -109
  194. package/dist/components/ColorPicker/ColorPicker.svelte.d.ts +0 -4
  195. package/dist/components/ColorPicker/color-picker.types.d.ts +0 -26
  196. package/dist/components/ColorPicker/color-picker.variants.d.ts +0 -69
  197. package/dist/components/ColorPicker/color-picker.variants.js +0 -13
  198. package/dist/components/ColorPicker/index.d.ts +0 -4
  199. package/dist/components/ColorPicker/index.js +0 -4
  200. package/dist/components/Resizable/Resizable.svelte.d.ts +0 -4
  201. package/dist/components/Resizable/index.d.ts +0 -4
  202. package/dist/components/Resizable/index.js +0 -4
  203. package/dist/components/Resizable/resizable.types.d.ts +0 -18
  204. package/dist/components/Resizable/resizable.types.js +0 -1
  205. package/dist/components/Resizable/resizable.variants.d.ts +0 -48
  206. package/dist/components/Resizable/resizable.variants.js +0 -17
  207. package/dist/components/ScrollArea/ScrollArea.svelte +0 -54
  208. package/dist/components/ScrollArea/ScrollArea.svelte.d.ts +0 -4
  209. package/dist/components/ScrollArea/index.d.ts +0 -4
  210. package/dist/components/ScrollArea/index.js +0 -4
  211. package/dist/components/ScrollArea/scroll-area.types.d.ts +0 -27
  212. package/dist/components/ScrollArea/scroll-area.types.js +0 -1
  213. package/dist/components/ScrollArea/scroll-area.variants.d.ts +0 -45
  214. package/dist/components/ScrollArea/scroll-area.variants.js +0 -27
  215. /package/dist/components/{ColorPicker/color-picker.types.js → ResizeContainer/resize-container.types.js} +0 -0
@@ -1,338 +1,337 @@
1
1
  #!/usr/bin/env node
2
2
 
3
- import { readFile } from 'node:fs/promises'
4
- import path from 'node:path'
5
- import { fileURLToPath } from 'node:url'
3
+ import { readFile } from "node:fs/promises";
4
+ import path from "node:path";
5
+ import { fileURLToPath } from "node:url";
6
6
 
7
- import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'
8
- import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js'
9
- import { codeToHtml } from 'shiki'
10
- import { z } from 'zod'
7
+ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
8
+ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
9
+ import { codeToHtml } from "shiki";
10
+ import { z } from "zod";
11
11
 
12
- const __filename = fileURLToPath(import.meta.url)
13
- const __dirname = path.dirname(__filename)
14
- const repoRoot = path.resolve(__dirname, '../../')
15
- const packagedDataPath = path.resolve(__dirname, './sv5ui-plus-docs.data.json')
12
+ const __filename = fileURLToPath(import.meta.url);
13
+ const __dirname = path.dirname(__filename);
14
+ const repoRoot = path.resolve(__dirname, "../../");
15
+ const packagedDataPath = path.resolve(__dirname, "./sv5ui-plus-docs.data.json");
16
16
 
17
- let packagedDataPromise
17
+ let packagedDataPromise;
18
18
 
19
19
  function resolveRepoPath(relativePath) {
20
- const fullPath = path.resolve(repoRoot, relativePath)
21
- if (!fullPath.startsWith(repoRoot)) {
22
- throw new Error('Invalid path')
23
- }
24
- return fullPath
20
+ const fullPath = path.resolve(repoRoot, relativePath);
21
+ if (!fullPath.startsWith(repoRoot)) {
22
+ throw new Error("Invalid path");
23
+ }
24
+ return fullPath;
25
25
  }
26
26
 
27
27
  async function readJsonIfExists(filePath) {
28
- try {
29
- const source = await readFile(filePath, 'utf8')
30
- return JSON.parse(source)
31
- } catch (error) {
32
- if (error && typeof error === 'object' && 'code' in error && error.code === 'ENOENT') {
33
- return null
34
- }
35
- throw error
36
- }
28
+ try {
29
+ const source = await readFile(filePath, "utf8");
30
+ return JSON.parse(source);
31
+ } catch (error) {
32
+ if (error && typeof error === "object" && "code" in error && error.code === "ENOENT") {
33
+ return null;
34
+ }
35
+ throw error;
36
+ }
37
37
  }
38
38
 
39
39
  async function getPackagedData() {
40
- packagedDataPromise ??= readJsonIfExists(packagedDataPath)
41
- return await packagedDataPromise
40
+ packagedDataPromise ??= readJsonIfExists(packagedDataPath);
41
+ return await packagedDataPromise;
42
42
  }
43
43
 
44
44
  function normalizeCode(code) {
45
- const lines = code.replaceAll('\r\n', '\n').split('\n')
46
- const firstNonEmpty = lines.findIndex((line) => line.trim().length > 0)
47
- if (firstNonEmpty === -1) return ''
48
-
49
- let lastNonEmptyFromEnd = 0
50
- for (let index = lines.length - 1; index >= 0; index -= 1) {
51
- if (lines[index].trim().length > 0) break
52
- lastNonEmptyFromEnd += 1
53
- }
54
-
55
- const trimmed = lines.slice(firstNonEmpty, lines.length - lastNonEmptyFromEnd)
56
- const indents = trimmed
57
- .filter((line) => line.trim().length > 0)
58
- .map((line) => line.match(/^(\s*)/)?.[1].length ?? 0)
59
-
60
- const minIndent = indents.length > 0 ? Math.min(...indents) : 0
61
- return trimmed
62
- .map((line) => line.slice(minIndent))
63
- .join('\n')
64
- .trim()
45
+ const lines = code.replaceAll("\r\n", "\n").split("\n");
46
+ const firstNonEmpty = lines.findIndex((line) => line.trim().length > 0);
47
+ if (firstNonEmpty === -1) return "";
48
+
49
+ let lastNonEmptyFromEnd = 0;
50
+ for (let index = lines.length - 1; index >= 0; index -= 1) {
51
+ if (lines[index].trim().length > 0) break;
52
+ lastNonEmptyFromEnd += 1;
53
+ }
54
+
55
+ const trimmed = lines.slice(firstNonEmpty, lines.length - lastNonEmptyFromEnd);
56
+ const indents = trimmed
57
+ .filter((line) => line.trim().length > 0)
58
+ .map((line) => line.match(/^(\s*)/)?.[1].length ?? 0);
59
+
60
+ const minIndent = indents.length > 0 ? Math.min(...indents) : 0;
61
+ return trimmed
62
+ .map((line) => line.slice(minIndent))
63
+ .join("\n")
64
+ .trim();
65
65
  }
66
66
 
67
67
  function unwrapPreviewWrappers(source) {
68
- let current = source.trim()
69
-
70
- const stripPrefix = (token) => token.split(':').at(-1) ?? token
71
- const isPresentationToken = (token) => {
72
- const t = stripPrefix(token)
73
- if (t.length === 0) return false
74
-
75
- if (t.startsWith('max-w-') || t.startsWith('min-w-') || t.startsWith('w-')) return true
76
- if (t.startsWith('max-h-') || t.startsWith('min-h-') || t.startsWith('h-')) return true
77
- if (/^(m|p)[trblxyse]?-\d+$/.test(t)) return true
78
- if (t.startsWith('gap-') || t.startsWith('space-')) return true
79
- if (t.startsWith('overflow-')) return true
80
- if (t === 'grid' || t.startsWith('grid-')) return true
81
- if (t === 'flex' || t === 'inline-flex' || t.startsWith('flex-')) return true
82
- if (t.startsWith('items-') || t.startsWith('justify-') || t.startsWith('content-'))
83
- return true
84
- if (t.startsWith('self-') || t.startsWith('place-')) return true
85
- if (t.startsWith('rounded')) return true
86
- if (t.startsWith('border') || t.startsWith('ring') || t.startsWith('shadow')) return true
87
- if (t === 'bg-transparent') return true
88
- if (t.startsWith('bg-surface')) return true
89
- if (t.startsWith('bg-[')) return true
90
- if (t.startsWith('text-') || t.startsWith('font-') || t.startsWith('leading-')) return true
91
- if (t.startsWith('tracking-')) return true
92
- if (t === 'uppercase' || t === 'lowercase' || t === 'capitalize') return true
93
- if (t.startsWith('opacity-')) return true
94
- if (t.startsWith('backdrop-blur') || t.startsWith('blur')) return true
95
- if (t.startsWith('aspect-') || t.startsWith('object-')) return true
96
- if (t.startsWith('size-')) return true
97
- if (t.startsWith('[') && t.includes(']:')) return true
98
-
99
- return false
100
- }
101
-
102
- for (let pass = 0; pass < 3; pass += 1) {
103
- const match = current.match(/^<div\b([^>]*)>([\s\S]*)<\/div>$/)
104
- if (!match) break
105
-
106
- const attrs = match[1]
107
- const attrsWithoutClass = attrs
108
- .replace(/\s*\bclass=(?:"[^"]*"|'[^']*')/, '')
109
- .replace(/\s+/g, ' ')
110
- .trim()
111
- if (attrsWithoutClass.length > 0) break
112
-
113
- const classMatch = attrs.match(/\bclass=(?:"([^"]*)"|'([^']*)')/)
114
- const classValue = (classMatch?.[1] ?? classMatch?.[2] ?? '').trim()
115
- const tokens = classValue.length > 0 ? classValue.split(/\s+/) : []
116
-
117
- const isPreviewBg = tokens.some((token) => token.startsWith('bg-surface-container'))
118
- const isBordered = tokens.some((token) => token.startsWith('border-outline-variant'))
119
- const isRounded = tokens.some((token) => token.startsWith('rounded'))
120
- const hasPadding = tokens.some((token) => /^p[trblxy]?-\d+$/.test(token))
121
- const isMaxWidth = tokens.some((token) => token.startsWith('max-w-'))
122
- const isOverflow = tokens.some((token) => token.startsWith('overflow-'))
123
- const isPresentationOnly = tokens.length > 0 && tokens.every(isPresentationToken)
124
-
125
- const shouldUnwrap = ((isPreviewBg || isBordered || isRounded) && hasPadding) || isOverflow
126
- const shouldUnwrapMaxWidth = isMaxWidth && isPresentationOnly
127
-
128
- if (!shouldUnwrap && !shouldUnwrapMaxWidth) break
129
-
130
- current = match[2].trim()
131
- }
132
-
133
- return current
68
+ let current = source.trim();
69
+
70
+ const stripPrefix = (token) => token.split(":").at(-1) ?? token;
71
+ const isPresentationToken = (token) => {
72
+ const t = stripPrefix(token);
73
+ if (t.length === 0) return false;
74
+
75
+ if (t.startsWith("max-w-") || t.startsWith("min-w-") || t.startsWith("w-")) return true;
76
+ if (t.startsWith("max-h-") || t.startsWith("min-h-") || t.startsWith("h-")) return true;
77
+ if (/^(m|p)[trblxyse]?-\d+$/.test(t)) return true;
78
+ if (t.startsWith("gap-") || t.startsWith("space-")) return true;
79
+ if (t.startsWith("overflow-")) return true;
80
+ if (t === "grid" || t.startsWith("grid-")) return true;
81
+ if (t === "flex" || t === "inline-flex" || t.startsWith("flex-")) return true;
82
+ if (t.startsWith("items-") || t.startsWith("justify-") || t.startsWith("content-")) return true;
83
+ if (t.startsWith("self-") || t.startsWith("place-")) return true;
84
+ if (t.startsWith("rounded")) return true;
85
+ if (t.startsWith("border") || t.startsWith("ring") || t.startsWith("shadow")) return true;
86
+ if (t === "bg-transparent") return true;
87
+ if (t.startsWith("bg-surface")) return true;
88
+ if (t.startsWith("bg-[")) return true;
89
+ if (t.startsWith("text-") || t.startsWith("font-") || t.startsWith("leading-")) return true;
90
+ if (t.startsWith("tracking-")) return true;
91
+ if (t === "uppercase" || t === "lowercase" || t === "capitalize") return true;
92
+ if (t.startsWith("opacity-")) return true;
93
+ if (t.startsWith("backdrop-blur") || t.startsWith("blur")) return true;
94
+ if (t.startsWith("aspect-") || t.startsWith("object-")) return true;
95
+ if (t.startsWith("size-")) return true;
96
+ if (t.startsWith("[") && t.includes("]:")) return true;
97
+
98
+ return false;
99
+ };
100
+
101
+ for (let pass = 0; pass < 3; pass += 1) {
102
+ const match = current.match(/^<div\b([^>]*)>([\s\S]*)<\/div>$/);
103
+ if (!match) break;
104
+
105
+ const attrs = match[1];
106
+ const attrsWithoutClass = attrs
107
+ .replace(/\s*\bclass=(?:"[^"]*"|'[^']*')/, "")
108
+ .replace(/\s+/g, " ")
109
+ .trim();
110
+ if (attrsWithoutClass.length > 0) break;
111
+
112
+ const classMatch = attrs.match(/\bclass=(?:"([^"]*)"|'([^']*)')/);
113
+ const classValue = (classMatch?.[1] ?? classMatch?.[2] ?? "").trim();
114
+ const tokens = classValue.length > 0 ? classValue.split(/\s+/) : [];
115
+
116
+ const isPreviewBg = tokens.some((token) => token.startsWith("bg-surface-container"));
117
+ const isBordered = tokens.some((token) => token.startsWith("border-outline-variant"));
118
+ const isRounded = tokens.some((token) => token.startsWith("rounded"));
119
+ const hasPadding = tokens.some((token) => /^p[trblxy]?-\d+$/.test(token));
120
+ const isMaxWidth = tokens.some((token) => token.startsWith("max-w-"));
121
+ const isOverflow = tokens.some((token) => token.startsWith("overflow-"));
122
+ const isPresentationOnly = tokens.length > 0 && tokens.every(isPresentationToken);
123
+
124
+ const shouldUnwrap = ((isPreviewBg || isBordered || isRounded) && hasPadding) || isOverflow;
125
+ const shouldUnwrapMaxWidth = isMaxWidth && isPresentationOnly;
126
+
127
+ if (!shouldUnwrap && !shouldUnwrapMaxWidth) break;
128
+
129
+ current = match[2].trim();
130
+ }
131
+
132
+ return current;
134
133
  }
135
134
 
136
135
  function decodeHeading(value) {
137
- return value
138
- .replaceAll('&amp;', '&')
139
- .replaceAll('&times;', '×')
140
- .replaceAll('&#39;', "'")
141
- .replaceAll('&quot;', '"')
142
- .trim()
136
+ return value
137
+ .replaceAll("&amp;", "&")
138
+ .replaceAll("&times;", "×")
139
+ .replaceAll("&#39;", "'")
140
+ .replaceAll("&quot;", '"')
141
+ .trim();
143
142
  }
144
143
 
145
144
  function extractSectionHeading(sectionSource) {
146
- const match = sectionSource.match(/<h2\b[^>]*>([\s\S]*?)<\/h2>/)
147
- if (!match) return ''
148
- return decodeHeading(match[1].replace(/<[^>]+>/g, ' '))
145
+ const match = sectionSource.match(/<h2\b[^>]*>([\s\S]*?)<\/h2>/);
146
+ if (!match) return "";
147
+ return decodeHeading(match[1].replace(/<[^>]+>/g, " "));
149
148
  }
150
149
 
151
150
  function extractSectionSnippet(sectionSource) {
152
- const openTagEnd = sectionSource.indexOf('>')
153
- const closeTagStart = sectionSource.lastIndexOf('</section>')
151
+ const openTagEnd = sectionSource.indexOf(">");
152
+ const closeTagStart = sectionSource.lastIndexOf("</section>");
154
153
 
155
- if (openTagEnd < 0 || closeTagStart < 0) {
156
- return normalizeCode(sectionSource)
157
- }
154
+ if (openTagEnd < 0 || closeTagStart < 0) {
155
+ return normalizeCode(sectionSource);
156
+ }
158
157
 
159
- let inner = sectionSource.slice(openTagEnd + 1, closeTagStart)
160
- inner = inner.replace(/^\s*<h2\b[\s\S]*?<\/h2>\s*/, '')
161
- inner = inner.replace(/^\s*<!--[\s\S]*?-->\s*/g, '')
158
+ let inner = sectionSource.slice(openTagEnd + 1, closeTagStart);
159
+ inner = inner.replace(/^\s*<h2\b[\s\S]*?<\/h2>\s*/, "");
160
+ inner = inner.replace(/^\s*<!--[\s\S]*?-->\s*/g, "");
162
161
 
163
- while (/^\s*<p\b[\s\S]*?<\/p>\s*/.test(inner)) {
164
- inner = inner.replace(/^\s*<p\b[\s\S]*?<\/p>\s*/, '')
165
- }
162
+ while (/^\s*<p\b[\s\S]*?<\/p>\s*/.test(inner)) {
163
+ inner = inner.replace(/^\s*<p\b[\s\S]*?<\/p>\s*/, "");
164
+ }
166
165
 
167
- inner = inner.replace(/\s*<!--[\s\S]*?-->\s*$/g, '')
168
- inner = unwrapPreviewWrappers(inner)
169
- return normalizeCode(inner)
166
+ inner = inner.replace(/\s*<!--[\s\S]*?-->\s*$/g, "");
167
+ inner = unwrapPreviewWrappers(inner);
168
+ return normalizeCode(inner);
170
169
  }
171
170
 
172
171
  function getSectionSnippets(source) {
173
- return [...source.matchAll(/<section\b[\s\S]*?<\/section>/g)].map((match) => {
174
- const sectionSource = match[0]
175
- return {
176
- heading: extractSectionHeading(sectionSource),
177
- snippet: extractSectionSnippet(sectionSource)
178
- }
179
- })
172
+ return [...source.matchAll(/<section\b[\s\S]*?<\/section>/g)].map((match) => {
173
+ const sectionSource = match[0];
174
+ return {
175
+ heading: extractSectionHeading(sectionSource),
176
+ snippet: extractSectionSnippet(sectionSource),
177
+ };
178
+ });
180
179
  }
181
180
 
182
181
  function detectLanguage(code) {
183
- const source = code.trim()
184
-
185
- if (
186
- source.includes('<script lang="ts">') ||
187
- source.includes('$state(') ||
188
- source.includes('{#each') ||
189
- source.includes('<Button') ||
190
- source.includes('<FormField')
191
- ) {
192
- return 'svelte'
193
- }
194
-
195
- if (source.startsWith('{') || source.startsWith('[')) {
196
- return 'json'
197
- }
198
-
199
- if (
200
- source.startsWith('@import') ||
201
- (source.includes('{') && source.includes(':') && source.includes(';'))
202
- ) {
203
- return 'css'
204
- }
205
-
206
- if (source.startsWith('#') || source.startsWith('bun ') || source.startsWith('npm ')) {
207
- return 'bash'
208
- }
209
-
210
- if (source.includes('export ') || source.includes('import ') || source.includes('interface ')) {
211
- return 'ts'
212
- }
213
-
214
- return 'html'
182
+ const source = code.trim();
183
+
184
+ if (
185
+ source.includes('<script lang="ts">') ||
186
+ source.includes("$state(") ||
187
+ source.includes("{#each") ||
188
+ source.includes("<Button") ||
189
+ source.includes("<FormField")
190
+ ) {
191
+ return "svelte";
192
+ }
193
+
194
+ if (source.startsWith("{") || source.startsWith("[")) {
195
+ return "json";
196
+ }
197
+
198
+ if (
199
+ source.startsWith("@import") ||
200
+ (source.includes("{") && source.includes(":") && source.includes(";"))
201
+ ) {
202
+ return "css";
203
+ }
204
+
205
+ if (source.startsWith("#") || source.startsWith("bun ") || source.startsWith("npm ")) {
206
+ return "bash";
207
+ }
208
+
209
+ if (source.includes("export ") || source.includes("import ") || source.includes("interface ")) {
210
+ return "ts";
211
+ }
212
+
213
+ return "html";
215
214
  }
216
215
 
217
216
  function decorateHighlightedHtml(html) {
218
- return html.replace(/<pre class="shiki[\s\S]*?"[^>]*>/, '<pre class="shiki">')
217
+ return html.replace(/<pre class="shiki[\s\S]*?"[^>]*>/, '<pre class="shiki">');
219
218
  }
220
219
 
221
220
  async function renderHighlightedCode(code, isDarkMode = true) {
222
- const html = await codeToHtml(code, {
223
- lang: detectLanguage(code),
224
- theme: isDarkMode ? 'github-dark' : 'github-light'
225
- })
226
- return decorateHighlightedHtml(html)
221
+ const html = await codeToHtml(code, {
222
+ lang: detectLanguage(code),
223
+ theme: isDarkMode ? "github-dark" : "github-light",
224
+ });
225
+ return decorateHighlightedHtml(html);
227
226
  }
228
227
 
229
228
  function getPagePathFromSlug(slug) {
230
- return `src/routes/${slug}/+page.svelte`
229
+ return `src/routes/${slug}/+page.svelte`;
231
230
  }
232
231
 
233
232
  async function readRouteSource(slug) {
234
- const packagedData = await getPackagedData()
235
- if (packagedData?.pages?.[slug]) {
236
- return packagedData.pages[slug]
237
- }
233
+ const packagedData = await getPackagedData();
234
+ if (packagedData?.pages?.[slug]) {
235
+ return packagedData.pages[slug];
236
+ }
238
237
 
239
- const filePath = resolveRepoPath(getPagePathFromSlug(slug))
240
- return await readFile(filePath, 'utf8')
238
+ const filePath = resolveRepoPath(getPagePathFromSlug(slug));
239
+ return await readFile(filePath, "utf8");
241
240
  }
242
241
 
243
242
  async function readDocsNavigationSource() {
244
- const filePath = resolveRepoPath('src/internal/docs/navigation.ts')
245
- return await readFile(filePath, 'utf8')
243
+ const filePath = resolveRepoPath("src/internal/docs/navigation.ts");
244
+ return await readFile(filePath, "utf8");
246
245
  }
247
246
 
248
247
  async function listDocSlugs() {
249
- const packagedData = await getPackagedData()
250
- if (packagedData?.slugs) {
251
- return packagedData.slugs
252
- }
248
+ const packagedData = await getPackagedData();
249
+ if (packagedData?.slugs) {
250
+ return packagedData.slugs;
251
+ }
253
252
 
254
- const navigationSource = await readDocsNavigationSource()
255
- return extractDocSlugs(navigationSource)
253
+ const navigationSource = await readDocsNavigationSource();
254
+ return extractDocSlugs(navigationSource);
256
255
  }
257
256
 
258
257
  function extractDocSlugs(navigationSource) {
259
- const componentSlugs = []
260
- const hookSlugs = []
258
+ const componentSlugs = [];
259
+ const hookSlugs = [];
261
260
 
262
- for (const match of navigationSource.matchAll(/href:\s*'\/docs\/components\/([^']+)'/g)) {
263
- componentSlugs.push(match[1])
264
- }
261
+ for (const match of navigationSource.matchAll(/href:\s*'\/docs\/components\/([^']+)'/g)) {
262
+ componentSlugs.push(match[1]);
263
+ }
265
264
 
266
- for (const match of navigationSource.matchAll(/href:\s*'\/docs\/hooks\/([^']+)'/g)) {
267
- hookSlugs.push(match[1])
268
- }
265
+ for (const match of navigationSource.matchAll(/href:\s*'\/docs\/hooks\/([^']+)'/g)) {
266
+ hookSlugs.push(match[1]);
267
+ }
269
268
 
270
- return {
271
- components: Array.from(new Set(componentSlugs)),
272
- hooks: Array.from(new Set(hookSlugs))
273
- }
269
+ return {
270
+ components: Array.from(new Set(componentSlugs)),
271
+ hooks: Array.from(new Set(hookSlugs)),
272
+ };
274
273
  }
275
274
 
276
275
  const server = new McpServer({
277
- name: 'sv5ui-plus-docs',
278
- version: '0.1.0'
279
- })
276
+ name: "sv5ui-plus-docs",
277
+ version: "0.1.0",
278
+ });
280
279
 
281
280
  server.tool(
282
- 'sv5ui_plus_docs_list_slugs',
283
- 'List docs slugs from src/internal/docs/navigation.ts (components + hooks)',
284
- {},
285
- async () => {
286
- const slugs = await listDocSlugs()
287
-
288
- return {
289
- content: [
290
- {
291
- type: 'text',
292
- text: JSON.stringify(slugs, null, 2)
293
- }
294
- ]
295
- }
296
- }
297
- )
281
+ "sv5ui_plus_docs_list_slugs",
282
+ "List docs slugs from src/internal/docs/navigation.ts (components + hooks)",
283
+ {},
284
+ async () => {
285
+ const slugs = await listDocSlugs();
286
+
287
+ return {
288
+ content: [
289
+ {
290
+ type: "text",
291
+ text: JSON.stringify(slugs, null, 2),
292
+ },
293
+ ],
294
+ };
295
+ },
296
+ );
298
297
 
299
298
  server.tool(
300
- 'sv5ui_plus_docs_get_page_source',
301
- 'Read src/routes/[slug]/+page.svelte and return as text',
302
- {
303
- slug: z.string().min(1).describe('Route slug, e.g. button, select-menu, use-form-field')
304
- },
305
- async ({ slug }) => {
306
- const source = await readRouteSource(slug)
307
- return { content: [{ type: 'text', text: source }] }
308
- }
309
- )
299
+ "sv5ui_plus_docs_get_page_source",
300
+ "Read src/routes/[slug]/+page.svelte and return as text",
301
+ {
302
+ slug: z.string().min(1).describe("Route slug, e.g. button, select-menu, use-form-field"),
303
+ },
304
+ async ({ slug }) => {
305
+ const source = await readRouteSource(slug);
306
+ return { content: [{ type: "text", text: source }] };
307
+ },
308
+ );
310
309
 
311
310
  server.tool(
312
- 'sv5ui_plus_docs_get_section_snippets',
313
- 'Extract all <section> headings and code snippets from a route page source',
314
- {
315
- slug: z.string().min(1).describe('Route slug, e.g. button, select-menu, use-form-field')
316
- },
317
- async ({ slug }) => {
318
- const source = await readRouteSource(slug)
319
- const sections = getSectionSnippets(source)
320
- return { content: [{ type: 'text', text: JSON.stringify(sections, null, 2) }] }
321
- }
322
- )
311
+ "sv5ui_plus_docs_get_section_snippets",
312
+ "Extract all <section> headings and code snippets from a route page source",
313
+ {
314
+ slug: z.string().min(1).describe("Route slug, e.g. button, select-menu, use-form-field"),
315
+ },
316
+ async ({ slug }) => {
317
+ const source = await readRouteSource(slug);
318
+ const sections = getSectionSnippets(source);
319
+ return { content: [{ type: "text", text: JSON.stringify(sections, null, 2) }] };
320
+ },
321
+ );
323
322
 
324
323
  server.tool(
325
- 'sv5ui_plus_docs_render_shiki',
326
- 'Render highlighted HTML (Shiki) for a code snippet. Returns <pre class="shiki">...</pre> HTML',
327
- {
328
- code: z.string().min(1).describe('Code string'),
329
- isDarkMode: z.boolean().optional().describe('Use dark theme when true')
330
- },
331
- async ({ code, isDarkMode }) => {
332
- const html = await renderHighlightedCode(code, isDarkMode ?? true)
333
- return { content: [{ type: 'text', text: html }] }
334
- }
335
- )
336
-
337
- const transport = new StdioServerTransport()
338
- await server.connect(transport)
324
+ "sv5ui_plus_docs_render_shiki",
325
+ 'Render highlighted HTML (Shiki) for a code snippet. Returns <pre class="shiki">...</pre> HTML',
326
+ {
327
+ code: z.string().min(1).describe("Code string"),
328
+ isDarkMode: z.boolean().optional().describe("Use dark theme when true"),
329
+ },
330
+ async ({ code, isDarkMode }) => {
331
+ const html = await renderHighlightedCode(code, isDarkMode ?? true);
332
+ return { content: [{ type: "text", text: html }] };
333
+ },
334
+ );
335
+
336
+ const transport = new StdioServerTransport();
337
+ await server.connect(transport);