@rimelight/ui 0.0.34 → 0.0.36
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 +1 -0
- package/package.json +19 -24
- package/src/components/astro/RLAAccordion.astro +94 -18
- package/src/components/astro/RLAAvatar.astro +135 -68
- package/src/components/astro/RLABadge.astro +4 -2
- package/src/components/astro/RLABanner.astro +138 -23
- package/src/components/astro/RLABreadcrumb.astro +13 -0
- package/src/components/astro/RLAButton.astro +8 -4
- package/src/components/astro/RLACallout.astro +112 -0
- package/src/components/astro/RLACard.astro +6 -5
- package/src/components/astro/RLACarousel.astro +104 -75
- package/src/components/astro/RLAChart.astro +4 -1
- package/src/components/astro/RLAChip.astro +11 -5
- package/src/components/astro/RLACollapsible.astro +4 -1
- package/src/components/astro/RLAColorArea.astro +432 -0
- package/src/components/astro/RLAColorField.astro +300 -0
- package/src/components/astro/RLAColorSlider.astro +413 -0
- package/src/components/astro/RLAConfirm.astro +13 -11
- package/src/components/astro/RLACopyMarkdown.astro +78 -0
- package/src/components/astro/RLADate.astro +30 -0
- package/src/components/astro/RLADrawer.astro +50 -3
- package/src/components/astro/RLADropdownMenu.astro +78 -51
- package/src/components/astro/RLAFieldGroup.astro +4 -1
- package/src/components/astro/RLAFileUpload.astro +114 -100
- package/src/components/astro/RLAFooter.astro +2 -1
- package/src/components/astro/RLAFormField.astro +10 -6
- package/src/components/astro/RLAGrid.astro +31 -39
- package/src/components/astro/RLAHead.astro +139 -39
- package/src/components/astro/RLAHeader.astro +2 -1
- package/src/components/astro/RLAImage.astro +274 -251
- package/src/components/astro/RLAInput.astro +14 -9
- package/src/components/astro/RLAInputMenu.astro +119 -83
- package/src/components/astro/RLAKbd.astro +5 -5
- package/src/components/astro/RLALayoutGrid.astro +395 -0
- package/src/components/astro/RLALink.astro +23 -1
- package/src/components/astro/RLALinkGroup.astro +99 -99
- package/src/components/astro/RLALocaleSelector.astro +34 -41
- package/src/components/astro/RLALogo.astro +117 -90
- package/src/components/astro/RLAModal.astro +48 -18
- package/src/components/astro/RLANavigationMenu.astro +381 -326
- package/src/components/astro/{RLADocsPackageManagers.astro → RLAPackageManagers.astro} +81 -87
- package/src/components/astro/RLAPageSection.astro +4 -2
- package/src/components/astro/RLAPopover.astro +4 -3
- package/src/components/astro/RLAPost.astro +11 -2
- package/src/components/astro/RLAScrollArea.astro +4 -1
- package/src/components/astro/RLAScrollToTop.astro +200 -172
- package/src/components/astro/RLASearch.astro +282 -0
- package/src/components/astro/RLASelect.astro +78 -55
- package/src/components/astro/RLASeparator.astro +11 -6
- package/src/components/astro/RLAShare.astro +60 -0
- package/src/components/astro/RLAShortcuts.astro +429 -0
- package/src/components/astro/RLASidebar.astro +158 -212
- package/src/components/astro/RLASlideover.astro +47 -17
- package/src/components/astro/RLASplitter.astro +194 -141
- package/src/components/astro/RLASteps.astro +118 -71
- package/src/components/astro/RLASurround.astro +39 -0
- package/src/components/astro/RLATable.astro +4 -1
- package/src/components/astro/RLATableOfContents.astro +109 -23
- package/src/components/astro/RLATabs.astro +147 -133
- package/src/components/astro/RLATextarea.astro +4 -1
- package/src/components/astro/RLAThemeSelector.astro +105 -76
- package/src/components/astro/RLAToast.astro +35 -21
- package/src/components/vue/RLVBanner.vue +230 -0
- package/src/components/vue/RLVButton.vue +3 -2
- package/src/components/vue/RLVCheckbox.vue +4 -2
- package/src/components/vue/RLVFooter.vue +3 -2
- package/src/components/vue/RLVHeader.vue +3 -2
- package/src/components/vue/RLVIcon.vue +4 -2
- package/src/components/vue/RLVInput.vue +5 -4
- package/src/components/vue/RLVLogo.vue +25 -3
- package/src/components/vue/RLVPlaceholder.vue +3 -2
- package/src/components/vue/RLVPost.vue +8 -2
- package/src/components/vue/RLVProgress.vue +60 -0
- package/src/components/vue/RLVScrollToTop.vue +65 -52
- package/src/components/vue/RLVSection.vue +14 -13
- package/src/components/vue/RLVToast.vue +17 -4
- package/src/composables/index.ts +1 -0
- package/src/composables/useHeaderStore.ts +1 -0
- package/src/composables/useShortcuts.ts +11 -0
- package/src/config/security.ts +43 -36
- package/src/config/site.config.ts +1 -0
- package/src/docs/components/ApiChangelog.astro +147 -0
- package/src/{plugins/starlightDocsApi → docs}/components/ApiEmits.astro +4 -4
- package/src/{plugins/starlightDocsApi → docs}/components/ApiProps.astro +4 -4
- package/src/{plugins/starlightDocsApi → docs}/components/ApiSlots.astro +4 -4
- package/src/docs/components/ApiTheme.astro +100 -0
- package/src/docs/extractAll.ts +94 -0
- package/src/docs/extractors/extractAstro.ts +69 -0
- package/src/docs/extractors/extractTheme.ts +56 -0
- package/src/{plugins/starlightDocsApi/extract-vue.ts → docs/extractors/extractVue.ts} +164 -15
- package/src/{plugins/starlightDocsApi → docs}/utils.ts +1 -2
- package/src/env.d.ts +0 -12
- package/src/integrations/ui.ts +35 -19
- package/src/middleware/security.ts +75 -19
- package/src/presets/index.ts +118 -293
- package/src/styles/index.css +0 -2
- package/src/themes/accordion.theme.ts +29 -3
- package/src/themes/aspect-ratio.theme.ts +1 -1
- package/src/themes/avatar-group.theme.ts +1 -1
- package/src/themes/avatar.theme.ts +2 -2
- package/src/themes/badge.theme.ts +2 -3
- package/src/themes/banner.theme.ts +40 -4
- package/src/themes/breadcrumb.theme.ts +1 -1
- package/src/themes/button.theme.ts +21 -22
- package/src/themes/{alert.theme.ts → callout.theme.ts} +12 -39
- package/src/themes/card.theme.ts +17 -9
- package/src/themes/carousel.theme.ts +1 -1
- package/src/themes/checkbox.theme.ts +1 -2
- package/src/themes/chip.theme.ts +2 -3
- package/src/themes/color-area.theme.ts +33 -0
- package/src/themes/color-field.theme.ts +32 -0
- package/src/themes/color-slider.theme.ts +34 -0
- package/src/themes/confirm.theme.ts +1 -1
- package/src/themes/container.theme.ts +1 -1
- package/src/themes/drawer.theme.ts +1 -1
- package/src/themes/footer.theme.ts +2 -2
- package/src/themes/grid.theme.ts +38 -0
- package/src/themes/header.theme.ts +4 -3
- package/src/themes/hover-card.theme.ts +1 -1
- package/src/themes/image.theme.ts +11 -1
- package/src/themes/input.theme.ts +7 -1
- package/src/themes/kbd.theme.ts +2 -3
- package/src/themes/label.theme.ts +1 -1
- package/src/themes/layout-grid.theme.ts +16 -0
- package/src/themes/link-group.theme.ts +0 -4
- package/src/themes/marquee.theme.ts +1 -1
- package/src/themes/modal.theme.ts +1 -1
- package/src/themes/navigation-menu.theme.ts +2 -2
- package/src/themes/page-section.theme.ts +4 -2
- package/src/themes/pagination.theme.ts +1 -1
- package/src/themes/pin-input.theme.ts +1 -1
- package/src/themes/popover.theme.ts +1 -1
- package/src/themes/post.theme.ts +23 -3
- package/src/themes/progress.theme.ts +1 -2
- package/src/themes/scroll-to-top.theme.ts +2 -3
- package/src/themes/search.theme.ts +64 -0
- package/src/themes/separator.theme.ts +1 -1
- package/src/themes/slideover.theme.ts +1 -1
- package/src/themes/slider.theme.ts +1 -2
- package/src/themes/spinner.theme.ts +1 -2
- package/src/themes/{megamenu.theme.ts → steps.theme.ts} +3 -3
- package/src/themes/sticky-surface.theme.ts +1 -1
- package/src/themes/switch.theme.ts +1 -2
- package/src/themes/table-of-contents.theme.ts +21 -2
- package/src/themes/timeline.theme.ts +7 -2
- package/src/themes/toast.theme.ts +1 -1
- package/src/types/components/accordion.ts +35 -2
- package/src/types/components/avatar.ts +16 -0
- package/src/types/components/banner.ts +42 -0
- package/src/types/components/button.ts +3 -4
- package/src/types/components/{alert.ts → callout.ts} +6 -6
- package/src/types/components/color-area.ts +19 -0
- package/src/types/components/color-field.ts +21 -0
- package/src/types/components/color-slider.ts +20 -0
- package/src/types/components/grid.ts +23 -0
- package/src/types/components/input.ts +4 -0
- package/src/types/components/layout-grid.ts +145 -0
- package/src/types/components/link-group.ts +4 -2
- package/src/types/components/link.ts +15 -0
- package/src/types/components/logo.ts +3 -3
- package/src/types/components/post.ts +12 -0
- package/src/types/components/search.ts +29 -0
- package/src/types/components/sidebar.ts +2 -6
- package/src/types/components/{megamenu.ts → steps.ts} +7 -1
- package/src/types/components/table-of-contents.ts +22 -0
- package/src/types/components/toast.ts +4 -0
- package/src/types/docs.ts +40 -0
- package/src/types/index.ts +151 -1
- package/src/types/theme.ts +6 -6
- package/src/utils/color.ts +165 -0
- package/src/utils/docs.ts +260 -110
- package/src/utils/headerStack.ts +24 -4
- package/src/utils/index.ts +2 -0
- package/src/utils/shortcuts.ts +322 -0
- package/src/components/TableOfContents.astro +0 -107
- package/src/components/astro/RLAAlert.astro +0 -93
- package/src/components/astro/RLAChangelog.astro +0 -23
- package/src/components/astro/RLAMegamenu.astro +0 -23
- package/src/plugins/index.ts +0 -2
- package/src/plugins/starlightDocsApi/components/ApiTheme.astro +0 -27
- package/src/plugins/starlightDocsApi/index.ts +0 -272
- package/src/styles/prism.css +0 -42
- package/src/themes/changelog.theme.ts +0 -13
- package/src/types/components/index.ts +0 -134
- /package/src/{plugins/starlightDocsApi → docs}/types.ts +0 -0
|
@@ -0,0 +1,322 @@
|
|
|
1
|
+
import { atom } from "nanostores"
|
|
2
|
+
|
|
3
|
+
export type Handler = (e: KeyboardEvent) => void
|
|
4
|
+
|
|
5
|
+
export interface ShortcutConfig {
|
|
6
|
+
handler: Handler
|
|
7
|
+
usingInput?: boolean | string
|
|
8
|
+
label?: string
|
|
9
|
+
description?: string
|
|
10
|
+
category?: string
|
|
11
|
+
order?: number
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export interface ShortcutsConfig {
|
|
15
|
+
[key: string]: ShortcutConfig | Handler | false | null | undefined
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export interface ShortcutsOptions {
|
|
19
|
+
chainDelay?: number
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
interface Shortcut {
|
|
23
|
+
key: string
|
|
24
|
+
handler: Handler
|
|
25
|
+
chained: boolean
|
|
26
|
+
ctrlKey: boolean
|
|
27
|
+
metaKey: boolean
|
|
28
|
+
shiftKey: boolean
|
|
29
|
+
altKey: boolean
|
|
30
|
+
usingInput?: boolean | string
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export interface RegisteredShortcut {
|
|
34
|
+
id: string
|
|
35
|
+
keys: string[]
|
|
36
|
+
label?: string
|
|
37
|
+
description?: string
|
|
38
|
+
category?: string
|
|
39
|
+
order?: number
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// OS detection
|
|
43
|
+
const macOS =
|
|
44
|
+
typeof window !== "undefined" &&
|
|
45
|
+
typeof navigator !== "undefined" &&
|
|
46
|
+
/Macintosh;/.test(navigator.userAgent)
|
|
47
|
+
|
|
48
|
+
// Modifiers map for human-readable display
|
|
49
|
+
const kbdKeysMap: Record<string, string> = {
|
|
50
|
+
meta: macOS ? "⌘" : "Ctrl",
|
|
51
|
+
command: macOS ? "⌘" : "Ctrl",
|
|
52
|
+
ctrl: macOS ? "Ctrl" : "Ctrl",
|
|
53
|
+
control: macOS ? "Ctrl" : "Ctrl",
|
|
54
|
+
alt: macOS ? "⌥" : "Alt",
|
|
55
|
+
option: macOS ? "⌥" : "Alt",
|
|
56
|
+
shift: macOS ? "⇧" : "Shift",
|
|
57
|
+
enter: "↵",
|
|
58
|
+
delete: "⌦",
|
|
59
|
+
backspace: "⌫",
|
|
60
|
+
escape: "Esc",
|
|
61
|
+
tab: "⇥",
|
|
62
|
+
space: "Space",
|
|
63
|
+
arrowup: "↑",
|
|
64
|
+
arrowdown: "↓",
|
|
65
|
+
arrowleft: "←",
|
|
66
|
+
arrowright: "→"
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
// Convert a combination string (e.g. meta_alt_t) into platform-specific readable key symbol arrays
|
|
70
|
+
export function formatShortcutKeys(keyStr: string): string[] {
|
|
71
|
+
const separator = keyStr.includes("-") ? "-" : "_"
|
|
72
|
+
const parts = keyStr.split(separator)
|
|
73
|
+
return parts.map((part) => {
|
|
74
|
+
const lower = part.toLowerCase()
|
|
75
|
+
if (kbdKeysMap[lower] !== undefined) {
|
|
76
|
+
return kbdKeysMap[lower]
|
|
77
|
+
}
|
|
78
|
+
if (lower.length === 1) {
|
|
79
|
+
return lower.toUpperCase()
|
|
80
|
+
}
|
|
81
|
+
return part.charAt(0).toUpperCase() + part.slice(1)
|
|
82
|
+
})
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
// Reactive store containing all currently registered shortcuts on the page
|
|
86
|
+
export const activeShortcutsStore = atom<RegisteredShortcut[]>([])
|
|
87
|
+
|
|
88
|
+
// Simple key to code conversion for layout/translation independence under Alt
|
|
89
|
+
function convertKeyToCode(key: string): string {
|
|
90
|
+
if (/^[a-z]$/i.test(key)) {
|
|
91
|
+
return `Key${key.toUpperCase()}`
|
|
92
|
+
}
|
|
93
|
+
if (/^\d$/.test(key)) {
|
|
94
|
+
return `Digit${key}`
|
|
95
|
+
}
|
|
96
|
+
if (/^f\d+$/i.test(key)) {
|
|
97
|
+
return key.toUpperCase()
|
|
98
|
+
}
|
|
99
|
+
const specialKeys: Record<string, string> = {
|
|
100
|
+
space: "Space",
|
|
101
|
+
enter: "Enter",
|
|
102
|
+
escape: "Escape",
|
|
103
|
+
tab: "Tab",
|
|
104
|
+
backspace: "Backspace",
|
|
105
|
+
delete: "Delete",
|
|
106
|
+
arrowup: "ArrowUp",
|
|
107
|
+
arrowdown: "ArrowDown",
|
|
108
|
+
arrowleft: "ArrowLeft",
|
|
109
|
+
arrowright: "ArrowRight"
|
|
110
|
+
}
|
|
111
|
+
return specialKeys[key.toLowerCase()] || key
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
// Input tag checking
|
|
115
|
+
function isUsingInput(activeElement: Element | null): boolean | string {
|
|
116
|
+
if (!activeElement) return false
|
|
117
|
+
const tagName = activeElement.tagName
|
|
118
|
+
const contentEditable = activeElement.getAttribute("contenteditable")
|
|
119
|
+
const isInput =
|
|
120
|
+
tagName === "INPUT" ||
|
|
121
|
+
tagName === "TEXTAREA" ||
|
|
122
|
+
contentEditable === "true" ||
|
|
123
|
+
contentEditable === "plaintext-only"
|
|
124
|
+
if (isInput) {
|
|
125
|
+
return activeElement.getAttribute("name") || true
|
|
126
|
+
}
|
|
127
|
+
return false
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
export function defineShortcuts(
|
|
131
|
+
config: ShortcutsConfig,
|
|
132
|
+
options: ShortcutsOptions = {}
|
|
133
|
+
): () => void {
|
|
134
|
+
if (typeof window === "undefined") {
|
|
135
|
+
return () => {}
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
const chainDelay = options.chainDelay ?? 800
|
|
139
|
+
const chainedInputs: string[] = []
|
|
140
|
+
let debounceTimer: any = null
|
|
141
|
+
|
|
142
|
+
const clearChainedInput = () => {
|
|
143
|
+
chainedInputs.length = 0
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
// Pre-parse the shortcuts configuration
|
|
147
|
+
const parsedShortcuts: Shortcut[] = Object.entries(config)
|
|
148
|
+
.map(([key, shortcutConfig]) => {
|
|
149
|
+
if (!shortcutConfig) return null
|
|
150
|
+
|
|
151
|
+
let handler: Handler
|
|
152
|
+
let usingInput: boolean | string = false
|
|
153
|
+
|
|
154
|
+
if (typeof shortcutConfig === "function") {
|
|
155
|
+
handler = shortcutConfig
|
|
156
|
+
} else {
|
|
157
|
+
handler = shortcutConfig.handler
|
|
158
|
+
usingInput = shortcutConfig.usingInput ?? false
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
if (!handler) return null
|
|
162
|
+
|
|
163
|
+
const chained = key.includes("-") && key !== "-" && !key.includes("_")
|
|
164
|
+
let baseKey = ""
|
|
165
|
+
let ctrlKey = false
|
|
166
|
+
let metaKey = false
|
|
167
|
+
let shiftKey = false
|
|
168
|
+
let altKey = false
|
|
169
|
+
|
|
170
|
+
if (chained) {
|
|
171
|
+
baseKey = key.toLowerCase()
|
|
172
|
+
} else {
|
|
173
|
+
const parts = key.toLowerCase().split("_")
|
|
174
|
+
baseKey = parts
|
|
175
|
+
.filter((p) => !["meta", "command", "ctrl", "shift", "alt", "option"].includes(p))
|
|
176
|
+
.join("_")
|
|
177
|
+
ctrlKey = parts.includes("ctrl")
|
|
178
|
+
metaKey = parts.includes("meta") || parts.includes("command")
|
|
179
|
+
shiftKey = parts.includes("shift")
|
|
180
|
+
altKey = parts.includes("alt") || parts.includes("option")
|
|
181
|
+
|
|
182
|
+
// Normalize Cmd/Ctrl for non-macOS
|
|
183
|
+
if (!macOS && metaKey && !ctrlKey) {
|
|
184
|
+
metaKey = false
|
|
185
|
+
ctrlKey = true
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
return {
|
|
190
|
+
key: baseKey,
|
|
191
|
+
handler,
|
|
192
|
+
chained,
|
|
193
|
+
ctrlKey,
|
|
194
|
+
metaKey,
|
|
195
|
+
shiftKey,
|
|
196
|
+
altKey,
|
|
197
|
+
usingInput
|
|
198
|
+
} as Shortcut
|
|
199
|
+
})
|
|
200
|
+
.filter((item): item is Shortcut => item != null)
|
|
201
|
+
|
|
202
|
+
// Register documented shortcuts to the store
|
|
203
|
+
const itemsToRegister: RegisteredShortcut[] = Object.entries(config).flatMap(
|
|
204
|
+
([key, shortcutConfig]) => {
|
|
205
|
+
if (!shortcutConfig || typeof shortcutConfig !== "object") return []
|
|
206
|
+
|
|
207
|
+
const { label, description, category, order } = shortcutConfig
|
|
208
|
+
if (!label && !description) return [] // only register documented shortcuts
|
|
209
|
+
|
|
210
|
+
const item: RegisteredShortcut = {
|
|
211
|
+
id: `${key}-${Math.random().toString(36).slice(2, 7)}`,
|
|
212
|
+
keys: formatShortcutKeys(key),
|
|
213
|
+
category: category || "system"
|
|
214
|
+
}
|
|
215
|
+
if (label) item.label = label
|
|
216
|
+
if (description) item.description = description
|
|
217
|
+
if (order !== undefined) item.order = order
|
|
218
|
+
return [item]
|
|
219
|
+
}
|
|
220
|
+
)
|
|
221
|
+
|
|
222
|
+
if (itemsToRegister.length > 0) {
|
|
223
|
+
activeShortcutsStore.set([...activeShortcutsStore.get(), ...itemsToRegister])
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
const onKeyDown = (e: KeyboardEvent) => {
|
|
227
|
+
if (!e.key) return
|
|
228
|
+
|
|
229
|
+
const activeEl = document.activeElement
|
|
230
|
+
const currentlyUsingInput = isUsingInput(activeEl)
|
|
231
|
+
|
|
232
|
+
// Helper to check if a shortcut is enabled given current focus state
|
|
233
|
+
const isShortcutEnabled = (shortcut: Shortcut) => {
|
|
234
|
+
if (!shortcut.usingInput) {
|
|
235
|
+
return !currentlyUsingInput
|
|
236
|
+
}
|
|
237
|
+
if (typeof shortcut.usingInput === "string") {
|
|
238
|
+
return currentlyUsingInput === shortcut.usingInput
|
|
239
|
+
}
|
|
240
|
+
return true
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
// Handle chained shortcuts
|
|
244
|
+
chainedInputs.push(e.key.toLowerCase())
|
|
245
|
+
clearTimeout(debounceTimer)
|
|
246
|
+
|
|
247
|
+
if (chainedInputs.length >= 2) {
|
|
248
|
+
const chainedKey = chainedInputs.slice(-2).join("-")
|
|
249
|
+
const matchedChained = parsedShortcuts.find((s) => s.chained && s.key === chainedKey)
|
|
250
|
+
if (matchedChained && isShortcutEnabled(matchedChained)) {
|
|
251
|
+
e.preventDefault()
|
|
252
|
+
matchedChained.handler(e)
|
|
253
|
+
clearChainedInput()
|
|
254
|
+
return
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
// Handle standard shortcuts
|
|
259
|
+
for (const shortcut of parsedShortcuts) {
|
|
260
|
+
if (shortcut.chained) continue
|
|
261
|
+
|
|
262
|
+
if (e.ctrlKey !== shortcut.ctrlKey) continue
|
|
263
|
+
if (e.metaKey !== shortcut.metaKey) continue
|
|
264
|
+
if (e.altKey !== shortcut.altKey) continue
|
|
265
|
+
|
|
266
|
+
// Match by code when Alt modifier is active to avoid key translation issues
|
|
267
|
+
const useCode = shortcut.altKey && e.altKey
|
|
268
|
+
if (useCode) {
|
|
269
|
+
if (e.code !== convertKeyToCode(shortcut.key)) continue
|
|
270
|
+
} else {
|
|
271
|
+
const pressedKey = e.key.toLowerCase()
|
|
272
|
+
if (pressedKey !== shortcut.key) continue
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
// Shift modifier check:
|
|
276
|
+
// If the shortcut explicitly specifies shiftKey: true, then e.shiftKey must be true.
|
|
277
|
+
// If the shortcut does NOT specify shiftKey: true, but e.shiftKey is true:
|
|
278
|
+
// - If the base key is a letter (e.g. 'k'), then we do NOT match (because it's Shift+K, not K).
|
|
279
|
+
// - If the base key is a shiftable control key (like 'arrowleft'), we do NOT match.
|
|
280
|
+
// - For other keys (like '?', '/', etc.), we allow it to match even if e.shiftKey is true.
|
|
281
|
+
const alphabetKey = /^[a-z]$/i.test(shortcut.key)
|
|
282
|
+
const shiftableKeys = [
|
|
283
|
+
"arrowleft",
|
|
284
|
+
"arrowright",
|
|
285
|
+
"arrowup",
|
|
286
|
+
"arrowdown",
|
|
287
|
+
"tab",
|
|
288
|
+
"escape",
|
|
289
|
+
"enter",
|
|
290
|
+
"backspace"
|
|
291
|
+
]
|
|
292
|
+
const shiftableKey = shiftableKeys.includes(shortcut.key)
|
|
293
|
+
|
|
294
|
+
if (shortcut.shiftKey && !e.shiftKey) continue
|
|
295
|
+
if (!shortcut.shiftKey && e.shiftKey && (alphabetKey || shiftableKey)) continue
|
|
296
|
+
|
|
297
|
+
if (isShortcutEnabled(shortcut)) {
|
|
298
|
+
e.preventDefault()
|
|
299
|
+
shortcut.handler(e)
|
|
300
|
+
clearChainedInput()
|
|
301
|
+
return
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
debounceTimer = setTimeout(clearChainedInput, chainDelay)
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
window.addEventListener("keydown", onKeyDown)
|
|
309
|
+
|
|
310
|
+
return () => {
|
|
311
|
+
window.removeEventListener("keydown", onKeyDown)
|
|
312
|
+
clearTimeout(debounceTimer)
|
|
313
|
+
|
|
314
|
+
// Unregister items from the active store
|
|
315
|
+
if (itemsToRegister.length > 0) {
|
|
316
|
+
const idsToRemove = new Set(itemsToRegister.map((item) => item.id))
|
|
317
|
+
activeShortcutsStore.set(
|
|
318
|
+
activeShortcutsStore.get().filter((item) => !idsToRemove.has(item.id))
|
|
319
|
+
)
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
}
|
|
@@ -1,107 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
export interface TableOfContentsHeading {
|
|
3
|
-
depth: number;
|
|
4
|
-
slug: string;
|
|
5
|
-
text: string;
|
|
6
|
-
}
|
|
7
|
-
|
|
8
|
-
export interface TableOfContentsConfig {
|
|
9
|
-
minHeadingLevel?: number;
|
|
10
|
-
maxHeadingLevel?: number;
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
export interface TableOfContentsProps {
|
|
14
|
-
headings: TableOfContentsHeading[];
|
|
15
|
-
/** false = hide entirely, object = heading level bounds */
|
|
16
|
-
tableOfContents?: false | TableOfContentsConfig;
|
|
17
|
-
/** @deprecated use tableOfContents.maxHeadingLevel instead */
|
|
18
|
-
levels?: 1 | 2 | 3;
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
type Props = TableOfContentsProps;
|
|
22
|
-
|
|
23
|
-
const { headings, tableOfContents, levels = 2 } = Astro.props as Props;
|
|
24
|
-
|
|
25
|
-
if (tableOfContents === false) {
|
|
26
|
-
// Render nothing — parent should also skip rendering this component,
|
|
27
|
-
// but guard here as a safety net.
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
const minLevel = (tableOfContents !== false && tableOfContents?.minHeadingLevel) ?? 2;
|
|
31
|
-
const maxLevel = (tableOfContents !== false && tableOfContents?.maxHeadingLevel) ?? levels;
|
|
32
|
-
|
|
33
|
-
const filteredHeadings = tableOfContents !== false
|
|
34
|
-
? headings.filter(h => h.depth >= minLevel && h.depth <= maxLevel)
|
|
35
|
-
: [];
|
|
36
|
-
---
|
|
37
|
-
|
|
38
|
-
{tableOfContents !== false && filteredHeadings.length > 0 && (
|
|
39
|
-
<div class="border-border rounded-xs border p-3xs text-sm leading-tight">
|
|
40
|
-
<h4 class="text-xl font-medium">On this page</h4>
|
|
41
|
-
<ul class="mt-2xl flex flex-col gap-3xs">
|
|
42
|
-
{filteredHeadings.map(heading => (
|
|
43
|
-
<li
|
|
44
|
-
class:list={{
|
|
45
|
-
"pl-3xs": heading.depth === 2,
|
|
46
|
-
"pl-6": heading.depth === 3,
|
|
47
|
-
"pl-9": heading.depth >= 4
|
|
48
|
-
}}
|
|
49
|
-
>
|
|
50
|
-
<a
|
|
51
|
-
href={`#${heading.slug}`}
|
|
52
|
-
class="toc-link transition hover:text-primary-accent"
|
|
53
|
-
>
|
|
54
|
-
{heading.text}
|
|
55
|
-
</a>
|
|
56
|
-
</li>
|
|
57
|
-
))}
|
|
58
|
-
</ul>
|
|
59
|
-
</div>
|
|
60
|
-
)}
|
|
61
|
-
|
|
62
|
-
<style>
|
|
63
|
-
.toc-current {
|
|
64
|
-
color: var(--primary);
|
|
65
|
-
font-weight: 500;
|
|
66
|
-
}
|
|
67
|
-
</style>
|
|
68
|
-
|
|
69
|
-
<script>
|
|
70
|
-
let wrappingElement: Element | null;
|
|
71
|
-
let observeHeaderTags: IntersectionObserver;
|
|
72
|
-
let allHeaderTags: NodeListOf<Element>;
|
|
73
|
-
|
|
74
|
-
function setCurrent(e: IntersectionObserverEntry[]) {
|
|
75
|
-
const allSectionLinks = document.querySelectorAll(".toc-link");
|
|
76
|
-
e.map(i => {
|
|
77
|
-
if (i.isIntersecting === true) {
|
|
78
|
-
allSectionLinks.forEach(link => link.classList.remove("toc-current"));
|
|
79
|
-
const targetLink = document.querySelector(`a[href="#${i.target.id}"].toc-link`);
|
|
80
|
-
if (targetLink) targetLink.classList.add("toc-current");
|
|
81
|
-
}
|
|
82
|
-
});
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
function initTOC() {
|
|
86
|
-
wrappingElement = document.querySelector(".markdown-content");
|
|
87
|
-
if (wrappingElement !== null) {
|
|
88
|
-
allHeaderTags = wrappingElement.querySelectorAll(":scope > h1, :scope > h2, :scope > h3, :scope > h4");
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
const options: IntersectionObserverInit = {
|
|
92
|
-
root: null,
|
|
93
|
-
rootMargin: "0px 0px -50% 0px",
|
|
94
|
-
threshold: [1]
|
|
95
|
-
};
|
|
96
|
-
|
|
97
|
-
observeHeaderTags = new IntersectionObserver(setCurrent, options);
|
|
98
|
-
if (wrappingElement === null) return;
|
|
99
|
-
allHeaderTags.forEach(tag => {
|
|
100
|
-
tag.classList.add("scroll-mt-3xl");
|
|
101
|
-
observeHeaderTags.observe(tag);
|
|
102
|
-
});
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
initTOC();
|
|
106
|
-
document.addEventListener("astro:after-swap", initTOC);
|
|
107
|
-
</script>
|
|
@@ -1,93 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
import { scv, cx } from "css-variants"
|
|
3
|
-
import { useUi, resolveClasses } from "../../utils"
|
|
4
|
-
import type { AlertProps } from "../../types"
|
|
5
|
-
import alertThemeDefault, { createAlertTheme } from "../../themes/alert.theme"
|
|
6
|
-
import { getUIConfig } from "virtual:rimelight-ui"
|
|
7
|
-
import RLAAvatar from "./RLAAvatar.astro"
|
|
8
|
-
|
|
9
|
-
const uiConfig = getUIConfig()
|
|
10
|
-
const alertTheme = uiConfig.colors ? createAlertTheme(uiConfig.colors) : alertThemeDefault
|
|
11
|
-
const alert = scv(alertTheme)
|
|
12
|
-
|
|
13
|
-
const {
|
|
14
|
-
variant = "solid",
|
|
15
|
-
color = "primary",
|
|
16
|
-
title,
|
|
17
|
-
description,
|
|
18
|
-
icon,
|
|
19
|
-
avatar,
|
|
20
|
-
actions,
|
|
21
|
-
close,
|
|
22
|
-
orientation = "horizontal",
|
|
23
|
-
theme,
|
|
24
|
-
ui: uiProp,
|
|
25
|
-
class: className,
|
|
26
|
-
...rest
|
|
27
|
-
} = Astro.props as AlertProps
|
|
28
|
-
|
|
29
|
-
const isIcon = !!(icon || Astro.slots.has("icon"))
|
|
30
|
-
|
|
31
|
-
const classes = resolveClasses(alert, {
|
|
32
|
-
variant,
|
|
33
|
-
color,
|
|
34
|
-
orientation,
|
|
35
|
-
title: !!(title || Astro.slots.has("title")),
|
|
36
|
-
theme
|
|
37
|
-
}, useUi("alert", uiProp), className)
|
|
38
|
-
---
|
|
39
|
-
<div
|
|
40
|
-
class={classes.root}
|
|
41
|
-
data-slot="root"
|
|
42
|
-
role="alert"
|
|
43
|
-
{...rest}
|
|
44
|
-
>
|
|
45
|
-
<slot name="icon">
|
|
46
|
-
{icon && (
|
|
47
|
-
<span class={classes.icon} data-slot="icon">
|
|
48
|
-
<span class={cx(icon)} aria-hidden="true" />
|
|
49
|
-
</span>
|
|
50
|
-
)}
|
|
51
|
-
</slot>
|
|
52
|
-
|
|
53
|
-
<slot name="avatar" {...{ ui: classes }}>
|
|
54
|
-
{avatar && (
|
|
55
|
-
<RLAAvatar
|
|
56
|
-
{...(typeof avatar === 'string' ? { src: avatar } : avatar)}
|
|
57
|
-
size={classes.avatarSize as any}
|
|
58
|
-
class={classes.avatar}
|
|
59
|
-
data-slot="avatar"
|
|
60
|
-
/>
|
|
61
|
-
)}
|
|
62
|
-
</slot>
|
|
63
|
-
|
|
64
|
-
<div class={classes.wrapper} data-slot="wrapper">
|
|
65
|
-
{(title || Astro.slots.has("title")) && (
|
|
66
|
-
<h5 class={classes.title} data-slot="title">
|
|
67
|
-
{title}
|
|
68
|
-
<slot name="title" />
|
|
69
|
-
</h5>
|
|
70
|
-
)}
|
|
71
|
-
|
|
72
|
-
{(description || Astro.slots.has("default")) && (
|
|
73
|
-
<div class={classes.description} data-slot="description">
|
|
74
|
-
{description}
|
|
75
|
-
<slot />
|
|
76
|
-
</div>
|
|
77
|
-
)}
|
|
78
|
-
|
|
79
|
-
{(actions || Astro.slots.has("actions")) && (
|
|
80
|
-
<div class={classes.actions} data-slot="actions">
|
|
81
|
-
<slot name="actions" />
|
|
82
|
-
</div>
|
|
83
|
-
)}
|
|
84
|
-
</div>
|
|
85
|
-
|
|
86
|
-
<slot name="close" {...{ ui: classes }}>
|
|
87
|
-
{close && (
|
|
88
|
-
<button class={classes.close} data-slot="close">
|
|
89
|
-
<span class="i-lucide-x size-4" />
|
|
90
|
-
</button>
|
|
91
|
-
)}
|
|
92
|
-
</slot>
|
|
93
|
-
</div>
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
import { scv } from "css-variants"
|
|
3
|
-
import { useUi, resolveClasses } from "../../utils"
|
|
4
|
-
import type { ChangelogProps } from "../../types"
|
|
5
|
-
import changelogThemeDefault, { createChangelogTheme } from "../../themes/changelog.theme"
|
|
6
|
-
import { getUIConfig } from "virtual:rimelight-ui"
|
|
7
|
-
|
|
8
|
-
const uiConfig = getUIConfig()
|
|
9
|
-
const changelogTheme = uiConfig.colors ? createChangelogTheme() : changelogThemeDefault
|
|
10
|
-
|
|
11
|
-
const changelog = scv(changelogTheme)
|
|
12
|
-
|
|
13
|
-
const {
|
|
14
|
-
ui: uiProp,
|
|
15
|
-
class: className,
|
|
16
|
-
...rest
|
|
17
|
-
} = Astro.props as ChangelogProps
|
|
18
|
-
|
|
19
|
-
const classes = resolveClasses(changelog, {}, useUi("changelog", uiProp), className);
|
|
20
|
-
---
|
|
21
|
-
<div class={classes.root} data-slot="root" {...rest}>
|
|
22
|
-
<slot />
|
|
23
|
-
</div>
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
import { scv } from "css-variants"
|
|
3
|
-
import { useUi, resolveClasses } from "../../utils"
|
|
4
|
-
import type { MegamenuProps } from "../../types"
|
|
5
|
-
import megamenuThemeDefault, { createMegamenuTheme } from "../../themes/megamenu.theme"
|
|
6
|
-
import { getUIConfig } from "virtual:rimelight-ui"
|
|
7
|
-
|
|
8
|
-
const uiConfig = getUIConfig()
|
|
9
|
-
const megamenuTheme = uiConfig.colors ? createMegamenuTheme() : megamenuThemeDefault
|
|
10
|
-
|
|
11
|
-
const megamenu = scv(megamenuTheme)
|
|
12
|
-
|
|
13
|
-
const {
|
|
14
|
-
ui: uiProp,
|
|
15
|
-
class: className,
|
|
16
|
-
...rest
|
|
17
|
-
} = Astro.props as MegamenuProps
|
|
18
|
-
|
|
19
|
-
const classes = resolveClasses(megamenu, {}, useUi("megamenu", uiProp), className);
|
|
20
|
-
---
|
|
21
|
-
<div class={classes.root} data-slot="root" {...rest}>
|
|
22
|
-
<slot />
|
|
23
|
-
</div>
|
package/src/plugins/index.ts
DELETED
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
import type { ComponentMetaMap } from "../types"
|
|
3
|
-
import { generateThemeCode } from "../utils"
|
|
4
|
-
import meta from "virtual:rimelight-ui-docs-meta"
|
|
5
|
-
|
|
6
|
-
interface Props {
|
|
7
|
-
component: string
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
const { component } = Astro.props
|
|
11
|
-
|
|
12
|
-
const allMeta = meta as unknown as ComponentMetaMap
|
|
13
|
-
const compMeta = allMeta[component]
|
|
14
|
-
|
|
15
|
-
const theme = compMeta?.theme ?? null
|
|
16
|
-
const themeCode = theme ? generateThemeCode(component, theme) : null
|
|
17
|
-
---
|
|
18
|
-
|
|
19
|
-
{themeCode ? (
|
|
20
|
-
<div class="expressive-code">
|
|
21
|
-
<figure class="frame">
|
|
22
|
-
<pre class="language-ts overflow-x-auto"><code class="language-ts">{themeCode}</code></pre>
|
|
23
|
-
</figure>
|
|
24
|
-
</div>
|
|
25
|
-
) : (
|
|
26
|
-
<p class="text-sm italic text-gray-500">No theme data available.</p>
|
|
27
|
-
)}
|