@rimelight/ui 0.0.33 → 0.0.34
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.
- package/README.md +157 -157
- package/package.json +105 -105
- package/src/components/astro/RLAAspectRatio.astro +2 -2
- package/src/components/astro/RLAButton.astro +141 -139
- package/src/components/astro/RLAChart.astro +19 -34
- package/src/components/astro/RLAHead.astro +427 -196
- package/src/components/astro/RLAHeader.astro +66 -59
- package/src/components/astro/RLAImage.astro +61 -19
- package/src/components/astro/RLALink.astro +22 -23
- package/src/components/astro/RLALinkGroup.astro +66 -4
- package/src/components/astro/RLALocaleSelector.astro +136 -113
- package/src/components/astro/RLAMain.astro +8 -3
- package/src/components/astro/RLAMarquee.astro +9 -2
- package/src/components/astro/RLANavigationMenu.astro +245 -56
- package/src/components/astro/RLAPagination.astro +2 -4
- package/src/components/astro/RLAProgress.astro +8 -2
- package/src/components/astro/RLASelect.astro +38 -24
- package/src/components/astro/RLASlideover.astro +66 -1
- package/src/components/astro/RLASlider.astro +14 -14
- package/src/components/astro/RLASplitter.astro +14 -2
- package/src/components/astro/RLAStickySurface.astro +9 -2
- package/src/components/vue/RLVCheckbox.vue +68 -68
- package/src/components/vue/RLVForm.vue +44 -44
- package/src/components/vue/RLVFormField.vue +58 -58
- package/src/components/vue/RLVInput.vue +93 -93
- package/src/components/vue/RLVPost.vue +63 -63
- package/src/components/vue/RLVPosts.vue +21 -21
- package/src/components/vue/RLVToast.vue +68 -68
- package/src/components/vue/RLVToaster.vue +29 -29
- package/src/composables/index.ts +3 -3
- package/src/composables/useHeaderStore.ts +13 -14
- package/src/composables/useScrollToTop.ts +62 -62
- package/src/composables/useToast.ts +43 -42
- package/src/config/index.ts +1 -0
- package/src/config/security.ts +220 -0
- package/src/integrations/ui.ts +199 -199
- package/src/middleware/security.ts +75 -15
- package/src/plugins/index.ts +2 -2
- package/src/plugins/starlightDocsApi/index.ts +272 -272
- package/src/presets/defaults.ts +297 -297
- package/src/presets/index.ts +683 -637
- package/src/styles/index.css +160 -160
- package/src/themes/3d-hover.theme.ts +13 -13
- package/src/themes/accordion.theme.ts +13 -13
- package/src/themes/alert.theme.ts +131 -125
- package/src/themes/app.theme.ts +13 -13
- package/src/themes/audio.theme.ts +13 -13
- package/src/themes/avatar.theme.ts +84 -84
- package/src/themes/badge.theme.ts +169 -163
- package/src/themes/banner.theme.ts +13 -13
- package/src/themes/browser-mockup.theme.ts +13 -13
- package/src/themes/button.theme.ts +224 -202
- package/src/themes/calendar.theme.ts +13 -13
- package/src/themes/card.theme.ts +42 -42
- package/src/themes/changelog.theme.ts +13 -13
- package/src/themes/chart.theme.ts +22 -22
- package/src/themes/chat-message.theme.ts +13 -13
- package/src/themes/chat-messages.theme.ts +13 -13
- package/src/themes/chat-palette.theme.ts +13 -13
- package/src/themes/chat-prompt-submit.theme.ts +13 -13
- package/src/themes/chat-prompt.theme.ts +13 -13
- package/src/themes/chat-reasoning.theme.ts +13 -13
- package/src/themes/chat-shimmer.theme.ts +13 -13
- package/src/themes/chat-tool.theme.ts +13 -13
- package/src/themes/chat.theme.ts +13 -13
- package/src/themes/checkbox.theme.ts +50 -50
- package/src/themes/chip.theme.ts +74 -74
- package/src/themes/color-picker.theme.ts +13 -13
- package/src/themes/command-palette.theme.ts +13 -13
- package/src/themes/compare.theme.ts +13 -13
- package/src/themes/confirm.theme.ts +48 -48
- package/src/themes/container.theme.ts +13 -13
- package/src/themes/context-menu.theme.ts +13 -13
- package/src/themes/dashboard-group.theme.ts +13 -13
- package/src/themes/dashboard-navbar.theme.ts +13 -13
- package/src/themes/dashboard-panel.theme.ts +13 -13
- package/src/themes/dashboard-resize-handle.theme.ts +13 -13
- package/src/themes/dashboard-search-button.theme.ts +13 -13
- package/src/themes/dashboard-search.theme.ts +13 -13
- package/src/themes/dashboard-sidebar-collapse.theme.ts +13 -13
- package/src/themes/dashboard-sidebar-toggle.theme.ts +13 -13
- package/src/themes/dashboard-sidebar.theme.ts +13 -13
- package/src/themes/dashboard-toolbar.theme.ts +13 -13
- package/src/themes/dock.theme.ts +13 -13
- package/src/themes/drawer.theme.ts +61 -61
- package/src/themes/dropdown-menu.theme.ts +29 -29
- package/src/themes/editor.theme.ts +13 -13
- package/src/themes/empty.theme.ts +13 -13
- package/src/themes/error.theme.ts +13 -13
- package/src/themes/field-group.theme.ts +24 -24
- package/src/themes/fieldset.theme.ts +13 -13
- package/src/themes/floating-action.theme.ts +13 -13
- package/src/themes/footer.theme.ts +30 -30
- package/src/themes/form.theme.ts +13 -13
- package/src/themes/gallery.theme.ts +13 -13
- package/src/themes/head.theme.ts +13 -13
- package/src/themes/header.theme.ts +45 -46
- package/src/themes/icon.theme.ts +23 -23
- package/src/themes/image.theme.ts +23 -19
- package/src/themes/input-date.theme.ts +13 -13
- package/src/themes/input-menu.theme.ts +35 -35
- package/src/themes/input-number.theme.ts +13 -13
- package/src/themes/input-tags.theme.ts +13 -13
- package/src/themes/input-time.theme.ts +13 -13
- package/src/themes/input.theme.ts +42 -42
- package/src/themes/kbd.theme.ts +95 -89
- package/src/themes/knob.theme.ts +13 -13
- package/src/themes/link-group.theme.ts +32 -32
- package/src/themes/link.theme.ts +13 -13
- package/src/themes/listbox.theme.ts +13 -13
- package/src/themes/locale-selector.theme.ts +49 -49
- package/src/themes/logo.theme.ts +13 -13
- package/src/themes/main.theme.ts +13 -13
- package/src/themes/megamenu.theme.ts +13 -13
- package/src/themes/meter.theme.ts +13 -13
- package/src/themes/navigation-menu.theme.ts +44 -27
- package/src/themes/page-aside.theme.ts +13 -13
- package/src/themes/page-body.theme.ts +13 -13
- package/src/themes/page-header.theme.ts +13 -13
- package/src/themes/page-section.theme.ts +187 -187
- package/src/themes/page.theme.ts +13 -13
- package/src/themes/password.theme.ts +13 -13
- package/src/themes/phone-mockup.theme.ts +13 -13
- package/src/themes/placeholder.theme.ts +15 -15
- package/src/themes/post.theme.ts +33 -33
- package/src/themes/pricing-plan.theme.ts +13 -13
- package/src/themes/pricing-table.theme.ts +13 -13
- package/src/themes/progress.theme.ts +38 -38
- package/src/themes/prose.theme.ts +13 -13
- package/src/themes/qr-code.theme.ts +13 -13
- package/src/themes/quote.theme.ts +13 -13
- package/src/themes/radio-group.theme.ts +13 -13
- package/src/themes/rating.theme.ts +13 -13
- package/src/themes/scroll-area.theme.ts +26 -26
- package/src/themes/scroll-to-top.theme.ts +52 -52
- package/src/themes/select.theme.ts +29 -29
- package/src/themes/separator.theme.ts +147 -147
- package/src/themes/sidebar.theme.ts +38 -38
- package/src/themes/skeleton.theme.ts +21 -21
- package/src/themes/slideover.theme.ts +4 -4
- package/src/themes/slider.theme.ts +36 -36
- package/src/themes/speed-dial.theme.ts +13 -13
- package/src/themes/spinner.theme.ts +34 -34
- package/src/themes/splitter.theme.ts +23 -23
- package/src/themes/spoiler.theme.ts +13 -13
- package/src/themes/stepper.theme.ts +13 -13
- package/src/themes/switch.theme.ts +67 -67
- package/src/themes/table-of-contents.theme.ts +48 -48
- package/src/themes/tabs.theme.ts +52 -52
- package/src/themes/textarea.theme.ts +27 -27
- package/src/themes/theme-selector.theme.ts +15 -15
- package/src/themes/timeline.theme.ts +13 -13
- package/src/themes/toast.theme.ts +31 -31
- package/src/themes/tooltip.theme.ts +28 -28
- package/src/themes/tour.theme.ts +13 -13
- package/src/themes/tree.theme.ts +13 -13
- package/src/themes/user.theme.ts +13 -13
- package/src/themes/video.theme.ts +17 -17
- package/src/themes/watermark.theme.ts +13 -13
- package/src/themes/window-mockup.theme.ts +13 -13
- package/src/types/components/3d-hover.ts +11 -11
- package/src/types/components/alert.ts +2 -2
- package/src/types/components/app.ts +11 -11
- package/src/types/components/audio.ts +11 -11
- package/src/types/components/avatar-group.ts +11 -11
- package/src/types/components/avatar.ts +60 -60
- package/src/types/components/badge.ts +2 -2
- package/src/types/components/banner.ts +11 -11
- package/src/types/components/browser-mockup.ts +11 -11
- package/src/types/components/button.ts +74 -81
- package/src/types/components/calendar.ts +11 -11
- package/src/types/components/changelog.ts +11 -11
- package/src/types/components/chart.ts +2 -1
- package/src/types/components/chat-message.ts +11 -11
- package/src/types/components/chat-messages.ts +11 -11
- package/src/types/components/chat-palette.ts +11 -11
- package/src/types/components/chat-prompt-submit.ts +11 -11
- package/src/types/components/chat-prompt.ts +11 -11
- package/src/types/components/chat-reasoning.ts +11 -11
- package/src/types/components/chat-shimmer.ts +11 -11
- package/src/types/components/chat-tool.ts +11 -11
- package/src/types/components/chat.ts +11 -11
- package/src/types/components/checkbox.ts +2 -2
- package/src/types/components/chip.ts +17 -17
- package/src/types/components/collapsible.ts +2 -1
- package/src/types/components/color-picker.ts +11 -11
- package/src/types/components/command-palette.ts +11 -11
- package/src/types/components/compare.ts +11 -11
- package/src/types/components/container.ts +17 -17
- package/src/types/components/context-menu.ts +11 -11
- package/src/types/components/dashboard-group.ts +11 -11
- package/src/types/components/dashboard-navbar.ts +11 -11
- package/src/types/components/dashboard-panel.ts +11 -11
- package/src/types/components/dashboard-resize-handle.ts +11 -11
- package/src/types/components/dashboard-search-button.ts +11 -11
- package/src/types/components/dashboard-search.ts +11 -11
- package/src/types/components/dashboard-sidebar-collapse.ts +11 -11
- package/src/types/components/dashboard-sidebar-toggle.ts +11 -11
- package/src/types/components/dashboard-sidebar.ts +11 -11
- package/src/types/components/dashboard-toolbar.ts +11 -11
- package/src/types/components/dock.ts +11 -11
- package/src/types/components/dropdown-menu.ts +2 -1
- package/src/types/components/editor.ts +11 -11
- package/src/types/components/empty.ts +11 -11
- package/src/types/components/error.ts +11 -11
- package/src/types/components/fieldset.ts +11 -11
- package/src/types/components/file-upload.ts +2 -1
- package/src/types/components/floating-action.ts +11 -11
- package/src/types/components/form.ts +19 -19
- package/src/types/components/gallery.ts +11 -11
- package/src/types/components/icon.ts +19 -19
- package/src/types/components/image.ts +32 -28
- package/src/types/components/index.ts +134 -135
- package/src/types/components/input-date.ts +11 -11
- package/src/types/components/input-menu.ts +44 -43
- package/src/types/components/input-number.ts +11 -11
- package/src/types/components/input-pin.ts +36 -35
- package/src/types/components/input-tags.ts +11 -11
- package/src/types/components/input-time.ts +11 -11
- package/src/types/components/input.ts +2 -2
- package/src/types/components/knob.ts +11 -11
- package/src/types/components/link-group.ts +45 -23
- package/src/types/components/link.ts +4 -0
- package/src/types/components/listbox.ts +11 -11
- package/src/types/components/locale-selector.ts +33 -33
- package/src/types/components/logo.ts +32 -31
- package/src/types/components/main.ts +17 -17
- package/src/types/components/megamenu.ts +11 -11
- package/src/types/components/meter.ts +11 -11
- package/src/types/components/modal.ts +39 -39
- package/src/types/components/navigation-menu.ts +59 -54
- package/src/types/components/page-aside.ts +11 -11
- package/src/types/components/page-body.ts +11 -11
- package/src/types/components/page-header.ts +11 -11
- package/src/types/components/page.ts +11 -11
- package/src/types/components/password.ts +11 -11
- package/src/types/components/phone-mockup.ts +5 -5
- package/src/types/components/pin-input.ts +11 -11
- package/src/types/components/popover.ts +23 -23
- package/src/types/components/post.ts +35 -35
- package/src/types/components/pricing-plan.ts +11 -11
- package/src/types/components/pricing-table.ts +11 -11
- package/src/types/components/progress.ts +33 -33
- package/src/types/components/prose.ts +11 -11
- package/src/types/components/qr-code.ts +11 -11
- package/src/types/components/radio-group.ts +11 -11
- package/src/types/components/rating.ts +11 -11
- package/src/types/components/scroll-area.ts +23 -23
- package/src/types/components/scroll-to-top.ts +2 -2
- package/src/types/components/select.ts +2 -1
- package/src/types/components/separator.ts +19 -19
- package/src/types/components/sidebar.ts +87 -72
- package/src/types/components/slideover.ts +31 -31
- package/src/types/components/slider.ts +2 -2
- package/src/types/components/speed-dial.ts +11 -11
- package/src/types/components/spinner.ts +25 -25
- package/src/types/components/splitter.ts +19 -19
- package/src/types/components/spoiler.ts +11 -11
- package/src/types/components/stepper.ts +11 -11
- package/src/types/components/sticky-surface.ts +19 -19
- package/src/types/components/switch.ts +41 -41
- package/src/types/components/table-of-contents.ts +17 -17
- package/src/types/components/tabs.ts +2 -1
- package/src/types/components/textarea.ts +2 -1
- package/src/types/components/theme-selector.ts +15 -15
- package/src/types/components/timeline.ts +11 -11
- package/src/types/components/toast.ts +2 -1
- package/src/types/components/tooltip.ts +23 -23
- package/src/types/components/tour.ts +11 -11
- package/src/types/components/tree.ts +11 -11
- package/src/types/components/user.ts +11 -11
- package/src/types/components/watermark.ts +11 -11
- package/src/types/components/window-mockup.ts +11 -11
- package/src/types/theme.ts +10 -0
- package/src/utils/docs.ts +215 -189
- package/src/utils/headerStack.ts +95 -95
- package/src/utils/index.ts +5 -5
- package/src/components/astro/RLABlogPost.astro +0 -7
- package/src/components/astro/RLABlogPosts.astro +0 -9
- package/src/components/astro/RLAPosts.astro +0 -23
- package/src/themes/posts.theme.ts +0 -13
- package/src/types/components/posts.ts +0 -11
|
@@ -0,0 +1,220 @@
|
|
|
1
|
+
import type { AstroUserConfig } from "astro"
|
|
2
|
+
|
|
3
|
+
export type AstroSecurityConfig = NonNullable<AstroUserConfig["security"]>
|
|
4
|
+
export type AstroCspConfig = Exclude<NonNullable<AstroSecurityConfig["csp"]>, boolean>
|
|
5
|
+
|
|
6
|
+
export interface SecurityConfigOptions {
|
|
7
|
+
/**
|
|
8
|
+
* The base domain name for this project (e.g., "starter.rimelight.com") used to autoconfigure
|
|
9
|
+
* standard allowedDomains and img-src CDN targets.
|
|
10
|
+
*/
|
|
11
|
+
domain: string
|
|
12
|
+
/**
|
|
13
|
+
* Additional Allowed Domains (appended to the default wildcard subdomains of `domain`)
|
|
14
|
+
*/
|
|
15
|
+
allowedDomains?: AstroSecurityConfig["allowedDomains"]
|
|
16
|
+
/**
|
|
17
|
+
* Additional sources to allow for img-src directive
|
|
18
|
+
*/
|
|
19
|
+
imgSrc?: string[]
|
|
20
|
+
/**
|
|
21
|
+
* Additional sources to allow for connect-src directive
|
|
22
|
+
*/
|
|
23
|
+
connectSrc?: string[]
|
|
24
|
+
/**
|
|
25
|
+
* Additional sources to allow for frame-src directive
|
|
26
|
+
*/
|
|
27
|
+
frameSrc?: string[]
|
|
28
|
+
/**
|
|
29
|
+
* Additional script resources
|
|
30
|
+
*/
|
|
31
|
+
scriptResources?: string[]
|
|
32
|
+
/**
|
|
33
|
+
* Additional style resources
|
|
34
|
+
*/
|
|
35
|
+
styleResources?: string[]
|
|
36
|
+
/**
|
|
37
|
+
* Direct overrides for any security config fields
|
|
38
|
+
*/
|
|
39
|
+
overrides?: Partial<Omit<AstroSecurityConfig, "csp">> & {
|
|
40
|
+
csp?: Partial<AstroCspConfig>
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Generates a standard, strictly configured Security/CSP object for Astro configurations with
|
|
46
|
+
* support for easy customization and additions per project.
|
|
47
|
+
*
|
|
48
|
+
* @example
|
|
49
|
+
* ```ts
|
|
50
|
+
* // Default returned shape:
|
|
51
|
+
* {
|
|
52
|
+
* checkOrigin: true,
|
|
53
|
+
* allowedDomains: [
|
|
54
|
+
* {
|
|
55
|
+
* hostname: "**.domain.com",
|
|
56
|
+
* protocol: "https"
|
|
57
|
+
* }
|
|
58
|
+
* ],
|
|
59
|
+
* csp: {
|
|
60
|
+
* algorithm: "SHA-384",
|
|
61
|
+
* directives: [
|
|
62
|
+
* "default-src 'none'",
|
|
63
|
+
* "img-src 'self' data: https://cdn.domain.com https://i3.ytimg.com https://www.youtube.com https://www.youtube-nocookie.com",
|
|
64
|
+
* "font-src 'self'",
|
|
65
|
+
* "connect-src 'self' https://cloudflareinsights.com",
|
|
66
|
+
* "frame-ancestors 'none'",
|
|
67
|
+
* "frame-src https://www.youtube.com https://www.youtube-nocookie.com",
|
|
68
|
+
* "upgrade-insecure-requests",
|
|
69
|
+
* "base-uri 'self'",
|
|
70
|
+
* "form-action 'self'"
|
|
71
|
+
* ],
|
|
72
|
+
* scriptDirective: {
|
|
73
|
+
* resources: [
|
|
74
|
+
* "'self'",
|
|
75
|
+
* "https://static.cloudflareinsights.com",
|
|
76
|
+
* "https://betterlytics.io/analytics.js",
|
|
77
|
+
* "'inline-speculation-rules'"
|
|
78
|
+
* ]
|
|
79
|
+
* },
|
|
80
|
+
* styleDirective: {
|
|
81
|
+
* resources: [
|
|
82
|
+
* "'self'",
|
|
83
|
+
* "'sha256-SKuaOGnks7NAUq37nvw1PfGEE0lOAs5ERbiYRbGFIbw='"
|
|
84
|
+
* ]
|
|
85
|
+
* }
|
|
86
|
+
* }
|
|
87
|
+
* }
|
|
88
|
+
* ```
|
|
89
|
+
*/
|
|
90
|
+
export function defineSecurity(options: SecurityConfigOptions): AstroSecurityConfig {
|
|
91
|
+
const { domain, overrides } = options
|
|
92
|
+
const domainWithWildcard = `**.${domain}`
|
|
93
|
+
|
|
94
|
+
// 1. Build default allowed domains
|
|
95
|
+
const allowedDomains = [
|
|
96
|
+
{
|
|
97
|
+
hostname: domainWithWildcard,
|
|
98
|
+
protocol: "https" as const
|
|
99
|
+
},
|
|
100
|
+
...(options.allowedDomains || [])
|
|
101
|
+
]
|
|
102
|
+
|
|
103
|
+
// 2. Build CSP directives
|
|
104
|
+
const imgSources = Array.from(
|
|
105
|
+
new Set([
|
|
106
|
+
"'self'",
|
|
107
|
+
"data:",
|
|
108
|
+
`https://cdn.${domain}`,
|
|
109
|
+
"https://i3.ytimg.com",
|
|
110
|
+
"https://www.youtube.com",
|
|
111
|
+
"https://www.youtube-nocookie.com",
|
|
112
|
+
...(options.imgSrc || [])
|
|
113
|
+
])
|
|
114
|
+
)
|
|
115
|
+
|
|
116
|
+
const connectSources = Array.from(
|
|
117
|
+
new Set(["'self'", "https://cloudflareinsights.com", ...(options.connectSrc || [])])
|
|
118
|
+
)
|
|
119
|
+
|
|
120
|
+
const frameSources = Array.from(
|
|
121
|
+
new Set([
|
|
122
|
+
"https://www.youtube.com",
|
|
123
|
+
"https://www.youtube-nocookie.com",
|
|
124
|
+
...(options.frameSrc || [])
|
|
125
|
+
])
|
|
126
|
+
)
|
|
127
|
+
|
|
128
|
+
const baseDirectives: AstroCspConfig["directives"] = [
|
|
129
|
+
"default-src 'none'",
|
|
130
|
+
`img-src ${imgSources.join(" ")}`,
|
|
131
|
+
"font-src 'self'",
|
|
132
|
+
`connect-src ${connectSources.join(" ")}`,
|
|
133
|
+
"frame-ancestors 'none'",
|
|
134
|
+
`frame-src ${frameSources.join(" ")}`,
|
|
135
|
+
"upgrade-insecure-requests",
|
|
136
|
+
"base-uri 'self'",
|
|
137
|
+
"form-action 'self'"
|
|
138
|
+
]
|
|
139
|
+
|
|
140
|
+
// 3. Build script & style directives
|
|
141
|
+
const scriptResources = Array.from(
|
|
142
|
+
new Set([
|
|
143
|
+
"'self'",
|
|
144
|
+
"https://static.cloudflareinsights.com",
|
|
145
|
+
"https://betterlytics.io/analytics.js",
|
|
146
|
+
"'inline-speculation-rules'",
|
|
147
|
+
// Astro ClientRouter (View Transitions)
|
|
148
|
+
"'sha256-ZuMSxilKU+4KIM8LWna4lqBEKzd6WaiAjz6gamhm7zM='",
|
|
149
|
+
...(options.scriptResources || [])
|
|
150
|
+
])
|
|
151
|
+
)
|
|
152
|
+
|
|
153
|
+
const styleResources = Array.from(
|
|
154
|
+
new Set([
|
|
155
|
+
"'self'",
|
|
156
|
+
// Astro ClientRouter (View Transitions)
|
|
157
|
+
"'sha256-SKuaOGnks7NAUq37nvw1PfGEE0lOAs5ERbiYRbGFIbw='",
|
|
158
|
+
...(options.styleResources || [])
|
|
159
|
+
])
|
|
160
|
+
)
|
|
161
|
+
|
|
162
|
+
// 4. Build base SecurityConfig
|
|
163
|
+
const securityConfig: AstroSecurityConfig = {
|
|
164
|
+
checkOrigin: true,
|
|
165
|
+
allowedDomains,
|
|
166
|
+
csp: {
|
|
167
|
+
algorithm: "SHA-384",
|
|
168
|
+
directives: baseDirectives,
|
|
169
|
+
scriptDirective: {
|
|
170
|
+
resources: scriptResources
|
|
171
|
+
},
|
|
172
|
+
styleDirective: {
|
|
173
|
+
resources: styleResources
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
// 5. Merge overrides
|
|
179
|
+
if (overrides) {
|
|
180
|
+
const { csp, ...restOverrides } = overrides
|
|
181
|
+
Object.assign(securityConfig, restOverrides)
|
|
182
|
+
if (csp && typeof securityConfig.csp === "object" && securityConfig.csp !== null) {
|
|
183
|
+
const currentCsp = securityConfig.csp
|
|
184
|
+
const mergedCsp: AstroCspConfig = {
|
|
185
|
+
...currentCsp,
|
|
186
|
+
...csp
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
if (csp.scriptDirective || currentCsp.scriptDirective) {
|
|
190
|
+
mergedCsp.scriptDirective = {
|
|
191
|
+
...currentCsp.scriptDirective,
|
|
192
|
+
...csp.scriptDirective,
|
|
193
|
+
resources: Array.from(
|
|
194
|
+
new Set([
|
|
195
|
+
...(currentCsp.scriptDirective?.resources || []),
|
|
196
|
+
...(csp.scriptDirective?.resources || [])
|
|
197
|
+
])
|
|
198
|
+
)
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
if (csp.styleDirective || currentCsp.styleDirective) {
|
|
203
|
+
mergedCsp.styleDirective = {
|
|
204
|
+
...currentCsp.styleDirective,
|
|
205
|
+
...csp.styleDirective,
|
|
206
|
+
resources: Array.from(
|
|
207
|
+
new Set([
|
|
208
|
+
...(currentCsp.styleDirective?.resources || []),
|
|
209
|
+
...(csp.styleDirective?.resources || [])
|
|
210
|
+
])
|
|
211
|
+
)
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
securityConfig.csp = mergedCsp
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
return securityConfig
|
|
220
|
+
}
|
package/src/integrations/ui.ts
CHANGED
|
@@ -1,199 +1,199 @@
|
|
|
1
|
-
import type { AstroIntegration } from "astro"
|
|
2
|
-
import UnoCSS from "unocss/astro"
|
|
3
|
-
import vue from "@astrojs/vue"
|
|
4
|
-
import defu from "defu"
|
|
5
|
-
import { defaultUIConfig } from "../themes"
|
|
6
|
-
import type { ComponentTheme } from "../utils/defineTheme"
|
|
7
|
-
import rimelightUiPreset, {
|
|
8
|
-
uiSrcGlob,
|
|
9
|
-
uiFilesystemGlob,
|
|
10
|
-
type ColorConfigValue,
|
|
11
|
-
type RimelightPresetOptions
|
|
12
|
-
} from "../presets"
|
|
13
|
-
|
|
14
|
-
/**
|
|
15
|
-
* Shape of the `ui` config that can be passed to the integration.
|
|
16
|
-
*/
|
|
17
|
-
export type UIConfigOverrides = Record<string, Partial<ComponentTheme>>
|
|
18
|
-
|
|
19
|
-
export interface UIOptions {
|
|
20
|
-
/**
|
|
21
|
-
* Configuration for the Logo component variants.
|
|
22
|
-
*/
|
|
23
|
-
logos?: Record<
|
|
24
|
-
string,
|
|
25
|
-
| string
|
|
26
|
-
| {
|
|
27
|
-
light?: string
|
|
28
|
-
dark?: string
|
|
29
|
-
color?: string
|
|
30
|
-
white?: string
|
|
31
|
-
black?: string
|
|
32
|
-
[key: string]: string | undefined
|
|
33
|
-
}
|
|
34
|
-
>
|
|
35
|
-
/**
|
|
36
|
-
* Global UI overrides applied to all components. Merged with defaults via `defu` (first arg
|
|
37
|
-
* wins).
|
|
38
|
-
*/
|
|
39
|
-
ui?: UIConfigOverrides
|
|
40
|
-
/**
|
|
41
|
-
* Custom colors. Each color can be:
|
|
42
|
-
*
|
|
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:
|
|
47
|
-
*
|
|
48
|
-
* ```ts
|
|
49
|
-
* { "500": "base", light: { "600": "light-blue" }, dark: { "500": "dark-blue" } }
|
|
50
|
-
* ```
|
|
51
|
-
*
|
|
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.
|
|
54
|
-
*
|
|
55
|
-
* Use the `theme` prop on components to pin colors: `<Button theme="flat">` forces the flat
|
|
56
|
-
* bucket regardless of current mode.
|
|
57
|
-
*/
|
|
58
|
-
colors?: Record<
|
|
59
|
-
string,
|
|
60
|
-
| Record<string, string>
|
|
61
|
-
| {
|
|
62
|
-
light?: Record<string, string>
|
|
63
|
-
dark?: Record<string, string>
|
|
64
|
-
flat?: Record<string, string>
|
|
65
|
-
}
|
|
66
|
-
>
|
|
67
|
-
/**
|
|
68
|
-
* When `true`, auto-generates missing `light`/`dark` mode buckets from flat color values using
|
|
69
|
-
* `color-mix(in oklch, ...)`. Explicitly provided buckets always take precedence. Defaults to
|
|
70
|
-
* `true`.
|
|
71
|
-
*/
|
|
72
|
-
autogenerateColorModes?: boolean
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
/**
|
|
76
|
-
* Astro integration for `@rimelight/ui`.
|
|
77
|
-
*
|
|
78
|
-
* Provides global UI configuration via a virtual module. Components import `virtual:rimelight-ui`
|
|
79
|
-
* to access the merged config.
|
|
80
|
-
*
|
|
81
|
-
* @example
|
|
82
|
-
* // astro.config.mjs
|
|
83
|
-
* import { ui } from "@rimelight/ui/integrations"
|
|
84
|
-
*
|
|
85
|
-
* export default defineConfig({
|
|
86
|
-
* integrations: [
|
|
87
|
-
* ui({
|
|
88
|
-
* ui: {
|
|
89
|
-
* button: {
|
|
90
|
-
* defaultVariants: { variant: "primary" }
|
|
91
|
-
* }
|
|
92
|
-
* }
|
|
93
|
-
* })
|
|
94
|
-
* ]
|
|
95
|
-
* })
|
|
96
|
-
*/
|
|
97
|
-
export function ui(options: UIOptions = {}): AstroIntegration[] {
|
|
98
|
-
const resolvedUI = defu(options.ui ?? {}, defaultUIConfig)
|
|
99
|
-
const coreColors = [
|
|
100
|
-
"primary",
|
|
101
|
-
"secondary",
|
|
102
|
-
"info",
|
|
103
|
-
"success",
|
|
104
|
-
"warning",
|
|
105
|
-
"error",
|
|
106
|
-
"commentary",
|
|
107
|
-
"ideation",
|
|
108
|
-
"source"
|
|
109
|
-
]
|
|
110
|
-
const userColors = (options.colors ?? {}) as Record<string, ColorConfigValue>
|
|
111
|
-
const userColorNames = Object.keys(userColors)
|
|
112
|
-
const mergedColors = [...new Set([...coreColors, ...userColorNames])]
|
|
113
|
-
const presetOptions: RimelightPresetOptions = {
|
|
114
|
-
colors: userColors
|
|
115
|
-
}
|
|
116
|
-
if (options.autogenerateColorModes !== undefined) {
|
|
117
|
-
presetOptions.autogenerateColorModes = options.autogenerateColorModes
|
|
118
|
-
}
|
|
119
|
-
const resolvedConfig = {
|
|
120
|
-
...resolvedUI,
|
|
121
|
-
logos: options.logos ?? {},
|
|
122
|
-
colors: mergedColors
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
const virtualModuleId = "virtual:rimelight-ui"
|
|
126
|
-
const resolvedVirtualModuleId = "\0" + virtualModuleId
|
|
127
|
-
|
|
128
|
-
function setViteConfig(updateConfig: (config: Record<string, unknown>) => void) {
|
|
129
|
-
updateConfig({
|
|
130
|
-
vite: {
|
|
131
|
-
optimizeDeps: {
|
|
132
|
-
exclude: ["@rimelight/ui"]
|
|
133
|
-
},
|
|
134
|
-
ssr: {
|
|
135
|
-
noExternal: ["@rimelight/ui"]
|
|
136
|
-
},
|
|
137
|
-
plugins: [
|
|
138
|
-
{
|
|
139
|
-
name: "vite-plugin-rimelight-ui-config",
|
|
140
|
-
enforce: "pre",
|
|
141
|
-
resolveId(id: string) {
|
|
142
|
-
if (id === virtualModuleId) return resolvedVirtualModuleId
|
|
143
|
-
return null
|
|
144
|
-
},
|
|
145
|
-
load(id: string) {
|
|
146
|
-
if (id === resolvedVirtualModuleId) {
|
|
147
|
-
return `export const getUIConfig = () => (${JSON.stringify(resolvedConfig)});`
|
|
148
|
-
}
|
|
149
|
-
return null
|
|
150
|
-
}
|
|
151
|
-
}
|
|
152
|
-
]
|
|
153
|
-
}
|
|
154
|
-
})
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
const rimelightUIIntegration: AstroIntegration = {
|
|
158
|
-
name: "@rimelight/ui",
|
|
159
|
-
hooks: {
|
|
160
|
-
"astro:config:setup": ({ updateConfig, logger }) => {
|
|
161
|
-
logger.info("Initializing @rimelight/ui core")
|
|
162
|
-
setViteConfig(updateConfig)
|
|
163
|
-
}
|
|
164
|
-
}
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
return [
|
|
168
|
-
UnoCSS({
|
|
169
|
-
presets: [rimelightUiPreset(presetOptions)],
|
|
170
|
-
content: {
|
|
171
|
-
pipeline: {
|
|
172
|
-
include: [
|
|
173
|
-
/\.(vue|svelte|[jt]sx|mdx?|astro|elm|php|phtml|html)($|\?)/,
|
|
174
|
-
"src/**/*.{js,ts,jsx,tsx,vue,svelte,astro}",
|
|
175
|
-
uiSrcGlob,
|
|
176
|
-
"../ui/src/**/*.{js,ts,jsx,tsx,vue,svelte,astro}"
|
|
177
|
-
]
|
|
178
|
-
},
|
|
179
|
-
filesystem: [uiFilesystemGlob, "../ui/src/**/*", "src/components/**/*", "src/pages/**/*"]
|
|
180
|
-
},
|
|
181
|
-
configResolved(config) {
|
|
182
|
-
if (process.env.NODE_ENV === "development" && !process.env.UNO_CONFIG_LOGGED) {
|
|
183
|
-
process.env.UNO_CONFIG_LOGGED = "true"
|
|
184
|
-
console.log(`[UnoCSS] Presets: ${config.presets.map((p) => p.name).join(", ")}`)
|
|
185
|
-
console.log(`[UnoCSS] Rules: ${config.rules.length}`)
|
|
186
|
-
console.log(`[UnoCSS] Shortcuts: ${Object.keys(config.shortcuts).length}`)
|
|
187
|
-
const ruleNames = config.rules.map((r) =>
|
|
188
|
-
Array.isArray(r) ? r[0].toString() : "dynamic"
|
|
189
|
-
)
|
|
190
|
-
const duplicates = ruleNames.filter((item, index) => ruleNames.indexOf(item) !== index)
|
|
191
|
-
const filtered = duplicates.filter((d) => d !== "/^(.+?)-(\\$.+)$/")
|
|
192
|
-
if (filtered.length > 0) console.warn(`[UnoCSS] Rule collisions: ${filtered.join(", ")}`)
|
|
193
|
-
}
|
|
194
|
-
}
|
|
195
|
-
}),
|
|
196
|
-
vue(),
|
|
197
|
-
rimelightUIIntegration
|
|
198
|
-
]
|
|
199
|
-
}
|
|
1
|
+
import type { AstroIntegration } from "astro"
|
|
2
|
+
import UnoCSS from "unocss/astro"
|
|
3
|
+
import vue from "@astrojs/vue"
|
|
4
|
+
import defu from "defu"
|
|
5
|
+
import { defaultUIConfig } from "../themes"
|
|
6
|
+
import type { ComponentTheme } from "../utils/defineTheme"
|
|
7
|
+
import rimelightUiPreset, {
|
|
8
|
+
uiSrcGlob,
|
|
9
|
+
uiFilesystemGlob,
|
|
10
|
+
type ColorConfigValue,
|
|
11
|
+
type RimelightPresetOptions
|
|
12
|
+
} from "../presets"
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Shape of the `ui` config that can be passed to the integration.
|
|
16
|
+
*/
|
|
17
|
+
export type UIConfigOverrides = Record<string, Partial<ComponentTheme>>
|
|
18
|
+
|
|
19
|
+
export interface UIOptions {
|
|
20
|
+
/**
|
|
21
|
+
* Configuration for the Logo component variants.
|
|
22
|
+
*/
|
|
23
|
+
logos?: Record<
|
|
24
|
+
string,
|
|
25
|
+
| string
|
|
26
|
+
| {
|
|
27
|
+
light?: string
|
|
28
|
+
dark?: string
|
|
29
|
+
color?: string
|
|
30
|
+
white?: string
|
|
31
|
+
black?: string
|
|
32
|
+
[key: string]: string | undefined
|
|
33
|
+
}
|
|
34
|
+
>
|
|
35
|
+
/**
|
|
36
|
+
* Global UI overrides applied to all components. Merged with defaults via `defu` (first arg
|
|
37
|
+
* wins).
|
|
38
|
+
*/
|
|
39
|
+
ui?: UIConfigOverrides
|
|
40
|
+
/**
|
|
41
|
+
* Custom colors. Each color can be:
|
|
42
|
+
*
|
|
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:
|
|
47
|
+
*
|
|
48
|
+
* ```ts
|
|
49
|
+
* { "500": "base", light: { "600": "light-blue" }, dark: { "500": "dark-blue" } }
|
|
50
|
+
* ```
|
|
51
|
+
*
|
|
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.
|
|
54
|
+
*
|
|
55
|
+
* Use the `theme` prop on components to pin colors: `<Button theme="flat">` forces the flat
|
|
56
|
+
* bucket regardless of current mode.
|
|
57
|
+
*/
|
|
58
|
+
colors?: Record<
|
|
59
|
+
string,
|
|
60
|
+
| Record<string, string>
|
|
61
|
+
| {
|
|
62
|
+
light?: Record<string, string>
|
|
63
|
+
dark?: Record<string, string>
|
|
64
|
+
flat?: Record<string, string>
|
|
65
|
+
}
|
|
66
|
+
>
|
|
67
|
+
/**
|
|
68
|
+
* When `true`, auto-generates missing `light`/`dark` mode buckets from flat color values using
|
|
69
|
+
* `color-mix(in oklch, ...)`. Explicitly provided buckets always take precedence. Defaults to
|
|
70
|
+
* `true`.
|
|
71
|
+
*/
|
|
72
|
+
autogenerateColorModes?: boolean
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* Astro integration for `@rimelight/ui`.
|
|
77
|
+
*
|
|
78
|
+
* Provides global UI configuration via a virtual module. Components import `virtual:rimelight-ui`
|
|
79
|
+
* to access the merged config.
|
|
80
|
+
*
|
|
81
|
+
* @example
|
|
82
|
+
* // astro.config.mjs
|
|
83
|
+
* import { ui } from "@rimelight/ui/integrations"
|
|
84
|
+
*
|
|
85
|
+
* export default defineConfig({
|
|
86
|
+
* integrations: [
|
|
87
|
+
* ui({
|
|
88
|
+
* ui: {
|
|
89
|
+
* button: {
|
|
90
|
+
* defaultVariants: { variant: "primary" }
|
|
91
|
+
* }
|
|
92
|
+
* }
|
|
93
|
+
* })
|
|
94
|
+
* ]
|
|
95
|
+
* })
|
|
96
|
+
*/
|
|
97
|
+
export function ui(options: UIOptions = {}): AstroIntegration[] {
|
|
98
|
+
const resolvedUI = defu(options.ui ?? {}, defaultUIConfig)
|
|
99
|
+
const coreColors = [
|
|
100
|
+
"primary",
|
|
101
|
+
"secondary",
|
|
102
|
+
"info",
|
|
103
|
+
"success",
|
|
104
|
+
"warning",
|
|
105
|
+
"error",
|
|
106
|
+
"commentary",
|
|
107
|
+
"ideation",
|
|
108
|
+
"source"
|
|
109
|
+
]
|
|
110
|
+
const userColors = (options.colors ?? {}) as Record<string, ColorConfigValue>
|
|
111
|
+
const userColorNames = Object.keys(userColors)
|
|
112
|
+
const mergedColors = [...new Set([...coreColors, ...userColorNames])]
|
|
113
|
+
const presetOptions: RimelightPresetOptions = {
|
|
114
|
+
colors: userColors
|
|
115
|
+
}
|
|
116
|
+
if (options.autogenerateColorModes !== undefined) {
|
|
117
|
+
presetOptions.autogenerateColorModes = options.autogenerateColorModes
|
|
118
|
+
}
|
|
119
|
+
const resolvedConfig = {
|
|
120
|
+
...resolvedUI,
|
|
121
|
+
logos: options.logos ?? {},
|
|
122
|
+
colors: mergedColors
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
const virtualModuleId = "virtual:rimelight-ui"
|
|
126
|
+
const resolvedVirtualModuleId = "\0" + virtualModuleId
|
|
127
|
+
|
|
128
|
+
function setViteConfig(updateConfig: (config: Record<string, unknown>) => void) {
|
|
129
|
+
updateConfig({
|
|
130
|
+
vite: {
|
|
131
|
+
optimizeDeps: {
|
|
132
|
+
exclude: ["@rimelight/ui"]
|
|
133
|
+
},
|
|
134
|
+
ssr: {
|
|
135
|
+
noExternal: ["@rimelight/ui"]
|
|
136
|
+
},
|
|
137
|
+
plugins: [
|
|
138
|
+
{
|
|
139
|
+
name: "vite-plugin-rimelight-ui-config",
|
|
140
|
+
enforce: "pre",
|
|
141
|
+
resolveId(id: string) {
|
|
142
|
+
if (id === virtualModuleId) return resolvedVirtualModuleId
|
|
143
|
+
return null
|
|
144
|
+
},
|
|
145
|
+
load(id: string) {
|
|
146
|
+
if (id === resolvedVirtualModuleId) {
|
|
147
|
+
return `export const getUIConfig = () => (${JSON.stringify(resolvedConfig)});`
|
|
148
|
+
}
|
|
149
|
+
return null
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
]
|
|
153
|
+
}
|
|
154
|
+
})
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
const rimelightUIIntegration: AstroIntegration = {
|
|
158
|
+
name: "@rimelight/ui",
|
|
159
|
+
hooks: {
|
|
160
|
+
"astro:config:setup": ({ updateConfig, logger }) => {
|
|
161
|
+
logger.info("Initializing @rimelight/ui core")
|
|
162
|
+
setViteConfig(updateConfig)
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
return [
|
|
168
|
+
UnoCSS({
|
|
169
|
+
presets: [rimelightUiPreset(presetOptions)],
|
|
170
|
+
content: {
|
|
171
|
+
pipeline: {
|
|
172
|
+
include: [
|
|
173
|
+
/\.(vue|svelte|[jt]sx|mdx?|astro|elm|php|phtml|html)($|\?)/,
|
|
174
|
+
"src/**/*.{js,ts,jsx,tsx,vue,svelte,astro}",
|
|
175
|
+
uiSrcGlob,
|
|
176
|
+
"../ui/src/**/*.{js,ts,jsx,tsx,vue,svelte,astro}"
|
|
177
|
+
]
|
|
178
|
+
},
|
|
179
|
+
filesystem: [uiFilesystemGlob, "../ui/src/**/*", "src/components/**/*", "src/pages/**/*"]
|
|
180
|
+
},
|
|
181
|
+
configResolved(config) {
|
|
182
|
+
if (process.env.NODE_ENV === "development" && !process.env.UNO_CONFIG_LOGGED) {
|
|
183
|
+
process.env.UNO_CONFIG_LOGGED = "true"
|
|
184
|
+
console.log(`[UnoCSS] Presets: ${config.presets.map((p) => p.name).join(", ")}`)
|
|
185
|
+
console.log(`[UnoCSS] Rules: ${config.rules.length}`)
|
|
186
|
+
console.log(`[UnoCSS] Shortcuts: ${Object.keys(config.shortcuts).length}`)
|
|
187
|
+
const ruleNames = config.rules.map((r) =>
|
|
188
|
+
Array.isArray(r) ? r[0].toString() : "dynamic"
|
|
189
|
+
)
|
|
190
|
+
const duplicates = ruleNames.filter((item, index) => ruleNames.indexOf(item) !== index)
|
|
191
|
+
const filtered = duplicates.filter((d) => d !== "/^(.+?)-(\\$.+)$/")
|
|
192
|
+
if (filtered.length > 0) console.warn(`[UnoCSS] Rule collisions: ${filtered.join(", ")}`)
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
}),
|
|
196
|
+
vue(),
|
|
197
|
+
rimelightUIIntegration
|
|
198
|
+
]
|
|
199
|
+
}
|