Repository navigation
Tutorials
English · Español
Each of the four screens (Deck, Design, Library, Play) has a short guided tour: it darkens the window except one area, outlines that area and explains it in a card beside it, step by step. It opens by itself the first time the user enters a screen and the help button in the top bar replays it. It is pure frontend (src/features/tutorial/): no Rust command, no network, nothing stored in the deck.
| File | Responsibility |
|---|---|
src/features/tutorial/pasos.ts |
type Paso = { ancla?, titulo, texto } and PASOS: Record<Vista, Paso[]>, the steps of each screen. |
src/features/tutorial/tutorial.tsx |
Tutorial (mounted once), its inner Recorrido (the overlay and card), useTutorialInicial() (first-visit opening), and the helpers zona (measure an anchor) and sitioTarjeta (place the card). |
src/stores/ui-store.ts |
tutorial: Vista | null (the open tour), abrirTutorial(v), and the persisted preference tutorialesVistos: Vista[]. See State-Stores. |
src/features/shell/app-shell.tsx |
The help button (CircleHelp icon, tooltip "Tutorial de esta pantalla"), <Tutorial /> and the useTutorialInicial() call. See Settings-and-Shell. |
src/i18n/<code>/tutorial.json |
The tour's strings, an i18n area of its own in the 15 languages. See Internationalization. |
src/index.css |
[data-slot="tutorial-tarjeta"] shares the opaque-modal rule. See Themes-and-Skins. |
A step points at an area through an anchor: the value of a data-tutorial attribute on the element to outline. The tour finds it with document.querySelector('[data-tutorial="…"]'), so the screens import nothing from the tutorial and the tutorial imports no screen component; moving a panel only needs the attribute to move with it. A step without ancla (each tour's introduction) shows its card centred over a fully dimmed window. titulo and texto are Spanish source strings wrapped in paraTraducir (the table lives outside React) and translated with t() when shown.
Screen (Vista) |
Anchor | Title (English UI) | Element (file) |
|---|---|---|---|
deck |
none | Welcome to Proxy Builder | |
pestanas |
Four screens | the view ToggleGroup (shell/app-shell.tsx) |
|
nombre-deck |
The deck's name |
NombreDeck input (shell/app-shell.tsx) |
|
lista-cuadro |
The card list | list editor panel (decklist/decklist-panel.tsx) |
|
lista-opciones |
Import and options | options panel (decklist/decklist-panel.tsx) |
|
vista-barra |
The preview toolbar | toolbar (preview/preview-pane.tsx) |
|
vista-hojas |
The sheets | sheets area (preview/preview-pane.tsx) |
|
exportar-boton |
Export | export header and button (export/export-panel.tsx) |
|
exportar-ajustes |
How the paper comes out | settings sections (export/export-panel.tsx) |
|
ajustes |
Settings | Settings button (shell/app-shell.tsx) |
|
ayuda |
To go over it again | help button (shell/app-shell.tsx) |
|
disenar |
none | Design: the card editor | |
disenar-lista |
The deck's cards |
ListaCartas (disenar/lista-cartas.tsx) |
|
disenar-barra |
Deck tools | top toolbar (disenar/disenar-screen.tsx) |
|
disenar-vista |
The preview |
VistaPrevia (disenar/vista-previa.tsx) |
|
disenar-incidencias |
Warnings |
Incidencias (disenar/incidencias.tsx) |
|
disenar-formulario |
What you can change | the form Tabs (disenar/formulario.tsx) |
|
disenar-pie |
Save | save footer (disenar/disenar-screen.tsx) |
|
biblioteca |
none | The library | |
biblioteca-barra |
Search and sort |
BarraHerramientas (library/barra-herramientas.tsx) |
|
biblioteca-acciones |
New, import and space | its actions slot (library/barra-herramientas.tsx) |
|
biblioteca-lateral |
Tags and favourites |
BarraLateral (library/barra-lateral.tsx) |
|
biblioteca-decks |
Your decks | deck area (library/library-screen.tsx) |
|
mesa |
none | The game table | |
mesa-entrada |
Choose deck and format | the entrance (mesa/entrada.tsx) |
|
mesa-solitario |
Solitaire | the «Solitario» button (mesa/entrada.tsx) |
|
mesa-barra |
The table bar |
BarraMesa (mesa/barra-mesa.tsx) |
|
mesa-campo |
The battlefield | the battlefield layer (mesa/tablero.tsx) |
|
mesa-mano |
The hand | the hand label (mesa/tablero.tsx) |
|
mesa-biblioteca |
The library | the library zone (mesa/tablero.tsx) |
|
mesa-vida |
Your life |
VidaJugador (mesa/vida-jugador.tsx) |
|
mesa-tablero |
Shortcuts | the whole board (mesa/tablero.tsx) |
The texts describe what each area does in the current version (for example the card sizes in "How the paper comes out", or that split, aftermath and double-faced cards have one artwork per part in the Design preview step), so a feature change that alters an area should also update its step.
The Play tour mixes two screens: the entrance (no game open) and the table (a game open). Only the anchors of the one on screen exist, so the others show centred; the tour opens by itself the first time «Jugar» is entered, which is normally the entrance. Other table anchors exist for future steps or reuse (mesa-lista, the game list selector of the entrance, mesa-pila, mesa-fantasma, mesa-pasar, mesa-cementerio, mesa-exilio, mesa-mando, mesa-banquillo). The table elements are described in Game-Table.
flowchart LR
A["useUi().tutorial = vista"] --> B["Tutorial: Recorrido key=vista"]
B --> C["zona(ancla): getBoundingClientRect"]
C -->|found, at least 4 x 4 px| D["ring + box-shadow dims the rest"]
C -->|missing or hidden| E["full dim, card centred"]
D --> F["sitioTarjeta: right, left, below, above, else centre"]
E --> F
-
Portal into
document.body: afixed inset-0 z-[100]layer (data-tutorial-capa) that covers the window, so clicks outside the card do nothing. -
Highlight: a non-interactive box 6 px (
AIRE) larger than the area, with a primary ring and a0 0 0 9999pxblack shadow at 60 % that dims everything else. Without an area, a plain 60 % black layer. -
Card (
data-slot="tutorial-tarjeta",role="dialog",aria-modal, labelled by its title): 320 px wide (ANCHO).sitioTarjetatries, in order, to the right of the area, to the left, below and above, 14 px away (HUECO) and at least 16 px from the window edges (MARGEN), clamped along the other axis; if no side has room, centred. Its height is measured after each render so the placement uses the real size. -
Re-measuring: on every step change, a
ResizeObserveron the anchored element and the windowresizeevent, so dragging the resizable panels or resizing the window moves the outline and the card along. - Missing anchor: if the element is not in the DOM or is smaller than 4 x 4 px (for example a Design panel that is not rendered while no card is selected), the step still shows, centred.
- Controls: a "Step {a} of {b}" counter, Back (from step 2), Next (Finish on the last step) and an X ("Close the tutorial"). The main button takes the focus at each step, so Enter advances.
-
Keyboard: a
keydownlistener onwindowin the capture phase handles Escape (close), ArrowRight (next, or close on the last step) and ArrowLeft (back), and callspreventDefault+stopPropagationfor them. Why capture: the screens have their own arrow handlers (Alt+arrows in Design, selection in the sheets) and they must not react while the tour is open. Other keys pass through untouched. -
TutorialrendersRecorridowithkey={vista}, so opening another screen's tour starts from step 1.
-
abrirTutorial(v)setstutorialand, whenvis not null and not yet intutorialesVistos, appends it; then it saves the preferences. A tour therefore counts as seen as soon as it opens, even if the user closes it at the first step: it is offered once, never nagging.abrirTutorial(null)closes. -
tutorialesVistosis persisted with the other preferences inlocalStorage["proxybuilder.preferencias"]; the open tour (tutorial) is session-only. -
useTutorialInicial()(called byAppShell) watchesuseUi().vista. If that screen is not intutorialesVistosand no tour is open, it waits 700 ms (so the screen is painted and its anchors measurable) and then opens it, but only if the user is still on that screen, no tour opened meanwhile,useUi().dialogois empty and no[role="dialog"]/[role="alertdialog"]is in the DOM. A tour never opens on top of a dialog; if one was open, it is offered again the next time the user enters that screen. - The help button calls
abrirTutorial(vista)for the current screen at any time.
-
New step: add
data-tutorial="<id>"to the element, add aPasotoPASOS[vista]at the right position, and add both strings totutorial.jsonin all 15 languages (pnpm idiomasfails otherwise). Keep the anchor on an element that is always rendered on that screen, or accept that the step will show centred. -
New screen (
Vista):PASOSis aRecord<Vista, Paso[]>, so TypeScript requires its steps;useTutorialInicialand the help button then work without changes. - Keep the card opaque: it relies on the opaque-modal rule in
src/index.cssthat also covers dialogs.
src/stores/__tests__/ui-store.test.ts: opening a tour marks it as seen once and the list is persisted, while the open tour is not (abrir un tutorial lo apunta como visto (una vez) y se recuerda; el abierto no), and the persisted preference keys include tutorialesVistos. The overlay itself has no automated test (it depends on layout measurements that Vitest's node environment does not have).
Use and build · Uso y desarrollo
- User-Guide · Guía de usuario
- Development-Setup · Preparación del entorno de desarrollo
- Testing-and-CI · Tests y CI
- Releases-and-Auto-Updates · Versiones y actualizaciones automáticas
- Conventions · Convenciones
Architecture · Arquitectura
- Architecture · Arquitectura
- IPC-and-Error-Handling · IPC y manejo de errores
- Rust-App-Layer · Capa de aplicación Rust
Data · Datos
- Deck-Model · Modelo del mazo
- Storage-and-Blobs · Almacenamiento y blobs
- Deck-Package-Format · Formato del paquete de mazo
- Deck-Library · Biblioteca de mazos
Getting cards · Conseguir cartas
- Decklist-Parsing · Parseo de la lista del mazo
- Scryfall-Integration · Integración con Scryfall
- External-Sources · Fuentes externas
- Card-Identification-and-OCR · Identificación de cartas y OCR
Layout, images, PDF · Maquetación, imagen y PDF
- Layout-Engine · Motor de maquetación
- Imaging-and-PDF · Imagen y PDF
- Export · Exportación
- Live-Preview · Vista previa en vivo
- Statistics · Estadísticas
Card designer · Diseñador de cartas
- Designer-Overview · Visión general del diseñador
- Designer-Engine · Motor del diseñador
- Designer-Composition · Composición del diseñador
- Frame-Packs · Packs de marcos
- Designer-App-Layer · Capa de aplicación del diseñador
- Designer-UI · Interfaz del diseñador
- Card-Editor-Dialog · Diálogo Editar carta
Game table · Mesa de juego
Frontend · Frontend
- Frontend-Architecture · Arquitectura del frontend
- State-Stores · Stores de estado
- Internationalization · Internacionalización
- Themes-and-Skins · Temas y skins
- Settings-and-Shell · Ajustes y shell
- Tutorials · Tutoriales
- Decklist-Panel · Panel de la lista del mazo
- Add-Card-and-Variants · Añadir carta y variantes
- Set-Browser · Explorador de sets
Reference · Referencia