mirror of
https://github.com/mleem97/gregWiki.git
synced 2026-04-11 03:29:19 +02:00
docs(readme): update README for clarity and consistency
- Translated sections from German to English for better accessibility. - Enhanced the structure by clearly defining the workspace relationship and local development instructions. - Improved descriptions for Docker setup and deployment processes to ensure users understand the requirements and context. - Updated links and formatting for consistency throughout the document. This commit aims to improve the overall clarity and usability of the README documentation.
This commit is contained in:
@@ -147,7 +147,14 @@ body {
|
||||
color: var(--color-on-surface);
|
||||
}
|
||||
|
||||
.navbar__item .navbar__link {
|
||||
.navbar__items--right {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.45rem;
|
||||
}
|
||||
|
||||
.navbar__item .navbar__link,
|
||||
.navbar__item.navbar__link {
|
||||
font-family: var(--font-headline);
|
||||
font-weight: 500;
|
||||
letter-spacing: 0.06em;
|
||||
@@ -157,11 +164,13 @@ body {
|
||||
transition: color 0.25s ease;
|
||||
}
|
||||
|
||||
.navbar__item .navbar__link:hover {
|
||||
.navbar__item .navbar__link:hover,
|
||||
.navbar__item.navbar__link:hover {
|
||||
color: var(--color-on-surface);
|
||||
}
|
||||
|
||||
.navbar__item .navbar__link--active {
|
||||
.navbar__item .navbar__link--active,
|
||||
.navbar__item.navbar__link--active {
|
||||
color: var(--color-primary);
|
||||
box-shadow: inset 0 -2px 0 0 var(--color-primary);
|
||||
}
|
||||
@@ -175,41 +184,40 @@ body {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 2.25rem;
|
||||
height: 2.25rem;
|
||||
min-width: 2.25rem;
|
||||
min-height: 2.25rem;
|
||||
padding: 0;
|
||||
border-radius: 999px;
|
||||
backdrop-filter: blur(12px);
|
||||
background: rgba(0, 30, 28, 0.65);
|
||||
box-shadow: inset 0 0 0 1px rgba(15, 81, 76, 0.15);
|
||||
}
|
||||
|
||||
.nav-icon-only {
|
||||
color: transparent;
|
||||
}
|
||||
|
||||
.nav-icon-only::before {
|
||||
font-size: 0.95rem;
|
||||
.nav-right-icon.nav-icon-only {
|
||||
color: var(--color-on-surface-variant);
|
||||
}
|
||||
|
||||
.nav-link-mods::before {
|
||||
content: '🧩';
|
||||
.nav-right-icon.nav-icon-only:hover,
|
||||
.nav-right-icon.nav-icon-only:focus-visible {
|
||||
color: var(--color-on-surface);
|
||||
}
|
||||
|
||||
.nav-link-discord::before {
|
||||
content: '💬';
|
||||
.nav-icon-svg {
|
||||
flex-shrink: 0;
|
||||
display: block;
|
||||
color: currentColor;
|
||||
}
|
||||
|
||||
.nav-link-support::before {
|
||||
content: '🛟';
|
||||
}
|
||||
|
||||
.nav-link-github::before {
|
||||
content: '⌁';
|
||||
}
|
||||
|
||||
.nav-locale::before {
|
||||
content: '🌐';
|
||||
.nav-icon-sr-only {
|
||||
position: absolute;
|
||||
width: 1px;
|
||||
height: 1px;
|
||||
padding: 0;
|
||||
margin: -1px;
|
||||
overflow: hidden;
|
||||
clip: rect(0, 0, 0, 0);
|
||||
white-space: nowrap;
|
||||
border: 0;
|
||||
}
|
||||
|
||||
/* Editorial bleed + hero (homepage) */
|
||||
@@ -423,11 +431,7 @@ body {
|
||||
|
||||
/* Doc canvas — editorial bleed (wiki layout alignment); no hard section borders */
|
||||
.theme-doc-wrapper {
|
||||
background: linear-gradient(
|
||||
180deg,
|
||||
var(--color-surface-container-low) 0%,
|
||||
var(--color-background) 42%
|
||||
);
|
||||
background: linear-gradient(180deg, var(--color-surface-container-low) 0%, var(--color-background) 42%);
|
||||
}
|
||||
|
||||
.theme-doc-root .theme-doc-sidebar-container {
|
||||
@@ -562,27 +566,22 @@ body {
|
||||
color: var(--color-primary);
|
||||
}
|
||||
|
||||
.footer-link-icon {
|
||||
position: relative;
|
||||
padding-left: 1.4rem;
|
||||
.footer-link-with-icon {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 0.4rem;
|
||||
}
|
||||
|
||||
.footer-link-icon::before {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
opacity: 0.9;
|
||||
.footer-icon-svg {
|
||||
flex-shrink: 0;
|
||||
opacity: 0.85;
|
||||
color: rgba(192, 252, 246, 0.45);
|
||||
transition: color 0.2s ease, opacity 0.2s ease;
|
||||
}
|
||||
|
||||
.footer-link-github::before {
|
||||
content: '⌁';
|
||||
}
|
||||
|
||||
.footer-link-discord::before {
|
||||
content: '💬';
|
||||
}
|
||||
|
||||
.footer-link-support::before {
|
||||
content: '🛟';
|
||||
.footer__link-item:hover .footer-icon-svg {
|
||||
opacity: 1;
|
||||
color: var(--color-primary);
|
||||
}
|
||||
|
||||
.button.button--primary {
|
||||
|
||||
@@ -36,12 +36,12 @@ export const sharedWorkflowLinksEn: HomepageDocLink[] = [
|
||||
{
|
||||
title: 'End-user docs',
|
||||
description: 'Install, update, and troubleshooting paths.',
|
||||
link: '/wiki/legacy/wiki-import/EndUser/End-User-Release',
|
||||
link: '/wiki/guides/players/overview',
|
||||
},
|
||||
{
|
||||
title: 'Mod developer docs',
|
||||
description: 'Setup, debugging, and hook integration.',
|
||||
link: '/wiki/legacy/wiki-import/ModDevs/Mod-Developer-Debug',
|
||||
link: '/wiki/guides/mod-developers/overview',
|
||||
},
|
||||
{
|
||||
title: 'Repo inventory',
|
||||
@@ -95,12 +95,12 @@ export const sharedWorkflowLinksDe: HomepageDocLink[] = [
|
||||
{
|
||||
title: 'Endnutzer-Doku',
|
||||
description: 'Installation, Updates und Fehlerbehebung.',
|
||||
link: '/wiki/legacy/wiki-import/EndUser/End-User-Release',
|
||||
link: '/wiki/guides/players/overview',
|
||||
},
|
||||
{
|
||||
title: 'Mod-Entwickler-Doku',
|
||||
description: 'Setup, Debugging und Hook-Integration.',
|
||||
link: '/wiki/legacy/wiki-import/ModDevs/Mod-Developer-Debug',
|
||||
link: '/wiki/guides/mod-developers/overview',
|
||||
},
|
||||
{
|
||||
title: 'Repo-Inventar',
|
||||
|
||||
63
src/theme/Footer/LinkItem/index.tsx
Normal file
63
src/theme/Footer/LinkItem/index.tsx
Normal file
@@ -0,0 +1,63 @@
|
||||
/**
|
||||
* Swizzled: community footer links use react-icons instead of emoji/CSS pseudo-elements.
|
||||
*/
|
||||
import React, {type ReactNode} from 'react';
|
||||
import clsx from 'clsx';
|
||||
import Link from '@docusaurus/Link';
|
||||
import useBaseUrl from '@docusaurus/useBaseUrl';
|
||||
import isInternalUrl from '@docusaurus/isInternalUrl';
|
||||
import IconExternalLink from '@theme/Icon/ExternalLink';
|
||||
import type {Props} from '@theme/Footer/LinkItem';
|
||||
import {FaDiscord, FaGithub, FaLifeRing} from 'react-icons/fa6';
|
||||
|
||||
const footerIconProps = {
|
||||
className: 'footer-icon-svg',
|
||||
'aria-hidden': true as const,
|
||||
size: 14,
|
||||
};
|
||||
|
||||
function getFooterIcon(className?: string): ReactNode | null {
|
||||
if (!className) {
|
||||
return null;
|
||||
}
|
||||
if (className.includes('footer-link-github')) {
|
||||
return <FaGithub {...footerIconProps} />;
|
||||
}
|
||||
if (className.includes('footer-link-discord')) {
|
||||
return <FaDiscord {...footerIconProps} />;
|
||||
}
|
||||
if (className.includes('footer-link-support')) {
|
||||
return <FaLifeRing {...footerIconProps} />;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
export default function FooterLinkItem({item}: Props): ReactNode {
|
||||
const {to, href, label, prependBaseUrlToHref, className, ...props} = item;
|
||||
const toUrl = useBaseUrl(to);
|
||||
const normalizedHref = useBaseUrl(href, {forcePrependBaseUrl: true});
|
||||
const icon = getFooterIcon(className);
|
||||
|
||||
return (
|
||||
<Link
|
||||
className={clsx('footer__link-item', className)}
|
||||
{...(href
|
||||
? {
|
||||
href: prependBaseUrlToHref ? normalizedHref : href,
|
||||
}
|
||||
: {
|
||||
to: toUrl,
|
||||
})}
|
||||
{...props}>
|
||||
{icon ? (
|
||||
<span className="footer-link-with-icon">
|
||||
{icon}
|
||||
<span>{label}</span>
|
||||
</span>
|
||||
) : (
|
||||
label
|
||||
)}
|
||||
{href && !isInternalUrl(href) && <IconExternalLink />}
|
||||
</Link>
|
||||
);
|
||||
}
|
||||
132
src/theme/NavbarItem/LocaleDropdownNavbarItem/index.tsx
Normal file
132
src/theme/NavbarItem/LocaleDropdownNavbarItem/index.tsx
Normal file
@@ -0,0 +1,132 @@
|
||||
/**
|
||||
* Swizzled: language control uses react-icons; compact desktop label matches icon-only navbar style.
|
||||
*/
|
||||
import React, {type ReactNode} from 'react';
|
||||
import useDocusaurusContext from '@docusaurus/useDocusaurusContext';
|
||||
import {useAlternatePageUtils} from '@docusaurus/theme-common/internal';
|
||||
import {translate} from '@docusaurus/Translate';
|
||||
import {mergeSearchStrings, useHistorySelector} from '@docusaurus/theme-common';
|
||||
import DropdownNavbarItem from '@theme/NavbarItem/DropdownNavbarItem';
|
||||
import type {LinkLikeNavbarItemProps} from '@theme/NavbarItem';
|
||||
import type {Props} from '@theme/NavbarItem/LocaleDropdownNavbarItem';
|
||||
import {IoLanguage} from 'react-icons/io5';
|
||||
|
||||
import styles from './styles.module.css';
|
||||
|
||||
function useLocaleDropdownUtils() {
|
||||
const {
|
||||
siteConfig,
|
||||
i18n: {localeConfigs},
|
||||
} = useDocusaurusContext();
|
||||
const alternatePageUtils = useAlternatePageUtils();
|
||||
const search = useHistorySelector((history) => history.location.search);
|
||||
const hash = useHistorySelector((history) => history.location.hash);
|
||||
|
||||
const getLocaleConfig = (locale: string) => {
|
||||
const localeConfig = localeConfigs[locale];
|
||||
if (!localeConfig) {
|
||||
throw new Error(
|
||||
`Docusaurus bug, no locale config found for locale=${locale}`,
|
||||
);
|
||||
}
|
||||
return localeConfig;
|
||||
};
|
||||
|
||||
const getBaseURLForLocale = (locale: string) => {
|
||||
const localeConfig = getLocaleConfig(locale);
|
||||
const isSameDomain = localeConfig.url === siteConfig.url;
|
||||
if (isSameDomain) {
|
||||
return `pathname://${alternatePageUtils.createUrl({
|
||||
locale,
|
||||
fullyQualified: false,
|
||||
})}`;
|
||||
}
|
||||
return alternatePageUtils.createUrl({
|
||||
locale,
|
||||
fullyQualified: true,
|
||||
});
|
||||
};
|
||||
|
||||
return {
|
||||
getURL: (locale: string, options: {queryString: string | undefined}) => {
|
||||
const finalSearch = mergeSearchStrings(
|
||||
[search, options.queryString],
|
||||
'append',
|
||||
);
|
||||
return `${getBaseURLForLocale(locale)}${finalSearch}${hash}`;
|
||||
},
|
||||
getLabel: (locale: string) => {
|
||||
return getLocaleConfig(locale).label;
|
||||
},
|
||||
getLang: (locale: string) => {
|
||||
return getLocaleConfig(locale).htmlLang;
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
export default function LocaleDropdownNavbarItem({
|
||||
mobile,
|
||||
dropdownItemsBefore,
|
||||
dropdownItemsAfter,
|
||||
queryString,
|
||||
className,
|
||||
...props
|
||||
}: Props): ReactNode {
|
||||
const utils = useLocaleDropdownUtils();
|
||||
|
||||
const {
|
||||
i18n: {currentLocale, locales},
|
||||
} = useDocusaurusContext();
|
||||
const localeItems = locales.map((locale): LinkLikeNavbarItemProps => {
|
||||
return {
|
||||
label: utils.getLabel(locale),
|
||||
lang: utils.getLang(locale),
|
||||
to: utils.getURL(locale, {queryString}),
|
||||
target: '_self',
|
||||
autoAddBaseUrl: false,
|
||||
className:
|
||||
locale === currentLocale
|
||||
? mobile
|
||||
? 'menu__link--active'
|
||||
: 'dropdown__link--active'
|
||||
: '',
|
||||
};
|
||||
});
|
||||
|
||||
const items = [...dropdownItemsBefore, ...localeItems, ...dropdownItemsAfter];
|
||||
|
||||
const dropdownLabel = mobile
|
||||
? translate({
|
||||
message: 'Languages',
|
||||
id: 'theme.navbar.mobileLanguageDropdown.label',
|
||||
description: 'The label for the mobile language switcher dropdown',
|
||||
})
|
||||
: utils.getLabel(currentLocale);
|
||||
|
||||
const iconOnlyDesktop =
|
||||
!mobile && String(className ?? '').includes('nav-icon-only');
|
||||
|
||||
const label: ReactNode = (
|
||||
<>
|
||||
<IoLanguage
|
||||
className={iconOnlyDesktop ? styles.iconOnly : styles.iconLanguage}
|
||||
aria-hidden
|
||||
/>
|
||||
{mobile || !iconOnlyDesktop ? (
|
||||
dropdownLabel
|
||||
) : (
|
||||
<span className="nav-icon-sr-only">{dropdownLabel}</span>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
|
||||
return (
|
||||
<DropdownNavbarItem
|
||||
{...props}
|
||||
className={className}
|
||||
mobile={mobile}
|
||||
label={label}
|
||||
items={items}
|
||||
/>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
/**
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
.iconLanguage {
|
||||
vertical-align: middle;
|
||||
margin-right: 5px;
|
||||
color: currentColor;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.iconOnly {
|
||||
vertical-align: middle;
|
||||
margin-right: 0;
|
||||
color: currentColor;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
117
src/theme/NavbarItem/NavbarNavLink.tsx
Normal file
117
src/theme/NavbarItem/NavbarNavLink.tsx
Normal file
@@ -0,0 +1,117 @@
|
||||
/**
|
||||
* Swizzled: icon-only navbar links use react-icons instead of CSS/emoji pseudo-elements.
|
||||
*/
|
||||
import React, {type ReactNode} from 'react';
|
||||
import Link from '@docusaurus/Link';
|
||||
import useBaseUrl from '@docusaurus/useBaseUrl';
|
||||
import isInternalUrl from '@docusaurus/isInternalUrl';
|
||||
import {isRegexpStringMatch} from '@docusaurus/theme-common';
|
||||
import IconExternalLink from '@theme/Icon/ExternalLink';
|
||||
import type {Props} from '@theme/NavbarItem/NavbarNavLink';
|
||||
import clsx from 'clsx';
|
||||
import {FaDiscord, FaGithub, FaLifeRing, FaPuzzlePiece} from 'react-icons/fa6';
|
||||
|
||||
const navIconProps = {
|
||||
className: 'nav-icon-svg',
|
||||
'aria-hidden': true as const,
|
||||
size: 18,
|
||||
};
|
||||
|
||||
function getNavIcon(className?: string): ReactNode | null {
|
||||
if (!className) {
|
||||
return null;
|
||||
}
|
||||
if (className.includes('nav-link-mods')) {
|
||||
return <FaPuzzlePiece {...navIconProps} />;
|
||||
}
|
||||
if (className.includes('nav-link-discord')) {
|
||||
return <FaDiscord {...navIconProps} />;
|
||||
}
|
||||
if (className.includes('nav-link-support')) {
|
||||
return <FaLifeRing {...navIconProps} />;
|
||||
}
|
||||
if (className.includes('nav-link-github')) {
|
||||
return <FaGithub {...navIconProps} />;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
function isIconOnlyClass(className?: string) {
|
||||
return Boolean(className?.includes('nav-icon-only'));
|
||||
}
|
||||
|
||||
export default function NavbarNavLink({
|
||||
activeBasePath,
|
||||
activeBaseRegex,
|
||||
to,
|
||||
href,
|
||||
label,
|
||||
html,
|
||||
isDropdownLink,
|
||||
prependBaseUrlToHref,
|
||||
className,
|
||||
...props
|
||||
}: Props): ReactNode {
|
||||
const toUrl = useBaseUrl(to);
|
||||
const activeBaseUrl = useBaseUrl(activeBasePath);
|
||||
const normalizedHref = useBaseUrl(href, {forcePrependBaseUrl: true});
|
||||
const cls = clsx(className);
|
||||
const navIcon = getNavIcon(cls);
|
||||
const iconOnly = isIconOnlyClass(cls) && Boolean(navIcon);
|
||||
const isExternalLink = Boolean(label && href && !isInternalUrl(href));
|
||||
|
||||
const linkContentProps = html
|
||||
? {dangerouslySetInnerHTML: {__html: html}}
|
||||
: iconOnly && navIcon
|
||||
? {
|
||||
children: (
|
||||
<>
|
||||
{navIcon}
|
||||
{typeof label === 'string' || typeof label === 'number' ? (
|
||||
<span className="nav-icon-sr-only">{label}</span>
|
||||
) : (
|
||||
label
|
||||
)}
|
||||
</>
|
||||
),
|
||||
}
|
||||
: {
|
||||
children: (
|
||||
<>
|
||||
{label}
|
||||
{isExternalLink && (
|
||||
<IconExternalLink
|
||||
{...(isDropdownLink && {width: 12, height: 12})}
|
||||
/>
|
||||
)}
|
||||
</>
|
||||
),
|
||||
};
|
||||
|
||||
if (href) {
|
||||
return (
|
||||
<Link
|
||||
href={prependBaseUrlToHref ? normalizedHref : href}
|
||||
className={className}
|
||||
{...props}
|
||||
{...linkContentProps}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<Link
|
||||
to={toUrl}
|
||||
isNavLink
|
||||
className={className}
|
||||
{...((activeBasePath || activeBaseRegex) && {
|
||||
isActive: (_match, location) =>
|
||||
activeBaseRegex
|
||||
? isRegexpStringMatch(activeBaseRegex, location.pathname)
|
||||
: location.pathname.startsWith(activeBaseUrl),
|
||||
})}
|
||||
{...props}
|
||||
{...linkContentProps}
|
||||
/>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user