@rimelight/ui 0.0.45 → 0.0.47
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/LICENSE +21 -0
- package/dist/icons-DPnFQCts.d.mts +72 -0
- package/dist/icons.d.mts +2 -0
- package/dist/icons.mjs +32 -0
- package/dist/icons.raw-CjAuL2Sc.mjs +67 -0
- package/dist/index.d.mts +13 -0
- package/dist/index.mjs +26 -0
- package/dist/preset.d.mts +2 -0
- package/dist/preset.mjs +215 -0
- package/dist/resolver.d.mts +6 -0
- package/dist/resolver.mjs +116 -0
- package/dist/shortcuts.d.mts +29 -0
- package/dist/shortcuts.mjs +119 -0
- package/dist/stores.d.mts +9 -0
- package/dist/stores.mjs +19 -0
- package/dist/types-DWmKMcYC.d.mts +86 -0
- package/dist/types.d.mts +2 -0
- package/dist/types.mjs +1 -0
- package/package.json +40 -12
- package/src/components/banner/RLABanner.astro +1 -1
- package/src/components/button/RLSButton.tsx +14 -8
- package/src/components/dashboard-sidebar/RLADashboardSidebar.astro +4 -4
- package/src/components/dropdown-menu/RLADropdownMenu.astro +1 -1
- package/src/components/file-upload/RLAFileUpload.astro +1 -1
- package/src/components/header/HeaderLayer.astro +1 -1
- package/src/components/input-menu/RLAInputMenu.astro +3 -3
- package/src/components/input-rating/RLAInputRating.astro +8 -8
- package/src/components/layout-grid/RLALayoutGrid.astro +29 -29
- package/src/components/link/RLALink.astro +5 -5
- package/src/components/link/RLSLink.tsx +4 -4
- package/src/components/locale-selector/RLALocaleSelector.astro +109 -102
- package/src/components/locale-selector/locale-selector.ts +2 -7
- package/src/components/logo/RLALogo.astro +88 -102
- package/src/components/navigation-menu/RLANavigationMenu.astro +6 -6
- package/src/components/popover/RLAPopover.astro +2 -2
- package/src/components/scroll-area/RLAScrollArea.astro +1 -1
- package/src/components/scroll-to-top/RLAScrollToTop.astro +4 -4
- package/src/components/search/RLASearch.astro +6 -6
- package/src/components/shortcuts/RLAShortcuts.astro +2 -2
- package/src/components/sidebar/RLASidebar.astro +1 -1
- package/src/components/splitter/RLASplitter.astro +1 -1
- package/src/components/stepper/RLAStepper.astro +9 -9
- package/src/components/table/RLATable.astro +1 -1
- package/src/components/tabs/RLATabs.astro +8 -8
- package/src/components/toast/RLAToast.astro +2 -2
- package/src/index.ts +13 -3
|
@@ -25,7 +25,7 @@ const {
|
|
|
25
25
|
const attrs = resolveLinkAttrs(Astro.props)
|
|
26
26
|
|
|
27
27
|
const classes = raw
|
|
28
|
-
? { root: (Astro.props
|
|
28
|
+
? { root: (Astro.props["class"] as string) || "", leadingIcon: "", label: "", trailingIcon: "" }
|
|
29
29
|
: (linkTheme({
|
|
30
30
|
theme,
|
|
31
31
|
...(active !== undefined ? { active } : {}),
|
|
@@ -34,7 +34,7 @@ const classes = raw
|
|
|
34
34
|
---
|
|
35
35
|
|
|
36
36
|
<a
|
|
37
|
-
class={classes
|
|
37
|
+
class={classes["root"]}
|
|
38
38
|
data-slot="root"
|
|
39
39
|
href={attrs.href}
|
|
40
40
|
target={attrs.target}
|
|
@@ -48,21 +48,21 @@ const classes = raw
|
|
|
48
48
|
>
|
|
49
49
|
<slot name="leading">
|
|
50
50
|
{leadingIcon && (
|
|
51
|
-
<span class={classes
|
|
51
|
+
<span class={classes["leadingIcon"]} data-slot="leading-icon">
|
|
52
52
|
<RLAIcon name={leadingIcon} size="sm" aria-hidden="true" />
|
|
53
53
|
</span>
|
|
54
54
|
)}
|
|
55
55
|
</slot>
|
|
56
56
|
|
|
57
57
|
{label !== undefined && label !== null ? (
|
|
58
|
-
<span class={classes
|
|
58
|
+
<span class={classes["label"]} data-slot="label">{label}</span>
|
|
59
59
|
) : (
|
|
60
60
|
<slot />
|
|
61
61
|
)}
|
|
62
62
|
|
|
63
63
|
<slot name="trailing">
|
|
64
64
|
{attrs.showTrailingIcon && (
|
|
65
|
-
<span class={classes
|
|
65
|
+
<span class={classes["trailingIcon"]} data-slot="trailing-icon">
|
|
66
66
|
<RLAIcon
|
|
67
67
|
name={attrs.showTrailingIcon}
|
|
68
68
|
size="sm"
|
|
@@ -53,7 +53,7 @@ const RLSLink: Component<RLSLinkProps> = (allProps) => {
|
|
|
53
53
|
|
|
54
54
|
return (
|
|
55
55
|
<a
|
|
56
|
-
class={classes()
|
|
56
|
+
class={classes()["root"]}
|
|
57
57
|
data-slot="root"
|
|
58
58
|
href={attrs().href}
|
|
59
59
|
target={attrs().target}
|
|
@@ -67,7 +67,7 @@ const RLSLink: Component<RLSLinkProps> = (allProps) => {
|
|
|
67
67
|
{props.leading ? (
|
|
68
68
|
props.leading
|
|
69
69
|
) : props.leadingIcon ? (
|
|
70
|
-
<span class={classes()
|
|
70
|
+
<span class={classes()["leadingIcon"]} data-slot="leading-icon">
|
|
71
71
|
<RLSIcon name={props.leadingIcon} size="sm" aria-hidden="true" />
|
|
72
72
|
</span>
|
|
73
73
|
) : null}
|
|
@@ -75,7 +75,7 @@ const RLSLink: Component<RLSLinkProps> = (allProps) => {
|
|
|
75
75
|
{props.children !== undefined && props.children !== null ? (
|
|
76
76
|
props.children
|
|
77
77
|
) : props.label !== undefined && props.label !== null ? (
|
|
78
|
-
<span class={classes()
|
|
78
|
+
<span class={classes()["label"]} data-slot="label">
|
|
79
79
|
{props.label}
|
|
80
80
|
</span>
|
|
81
81
|
) : null}
|
|
@@ -83,7 +83,7 @@ const RLSLink: Component<RLSLinkProps> = (allProps) => {
|
|
|
83
83
|
{props.trailing ? (
|
|
84
84
|
props.trailing
|
|
85
85
|
) : attrs().showTrailingIcon ? (
|
|
86
|
-
<span class={classes()
|
|
86
|
+
<span class={classes()["trailingIcon"]} data-slot="trailing-icon">
|
|
87
87
|
<RLSIcon name={attrs().showTrailingIcon!} size="sm" aria-hidden="true" />
|
|
88
88
|
</span>
|
|
89
89
|
) : null}
|
|
@@ -1,102 +1,109 @@
|
|
|
1
|
-
---
|
|
2
|
-
import type { LocaleSelectorProps } from "./locale-selector"
|
|
3
|
-
import { localeSelectorTheme } from "./locale-selector.theme"
|
|
4
|
-
import
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
const
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
const
|
|
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
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
1
|
+
---
|
|
2
|
+
import type { LocaleSelectorProps, LocaleItem } from "./locale-selector"
|
|
3
|
+
import { localeSelectorTheme } from "./locale-selector.theme"
|
|
4
|
+
import RLASelect from "../select/RLASelect.astro"
|
|
5
|
+
|
|
6
|
+
const {
|
|
7
|
+
locales = [],
|
|
8
|
+
currentLocale = "en",
|
|
9
|
+
size = "md",
|
|
10
|
+
theme,
|
|
11
|
+
...rest
|
|
12
|
+
} = Astro.props as LocaleSelectorProps;
|
|
13
|
+
|
|
14
|
+
const classes = localeSelectorTheme(Astro.props);
|
|
15
|
+
|
|
16
|
+
function getLocaleDisplayName(localeCode: string): string {
|
|
17
|
+
try {
|
|
18
|
+
const formatter = new Intl.DisplayNames([localeCode], { type: 'language' });
|
|
19
|
+
const nativeName = formatter.of(localeCode);
|
|
20
|
+
return nativeName
|
|
21
|
+
? nativeName.charAt(0).toUpperCase() + nativeName.slice(1)
|
|
22
|
+
: localeCode.toUpperCase();
|
|
23
|
+
} catch {
|
|
24
|
+
return localeCode.toUpperCase();
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
// Normalize locales: string or LocaleItem
|
|
29
|
+
const processedLocales: LocaleItem[] = locales.map(item =>
|
|
30
|
+
typeof item === 'string'
|
|
31
|
+
? { code: item, label: getLocaleDisplayName(item) }
|
|
32
|
+
: { ...item, label: item.label || getLocaleDisplayName(item.code) }
|
|
33
|
+
);
|
|
34
|
+
|
|
35
|
+
const items = processedLocales.map((item) => {
|
|
36
|
+
let targetUrl: string;
|
|
37
|
+
if (item.href !== undefined && item.href !== null) {
|
|
38
|
+
targetUrl = item.href + (item.href.includes("?") ? "" : Astro.url.search);
|
|
39
|
+
} else {
|
|
40
|
+
// Derive the known locale codes from the props list so we can detect
|
|
41
|
+
// whether the first URL segment is a locale prefix or a real path segment.
|
|
42
|
+
const knownCodes = new Set(processedLocales.map((l) => l.code));
|
|
43
|
+
|
|
44
|
+
const pathname = Astro.url.pathname;
|
|
45
|
+
const segments = pathname.split("/").filter(Boolean);
|
|
46
|
+
const firstIsLocale = segments.length > 0 && knownCodes.has(segments[0]!);
|
|
47
|
+
|
|
48
|
+
if (firstIsLocale) {
|
|
49
|
+
// Replace existing locale prefix with the target locale.
|
|
50
|
+
segments[0] = item.code;
|
|
51
|
+
targetUrl = `/${segments.join("/")}${pathname.endsWith("/") ? "/" : ""}${Astro.url.search}`;
|
|
52
|
+
} else if (segments.length > 0) {
|
|
53
|
+
// No locale prefix in the current URL — prepend the target locale.
|
|
54
|
+
targetUrl = `/${item.code}/${segments.join("/")}${pathname.endsWith("/") ? "/" : ""}${Astro.url.search}`;
|
|
55
|
+
} else {
|
|
56
|
+
// Root path.
|
|
57
|
+
targetUrl = `/${item.code}/${Astro.url.search}`;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
return {
|
|
62
|
+
label: item.label,
|
|
63
|
+
value: targetUrl,
|
|
64
|
+
code: item.code
|
|
65
|
+
};
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
const currentLocaleUrl = items.find(item => item.code === currentLocale)?.value || "";
|
|
69
|
+
---
|
|
70
|
+
|
|
71
|
+
<rla-locale-selector data-theme={theme} {...rest}>
|
|
72
|
+
<div class:list={[classes.root]} data-locale-selector>
|
|
73
|
+
{Astro.slots.has("label") && (
|
|
74
|
+
<label class:list={[classes.label]}>
|
|
75
|
+
<slot name="label" />
|
|
76
|
+
</label>
|
|
77
|
+
)}
|
|
78
|
+
|
|
79
|
+
<div class:list={[classes.wrapper]}>
|
|
80
|
+
<RLASelect
|
|
81
|
+
items={items}
|
|
82
|
+
value={currentLocaleUrl}
|
|
83
|
+
size={size}
|
|
84
|
+
theme={theme}
|
|
85
|
+
/>
|
|
86
|
+
</div>
|
|
87
|
+
</div>
|
|
88
|
+
</rla-locale-selector>
|
|
89
|
+
|
|
90
|
+
<script>
|
|
91
|
+
class RLALocaleSelector extends HTMLElement {
|
|
92
|
+
connectedCallback() {
|
|
93
|
+
this.style.display = 'contents';
|
|
94
|
+
this.addEventListener('change', (event) => {
|
|
95
|
+
const target = event.target as HTMLSelectElement;
|
|
96
|
+
if (target && target.tagName === 'SELECT') {
|
|
97
|
+
const targetUrl = target.value;
|
|
98
|
+
if (targetUrl) {
|
|
99
|
+
window.location.href = targetUrl;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
if (!customElements.get('rla-locale-selector')) {
|
|
107
|
+
customElements.define('rla-locale-selector', RLALocaleSelector);
|
|
108
|
+
}
|
|
109
|
+
</script>
|
|
@@ -4,13 +4,8 @@ export interface LocaleItem {
|
|
|
4
4
|
/**
|
|
5
5
|
* The URL to navigate to when this locale is selected.
|
|
6
6
|
*
|
|
7
|
-
* Supply this to make the component fully routing-agnostic: it will use `href` directly
|
|
8
|
-
*
|
|
9
|
-
* strategy their project uses — `getRelativeLocaleUrl`, `@rimelight/i18n`, a custom helper, or a
|
|
10
|
-
* plain string.
|
|
11
|
-
*
|
|
12
|
-
* When omitted the component falls back to computing the URL via Astro's built-in
|
|
13
|
-
* `getRelativeLocaleUrl` helper (requires Astro i18n to be configured).
|
|
7
|
+
* Supply this to make the component fully routing-agnostic: it will use `href` directly. When
|
|
8
|
+
* omitted, the component falls back to updating the first URL segment to match the locale code.
|
|
14
9
|
*/
|
|
15
10
|
href?: string
|
|
16
11
|
}
|
|
@@ -1,102 +1,88 @@
|
|
|
1
|
-
---
|
|
2
|
-
import type { LogoProps } from "./logo"
|
|
3
|
-
import { logoTheme } from "./logo.theme"
|
|
4
|
-
import uiConfig from "virtual:rimelight/ui"
|
|
5
|
-
|
|
6
|
-
const {
|
|
7
|
-
variant = "logomark",
|
|
8
|
-
mode,
|
|
9
|
-
href = "/",
|
|
10
|
-
alt,
|
|
11
|
-
...rest
|
|
12
|
-
} = Astro.props as LogoProps;
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
if (
|
|
40
|
-
|
|
41
|
-
} else
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
const
|
|
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
|
-
class="size-full hidden object-contain shrink-0 dark:block"
|
|
90
|
-
/>
|
|
91
|
-
</>
|
|
92
|
-
) : (
|
|
93
|
-
<img
|
|
94
|
-
src={logoSrc}
|
|
95
|
-
alt={alt || ""}
|
|
96
|
-
class="size-full block object-contain shrink-0"
|
|
97
|
-
/>
|
|
98
|
-
)
|
|
99
|
-
) : (
|
|
100
|
-
<slot />
|
|
101
|
-
)}
|
|
102
|
-
</a>
|
|
1
|
+
---
|
|
2
|
+
import type { LogoProps } from "./logo"
|
|
3
|
+
import { logoTheme } from "./logo.theme"
|
|
4
|
+
import uiConfig from "virtual:rimelight/ui"
|
|
5
|
+
|
|
6
|
+
const {
|
|
7
|
+
variant = "logomark",
|
|
8
|
+
mode,
|
|
9
|
+
href = "/",
|
|
10
|
+
alt,
|
|
11
|
+
...rest
|
|
12
|
+
} = Astro.props as LogoProps;
|
|
13
|
+
|
|
14
|
+
const classes = logoTheme(Astro.props);
|
|
15
|
+
|
|
16
|
+
let logoSrc: string | null = null;
|
|
17
|
+
let darkSrc: string | null = null;
|
|
18
|
+
let lightSrc: string | null = null;
|
|
19
|
+
|
|
20
|
+
const logoFiles = import.meta.glob<{ default: any }>("/src/assets/**/*.{svg,png,jpg,jpeg,webp,gif}", { eager: true });
|
|
21
|
+
|
|
22
|
+
function resolveLogo(pathStr: string | null | undefined): any {
|
|
23
|
+
if (!pathStr) return null;
|
|
24
|
+
let lookupPath = pathStr;
|
|
25
|
+
if (lookupPath.startsWith("./")) {
|
|
26
|
+
lookupPath = lookupPath.substring(1);
|
|
27
|
+
} else if (!lookupPath.startsWith("/")) {
|
|
28
|
+
lookupPath = "/" + lookupPath;
|
|
29
|
+
}
|
|
30
|
+
const file = logoFiles[lookupPath];
|
|
31
|
+
if (file) {
|
|
32
|
+
return file.default?.src || file.default;
|
|
33
|
+
}
|
|
34
|
+
return pathStr;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
const logoVariant = uiConfig.logos?.[variant];
|
|
38
|
+
if (logoVariant && typeof logoVariant === "object") {
|
|
39
|
+
if (mode) {
|
|
40
|
+
logoSrc = resolveLogo(logoVariant[mode] || logoVariant.color);
|
|
41
|
+
} else {
|
|
42
|
+
logoSrc = resolveLogo(logoVariant.color || logoVariant.black || logoVariant.white);
|
|
43
|
+
darkSrc = resolveLogo(logoVariant.white || logoVariant.color);
|
|
44
|
+
lightSrc = resolveLogo(logoVariant.black || logoVariant.color);
|
|
45
|
+
}
|
|
46
|
+
} else if (typeof logoVariant === "string") {
|
|
47
|
+
logoSrc = resolveLogo(logoVariant);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
const startsWithUrlPrefix = logoSrc && (logoSrc.startsWith("http") || logoSrc.startsWith("/") || logoSrc.startsWith("."));
|
|
51
|
+
const isIcon = logoSrc && !startsWithUrlPrefix && (logoSrc.includes(":") || logoSrc.startsWith("i-"));
|
|
52
|
+
const hasAutoMode = darkSrc && lightSrc && darkSrc !== lightSrc && !mode;
|
|
53
|
+
---
|
|
54
|
+
|
|
55
|
+
<a
|
|
56
|
+
class={classes.root}
|
|
57
|
+
href={href}
|
|
58
|
+
aria-label={alt || variant}
|
|
59
|
+
data-slot="root"
|
|
60
|
+
{...rest}
|
|
61
|
+
>
|
|
62
|
+
{logoSrc ? (
|
|
63
|
+
isIcon ? (
|
|
64
|
+
<span class:list={[logoSrc, "size-full block shrink-0"]} aria-hidden="true" />
|
|
65
|
+
) : hasAutoMode ? (
|
|
66
|
+
<>
|
|
67
|
+
<img
|
|
68
|
+
src={lightSrc}
|
|
69
|
+
alt={alt || ""}
|
|
70
|
+
class="size-full block object-contain shrink-0 dark:hidden"
|
|
71
|
+
/>
|
|
72
|
+
<img
|
|
73
|
+
src={darkSrc}
|
|
74
|
+
alt={alt || ""}
|
|
75
|
+
class="size-full hidden object-contain shrink-0 dark:block"
|
|
76
|
+
/>
|
|
77
|
+
</>
|
|
78
|
+
) : (
|
|
79
|
+
<img
|
|
80
|
+
src={logoSrc}
|
|
81
|
+
alt={alt || ""}
|
|
82
|
+
class="size-full block object-contain shrink-0"
|
|
83
|
+
/>
|
|
84
|
+
)
|
|
85
|
+
) : (
|
|
86
|
+
<slot />
|
|
87
|
+
)}
|
|
88
|
+
</a>
|
|
@@ -29,11 +29,11 @@ await Promise.all(
|
|
|
29
29
|
{items.map((item, i) => {
|
|
30
30
|
const hasChildren = item.children && item.children.length > 0
|
|
31
31
|
|
|
32
|
-
const itemPath = (item
|
|
32
|
+
const itemPath = (item["href"] ?? item["to"] ?? "#") as string
|
|
33
33
|
const normalizedPath = itemPath.replace(/^\/[a-z]{2}(?:-[a-zA-Z]{2})?(?=\/|$)/, '').replace(/\/+$/, '') || '/'
|
|
34
34
|
const currentPath = Astro.url.pathname.replace(/^\/[a-z]{2}(?:-[a-zA-Z]{2})?(?=\/|$)/, '').replace(/\/+$/, '') || '/'
|
|
35
35
|
|
|
36
|
-
const isActive = item
|
|
36
|
+
const isActive = item["active"] ?? (
|
|
37
37
|
normalizedPath !== '' && normalizedPath !== '/'
|
|
38
38
|
? currentPath.startsWith(normalizedPath)
|
|
39
39
|
: currentPath === '/'
|
|
@@ -56,7 +56,7 @@ await Promise.all(
|
|
|
56
56
|
</button>
|
|
57
57
|
) : (
|
|
58
58
|
<a
|
|
59
|
-
href={typeof item
|
|
59
|
+
href={typeof item["href"] === "string" ? item["href"] : (typeof item["to"] === "string" ? item["to"] : "#")}
|
|
60
60
|
class={classes.link}
|
|
61
61
|
data-slot="link"
|
|
62
62
|
aria-current={isActive ? "page" : undefined}
|
|
@@ -81,12 +81,12 @@ await Promise.all(
|
|
|
81
81
|
{item.children!.map(child => (
|
|
82
82
|
<li>
|
|
83
83
|
<a
|
|
84
|
-
href={typeof child
|
|
84
|
+
href={typeof child["href"] === "string" ? child["href"] : (typeof child["to"] === "string" ? child["to"] : "#")}
|
|
85
85
|
class="flex items-start gap-3 rounded-sm px-3 py-2 text-sm hover:bg-accented hover:text-highlighted transition-colors"
|
|
86
86
|
>
|
|
87
|
-
{child
|
|
87
|
+
{child["icon"] && <span class={child["icon"] + " mt-0.5 size-4 shrink-0 text-muted"} />}
|
|
88
88
|
<div>
|
|
89
|
-
<div class="font-medium leading-none">{child
|
|
89
|
+
<div class="font-medium leading-none">{child["label"]}</div>
|
|
90
90
|
{child.description && (
|
|
91
91
|
<p class="mt-1 text-xs text-muted line-clamp-2">{child.description}</p>
|
|
92
92
|
)}
|
|
@@ -198,7 +198,7 @@ const popoverId = `rla-popover-${Math.random().toString(36).substring(2, 9)}`
|
|
|
198
198
|
*/
|
|
199
199
|
function setupPopovers() {
|
|
200
200
|
document.querySelectorAll<HTMLElement>('[data-slot="popover-container"]').forEach(container => {
|
|
201
|
-
const mode = container.dataset
|
|
201
|
+
const mode = container.dataset["mode"] || 'both';
|
|
202
202
|
const popoverId = container.querySelector<HTMLElement>('[data-slot="content"]')?.id;
|
|
203
203
|
if (!popoverId) return;
|
|
204
204
|
|
|
@@ -248,7 +248,7 @@ const popoverId = `rla-popover-${Math.random().toString(36).substring(2, 9)}`
|
|
|
248
248
|
const ph = panel.offsetHeight;
|
|
249
249
|
if (pw === 0 || ph === 0) return; // closed or not yet rendered
|
|
250
250
|
|
|
251
|
-
const parts = (container.dataset
|
|
251
|
+
const parts = (container.dataset["placement"] || 'bottom').split('-');
|
|
252
252
|
const vert = parts[0]; // top | bottom
|
|
253
253
|
const horiz = parts[1] || 'center'; // start | end | center
|
|
254
254
|
const gap = 8;
|
|
@@ -66,7 +66,7 @@ const heightStyle = height
|
|
|
66
66
|
const viewport = area.querySelector("[data-scroll-viewport]") as HTMLElement | null;
|
|
67
67
|
if (!viewport) return;
|
|
68
68
|
|
|
69
|
-
const hideDelay = parseInt((area as HTMLElement).dataset
|
|
69
|
+
const hideDelay = parseInt((area as HTMLElement).dataset["hideDelay"] ?? "600", 10);
|
|
70
70
|
|
|
71
71
|
const vBar = area.querySelector("[data-scroll-bar='vertical']") as HTMLElement | null;
|
|
72
72
|
const hBar = area.querySelector("[data-scroll-bar='horizontal']") as HTMLElement | null;
|
|
@@ -69,12 +69,12 @@ const classes = scrollToTopTheme(Astro.props)
|
|
|
69
69
|
if (!button || !innerElement) return;
|
|
70
70
|
|
|
71
71
|
const id = ++RLAScrollToTop.instanceCounter;
|
|
72
|
-
const threshold = Number(this.dataset
|
|
73
|
-
const color = this.dataset
|
|
74
|
-
const progressWidth = Number(this.dataset
|
|
72
|
+
const threshold = Number(this.dataset["threshold"]) || 200;
|
|
73
|
+
const color = this.dataset["color"] || 'primary';
|
|
74
|
+
const progressWidth = Number(this.dataset["progressWidth"]) || 6;
|
|
75
75
|
const gaugeBorderWidth = progressWidth * 0.5;
|
|
76
76
|
|
|
77
|
-
innerElement.dataset
|
|
77
|
+
innerElement.dataset["rlaInstance"] = String(id);
|
|
78
78
|
|
|
79
79
|
button.addEventListener('click', scrollToTop);
|
|
80
80
|
|
|
@@ -112,12 +112,12 @@ const emptyId = `search-empty-${uniqueId}`
|
|
|
112
112
|
|
|
113
113
|
connectedCallback() {
|
|
114
114
|
this.style.display = 'contents';
|
|
115
|
-
const triggerId = this.dataset
|
|
116
|
-
const modalId = this.dataset
|
|
117
|
-
const inputId = this.dataset
|
|
118
|
-
const resultsId = this.dataset
|
|
119
|
-
const emptyId = this.dataset
|
|
120
|
-
const endpoint = this.dataset
|
|
115
|
+
const triggerId = this.dataset["triggerId"];
|
|
116
|
+
const modalId = this.dataset["modalId"];
|
|
117
|
+
const inputId = this.dataset["inputId"];
|
|
118
|
+
const resultsId = this.dataset["resultsId"];
|
|
119
|
+
const emptyId = this.dataset["emptyId"];
|
|
120
|
+
const endpoint = this.dataset["endpoint"];
|
|
121
121
|
|
|
122
122
|
const trigger = this.querySelector(`#${triggerId}`);
|
|
123
123
|
const modal = this.querySelector(`#${modalId}`) as HTMLElement | null;
|
|
@@ -70,8 +70,8 @@ const modalId = `rla-shortcuts-${Math.random().toString(36).substring(2, 9)}`
|
|
|
70
70
|
const body = dialog.querySelector('.rla-shortcuts-body');
|
|
71
71
|
const closeBtn = dialog.querySelector('.rla-shortcuts-close');
|
|
72
72
|
|
|
73
|
-
const resolvedCategories = JSON.parse(dialog.dataset
|
|
74
|
-
const categoryOrder = JSON.parse(dialog.dataset
|
|
73
|
+
const resolvedCategories = JSON.parse(dialog.dataset["categories"] || '{}');
|
|
74
|
+
const categoryOrder = JSON.parse(dialog.dataset["categoryOrder"] || '[]');
|
|
75
75
|
|
|
76
76
|
let escapeCleanup: (() => void) | null = null;
|
|
77
77
|
|
|
@@ -65,7 +65,7 @@ const textSizeClass = _depth === 0 ? "" : "text-xs"
|
|
|
65
65
|
<!-- Body -->
|
|
66
66
|
<div class={classes.content} data-slot="content">
|
|
67
67
|
<slot>
|
|
68
|
-
<Astro.self items={items} t={t} _depth={1} ui={Astro.props
|
|
68
|
+
<Astro.self items={items} t={t} _depth={1} ui={Astro.props["ui"]} />
|
|
69
69
|
</slot>
|
|
70
70
|
</div>
|
|
71
71
|
|
|
@@ -85,7 +85,7 @@ await Promise.all(
|
|
|
85
85
|
const container = this.querySelector("[data-resizable]") as HTMLElement | null;
|
|
86
86
|
if (!container) return;
|
|
87
87
|
|
|
88
|
-
const direction = container.dataset
|
|
88
|
+
const direction = container.dataset["direction"] ?? "horizontal";
|
|
89
89
|
const isHorizontal = direction === "horizontal";
|
|
90
90
|
|
|
91
91
|
const panels = Array.from(
|