@rimelight/ui 0.0.34 → 0.0.35

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (185) hide show
  1. package/README.md +1 -0
  2. package/package.json +19 -24
  3. package/src/components/astro/RLAAccordion.astro +94 -18
  4. package/src/components/astro/RLAAvatar.astro +135 -68
  5. package/src/components/astro/RLABadge.astro +4 -2
  6. package/src/components/astro/RLABanner.astro +138 -23
  7. package/src/components/astro/RLABreadcrumb.astro +13 -0
  8. package/src/components/astro/RLAButton.astro +8 -4
  9. package/src/components/astro/RLACallout.astro +112 -0
  10. package/src/components/astro/RLACard.astro +6 -5
  11. package/src/components/astro/RLACarousel.astro +104 -75
  12. package/src/components/astro/RLAChart.astro +4 -1
  13. package/src/components/astro/RLAChip.astro +11 -5
  14. package/src/components/astro/RLACollapsible.astro +4 -1
  15. package/src/components/astro/RLAColorArea.astro +432 -0
  16. package/src/components/astro/RLAColorField.astro +300 -0
  17. package/src/components/astro/RLAColorSlider.astro +413 -0
  18. package/src/components/astro/RLAConfirm.astro +13 -11
  19. package/src/components/astro/RLACopyMarkdown.astro +78 -0
  20. package/src/components/astro/RLADate.astro +30 -0
  21. package/src/components/astro/RLADrawer.astro +50 -3
  22. package/src/components/astro/RLADropdownMenu.astro +78 -51
  23. package/src/components/astro/RLAFieldGroup.astro +4 -1
  24. package/src/components/astro/RLAFileUpload.astro +114 -100
  25. package/src/components/astro/RLAFooter.astro +2 -1
  26. package/src/components/astro/RLAFormField.astro +10 -6
  27. package/src/components/astro/RLAGrid.astro +31 -39
  28. package/src/components/astro/RLAHead.astro +139 -39
  29. package/src/components/astro/RLAHeader.astro +2 -1
  30. package/src/components/astro/RLAImage.astro +274 -251
  31. package/src/components/astro/RLAInput.astro +14 -9
  32. package/src/components/astro/RLAInputMenu.astro +119 -83
  33. package/src/components/astro/RLAKbd.astro +5 -5
  34. package/src/components/astro/RLALayoutGrid.astro +395 -0
  35. package/src/components/astro/RLALink.astro +23 -1
  36. package/src/components/astro/RLALinkGroup.astro +99 -99
  37. package/src/components/astro/RLALocaleSelector.astro +29 -35
  38. package/src/components/astro/RLALogo.astro +117 -90
  39. package/src/components/astro/RLAModal.astro +48 -18
  40. package/src/components/astro/RLANavigationMenu.astro +381 -326
  41. package/src/components/astro/{RLADocsPackageManagers.astro → RLAPackageManagers.astro} +81 -87
  42. package/src/components/astro/RLAPageSection.astro +4 -2
  43. package/src/components/astro/RLAPopover.astro +4 -3
  44. package/src/components/astro/RLAPost.astro +11 -2
  45. package/src/components/astro/RLAScrollArea.astro +4 -1
  46. package/src/components/astro/RLAScrollToTop.astro +200 -172
  47. package/src/components/astro/RLASearch.astro +282 -0
  48. package/src/components/astro/RLASelect.astro +78 -55
  49. package/src/components/astro/RLASeparator.astro +11 -6
  50. package/src/components/astro/RLAShare.astro +60 -0
  51. package/src/components/astro/RLAShortcuts.astro +429 -0
  52. package/src/components/astro/RLASidebar.astro +158 -212
  53. package/src/components/astro/RLASlideover.astro +47 -17
  54. package/src/components/astro/RLASplitter.astro +194 -141
  55. package/src/components/astro/RLASteps.astro +118 -71
  56. package/src/components/astro/RLASurround.astro +39 -0
  57. package/src/components/astro/RLATable.astro +4 -1
  58. package/src/components/astro/RLATableOfContents.astro +109 -23
  59. package/src/components/astro/RLATabs.astro +147 -133
  60. package/src/components/astro/RLATextarea.astro +4 -1
  61. package/src/components/astro/RLAThemeSelector.astro +105 -76
  62. package/src/components/astro/RLAToast.astro +35 -21
  63. package/src/components/vue/RLVBanner.vue +230 -0
  64. package/src/components/vue/RLVButton.vue +3 -2
  65. package/src/components/vue/RLVCheckbox.vue +4 -2
  66. package/src/components/vue/RLVFooter.vue +3 -2
  67. package/src/components/vue/RLVHeader.vue +3 -2
  68. package/src/components/vue/RLVIcon.vue +4 -2
  69. package/src/components/vue/RLVInput.vue +5 -4
  70. package/src/components/vue/RLVLogo.vue +25 -3
  71. package/src/components/vue/RLVPlaceholder.vue +3 -2
  72. package/src/components/vue/RLVPost.vue +8 -2
  73. package/src/components/vue/RLVProgress.vue +60 -0
  74. package/src/components/vue/RLVScrollToTop.vue +65 -52
  75. package/src/components/vue/RLVSection.vue +14 -13
  76. package/src/components/vue/RLVToast.vue +17 -4
  77. package/src/composables/index.ts +1 -0
  78. package/src/composables/useHeaderStore.ts +1 -0
  79. package/src/composables/useShortcuts.ts +11 -0
  80. package/src/config/security.ts +43 -36
  81. package/src/config/site.config.ts +1 -0
  82. package/src/docs/components/ApiChangelog.astro +147 -0
  83. package/src/{plugins/starlightDocsApi → docs}/components/ApiEmits.astro +4 -4
  84. package/src/{plugins/starlightDocsApi → docs}/components/ApiProps.astro +4 -4
  85. package/src/{plugins/starlightDocsApi → docs}/components/ApiSlots.astro +4 -4
  86. package/src/docs/components/ApiTheme.astro +100 -0
  87. package/src/docs/extractAll.ts +94 -0
  88. package/src/docs/extractors/extractAstro.ts +69 -0
  89. package/src/docs/extractors/extractTheme.ts +56 -0
  90. package/src/{plugins/starlightDocsApi/extract-vue.ts → docs/extractors/extractVue.ts} +164 -15
  91. package/src/{plugins/starlightDocsApi → docs}/utils.ts +1 -2
  92. package/src/env.d.ts +0 -12
  93. package/src/integrations/ui.ts +35 -19
  94. package/src/middleware/security.ts +75 -19
  95. package/src/presets/index.ts +118 -293
  96. package/src/styles/index.css +0 -2
  97. package/src/themes/accordion.theme.ts +29 -3
  98. package/src/themes/aspect-ratio.theme.ts +1 -1
  99. package/src/themes/avatar-group.theme.ts +1 -1
  100. package/src/themes/avatar.theme.ts +2 -2
  101. package/src/themes/badge.theme.ts +2 -3
  102. package/src/themes/banner.theme.ts +40 -4
  103. package/src/themes/breadcrumb.theme.ts +1 -1
  104. package/src/themes/button.theme.ts +21 -22
  105. package/src/themes/{alert.theme.ts → callout.theme.ts} +12 -39
  106. package/src/themes/card.theme.ts +17 -9
  107. package/src/themes/carousel.theme.ts +1 -1
  108. package/src/themes/checkbox.theme.ts +1 -2
  109. package/src/themes/chip.theme.ts +2 -3
  110. package/src/themes/color-area.theme.ts +33 -0
  111. package/src/themes/color-field.theme.ts +32 -0
  112. package/src/themes/color-slider.theme.ts +34 -0
  113. package/src/themes/confirm.theme.ts +1 -1
  114. package/src/themes/container.theme.ts +1 -1
  115. package/src/themes/drawer.theme.ts +1 -1
  116. package/src/themes/footer.theme.ts +2 -2
  117. package/src/themes/grid.theme.ts +38 -0
  118. package/src/themes/header.theme.ts +4 -3
  119. package/src/themes/hover-card.theme.ts +1 -1
  120. package/src/themes/image.theme.ts +11 -1
  121. package/src/themes/input.theme.ts +7 -1
  122. package/src/themes/kbd.theme.ts +2 -3
  123. package/src/themes/label.theme.ts +1 -1
  124. package/src/themes/layout-grid.theme.ts +16 -0
  125. package/src/themes/link-group.theme.ts +0 -4
  126. package/src/themes/marquee.theme.ts +1 -1
  127. package/src/themes/modal.theme.ts +1 -1
  128. package/src/themes/navigation-menu.theme.ts +2 -2
  129. package/src/themes/page-section.theme.ts +4 -2
  130. package/src/themes/pagination.theme.ts +1 -1
  131. package/src/themes/pin-input.theme.ts +1 -1
  132. package/src/themes/popover.theme.ts +1 -1
  133. package/src/themes/post.theme.ts +23 -3
  134. package/src/themes/progress.theme.ts +1 -2
  135. package/src/themes/scroll-to-top.theme.ts +2 -3
  136. package/src/themes/search.theme.ts +64 -0
  137. package/src/themes/separator.theme.ts +1 -1
  138. package/src/themes/slideover.theme.ts +1 -1
  139. package/src/themes/slider.theme.ts +1 -2
  140. package/src/themes/spinner.theme.ts +1 -2
  141. package/src/themes/{megamenu.theme.ts → steps.theme.ts} +3 -3
  142. package/src/themes/sticky-surface.theme.ts +1 -1
  143. package/src/themes/switch.theme.ts +1 -2
  144. package/src/themes/table-of-contents.theme.ts +21 -2
  145. package/src/themes/timeline.theme.ts +7 -2
  146. package/src/themes/toast.theme.ts +1 -1
  147. package/src/types/components/accordion.ts +35 -2
  148. package/src/types/components/avatar.ts +16 -0
  149. package/src/types/components/banner.ts +42 -0
  150. package/src/types/components/button.ts +3 -4
  151. package/src/types/components/{alert.ts → callout.ts} +6 -6
  152. package/src/types/components/color-area.ts +19 -0
  153. package/src/types/components/color-field.ts +21 -0
  154. package/src/types/components/color-slider.ts +20 -0
  155. package/src/types/components/grid.ts +23 -0
  156. package/src/types/components/input.ts +4 -0
  157. package/src/types/components/layout-grid.ts +145 -0
  158. package/src/types/components/link-group.ts +4 -2
  159. package/src/types/components/link.ts +15 -0
  160. package/src/types/components/logo.ts +3 -3
  161. package/src/types/components/post.ts +12 -0
  162. package/src/types/components/search.ts +29 -0
  163. package/src/types/components/sidebar.ts +2 -6
  164. package/src/types/components/{megamenu.ts → steps.ts} +7 -1
  165. package/src/types/components/table-of-contents.ts +22 -0
  166. package/src/types/components/toast.ts +4 -0
  167. package/src/types/docs.ts +40 -0
  168. package/src/types/index.ts +151 -1
  169. package/src/types/theme.ts +6 -6
  170. package/src/utils/color.ts +165 -0
  171. package/src/utils/docs.ts +260 -110
  172. package/src/utils/headerStack.ts +24 -4
  173. package/src/utils/index.ts +2 -0
  174. package/src/utils/shortcuts.ts +322 -0
  175. package/src/components/TableOfContents.astro +0 -107
  176. package/src/components/astro/RLAAlert.astro +0 -93
  177. package/src/components/astro/RLAChangelog.astro +0 -23
  178. package/src/components/astro/RLAMegamenu.astro +0 -23
  179. package/src/plugins/index.ts +0 -2
  180. package/src/plugins/starlightDocsApi/components/ApiTheme.astro +0 -27
  181. package/src/plugins/starlightDocsApi/index.ts +0 -272
  182. package/src/styles/prism.css +0 -42
  183. package/src/themes/changelog.theme.ts +0 -13
  184. package/src/types/components/index.ts +0 -134
  185. /package/src/{plugins/starlightDocsApi → docs}/types.ts +0 -0
