@svadmin/lite 0.17.0 → 0.22.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 (226) hide show
  1. package/README.md +71 -2
  2. package/dist/components/LiteActivityFeed.svelte +24 -2
  3. package/dist/components/LiteActivityFeed.svelte.d.ts +6 -0
  4. package/dist/components/LiteAffix.svelte +29 -0
  5. package/dist/components/LiteAffix.svelte.d.ts +13 -0
  6. package/dist/components/LiteAnchor.svelte +38 -0
  7. package/dist/components/LiteAnchor.svelte.d.ts +14 -0
  8. package/dist/components/LiteApprovalActionCard.svelte +4 -1
  9. package/dist/components/LiteApprovalActionCard.svelte.d.ts +2 -0
  10. package/dist/components/LiteAutoComplete.svelte +41 -0
  11. package/dist/components/LiteAutoComplete.svelte.d.ts +13 -0
  12. package/dist/components/LiteBackTop.svelte +16 -0
  13. package/dist/components/LiteBackTop.svelte.d.ts +8 -0
  14. package/dist/components/LiteBreadcrumbs.svelte +4 -1
  15. package/dist/components/LiteBreadcrumbs.svelte.d.ts +2 -0
  16. package/dist/components/LiteCalendar.svelte +124 -0
  17. package/dist/components/LiteCalendar.svelte.d.ts +20 -0
  18. package/dist/components/LiteCarousel.svelte +72 -0
  19. package/dist/components/LiteCarousel.svelte.d.ts +14 -0
  20. package/dist/components/LiteCollapse.svelte +49 -0
  21. package/dist/components/LiteCollapse.svelte.d.ts +15 -0
  22. package/dist/components/LiteColumnHeaderFilter.svelte +4 -1
  23. package/dist/components/LiteColumnHeaderFilter.svelte.d.ts +2 -0
  24. package/dist/components/LiteColumnSettings.svelte +4 -1
  25. package/dist/components/LiteColumnSettings.svelte.d.ts +2 -0
  26. package/dist/components/LiteCommentThread.svelte +113 -0
  27. package/dist/components/LiteCommentThread.svelte.d.ts +26 -0
  28. package/dist/components/LiteCountdown.svelte +49 -0
  29. package/dist/components/LiteCountdown.svelte.d.ts +10 -0
  30. package/dist/components/LiteDetailDrawer.svelte +45 -0
  31. package/dist/components/LiteDetailDrawer.svelte.d.ts +14 -0
  32. package/dist/components/LiteDraggableRowTable.svelte +4 -1
  33. package/dist/components/LiteDraggableRowTable.svelte.d.ts +2 -0
  34. package/dist/components/LiteDrawerForm.svelte +4 -1
  35. package/dist/components/LiteDrawerForm.svelte.d.ts +2 -0
  36. package/dist/components/LiteEditableTable.svelte +4 -1
  37. package/dist/components/LiteEditableTable.svelte.d.ts +2 -0
  38. package/dist/components/LiteEmptyState.svelte +8 -1
  39. package/dist/components/LiteEmptyState.svelte.d.ts +3 -0
  40. package/dist/components/LiteFilterBuilder.svelte +4 -1
  41. package/dist/components/LiteFilterBuilder.svelte.d.ts +2 -0
  42. package/dist/components/LiteFloatButton.svelte +54 -0
  43. package/dist/components/LiteFloatButton.svelte.d.ts +15 -0
  44. package/dist/components/LiteGrid.svelte +34 -0
  45. package/dist/components/LiteGrid.svelte.d.ts +11 -0
  46. package/dist/components/LiteImage.svelte +54 -0
  47. package/dist/components/LiteImage.svelte.d.ts +14 -0
  48. package/dist/components/LiteImageCropper.svelte +4 -1
  49. package/dist/components/LiteImageCropper.svelte.d.ts +2 -0
  50. package/dist/components/LiteImagePreview.svelte +36 -0
  51. package/dist/components/LiteImagePreview.svelte.d.ts +13 -0
  52. package/dist/components/LiteItemList.svelte +50 -0
  53. package/dist/components/LiteItemList.svelte.d.ts +15 -0
  54. package/dist/components/LiteJsonSchemaForm.svelte +4 -1
  55. package/dist/components/LiteJsonSchemaForm.svelte.d.ts +2 -0
  56. package/dist/components/LiteLayout.svelte +16 -4
  57. package/dist/components/LiteLayout.svelte.d.ts +8 -0
  58. package/dist/components/LiteLink.svelte +32 -0
  59. package/dist/components/LiteLink.svelte.d.ts +11 -0
  60. package/dist/components/LiteLogin.svelte +9 -2
  61. package/dist/components/LiteLogin.svelte.d.ts +2 -0
  62. package/dist/components/LiteMasterDetailView.svelte +4 -1
  63. package/dist/components/LiteMasterDetailView.svelte.d.ts +2 -0
  64. package/dist/components/LiteMediaLibraryModal.svelte +4 -1
  65. package/dist/components/LiteMediaLibraryModal.svelte.d.ts +2 -0
  66. package/dist/components/LiteMenu.svelte +22 -0
  67. package/dist/components/LiteMenu.svelte.d.ts +12 -0
  68. package/dist/components/LiteMenuList.svelte +55 -0
  69. package/dist/components/LiteMenuList.svelte.d.ts +17 -0
  70. package/dist/components/LiteModalForm.svelte +4 -1
  71. package/dist/components/LiteModalForm.svelte.d.ts +2 -0
  72. package/dist/components/LiteNotificationCenter.svelte +85 -0
  73. package/dist/components/LiteNotificationCenter.svelte.d.ts +22 -0
  74. package/dist/components/LiteOtpInput.svelte +50 -0
  75. package/dist/components/LiteOtpInput.svelte.d.ts +15 -0
  76. package/dist/components/LitePageHeader.svelte +34 -0
  77. package/dist/components/LitePageHeader.svelte.d.ts +13 -0
  78. package/dist/components/LitePagination.svelte +10 -2
  79. package/dist/components/LitePagination.svelte.d.ts +2 -0
  80. package/dist/components/LitePopconfirm.svelte +49 -0
  81. package/dist/components/LitePopconfirm.svelte.d.ts +14 -0
  82. package/dist/components/LitePresenceAvatarGroup.svelte +4 -1
  83. package/dist/components/LitePresenceAvatarGroup.svelte.d.ts +2 -0
  84. package/dist/components/LitePrintableBill.svelte +4 -1
  85. package/dist/components/LitePrintableBill.svelte.d.ts +2 -0
  86. package/dist/components/LiteProgress.svelte +46 -0
  87. package/dist/components/LiteProgress.svelte.d.ts +12 -0
  88. package/dist/components/LiteQRCode.svelte +62 -0
  89. package/dist/components/LiteQRCode.svelte.d.ts +14 -0
  90. package/dist/components/LiteResizeBox.svelte +34 -0
  91. package/dist/components/LiteResizeBox.svelte.d.ts +12 -0
  92. package/dist/components/LiteResult.svelte +52 -0
  93. package/dist/components/LiteResult.svelte.d.ts +14 -0
  94. package/dist/components/LiteRowActions.svelte +36 -0
  95. package/dist/components/LiteRowActions.svelte.d.ts +17 -0
  96. package/dist/components/LiteSensitiveDataMask.svelte +4 -1
  97. package/dist/components/LiteSensitiveDataMask.svelte.d.ts +2 -0
  98. package/dist/components/LiteSkeleton.svelte +100 -0
  99. package/dist/components/LiteSkeleton.svelte.d.ts +19 -0
  100. package/dist/components/LiteSpace.svelte +31 -0
  101. package/dist/components/LiteSpace.svelte.d.ts +12 -0
  102. package/dist/components/LiteSpin.svelte +27 -0
  103. package/dist/components/LiteSpin.svelte.d.ts +10 -0
  104. package/dist/components/LiteSplitPaneLayout.svelte +16 -4
  105. package/dist/components/LiteSplitPaneLayout.svelte.d.ts +8 -0
  106. package/dist/components/LiteStatistic.svelte +63 -0
  107. package/dist/components/LiteStatistic.svelte.d.ts +15 -0
  108. package/dist/components/LiteStatsCard.svelte +5 -2
  109. package/dist/components/LiteStatsCard.svelte.d.ts +2 -0
  110. package/dist/components/LiteStatusBadge.svelte +33 -0
  111. package/dist/components/LiteStatusBadge.svelte.d.ts +12 -0
  112. package/dist/components/LiteStatusTabs.svelte +35 -0
  113. package/dist/components/LiteStatusTabs.svelte.d.ts +14 -0
  114. package/dist/components/LiteStepForm.svelte +4 -1
  115. package/dist/components/LiteStepForm.svelte.d.ts +2 -0
  116. package/dist/components/LiteSteps.svelte +64 -0
  117. package/dist/components/LiteSteps.svelte.d.ts +18 -0
  118. package/dist/components/LiteTable.svelte +4 -1
  119. package/dist/components/LiteTable.svelte.d.ts +2 -0
  120. package/dist/components/LiteTableSummary.svelte +4 -1
  121. package/dist/components/LiteTableSummary.svelte.d.ts +2 -0
  122. package/dist/components/LiteTabs.svelte +28 -18
  123. package/dist/components/LiteTabs.svelte.d.ts +11 -2
  124. package/dist/components/LiteTag.svelte +31 -0
  125. package/dist/components/LiteTag.svelte.d.ts +13 -0
  126. package/dist/components/LiteTimeline.svelte +48 -0
  127. package/dist/components/LiteTimeline.svelte.d.ts +17 -0
  128. package/dist/components/LiteTour.svelte +54 -0
  129. package/dist/components/LiteTour.svelte.d.ts +15 -0
  130. package/dist/components/LiteTransfer.svelte +4 -1
  131. package/dist/components/LiteTransfer.svelte.d.ts +2 -0
  132. package/dist/components/LiteTree.svelte +48 -0
  133. package/dist/components/LiteTree.svelte.d.ts +17 -0
  134. package/dist/components/LiteTwoFactorStepper.svelte +53 -0
  135. package/dist/components/LiteTwoFactorStepper.svelte.d.ts +16 -0
  136. package/dist/components/LiteVersionDiffViewer.svelte +4 -1
  137. package/dist/components/LiteVersionDiffViewer.svelte.d.ts +2 -0
  138. package/dist/components/LiteVideoPlayer.svelte +67 -0
  139. package/dist/components/LiteVideoPlayer.svelte.d.ts +22 -0
  140. package/dist/components/advanced/LiteAutoSaveIndicator.svelte +42 -13
  141. package/dist/components/advanced/LiteAutoSaveIndicator.svelte.d.ts +10 -4
  142. package/dist/components/advanced/LiteDrawerForm.svelte +4 -1
  143. package/dist/components/advanced/LiteDrawerForm.svelte.d.ts +2 -0
  144. package/dist/components/advanced/LiteModalForm.svelte +4 -1
  145. package/dist/components/advanced/LiteModalForm.svelte.d.ts +2 -0
  146. package/dist/components/compatibility/LiteRealtimeStatus.svelte +41 -2
  147. package/dist/components/compatibility/LiteRealtimeStatus.svelte.d.ts +15 -0
  148. package/dist/components/fields/LiteBooleanField.svelte +4 -2
  149. package/dist/components/fields/LiteBooleanField.svelte.d.ts +2 -0
  150. package/dist/components/fields/LiteCascader.svelte +5 -2
  151. package/dist/components/fields/LiteCascader.svelte.d.ts +2 -0
  152. package/dist/components/fields/LiteDateField.svelte +39 -9
  153. package/dist/components/fields/LiteDateField.svelte.d.ts +2 -0
  154. package/dist/components/fields/LiteImageField.svelte +6 -2
  155. package/dist/components/fields/LiteImageField.svelte.d.ts +2 -0
  156. package/dist/components/fields/LiteMarkdownField.svelte +49 -3
  157. package/dist/components/fields/LiteMarkdownField.svelte.d.ts +5 -0
  158. package/dist/components/fields/LiteNumberField.svelte +5 -3
  159. package/dist/components/fields/LiteNumberField.svelte.d.ts +2 -0
  160. package/dist/components/fields/LiteRichTextField.svelte +45 -8
  161. package/dist/components/fields/LiteRichTextField.svelte.d.ts +3 -0
  162. package/dist/components/fields/LiteSelectField.svelte +5 -3
  163. package/dist/components/fields/LiteSelectField.svelte.d.ts +2 -0
  164. package/dist/components/fields/LiteTagField.svelte +38 -15
  165. package/dist/components/fields/LiteTagField.svelte.d.ts +2 -0
  166. package/dist/components/fields/LiteTextField.svelte +26 -5
  167. package/dist/components/fields/LiteTextField.svelte.d.ts +2 -0
  168. package/dist/components/fields/LiteTreeSelect.svelte +5 -2
  169. package/dist/components/fields/LiteTreeSelect.svelte.d.ts +2 -0
  170. package/dist/components/fields/LiteUrlField.svelte +5 -3
  171. package/dist/components/fields/LiteUrlField.svelte.d.ts +2 -0
  172. package/dist/components/layout/LiteSidebar.svelte +4 -1
  173. package/dist/components/layout/LiteSidebar.svelte.d.ts +2 -0
  174. package/dist/components/pages/LiteCreatePage.svelte +4 -1
  175. package/dist/components/pages/LiteCreatePage.svelte.d.ts +2 -0
  176. package/dist/components/pages/LiteEditPage.svelte +4 -1
  177. package/dist/components/pages/LiteEditPage.svelte.d.ts +2 -0
  178. package/dist/components/pages/LiteListPage.svelte +4 -1
  179. package/dist/components/pages/LiteListPage.svelte.d.ts +2 -0
  180. package/dist/components/pages/LiteShowPage.svelte +4 -1
  181. package/dist/components/pages/LiteShowPage.svelte.d.ts +2 -0
  182. package/dist/components/widgets/LiteAnomalyBadge.svelte +5 -2
  183. package/dist/components/widgets/LiteAnomalyBadge.svelte.d.ts +2 -0
  184. package/dist/components/widgets/LiteAreaChart.svelte +20 -0
  185. package/dist/components/widgets/LiteAreaChart.svelte.d.ts +10 -0
  186. package/dist/components/widgets/LiteChartSvg.svelte +102 -0
  187. package/dist/components/widgets/LiteChartSvg.svelte.d.ts +10 -0
  188. package/dist/components/widgets/LiteChartTable.svelte +44 -0
  189. package/dist/components/widgets/LiteChartTable.svelte.d.ts +10 -0
  190. package/dist/components/widgets/LiteDonutChart.svelte +20 -0
  191. package/dist/components/widgets/LiteDonutChart.svelte.d.ts +10 -0
  192. package/dist/components/widgets/LiteFunnelChart.svelte +20 -0
  193. package/dist/components/widgets/LiteFunnelChart.svelte.d.ts +10 -0
  194. package/dist/components/widgets/LiteGaugeChart.svelte +20 -0
  195. package/dist/components/widgets/LiteGaugeChart.svelte.d.ts +10 -0
  196. package/dist/components/widgets/LiteHeatmapChart.svelte +20 -0
  197. package/dist/components/widgets/LiteHeatmapChart.svelte.d.ts +10 -0
  198. package/dist/components/widgets/LiteInsightCard.svelte +34 -12
  199. package/dist/components/widgets/LiteInsightCard.svelte.d.ts +7 -4
  200. package/dist/components/widgets/LiteLineChart.svelte +6 -3
  201. package/dist/components/widgets/LiteLineChart.svelte.d.ts +0 -5
  202. package/dist/components/widgets/LitePieChart.svelte +5 -3
  203. package/dist/components/widgets/LitePieChart.svelte.d.ts +0 -5
  204. package/dist/components/widgets/LiteRadarChart.svelte +20 -0
  205. package/dist/components/widgets/LiteRadarChart.svelte.d.ts +10 -0
  206. package/dist/components/widgets/LiteRoseChart.svelte +20 -0
  207. package/dist/components/widgets/LiteRoseChart.svelte.d.ts +10 -0
  208. package/dist/components/widgets/LiteScatterChart.svelte +20 -0
  209. package/dist/components/widgets/LiteScatterChart.svelte.d.ts +10 -0
  210. package/dist/components/widgets/LiteWaterfallChart.svelte +20 -0
  211. package/dist/components/widgets/LiteWaterfallChart.svelte.d.ts +10 -0
  212. package/dist/components/widgets/chart-geometry.d.ts +65 -0
  213. package/dist/components/widgets/chart-geometry.js +229 -0
  214. package/dist/components/widgets/index.d.ts +10 -0
  215. package/dist/components/widgets/index.js +10 -0
  216. package/dist/index.d.ts +40 -0
  217. package/dist/index.js +47 -0
  218. package/dist/lite-code-theme.css +139 -0
  219. package/dist/lite.css +108 -1
  220. package/dist/rich-content.d.ts +47 -0
  221. package/dist/rich-content.js +498 -0
  222. package/dist/schema-generator.js +3 -1
  223. package/dist/server-adapter.js +6 -11
  224. package/dist/value-normalization.d.ts +4 -0
  225. package/dist/value-normalization.js +13 -0
  226. package/package.json +18 -4
