lightnet 4.3.0 → 4.4.0
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/CHANGELOG.md +10 -0
- package/package.json +1 -1
- package/src/astro-integration/config.ts +19 -15
- package/src/layouts/Page.astro +27 -6
- package/src/layouts/components/footer/Credits.astro +14 -0
- package/src/layouts/components/footer/Footer.astro +88 -0
- package/src/layouts/components/footer/LanguageSelectionMenu.astro +44 -0
- package/src/layouts/components/{LightNetLogo.svg → footer/LightNetLogo.svg} +1 -1
- package/src/layouts/components/{LanguagePicker.astro → header/LanguageSelectionMenu.astro} +1 -1
- package/src/layouts/components/{MenuItem.astro → header/MenuItem.astro} +1 -1
- package/src/layouts/components/{PageNavigation.astro → header/PageNavigation.astro} +4 -4
- package/src/layouts/components/{PageTitle.astro → header/PageTitle.astro} +1 -1
- package/src/layouts/components/Footer.astro +0 -149
- /package/src/layouts/components/{format-footer-text.ts → footer/format-footer-text.ts} +0 -0
- /package/src/layouts/components/{Header.astro → header/Header.astro} +0 -0
- /package/src/layouts/components/{Menu.astro → header/Menu.astro} +0 -0
- /package/src/layouts/components/{Favicon.astro → meta/Favicon.astro} +0 -0
- /package/src/layouts/components/{ViewTransition.astro → meta/ViewTransition.astro} +0 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,15 @@
|
|
|
1
1
|
# lightnet
|
|
2
2
|
|
|
3
|
+
## 4.4.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- [#409](https://github.com/LightNetDev/LightNet/pull/409) [`6d214f6`](https://github.com/LightNetDev/LightNet/commit/6d214f6b620dc00b8860da50006778649e977d59) - Add ` disallowSearchIndexing` settings to exclude entire site or pages from search engines.
|
|
8
|
+
|
|
9
|
+
### Patch Changes
|
|
10
|
+
|
|
11
|
+
- [#409](https://github.com/LightNetDev/LightNet/pull/409) [`6d214f6`](https://github.com/LightNetDev/LightNet/commit/6d214f6b620dc00b8860da50006778649e977d59) - Improved footer layout
|
|
12
|
+
|
|
3
13
|
## 4.3.0
|
|
4
14
|
|
|
5
15
|
### Minor Changes
|
package/package.json
CHANGED
|
@@ -110,22 +110,10 @@ export const configSchema = z.object({
|
|
|
110
110
|
*/
|
|
111
111
|
favicon: faviconSchema.array().optional(),
|
|
112
112
|
/**
|
|
113
|
-
*
|
|
114
|
-
|
|
115
|
-
credits: z.boolean().default(false),
|
|
116
|
-
/**
|
|
117
|
-
* Optional localized text to display in your site's footer.
|
|
118
|
-
*
|
|
119
|
-
* Use `{{year}}` to render the current calendar year.
|
|
120
|
-
*
|
|
121
|
-
* @example { en: "Copyright {{year}} LightNet" }
|
|
122
|
-
*/
|
|
123
|
-
footerText: translationMapSchema.optional(),
|
|
124
|
-
/**
|
|
125
|
-
* Optional links to display in your site's footer.
|
|
113
|
+
* If set too true, this sets robots meta tag to no index to tell search engines like google to
|
|
114
|
+
* not add any page of this media library to their search results.
|
|
126
115
|
*/
|
|
127
|
-
|
|
128
|
-
|
|
116
|
+
disallowSearchIndexing: z.boolean().optional(),
|
|
129
117
|
/**
|
|
130
118
|
* Link to manifest file within public/ folder
|
|
131
119
|
*/
|
|
@@ -186,6 +174,22 @@ export const configSchema = z.object({
|
|
|
186
174
|
* @example "./src/components/MyHeadTag.astro"
|
|
187
175
|
*/
|
|
188
176
|
headComponent: z.string().optional(),
|
|
177
|
+
/**
|
|
178
|
+
* Enable displaying a “Powered by LightNet” link in your site’s footer.
|
|
179
|
+
*/
|
|
180
|
+
credits: z.boolean().default(false),
|
|
181
|
+
/**
|
|
182
|
+
* Optional localized text to display in your site's footer.
|
|
183
|
+
*
|
|
184
|
+
* Use `{{year}}` to render the current calendar year.
|
|
185
|
+
*
|
|
186
|
+
* @example { en: "Copyright {{year}} LightNet" }
|
|
187
|
+
*/
|
|
188
|
+
footerText: translationMapSchema.optional(),
|
|
189
|
+
/**
|
|
190
|
+
* Optional links to display in your site's footer.
|
|
191
|
+
*/
|
|
192
|
+
footerLinks: z.array(linkSchema).optional(),
|
|
189
193
|
/**
|
|
190
194
|
* Path to an Astro component to be added at the bottom of all pages.
|
|
191
195
|
*
|
package/src/layouts/Page.astro
CHANGED
|
@@ -7,10 +7,10 @@ import config from "virtual:lightnet/config"
|
|
|
7
7
|
|
|
8
8
|
import { resolveLanguage } from "../i18n/resolve-language"
|
|
9
9
|
import { pathWithBase } from "../utils/paths"
|
|
10
|
-
import
|
|
11
|
-
import
|
|
12
|
-
import
|
|
13
|
-
import ViewTransition from "./components/ViewTransition.astro"
|
|
10
|
+
import Footer from "./components/footer/Footer.astro"
|
|
11
|
+
import Header from "./components/header/Header.astro"
|
|
12
|
+
import Favicon from "./components/meta/Favicon.astro"
|
|
13
|
+
import ViewTransition from "./components/meta/ViewTransition.astro"
|
|
14
14
|
|
|
15
15
|
export interface Props {
|
|
16
16
|
/**
|
|
@@ -37,10 +37,26 @@ export interface Props {
|
|
|
37
37
|
* analytics providers that choose to respect it. e.g. @lightnet/plausible-analytics
|
|
38
38
|
*/
|
|
39
39
|
disableShouldTrack?: boolean
|
|
40
|
+
/**
|
|
41
|
+
* Disallow search indexing for this page from search tools like google.
|
|
42
|
+
* This tells them to not index content on this page.
|
|
43
|
+
*
|
|
44
|
+
* There is also a global setting to disable search indexing for all pages.
|
|
45
|
+
* The page specific setting will take precedence.
|
|
46
|
+
*
|
|
47
|
+
* default: false
|
|
48
|
+
*/
|
|
49
|
+
disallowSearchIndexing?: boolean
|
|
40
50
|
}
|
|
41
51
|
|
|
42
|
-
const {
|
|
43
|
-
|
|
52
|
+
const {
|
|
53
|
+
title,
|
|
54
|
+
description,
|
|
55
|
+
mainClass,
|
|
56
|
+
locale,
|
|
57
|
+
disableShouldTrack,
|
|
58
|
+
disallowSearchIndexing,
|
|
59
|
+
} = Astro.props
|
|
44
60
|
const { currentLocale: pathCurrentLocale, tConfigField } = Astro.locals.i18n
|
|
45
61
|
const currentLocale = locale ?? pathCurrentLocale
|
|
46
62
|
const configTitle = tConfigField(config.title, config)
|
|
@@ -56,6 +72,11 @@ const { direction } = resolveLanguage(currentLocale)
|
|
|
56
72
|
<head>
|
|
57
73
|
<meta charset="UTF-8" />
|
|
58
74
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
75
|
+
{
|
|
76
|
+
(disallowSearchIndexing ?? config.disallowSearchIndexing) && (
|
|
77
|
+
<meta name="robots" content="noindex" />
|
|
78
|
+
)
|
|
79
|
+
}
|
|
59
80
|
{CustomHead && <CustomHead />}
|
|
60
81
|
<title>{title ? `${title} | ${configTitle}` : configTitle}</title>
|
|
61
82
|
{description && <meta name="description" content={description} />}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
---
|
|
2
|
+
import { getLinkAttributes } from "../../../utils/link-attributes"
|
|
3
|
+
import LightNetLogo from "./LightNetLogo.svg"
|
|
4
|
+
|
|
5
|
+
const { t } = Astro.locals.i18n
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
<a
|
|
9
|
+
class="inline-flex items-center gap-2 whitespace-nowrap underline-offset-4 hover:underline"
|
|
10
|
+
{...getLinkAttributes("https://lightnet.community")}
|
|
11
|
+
>
|
|
12
|
+
<img src={LightNetLogo.src} alt="" class="h-5 w-auto" loading="lazy" />
|
|
13
|
+
<span>{t("ln.footer.powered-by-lightnet")}</span>
|
|
14
|
+
</a>
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
---
|
|
2
|
+
import config from "virtual:lightnet/config"
|
|
3
|
+
|
|
4
|
+
import { getLinkAttributes } from "../../../utils/link-attributes"
|
|
5
|
+
import { localizePath } from "../../../utils/paths"
|
|
6
|
+
import Credits from "./Credits.astro"
|
|
7
|
+
import { formatFooterText } from "./format-footer-text"
|
|
8
|
+
import LanguageSelectionMenu from "./LanguageSelectionMenu.astro"
|
|
9
|
+
|
|
10
|
+
const { tConfigField, currentLocale } = Astro.locals.i18n
|
|
11
|
+
|
|
12
|
+
// Resolve optional footer text for the current locale.
|
|
13
|
+
const footerText = config.footerText
|
|
14
|
+
? formatFooterText(tConfigField(config.footerText, config))
|
|
15
|
+
: undefined
|
|
16
|
+
|
|
17
|
+
// Prepare footer links using the same locale rules as the main menu.
|
|
18
|
+
const footerLinks = (config.footerLinks ?? []).map(
|
|
19
|
+
({ href, label, requiresLocale }) => {
|
|
20
|
+
return {
|
|
21
|
+
href: requiresLocale ? localizePath(currentLocale, href) : href,
|
|
22
|
+
label: tConfigField(label, config),
|
|
23
|
+
}
|
|
24
|
+
},
|
|
25
|
+
)
|
|
26
|
+
|
|
27
|
+
const shouldShowLanguageSelectionMenu = config.locales.length > 1
|
|
28
|
+
|
|
29
|
+
// Hide the footer entirely when there is nothing to show.
|
|
30
|
+
const shouldRenderFooter =
|
|
31
|
+
config.credits ||
|
|
32
|
+
!!footerText ||
|
|
33
|
+
footerLinks.length > 0 ||
|
|
34
|
+
shouldShowLanguageSelectionMenu
|
|
35
|
+
|
|
36
|
+
if (!shouldRenderFooter) {
|
|
37
|
+
return
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
const footerItems = [
|
|
41
|
+
...(footerText ? [{ type: "text" as const, label: footerText }] : []),
|
|
42
|
+
...footerLinks.map((link) => ({ type: "link" as const, ...link })),
|
|
43
|
+
]
|
|
44
|
+
---
|
|
45
|
+
|
|
46
|
+
<footer class="w-full border-t border-gray-200 bg-white text-sm text-gray-800">
|
|
47
|
+
<div
|
|
48
|
+
class="mx-auto flex w-full max-w-screen-xl px-4 py-4 md:px-8 md:py-6"
|
|
49
|
+
class:list={footerItems.length === 0
|
|
50
|
+
? "flex-col justify-between gap-4 sm:flex-row sm:items-center"
|
|
51
|
+
: "flex-col gap-2"}
|
|
52
|
+
>
|
|
53
|
+
{shouldShowLanguageSelectionMenu && <LanguageSelectionMenu />}
|
|
54
|
+
{
|
|
55
|
+
(footerItems.length > 0 || config.credits) && (
|
|
56
|
+
<div class="flex shrink flex-col gap-6 md:flex-row md:items-start md:justify-between">
|
|
57
|
+
{footerItems.length > 0 && (
|
|
58
|
+
<div class="flex w-full min-w-0 flex-1 shrink flex-wrap">
|
|
59
|
+
{footerItems.map((item, index) => (
|
|
60
|
+
<span class="inline-flex">
|
|
61
|
+
{item.type === "text" ? (
|
|
62
|
+
<span>{item.label}</span>
|
|
63
|
+
) : (
|
|
64
|
+
<a
|
|
65
|
+
{...getLinkAttributes(item.href)}
|
|
66
|
+
class="underline-offset-4 hover:underline"
|
|
67
|
+
>
|
|
68
|
+
{item.label}
|
|
69
|
+
</a>
|
|
70
|
+
)}
|
|
71
|
+
{index !== footerItems.length - 1 && (
|
|
72
|
+
<span
|
|
73
|
+
class="shrink-0 px-2 text-gray-400"
|
|
74
|
+
aria-hidden="true"
|
|
75
|
+
>
|
|
76
|
+
·
|
|
77
|
+
</span>
|
|
78
|
+
)}
|
|
79
|
+
</span>
|
|
80
|
+
))}
|
|
81
|
+
</div>
|
|
82
|
+
)}
|
|
83
|
+
{config.credits && <Credits />}
|
|
84
|
+
</div>
|
|
85
|
+
)
|
|
86
|
+
}
|
|
87
|
+
</div>
|
|
88
|
+
</footer>
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
---
|
|
2
|
+
import { GlobeIcon } from "lucide-react"
|
|
3
|
+
|
|
4
|
+
import { getLanguageSelectionMenuItems } from "../get-language-selection-menu-items"
|
|
5
|
+
|
|
6
|
+
const { t, tConfigField, currentLocale } = Astro.locals.i18n
|
|
7
|
+
|
|
8
|
+
const { links: languageMenuItems } = getLanguageSelectionMenuItems({
|
|
9
|
+
currentLocale,
|
|
10
|
+
pathname: Astro.url.pathname,
|
|
11
|
+
tConfigField,
|
|
12
|
+
})
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
<label class="inline-flex items-center gap-2 py-2 font-medium">
|
|
16
|
+
<GlobeIcon className="h-5 w-5 shrink-0 text-gray-600" aria-hidden="true" />
|
|
17
|
+
<span class="sr-only">{t("ln.select-language")}</span>
|
|
18
|
+
<select
|
|
19
|
+
class="min-w-0 cursor-pointer appearance-none border-0 bg-transparent p-0 pr-0 outline-none focus:ring-0"
|
|
20
|
+
aria-label={t("ln.select-language")}
|
|
21
|
+
data-footer-language-select
|
|
22
|
+
>
|
|
23
|
+
{
|
|
24
|
+
languageMenuItems.map(({ href, label, locale, active }) => (
|
|
25
|
+
<option value={href} selected={active} lang={locale}>
|
|
26
|
+
{label}
|
|
27
|
+
</option>
|
|
28
|
+
))
|
|
29
|
+
}
|
|
30
|
+
</select>
|
|
31
|
+
</label>
|
|
32
|
+
<script>
|
|
33
|
+
const footerLanguageSelect = document.querySelector<HTMLSelectElement>(
|
|
34
|
+
"[data-footer-language-select]",
|
|
35
|
+
)
|
|
36
|
+
|
|
37
|
+
footerLanguageSelect?.addEventListener("change", () => {
|
|
38
|
+
if (!footerLanguageSelect.value) {
|
|
39
|
+
return
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
window.location.assign(footerLanguageSelect.value)
|
|
43
|
+
})
|
|
44
|
+
</script>
|
|
@@ -1 +1 @@
|
|
|
1
|
-
<svg viewBox="16 16 141 173" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M88.007 180.642c-21.767-5.846-39.688-19.304-40.574-42.862-.887-23.558 17.751-43.334 45.426-40.84v-7.844c.011-4.03 4.977-5.495 8.021-2.928l29.136 23.729c2.155 1.821 2.15 5.16-.019 7.08l-29.117 24.152c-3.059 2.72-8.031.681-8.02-3.349v-8.005c-2.916-.453-5.137-.579-6.708-.453-25.207 2.016-23.083 44.6 20.454 42.388 18.705-.951 49.148-21.73 50.394-53.985 0-48.62-60.4-64.433-45.205-97.762 1.529-3.354-4.627-4.867-8.501-3.393-15.573 4.29-32.752 13.714-42.526 41.693-1.251 3.581-2.824 12.038-4.168 15.558-1.242 3.533-3.034 11.445-7.996 11.025-6.501-.55-4.236-11.168-2.815-15.74 1.197-3.854-4.14-7.109-9.028-2.073-8.3 8.549-16.598 19.982-19.804 37.823-1.259 7.001-1.327 16.903.101 25.208 6.204 36.183 37.705 59.276 68.356 58.915 7.58-.09 7.787-6.942 2.593-8.337Z" fill="#
|
|
1
|
+
<svg viewBox="16 16 141 173" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M88.007 180.642c-21.767-5.846-39.688-19.304-40.574-42.862-.887-23.558 17.751-43.334 45.426-40.84v-7.844c.011-4.03 4.977-5.495 8.021-2.928l29.136 23.729c2.155 1.821 2.15 5.16-.019 7.08l-29.117 24.152c-3.059 2.72-8.031.681-8.02-3.349v-8.005c-2.916-.453-5.137-.579-6.708-.453-25.207 2.016-23.083 44.6 20.454 42.388 18.705-.951 49.148-21.73 50.394-53.985 0-48.62-60.4-64.433-45.205-97.762 1.529-3.354-4.627-4.867-8.501-3.393-15.573 4.29-32.752 13.714-42.526 41.693-1.251 3.581-2.824 12.038-4.168 15.558-1.242 3.533-3.034 11.445-7.996 11.025-6.501-.55-4.236-11.168-2.815-15.74 1.197-3.854-4.14-7.109-9.028-2.073-8.3 8.549-16.598 19.982-19.804 37.823-1.259 7.001-1.327 16.903.101 25.208 6.204 36.183 37.705 59.276 68.356 58.915 7.58-.09 7.787-6.942 2.593-8.337Z" fill="#4b5563"/></svg>
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
import { GlobeIcon } from "lucide-react"
|
|
3
3
|
|
|
4
|
-
import { getLanguageSelectionMenuItems } from "
|
|
4
|
+
import { getLanguageSelectionMenuItems } from "../get-language-selection-menu-items"
|
|
5
5
|
import Menu from "./Menu.astro"
|
|
6
6
|
import MenuItem from "./MenuItem.astro"
|
|
7
7
|
|
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
import { ExternalLinkIcon, MenuIcon, SearchIcon } from "lucide-react"
|
|
3
3
|
import config from "virtual:lightnet/config"
|
|
4
4
|
|
|
5
|
-
import { isExternalUrl } from "
|
|
6
|
-
import { localizePath, searchPagePath } from "
|
|
7
|
-
import
|
|
5
|
+
import { isExternalUrl } from "../../../utils/is-external-url"
|
|
6
|
+
import { localizePath, searchPagePath } from "../../../utils/paths"
|
|
7
|
+
import LanguageSelectionMenu from "./LanguageSelectionMenu.astro"
|
|
8
8
|
import Menu from "./Menu.astro"
|
|
9
9
|
import MenuItem from "./MenuItem.astro"
|
|
10
10
|
|
|
@@ -40,7 +40,7 @@ const items = (config.mainMenu ?? []).map(({ href, label, requiresLocale }) => {
|
|
|
40
40
|
)
|
|
41
41
|
}
|
|
42
42
|
|
|
43
|
-
<
|
|
43
|
+
<LanguageSelectionMenu />
|
|
44
44
|
|
|
45
45
|
{
|
|
46
46
|
!!items.length && (
|
|
@@ -4,7 +4,7 @@ import { Image } from "astro:assets"
|
|
|
4
4
|
import config from "virtual:lightnet/config"
|
|
5
5
|
import logo from "virtual:lightnet/logo"
|
|
6
6
|
|
|
7
|
-
import { localizePath } from "
|
|
7
|
+
import { localizePath } from "../../../utils/paths"
|
|
8
8
|
|
|
9
9
|
function getWidth(logo: ImageMetadata) {
|
|
10
10
|
const size = config.logo?.size ?? 28
|
|
@@ -1,149 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
import { GlobeIcon } from "lucide-react"
|
|
3
|
-
import config from "virtual:lightnet/config"
|
|
4
|
-
|
|
5
|
-
import { getLinkAttributes } from "../../utils/link-attributes"
|
|
6
|
-
import { localizePath } from "../../utils/paths"
|
|
7
|
-
import { formatFooterText } from "./format-footer-text"
|
|
8
|
-
import { getLanguageSelectionMenuItems } from "./get-language-selection-menu-items"
|
|
9
|
-
import LightNetLogo from "./LightNetLogo.svg"
|
|
10
|
-
|
|
11
|
-
const { t, tConfigField, currentLocale } = Astro.locals.i18n
|
|
12
|
-
|
|
13
|
-
// Resolve optional footer text for the current locale.
|
|
14
|
-
const footerText = config.footerText
|
|
15
|
-
? formatFooterText(tConfigField(config.footerText, config))
|
|
16
|
-
: undefined
|
|
17
|
-
|
|
18
|
-
// Prepare footer links using the same locale rules as the main menu.
|
|
19
|
-
const footerLinks = (config.footerLinks ?? []).map(
|
|
20
|
-
({ href, label, requiresLocale }) => {
|
|
21
|
-
return {
|
|
22
|
-
href: requiresLocale ? localizePath(currentLocale, href) : href,
|
|
23
|
-
label: tConfigField(label, config),
|
|
24
|
-
}
|
|
25
|
-
},
|
|
26
|
-
)
|
|
27
|
-
|
|
28
|
-
const { links: languageMenuItems } = getLanguageSelectionMenuItems({
|
|
29
|
-
currentLocale,
|
|
30
|
-
pathname: Astro.url.pathname,
|
|
31
|
-
tConfigField,
|
|
32
|
-
})
|
|
33
|
-
|
|
34
|
-
const shouldShowLanguageSelector = languageMenuItems.length > 1
|
|
35
|
-
|
|
36
|
-
// Hide the footer entirely when there is nothing to show.
|
|
37
|
-
const shouldRenderFooter =
|
|
38
|
-
config.credits ||
|
|
39
|
-
!!footerText ||
|
|
40
|
-
footerLinks.length > 0 ||
|
|
41
|
-
shouldShowLanguageSelector
|
|
42
|
-
|
|
43
|
-
if (!shouldRenderFooter) {
|
|
44
|
-
return
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
const footerItems = [
|
|
48
|
-
...(footerText ? [{ type: "text" as const, label: footerText }] : []),
|
|
49
|
-
...footerLinks.map((link) => ({ type: "link" as const, ...link })),
|
|
50
|
-
]
|
|
51
|
-
---
|
|
52
|
-
|
|
53
|
-
<footer class="w-full border-t border-gray-200 bg-white">
|
|
54
|
-
<div class="mx-auto w-full max-w-screen-xl px-4 md:px-8">
|
|
55
|
-
<div class="flex flex-col gap-4 py-6">
|
|
56
|
-
{
|
|
57
|
-
shouldShowLanguageSelector && (
|
|
58
|
-
<div class="flex w-full justify-start">
|
|
59
|
-
<label class="inline-flex items-center gap-2 bg-white py-2 text-sm text-gray-800">
|
|
60
|
-
<GlobeIcon
|
|
61
|
-
className="h-4 w-4 shrink-0 text-gray-500"
|
|
62
|
-
aria-hidden="true"
|
|
63
|
-
/>
|
|
64
|
-
<span class="sr-only">{t("ln.select-language")}</span>
|
|
65
|
-
<select
|
|
66
|
-
class="min-w-0 cursor-pointer appearance-none border-0 bg-transparent p-0 pr-0 text-sm font-medium text-gray-800 outline-none focus:ring-0"
|
|
67
|
-
aria-label={t("ln.select-language")}
|
|
68
|
-
data-footer-language-select
|
|
69
|
-
>
|
|
70
|
-
{languageMenuItems.map(({ href, label, locale, active }) => (
|
|
71
|
-
<option value={href} selected={active} lang={locale}>
|
|
72
|
-
{label}
|
|
73
|
-
</option>
|
|
74
|
-
))}
|
|
75
|
-
</select>
|
|
76
|
-
</label>
|
|
77
|
-
</div>
|
|
78
|
-
)
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
<div
|
|
82
|
-
class="flex w-full flex-col gap-4 text-sm text-gray-800 md:flex-row md:items-center md:justify-between md:gap-6"
|
|
83
|
-
>
|
|
84
|
-
{
|
|
85
|
-
footerItems.length > 0 && (
|
|
86
|
-
<div class="flex w-full flex-row flex-wrap items-center gap-x-2 gap-y-1 md:w-auto">
|
|
87
|
-
{footerItems.map((item, index) => (
|
|
88
|
-
<span class="inline-flex items-center gap-1.5">
|
|
89
|
-
<span
|
|
90
|
-
class:list={[
|
|
91
|
-
"w-3 shrink-0 justify-center text-center text-[0.8em] leading-none text-gray-400",
|
|
92
|
-
index === 0 ? "hidden" : "inline-flex",
|
|
93
|
-
]}
|
|
94
|
-
aria-hidden="true"
|
|
95
|
-
>
|
|
96
|
-
·
|
|
97
|
-
</span>
|
|
98
|
-
{item.type === "text" ? (
|
|
99
|
-
<span class="text-gray-800">{item.label}</span>
|
|
100
|
-
) : (
|
|
101
|
-
<a
|
|
102
|
-
{...getLinkAttributes(item.href)}
|
|
103
|
-
class="text-gray-800 underline-offset-4 hover:underline"
|
|
104
|
-
>
|
|
105
|
-
{item.label}
|
|
106
|
-
</a>
|
|
107
|
-
)}
|
|
108
|
-
</span>
|
|
109
|
-
))}
|
|
110
|
-
</div>
|
|
111
|
-
)
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
{
|
|
115
|
-
config.credits && (
|
|
116
|
-
<div class="flex w-full items-center justify-start md:w-auto md:justify-end">
|
|
117
|
-
<a
|
|
118
|
-
class="flex items-center gap-2 whitespace-nowrap text-gray-800 underline-offset-4 hover:underline"
|
|
119
|
-
{...getLinkAttributes("https://lightnet.community")}
|
|
120
|
-
>
|
|
121
|
-
<img
|
|
122
|
-
src={LightNetLogo.src}
|
|
123
|
-
alt=""
|
|
124
|
-
class="h-5 w-auto"
|
|
125
|
-
loading="lazy"
|
|
126
|
-
/>
|
|
127
|
-
<span>{t("ln.footer.powered-by-lightnet")}</span>
|
|
128
|
-
</a>
|
|
129
|
-
</div>
|
|
130
|
-
)
|
|
131
|
-
}
|
|
132
|
-
</div>
|
|
133
|
-
</div>
|
|
134
|
-
</div>
|
|
135
|
-
</footer>
|
|
136
|
-
|
|
137
|
-
<script>
|
|
138
|
-
const footerLanguageSelect = document.querySelector<HTMLSelectElement>(
|
|
139
|
-
"[data-footer-language-select]",
|
|
140
|
-
)
|
|
141
|
-
|
|
142
|
-
footerLanguageSelect?.addEventListener("change", () => {
|
|
143
|
-
if (!footerLanguageSelect.value) {
|
|
144
|
-
return
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
window.location.assign(footerLanguageSelect.value)
|
|
148
|
-
})
|
|
149
|
-
</script>
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|