@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
|
@@ -7,16 +7,38 @@ const {
|
|
|
7
7
|
href,
|
|
8
8
|
variant = "link",
|
|
9
9
|
color = "neutral",
|
|
10
|
+
external,
|
|
11
|
+
isButton = false,
|
|
12
|
+
ariaLabel,
|
|
13
|
+
externalIcon,
|
|
14
|
+
target,
|
|
15
|
+
rel,
|
|
16
|
+
trailingIcon,
|
|
10
17
|
...rest
|
|
11
18
|
} = Astro.props as LinkProps
|
|
12
19
|
|
|
13
20
|
const linkHref = href || (typeof to === 'string' ? to : undefined);
|
|
21
|
+
|
|
22
|
+
const isExternal = !!(external || (linkHref && (linkHref.startsWith('http://') || linkHref.startsWith('https://') || linkHref.startsWith('//'))));
|
|
23
|
+
|
|
24
|
+
const linkVariant = isButton && variant === "link" ? "solid" : variant;
|
|
25
|
+
const linkTarget = target || (isExternal ? "_blank" : undefined);
|
|
26
|
+
const linkRel = rel || (isExternal ? "noopener noreferrer" : undefined);
|
|
27
|
+
|
|
28
|
+
const showExternalIcon = isExternal && !trailingIcon ? (externalIcon || "i-lucide-external-link") : trailingIcon;
|
|
14
29
|
---
|
|
15
30
|
<RLAButton
|
|
16
|
-
variant={
|
|
31
|
+
variant={linkVariant as any}
|
|
17
32
|
color={color as any}
|
|
18
33
|
href={linkHref}
|
|
34
|
+
target={linkTarget}
|
|
35
|
+
rel={linkRel}
|
|
36
|
+
aria-label={ariaLabel}
|
|
37
|
+
trailingIcon={showExternalIcon}
|
|
19
38
|
{...rest}
|
|
20
39
|
>
|
|
21
40
|
<slot />
|
|
41
|
+
{isExternal && !ariaLabel && (
|
|
42
|
+
<span class="sr-only"> (opens in a new tab)</span>
|
|
43
|
+
)}
|
|
22
44
|
</RLAButton>
|
|
@@ -1,100 +1,100 @@
|
|
|
1
|
-
---
|
|
2
|
-
import { scv } from "css-variants"
|
|
3
|
-
import { useUi, resolveClasses } from "../../utils"
|
|
4
|
-
import type { LinkGroupProps } from "../../types"
|
|
5
|
-
import linkGroupThemeDefault, { createLinkGroupTheme } from "../../themes/link-group.theme"
|
|
6
|
-
import { getUIConfig } from "virtual:rimelight-ui"
|
|
7
|
-
|
|
8
|
-
import RLALink from "./RLALink.astro"
|
|
9
|
-
|
|
10
|
-
const uiConfig = getUIConfig()
|
|
11
|
-
const linkGroupTheme = uiConfig.colors ? createLinkGroupTheme() : linkGroupThemeDefault
|
|
12
|
-
|
|
13
|
-
const linkGroup = scv(linkGroupTheme)
|
|
14
|
-
|
|
15
|
-
const {
|
|
16
|
-
title,
|
|
17
|
-
label,
|
|
18
|
-
leadingIcon,
|
|
19
|
-
trailingIcon,
|
|
20
|
-
href,
|
|
21
|
-
to,
|
|
22
|
-
links = [],
|
|
23
|
-
theme,
|
|
24
|
-
ui: uiProp,
|
|
25
|
-
class: className,
|
|
26
|
-
...rest
|
|
27
|
-
} = Astro.props as LinkGroupProps
|
|
28
|
-
|
|
29
|
-
const classes = resolveClasses(linkGroup, { theme }, useUi("linkGroup", uiProp), className);
|
|
30
|
-
|
|
31
|
-
const headingLabel = label || (typeof title === "object" ? title.label : (typeof title === "string" ? title : undefined));
|
|
32
|
-
const headingLeadingIcon = leadingIcon || (typeof title === "object" ? title.leadingIcon : undefined);
|
|
33
|
-
const headingTrailingIcon = trailingIcon || (typeof title === "object" ? title.trailingIcon : undefined);
|
|
34
|
-
const headingHref = href || (typeof title === "object" ? title.href : undefined);
|
|
35
|
-
const headingTo = to || (typeof title === "object" ? (title as any).to : undefined);
|
|
36
|
-
|
|
37
|
-
const linksProp = links ?? [];
|
|
38
|
-
const normalizedLinks = Array.isArray(linksProp) ? linksProp : [linksProp];
|
|
39
|
-
|
|
40
|
-
// Prefix utility classes in classes.link with `!` to cleanly override conflicting text colors in RLAButton's base classes.
|
|
41
|
-
// For default or light themes, do not force base text classes so RLAButton's own light/dark mode styles can adapt naturally.
|
|
42
|
-
const isPinnedDark = theme === "
|
|
43
|
-
const overrideLinkClass = classes.link
|
|
44
|
-
? classes.link
|
|
45
|
-
.split(" ")
|
|
46
|
-
.map(cls => {
|
|
47
|
-
if (!cls) return "";
|
|
48
|
-
if (cls.includes(":")) {
|
|
49
|
-
const parts = cls.split(":");
|
|
50
|
-
const state = parts.slice(0, -1).join(":");
|
|
51
|
-
const baseCls = parts[parts.length - 1];
|
|
52
|
-
return `${state}:!${baseCls}`;
|
|
53
|
-
}
|
|
54
|
-
if (cls.startsWith("text-") && !isPinnedDark) {
|
|
55
|
-
return cls;
|
|
56
|
-
}
|
|
57
|
-
return `!${cls}`;
|
|
58
|
-
})
|
|
59
|
-
.filter(Boolean)
|
|
60
|
-
.join(" ")
|
|
61
|
-
: "";
|
|
62
|
-
---
|
|
63
|
-
<div class={classes.root} data-slot="root" {...rest}>
|
|
64
|
-
{headingLabel && (
|
|
65
|
-
<h4 class={classes.title} data-slot="title">
|
|
66
|
-
{headingHref || headingTo ? (
|
|
67
|
-
<a href={headingHref || (typeof headingTo === 'string' ? headingTo : undefined)} class="hover:underline flex items-center gap-1.5">
|
|
68
|
-
{headingLeadingIcon && <span class={headingLeadingIcon} />}
|
|
69
|
-
<span>{headingLabel}</span>
|
|
70
|
-
{headingTrailingIcon && <span class={headingTrailingIcon} />}
|
|
71
|
-
</a>
|
|
72
|
-
) : (
|
|
73
|
-
<span class="flex items-center gap-1.5">
|
|
74
|
-
{headingLeadingIcon && <span class={headingLeadingIcon} />}
|
|
75
|
-
<span>{headingLabel}</span>
|
|
76
|
-
{headingTrailingIcon && <span class={headingTrailingIcon} />}
|
|
77
|
-
</span>
|
|
78
|
-
)}
|
|
79
|
-
</h4>
|
|
80
|
-
)}
|
|
81
|
-
|
|
82
|
-
<ul class={classes.list} data-slot="list">
|
|
83
|
-
<slot>
|
|
84
|
-
{normalizedLinks.map((link) => (
|
|
85
|
-
<li class={classes.item} data-slot="item">
|
|
86
|
-
<RLALink
|
|
87
|
-
variant={link.variant ?? "ghost"}
|
|
88
|
-
color={link.color ?? "neutral"}
|
|
89
|
-
theme={link.theme ?? theme}
|
|
90
|
-
class:list={[overrideLinkClass, "w-full !justify-start"]}
|
|
91
|
-
data-slot="link"
|
|
92
|
-
{...link}
|
|
93
|
-
>
|
|
94
|
-
{link.label}
|
|
95
|
-
</RLALink>
|
|
96
|
-
</li>
|
|
97
|
-
))}
|
|
98
|
-
</slot>
|
|
99
|
-
</ul>
|
|
1
|
+
---
|
|
2
|
+
import { scv } from "css-variants"
|
|
3
|
+
import { useUi, resolveClasses } from "../../utils"
|
|
4
|
+
import type { LinkGroupProps } from "../../types"
|
|
5
|
+
import linkGroupThemeDefault, { createLinkGroupTheme } from "../../themes/link-group.theme"
|
|
6
|
+
import { getUIConfig } from "virtual:rimelight-ui"
|
|
7
|
+
|
|
8
|
+
import RLALink from "./RLALink.astro"
|
|
9
|
+
|
|
10
|
+
const uiConfig = getUIConfig()
|
|
11
|
+
const linkGroupTheme = uiConfig.colors ? createLinkGroupTheme() : linkGroupThemeDefault
|
|
12
|
+
|
|
13
|
+
const linkGroup = scv(linkGroupTheme)
|
|
14
|
+
|
|
15
|
+
const {
|
|
16
|
+
title,
|
|
17
|
+
label,
|
|
18
|
+
leadingIcon,
|
|
19
|
+
trailingIcon,
|
|
20
|
+
href,
|
|
21
|
+
to,
|
|
22
|
+
links = [],
|
|
23
|
+
theme,
|
|
24
|
+
ui: uiProp,
|
|
25
|
+
class: className,
|
|
26
|
+
...rest
|
|
27
|
+
} = Astro.props as LinkGroupProps
|
|
28
|
+
|
|
29
|
+
const classes = resolveClasses(linkGroup, { theme }, useUi("linkGroup", uiProp), className);
|
|
30
|
+
|
|
31
|
+
const headingLabel = label || (typeof title === "object" ? title.label : (typeof title === "string" ? title : undefined));
|
|
32
|
+
const headingLeadingIcon = leadingIcon || (typeof title === "object" ? title.leadingIcon : undefined);
|
|
33
|
+
const headingTrailingIcon = trailingIcon || (typeof title === "object" ? title.trailingIcon : undefined);
|
|
34
|
+
const headingHref = href || (typeof title === "object" ? title.href : undefined);
|
|
35
|
+
const headingTo = to || (typeof title === "object" ? (title as any).to : undefined);
|
|
36
|
+
|
|
37
|
+
const linksProp = links ?? [];
|
|
38
|
+
const normalizedLinks = Array.isArray(linksProp) ? linksProp : [linksProp];
|
|
39
|
+
|
|
40
|
+
// Prefix utility classes in classes.link with `!` to cleanly override conflicting text colors in RLAButton's base classes.
|
|
41
|
+
// For default or light themes, do not force base text classes so RLAButton's own light/dark mode styles can adapt naturally.
|
|
42
|
+
const isPinnedDark = theme === "dark";
|
|
43
|
+
const overrideLinkClass = classes.link
|
|
44
|
+
? classes.link
|
|
45
|
+
.split(" ")
|
|
46
|
+
.map(cls => {
|
|
47
|
+
if (!cls) return "";
|
|
48
|
+
if (cls.includes(":")) {
|
|
49
|
+
const parts = cls.split(":");
|
|
50
|
+
const state = parts.slice(0, -1).join(":");
|
|
51
|
+
const baseCls = parts[parts.length - 1];
|
|
52
|
+
return `${state}:!${baseCls}`;
|
|
53
|
+
}
|
|
54
|
+
if (cls.startsWith("text-") && !isPinnedDark) {
|
|
55
|
+
return cls;
|
|
56
|
+
}
|
|
57
|
+
return `!${cls}`;
|
|
58
|
+
})
|
|
59
|
+
.filter(Boolean)
|
|
60
|
+
.join(" ")
|
|
61
|
+
: "";
|
|
62
|
+
---
|
|
63
|
+
<div class={classes.root} data-slot="root" {...rest}>
|
|
64
|
+
{headingLabel && (
|
|
65
|
+
<h4 class={classes.title} data-slot="title">
|
|
66
|
+
{headingHref || headingTo ? (
|
|
67
|
+
<a href={headingHref || (typeof headingTo === 'string' ? headingTo : undefined)} class="hover:underline flex items-center gap-1.5">
|
|
68
|
+
{headingLeadingIcon && <span class={headingLeadingIcon} />}
|
|
69
|
+
<span>{headingLabel}</span>
|
|
70
|
+
{headingTrailingIcon && <span class={headingTrailingIcon} />}
|
|
71
|
+
</a>
|
|
72
|
+
) : (
|
|
73
|
+
<span class="flex items-center gap-1.5">
|
|
74
|
+
{headingLeadingIcon && <span class={headingLeadingIcon} />}
|
|
75
|
+
<span>{headingLabel}</span>
|
|
76
|
+
{headingTrailingIcon && <span class={headingTrailingIcon} />}
|
|
77
|
+
</span>
|
|
78
|
+
)}
|
|
79
|
+
</h4>
|
|
80
|
+
)}
|
|
81
|
+
|
|
82
|
+
<ul class={classes.list} data-slot="list">
|
|
83
|
+
<slot>
|
|
84
|
+
{normalizedLinks.map((link) => (
|
|
85
|
+
<li class={classes.item} data-slot="item">
|
|
86
|
+
<RLALink
|
|
87
|
+
variant={link.variant ?? "ghost"}
|
|
88
|
+
color={link.color ?? "neutral"}
|
|
89
|
+
theme={link.theme ?? theme}
|
|
90
|
+
class:list={[overrideLinkClass, "w-full !justify-start"]}
|
|
91
|
+
data-slot="link"
|
|
92
|
+
{...link}
|
|
93
|
+
>
|
|
94
|
+
{link.label}
|
|
95
|
+
</RLALink>
|
|
96
|
+
</li>
|
|
97
|
+
))}
|
|
98
|
+
</slot>
|
|
99
|
+
</ul>
|
|
100
100
|
</div>
|
|
@@ -81,57 +81,50 @@ const overrideTriggerClass = classes.select
|
|
|
81
81
|
|
|
82
82
|
const gapClass = size === "sm" ? "gap-1.5" : size === "lg" ? "gap-3" : "gap-2";
|
|
83
83
|
|
|
84
|
-
const isDefault = variant === "default";
|
|
85
|
-
const triggerDarkModeOverrides = isDefault
|
|
86
|
-
? "dark:!bg-neutral-800 dark:!text-white dark:hover:!bg-neutral-700"
|
|
87
|
-
: "";
|
|
88
|
-
|
|
89
84
|
const selectUi = {
|
|
90
85
|
root: "!w-fit !inline-flex",
|
|
91
|
-
trigger: `flex items-center justify-between !w-fit ${gapClass} ${overrideTriggerClass}
|
|
92
|
-
content: "!min-w-0 !w-full !bg-
|
|
93
|
-
item: "!text-
|
|
86
|
+
trigger: `flex items-center justify-between !w-fit ${gapClass} ${overrideTriggerClass}`,
|
|
87
|
+
content: "!min-w-0 !w-full !bg-[var(--popover)] !border-[var(--border)] !text-[var(--popover-foreground)]",
|
|
88
|
+
item: "!text-[var(--foreground)] hover:!bg-[var(--accent)] hover:!text-[var(--accent-foreground)]"
|
|
94
89
|
};
|
|
95
90
|
---
|
|
96
91
|
|
|
97
|
-
<
|
|
98
|
-
{
|
|
99
|
-
|
|
100
|
-
<
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
<
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
92
|
+
<rla-locale-selector {...rest}>
|
|
93
|
+
<div class:list={[classes.root]} data-locale-selector>
|
|
94
|
+
{Astro.slots.has("label") && (
|
|
95
|
+
<label class:list={[classes.label]}>
|
|
96
|
+
<slot name="label" />
|
|
97
|
+
</label>
|
|
98
|
+
)}
|
|
99
|
+
|
|
100
|
+
<div class:list={[classes.wrapper]}>
|
|
101
|
+
<RLASelect
|
|
102
|
+
items={items}
|
|
103
|
+
value={currentLocaleUrl}
|
|
104
|
+
size={size}
|
|
105
|
+
ui={selectUi}
|
|
106
|
+
/>
|
|
107
|
+
</div>
|
|
111
108
|
</div>
|
|
112
|
-
</
|
|
109
|
+
</rla-locale-selector>
|
|
113
110
|
|
|
114
111
|
<script>
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
if (selector.hasAttribute('data-initialized')) return;
|
|
120
|
-
selector.setAttribute('data-initialized', 'true');
|
|
121
|
-
|
|
122
|
-
const hiddenInput = selector.querySelector('[data-select-hidden-input]') as HTMLInputElement;
|
|
123
|
-
if (!hiddenInput) return;
|
|
124
|
-
|
|
125
|
-
hiddenInput.addEventListener('change', (event) => {
|
|
112
|
+
class RLALocaleSelector extends HTMLElement {
|
|
113
|
+
connectedCallback() {
|
|
114
|
+
this.style.display = 'contents';
|
|
115
|
+
this.addEventListener('change', (event) => {
|
|
126
116
|
const target = event.target as HTMLInputElement;
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
117
|
+
if (target && target.hasAttribute('data-select-hidden-input')) {
|
|
118
|
+
const targetUrl = target.value;
|
|
119
|
+
if (targetUrl) {
|
|
120
|
+
window.location.href = targetUrl;
|
|
121
|
+
}
|
|
130
122
|
}
|
|
131
123
|
});
|
|
132
|
-
}
|
|
133
|
-
}
|
|
124
|
+
}
|
|
125
|
+
}
|
|
134
126
|
|
|
135
|
-
|
|
136
|
-
|
|
127
|
+
if (!customElements.get('rla-locale-selector')) {
|
|
128
|
+
customElements.define('rla-locale-selector', RLALocaleSelector);
|
|
129
|
+
}
|
|
137
130
|
</script>
|
|
@@ -1,90 +1,117 @@
|
|
|
1
|
-
---
|
|
2
|
-
import { scv } from "css-variants"
|
|
3
|
-
import { useUi, resolveClasses } from "../../utils"
|
|
4
|
-
import type { LogoProps } from "../../types"
|
|
5
|
-
import logoThemeDefault, { createLogoTheme } from "../../themes/logo.theme"
|
|
6
|
-
import { getUIConfig } from "virtual:rimelight-ui"
|
|
7
|
-
|
|
8
|
-
const uiConfig = getUIConfig()
|
|
9
|
-
const logoTheme = uiConfig.colors ? createLogoTheme() : logoThemeDefault
|
|
10
|
-
|
|
11
|
-
const logo = scv(logoTheme)
|
|
12
|
-
|
|
13
|
-
const {
|
|
14
|
-
variant = "logomark",
|
|
15
|
-
mode,
|
|
16
|
-
theme,
|
|
17
|
-
href = "/",
|
|
18
|
-
alt,
|
|
19
|
-
ui: uiProp,
|
|
20
|
-
class: className,
|
|
21
|
-
...rest
|
|
22
|
-
} = Astro.props as LogoProps;
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
const
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
)
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
1
|
+
---
|
|
2
|
+
import { scv } from "css-variants"
|
|
3
|
+
import { useUi, resolveClasses } from "../../utils"
|
|
4
|
+
import type { LogoProps } from "../../types"
|
|
5
|
+
import logoThemeDefault, { createLogoTheme } from "../../themes/logo.theme"
|
|
6
|
+
import { getUIConfig } from "virtual:rimelight-ui"
|
|
7
|
+
|
|
8
|
+
const uiConfig = getUIConfig()
|
|
9
|
+
const logoTheme = uiConfig.colors ? createLogoTheme() : logoThemeDefault
|
|
10
|
+
|
|
11
|
+
const logo = scv(logoTheme)
|
|
12
|
+
|
|
13
|
+
const {
|
|
14
|
+
variant = "logomark",
|
|
15
|
+
mode,
|
|
16
|
+
theme,
|
|
17
|
+
href = "/",
|
|
18
|
+
alt,
|
|
19
|
+
ui: uiProp,
|
|
20
|
+
class: className,
|
|
21
|
+
...rest
|
|
22
|
+
} = Astro.props as LogoProps;
|
|
23
|
+
|
|
24
|
+
let resolvedHref = href;
|
|
25
|
+
if (href === "/") {
|
|
26
|
+
try {
|
|
27
|
+
const { getRelativeLocaleUrl } = await import("@rimelight/i18n");
|
|
28
|
+
resolvedHref = Astro.currentLocale
|
|
29
|
+
? getRelativeLocaleUrl(Astro.currentLocale, "/")
|
|
30
|
+
: getRelativeLocaleUrl("/");
|
|
31
|
+
} catch {
|
|
32
|
+
if (Astro.currentLocale) {
|
|
33
|
+
resolvedHref = `/${Astro.currentLocale}/`;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
const classes = resolveClasses(logo, {}, useUi("logo", uiProp), className);
|
|
39
|
+
|
|
40
|
+
const globalConfig = getUIConfig();
|
|
41
|
+
const rcLogos = globalConfig.logos as Record<string, any>;
|
|
42
|
+
|
|
43
|
+
let logoSrc: string | null = null;
|
|
44
|
+
let darkSrc: string | null = null;
|
|
45
|
+
let lightSrc: string | null = null;
|
|
46
|
+
|
|
47
|
+
const logoFiles = import.meta.glob<{ default: any }>("/src/assets/**/*.{svg,png,jpg,jpeg,webp,gif}", { eager: true });
|
|
48
|
+
|
|
49
|
+
function resolveLogo(pathStr: string | null | undefined): any {
|
|
50
|
+
if (!pathStr) return null;
|
|
51
|
+
let lookupPath = pathStr;
|
|
52
|
+
if (lookupPath.startsWith("./")) {
|
|
53
|
+
lookupPath = lookupPath.substring(1);
|
|
54
|
+
} else if (!lookupPath.startsWith("/")) {
|
|
55
|
+
lookupPath = "/" + lookupPath;
|
|
56
|
+
}
|
|
57
|
+
const file = logoFiles[lookupPath];
|
|
58
|
+
if (file) {
|
|
59
|
+
return file.default?.src || file.default;
|
|
60
|
+
}
|
|
61
|
+
return pathStr;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
if (rcLogos && typeof rcLogos === "object") {
|
|
65
|
+
let src = rcLogos[variant];
|
|
66
|
+
if (src && typeof src === "object") {
|
|
67
|
+
if (mode) {
|
|
68
|
+
logoSrc = resolveLogo(src[mode] || src.color);
|
|
69
|
+
} else {
|
|
70
|
+
logoSrc = resolveLogo(src.color || src.black || src.white);
|
|
71
|
+
darkSrc = resolveLogo(src.white || src.color);
|
|
72
|
+
lightSrc = resolveLogo(src.black || src.color);
|
|
73
|
+
}
|
|
74
|
+
} else if (typeof src === "string") {
|
|
75
|
+
logoSrc = resolveLogo(src);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
const startsWithUrlPrefix = logoSrc && (logoSrc.startsWith("http") || logoSrc.startsWith("/") || logoSrc.startsWith("."));
|
|
80
|
+
const isIcon = logoSrc && !startsWithUrlPrefix && (logoSrc.includes(":") || logoSrc.startsWith("i-"));
|
|
81
|
+
const hasAutoMode = darkSrc && lightSrc && darkSrc !== lightSrc && !mode;
|
|
82
|
+
---
|
|
83
|
+
|
|
84
|
+
<a
|
|
85
|
+
class={classes.root}
|
|
86
|
+
href={resolvedHref}
|
|
87
|
+
aria-label={alt || variant}
|
|
88
|
+
data-slot="root"
|
|
89
|
+
{...rest}
|
|
90
|
+
>
|
|
91
|
+
{logoSrc ? (
|
|
92
|
+
isIcon ? (
|
|
93
|
+
<span class:list={[logoSrc, "size-full block shrink-0"]} aria-hidden="true" />
|
|
94
|
+
) : hasAutoMode ? (
|
|
95
|
+
<>
|
|
96
|
+
<img
|
|
97
|
+
src={lightSrc}
|
|
98
|
+
alt={alt || ""}
|
|
99
|
+
class="size-full block object-contain shrink-0 dark:hidden"
|
|
100
|
+
/>
|
|
101
|
+
<img
|
|
102
|
+
src={darkSrc}
|
|
103
|
+
alt={alt || ""}
|
|
104
|
+
class="size-full hidden object-contain shrink-0 dark:block"
|
|
105
|
+
/>
|
|
106
|
+
</>
|
|
107
|
+
) : (
|
|
108
|
+
<img
|
|
109
|
+
src={logoSrc}
|
|
110
|
+
alt={alt || ""}
|
|
111
|
+
class="size-full block object-contain shrink-0"
|
|
112
|
+
/>
|
|
113
|
+
)
|
|
114
|
+
) : (
|
|
115
|
+
<slot />
|
|
116
|
+
)}
|
|
117
|
+
</a>
|
|
@@ -22,7 +22,7 @@ const {
|
|
|
22
22
|
ui: uiProp,
|
|
23
23
|
class: className,
|
|
24
24
|
...rest
|
|
25
|
-
} = Astro.props as ModalProps
|
|
25
|
+
} = Astro.props as ModalProps & { size?: "sm" | "md" | "lg" | "xl" }
|
|
26
26
|
|
|
27
27
|
const classes = resolveClasses(modal, {
|
|
28
28
|
size
|
|
@@ -36,12 +36,12 @@ const modalId = `rla-modal-${Math.random().toString(36).substring(2, 9)}`
|
|
|
36
36
|
class={classes.trigger}
|
|
37
37
|
data-slot="trigger"
|
|
38
38
|
type="button"
|
|
39
|
-
|
|
39
|
+
data-dialog-show={modalId}
|
|
40
40
|
>
|
|
41
41
|
{triggerLabel}
|
|
42
42
|
</button>
|
|
43
43
|
) : (
|
|
44
|
-
<span
|
|
44
|
+
<span data-dialog-show={modalId}>
|
|
45
45
|
<slot name="trigger" />
|
|
46
46
|
</span>
|
|
47
47
|
)}
|
|
@@ -59,7 +59,7 @@ const modalId = `rla-modal-${Math.random().toString(36).substring(2, 9)}`
|
|
|
59
59
|
class={classes.closeButton}
|
|
60
60
|
data-slot="close-button"
|
|
61
61
|
type="button"
|
|
62
|
-
|
|
62
|
+
data-dialog-close={modalId}
|
|
63
63
|
aria-label="Close modal"
|
|
64
64
|
>
|
|
65
65
|
<span class="i-lucide-x size-4" aria-hidden="true" />
|
|
@@ -81,19 +81,49 @@ const modalId = `rla-modal-${Math.random().toString(36).substring(2, 9)}`
|
|
|
81
81
|
</dialog>
|
|
82
82
|
</div>
|
|
83
83
|
|
|
84
|
-
<script
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
const
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
84
|
+
<script>
|
|
85
|
+
if (!(window as any).rlaDialogListenerActive) {
|
|
86
|
+
(window as any).rlaDialogListenerActive = true;
|
|
87
|
+
document.addEventListener('click', (e) => {
|
|
88
|
+
const target = e.target as HTMLElement | null;
|
|
89
|
+
if (!target) return;
|
|
90
|
+
|
|
91
|
+
const showTrigger = target.closest('[data-dialog-show]');
|
|
92
|
+
if (showTrigger) {
|
|
93
|
+
const dialogId = showTrigger.getAttribute('data-dialog-show');
|
|
94
|
+
if (dialogId) {
|
|
95
|
+
const dialog = document.getElementById(dialogId) as HTMLDialogElement | null;
|
|
96
|
+
if (dialog) {
|
|
97
|
+
if (typeof dialog.showModal === 'function') {
|
|
98
|
+
dialog.showModal();
|
|
99
|
+
} else if (typeof (dialog as any).showmodal === 'function') {
|
|
100
|
+
(dialog as any).showmodal();
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
const closeTrigger = target.closest('[data-dialog-close]');
|
|
107
|
+
if (closeTrigger) {
|
|
108
|
+
const dialogId = closeTrigger.getAttribute('data-dialog-close');
|
|
109
|
+
if (dialogId) {
|
|
110
|
+
const dialog = document.getElementById(dialogId) as HTMLDialogElement | null;
|
|
111
|
+
dialog?.close();
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
if (target.tagName === 'DIALOG' && target.getAttribute('data-close-on-click-outside') === 'true') {
|
|
116
|
+
const rect = target.getBoundingClientRect();
|
|
117
|
+
const isInModal = (
|
|
118
|
+
rect.top <= e.clientY &&
|
|
119
|
+
e.clientY <= rect.top + rect.height &&
|
|
120
|
+
rect.left <= e.clientX &&
|
|
121
|
+
e.clientX <= rect.left + rect.width
|
|
122
|
+
);
|
|
123
|
+
if (!isInModal) {
|
|
124
|
+
(target as HTMLDialogElement).close();
|
|
125
|
+
}
|
|
96
126
|
}
|
|
97
|
-
}
|
|
98
|
-
}
|
|
127
|
+
});
|
|
128
|
+
}
|
|
99
129
|
</script>
|