@@ -6,16 +6,18 @@
6
6
  value?: unknown;
7
7
  error?: string[];
8
8
  mode?: 'show' | 'edit' | 'create';
9
+ /** Caller class merged with the built-in class list. */
10
+ class?: string;
9
11
  }
10
12
 
11
- let { field, value, error = [], mode = 'show' }: Props = $props();
13
+ let { field, value, error = [], mode = 'show', class: className = '' }: Props = $props();
12
14
  let hasError = $derived(error.length > 0);
13
15
  </script>
14
16
 
15
17
  {#if mode === 'show'}
16
- <span>{value == null ? '—' : Number(value).toLocaleString()}</span>
18
+ <span class="lite-field-value {className}">{value == null ? '—' : Number(value).toLocaleString()}</span>
17
19
  {:else}
18
- <div>
20
+ <div class="lite-field-edit {className}">
19
21
  <input
20
22
  type="number"
21
23
  name={field.key}
@@ -4,6 +4,8 @@ interface Props {
4
4
  value?: unknown;
5
5
  error?: string[];
6
6
  mode?: 'show' | 'edit' | 'create';
7
+ /** Caller class merged with the built-in class list. */
8
+ class?: string;
7
9
  }
8
10
  declare const LiteNumberField: import("svelte").Component<Props, {}, "">;
9
11
  type LiteNumberField = ReturnType<typeof LiteNumberField>;
@@ -1,28 +1,33 @@
1
1
  <script lang="ts">
2
2
  import type { FieldDefinition } from '@svadmin/core';
3
3
  import { toSafeText } from '../../security.js';
4
+ import { renderRichContent, type MarkdownRenderOptions } from '../../rich-content.js';
4
5
 
5
6
  interface Props {
6
7
  field: FieldDefinition;
7
8
  value?: unknown;
8
9
  error?: string[];
9
10
  mode?: 'show' | 'edit' | 'create';
11
+ /** Per-field renderer options; app-wide defaults come from configureMarkdownRenderer. */
12
+ renderOptions?: MarkdownRenderOptions;
10
13
  }
11
14
 
12
- let { field, value, error = [], mode = 'show' }: Props = $props();
15
+ let { field, value, error = [], mode = 'show', renderOptions }: Props = $props();
13
16
  let hasError = $derived(error.length > 0);
14
- const displayValue = $derived(toSafeText(value, '—'));
17
+ const preview = $derived(renderRichContent(value, renderOptions));
15
18
  </script>
16
19
 
17
20
  {#if mode === 'show'}
18
- <!-- Lite mode intentionally renders rich content as text to keep SSR output safe without a sanitizer dependency. -->
19
- <div style="padding: 16px; border: 1px solid #E5E6EB; border-radius: 6px; max-height: 500px; overflow-y: auto; background: #fff; white-space: pre-wrap;" class="prose">
20
- {displayValue}
21
- </div>
21
+ {#if preview}
22
+ <!-- eslint-disable-next-line svelte/no-at-html-tags -- 内容由 renderRichContent 转义或白名单过滤,高亮回调仅允许可信服务端实现。 -->
23
+ <div class="lite-rich-preview">{@html preview}</div>
24
+ {:else}
25
+ <span>—</span>
26
+ {/if}
22
27
  {:else}
23
28
  <div class="lite-markdown-editor">
24
29
  <div class="lite-inline-lg lite-flex-wrap" style="padding: 8px 12px; border: 1px solid #E5E6EB; border-bottom: none; border-radius: 6px 6px 0 0; background: #F7F8FA; color: #4E5969; font-size: 12px; font-weight: 500;">
25
- <span>Markdown is supported</span>
30
+ <span>HTML or Markdown source</span>
26
31
  <span style="color: #86909C;">**bold**</span>
27
32
  <span style="color: #86909C; font-style: italic;">*italic*</span>
28
33
  <span style="color: #86909C;"># heading</span>
@@ -32,7 +37,7 @@
32
37
  id={field.key}
33
38
  class="lite-input {hasError ? 'lite-input-error' : ''}"
34
39
  style="min-height: 280px; font-family: 'SFMono-Regular', Consolas, 'Liberation Mono', Menlo, monospace; font-size: 13px; line-height: 1.6; padding: 16px; border-radius: 0 0 6px 6px; resize: vertical;"
35
- placeholder="Wait... Rich Text Editor is disabled in lite mode.&#10;&#10;You can write standard HTML or use Markdown syntax here. Content will be safely rendered on the server."
40
+ placeholder="Rich text editing is disabled in lite mode. Write standard HTML or Markdown; the server renders it through a safe allowlist."
36
41
  {...field.required ? { required: true } : {}}
37
42
  >{toSafeText(value)}</textarea>
38
43
  {#if hasError}
@@ -40,5 +45,37 @@
40
45
  <div class="lite-error-text">{err}</div>
41
46
  {/each}
42
47
  {/if}
48
+ <div class="lite-rich-preview-block">
49
+ <span class="lite-rich-preview-block__label">Preview</span>
50
+ {#if preview}
51
+ <!-- eslint-disable-next-line svelte/no-at-html-tags -- 内容由 renderRichContent 转义或白名单过滤,高亮回调仅允许可信服务端实现。 -->
52
+ <div class="lite-rich-preview">{@html preview}</div>
53
+ {:else}
54
+ <p class="lite-rich-preview-block__empty">Nothing to preview yet.</p>
55
+ {/if}
56
+ </div>
43
57
  </div>
44
58
  {/if}
59
+
60
+ <style>
61
+ .lite-rich-preview { padding: 16px; border: 1px solid #E5E6EB; border-radius: 6px; max-height: 500px; overflow-y: auto; background: #fff; color: #1D2129; font-size: 13px; line-height: 1.7; overflow-wrap: anywhere; }
62
+ .lite-rich-preview :global(p) { margin: 0 0 8px; }
63
+ .lite-rich-preview :global(h1),
64
+ .lite-rich-preview :global(h2),
65
+ .lite-rich-preview :global(h3) { margin: 12px 0 6px; font-size: 16px; }
66
+ .lite-rich-preview :global(ul),
67
+ .lite-rich-preview :global(ol) { margin: 0 0 8px; padding-left: 20px; }
68
+ .lite-rich-preview :global(code) { font-family: monospace; font-size: 12px; }
69
+ .lite-rich-preview :global(blockquote) { margin: 0 0 8px; padding-left: 10px; border-left: 3px solid #E5E6EB; color: #4E5969; }
70
+ .lite-rich-preview :global(a) { color: #165DFF; }
71
+ .lite-rich-preview :global(img) { max-width: 100%; height: auto; }
72
+ .lite-rich-preview :global(table) { width: 100%; margin: 0 0 8px; border-collapse: collapse; }
73
+ .lite-rich-preview :global(th),
74
+ .lite-rich-preview :global(td) { padding: 6px 8px; border: 1px solid #E5E6EB; text-align: left; }
75
+ .lite-rich-preview :global(th) { background: #F2F3F5; font-weight: 600; }
76
+ .lite-rich-preview :global(ul.lite-task-list) { padding-left: 2px; list-style: none; }
77
+ .lite-rich-preview :global(.lite-task-item input) { margin-right: 6px; }
78
+ .lite-rich-preview-block { margin-top: 8px; }
79
+ .lite-rich-preview-block__label { display: block; margin-bottom: 4px; color: #86909C; font-size: 11px; font-weight: 600; }
80
+ .lite-rich-preview-block__empty { margin: 0; padding: 8px 12px; border: 1px dashed #E5E6EB; border-radius: 4px; color: #86909C; font-size: 12px; }
81
+ </style>
@@ -1,9 +1,12 @@
1
1
  import type { FieldDefinition } from '@svadmin/core';
2
+ import { type MarkdownRenderOptions } from '../../rich-content.js';
2
3
  interface Props {
3
4
  field: FieldDefinition;
4
5
  value?: unknown;
5
6
  error?: string[];
6
7
  mode?: 'show' | 'edit' | 'create';
8
+ /** Per-field renderer options; app-wide defaults come from configureMarkdownRenderer. */
9
+ renderOptions?: MarkdownRenderOptions;
7
10
  }
8
11
  declare const LiteRichTextField: import("svelte").Component<Props, {}, "">;
9
12
  type LiteRichTextField = ReturnType<typeof LiteRichTextField>;
@@ -7,9 +7,11 @@
7
7
  value?: unknown;
8
8
  error?: string[];
9
9
  mode?: 'show' | 'edit' | 'create';
10
+ /** Caller class merged with the built-in class list. */
11
+ class?: string;
10
12
  }
11
13
 
12
- let { field, value, error = [], mode = 'show' }: Props = $props();
14
+ let { field, value, error = [], mode = 'show', class: className = '' }: Props = $props();
13
15
  let hasError = $derived(error.length > 0);
14
16
 
15
17
  function displaySelect(v: unknown): string {
@@ -20,9 +22,9 @@
20
22
  </script>
21
23
 
22
24
  {#if mode === 'show'}
23
- <span class="lite-badge">{displaySelect(value)}</span>
25
+ <span class="lite-badge {className}">{displaySelect(value)}</span>
24
26
  {:else}
25
- <div>
27
+ <div class="lite-field-edit {className}">
26
28
  <select
27
29
  name={field.key}
28
30
  id={field.key}
@@ -4,6 +4,8 @@ interface Props {
4
4
  value?: unknown;
5
5
  error?: string[];
6
6
  mode?: 'show' | 'edit' | 'create';
7
+ /** Caller class merged with the built-in class list. */
8
+ class?: string;
7
9
  }
8
10
  declare const LiteSelectField: import("svelte").Component<Props, {}, "">;
9
11
  type LiteSelectField = ReturnType<typeof LiteSelectField>;
@@ -6,15 +6,17 @@
6
6
  value?: unknown;
7
7
  error?: string[];
8
8
  mode?: 'show' | 'edit' | 'create';
9
+ /** Caller class merged with the built-in class list. */
10
+ class?: string;
9
11
  }
10
12
 
11
- let { field, value, error = [], mode = 'show' }: Props = $props();
13
+ let { field, value, error = [], mode = 'show', class: className = '' }: Props = $props();
12
14
  let hasError = $derived(error.length > 0);
13
15
  const tags = $derived(Array.isArray(value) ? value.map(String) : []);
14
16
  </script>
15
17
 
16
18
  {#if mode === 'show'}
17
- <div class="lite-inline-xs lite-flex-wrap">
19
+ <div class="lite-inline-xs lite-flex-wrap {className}">
18
20
  {#each tags as tag, _i (_i)}
19
21
  <span class="lite-badge">{tag}</span>
20
22
  {:else}
@@ -22,19 +24,33 @@
22
24
  {/each}
23
25
  </div>
24
26
  {:else}
25
- <div>
26
- <!-- For SSR without JS, we just accept a comma-separated string -->
27
- <input
28
- type="text"
29
- name={field.key}
30
- id={field.key}
31
- value={tags.join(', ')}
32
- class="lite-input {hasError ? 'lite-input-error' : ''}"
33
- placeholder="Comma separated tags (e.g. admin, user, internal)"
34
- />
35
- <span style="font-size: 11px; color: #6b7280; display: block; margin-top: 4px;">
36
- Separate tags with commas.
37
- </span>
27
+ <div class="lite-tags-input {className}">
28
+ <!-- SSR 无脚本:每个标签一个同名字段,服务端按 getAll 解析为数组。 -->
29
+ {#each tags as tag, index (index)}
30
+ <label class="lite-tags-input__row">
31
+ <span class="lite-visually-hidden">{field.label ?? 'Tag'} {index + 1}</span>
32
+ <input
33
+ type="text"
34
+ name={field.key}
35
+ value={tag}
36
+ class="lite-input{hasError ? ' lite-input-error' : ''}"
37
+ aria-label={`${field.label ?? 'Tag'} ${index + 1}`}
38
+ placeholder="Remove this tag by clearing the field"
39
+ />
40
+ </label>
41
+ {/each}
42
+ <label class="lite-tags-input__row">
43
+ <span class="lite-visually-hidden">{field.label ?? 'Tag'} (new)</span>
44
+ <input
45
+ type="text"
46
+ name={field.key}
47
+ value=""
48
+ class="lite-input{hasError ? ' lite-input-error' : ''}"
49
+ aria-label={`${field.label ?? 'Tag'} (new)`}
50
+ placeholder="Add a tag"
51
+ />
52
+ </label>
53
+ <span class="lite-tags-input__hint">One tag per field. Leave a field blank to drop it.</span>
38
54
  {#if hasError}
39
55
  {#each error as err, _i (_i)}
40
56
  <div class="lite-error-text">{err}</div>
@@ -42,3 +58,10 @@
42
58
  {/if}
43
59
  </div>
44
60
  {/if}
61
+
62
+ <style>
63
+ .lite-tags-input { display: block; }
64
+ .lite-tags-input__row { display: block; margin-bottom: 6px; }
65
+ .lite-tags-input__hint { display: block; margin-top: 4px; color: #6B7280; font-size: 11px; }
66
+ .lite-visually-hidden { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
67
+ </style>
@@ -4,6 +4,8 @@ interface Props {
4
4
  value?: unknown;
5
5
  error?: string[];
6
6
  mode?: 'show' | 'edit' | 'create';
7
+ /** Caller class merged with the built-in class list. */
8
+ class?: string;
7
9
  }
8
10
  declare const LiteTagField: import("svelte").Component<Props, {}, "">;
9
11
  type LiteTagField = ReturnType<typeof LiteTagField>;
@@ -6,21 +6,42 @@
6
6
  value?: unknown;
7
7
  error?: string[];
8
8
  mode?: 'show' | 'edit' | 'create';
9
+ /** Caller class merged with the built-in class list. */
10
+ class?: string;
9
11
  }
10
12
 
11
- let { field, value, error = [], mode = 'show' }: Props = $props();
13
+ let { field, value, error = [], mode = 'show', class: className = '' }: Props = $props();
12
14
  let hasError = $derived(error.length > 0);
15
+
16
+ /**
17
+ * Native input type per value domain. Time, datetime, color, email, url and
18
+ * phone fields must not degrade to a free-text box.
19
+ */
20
+ const nativeType: Record<string, string> = {
21
+ time: 'time',
22
+ datetime: 'datetime-local',
23
+ color: 'color',
24
+ email: 'email',
25
+ url: 'url',
26
+ phone: 'tel',
27
+ };
28
+ const hexColour = $derived(typeof value === 'string' && /^#[0-9a-f]{6}$/iu.test(value) ? value : '#000000');
29
+ const colorNeedsTextFallback = $derived(field.type === 'color' && value != null && String(value) !== '' && !/^#[0-9a-f]{6}$/iu.test(String(value)));
30
+ const inputType = $derived(
31
+ field.type === 'color' && colorNeedsTextFallback ? 'text' : nativeType[field.type] ?? 'text',
32
+ );
33
+ const inputValue = $derived(inputType === 'color' ? hexColour : String(value ?? ''));
13
34
  </script>
14
35
 
15
36
  {#if mode === 'show'}
16
- <span>{value == null ? '—' : String(value)}</span>
37
+ <span class="lite-field-value {className}">{value == null ? '—' : String(value)}</span>
17
38
  {:else}
18
- <div>
39
+ <div class="lite-field-edit {className}">
19
40
  <input
20
- type="text"
41
+ type={inputType}
21
42
  name={field.key}
22
43
  id={field.key}
23
- value={String(value ?? '')}
44
+ value={inputValue}
24
45
  class="lite-input {hasError ? 'lite-input-error' : ''}"
25
46
  placeholder={field.label}
26
47
  {...field.required ? { required: true } : {}}
@@ -4,6 +4,8 @@ interface Props {
4
4
  value?: unknown;
5
5
  error?: string[];
6
6
  mode?: 'show' | 'edit' | 'create';
7
+ /** Caller class merged with the built-in class list. */
8
+ class?: string;
7
9
  }
8
10
  declare const LiteTextField: import("svelte").Component<Props, {}, "">;
9
11
  type LiteTextField = ReturnType<typeof LiteTextField>;
@@ -23,6 +23,8 @@
23
23
  required?: boolean;
24
24
  error?: string[];
25
25
  mode?: 'show' | 'edit' | 'create';
26
+ /** Caller class merged with the built-in class list. */
27
+ class?: string;
26
28
  }
27
29
 
28
30
  let {
@@ -37,6 +39,7 @@
37
39
  required = field?.required ?? false,
38
40
  error = [],
39
41
  mode = 'show',
42
+ class: className = ''
40
43
  }: Props = $props();
41
44
 
42
45
  const hasError = $derived(error.length > 0);
@@ -87,9 +90,9 @@
87
90
  </script>
88
91
 
89
92
  {#if mode === 'show'}
90
- <span class="lite-badge">{formatDisplay(value)}</span>
93
+ <span class="lite-badge {className}">{formatDisplay(value)}</span>
91
94
  {:else}
92
- <div class="lite-form-group">
95
+ <div class="lite-form-group {className}">
93
96
  {#if label}
94
97
  <label class="lite-label" for={name}>
95
98
  {label}
@@ -17,6 +17,8 @@ interface Props {
17
17
  required?: boolean;
18
18
  error?: string[];
19
19
  mode?: 'show' | 'edit' | 'create';
20
+ /** Caller class merged with the built-in class list. */
21
+ class?: string;
20
22
  }
21
23
  declare const LiteTreeSelect: import("svelte").Component<Props, {}, "">;
22
24
  type LiteTreeSelect = ReturnType<typeof LiteTreeSelect>;
@@ -7,9 +7,11 @@
7
7
  value?: unknown;
8
8
  error?: string[];
9
9
  mode?: 'show' | 'edit' | 'create';
10
+ /** Caller class merged with the built-in class list. */
11
+ class?: string;
10
12
  }
11
13
 
12
- let { field, value, error = [], mode = 'show' }: Props = $props();
14
+ let { field, value, error = [], mode = 'show', class: className = '' }: Props = $props();
13
15
  let hasError = $derived(error.length > 0);
14
16
  let displayValue = $derived(toSafeText(value));
15
17
  let safeHref = $derived(toSafeHref(value));
@@ -17,7 +19,7 @@
17
19
  </script>
18
20
 
19
21
  {#if mode === 'show'}
20
- <span>
22
+ <span class="lite-field-value {className}">
21
23
  {#if displayValue}
22
24
  {#if safeHref}
23
25
  <a href={safeHref} target="_blank" rel="noopener noreferrer">{displayValue}</a>
@@ -29,7 +31,7 @@
29
31
  {/if}
30
32
  </span>
31
33
  {:else}
32
- <div>
34
+ <div class="lite-field-edit {className}">
33
35
  <input
34
36
  type="url"
35
37
  name={field.key}
@@ -4,6 +4,8 @@ interface Props {
4
4
  value?: unknown;
5
5
  error?: string[];
6
6
  mode?: 'show' | 'edit' | 'create';
7
+ /** Caller class merged with the built-in class list. */
8
+ class?: string;
7
9
  }
8
10
  declare const LiteUrlField: import("svelte").Component<Props, {}, "">;
9
11
  type LiteUrlField = ReturnType<typeof LiteUrlField>;
@@ -11,6 +11,8 @@
11
11
  basePath?: string;
12
12
  menu?: MenuItem[];
13
13
  canAccess?: (resource: string, action: string) => boolean;
14
+ /** Caller class merged with the built-in class list. */
15
+ class?: string;
14
16
  }
15
17
 
16
18
  let {
@@ -21,6 +23,7 @@
21
23
  basePath = '/lite',
22
24
  menu,
23
25
  canAccess,
26
+ class: className = ''
24
27
  }: Props = $props();
25
28
 
26
29
  const menuResources = $derived(filterVisibleResources(resources, canAccess));
@@ -29,7 +32,7 @@
29
32
  const visibleMenu = $derived(menu ? filterVisibleMenu(menu, canAccess) : []);
30
33
  </script>
31
34
 
32
- <nav class="lite-sidebar">
35
+ <nav class={`lite-sidebar ${className}`.trim()}>
33
36
  <div class="lite-sidebar-brand">{brandName}</div>
34
37
  {#if hasCustomMenu}
35
38
  <LiteMenuList items={visibleMenu} {basePath} {currentResource} />
@@ -7,6 +7,8 @@ interface Props {
7
7
  basePath?: string;
8
8
  menu?: MenuItem[];
9
9
  canAccess?: (resource: string, action: string) => boolean;
10
+ /** Caller class merged with the built-in class list. */
11
+ class?: string;
10
12
  }
11
13
  declare const LiteSidebar: import("svelte").Component<Props, {}, "">;
12
14
  type LiteSidebar = ReturnType<typeof LiteSidebar>;
@@ -10,6 +10,8 @@
10
10
  errors?: Record<string, string[]>;
11
11
  values?: Record<string, unknown>;
12
12
  basePath?: string;
13
+ /** Caller class merged with the built-in class list. */
14
+ class?: string;
13
15
  }
14
16
 
15
17
  let {
@@ -17,10 +19,11 @@
17
19
  errors = {},
18
20
  values = {},
19
21
  basePath = "/lite",
22
+ class: className = '',
20
23
  }: Props = $props();
21
24
  </script>
22
25
 
23
- <div class="lite-page">
26
+ <div class="lite-page {className}">
24
27
  <LiteBreadcrumbs
25
28
  items={[
26
29
  { label: t("common.dashboard") || "Dashboard", href: basePath },
@@ -4,6 +4,8 @@ interface Props {
4
4
  errors?: Record<string, string[]>;
5
5
  values?: Record<string, unknown>;
6
6
  basePath?: string;
7
+ /** Caller class merged with the built-in class list. */
8
+ class?: string;
7
9
  }
8
10
  declare const LiteCreatePage: import("svelte").Component<Props, {}, "">;
9
11
  type LiteCreatePage = ReturnType<typeof LiteCreatePage>;
@@ -14,6 +14,8 @@
14
14
  basePath?: string;
15
15
  canDelete?: boolean;
16
16
  canShow?: boolean;
17
+ /** Caller class merged with the built-in class list. */
18
+ class?: string;
17
19
  }
18
20
 
19
21
  let {
@@ -23,6 +25,7 @@
23
25
  basePath = "/lite",
24
26
  canDelete,
25
27
  canShow,
28
+ class: className = '',
26
29
  }: Props = $props();
27
30
 
28
31
  let pk = $derived(resource.primaryKey ?? "id");
@@ -31,7 +34,7 @@
31
34
  const showView = $derived(canShow ?? resource.canShow !== false);
32
35
  </script>
33
36
 
34
- <div class="lite-page">
37
+ <div class="lite-page {className}">
35
38
  <LiteBreadcrumbs
36
39
  items={[
37
40
  { label: t("common.dashboard") || "Dashboard", href: basePath },
@@ -6,6 +6,8 @@ interface Props {
6
6
  basePath?: string;
7
7
  canDelete?: boolean;
8
8
  canShow?: boolean;
9
+ /** Caller class merged with the built-in class list. */
10
+ class?: string;
9
11
  }
10
12
  declare const LiteEditPage: import("svelte").Component<Props, {}, "">;
11
13
  type LiteEditPage = ReturnType<typeof LiteEditPage>;
@@ -24,6 +24,8 @@
24
24
  canEdit?: boolean;
25
25
  canDelete?: boolean;
26
26
  enableBatch?: boolean;
27
+ /** Caller class merged with the built-in class list. */
28
+ class?: string;
27
29
  }
28
30
 
29
31
  let {
@@ -41,6 +43,7 @@
41
43
  canEdit,
42
44
  canDelete,
43
45
  enableBatch = true,
46
+ class: className = '',
44
47
  }: Props = $props();
45
48
 
46
49
  const showCreate = $derived(canCreate ?? resource.canCreate !== false);
@@ -59,7 +62,7 @@
59
62
  );
60
63
  </script>
61
64
 
62
- <div class="lite-page">
65
+ <div class="lite-page {className}">
63
66
  <LiteBreadcrumbs
64
67
  items={[
65
68
  { label: t("common.dashboard") || "Dashboard", href: basePath },
@@ -17,6 +17,8 @@ interface Props {
17
17
  canEdit?: boolean;
18
18
  canDelete?: boolean;
19
19
  enableBatch?: boolean;
20
+ /** Caller class merged with the built-in class list. */
21
+ class?: string;
20
22
  }
21
23
  declare const LiteListPage: import("svelte").Component<Props, {}, "">;
22
24
  type LiteListPage = ReturnType<typeof LiteListPage>;
@@ -13,6 +13,8 @@
13
13
  basePath?: string;
14
14
  canEdit?: boolean;
15
15
  canDelete?: boolean;
16
+ /** Caller class merged with the built-in class list. */
17
+ class?: string;
16
18
  }
17
19
 
18
20
  let {
@@ -21,6 +23,7 @@
21
23
  basePath = "/lite",
22
24
  canEdit,
23
25
  canDelete,
26
+ class: className = '',
24
27
  }: Props = $props();
25
28
 
26
29
  let pk = $derived(resource.primaryKey ?? "id");
@@ -33,7 +36,7 @@
33
36
  );
34
37
  </script>
35
38
 
36
- <div class="lite-page">
39
+ <div class="lite-page {className}">
37
40
  <LiteBreadcrumbs
38
41
  items={[
39
42
  { label: t("common.dashboard") || "Dashboard", href: basePath },
@@ -5,6 +5,8 @@ interface Props {
5
5
  basePath?: string;
6
6
  canEdit?: boolean;
7
7
  canDelete?: boolean;
8
+ /** Caller class merged with the built-in class list. */
9
+ class?: string;
8
10
  }
9
11
  declare const LiteShowPage: import("svelte").Component<Props, {}, "">;
10
12
  type LiteShowPage = ReturnType<typeof LiteShowPage>;
@@ -10,6 +10,8 @@
10
10
  threshold?: number;
11
11
  formatter?: (val: number) => string;
12
12
  lowerIsBetter?: boolean;
13
+ /** Caller class merged with the built-in class list. */
14
+ class?: string;
13
15
  }
14
16
 
15
17
  let {
@@ -18,6 +20,7 @@
18
20
  threshold = 0.2,
19
21
  formatter = (v: number) => v.toString(),
20
22
  lowerIsBetter = false,
23
+ class: className = '',
21
24
  }: Props = $props();
22
25
 
23
26
  const diff = $derived(
@@ -32,11 +35,11 @@
32
35
  </script>
33
36
 
34
37
  {#if !isAnomaly}
35
- <span style="font-size: 14px; color: #4E5969;">{formatter(value)}</span>
38
+ <span class="lite-anomaly-value {className}" style="font-size: 14px; color: #4E5969;">{formatter(value)}</span>
36
39
  {:else}
37
40
  <span
38
41
  title="Baseline: {formatter(baseline)} ({diff > 0 ? '+' : '-'}{percentLabel})"
39
- class="lite-badge"
42
+ class="lite-badge {className}"
40
43
  style="background: {isGood ? '#E8FFEA' : '#FFECE8'}; color: {isGood ? '#009A29' : '#CB272D'}; border: 1px solid {isGood ? '#E8FFEA' : '#FDCDC5'};"
41
44
  >
42
45
  {arrow} {formatter(value)}
@@ -9,6 +9,8 @@ interface Props {
9
9
  threshold?: number;
10
10
  formatter?: (val: number) => string;
11
11
  lowerIsBetter?: boolean;
12
+ /** Caller class merged with the built-in class list. */
13
+ class?: string;
12
14
  }
13
15
  declare const LiteAnomalyBadge: import("svelte").Component<Props, {}, "">;
14
16
  type LiteAnomalyBadge = ReturnType<typeof LiteAnomalyBadge>;
@@ -0,0 +1,20 @@
1
+ <script lang="ts">
2
+ import LiteChartSvg from './LiteChartSvg.svelte';
3
+ import LiteChartTable from './LiteChartTable.svelte';
4
+
5
+ interface Props {
6
+ title?: string;
7
+ data?: Array<Record<string, unknown>>;
8
+ rows?: Array<Array<string | number>>;
9
+ columns?: string[];
10
+ emptyText?: string;
11
+ }
12
+
13
+ let { title, data = [], rows, columns, emptyText }: Props = $props();
14
+ const normalized = $derived(rows ?? data.map((item) => Object.values(item).map((value) => typeof value === 'number' ? value : String(value ?? ''))));
15
+ </script>
16
+
17
+ <div class="lite-chart-widget">
18
+ <LiteChartSvg kind="area" rows={normalized} {title} />
19
+ <LiteChartTable {title} kind="area" columns={columns ?? ['Label', 'Value']} rows={normalized} {emptyText} />
20
+ </div>
@@ -0,0 +1,10 @@
1
+ interface Props {
2
+ title?: string;
3
+ data?: Array<Record<string, unknown>>;
4
+ rows?: Array<Array<string | number>>;
5
+ columns?: string[];
6
+ emptyText?: string;
7
+ }
8
+ declare const LiteAreaChart: import("svelte").Component<Props, {}, "">;
9
+ type LiteAreaChart = ReturnType<typeof LiteAreaChart>;
10
+ export default LiteAreaChart;