From a2b418b78aadc246737783f7763c5cdc37bb1bc7 Mon Sep 17 00:00:00 2001 From: Ivan Fontosh Date: Tue, 28 Jul 2026 12:13:53 +0800 Subject: [PATCH] feat(help): traps/tokens/grid sections and clickable cross-links Add instruction pages for traps, non-player tokens, and grid generator, and turn section mentions into in-modal navigation links. Co-authored-by: Cursor --- app/renderer/editor/EditorApp.module.css | 18 +++ .../editor/about/EditorAboutModals.tsx | 41 ++++++- app/renderer/editor/help/helpLinkify.test.ts | 82 +++++++++++++ app/renderer/editor/help/helpLinkify.ts | 115 ++++++++++++++++++ app/renderer/editor/help/helpSections.ts | 3 + app/renderer/editor/i18n/editorMessages.ts | 44 +++++-- package.json | 2 +- 7 files changed, 289 insertions(+), 16 deletions(-) create mode 100644 app/renderer/editor/help/helpLinkify.test.ts create mode 100644 app/renderer/editor/help/helpLinkify.ts diff --git a/app/renderer/editor/EditorApp.module.css b/app/renderer/editor/EditorApp.module.css index 5dd61c3..d966fc8 100644 --- a/app/renderer/editor/EditorApp.module.css +++ b/app/renderer/editor/EditorApp.module.css @@ -495,6 +495,24 @@ margin-bottom: 0; } +.instructionsInlineLink { + display: inline; + margin: 0; + padding: 0; + border: none; + background: none; + color: var(--accent, #a78bfa); + font: inherit; + font-weight: 700; + text-decoration: underline; + text-underline-offset: 2px; + cursor: pointer; +} + +.instructionsInlineLink:hover { + color: var(--text0); +} + .instructionsNav { min-height: 0; overflow: auto; diff --git a/app/renderer/editor/about/EditorAboutModals.tsx b/app/renderer/editor/about/EditorAboutModals.tsx index e6b0611..fca2ec7 100644 --- a/app/renderer/editor/about/EditorAboutModals.tsx +++ b/app/renderer/editor/about/EditorAboutModals.tsx @@ -1,9 +1,10 @@ -import React, { useEffect, useState } from 'react'; +import React, { useEffect, useMemo, useRef, useState } from 'react'; import { createPortal } from 'react-dom'; import { APP_DISPLAY_NAME_EN, APP_DISPLAY_NAME_RU } from '../../../shared/appBranding'; import { Button } from '../../shared/ui/controls'; import styles from '../EditorApp.module.css'; +import { buildHelpLinkCatalog, splitHelpTextWithLinks } from '../help/helpLinkify'; import { HELP_SECTION_IDS, helpSectionBodyKey, @@ -107,6 +108,8 @@ function InstructionsModalBody({ }) { const { t } = useEditorI18n(); const [activeId, setActiveId] = useState(initialSection); + const contentRef = useRef(null); + const navRef = useRef(null); useEffect(() => { const onKey = (e: KeyboardEvent) => { @@ -116,9 +119,24 @@ function InstructionsModalBody({ return () => window.removeEventListener('keydown', onKey); }, [onClose]); + useEffect(() => { + contentRef.current?.scrollTo({ top: 0 }); + const activeNav = navRef.current?.querySelector('[aria-current="true"]'); + activeNav?.scrollIntoView({ block: 'nearest' }); + }, [activeId]); + + const linkCatalog = useMemo( + () => buildHelpLinkCatalog((id) => t(helpSectionTitleKey(id))), + [t], + ); + const body = t(helpSectionBodyKey(activeId)); const paragraphs = body.split('\n\n').filter((p) => p.trim() !== ''); + const goToSection = (id: HelpSectionId) => { + setActiveId(id); + }; + return createPortal( <> + ), + )}

))} -