@@ -10,13 +10,24 @@ import rimelightUiPreset, {
10
10
  type ColorConfigValue,
11
11
  type RimelightPresetOptions
12
12
  } from "../presets"
13
+ import { extractAllMeta } from "../docs/extractAll"
14
+ import virtual from "vite-plugin-virtual"
13
15
 
14
- /**
15
- * Shape of the `ui` config that can be passed to the integration.
16
- */
17
- export type UIConfigOverrides = Record<string, Partial<ComponentTheme>>
16
+ export interface CategoryConfig {
17
+ label: string
18
+ }
19
+
20
+ export interface UIConfigOverrides {
21
+ [key: string]: Partial<ComponentTheme>
22
+ }
18
23
 
19
24
  export interface UIOptions {
25
+ /**
26
+ * Configuration for keyboard shortcuts.
27
+ */
28
+ shortcuts?: {
29
+ categories?: Record<string, CategoryConfig>
30
+ }
20
31
  /**
21
32
  * Configuration for the Logo component variants.
22
33
  */
@@ -40,20 +51,21 @@ export interface UIOptions {
40
51
  /**
41
52
  * Custom colors. Each color can be:
42
53
  *
43
- * - **Flat format**: `{ "500": "#7146ff", "600": "#6222ff" }` — used in all modes. No mode-specific
44
- * buckets needed.
45
- * - **Mode format**: flat shades at root define the base; `light`, `dark`, `flat` buckets layer on
46
- * top:
54
+ * - **Flat format**: `{ "500": "#7146ff", "600": "#6222ff" }` — used as the base for autogenerated
55
+ * light and dark shades via `color-mix(in oklch, ...)`.
56
+ * - **Mode format**: provide explicit `light` and/or `dark` buckets to control each scheme
57
+ * independently:
47
58
  *
48
59
  * ```ts
49
- * { "500": "base", light: { "600": "light-blue" }, dark: { "500": "dark-blue" } }
60
+ * { light: { "500": "#0064d7" }, dark: { "500": "#60a5fa" } }
50
61
  * ```
51
62
  *
52
- * Each shade falls back through: **mode bucket → flat → unthemed → light → dark**. Defining a
53
- * single source (e.g. only `dark`) propagates to all modes.
63
+ * Shades fall back through: **mode bucket → flat → light → dark**. Defining only one side
64
+ * autogenerates the other when `autogenerateColorModes` is enabled.
54
65
  *
55
- * Use the `theme` prop on components to pin colors: `<Button theme="flat">` forces the flat
56
- * bucket regardless of current mode.
66
+ * To pin a component to a specific scheme, use `theme="light"` or `theme="dark"` on the component
67
+ * this sets `color-scheme` natively on the element, causing all `light-dark()` variables to
68
+ * resolve to the correct side.
57
69
  */
58
70
  colors?: Record<
59
71
  string,
@@ -61,7 +73,6 @@ export interface UIOptions {
61
73
  | {
62
74
  light?: Record<string, string>
63
75
  dark?: Record<string, string>
64
- flat?: Record<string, string>
65
76
  }
66
77
  >
67
78
  /**
@@ -119,13 +130,15 @@ export function ui(options: UIOptions = {}): AstroIntegration[] {
119
130
  const resolvedConfig = {
120
131
  ...resolvedUI,
121
132
  logos: options.logos ?? {},
122
- colors: mergedColors
133
+ colors: mergedColors,
134
+ shortcuts: options.shortcuts ?? {}
123
135
  }
124
136
 
125
137
  const virtualModuleId = "virtual:rimelight-ui"
126
138
  const resolvedVirtualModuleId = "\0" + virtualModuleId
127
139
 
128
- function setViteConfig(updateConfig: (config: Record<string, unknown>) => void) {
140
+ async function setViteConfig(updateConfig: (config: Record<string, unknown>) => void) {
141
+ const docsMeta = await extractAllMeta()
129
142
  updateConfig({
130
143
  vite: {
131
144
  optimizeDeps: {
@@ -148,7 +161,10 @@ export function ui(options: UIOptions = {}): AstroIntegration[] {
148
161
  }
149
162
  return null
150
163
  }
151
- }
164
+ },
165
+ virtual({
166
+ "virtual:rimelight-ui-docs-meta": `export default ${JSON.stringify(docsMeta)}`
167
+ })
152
168
  ]
153
169
  }
154
170
  })
@@ -157,9 +173,9 @@ export function ui(options: UIOptions = {}): AstroIntegration[] {
157
173
  const rimelightUIIntegration: AstroIntegration = {
158
174
  name: "@rimelight/ui",
159
175
  hooks: {
160
- "astro:config:setup": ({ updateConfig, logger }) => {
176
+ "astro:config:setup": async ({ updateConfig, logger }) => {
161
177
  logger.info("Initializing @rimelight/ui core")
162
- setViteConfig(updateConfig)
178
+ await setViteConfig(updateConfig)
163
179
  }
164
180
  }
165
181
  }
@@ -8,17 +8,30 @@ function assertManifest(obj: unknown): asserts obj is Record<string, string> {
8
8
  if (!obj || typeof obj !== "object") throw new Error("Expected manifest")
9
9
  }
10
10
 
11
- function addSecurityHeaders(response: Response): Response {
12
- const newResponse = new Response(response.body, response)
13
- newResponse.headers.set("Referrer-Policy", "strict-origin-when-cross-origin")
14
- newResponse.headers.set("X-Content-Type-Options", "nosniff")
15
- newResponse.headers.set("X-Frame-Options", "DENY")
16
- newResponse.headers.set("Cross-Origin-Resource-Policy", "same-origin")
17
- newResponse.headers.set(
18
- "Strict-Transport-Security",
19
- "max-age=31536000; includeSubDomains; preload"
20
- )
21
- return newResponse
11
+ function addSecurityHeaders(response: Response, origin?: string): Response {
12
+ const headers = new Headers(response.headers)
13
+ headers.set("Referrer-Policy", "strict-origin-when-cross-origin")
14
+ headers.set("X-Content-Type-Options", "nosniff")
15
+ headers.set("X-Frame-Options", "DENY")
16
+ headers.set("Cross-Origin-Resource-Policy", "same-origin")
17
+ headers.set("Strict-Transport-Security", "max-age=31536000; includeSubDomains; preload")
18
+ headers.set("Permissions-Policy", "camera=(), microphone=(), geolocation=(), payment=(), usb=()")
19
+ if (origin) {
20
+ headers.set(
21
+ "Link",
22
+ [
23
+ `<${origin}/sitemap-index.xml>; rel="sitemap"`,
24
+ `<${origin}/llms.txt>; rel="llms"`,
25
+ `<${origin}/.well-known/api-catalog>; rel="api-catalog"`,
26
+ `<${origin}/rss.xml>; rel="alternate"; type="application/rss+xml"`
27
+ ].join(", ")
28
+ )
29
+ }
30
+ return new Response(response.body, {
31
+ status: response.status,
32
+ statusText: response.statusText,
33
+ headers
34
+ })
22
35
  }
23
36
 
24
37
  /**
@@ -34,14 +47,42 @@ export const security = defineMiddleware(async (context, next) => {
34
47
  const response = await next()
35
48
  const contentType = response.headers.get("content-type") || ""
36
49
 
37
- if (!contentType.includes("text/html")) {
38
- return addSecurityHeaders(response)
50
+ if (import.meta.env.DEV) {
51
+ if (!contentType.includes("text/html")) {
52
+ return addSecurityHeaders(response, context.url.origin)
53
+ }
54
+ const cleanHeaders = new Headers(response.headers)
55
+ cleanHeaders.delete("content-security-policy")
56
+ let modifiedHtml = await response.text()
57
+ modifiedHtml = modifiedHtml.replace(
58
+ /<meta\s[^>]*http-equiv\s*=\s*["']?content-security-policy[^>]*>/gi,
59
+ ""
60
+ )
61
+ return addSecurityHeaders(
62
+ new Response(modifiedHtml, {
63
+ status: response.status,
64
+ statusText: response.statusText,
65
+ headers: cleanHeaders
66
+ }),
67
+ context.url.origin
68
+ )
39
69
  }
40
70
 
41
- const cspHeader = response.headers.get("content-security-policy")
42
- const nonceValue = cspHeader ? crypto.randomUUID().replace(/-/g, "") : null
71
+ let cspHeader = response.headers.get("content-security-policy")
43
72
  const newHeaders = new Headers(response.headers)
44
73
 
74
+ if (cspHeader) {
75
+ // Unescape HTML entities (like &#39; or &#x27; to ') that Astro's native CSP generation mistakenly puts in the header
76
+ cspHeader = cspHeader
77
+ .replace(/&#0*39;/g, "'")
78
+ .replace(/&#x0*27;/gi, "'")
79
+ .replace(/&quot;/g, '"')
80
+ .replace(/&amp;/g, "&")
81
+ newHeaders.set("content-security-policy", cspHeader)
82
+ }
83
+
84
+ const nonceValue = cspHeader ? crypto.randomUUID().replace(/-/g, "") : null
85
+
45
86
  if (cspHeader && nonceValue) {
46
87
  let newCsp = cspHeader
47
88
  if (newCsp.includes("script-src ")) {
@@ -77,6 +118,11 @@ export const security = defineMiddleware(async (context, next) => {
77
118
  }
78
119
  }
79
120
  })
121
+ .on('meta[http-equiv="content-security-policy" i]', {
122
+ element(el: any) {
123
+ el.remove()
124
+ }
125
+ })
80
126
 
81
127
  if (nonceValue) {
82
128
  rewriter = rewriter
@@ -106,12 +152,19 @@ export const security = defineMiddleware(async (context, next) => {
106
152
  statusText: response.statusText,
107
153
  headers: newHeaders
108
154
  })
109
- )
155
+ ),
156
+ context.url.origin
110
157
  )
111
158
  }
112
159
 
113
160
  let modifiedHtml = await response.text()
114
161
 
162
+ // Remove Astro-injected CSP meta tag to prevent duplicate CSP headers and HTML escaping errors
163
+ modifiedHtml = modifiedHtml.replace(
164
+ /<meta\s[^>]*http-equiv\s*=\s*["']?content-security-policy[^>]*>/gi,
165
+ ""
166
+ )
167
+
115
168
  assertManifest(manifest)
116
169
 
117
170
  const entries = Object.entries(manifest)
@@ -132,7 +185,10 @@ export const security = defineMiddleware(async (context, next) => {
132
185
  }
133
186
 
134
187
  if (nonceValue) {
135
- modifiedHtml = modifiedHtml.replace(/<head([^>]*)>/i, `<head$1>\n<meta name="csp-nonce" content="${nonceValue}">`)
188
+ modifiedHtml = modifiedHtml.replace(
189
+ /<head([^>]*)>/i,
190
+ `<head$1>\n<meta name="csp-nonce" content="${nonceValue}">`
191
+ )
136
192
  modifiedHtml = modifiedHtml.replace(
137
193
  /<script(?![^>]*nonce=)([^>]*)>/gi,
138
194
  `<script$1 nonce="${nonceValue}">`
@@ -148,7 +204,7 @@ export const security = defineMiddleware(async (context, next) => {
148
204
  status: response.status,
149
205
  statusText: response.statusText,
150
206
  headers: newHeaders
151
- })
207
+ }),
208
+ context.url.origin
152
209
  )
153
210
  })
154
-