From 6faeb014df101312ab3c0fc244e8b0a76dca0003 Mon Sep 17 00:00:00 2001 From: DrAv0011 Date: Wed, 26 Aug 2026 10:49:07 +0200 Subject: [PATCH 01/48] docs(ui): container screens, slot components, the ui-compile filter A container-screens section covering the screen model, the ui-compile Regolith filter and the measured chest-screen facts, component pages for Container, Slot, SlotGrid, PlayerInventory and Hotbar, live text on the Text page, and the item view pages gone with their components. Co-Authored-By: Claude Opus 4.8 --- docs/ui/container-screens/_category_.json | 11 ++ .../ui/container-screens/container-screens.md | 170 ++++++++++++++++++ docs/ui/container-screens/findings.md | 126 +++++++++++++ docs/ui/container-screens/regolith-filter.md | 138 ++++++++++++++ docs/ui/guides/guides.md | 8 +- docs/ui/ore-styled/EquipmentSlots.md | 59 ------ docs/ui/ore-styled/Form/Form.md | 2 +- docs/ui/ore-styled/ItemContainer.md | 88 --------- docs/ui/ore-styled/ItemSlot.md | 75 -------- docs/ui/ore-styled/ore-styled.md | 15 -- docs/ui/ore-styled/theme.md | 3 - docs/ui/ui-runtime/components/Container.md | 84 +++++++++ docs/ui/ui-runtime/components/Form/Form.md | 2 +- docs/ui/ui-runtime/components/Hotbar.md | 36 ++++ docs/ui/ui-runtime/components/ItemRenderer.md | 98 ---------- .../ui-runtime/components/PlayerInventory.md | 38 ++++ docs/ui/ui-runtime/components/Slot.md | 119 ++++++++++++ docs/ui/ui-runtime/components/SlotGrid.md | 76 ++++++++ docs/ui/ui-runtime/components/Text.md | 24 +++ docs/ui/ui-runtime/components/components.md | 17 +- .../ui/ui-runtime/components/control-props.md | 6 +- .../components/modal-field-props.md | 2 +- docs/ui/ui-runtime/ui-runtime.md | 12 -- 23 files changed, 842 insertions(+), 367 deletions(-) create mode 100644 docs/ui/container-screens/_category_.json create mode 100644 docs/ui/container-screens/container-screens.md create mode 100644 docs/ui/container-screens/findings.md create mode 100644 docs/ui/container-screens/regolith-filter.md delete mode 100644 docs/ui/ore-styled/EquipmentSlots.md delete mode 100644 docs/ui/ore-styled/ItemContainer.md delete mode 100644 docs/ui/ore-styled/ItemSlot.md create mode 100644 docs/ui/ui-runtime/components/Container.md create mode 100644 docs/ui/ui-runtime/components/Hotbar.md delete mode 100644 docs/ui/ui-runtime/components/ItemRenderer.md create mode 100644 docs/ui/ui-runtime/components/PlayerInventory.md create mode 100644 docs/ui/ui-runtime/components/Slot.md create mode 100644 docs/ui/ui-runtime/components/SlotGrid.md diff --git a/docs/ui/container-screens/_category_.json b/docs/ui/container-screens/_category_.json new file mode 100644 index 0000000..ff35916 --- /dev/null +++ b/docs/ui/container-screens/_category_.json @@ -0,0 +1,11 @@ +{ + "position": 9, + "label": "container screens", + "key": "container-screens", + "collapsible": true, + "collapsed": true, + "link": { + "type": "doc", + "id": "container-screens" + } +} diff --git a/docs/ui/container-screens/container-screens.md b/docs/ui/container-screens/container-screens.md new file mode 100644 index 0000000..796746e --- /dev/null +++ b/docs/ui/container-screens/container-screens.md @@ -0,0 +1,170 @@ +--- +sidebar_position: 1 +--- + +# Container screens + +A **container screen** is a custom entity's chest screen, written in JSX with the same components as a form. The [ui-compile Regolith filter](./regolith-filter.md) compiles it into static JSON UI at build time; at runtime `createContainerScreen` serves it to every player who opens the entity, and everything alive in it — text, buttons, entities, the items in its slots — travels through the container's own slots. + +It is the second backend of `@bedrock-core/ui`. A form is serialized per player when it is shown. A container screen cannot be: the chest screen has no string channel wide enough to carry a layout, so the layout is baked once and only state moves at runtime. What you get in exchange is what a form cannot give — real item slots the player drags into, a screen that stays open while its values change, and state that belongs to a thing in the world. + +## A screen + +```tsx title="packs/BP/scripts/screens/furnace.screen.tsx" +/** @jsxImportSource @bedrock-core/ui */ +import { Button, Card } from '@bedrock-core/ore-styled'; +import { Background, Container, Hotbar, Panel, PlayerInventory, Slot, Text, useState } from '@bedrock-core/ui'; +import { Progress } from './Progress'; + +export default function Furnace() { + const [charge, setCharge] = useState(0); + const [held, setHeld] = useState('nothing'); + + return ( + + + + + {'§fBEDROCK CORE'} + + {`holding ${held}`} + + + + + setHeld(stack.typeId)} /> + setHeld(`took ${stack.typeId}`)} /> + + + + + + + + ); +} +``` + +Three things make it a container screen: the file name ends in `.screen.tsx` (that is how the filter finds it), the module default-exports the component, and the root is a [``](../ui-runtime/components/Container.md) naming the entity it opens from. Everything else is the component set you already know. + +The build runs the component once to decide the **shape**; the runtime runs it again, per viewer, to decide the **values**. The two walks line up position for position because a compiled screen cannot change shape — so nothing is named, nothing is registered, and there is no second file describing the same screen. + +:::caution A screen must not touch the world at import time +The build evaluates the module once, on the build machine, with `@minecraft/server` replaced by a stub. Hooks are fine; module-scope code that reaches for the game (`world.afterEvents.*.subscribe`, `system.run`, a dynamic property read next to an `import`) is not. Keep that in the module that calls `createContainerScreen` — see [the filter page](./regolith-filter.md#the-one-rule). +::: + +## Serving it + +```ts title="packs/BP/scripts/container/furnace.ts" +import { createContainerScreen } from '@bedrock-core/ui/container'; +import Furnace from '../screens/furnace.screen'; + +const screen = createContainerScreen(Furnace); +``` + +That is the whole behavior-pack side. `createContainerScreen` attaches the screen to every entity of the type the `` names; a player opens it by interacting with the entity, the way they open a chest, and the runtime drives the screen for as long as it is open. Nothing opens a container from script — a screen is bound to something in the world. + +```ts +function createContainerScreen( + Screen: FunctionComponent, + options?: { pollInterval?: number; debug?: boolean }, +): { entity: string; detach(): void } +``` + +| Option | Type | Default | Description | +| --- | --- | --- | --- | +| `pollInterval` | `number` | `1` | How often, in ticks, the drawn slots are swept. A container reports no events, so the runtime polls the slots a player can reach and reacts to what moved. | +| `debug` | `boolean` | `false` | Log every action with where each item ended up — the only way to see a container bug from inside the game. | + +| Member | Description | +| --- | --- | +| `entity` | The entity type the screen names, for spawning or finding hosts. | +| `detach()` | Stop serving the screen. | + +## The components + +The same set as a form, with four additions and a few container-specific behaviours: + +| Component | In a container screen | +| --- | --- | +| [`Container`](../ui-runtime/components/Container.md) | The root. Names the entity, and is the screen's own panel: `padding`, `gap` and `background` apply. | +| [`Slot`](../ui-runtime/components/Slot.md) | A container cell of the screen's own container. `role` is `both` (storage), `input` (in only) or `output` (out only), enforced server-side; `interactive={false}` locks it inert. `onInsert(player, stack, host)` and `onRemove(player, stack, host)` fire after a move. Given a `collection`, it instead reads a foreign cell — see [Rendering other containers](#rendering-other-containers). | +| [`SlotGrid`](../ui-runtime/components/SlotGrid.md) | A grid of cells over a foreign collection — any collection the engine exposes. Not part of the screen's own container. | +| [`PlayerInventory`](../ui-runtime/components/PlayerInventory.md), [`Hotbar`](../ui-runtime/components/Hotbar.md) | The player's own grids — thin `SlotGrid` wrappers over `inventory_items` / `hotbar_items`. Placed by the layout engine. Not free: a screen owns the whole chest screen, so leave them out and they are gone. | +| [`Text`](../ui-runtime/components/Text.md) | Baked, unless it has `maxLength` — see [Live text](#live-text). | +| [`Image`](../ui-runtime/components/Image.md) | A texture, baked into the layout. | +| [`Scroll`](../ui-runtime/components/Scroll.md) | A region laid out at its own height that the client scrolls. Not inside another scroll. | +| [`Button`](../ui-runtime/components/Button.md) | A container slot with the item hidden: a press reaches script only as an item move, and the face is ordinary JSON UI. `enabled={false}` draws `backgroundLocked` and ignores presses. Its children are baked into the face, so they are static text or images. | +| [`Background`](../ui-runtime/components/Background.md) | A full-screen texture behind everything, as in a form. | +| `Panel`, `Fragment`, contexts | Exactly as in a form. | + +[ore-styled](../ore-styled/ore-styled.md) components compose the same way: the `Button` above is ore-styled's, with `enabled` driving its disabled look. + +### Live text + +A container slot publishes numbers, not strings, so text that changes at runtime has to reserve its cells before the build knows what it will say: + +```tsx +{'§fBEDROCK CORE'} {/* baked: any character, any formatting code */} +{`holding ${held}`} {/* live: 24 cells, one container slot each */} +``` + +`maxLength` is what makes a `Text` live. Each cell is one container slot whose stack size is a character code, decoded through a 64-glyph table the filter writes into your `.lang` files: space, `A–Z`, `a–z`, `0–9` and `.`. Anything outside that table — formatting codes included — draws as a blank, and a string longer than `maxLength` is cut. Text without `maxLength` is baked into the layout and may say anything at all. + +A live `Text` cannot sit inside a `Button` — a button's children are its face. Put it beside the button. + +### Rendering other containers + +A `Slot` and a `SlotGrid` can read a collection the screen does **not** own — the player's own inventory, another container's items, any JSON UI collection — by naming it: + +```tsx + {/* one foreign cell */} + {/* a whole collection */} +``` + +The difference between an **own** slot and a **foreign** one is where the value lives and who drives it: + +- An **own** `Slot` (no `collection`) is a cell of the screen's own container. It is allocated a container index, the runtime polls it every sweep, and its `role` — `input` / `output` — is enforced a tick later by undoing a move the engine already made. A container reports no events and offers no veto, so a role is a server-side runtime thing, never a baked one. +- A **foreign** `Slot collection` / `SlotGrid` reads another collection at an author-given index. It costs no index in the screen's own container and the runtime never touches it: the engine's own take and place drive it directly. `role` has no meaning here (nothing polls it) and is refused. + +What *is* baked into the JSON UI is inertness. A container slot's take and place are a single combined engine action, so there is no take-only or place-only cell to express a one-directional `role` on the client — the runtime undoes the wrong direction a tick later. (Two things are baked: **no slot drops** — Q is not a route on any container cell, since dropping belongs outside a container and a dropped item lands out of the runtime's reach; and an output slot with no result holds the runtime's marker item while its compiled cell swaps to an empty fake — the slot is never empty, so shift-click auto-placement is blocked, and the marker is never rendered, hovered or takeable, because no real cell exists while it sits there.) A cell can also be made fully inert with `interactive={false}` — it withholds focus, so it can neither be taken from, placed into, nor dropped. A drawn-but-untouchable mirror of the player's inventory is exactly that. + +## State and handlers + +State is **entity-owned**. Hook state lives on the entity the screen is attached to, in a dynamic property, and persists on its own: close the screen and reopen it, leave and come back, restart the world — the furnace is still at the charge it was left at. Nothing has to be saved or restored, but it does mean state must be JSON-serializable: numbers, strings, booleans, plain objects and arrays. + +There is no single viewer, so **the player reaches a screen through its handlers** rather than a hook: `Slot` and `Button` handlers receive the player who moved the item, and the `Container` itself has `onOpen` / `onClose` with the player who came or went — keep what the screen needs (a name, a count of viewers) in state. [`usePlayer`](../ui-runtime/hooks/usePlayer.md) is unavailable, because a container screen has no player of its own. [`useExit`](../ui-runtime/hooks/useExit.md) hands back a press rather than a closer: nothing closes a container from script, but a ` - setHeld(stack.typeId)} /> - setHeld(`took ${stack.typeId}`)} /> + setHeld(stack.typeId)} /> + setHeld(`took ${stack.typeId}`)} /> @@ -88,7 +88,7 @@ The same set as a form, with four additions and a few container-specific behavio | Component | In a container screen | | --- | --- | | [`Container`](../ui-runtime/components/Container.md) | The root. Names the entity, and is the screen's own panel: `padding`, `gap` and `background` apply. | -| [`Slot`](../ui-runtime/components/Slot.md) | A container cell of the screen's own container. `role` is `both` (storage), `input` (in only) or `output` (out only), enforced server-side; `interactive={false}` locks it inert. `onInsert(player, stack, host)` and `onRemove(player, stack, host)` fire after a move. Given a `collection`, it instead reads a foreign cell — see [Rendering other containers](#rendering-other-containers). | +| [`Slot`](../ui-runtime/components/Slot.md) | A container cell of the screen's own container. `role` is `both` (storage), `input` (in only) or `output` (out only), enforced server-side; `interactive={false}` locks it inert. `onInsert(event)` and `onRemove(event)` fire after a move, with `event.stack`, `event.player` and `event.host`. Given a `collection`, it instead reads a foreign cell — see [Rendering other containers](#rendering-other-containers). | | [`SlotGrid`](../ui-runtime/components/SlotGrid.md) | A grid of cells over a foreign collection — any collection the engine exposes. Not part of the screen's own container. | | [`PlayerInventory`](../ui-runtime/components/PlayerInventory.md), [`Hotbar`](../ui-runtime/components/Hotbar.md) | The player's own grids — thin `SlotGrid` wrappers over `inventory_items` / `hotbar_items`. Placed by the layout engine. Not free: a screen owns the whole chest screen, so leave them out and they are gone. | | [`Text`](../ui-runtime/components/Text.md) | Baked, unless it has `maxLength` — see [Live text](#live-text). | @@ -133,7 +133,7 @@ What *is* baked into the JSON UI is inertness. A container slot's take and place State is **entity-owned**. Hook state lives on the entity the screen is attached to, in a dynamic property, and persists on its own: close the screen and reopen it, leave and come back, restart the world — the furnace is still at the charge it was left at. Nothing has to be saved or restored, but it does mean state must be JSON-serializable: numbers, strings, booleans, plain objects and arrays. -There is no single viewer, so **the player reaches a screen through its handlers** rather than a hook: `Slot` and `Button` handlers receive the player who moved the item, and the `Container` itself has `onOpen` / `onClose` with the player who came or went — keep what the screen needs (a name, a count of viewers) in state. [`usePlayer`](../ui-runtime/hooks/usePlayer.md) is unavailable, because a container screen has no player of its own. [`useExit`](../ui-runtime/hooks/useExit.md) hands back a press rather than a closer: nothing closes a container from script, but a ` + +``` + +Sizes sm 28 / md 34 / lg 44px. Press state nudges down 1px; there is no scale or bounce anywhere in this brand. + +
Props contract + +```ts +/** + * @startingPoint section="Core" subtitle="Buttons, tags, badges and other primitives" viewport="700x220" + */ +export interface ButtonProps { + children?: React.ReactNode; + /** primary = emerald solid; secondary = raised stone; ghost = bare; accentSoft = tinted; danger = redstone. */ + variant?: 'primary' | 'secondary' | 'ghost' | 'accentSoft' | 'danger'; + size?: 'sm' | 'md' | 'lg'; + /** Lucide icon name rendered before the label. */ + iconLeft?: string; + /** Lucide icon name rendered after the label. */ + iconRight?: string; + disabled?: boolean; + fullWidth?: boolean; + as?: 'button' | 'a'; + href?: string; + onClick?: (e: React.MouseEvent) => void; + style?: React.CSSProperties; +} +export declare function Button(props: ButtonProps): JSX.Element; +``` + +
+ +### Card + +Flat stone panel used for every boxed surface in the system. + +```jsx +

ore-styled

+``` + +The accent rule sits on the TOP edge — never a coloured left border. + +
Props contract + +```ts +export interface CardProps { + children?: React.ReactNode; + /** Lifts onto --bg-raised with a small shadow. */ + raised?: boolean; + /** Adds pointer + border-strong hover. */ + interactive?: boolean; + /** Colour of the 2px top rule — pass a --pkg-* token. Top edge only, never a left border. */ + accent?: string; + padding?: string; + onClick?: (e: React.MouseEvent) => void; + style?: React.CSSProperties; +} +export declare function Card(props: CardProps): JSX.Element; +``` + +
+ +### Divider + +Hairline separator, optionally with an uppercase mono label. + +```jsx + +``` + +
Props contract + +```ts +export interface DividerProps { + /** Centred uppercase mono label. */ + label?: string; + vertical?: boolean; + style?: React.CSSProperties; +} +export declare function Divider(props: DividerProps): JSX.Element; +``` + +
+ +### Icon + +Monochrome glyph wrapper around the Lucide icon set — use it anywhere an icon is needed instead of inlining SVG. + +```jsx + + +``` + +Icons are fetched from the Lucide CDN and inlined as real SVG, so they always take `currentColor` from their parent. Sizes: xs 12 / sm 14 / md 16 / lg 20 / xl 24, or a raw number. + +
Props contract + +```ts +export interface IconProps { + /** Lucide icon name in kebab-case, e.g. "terminal", "box", "arrow-right". */ + name: string; + size?: 'xs' | 'sm' | 'md' | 'lg' | 'xl' | number; + /** Any CSS color. Defaults to currentColor. */ + color?: string; + /** Lucide's own default is 2. */ + strokeWidth?: number; + style?: React.CSSProperties; +} +export declare function Icon(props: IconProps): JSX.Element; +``` + +
+ +### IconButton + +Icon-only square control — theme toggle, copy button, sidebar collapse. + +```jsx + + +``` + +
Props contract + +```ts +export interface IconButtonProps { + /** Lucide icon name. */ + icon: string; + /** Accessible label — also used as the tooltip. */ + label: string; + size?: 'sm' | 'md' | 'lg'; + variant?: 'ghost' | 'outline'; + active?: boolean; + onClick?: (e: React.MouseEvent) => void; + style?: React.CSSProperties; +} +export declare function IconButton(props: IconButtonProps): JSX.Element; +``` + +
+ +### Kbd + +Key cap for shortcut hints. Bottom border is 2px to fake the cap edge. + +```jsx +⌘K +``` + +
Props contract + +```ts +export interface KbdProps { + children?: React.ReactNode; + style?: React.CSSProperties; +} +export declare function Kbd(props: KbdProps): JSX.Element; +``` + +
+ +### Tag + +Chip for package names and topics. The dot carries the package accent. + +```jsx +@bedrock-core/server +``` + +
Props contract + +```ts +export interface TagProps { + children?: React.ReactNode; + /** Colour of the leading dot — pass a --pkg-* token to carry package identity. */ + accent?: string; + mono?: boolean; + dot?: boolean; + style?: React.CSSProperties; +} +export declare function Tag(props: TagProps): JSX.Element; +``` + +
+ +## components/navigation/ + +### Breadcrumbs + +Trail above the docs H1. Separator is a literal slash — it matches the package-scope typography. + +```jsx + +``` + +
Props contract + +```ts +export interface Crumb { label: string; href?: string } +export interface BreadcrumbsProps { + items: Crumb[]; + style?: React.CSSProperties; +} +export declare function Breadcrumbs(props: BreadcrumbsProps): JSX.Element; +``` + +
+ +### DocsMenu + +Header mega-menu that replaces per-package nav tabs once the docs outgrow two sections — categories across the top, a row per package underneath. + +```jsx + +``` + +Use up to four categories per row. `status: "planned"` is how unreleased surfaces stay visible without being clickable. + +
Props contract + +```ts +export interface DocsMenuItem { + id: string; + label: string; + description?: string; + /** "planned" dims the row and disables selection; any other string renders as a badge. */ + status?: string; +} +export interface DocsMenuCategory { + id: string; + label: string; + /** Category identity colour — pass a --cat-* token. */ + accent: string; + items: DocsMenuItem[]; +} +export interface DocsMenuProps { + label?: string; + categories: DocsMenuCategory[]; + activeId?: string; + onSelect?: (id: string) => void; + style?: React.CSSProperties; +} +export declare function DocsMenu(props: DocsMenuProps): JSX.Element; +``` + +
+ +### NavBar + +Site header for both the docs and marketing surfaces. Translucent + blurred over the canvas. + +```jsx +} /> +``` + +Section labels are lowercase mono — they are package names, not sentence-case nav items. + +
Props contract + +```ts +export interface NavSection { id: string; label: string; accent?: string } +export interface NavBarProps { + /** Path to the @bedrock-core mark, usually assets/logo-mark.png. */ + logoSrc?: string; + /** Left-hand nav slot — put a here once the docs outgrow a tab strip. Rendered before `sections`. */ + menu?: React.ReactNode; + sections?: NavSection[]; + activeSection?: string; + onSelectSection?: (id: string) => void; + /** Right-hand slot: search, GitHub/Discord buttons, theme toggle. */ + right?: React.ReactNode; + sticky?: boolean; + style?: React.CSSProperties; +} +export declare function NavBar(props: NavBarProps): JSX.Element; +``` + +
+ +### PaginationNav + +Prev/next footer that closes a docs article. + +```jsx + +``` + +
Props contract + +```ts +export interface PageLink { label: string; href?: string; onClick?: (e: React.MouseEvent) => void } +export interface PaginationNavProps { + prev?: PageLink; + next?: PageLink; + style?: React.CSSProperties; +} +export declare function PaginationNav(props: PaginationNavProps): JSX.Element; +``` + +
+ +### SectionSwitcher + +Sidebar header that names the current docs section and drops down to switch. Pair it with `SidebarNav`'s `header` slot — it is the flat, searchable counterpart to `DocsMenu`. + +```jsx +} … /> +``` + +
Props contract + +```ts +export interface SwitcherSection { + id: string; + label: string; + /** Category identity colour — pass a --cat-* token. */ + accent: string; + /** Category name shown right-aligned in the list. */ + category?: string; + /** "planned" dims the row and disables selection. */ + status?: string; +} +export interface SectionSwitcherProps { + sections: SwitcherSection[]; + value?: string; + onChange?: (id: string) => void; + scope?: string; + /** Release badge shown on the closed trigger, e.g. "pre-1.0". */ + status?: string; + style?: React.CSSProperties; +} +export declare function SectionSwitcher(props: SectionSwitcherProps): JSX.Element; +``` + +
+ +### SidebarNav + +Docs left sidebar. Top-level entries are sans; nested pages are mono (they are file/API names). + +```jsx + +``` + +
Props contract + +```ts +export interface SidebarNode { + id: string; + label: string; + items?: SidebarNode[]; + /** Collapsed on first render when false. */ + defaultOpen?: boolean; +} +export interface SidebarNavProps { + items: SidebarNode[]; + activeId?: string; + onSelect?: (id: string) => void; + /** Slot above the tree — version switcher, package pill. */ + header?: React.ReactNode; + style?: React.CSSProperties; +} +export declare function SidebarNav(props: SidebarNavProps): JSX.Element; +``` + +
+ +### SiteFooter + +Footer shared by the docs and marketing surfaces. + +```jsx + +``` + +
Props contract + +```ts +export interface FooterColumn { title: string; links: { label: string; href?: string }[] } +export interface SiteFooterProps { + /** Path to the wordmark PNG, usually assets/logo-wordmark.png. */ + wordmarkSrc?: string; + columns?: FooterColumn[]; + note?: string; + style?: React.CSSProperties; +} +export declare function SiteFooter(props: SiteFooterProps): JSX.Element; +``` + +
+ +### TableOfContents + +Right-hand page outline. Active item gets an emerald left rule, not a background. + +```jsx + +``` + +
Props contract + +```ts +export interface TocItem { id: string; label: string; depth?: 0 | 1 | 2 } +export interface TableOfContentsProps { + items: TocItem[]; + activeId?: string; + onSelect?: (id: string) => void; + title?: string; + style?: React.CSSProperties; +} +export declare function TableOfContents(props: TableOfContentsProps): JSX.Element; +``` + +
+ +## components/docs/ + +### Callout + +Admonition block for the docs body — the "Pre-1.0" banner on every package overview is `kind="warning"`. + +```jsx +Breaking changes can still land until 1.0.0. +``` + +
Props contract + +```ts +export interface CalloutProps { + kind?: 'note' | 'tip' | 'info' | 'warning' | 'danger'; + /** Overrides the default uppercase title. */ + title?: string; + children?: React.ReactNode; + style?: React.CSSProperties; +} +export declare function Callout(props: CalloutProps): JSX.Element; +``` + +
+ +### CodeBlock + +Code fence for the docs body and marketing hero. Always dark, in both themes. + +```jsx + + +``` + +
Props contract + +```ts +export interface CodeBlockProps { + code: string; + /** Shown as an uppercase mono badge in the title bar. */ + language?: string; + /** Filename or command context, e.g. "main.ts". */ + title?: string; + showLineNumbers?: boolean; + copyable?: boolean; + style?: React.CSSProperties; +} +export declare function CodeBlock(props: CodeBlockProps): JSX.Element; +``` + +
+ +### DocTabs + +Underlined tab strip for alternative instructions (npm / pnpm / yarn, TS / JS). + +```jsx + + {(id) => } + +``` + +
Props contract + +```ts +export interface DocTab { id: string; label: string } +export interface DocTabsProps { + tabs: DocTab[]; + /** Controlled active tab id. */ + value?: string; + defaultValue?: string; + onChange?: (id: string) => void; + /** Node, or a render function receiving the active tab id. */ + children?: React.ReactNode | ((activeId: string) => React.ReactNode); + style?: React.CSSProperties; +} +export declare function DocTabs(props: DocTabsProps): JSX.Element; +``` + +
+ +### FeatureCard + +Feature block for the marketing page's "what you get" grid. + +```jsx +Addons find each other at runtime. +``` + +
Props contract + +```ts +export interface FeatureCardProps { + /** Lucide icon name. */ + icon?: string; + title?: string; + children?: React.ReactNode; + accent?: string; + style?: React.CSSProperties; +} +export declare function FeatureCard(props: FeatureCardProps): JSX.Element; +``` + +
+ +### NextStepsList + +Closing link list for a docs page — mono link title, sentence-case description on the same line. + +```jsx + +``` + +
Props contract + +```ts +export interface NextStepItem { title: string; description?: string; href?: string } +export interface NextStepsListProps { + items: NextStepItem[]; + style?: React.CSSProperties; +} +export declare function NextStepsList(props: NextStepsListProps): JSX.Element; +``` + +
+ +### PackageCard + +Tile for one package in the homepage grid or a docs index. + +```jsx + +``` + +
Props contract + +```ts +/** + * @startingPoint section="Docs" subtitle="Package tiles, callouts, code fences and API tables" viewport="700x320" + */ +export interface PackageCardProps { + /** Package name after the scope, e.g. "server". */ + name: string; + scope?: string; + description?: string; + /** Lucide icon name. */ + icon?: string; + /** Package identity colour — pass a --pkg-* token. */ + accent?: string; + /** Short release-state label, e.g. "pre-1.0". */ + status?: string; + href?: string; + style?: React.CSSProperties; +} +export declare function PackageCard(props: PackageCardProps): JSX.Element; +``` + +
+ +### PropsTable + +API reference table used under every component/API heading in the docs. + +```jsx + +``` + +
Props contract + +```ts +export interface PropsTableRow { + name: string; + type: string; + default?: string; + required?: boolean; + description?: React.ReactNode; +} +export interface PropsTableProps { + rows: PropsTableRow[]; + style?: React.CSSProperties; +} +export declare function PropsTable(props: PropsTableProps): JSX.Element; +``` + +
+ +## components/forms/ + +### SearchInput + +Docs search field for the header. + +```jsx + +``` + +
Props contract + +```ts +export interface SearchInputProps { + value?: string; + onChange?: (value: string) => void; + placeholder?: string; + /** Second key in the hint; pass null to hide the hint entirely. */ + shortcut?: string | null; + width?: number | string; + style?: React.CSSProperties; +} +export declare function SearchInput(props: SearchInputProps): JSX.Element; +``` + +
+ +### Select + +Compact select for version and locale switching. Mono type — the values are identifiers. + +```jsx + ``` -## Best Practices +## Notes - Give the field a `width` (or let it stretch in a column) so the framed box reads as a field even when empty. - Provide a `placeholder` so an empty field still reads as editable. diff --git a/docs/ui/ore-styled/MenuRow.md b/docs/ore-styled/MenuRow.md similarity index 61% rename from docs/ui/ore-styled/MenuRow.md rename to docs/ore-styled/MenuRow.md index d8753f7..12cd643 100644 --- a/docs/ui/ore-styled/MenuRow.md +++ b/docs/ore-styled/MenuRow.md @@ -1,5 +1,6 @@ --- -sidebar_position: 3.2 +sidebar_position: 5 +description: "The browse-screen row: leading thumbnail, title, one-line subtitle, and a trailing chevron, drawn on the dropdown-option face." --- # MenuRow @@ -26,48 +27,27 @@ import { MenuRow } from '@bedrock-core/ore-styled'; ## Props -### Component-Specific Props +### Component-Specific props -#### `title` -- Type: [`DisplayText`](../i18n/i18n.md#displaytext) (`string | RawMessage`) +| Prop | Type | Description | +| --- | --- | --- | +| `title` | [`DisplayText`](/docs/i18n#displaytext) (`string \| RawMessage`) | | - Required - Description: First line — the row's name. -#### `subtitle` -- Type: `DisplayText` -- Description: Second line, rendered muted. Omit for a single-line row. +| Prop | Type | Default | Description | +| --- | --- | --- | --- | +| `subtitle` | `DisplayText` | — | Second line, rendered muted. Omit for a single-line row | +| `icon` | `string` | — | Leading thumbnail texture path. Omit for a text-only row | +| `iconSize` | `number` | `16` (the theme's row icon size) | Thumbnail edge in px | +| `chevron` | `boolean` | `true` | Trailing `>` affordance. Set `false` for rows that **select** rather than navigate | +| `depth` | `number` | `0` | Indent level for nested index rows. Each step insets the row's whole **box** by `theme.tokens.spacing.lg` (12 px), not just its contents, so a child row is visibly narrower than its section header | +| `onPress` | `() => unknown \| Promise` | — | Press handler | +| `enabled` | `boolean` | `true` | A disabled row keeps its face and greys its text instead | -#### `icon` -- Type: `string` -- Description: Leading thumbnail texture path. Omit for a text-only row. +### Control props -#### `iconSize` -- Type: `number` -- Default: `16` (the theme's row icon size) -- Description: Thumbnail edge in px. - -#### `chevron` -- Type: `boolean` -- Default: `true` -- Description: Trailing `>` affordance. Set `false` for rows that **select** rather than navigate. - -#### `depth` -- Type: `number` -- Default: `0` -- Description: Indent level for nested index rows. Each step insets the row's whole **box** by `theme.tokens.spacing.lg` (12 px), not just its contents, so a child row is visibly narrower than its section header. - -#### `onPress` -- Type: `() => unknown | Promise` -- Description: Press handler. - -#### `enabled` -- Type: `boolean` -- Default: `true` -- Description: A disabled row keeps its face and greys its text instead. - -### Control Props - -MenuRow inherits all standard [control props](../ui-runtime/components/control-props.md). It sets `alignSelf: 'stretch'` rather than an explicit width, so don't hard-code a `width` alongside `depth`. +MenuRow inherits all standard [control props](/docs/ui/components/control-props). It sets `alignSelf: 'stretch'` rather than an explicit width, so don't hard-code a `width` alongside `depth`. ## Localized labels @@ -83,10 +63,10 @@ const { key, raw } = useTranslation(i18n); /> ``` -:::caution Colour prefixes only apply to literals -MenuRow colours its lines with a `§` prefix, and applies it **only** to literal strings — a `RawMessage`, or a string the active resolver recognises as a key, passes through untouched in the label's own colour. +:::caution Color prefixes only apply to literals +MenuRow colors its lines with a `§` prefix, and applies it **only** to literal strings — a `RawMessage`, or a string the active resolver recognizes as a key, passes through untouched in the label's own color. -If you need a specific colour on localized text, bake the `§` code into the authored translation value instead of the call site. +If you need a specific color on localized text, bake the `§` code into the authored translation value instead of the call site. ::: ## Examples @@ -158,10 +138,10 @@ Read from `theme.components.menuRow`: | `textures.background` | the dropdown option face | | `textures.backgroundSelected` | the dropdown's selected option face | -## Best Practices +## Notes - Use `MenuRow` for every list in a screen rather than hand-rolling rows. - Keep subtitles to one short line; both lines are clipped with an ellipsis at one line each. - Use `depth` for hierarchy instead of nesting `Panel`s with padding — the inset box is what communicates the level. - Set `chevron={false}` whenever pressing the row does not open another screen. -- Pair with [`Header`](./Header.md) above and a [`Scroll`](../ui-runtime/components/Scroll.md) around the rows for a standard browse screen. +- Pair with [`Header`](./Header.md) above and a [`Scroll`](/docs/ui/components/Scroll) around the rows for a standard browse screen. diff --git a/docs/ui/ore-styled/Radio.md b/docs/ore-styled/Radio.md similarity index 56% rename from docs/ui/ore-styled/Radio.md rename to docs/ore-styled/Radio.md index dee1212..fa4c6ee 100644 --- a/docs/ui/ore-styled/Radio.md +++ b/docs/ore-styled/Radio.md @@ -1,5 +1,6 @@ --- -sidebar_position: 6 +sidebar_position: 8 +description: "Single-choice radio set." --- # Radio @@ -28,47 +29,25 @@ import { RadioGroup, Radio } from '@bedrock-core/ore-styled'; ### `RadioGroup` -#### `value` -- Type: `string` -- Description: Controlled selected value. Provide alongside `onChange` to drive the group from the outside. - -#### `defaultValue` -- Type: `string` -- Default: `''` -- Description: Initial selected value when running uncontrolled. - -#### `onChange` -- Type: `(value: string) => void` -- Description: Called whenever the player selects a different `Radio`. - -#### `disabled` -- Type: `boolean` -- Default: `false` -- Description: Disables every `Radio` inside the group. Individual `Radio`s can still set their own `disabled={true}` regardless. - -#### `children` -- Type: `JSX.Node` -- Required: Yes -- Description: One or more `Radio` items. +| Prop | Type | Default | Description | +| --- | --- | --- | --- | +| `value` | `string` | — | Controlled selected value. Provide alongside `onChange` to drive the group from the outside | +| `defaultValue` | `string` | `''` | Initial selected value when running uncontrolled | +| `onChange` | `(value: string) => void` | — | Called whenever the player selects a different `Radio` | +| `disabled` | `boolean` | `false` | Disables every `Radio` inside the group. Individual `Radio`s can still set their own `disabled={true}` regardless | +| `children` | `JSX.Node` | — (**required**) | One or more `Radio` items | ### `Radio` -#### `value` -- Type: `string` -- Required: Yes -- Description: Identifier matched against the group's selected value. - -#### `label` -- Type: `string` -- Description: Text rendered next to the radio. Omit for an unlabelled bullet. - -#### `disabled` -- Type: `boolean` -- Description: Disables this `Radio` only. Falls back to the group's `disabled` when unset. +| Prop | Type | Default | Description | +| --- | --- | --- | --- | +| `value` | `string` | — (**required**) | Identifier matched against the group's selected value | +| `label` | `string` | — | Text rendered next to the radio. Omit for an unlabeled bullet | +| `disabled` | `boolean` | — | Disables this `Radio` only. Falls back to the group's `disabled` when unset | -### Control Props +### Control props -Both `RadioGroup` and `Radio` inherit all standard [control props](../ui-runtime/components/control-props.md). +Both `RadioGroup` and `Radio` inherit all standard [control props](/docs/ui/components/control-props). ## Examples @@ -89,7 +68,7 @@ function DifficultyPicker() { } ``` -### Disabled Group +### Disabled group ```tsx @@ -98,7 +77,7 @@ function DifficultyPicker() { ``` -## Best Practices +## Notes - Always provide a `defaultValue` (or `value`) so the group has a clear initial selection — radio groups without a pre-selection are confusing for players. - Keep `value` strings short and stable — they're not shown to the player, that's what `label` is for. diff --git a/docs/ore-styled/Slider.md b/docs/ore-styled/Slider.md new file mode 100644 index 0000000..8488573 --- /dev/null +++ b/docs/ore-styled/Slider.md @@ -0,0 +1,93 @@ +--- +sidebar_position: 13 +description: "Numeric field drawn as a track with a thumb." +--- +# Slider + +Numeric field drawn as a track with a thumb. The thumb shows the value's position along the track; pressing it opens a modal to pick a value within the range. Supports controlled and uncontrolled usage. + +:::caution Deprecated +This is the legacy one-modal-per-field pattern. For new screens, use [`Form.Slider`](./Form/FormSlider.md) inside a [`Form`](./Form/Form.md). Still fully supported for existing screens. +::: + +![Slider](/img/ore-styled/Slider.png) + +## Import + +```tsx +import { Slider } from '@bedrock-core/ore-styled'; +``` + +## Usage + +```tsx + console.log(value)} +/> +``` + +Built on top of the [`Slider`](/docs/ui/components/deprecated/Slider) primitive and the [theme](./theme.md) token map. The thumb only displays the current value; pressing the field opens a single-slider modal where the value is actually chosen — confirm commits, cancel keeps the current one. + +## Props + +### Component-Specific props + +| Prop | Type | Default | Description | +| --- | --- | --- | --- | +| `min` (required) | `number` | — | Minimum selectable value; the left end of the track | +| `max` (required) | `number` | — | Maximum selectable value; the right end of the track | +| `step` | `number` | `1` | Increment between selectable values in the modal | +| `value` | `number` | — | Controlled value. When provided, the thumb reflects it on every render and `onChange` is your only way to update it | +| `defaultValue` | `number` | `min` | Initial value when running uncontrolled | +| `onChange` | `(value: number) => void` | — | Called with the new value when the player confirms the modal | +| `onCancel` | `() => void` | — | Called when the player cancels (X / Esc) the modal. The value is left unchanged | + +### Modal field props + +Slider inherits all [modal field props](/docs/ui/components/deprecated/modal-field-props) (`label`, `title`, `body`, `submitLabel`, `tooltip`) for configuring the modal. + +### Control props + +Slider inherits all standard [control props](/docs/ui/components/control-props). Use `enabled={false}` to render the disabled track/thumb textures and make the field inert (no modal opens). + +## Examples + +### Controlled + +```tsx +function VolumeSetting() { + const [volume, setVolume] = useState(50); + + return ( + + + {`${volume}`} + + ); +} +``` + +### Uncontrolled + +```tsx + console.log(v)} /> +``` + +## Notes + +- The thumb only *shows* the value — pair the slider with a `Text` echo if you want the exact number visible without opening the modal. +- Choose a `step` that matches the precision you actually need — players can only land on `min + n * step`. +- Make sure `defaultValue` (or a controlled `value`) sits within `[min, max]` so the thumb stays on the track. diff --git a/docs/ui/ore-styled/Toggle.md b/docs/ore-styled/Toggle.md similarity index 53% rename from docs/ui/ore-styled/Toggle.md rename to docs/ore-styled/Toggle.md index ef16f28..88bb200 100644 --- a/docs/ui/ore-styled/Toggle.md +++ b/docs/ore-styled/Toggle.md @@ -1,5 +1,6 @@ --- -sidebar_position: 5 +sidebar_position: 7 +description: "On/off switch." --- # Toggle @@ -21,29 +22,18 @@ import { Toggle } from '@bedrock-core/ore-styled'; ## Props -### Component-Specific Props +### Component-Specific props -#### `on` -- Type: `boolean` -- Description: Controlled value. When provided, the component renders this state and `onChange` is your only way to update it. +| Prop | Type | Default | Description | +| --- | --- | --- | --- | +| `on` | `boolean` | — | Controlled value. When provided, the component renders this state and `onChange` is your only way to update it | +| `defaultOn` | `boolean` | `false` | Initial state when running uncontrolled | +| `onChange` | `(on: boolean) => void` | — | Called with the next state every time the player flips the toggle | +| `disabled` | `boolean` | `false` | When `true`, the toggle renders the disabled texture and ignores presses | -#### `defaultOn` -- Type: `boolean` -- Default: `false` -- Description: Initial state when running uncontrolled. +### Control props -#### `onChange` -- Type: `(on: boolean) => void` -- Description: Called with the next state every time the player flips the toggle. - -#### `disabled` -- Type: `boolean` -- Default: `false` -- Description: When `true`, the toggle renders the disabled texture and ignores presses. - -### Control Props - -Toggle inherits all standard [control props](../ui-runtime/components/control-props.md). +Toggle inherits all standard [control props](/docs/ui/components/control-props). ## Examples @@ -68,7 +58,7 @@ function MusicSetting() { ``` -## Best Practices +## Notes - Pair `Toggle` with a left-aligned label inside a `Panel` row so the player knows what they're flipping. - For more than two states, use [`ToggleButtonGroup`](./ToggleButton.md) or [`RadioGroup`](./Radio.md) instead. diff --git a/docs/ui/ore-styled/ToggleButton.md b/docs/ore-styled/ToggleButton.md similarity index 55% rename from docs/ui/ore-styled/ToggleButton.md rename to docs/ore-styled/ToggleButton.md index 67d4688..a791e9f 100644 --- a/docs/ui/ore-styled/ToggleButton.md +++ b/docs/ore-styled/ToggleButton.md @@ -1,9 +1,10 @@ --- -sidebar_position: 7 +sidebar_position: 9 +description: "Segmented button group with single-selection semantics — visually similar to a row of buttons, behaviorally a radio group." --- # ToggleButton -Segmented button group with single-selection semantics — visually similar to a row of buttons, behaviourally a radio group. Use it when the choices benefit from a button-sized hit target and you want them to read as a connected control. +Segmented button group with single-selection semantics — visually similar to a row of buttons, behaviorally a radio group. Use it when the choices benefit from a button-sized hit target and you want them to read as a connected control. ![ToggleButton](/img/ore-styled/ToggleButton.png) @@ -29,48 +30,25 @@ The group lays its items out in a row with their edges flush, reading as a singl ### `ToggleButtonGroup` -#### `value` -- Type: `string` -- Description: Controlled selected value. Provide alongside `onChange` to drive selection from the outside. - -#### `defaultValue` -- Type: `string` -- Default: `''` -- Description: Initial selected value when running uncontrolled. - -#### `onChange` -- Type: `(value: string) => void` -- Description: Called whenever the player picks a different item. - -#### `disabled` -- Type: `boolean` -- Default: `false` -- Description: Disables every item in the group. Individual items can still set their own `disabled={true}` regardless. - -#### `children` -- Type: `JSX.Node` -- Required: Yes -- Description: One or more `ToggleButtonItem` children. +| Prop | Type | Default | Description | +| --- | --- | --- | --- | +| `value` | `string` | — | Controlled selected value. Provide alongside `onChange` to drive selection from the outside | +| `defaultValue` | `string` | `''` | Initial selected value when running uncontrolled | +| `onChange` | `(value: string) => void` | — | Called whenever the player picks a different item | +| `disabled` | `boolean` | `false` | Disables every item in the group. Individual items can still set their own `disabled={true}` regardless | +| `children` | `JSX.Node` | — (**required**) | One or more `ToggleButtonItem` children | ### `ToggleButtonItem` -#### `value` -- Type: `string` -- Required: Yes -- Description: Identifier matched against the group's selected value. - -#### `disabled` -- Type: `boolean` -- Description: Disables this item only. Falls back to the group's `disabled` when unset. - -#### `children` -- Type: `JSX.Node` -- Required: Yes -- Description: Item content. A string is auto-wrapped in a themed `Text` whose color reflects the selected/unselected/disabled state. +| Prop | Type | Default | Description | +| --- | --- | --- | --- | +| `value` | `string` | — (**required**) | Identifier matched against the group's selected value | +| `disabled` | `boolean` | — | Disables this item only. Falls back to the group's `disabled` when unset | +| `children` | `JSX.Node` | — (**required**) | Item content. A string is auto-wrapped in a themed `Text` whose color reflects the selected/unselected/disabled state | -### Control Props +### Control props -Both `ToggleButtonGroup` and `ToggleButtonItem` inherit all standard [control props](../ui-runtime/components/control-props.md). +Both `ToggleButtonGroup` and `ToggleButtonItem` inherit all standard [control props](/docs/ui/components/control-props). ## Examples @@ -90,7 +68,7 @@ function ModePicker() { } ``` -### Disabled Item +### Disabled item ```tsx @@ -100,7 +78,7 @@ function ModePicker() { ``` -## Best Practices +## Notes - Use a `ToggleButtonGroup` when the options are short labels and you want a chunky, button-shaped hit area. For longer lists with descriptive labels reach for [`RadioGroup`](./Radio.md) instead. - Three to five items is the comfortable range — many more and the segments get cramped. diff --git a/docs/ui/ore-styled/ore-styled.md b/docs/ore-styled/index.md similarity index 74% rename from docs/ui/ore-styled/ore-styled.md rename to docs/ore-styled/index.md index 26561fd..f488250 100644 --- a/docs/ui/ore-styled/ore-styled.md +++ b/docs/ore-styled/index.md @@ -1,17 +1,18 @@ --- +slug: / sidebar_position: 1 +sidebar_label: Overview +description: "@bedrock-core/ore-styled is a themed component layer built on top of the @bedrock-core/ui primitives." --- # ore-styled -`@bedrock-core/ore-styled` is a themed component layer built on top of the [`@bedrock-core/ui`](../ui-runtime/components/components.md) primitives. Every component renders with authentic Minecraft textures shipped in the [render pack](../ui-runtime/render-pack.md), so your UI matches the vanilla look out of the box. +`@bedrock-core/ore-styled` is a themed component layer built on top of the [`@bedrock-core/ui`](/docs/ui/components) primitives. Every component renders with authentic Minecraft textures shipped in the [render pack](/docs/ui/guides/render-pack), so your UI matches the vanilla look out of the box. ## Install -```bash -yarn add @bedrock-core/ore-styled -``` + -No extra resource pack: the theme's textures live in the same [render pack](../ui-runtime/render-pack.md) the framework already requires. +No extra resource pack: the theme's textures live in the same [render pack](/docs/ui/guides/render-pack) the framework already requires. ## Import @@ -25,7 +26,7 @@ import { Button, Card, Header, MenuRow, Checkbox, Toggle, RadioGroup, Radio, Tog - [**``**](./Card.md) — container with the standard panel background, padding, and gap, in six variants. - [**`
`**](./Header.md) — screen header bar: back button, breadcrumb trail, and close button. - [**``**](./MenuRow.md) — browse-list row: thumbnail, title, subtitle, and trailing chevron. -- [**``**](./Checkbox.md) — labelled checkbox, controlled or uncontrolled. +- [**``**](./Checkbox.md) — labeled checkbox, controlled or uncontrolled. - [**``**](./Toggle.md) — on/off switch. - [**`` / ``**](./Radio.md) — single-choice radio set. - [**`` / ``**](./ToggleButton.md) — segmented button group with single selection. @@ -42,4 +43,8 @@ Atomic modal form — one native `ModalFormData` for the whole screen, all value ## Theme +:::caution Pre-1.0 +`@bedrock-core/ore-styled` is under active development. Breaking changes can still land until `1.0.0` — pin exact versions and read the release notes before upgrading. +::: + All visual tokens (spacing, font colors, component textures) live in a single `theme` object you can read and reuse. See the [theme](./theme.md) page for the full token map. diff --git a/docs/ui/ore-styled/theme.md b/docs/ore-styled/theme.md similarity index 96% rename from docs/ui/ore-styled/theme.md rename to docs/ore-styled/theme.md index 0bcafd4..17c58c4 100644 --- a/docs/ui/ore-styled/theme.md +++ b/docs/ore-styled/theme.md @@ -1,5 +1,6 @@ --- -sidebar_position: 16 +sidebar_position: 15 +description: "ore-styled ships a single theme object that holds every visual token it uses — spacing scale, font colors, and per-component texture paths plus sizing." --- # Theme diff --git a/docs/server/api/_category_.json b/docs/server/api/_category_.json new file mode 100644 index 0000000..2ab4e9a --- /dev/null +++ b/docs/server/api/_category_.json @@ -0,0 +1,10 @@ +{ + "position": 4, + "label": "API", + "collapsible": true, + "collapsed": false, + "link": { + "type": "doc", + "id": "api/runtime" + } +} diff --git a/docs/server/server-runtime/config.md b/docs/server/api/config.md similarity index 96% rename from docs/server/server-runtime/config.md rename to docs/server/api/config.md index aede5f0..80bfe08 100644 --- a/docs/server/server-runtime/config.md +++ b/docs/server/api/config.md @@ -1,8 +1,9 @@ --- sidebar_position: 6 +description: "core.config turns a declarative schema into typed, persisted, cross-addon settings." --- -# ConfigRegistry +# core.config `core.config` turns a declarative schema into typed, persisted, cross-addon settings. An addon declares its schema once; the runtime handles storage, change events, discovery and remote access. @@ -45,8 +46,6 @@ config.player.for(player).allowGifts.get(); // entity scopes pick The tree is built once, when the schema is registered, and every access down it is an ordinary property lookup — cheap enough to read inside a tick loop. ---- - ## `define` ```ts @@ -107,7 +106,7 @@ server: { }, ``` -Leave them off and the UI derives a title from the key (`economy` reads as "Economy"), which is what every schema did before these existed — so adding them is optional and never breaking. +Leave them off and the UI derives a title from the key (`economy` reads as "Economy"), so both fields are optional. They are **not** settings. `$label` never appears in the value object, is not patchable, and is not a dot-path: @@ -133,8 +132,6 @@ config schema: "server.economy.set" uses the reserved key "set"; reserved keys a The list is exported as `RESERVED_KEYS`, and `validateConfigSchema(scope, schema)` runs the same check if you want it earlier. ::: ---- - ## Entry types ```ts @@ -181,18 +178,7 @@ config.server.bannedItems.set(['minecraft:bedrock', 'minecraft:barrier']); `itemType: 'enum'` plus `options` constrains what the UI offers and what a command will accept as an item; `maxItems` caps the length. :::note Where a list is editable in game -A modal form still has no control for a list, so whether the config screen can edit one comes down to where it sits — see [how a schema becomes screens](/docs/ui/config#how-a-schema-becomes-screens). On a level that renders as buttons it gets a row and a full editor; on a level that renders as a form it falls back to showing its items and naming the command. - -The commands work either way, and carry [four verbs](/docs/ui/config#list-settings-from-a-command): - -```text -/:config get bannedItems → [tnt, lava_bucket] (2/50) -/:config set bannedItems "tnt, lava_bucket" -/:config add bannedItems flint_and_steel -/:config remove bannedItems tnt -``` - -From code the typed API is unchanged — `get()` still returns `string[]` and `set()` still takes one. +A modal form has no control for a list, so whether the config screen can edit one depends on where it sits; the commands work either way. See [how a schema becomes screens](/docs/config#how-a-schema-becomes-screens) and [list settings from a command](/docs/config#list-settings-from-a-command). ::: ### Inferred value shape @@ -226,8 +212,6 @@ config.server.bannedItems.get(); // string[] config.server.pricing.nope; // compile error — not a schema key ``` ---- - ## Reading and writing Two write operations with identical semantics everywhere — local and remote, all three scopes: @@ -283,8 +267,6 @@ The entity-first forms — `config.player.get(player)`, `patch(player, …)`, `s The player scope tracks connected players. Values are loaded on `playerSpawn` (and for anyone already connected when the schema is defined, which matters after a `/reload`), and cleared on `playerLeave`. A remote `patch`/`set` aimed at an offline player logs a warning and is ignored — the read still answers with schema defaults. ::: ---- - ## Change listeners `subscribe` sits on **every** node, so you watch a value by naming it. Listeners **bubble**: a change to `pricing.taxRate` fires the leaf listener, then the `pricing` group listener, then the root listener — deepest first. @@ -323,8 +305,6 @@ When the path is a literal, prefer the node — `config.server.pricing.taxRate.s The listener signature is `(next, prev)` where `prev` may be `undefined`. Every `subscribe` returns an unsubscribe function. ---- - ## Timing and persistence Values live in dynamic properties, one property per key: @@ -350,8 +330,6 @@ const { config } = core.register({ manifest, config: configDef }); config.server.pricing.taxRate.subscribe((next) => { applyTax(next); }); ``` ---- - ## Cross-addon config ### `of` @@ -432,8 +410,6 @@ const { config } = core.register({ manifest, config: configDef }); A consumer passes `ShopConfigDef` to `core.config.of()` or `core.config.subscribe()` and gets `pricing.taxRate` typed as `number`. ---- - ## Authorization Remote access can be made **on behalf of a player** by passing an `actorId`. The owning addon then authorizes every request against that player. @@ -478,8 +454,6 @@ Reads `player.playerPermissionLevel`, which is **readonly** on `Player`. It deli Every addon in a world runs arbitrary script and can write the underlying dynamic properties directly, so nothing here stops a hostile *pack*. The boundary this enforces is the one that actually exists: a **player** driving a config UI or a config command must not be able to change settings they have no business changing. ::: ---- - ## The RPC surface `define()` registers these methods on your node automatically. You will not call them by hand — `core.config.of()` wraps them — but they are the contract a non-bedrock-core caller would need. @@ -498,8 +472,6 @@ Every addon in a world runs arbitrary script and can write the underlying dynami `values` is a flat dot-path map of primitives, always nested under a `values` field so that an `actorId` can never collide with a schema key of the same name. ---- - ## The published schema In the same deferred pass that loads values, the flattened schema is written to replicated state: @@ -545,8 +517,6 @@ A group that names neither is absent rather than empty, so a schema that names n `core-config/schema` keeps exactly the shape it always had. A consumer written before group strings existed reads it unchanged and never sees the new key; one written after reads both and falls back to key-derived titles when the second is missing — which is the same thing it does for an addon that simply names no group. Neither side needs a version check. ::: ---- - ## `core.config.local` ```ts diff --git a/docs/server/server-runtime/features.md b/docs/server/api/features.md similarity index 90% rename from docs/server/server-runtime/features.md rename to docs/server/api/features.md index 7c7c74a..d7ed9c1 100644 --- a/docs/server/server-runtime/features.md +++ b/docs/server/api/features.md @@ -1,10 +1,11 @@ --- sidebar_position: 3 +description: "core.features declares behavior that switches itself on when a condition becomes true and off when it stops being true." --- -# FeatureManager +# core.features -`core.features` declares behaviour that switches itself on when a condition becomes true and off when it stops being true. It is how an addon reacts to `optionalDependencies` without writing its own bookkeeping. +`core.features` declares behavior that switches itself on when a condition becomes true and off when it stops being true. It is how an addon reacts to `optionalDependencies` without writing its own bookkeeping. Each feature's enabled flag is published to replicated state automatically, under the [reserved `core-` prefix](./shared.md#reserved-keys), so other addons can read it with `ctx.feature()` or `core.features.of()`. @@ -27,8 +28,6 @@ core.features.add('leaderboard-sync', { The condition is evaluated **immediately** when you call `add()`, and re-evaluated on **every** registry change and **every** replicated-state change. `onEnable` / `onDisable` are edge-triggered — they run only when the result flips. ---- - ## `FeatureSpec` ```ts @@ -57,8 +56,6 @@ condition: r => r.has('drav0011_leaderboard') Because a condition re-runs on every registry and state change — and state changes include every config-schema, translation and guide broadcast in the world — it must be a fast predicate with no side effects. Do the work in `onEnable` / `onDisable`, never in `condition`. ::: ---- - ## `FeatureConditionContext` ```ts @@ -72,7 +69,7 @@ interface FeatureConditionContext { | Member | Use it for | |---|---| | `ctx.registry` | Peer presence — the full [`Registry`](./registry.md) API. | -| `ctx.state` | Any addon's published values, via the raw [`State`](../sync/state.md) mirror (`ctx.state.get(ns, key)`). | +| `ctx.state` | Any addon's published values, via the raw [`State`](/docs/sync/state) mirror (`ctx.state.get(ns, key)`). | | `ctx.feature` | Another addon's feature flag, read straight from the state mirror. | ### Another addon's feature flag @@ -97,8 +94,6 @@ core.features.add('shop-integration', { }); ``` ---- - ## API ### `add` diff --git a/docs/server/server-runtime/guides.md b/docs/server/api/guides.md similarity index 90% rename from docs/server/server-runtime/guides.md rename to docs/server/api/guides.md index 07c5dcb..09c72d2 100644 --- a/docs/server/server-runtime/guides.md +++ b/docs/server/api/guides.md @@ -1,8 +1,9 @@ --- sidebar_position: 8 +description: "core.guides replicates each addon's compiled guide manifest across the world, so the elected host can list and render every addon's guide locally — one…" --- -# GuidesRegistry +# core.guides `core.guides` replicates each addon's **compiled guide manifest** across the world, so the [elected host](./host.md) can list and render every addon's guide locally — one in-game documentation browser for everything installed, without any addon importing another. @@ -28,11 +29,9 @@ core.guides.addonsWithGuides(); // every namespace that published one core.guides.subscribe(() => { /* … */ }); ``` ---- - ## What a manifest is -A guide is authored as Markdown and compiled by the `guides` Regolith filter into `@bedrock-core/generated/guides`. To the runtime it is an opaque payload with two known fields: +A guide is authored as MDX and compiled by the [`guides` filter](/docs/filters/guides) into `@bedrock-core/generated/guides`. To the runtime it is an opaque payload with two known fields: ```ts interface GuideManifest { @@ -53,8 +52,6 @@ Each addon publishes under its own namespace, so an addon that loads late still Reads verify only that the value is an object carrying `tree` and `pages`. Narrow it properly with `isGuideManifest` from `@bedrock-core/guides` before rendering. ---- - ## API ### `provideManifest` @@ -115,8 +112,6 @@ type GuidesChangeListener = () => void; Fires when **any** addon's published guide changes. Coarse and payload-free — re-read through `of()` / `addonsWithGuides()`. ---- - ## Guides and the host election Rendering is a job for exactly one realm, so the pattern is: diff --git a/docs/server/server-runtime/host.md b/docs/server/api/host.md similarity index 92% rename from docs/server/server-runtime/host.md rename to docs/server/api/host.md index 853fba0..c30f921 100644 --- a/docs/server/server-runtime/host.md +++ b/docs/server/api/host.md @@ -1,8 +1,9 @@ --- sidebar_position: 4 +description: "core.host answers one question: should this realm do the work that exactly one realm may do?" --- -# HostElection +# core.host `core.host` answers one question: **should this realm do the work that exactly one realm may do?** @@ -28,19 +29,15 @@ if (core.host.isHost) { core.host.subscribe(hostId => console.warn('UI host is now', hostId)); ``` ---- - ## Why it exists Bedrock's custom-command registry is **world-global** and has no unregister API, so whichever realm loads first *owns* a given command name for the life of the world. That ownership is immovable — who does the **rendering** is not. The election picks the realm running the newest `@bedrock-core/server-runtime`, and the command owner becomes a router: it forwards the request to `core.host.hostId` instead of rendering locally. The practical consequence: **installing one up-to-date bedrock-core addon upgrades the shared UI for every addon in the world**, including ones whose authors never shipped again. ---- - ## The rule -1. Highest `runtimeVersion` wins — that is [`RUNTIME_VERSION`](./server-runtime.md#version-helpers), the version of `@bedrock-core/server-runtime` each addon was built against, **not** the addon's own `version`. +1. Highest `runtimeVersion` wins — that is [`RUNTIME_VERSION`](./runtime.md#version-helpers), the version of `@bedrock-core/server-runtime` each addon was built against, **not** the addon's own `version`. 2. Ties are broken by the **lowest namespace**, compared as a plain string. Every realm sees the same [registry](./registry.md) and applies the same rule, so they all agree on the same winner without exchanging a single message. @@ -51,8 +48,6 @@ The election re-runs whenever a peer appears or disappears. A peer whose `meta` carries no usable `runtimeVersion` is treated as `0.0.0`. It loses the election instead of corrupting it. ::: ---- - ## API ### `isHost` @@ -97,8 +92,6 @@ core.host.subscribe((hostId, previousHostId) => { }); ``` ---- - ## The router pattern The shape this is built for: whichever realm receives a player-facing command does the smallest possible slice of work — identify the player, name the request, forward the raw arguments — and everything that involves a decision happens on the host. @@ -136,9 +129,7 @@ core.rpc.onRequest('core:ui.open', (params) => { Hosting can move at any time — a newer addon loads, the current host's pack is removed. Every realm that participates should register the handler at startup so it is ready if it wins later. ::: -This is exactly how [`@bedrock-core/config`](../ui-integration.md) mounts the shared config and guide UI. - ---- +This is exactly how [`@bedrock-core/config`](../guides/ui-integration.md) mounts the shared config and guide UI. ## `HostElection` standalone diff --git a/docs/server/server-runtime/registry.md b/docs/server/api/registry.md similarity index 92% rename from docs/server/server-runtime/registry.md rename to docs/server/api/registry.md index 34d3003..2d8129d 100644 --- a/docs/server/server-runtime/registry.md +++ b/docs/server/api/registry.md @@ -1,10 +1,11 @@ --- sidebar_position: 2 +description: "core.registry is a live directory of every bedrock-core addon present in the world — the local addon plus every peer discovery can currently see." --- -# Registry +# core.registry -`core.registry` is a live directory of every bedrock-core addon present in the world — the local addon plus every peer [discovery](../sync/discovery.md) can currently see. Each peer's announce `meta` blob is interpreted as an [`AddonManifest`](./server-runtime.md#manifest-fields), keyed by its namespace. +`core.registry` is a live directory of every bedrock-core addon present in the world — the local addon plus every peer [discovery](/docs/sync/discovery) can currently see. Each peer's announce `meta` blob is interpreted as an [`AddonManifest`](./runtime.md#manifest-fields), keyed by its namespace. ## Import @@ -47,8 +48,6 @@ Every entry carries the full manifest plus three fields the registry adds: A peer's manifest is reconstructed from its discovery `meta`. A node that published no meta keeps its whole namespace as `pack` and an empty string as `creator` — the id is never split back into halves. `runtimeVersion` defaults to `0.0.0` when absent or malformed, so that peer loses the host election rather than corrupting it. ::: ---- - ## API ### `all` @@ -65,8 +64,6 @@ for (const addon of core.registry.all()) { } ``` ---- - ### `get` ```ts @@ -75,8 +72,6 @@ core.registry.get(id: string): RegisteredAddon | undefined Look up an addon by its namespace. Returns the local addon when `id === core.id`. ---- - ### `has` ```ts @@ -85,8 +80,6 @@ core.registry.has(id: string): boolean Whether an addon with that namespace is present. This is the predicate feature conditions are usually built from — see [FeatureManager](./features.md). ---- - ### `onRegister` ```ts @@ -108,8 +101,6 @@ off(); `onRegister` only fires for peers that appear *after* you subscribe. Peers already present are in `all()`. Since addons load in undefined order, code that must react to a peer either way should check `has()`/`all()` first and then subscribe — or use a [feature](./features.md), which evaluates its condition immediately and on every change. ::: ---- - ### `onUnregister` ```ts @@ -118,8 +109,6 @@ core.registry.onUnregister(listener: AddonListener): Unsubscribe Fires when a peer goes away — that is, when discovery evicts it after its TTL elapses without a heartbeat. ---- - ### `onNamespaceCollision` ```ts @@ -131,7 +120,7 @@ interface CollisionInfo { } ``` -Fires when **another instance is announcing our own namespace** — two packs both registered `creator` + `pack` with identical halves. The runtime also logs: +Fires when **another instance is announcing this addon's namespace** — two packs both registered `creator` + `pack` with identical halves. The runtime also logs: ``` [bedrock-core] collision: another instance shares identity '' @@ -145,8 +134,6 @@ core.registry.onNamespaceCollision((info) => { }); ``` ---- - ### `incompatible` ```ts @@ -160,7 +147,7 @@ interface IncompatiblePeer { } ``` -Addons heard on the bus that this build cannot talk to, because the [protocol ranges](../sync/discovery.md#protocol-negotiation) the two were built with do not overlap. They are present in the world but absent from [`all()`](#all): without a conversation there is no manifest to read. +Addons heard on the bus that this build cannot talk to, because the [protocol ranges](/docs/sync/discovery#protocol-negotiation) the two were built with do not overlap. They are present in the world but absent from [`all()`](#all): without a conversation there is no manifest to read. They are listed rather than ignored because the alternative is worse than an error. An addon that cannot be reached, silently left out, looks exactly like an addon that was never installed — the addon list is confidently wrong instead of visibly incomplete. @@ -178,8 +165,6 @@ Fires the **first** time such an addon is heard. The runtime also logs: The fix is always to update one of the two packs; there is no runtime setting that bridges the gap. ---- - ## Dependencies Dependencies are declared and matched by namespace, and they are **soft**: a missing one is reported but never blocks the addon from loading or running. diff --git a/docs/server/server-runtime/server-runtime.md b/docs/server/api/runtime.md similarity index 92% rename from docs/server/server-runtime/server-runtime.md rename to docs/server/api/runtime.md index 1394747..24c80cf 100644 --- a/docs/server/server-runtime/server-runtime.md +++ b/docs/server/api/runtime.md @@ -1,16 +1,15 @@ --- sidebar_position: 1 +description: "@bedrock-core/server-runtime is the framework layer addons build on." --- -# server-runtime +# core -`@bedrock-core/server-runtime` is the framework layer addons build on. Where [`@bedrock-core/sync`](../sync/sync.md) is the low-level transport, the runtime is the thing you **register into**: an addon declares its identity and its data once, and that declaration flows into a cross-addon registry — a live directory of every bedrock-core addon present in the world. +`@bedrock-core/server-runtime` is the framework layer addons build on. Where [`@bedrock-core/sync`](/docs/sync) is the low-level transport, the runtime is the thing you **register into**: an addon declares its identity and its data once, and that declaration flows into a cross-addon registry — a live directory of every bedrock-core addon present in the world. ## Install -```bash -npm install @bedrock-core/server-runtime -``` + Most addons install [`@bedrock-core/server`](https://www.npmjs.com/package/@bedrock-core/server) instead, which re-exports everything below and pins a matching `@bedrock-core/sync`. Both imports are interchangeable: @@ -38,17 +37,15 @@ Every accessor below throws `runtime. is unavailable: call register() firs | `core.namespace` | `string` | Alias of `core.id`. | | `core.manifest` | `AddonManifest` | The validated manifest, identity fields only. | | `core.registry` | [`Registry`](./registry.md) | The cross-addon directory. | -| `core.features` | [`FeatureManager`](./features.md) | Condition-driven togglable behaviour. | +| `core.features` | [`FeatureManager`](./features.md) | Condition-driven togglable behavior. | | `core.host` | [`HostElection`](./host.md) | Which realm does the work only one realm may do. | | `core.shared` | [`SharedRegistry`](./shared.md) | The replicated mirror as typed trees: `of(ns)` for a peer's, `own` for this addon's. | | `core.state` | `ScopedState` | Deprecated string-keyed access to this addon's namespace; declare `shared` in `register()` instead. | | `core.config` | [`ConfigRegistry`](./config.md) | Schema, scopes and cross-addon config access. | | `core.translations` | [`TranslationsRegistry`](./translations.md) | Cross-addon i18n bundles. | | `core.guides` | [`GuidesRegistry`](./guides.md) | Cross-addon compiled guides. | -| `core.rpc` | `Rpc` | [RPC](../sync/rpc.md), passed through from the sync node. | -| `core.node` | `SyncNode` | The raw [sync node](../sync/sync.md) — bus, discovery, unscoped state. | - ---- +| `core.rpc` | `Rpc` | [RPC](/docs/sync/rpc), passed through from the sync node. | +| `core.node` | `SyncNode` | The raw [sync node](/docs/sync) — bus, discovery, unscoped state. | ## `register()` @@ -95,8 +92,6 @@ const { config } = core.register({ config.server.get(); // fully typed ``` ---- - ## Manifest fields ```ts @@ -163,8 +158,6 @@ core.register({ `addonNamespace(manifest)` is exported too, and simply returns `` `${manifest.creator}_${manifest.pack}` ``. ---- - ## `stop()` ```ts @@ -173,8 +166,6 @@ core.stop(); Take the addon offline and clear every accessor. Safe to call before registering (no-op). Mostly useful in GameTests — a shipped addon registers and stays up. ---- - ## Several runtimes in one realm The `Runtime` class stands alone, so a GameTest can create **several runtimes in one script realm**. They talk over the real `system` script-event bus, and each `register()` brings its runtime online independently. @@ -215,8 +206,6 @@ register('core', 'discovery_and_rpc', (test: Test) => { Use `core` — the singleton — in a real addon. One identity per pack. ---- - ## Version helpers ```ts @@ -226,14 +215,12 @@ import { RUNTIME_VERSION, compareVersions } from '@bedrock-core/server-runtime'; - **`RUNTIME_VERSION`** — the version of `@bedrock-core/server-runtime` this build was compiled against. It is stamped into the discovery `meta` blob automatically, surfaces on every registry entry as `runtimeVersion`, and is what the [host election](./host.md) compares. It is generated at release time; addons never set it. - **`compareVersions(a, b)`** — minimal semver comparison returning `-1` / `0` / `1`, suitable for `Array.prototype.sort`. Handles `major.minor.patch` with an optional `-prerelease` tail; anything unparseable sorts as `0.0.0` rather than throwing. ---- - -## In This Section +## In this section | Page | Description | |---|---| | [Registry](./registry.md) | Enumerate peers, resolve dependencies, detect namespace collisions | -| [FeatureManager](./features.md) | Behaviour that toggles on a condition over registry and state | +| [FeatureManager](./features.md) | Behavior that toggles on a condition over registry and state | | [HostElection](./host.md) | `core.host` — deterministic "who does the shared work" | | [Shared](./shared.md) | The replicated mirror as typed trees, owner-only writes, `open()` and `persisted()` | | [ConfigRegistry](./config.md) | Schema, three scopes, persistence, cross-addon access, authorization | diff --git a/docs/server/server-runtime/shared.md b/docs/server/api/shared.md similarity index 93% rename from docs/server/server-runtime/shared.md rename to docs/server/api/shared.md index 2cda275..285d75c 100644 --- a/docs/server/server-runtime/shared.md +++ b/docs/server/api/shared.md @@ -1,10 +1,11 @@ --- sidebar_position: 5 +description: "core.shared is the replicated mirror every realm holds, as typed trees." --- -# Shared +# core.shared -`core.shared` is the replicated mirror every realm holds, as typed trees. An addon declares a shape once, in `register()`, and gets a tree back whose every node reads, writes and subscribes; every other realm mirrors it and reads it through `core.shared.of()`. Reads are local and synchronous. Writes broadcast a delta over sync's [`State`](../sync/state.md). +`core.shared` is the replicated mirror every realm holds, as typed trees. An addon declares a shape once, in `register()`, and gets a tree back whose every node reads, writes and subscribes; every other realm mirrors it and reads it through `core.shared.of()`. Reads are local and synchronous. Writes broadcast a delta over sync's [`State`](/docs/sync/state). Two rules make it safe to build on: @@ -117,16 +118,4 @@ core.node.state.get(core.id, 'core-config/schema'); ## `core.state` -The string-keyed `core.state` (`set` / `get` / `delete` / `getNamespace` / `subscribe` on this addon's namespace, framework keys hidden) is deprecated in favour of the tree and goes away in a later minor. Everything it did is a leaf now: - -```ts -// before -core.state.set('currency', 'gold'); -core.node.state.get('drav0011_economy', 'currency'); -core.state.subscribe(change => save(change.key, change.value)); - -// after -shared.currency.set('gold'); -core.shared.of('drav0011_economy')?.currency.get(); -// nothing — `persisted()` in the declaration -``` +The string-keyed `core.state` (`set` / `get` / `delete` / `getNamespace` / `subscribe` on this addon's namespace, framework keys hidden) is deprecated: a leaf of the tree covers each of its calls, and `persisted()` in the declaration replaces subscribing to save. It is removed in a later minor. diff --git a/docs/server/server-runtime/translations.md b/docs/server/api/translations.md similarity index 84% rename from docs/server/server-runtime/translations.md rename to docs/server/api/translations.md index 370db75..ca4a43a 100644 --- a/docs/server/server-runtime/translations.md +++ b/docs/server/api/translations.md @@ -1,8 +1,9 @@ --- sidebar_position: 7 +description: "core.translations replicates each addon's i18n bundle across the world, so one addon can resolve, measure and render another addon's strings server-side." --- -# TranslationsRegistry +# core.translations `core.translations` replicates each addon's **i18n bundle** across the world, so one addon can resolve, measure and render another addon's strings server-side. @@ -15,7 +16,7 @@ import { core } from '@bedrock-core/server-runtime'; import type { I18nBundle, TranslationResolver, TranslationsChangeListener } from '@bedrock-core/server-runtime'; ``` -`I18nBundle` and `TranslationResolver` are re-exported from [`@bedrock-core/i18n`](../ui-integration.md#i18n), which `server-runtime` depends on. +`I18nBundle` and `TranslationResolver` are re-exported from [`@bedrock-core/i18n`](../guides/ui-integration.md#i18n), which `server-runtime` depends on. ## Usage @@ -31,11 +32,9 @@ core.translations.forLocale('en_US'); // chained resolver for one locale core.translations.subscribe(() => { /* … */ }); // any addon re-published ``` ---- - ## What travels -The registry replicates the **bundle itself** — the module the i18n Regolith filter generates (`@bedrock-core/generated/i18n`), or `createResourceBundle`'s runtime equivalent. Templates stay in `{{var}}` form with their recorded argument order. +The registry replicates the **bundle itself** — the module the [i18n filter](/docs/filters/i18n) generates (`@bedrock-core/generated/i18n`), or `createResourceBundle`'s runtime equivalent. Templates stay in `{{var}}` form with their recorded argument order. ``` → core-i18n/bundle → I18nBundle @@ -43,8 +42,6 @@ The registry replicates the **bundle itself** — the module the i18n Regolith f Late joiners are covered by sync's snapshot exchange, so an addon that loads after everyone else still sees every bundle. A payload that fails structural validation is ignored rather than replacing a good one. ---- - ## API ### `provide` @@ -135,8 +132,6 @@ type TranslationsChangeListener = () => void; Fires when **any** addon's published bundle changes. It is deliberately coarse — it carries no payload. Re-read through `of()` / `forLocale()` / `forPlayer()`, which return freshly rebuilt views. ---- - ## Display fields are keys -`packName`, `creatorName` and `description` are i18n keys — see [display fields](./server-runtime.md#display-fields-are-translation-keys) for the `register()` call. Publishing the bundle alongside them is what lets a *different* addon's UI render your `packName` in the player's language: the client resolves a key on its own when the string is sent as a `RawMessage`, but a host realm laying out a screen has to resolve and **measure** it server-side. +`packName`, `creatorName` and `description` are i18n keys — see [display fields](./runtime.md#display-fields-are-translation-keys) for the `register()` call. Publishing the bundle alongside them is what lets a *different* addon's UI render your `packName` in the player's language: the client resolves a key on its own when the string is sent as a `RawMessage`, but a host realm laying out a screen has to resolve and **measure** it server-side. diff --git a/docs/server/get-started/_category_.json b/docs/server/get-started/_category_.json deleted file mode 100644 index 94b132d..0000000 --- a/docs/server/get-started/_category_.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "position": 1, - "label": "Get started", - "key": "get-started", - "collapsible": true, - "collapsed": false, - "link": { - "type": "doc", - "id": "overview" - } -} \ No newline at end of file diff --git a/docs/server/get-started/overview.md b/docs/server/get-started/overview.md deleted file mode 100644 index b935578..0000000 --- a/docs/server/get-started/overview.md +++ /dev/null @@ -1,53 +0,0 @@ ---- -sidebar_position: 1 ---- - -# Overview - -Get two Minecraft addons talking to each other. - -:::caution Pre-1.0 -The `@bedrock-core` server packages are under active development. Breaking changes can still land until `1.0.0` — pin exact versions and read the release notes before upgrading. -::: - -## What is @bedrock-core/server? - -Every behavior pack runs its scripts in its **own isolated realm**. Two packs in the same world cannot import each other, share a module, or see each other's variables. - -`@bedrock-core/server` builds a framework on top of the one thing that does cross a realm boundary: script events. Addons discover each other at runtime, call each other, share state, and expose their settings and guides through one common surface. - -``` -world - ├─ drav0011_economy serves getBalance over RPC, publishes its config schema - ├─ drav0011_shop depends on economy, calls it, publishes its own schema - └─ someone_leaderboard shop's optional feature lights up because it is present -``` - -None of them imported each other. They found each other at runtime. - -## Install one package - -```bash -npm install @bedrock-core/server -``` - -That is the answer for an addon. It is a meta-package that pins a matching set of the stack and re-exports everything, so `import { core } from '@bedrock-core/server'` is all you need. The transport stays available at `@bedrock-core/server/sync` if you ever want it, and the runtime already owns exactly one node and hands it to you as `core.node`. - -The two packages underneath — [`@bedrock-core/server-runtime`](../server-runtime/server-runtime.md) (registry, features, config, guides, translations, host election) and [`@bedrock-core/sync`](../sync/sync.md) (bus, discovery, RPC, replicated state) — are strictly layered and installable on their own if you are building a framework layer of your own. - -## What you get - -- **[Registry](../server-runtime/registry.md)** — declare `creator` + `pack` once and every other bedrock-core addon sees you, with version, dependencies and display labels. Missing soft dependencies log and fire an event; they never block loading. -- **[RPC](../sync/rpc.md)** — typed request/response calls to another addon, with a timeout so an absent peer can never hang your code. -- **[Shared](../server-runtime/shared.md)** — a declared shape every realm mirrors locally as a typed tree. Reads are synchronous; writes broadcast a delta; only the owner writes. -- **[Config](../server-runtime/config.md)** — a declarative schema in three scopes (server, dimension, player), persisted automatically and editable in game. -- **[Features](../server-runtime/features.md)** — behaviour that auto-enables when a condition over the registry becomes true, and auto-disables when it stops being true. -- **[Translations](../server-runtime/translations.md)** and **[guides](../server-runtime/guides.md)** — publish your i18n bundle and compiled guide so any addon's UI can render your content. -- **[Host election](../server-runtime/host.md)** — a deterministic rule for "which realm does the work only one realm may do". - -## Next Steps - -- [Installation](./installation.md) - Scaffold with the CLI, or install and register by hand -- [server-runtime](../server-runtime/server-runtime.md) - The runtime reference: `core`, registry, features, host, state, config -- [sync](../sync/sync.md) - The transport reference: nodes, discovery, RPC, replicated state -- [UI integration](../ui-integration.md) - How config, translations and guides feed the UI packages diff --git a/docs/server/guides/_category_.json b/docs/server/guides/_category_.json new file mode 100644 index 0000000..843fe72 --- /dev/null +++ b/docs/server/guides/_category_.json @@ -0,0 +1,11 @@ +{ + "position": 3, + "label": "Guides", + "collapsible": true, + "collapsed": false, + "link": { + "type": "generated-index", + "title": "Guides", + "description": "How the server side fits together and how other packages read it." + } +} diff --git a/docs/server/ui-integration.md b/docs/server/guides/ui-integration.md similarity index 70% rename from docs/server/ui-integration.md rename to docs/server/guides/ui-integration.md index b95e3d6..9e96b20 100644 --- a/docs/server/ui-integration.md +++ b/docs/server/guides/ui-integration.md @@ -1,10 +1,11 @@ --- -sidebar_position: 4 +sidebar_position: 1 +description: "The server side stores, validates and replicates data." --- # UI integration -The server side stores, validates and replicates data. It draws nothing. Presentation lives in the `@bedrock-core` **ui** packages — start at the [ui overview](/docs/ui/get-started/overview) for their full reference. +The server side stores, validates and replicates data. It draws nothing. Presentation lives in the `@bedrock-core` **ui** packages — start at the [ui overview](/docs/ui) for their full reference. This page is the seam between the two: what `server-runtime` publishes, which UI package consumes it, and what you have to do in your addon to light it up. @@ -34,8 +35,6 @@ This page is the seam between the two: what `server-runtime` publishes, which UI **The UI reads the registries, not your addon.** It never imports your code and never knows your schema type — everything it draws it discovered at runtime from replicated state. ---- - ## Mounting the shared UI One call, after `core.register()`: @@ -57,17 +56,15 @@ core.register({ ui(core); ``` -`ui` comes from [`@bedrock-core/config`](/docs/ui/config) — the shared addon list, settings screens and guide viewer. `ui(core)` registers this addon's commands and serves the open RPC, so this realm can render on behalf of another whenever it wins the [host election](./server-runtime/host.md). +`ui` comes from [`@bedrock-core/config`](/docs/config) — the shared addon list, settings screens and guide viewer. `ui(core)` registers this addon's commands and serves the open RPC, so this realm can render on behalf of another whenever it wins the [host election](../api/host.md). -Pass the `Runtime` itself, not the typed config accessors — everything `ui` needs it reaches generically, through [`core.config.local`](./server-runtime/config.md#coreconfiglocal), `core.config.of()`, `core.registry`, `core.guides`, `core.translations` and `core.host`. - ---- +Pass the `Runtime` itself, not the typed config accessors — everything `ui` needs it reaches generically, through [`core.config.local`](../api/config.md#coreconfiglocal), `core.config.of()`, `core.registry`, `core.guides`, `core.translations` and `core.host`. ## The three feeds ### Config -[`ConfigRegistry`](./server-runtime/config.md) publishes a **flattened, scope-prefixed schema** to replicated state: +[`ConfigRegistry`](../api/config.md) publishes a **flattened, scope-prefixed schema** to replicated state: ``` → core-config/schema → { @@ -86,15 +83,15 @@ The schema describes **data only**; the UI picks the control: | `type: 'number'` with `min`/`max`/`step` | a slider or a numeric input | | `type: 'string'` with `maxLength` | a text input | | `type: 'enum'` with `options` | a dropdown or a toggle-button row | -| `type: 'list'` with `itemType`/`maxItems` | *no control* — a modal form has nothing to draw for it. The screen shows the label, the current items against `maxItems`, and the command that changes it; editing goes through [`get`/`set`/`add`/`remove`](/docs/ui/config#list-settings-from-a-command) | +| `type: 'list'` with `itemType`/`maxItems` | *no control* — a modal form has nothing to draw for it. The screen shows the label, the current items against `maxItems`, and the command that changes it; editing goes through [`get`/`set`/`add`/`remove`](/docs/config#list-settings-from-a-command) | -Authorization crosses the seam too. When the UI acts for a player it builds its accessor with `core.config.of(addonId, { actorId: player.id })`, and the owning addon applies [the operator rule](./server-runtime/config.md#authorization) on its side. The caller-side permission checks in the UI are a convenience — they keep unreachable settings out of a player's command list and screens — but the decision that counts is made by the addon that owns the data. +Authorization crosses the seam too. When the UI acts for a player it builds its accessor with `core.config.of(addonId, { actorId: player.id })`, and the owning addon applies [the operator rule](../api/config.md#authorization) on its side. The caller-side permission checks in the UI are a convenience — they keep unreachable settings out of a player's command list and screens — but the decision that counts is made by the addon that owns the data. ### i18n -[`TranslationsRegistry`](./server-runtime/translations.md) replicates each addon's `I18nBundle` — the artifact the `i18n` Regolith filter generates as `@bedrock-core/generated/i18n`. +[`TranslationsRegistry`](../api/translations.md) replicates each addon's `I18nBundle` — the artifact the `i18n` Regolith filter generates as `@bedrock-core/generated/i18n`. -`packName`, `creatorName` and `description` are translation keys in *someone else's* resource pack. `core.translations.forPlayer(player)` resolves them against every published bundle, picking the player's locale through the [override → client locale → sibling region → default chain](/docs/ui/i18n#locale-resolution). +`packName`, `creatorName` and `description` are translation keys in *someone else's* resource pack. `core.translations.forPlayer(player)` resolves them against every published bundle, picking the player's locale through the [override → client locale → sibling region → default chain](/docs/i18n#locale-resolution). Declare `translations`, or the realm rendering your addon can neither resolve your labels nor **measure** them — and layout needs a string's width before it is sent to the client. @@ -108,9 +105,9 @@ for (const addon of core.registry.all()) { ### Guides -[`GuidesRegistry`](./server-runtime/guides.md) replicates each addon's compiled `GuideManifest` — the `guides` Regolith filter's output, `@bedrock-core/generated/guides`. +[`GuidesRegistry`](../api/guides.md) replicates each addon's compiled `GuideManifest` — the `guides` Regolith filter's output, `@bedrock-core/generated/guides`. -The runtime treats it as opaque: two fields, `tree` and `pages`, and no interpretation. [`@bedrock-core/guides`](/docs/ui/guides) owns the real intermediate representation and narrows the payload with `isGuideManifest` at the point of rendering. +The runtime treats it as opaque: two fields, `tree` and `pages`, and no interpretation. [`@bedrock-core/guides`](/docs/guides) owns the real intermediate representation and narrows the payload with `isGuideManifest` at the point of rendering. Because manifests are replicated rather than fetched, the elected host already has every guide in memory: @@ -120,13 +117,9 @@ for (const id of core.guides.addonsWithGuides()) { } ``` ---- - ## Which realm renders -The realm whose command was typed forwards the raw request to the realm running the newest `@bedrock-core/server-runtime`, and every decision happens there. See [HostElection](./server-runtime/host.md). - ---- +The realm whose command was typed forwards the raw request to the realm running the newest `@bedrock-core/server-runtime`, and every decision happens there. See [HostElection](../api/host.md). ## What you have to do @@ -139,9 +132,7 @@ The realm whose command was typed forwards the raw request to the realm running | Call `ui(core)` once, after `register()` | Registers your commands and serves the open RPC | | Ship the generated artifacts | The `i18n` and `guides` Regolith filters produce `@bedrock-core/generated/*` | -Everything else is the ui side's job: [screens and components](/docs/ui/ui-runtime), [navigation](/docs/ui/navigation), [theming](/docs/ui/ore-styled), and [per-player locale](/docs/ui/i18n). - ---- +Everything else is the ui side's job: [screens and components](/docs/ui), [navigation](/docs/navigation), [theming](/docs/ore-styled), and [per-player locale](/docs/i18n). ## The generated imports @@ -152,26 +143,13 @@ import bundle from '@bedrock-core/generated/i18n'; // the i18n filter's outpu import guides from '@bedrock-core/generated/guides'; // the guides filter's output ``` -Those specifiers are aliases mapped in `tsconfig.json` to the filter's generated JSON, and inlined by the [`bundler` Regolith filter](https://github.com/bedrock-core/regolith-filters) at build time: +The specifiers are `tsconfig.json` aliases the [`bundler`](/docs/filters/bundler) inlines at build time; the [`i18n`](/docs/filters/i18n) and [`guides`](/docs/filters/guides) filter pages cover the aliases, the outputs and the `namespace` they derive from `register()`. -```jsonc title="tsconfig.json" -{ - "compilerOptions": { - "paths": { - "@bedrock-core/generated/i18n": ["./packs/data/i18n/i18n.generated.json"], - "@bedrock-core/generated/guides": ["./packs/data/guides/guides.generated.json"] - } - } -} -``` +An addon with no guide omits the `guide` field and the filter; the registries handle absence everywhere (`core.guides.of()` returns `undefined`, `core.config.of()` returns `undefined`, resolvers fall through). -Both filters take a `namespace` setting, which must be **your addon's namespace** — the same `creator_pack` string you pass to `register()`: - -```jsonc title="config.json (Regolith)" -{ - "filter": "i18n", - "settings": { "namespace": "drav0011_economy" } -} -``` +## Next steps -An addon with no guide simply omits the `guide` field and the filter; the registries handle absence everywhere (`core.guides.of()` returns `undefined`, `core.config.of()` returns `undefined`, resolvers fall through). +- [`core.config`](../api/config.md) — schema types, scopes and authorization +- [`core.translations`](../api/translations.md) — what the bundle publishes +- [`core.guides`](../api/guides.md) — the manifest the runtime replicates +- [config](/docs/config) — the shared UI that reads all three diff --git a/docs/server/index.md b/docs/server/index.md new file mode 100644 index 0000000..d1ee494 --- /dev/null +++ b/docs/server/index.md @@ -0,0 +1,54 @@ +--- +slug: / +sidebar_position: 1 +sidebar_label: Overview +description: "Get two Minecraft addons talking to each other." +--- + +# server + +Get two Minecraft addons talking to each other. + +:::caution Pre-1.0 +The `@bedrock-core` server packages are under active development. Breaking changes can still land until `1.0.0` — pin exact versions and read the release notes before upgrading. +::: + +## What is @bedrock-core/server? + +Every behavior pack runs its scripts in its **own isolated realm**. Two packs in the same world cannot import each other, share a module, or see each other's variables. + +`@bedrock-core/server` builds a framework on top of the one thing that does cross a realm boundary: script events. Addons discover each other at runtime, call each other, share state, and expose their settings and guides through one common surface. + +``` +world + ├─ drav0011_economy serves getBalance over RPC, publishes its config schema + ├─ drav0011_shop depends on economy, calls it, publishes its own schema + └─ someone_leaderboard shop's optional feature lights up because it is present +``` + +None of them imported each other. They found each other at runtime. + +## Install one package + + + +That is the answer for an addon. It is a meta-package that pins a matching set of the stack and re-exports everything, so `import { core } from '@bedrock-core/server'` is all you need. The transport stays available at `@bedrock-core/server/sync` if you ever want it, and the runtime already owns exactly one node and hands it to you as `core.node`. + +The two packages underneath — [`@bedrock-core/server-runtime`](./api/runtime.md) (registry, features, config, guides, translations, host election) and [`@bedrock-core/sync`](/docs/sync) (bus, discovery, RPC, replicated state) — are strictly layered and installable on their own if you are building a framework layer of your own. + +## What you get + +- **[Registry](./api/registry.md)** — declare `creator` + `pack` once and every other bedrock-core addon sees you, with version, dependencies and display labels. Missing soft dependencies log and fire an event; they never block loading. +- **[RPC](/docs/sync/rpc)** — typed request/response calls to another addon, with a timeout so an absent peer can never hang your code. +- **[Shared](./api/shared.md)** — a declared shape every realm mirrors locally as a typed tree. Reads are synchronous; writes broadcast a delta; only the owner writes. +- **[Config](./api/config.md)** — a declarative schema in three scopes (server, dimension, player), persisted automatically and editable in game. +- **[Features](./api/features.md)** — behavior that auto-enables when a condition over the registry becomes true, and auto-disables when it stops being true. +- **[Translations](./api/translations.md)** and **[guides](./api/guides.md)** — publish your i18n bundle and compiled guide so any addon's UI can render your content. +- **[Host election](./api/host.md)** — a deterministic rule for "which realm does the work only one realm may do". + +## Next steps + +- [Installation](./installation.md) — Scaffold with the CLI, or install and register by hand +- [server-runtime](./api/runtime.md) — The runtime reference: `core`, registry, features, host, state, config +- [sync](/docs/sync) — The transport reference: nodes, discovery, RPC, replicated state +- [UI integration](./guides/ui-integration.md) — How config, translations and guides feed the UI packages diff --git a/docs/server/get-started/installation.md b/docs/server/installation.md similarity index 78% rename from docs/server/get-started/installation.md rename to docs/server/installation.md index 5402e1e..61ea599 100644 --- a/docs/server/get-started/installation.md +++ b/docs/server/installation.md @@ -1,5 +1,6 @@ --- sidebar_position: 2 +description: "Get a bedrock-core addon online, then get a second one talking to it." --- # Installation @@ -11,43 +12,17 @@ Get a bedrock-core addon online, then get a second one talking to it. - Node.js 20+ and Yarn (or npm) — https://nodejs.org/ - Regolith (recommended) — https://regolith-docs.readthedocs.io/en/stable -## Quick Start with CLI (Recommended) +## Quick start with the CLI -The fastest way to get started is using our [CLI](/docs/ui/cli) to scaffold a complete project: +The [CLI](/docs/cli) scaffolds a full-stack addon: `core.register()` called with your ids, a typed config schema, translations and a guide wired to their filters, `@bedrock-core/ui` screens mounted, and the Regolith build. With a scaffold you can skip the rest of this page. -```bash -npx @bedrock-core/cli -``` - -The scaffold is full-stack — it wires the server side up for you, so you can skip the rest of this page: - -- ✅ `core.register()` already called, with your creator/pack ids filled in -- ✅ A typed config schema, replicated and editable in game -- ✅ Translations and an in-game guide, wired to the i18n and guides filters -- ✅ `@bedrock-core/ui` screens mounted with `ui(core)` -- ✅ Regolith build configuration and the render pack + -After generation: - -```bash -cd your-addon-name -yarn install # or npm install -yarn regolith-install # Install Regolith filters -yarn build # Build the addon -yarn watch # Watch for changes and redeploy -``` - -## Manual Installation +## Manual installation If you're adding to an existing project, install the package: -```bash -yarn add @bedrock-core/server -``` - -```bash -npm install @bedrock-core/server -``` + That single dependency pins matching versions of `@bedrock-core/server-runtime` and `@bedrock-core/sync`, and re-exports them: @@ -57,7 +32,7 @@ import { createSync } from '@bedrock-core/server/sync'; // the raw transport, ra ``` :::info The packages ship TypeScript sources -Their `exports` map points at `src/*.ts` rather than at compiled JavaScript, so whatever bundles your behavior pack compiles them along with your own code. The [`bundler` Regolith filter](https://github.com/bedrock-core/regolith-filters) handles this out of the box; a hand-rolled build needs a bundler that can consume TypeScript from `node_modules`. +Their `exports` map points at `src/*.ts` rather than at compiled JavaScript, so whatever bundles your behavior pack compiles them along with your own code. The [`bundler` filter](/docs/filters/bundler) handles this out of the box; a hand-rolled build needs a bundler that can consume TypeScript from `node_modules`. ::: ## Register @@ -100,9 +75,9 @@ There is no colon form anywhere in the API. `core.id` is a plain lowercase names That one namespace is the sync transport address other addons send to, the replicated-state namespace this addon owns, and the namespace of every command and command enum the addon registers. -Two addons collide only when **both** halves match. A creator shipping several addons uses distinct `pack` ids (`drav0011_economy`, `drav0011_shop`) and they coexist happily. Two packs registering `drav0011_economy` collide: the runtime logs an error and fires [`core.registry.onNamespaceCollision`](../server-runtime/registry.md#onnamespacecollision). +Two addons collide only when **both** halves match. A creator shipping several addons uses distinct `pack` ids (`drav0011_economy`, `drav0011_shop`) and they coexist happily. Two packs registering `drav0011_economy` collide: the runtime logs an error and fires [`core.registry.onNamespaceCollision`](./api/registry.md#onnamespacecollision). -`packName`, `creatorName` and `description` are display labels and play no part in identity. See [manifest fields](../server-runtime/server-runtime.md#manifest-fields) for the full list. +`packName`, `creatorName` and `description` are display labels and play no part in identity. See [manifest fields](./api/runtime.md#manifest-fields) for the full list. ## A minimal working addon @@ -175,7 +150,7 @@ world.afterEvents.playerSpawn.subscribe(({ player, initialSpawn }) => { :::caution Dynamic properties are unreadable during early execution Anything that touches `world.getDynamicProperty` / `setDynamicProperty` — including your own persistence — must be deferred with `system.run()`. The runtime already does this for config: persisted values load one tick after registration, and change listeners fire for every key whose stored value differs from its default, so a subscriber attached right after `register()` still ends up seeing the real values. -Nothing in the shared mirror survives a reload unless the leaf is declared `persisted()` — see [Persistence](../server-runtime/shared.md#persistence). +Nothing in the shared mirror survives a reload unless the leaf is declared `persisted()` — see [Persistence](./api/shared.md#persistence). ::: ## Getting two addons talking @@ -215,7 +190,7 @@ core.registry.onDependenciesSatisfied(() => { .catch((error: unknown) => console.warn(`[shop] balance request failed: ${String(error)}`)); }); -// Behaviour that only exists when a leaderboard addon is installed. +// Behavior that only exists when a leaderboard addon is installed. core.features.add('leaderboard-sync', { condition: ctx => ctx.registry.has('drav0011_leaderboard'), onEnable() { console.warn('[shop] leaderboard sync on'); }, @@ -229,8 +204,8 @@ Addons load in undefined order and messages flush over ticks, so you will never ## Next steps -- [server-runtime](../server-runtime/server-runtime.md) — the full runtime reference -- [ConfigRegistry](../server-runtime/config.md) — schema types, scopes, cross-addon access and authorization -- [Registry](../server-runtime/registry.md) — enumerating peers, dependencies and collisions -- [sync](../sync/sync.md) — the transport underneath, when you need it directly -- [UI integration](../ui-integration.md) — turning your schema and guides into player-facing screens +- [server-runtime](./api/runtime.md) — the full runtime reference +- [ConfigRegistry](./api/config.md) — schema types, scopes, cross-addon access and authorization +- [Registry](./api/registry.md) — enumerating peers, dependencies and collisions +- [sync](/docs/sync) — the transport underneath, when you need it directly +- [UI integration](./guides/ui-integration.md) — turning your schema and guides into player-facing screens diff --git a/docs/server/server-runtime/_category_.json b/docs/server/server-runtime/_category_.json deleted file mode 100644 index a53d8df..0000000 --- a/docs/server/server-runtime/_category_.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "position": 2, - "label": "server-runtime", - "key": "server-runtime", - "collapsible": true, - "collapsed": true, - "link": { - "type": "doc", - "id": "server-runtime" - } -} diff --git a/docs/server/sync/_category_.json b/docs/server/sync/_category_.json deleted file mode 100644 index d40cf3f..0000000 --- a/docs/server/sync/_category_.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "position": 3, - "label": "sync", - "key": "sync", - "collapsible": true, - "collapsed": true, - "link": { - "type": "doc", - "id": "sync" - } -} diff --git a/docs/server/sync/discovery.md b/docs/sync/discovery.md similarity index 81% rename from docs/server/sync/discovery.md rename to docs/sync/discovery.md index f46181a..9350d42 100644 --- a/docs/server/sync/discovery.md +++ b/docs/sync/discovery.md @@ -1,5 +1,6 @@ --- sidebar_position: 2 +description: "sync.discovery finds the other bedrock-core nodes in the world and keeps a live list of them." --- # Discovery @@ -24,9 +25,7 @@ const peers = sync.discovery.peers; const economy = sync.discovery.getPeer('drav0011_economy'); ``` -From a runtime, the same information arrives pre-interpreted through [`core.registry`](../server-runtime/registry.md), which turns each peer's `meta` into an addon manifest. Reach for `core.node.discovery` only when you want the raw peer records. - ---- +From a runtime, the same information arrives pre-interpreted through [`core.registry`](/docs/server/api/registry), which turns each peer's `meta` into an addon manifest. Reach for `core.node.discovery` only when you want the raw peer records. ## `PeerInfo` @@ -48,12 +47,10 @@ interface PeerInfo { | `version` | Whatever it passed as `version`, or `'0.0.0'`. | | `schemaVersion` | Whatever it passed as `schemaVersion`, or `0`. | | `protocol` | The wire version this node and that peer [settled on](#protocol-negotiation). | -| `caps` | Optional behaviours the peer can read, narrowed to what `protocol` allows. | +| `caps` | Optional behaviors the peer can read, narrowed to what `protocol` allows. | | `meta` | The opaque blob it attached to its announce. `server-runtime` puts the addon manifest plus `runtimeVersion` here. | | `lastSeen` | The tick this peer was last heard from. | ---- - ## Protocol negotiation Discovery is also where two nodes agree on what to speak. Every announce carries the range its sender supports, and hearing one settles the pair on the newest version both know: @@ -62,13 +59,13 @@ Discovery is also where two nodes agree on what to speak. Every announce carries agreed = min(PROTOCOL_MAX, theirMax) // valid while agreed >= max(PROTOCOL_MIN, theirMin) ``` -Nothing is exchanged to arrive at this. Both sides apply the same rule to the same two advertised ranges, so they reach the same answer from one message — the same reasoning the runtime's [host election](../server-runtime/host.md) uses. The result is pushed to the bus, which encodes traffic for that peer at it. +Nothing is exchanged to arrive at this. Both sides apply the same rule to the same two advertised ranges, so they reach the same answer from one message — the same reasoning the runtime's [host election](/docs/server/api/host) uses. The result is pushed to the bus, which encodes traffic for that peer at it. An announce with no range at all comes from a node built before the field existed, which pins it to `PROTOCOL_MIN` exactly. ### Capabilities -`caps` carries optional behaviours a node can **read**, so a sender consults the receiver's set before using one. Versions move in lockstep for everyone; capabilities let a single behaviour appear or degrade on its own, which is what keeps the next addition from needing a version bump. +`caps` carries optional behaviors a node can **read**, so a sender consults the receiver's set before using one. Versions move in lockstep for everyone; capabilities let a single behavior appear or degrade on its own, which is what keeps the next addition from needing a version bump. ```ts Cap.Batch // 'batch' — reads several envelopes packed into one message @@ -76,8 +73,6 @@ Cap.Batch // 'batch' — reads several envelopes packed into one message A capability is always narrowed by the negotiated version: one advertised by a node that also speaks something newer is still out of reach at the version actually in use. ---- - ## API ### `peers` @@ -121,9 +116,9 @@ interface CollisionInfo { } ``` -Fires when **another instance is announcing our own id** — a namespace collision. Such an announce is surfaced here rather than being stored as a peer. +Fires when **another instance is announcing this node's id** — a namespace collision. Such an announce is surfaced here rather than being stored as a peer. -At the runtime layer this is [`core.registry.onNamespaceCollision`](../server-runtime/registry.md#onnamespacecollision). +At the runtime layer this is [`core.registry.onNamespaceCollision`](/docs/server/api/registry#onnamespacecollision). ### `incompatiblePeers` @@ -146,7 +141,7 @@ Nodes heard on the bus whose protocol range does not overlap this build's. They sync.discovery.onIncompatible(listener: IncompatibleListener): Unsubscribe ``` -Fires the **first** time such a node is heard. At the runtime layer this is [`core.registry.onIncompatible`](../server-runtime/registry.md), which also logs a warning naming both ranges. +Fires the **first** time such a node is heard. At the runtime layer this is [`core.registry.onIncompatible`](/docs/server/api/registry), which also logs a warning naming both ranges. ### `announce` @@ -166,8 +161,6 @@ sync.discovery.whois(): void Ask every peer to announce itself. Sent once at `start()`. Peers reply **directly to the asker** rather than broadcasting, so a late loader joining a busy world does not spam everyone. ---- - ## Timing | Constant | Value | Meaning | @@ -176,6 +169,6 @@ Ask every peer to announce itself. Sent once at `start()`. Peers reply **directl | `PEER_TTL_TICKS` | `320` | A peer unheard from for 16 s is considered gone. | | Sweep interval | `40` ticks | How often the TTL check runs. | -So a peer that disappears is detected somewhere between 16 and 18 seconds later, and a peer that appears is normally visible within a tick or two of its `whois` reply — but **never assume a peer exists on tick 0**. React to peers through events (`onPeerUp`, [`onDependenciesSatisfied`](../server-runtime/registry.md#ondependenciessatisfied), a [feature condition](../server-runtime/features.md)) rather than by checking once at startup. +So a peer that disappears is detected somewhere between 16 and 18 seconds later, and a peer that appears is normally visible within a tick or two of its `whois` reply — but **never assume a peer exists on tick 0**. React to peers through events (`onPeerUp`, [`onDependenciesSatisfied`](/docs/server/api/registry#ondependenciessatisfied), a [feature condition](/docs/server/api/features)) rather than by checking once at startup. `DiscoveryOptions` lets a test override `announceIntervalTicks` and `peerTtlTicks`. diff --git a/docs/server/sync/sync.md b/docs/sync/index.md similarity index 89% rename from docs/server/sync/sync.md rename to docs/sync/index.md index b7af847..3fe393b 100644 --- a/docs/server/sync/sync.md +++ b/docs/sync/index.md @@ -1,5 +1,8 @@ --- +slug: / sidebar_position: 1 +sidebar_label: Overview +description: "@bedrock-core/sync is the low-level cross-addon transport for Minecraft Bedrock." --- # sync @@ -7,14 +10,12 @@ sidebar_position: 1 `@bedrock-core/sync` is the low-level cross-addon transport for Minecraft Bedrock. It layers a message bus, peer discovery, RPC and a replicated state channel on top of script events, so addons in separate script realms can talk. :::warning For framework and library developers -If you are building a Bedrock addon, you do not need this package directly — use [`@bedrock-core/server-runtime`](../server-runtime/server-runtime.md) instead. The runtime creates and manages the one sync node for you, and raw transport access is available as `core.node` whenever you want it. +If you are building a Bedrock addon, you do not need this package directly — use [`@bedrock-core/server-runtime`](/docs/server/api/runtime) instead. The runtime creates and manages the one sync node for you, and raw transport access is available as `core.node` whenever you want it. ::: ## Install -```bash -npm install @bedrock-core/sync -``` + Or reach it through the meta-package, which pins a matching version: @@ -30,8 +31,6 @@ import { createSync } from '@bedrock-core/server/sync'; You do **not** need a second node just to read another addon's state. The state store is a globally shared mirror, so `core.node.state.get('other_addon', 'key')` works from the one node you already have. ---- - ## Quick start Create **one** `SyncNode` for the realm and call `start()` once on boot. @@ -56,8 +55,6 @@ sync.rpc.onRequest('ping', () => 'pong'); sync.state.set('mycoolitems', 'volume', 5); ``` ---- - ## `SyncNodeOptions` ```ts @@ -84,8 +81,6 @@ interface SyncNodeOptions { | `maxMessage` | `2000` | Character budget for one script-event message — what the [chunker](./protocol.md#framing-and-chunking) splits against and what a batch is packed up to. Mainly for tests. | | `instanceId` | generated | Overrides the auto-generated instance id. Mainly for tests. | ---- - ## `SyncNode` ```ts @@ -103,9 +98,7 @@ class SyncNode { `createSync(options)` simply builds one and returns it; `new SyncNode(options)` is equivalent. `start()` brings up the bus, RPC, discovery and state in that order, and `stop()` tears them down in reverse. ---- - -## Things to know +## Notes - **One node per realm.** Several `SyncNode`s with different ids in one realm is only useful for in-realm testing. Production addons use `server-runtime` and `core.node`. - **Timing is tick-based.** Messages flush over ticks; you will never get an RPC reply on the same tick you sent it. @@ -114,9 +107,11 @@ class SyncNode { - **sync never touches dynamic properties.** They are pack-scoped, and persistence is each addon's own responsibility — see [State](./state.md#persistence-is-not-syncs-job). - **Load order is not a problem.** Every node re-announces on a heartbeat and broadcasts a `whois` at startup, so a late loader catches up and an early loader hears about it. ---- +## In this section -## In This Section +:::caution Pre-1.0 +`@bedrock-core/sync` is under active development. Breaking changes can still land until `1.0.0` — pin exact versions and read the release notes before upgrading. +::: | Page | Description | |---|---| diff --git a/docs/server/sync/protocol.md b/docs/sync/protocol.md similarity index 96% rename from docs/server/sync/protocol.md rename to docs/sync/protocol.md index 83a62a5..128283e 100644 --- a/docs/server/sync/protocol.md +++ b/docs/sync/protocol.md @@ -1,5 +1,6 @@ --- sidebar_position: 5 +description: "What actually goes over the wire: the bus, the envelope, framing and rate limiting." --- # Protocol @@ -13,8 +14,6 @@ import { Bus, Cap, MAX_MESSAGE, MessageType, PROTOCOL_MAX, PROTOCOL_MIN } from ' import type { Envelope, BusOptions, SendOptions, EnvelopeHandler, Unsubscribe } from '@bedrock-core/sync'; ``` ---- - ## One channel Every bedrock-core message in the world travels on a single script-event channel: @@ -26,8 +25,6 @@ channel : bedrock-core:bus The bus subscribes to `system.afterEvents.scriptEventReceive` filtered to the `bedrock-core` namespace, and sends with `system.sendScriptEvent('bedrock-core:bus', …)`. Everything — discovery, RPC, state — is multiplexed over that one id and demultiplexed by the envelope's `type`. ---- - ## The envelope ```ts @@ -72,8 +69,6 @@ The window is two versions wide: a version stays readable for two releases after A node whose range does not overlap this build's at all cannot be addressed. It is reported through [`onIncompatible`](./discovery.md#onincompatible) and named in the addon list rather than quietly missing from it. ---- - ## Message types ```ts @@ -96,8 +91,6 @@ MessageType.StateSnapshot // 'state-snapshot' | `state-req` | State | broadcast | `{}` or `{ ns }` | | `state-snapshot` | State | broadcast at start, direct in reply | `{ ns, entries }` | ---- - ## Bus ```ts @@ -133,8 +126,8 @@ The receive path, in order: 2. Read the [wire tag](#wire-messages); drop the message if the tag is unknown or the body is malformed. 3. For a chunk, feed the frame to the reassembler and stop unless the group is now complete, then decode the envelope. 4. Drop any envelope that is malformed or whose `v` falls outside the supported window. A batch keeps whichever of its envelopes are sound. -5. Drop it if `iid` is our own instance — that is our own echo. -6. Drop it if `dst` is set and is not us. +5. Drop it if `iid` is this instance — its own echo. +6. Drop it if `dst` is set and names another node. 7. Dispatch to every handler registered for `type`. `stop()` tears down the subscription and the loops but **keeps registered handlers**, so a stopped bus can be restarted. @@ -143,8 +136,6 @@ The receive path, in order: A message whose `dst` equals the sender's own id never goes over the wire — it could not come back, since step 5 would drop it. `send()` detects that case and delivers the envelope to local handlers via `system.run()` instead, one tick later, preserving the async semantics of a real hop. This is what makes [RPC to self](./rpc.md#calling-yourself) work. ---- - ## Wire messages One script-event message opens with a single tag character naming which of three shapes follows: @@ -155,11 +146,11 @@ One script-event message opens with a single tag character naming which of three 1{"c":"…","s":0,"t":9,"p":"…"} one frame of an envelope too large to send whole ``` -The tag exists to keep the common case cheap. Nesting an envelope inside a frame's `p` field means JSON-escaping the whole thing to sit inside a JSON string — every quote costs a backslash — and a one-piece message would carry a `c`/`s`/`t` header describing a split that never happened. Most bus traffic is one-piece, so that was the common case paying for the rare one. +The tag exists to keep the common case cheap. Nesting an envelope inside a frame's `p` field means JSON-escaping the whole thing to sit inside a JSON string — every quote costs a backslash — and a one-piece message would carry a `c`/`s`/`t` header describing a split that never happened. Most bus traffic is one-piece, so the tag keeps the common case cheap. A batch (`2`) is a JSON array of envelopes, not of encoded strings, so packing costs no escaping either. Batching is the [outbound queue](#outbound-queue-and-rate-limiting)'s work, not the bus's. -Protocol 1 predates the tag: every message was a bare frame, so it opens with `{`. The frame shape never changed — only what wraps it — so a message recognised by that leading brace is read through the same reassembly path as a tagged chunk. +A protocol 1 message is a bare frame and opens with `{`. The frame shape is the same under both protocols — only the wrapping differs — so a message recognized by that leading brace is read through the same reassembly path as a tagged chunk. The tag is otherwise frozen. A shape added by some later protocol takes a character of its own, and a reader that does not know a character drops that one message rather than the peer that sent it. @@ -176,8 +167,6 @@ Announces are pinned because they are what establishes everything else: the mess Both broadcast values rise on their own as the peers holding them down expire, so a world returns to the newest encoding once its last outdated addon is gone — no restart, no setting. ---- - ## Framing and chunking Script-event messages are size-capped, so an encoded envelope larger than the budget is split across several **frames**, each sent as its own tagged message: @@ -203,8 +192,6 @@ The per-frame payload budget is exact rather than pessimistic: each character is The reassembler ignores stray frames whose `t` disagrees with the group, out-of-range sequence numbers, and duplicate sequence numbers — so a partially-arrived group from a node that restarted mid-send times out rather than producing garbage. ---- - ## Outbound queue and rate limiting The engine only processes a bounded number of script events per tick, so **nothing is ever sent inline**. Everything goes into an outbound queue drained on an interval: @@ -224,8 +211,6 @@ If a send throws — an unexpectedly oversized message slipping through, for ins The practical consequence is the one stated everywhere else in these docs: **timing is tick-based**. A reply cannot arrive on the tick you sent the request, and a large payload that spans many frames takes proportionally longer to land. ---- - ## Reading it in practice To watch raw traffic from an addon: diff --git a/docs/server/sync/rpc.md b/docs/sync/rpc.md similarity index 98% rename from docs/server/sync/rpc.md rename to docs/sync/rpc.md index 3a3da4c..eb2394c 100644 --- a/docs/server/sync/rpc.md +++ b/docs/sync/rpc.md @@ -1,5 +1,6 @@ --- sidebar_position: 3 +description: "sync.rpc — and core.rpc, which is the same object — is request/response messaging between addons." --- # Rpc @@ -30,8 +31,6 @@ core.rpc.onRequest('getBalance', (params, from) => { const balance = await core.rpc.request('drav0011_economy', 'getBalance', { player: 'Steve' }); ``` ---- - ## Serving ### `onRequest` @@ -84,8 +83,6 @@ core.rpc.serve({ `RPCHandlerMap` maps each `(params: P) => R` in the interface to `(params: P, from: string) => R | Promise>`, so handlers get typed params and may still be async. ---- - ## Calling ### `request` @@ -130,8 +127,6 @@ const balance = await economy.getBalance({ player: 'Steve' }); // Promise { /* … */ }); sync.state.delete('mycoolitems', 'spawnRate'); ``` ---- - ## API ### `get` @@ -95,11 +94,9 @@ interface StateChange { Fires on **every applied change**, local or remote, in **every** namespace. Only writes that win the last-write-wins comparison are applied, so a losing delta fires nothing. :::caution This listener is very chatty -Config schemas, i18n bundles, guide manifests and feature flags all replicate through this channel, so a raw `subscribe` sees traffic from every addon in the world. Filter by `ns` and `key`, or subscribe on a node of a [shared tree](../server-runtime/shared.md#use-your-own-tree), which fires for one leaf, one branch or one namespace. +Config schemas, i18n bundles, guide manifests and feature flags all replicate through this channel, so a raw `subscribe` sees traffic from every addon in the world. Filter by `ns` and `key`, or subscribe on a node of a [shared tree](/docs/server/api/shared#use-your-own-tree), which fires for one leaf, one branch or one namespace. ::: ---- - ## Typed keys ```ts @@ -113,8 +110,6 @@ const rate = sync.state.get('mycoolitems', SPAWN_RATE); // number | undefined `StateKey` is a branded string — a **compile-time assertion only**. Like any state read, the actual value comes from whichever peer wrote it last and is never validated at runtime. ---- - ## Conflict resolution Each write stamps an entry with a version from a monotonically increasing logical clock, plus the writer's id: @@ -124,8 +119,6 @@ Each write stamps an entry with a version from a monotonically increasing logica Receiving a delta or snapshot also advances the local clock to at least the incoming version. ---- - ## Snapshots and late join A node that starts long after everyone else still needs the current picture. Two mechanisms cover that, and they run automatically inside `state.start()`: @@ -134,7 +127,7 @@ A node that starts long after everyone else still needs the current picture. Two node.start() └─ state.start() ├─ requestSync() broadcast "send me your state" - └─ broadcastOwnedSnapshots() push our own owned namespaces out + └─ broadcastOwnedSnapshots() push the owned namespaces out ``` ### `requestSync` @@ -187,8 +180,6 @@ Serialize a namespace, **including tombstones** — a snapshot that dropped them | Addressed | Broadcast | Broadcast at startup, direct reply to a request | | Applied | Last-write-wins per key | Last-write-wins per entry | ---- - ## Ownership and `strictOwnership` ```ts @@ -213,11 +204,9 @@ By default **writes are open** — any node may write any namespace. With `stric The runtime creates its node with `ownedNamespaces: [namespace]` and leaves `strictOwnership` at its default, so `core.node.state` can still write anywhere. `core.state` narrows that by construction — it only ever addresses your own namespace. :::note Ownership is a convention, not a security boundary -`strictOwnership` guards *your* node against writing where it should not. It cannot stop another pack from writing your namespace — every addon in a world runs arbitrary script. Treat state as shared and cooperative; put anything that needs an authority check behind [RPC](./rpc.md), the way [config](../server-runtime/config.md#authorization) does. +`strictOwnership` guards *your* node against writing where it should not. It cannot stop another pack from writing your namespace — every addon in a world runs arbitrary script. Treat state as shared and cooperative; put anything that needs an authority check behind [RPC](./rpc.md), the way [config](/docs/server/api/config#authorization) does. ::: ---- - ## Persistence is not sync's job sync is in-memory only, and it deliberately does **not** touch dynamic properties — those are pack-scoped, and each addon owns its own durability. @@ -245,4 +234,4 @@ system.run(() => { }); ``` -From an addon, `persisted()` on a [shared](../server-runtime/shared.md#persistence) leaf does this per key, which is what you want once a namespace can grow past a dynamic property's 32767-character ceiling. +From an addon, `persisted()` on a [shared](/docs/server/api/shared#persistence) leaf does this per key, which is what you want once a namespace can grow past a dynamic property's 32767-character ceiling. diff --git a/docs/ui/ui-runtime/api/TranslationContext.md b/docs/ui/api/TranslationContext.md similarity index 89% rename from docs/ui/ui-runtime/api/TranslationContext.md rename to docs/ui/api/TranslationContext.md index 1433ace..ade0077 100644 --- a/docs/ui/ui-runtime/api/TranslationContext.md +++ b/docs/ui/api/TranslationContext.md @@ -1,5 +1,6 @@ --- sidebar_position: 4 +description: "The context carrying how localized text resolves for a component subtree." --- # TranslationContext @@ -46,7 +47,7 @@ Providing a value **shadows** the injected one for that subtree. Two legitimate ### 1. Resolving beyond your own bundle -A host that renders other addons' strings needs a resolver over every published bundle. That is what [`@bedrock-core/config`](../../config/config.md) does — it renders every registered addon's display fields, so it provides the world resolver: +A host that renders other addons' strings needs a resolver over every published bundle. That is what [`@bedrock-core/config`](/docs/config) does — it renders every registered addon's display fields, so it provides the world resolver: ```tsx @@ -116,7 +117,7 @@ const overrides: Record = { | Whether a `Text` string child is treated as a key | What the client ultimately paints | | Layout metrics — wrapping, ellipsis, `maxLines` | Whether a key exists in the world's `.lang` | | Wrap routing for localized text | | -| Components that build display strings themselves ([`Header`](../../ore-styled/Header.md), [`MenuRow`](../../ore-styled/MenuRow.md)) | | +| Components that build display strings themselves ([`Header`](/docs/ore-styled/Header), [`MenuRow`](/docs/ore-styled/MenuRow)) | | The client always makes its own resolution attempt, so a resolver miss on a key the world *does* publish still paints correctly — only its server-side wrap metrics are approximate. @@ -125,4 +126,4 @@ The client always makes its own resolution attempt, so a resolver miss on a key - [useTranslationResolver](../hooks/useTranslationResolver.md) — reading the active resolver - [useTranslation](../hooks/useTranslation.md) — typed verbs bound to the viewing player - [createContext](./createContext.md) — how context works in general -- [i18n](../../i18n/i18n.md) — where resolvers come from +- [i18n](/docs/i18n) — where resolvers come from diff --git a/docs/ui/ui-runtime/api/_category_.json b/docs/ui/api/_category_.json similarity index 66% rename from docs/ui/ui-runtime/api/_category_.json rename to docs/ui/api/_category_.json index dd8efce..87fc9dc 100644 --- a/docs/ui/ui-runtime/api/_category_.json +++ b/docs/ui/api/_category_.json @@ -1,11 +1,10 @@ { - "position": 3, + "position": 6, "label": "API", - "key": "api", "collapsible": true, "collapsed": true, "link": { "type": "doc", - "id": "api" + "id": "api/api" } -} \ No newline at end of file +} diff --git a/docs/ui/ui-runtime/api/api.md b/docs/ui/api/api.md similarity index 54% rename from docs/ui/ui-runtime/api/api.md rename to docs/ui/api/api.md index 99dd365..137de43 100644 --- a/docs/ui/ui-runtime/api/api.md +++ b/docs/ui/api/api.md @@ -1,5 +1,6 @@ --- sidebar_position: 1 +description: "Core functions and utilities for building and displaying UI." --- # API @@ -16,9 +17,9 @@ Core functions and utilities for building and displaying UI. ## Advanced -- [Custom Native Components](./custom-native-components.md) — register your own native component `type` that the runtime serializes and your resource pack's JSON UI decodes. Requires JSON UI **and** serialization knowledge. +- [Custom Native Components](../guides/custom-native-components.md) — register your own native component `type` that the runtime serializes and your resource pack's JSON UI decodes. Requires JSON UI **and** serialization knowledge. -## Next Steps +## Next steps -- [Components](../components/components.md) - Built-in components that you can use in your JSX -- [Hooks](../hooks/hooks.md) - Add state and effects to your components +- [Components](../components/components.md) — Built-in components that you can use in your JSX +- [Hooks](../hooks/hooks.md) — Add state and effects to your components diff --git a/docs/ui/ui-runtime/api/createContext.md b/docs/ui/api/createContext.md similarity index 77% rename from docs/ui/ui-runtime/api/createContext.md rename to docs/ui/api/createContext.md index 6fc35de..7d0f191 100644 --- a/docs/ui/ui-runtime/api/createContext.md +++ b/docs/ui/api/createContext.md @@ -1,5 +1,6 @@ --- -sidebar_position: 2 +sidebar_position: 3 +description: "Create a context object for sharing data across component trees without prop drilling." --- # createContext @@ -20,9 +21,9 @@ function createContext(defaultValue: T): Context ### Parameters -#### `defaultValue` -- Type: `T` (generic) -- Description: The default value used +| Parameter | Type | Description | +| --- | --- | --- | +| `defaultValue` | `T` (generic) | The default value used | ### Returns @@ -64,7 +65,7 @@ function ThemedComponent() { ## Examples -### User Authentication Context +### User authentication context ```tsx interface User { @@ -108,7 +109,7 @@ function Dashboard() { } ``` -### Settings Context with Updates +### Settings context with updates ```tsx interface Settings { @@ -167,42 +168,3 @@ function VolumeControl() { ); } ``` - -## Best Practices - -### Provide Meaningful Defaults - -```tsx -// ✅ Good - meaningful default values -const ThemeContext = createContext({ - color: '#000000', - fontSize: 14, -}); - -// ❌ Less ideal -const ThemeContext = createContext(null); -``` - -### Create Provider Components - -```tsx -// ✅ Good - dedicated provider -function ThemeProvider({ children }: { children: JSX.Element }) { - const [theme, setTheme] = useState(defaultTheme); - - return ( - - {children} - - ); -} -``` - -### Split Contexts by Concern - -```tsx -// ✅ Good - separate concerns -const ThemeContext = createContext({}); -const AuthContext = createContext({}); -const SettingsContext = createContext({}); -``` diff --git a/docs/ui/ui-runtime/api/render.md b/docs/ui/api/render.md similarity index 87% rename from docs/ui/ui-runtime/api/render.md rename to docs/ui/api/render.md index 1d4fe79..713e8ae 100644 --- a/docs/ui/ui-runtime/api/render.md +++ b/docs/ui/api/render.md @@ -1,3 +1,8 @@ +--- +sidebar_position: 2 +description: "Display a UI component tree to a player." +--- + # render Display a UI component tree to a player. @@ -16,13 +21,10 @@ function render(root: FunctionComponent | JSX.Element, player: Player): void ### Parameters -#### `root` -- Type: `FunctionComponent | JSX.Element` -- Description: The root component or element to render - -#### `player` -- Type: `Player` (from `@minecraft/server`) -- Description: The player who will see the UI +| Parameter | Type | Description | +| --- | --- | --- | +| `root` | `FunctionComponent \| JSX.Element` | The root component or element to render | +| `player` | `Player` (from `@minecraft/server`) | The player who will see the UI | ### Scrolls diff --git a/docs/ui/ui-runtime/components/Background.md b/docs/ui/components/Background.md similarity index 86% rename from docs/ui/ui-runtime/components/Background.md rename to docs/ui/components/Background.md index 9a7f473..f2c20e5 100644 --- a/docs/ui/ui-runtime/components/Background.md +++ b/docs/ui/components/Background.md @@ -1,5 +1,6 @@ --- sidebar_position: 6 +description: "Draw a full-screen texture behind everything in a form." --- # Background @@ -30,12 +31,11 @@ If a tree contains more than one ``, only the first is rendered; the ## Props -### Component-Specific Props +### Component-Specific props -#### `texture` -- Type: `string` -- Required: yes -- Description: Resource-pack texture path drawn as the full-screen backdrop, e.g. `'textures/ui/my_background'`. +| Prop | Type | Default | Description | +| --- | --- | --- | --- | +| `texture` | `string` | — (**required**) | Resource-pack texture path drawn as the full-screen backdrop, e.g. `'textures/ui/my_background'` | - Constraints: The path must fit within 80 UTF-8 bytes and may not contain a `;` character. ## Examples @@ -81,7 +81,7 @@ function Menu() { } ``` -## Limitations +## Limits - The texture path is capped at 80 UTF-8 bytes and cannot contain `;`. - Only the first `` in a tree is drawn. diff --git a/docs/ui/ui-runtime/components/Button.md b/docs/ui/components/Button.md similarity index 64% rename from docs/ui/ui-runtime/components/Button.md rename to docs/ui/components/Button.md index 8739a67..8deef88 100644 --- a/docs/ui/ui-runtime/components/Button.md +++ b/docs/ui/components/Button.md @@ -1,5 +1,6 @@ --- sidebar_position: 4 +description: "Interactive button component that responds to player interactions." --- # Button @@ -23,37 +24,25 @@ Buttons are sized intrinsically from their content plus the button's built-in pa ## Props -### Component-Specific Props +### Component-Specific props -#### `onPress` -- Type: `(event: PressEvent) => unknown | Promise` -- Description: Runs when the player presses the button. `event.player` is who pressed; on a [container screen](../../container-screens/container-screens.md) `event.host` is the entity that owns the screen, and on a form there is none. Every handler in the library takes one event object — see [Handler events](./components.md#handler-events). +| Prop | Type | Description | +| --- | --- | --- | +| `onPress` | `(event: PressEvent) => unknown \| Promise` | Runs when the player presses the button. `event.player` is who pressed; on a [container screen](../guides/container-screens.md) `event.host` is the entity that owns the screen, and on a form there is none. Every handler in the library takes one event object — see [Handler events](../guides/handler-events.md) | +| `children` | `JSX.Node` | Child components — typically a `Text` (label) or `Image` (icon) | +| `backgroundHover` | `string` | Texture path used while the player hovers over the button | +| `backgroundPressed` | `string` | Texture path used while the button is being pressed | +| `backgroundLocked` | `string` | Texture path used when the button is disabled (`enabled={false}`) | -#### `children` -- Type: `JSX.Node` -- Description: Child components — typically a `Text` (label) or `Image` (icon). +Combine these with `background` (from control props) to fully texture the button across every state. This is the foundation that [`@bedrock-core/ore-styled`'s `Button`](/docs/ore-styled/Button) builds on top of. -#### `backgroundHover` -- Type: `string` -- Description: Texture path used while the player hovers over the button. - -#### `backgroundPressed` -- Type: `string` -- Description: Texture path used while the button is being pressed. - -#### `backgroundLocked` -- Type: `string` -- Description: Texture path used when the button is disabled (`enabled={false}`). - -Combine these with `background` (from control props) to fully texture the button across every state. This is the foundation that [`@bedrock-core/ore-styled`'s `Button`](../../ore-styled/Button.md) builds on top of. - -### Control Props +### Control props Button inherits all standard [control props](./control-props.md). ## Examples -### Basic Button +### Basic button ```tsx ``` -### Button with State +### Button with state ```tsx function ToggleButton() { @@ -75,7 +64,7 @@ function ToggleButton() { } ``` -### Disabled Button +### Disabled button ```tsx ``` -### Row of Buttons +### Row of buttons ```tsx @@ -96,7 +85,7 @@ function ToggleButton() { ``` -### Icon Button +### Icon button ```tsx ``` -### Fully Themed Button +### Fully themed button ```tsx + + +``` + +### Centered content + +```tsx + + {'Centered'} + +``` + +### Visibility control + +```tsx +function ConditionalUI({ showButton }: { showButton: boolean }) { + return ( + + {'Some text'} + + + ); +} +``` + +### Display None vs Visible + +```tsx +{/* visible={false} keeps the space reserved */} + + +{/* display={'none'} removes from layout — siblings collapse */} + +``` + +### Absolute positioning + +```tsx + + {'Main content'} + {/* Pinned to top-right, outside normal flow */} + + {'✕'} + + +``` + +## Visibility vs Display + +| | `visible={false}` | `display={'none'}` | +|---|---|---| +| Space reserved | Yes | No | +| Children executed | Yes | No | +| Use case | Hide visually | Remove from layout | + +## TypeScript + +```tsx +import type { ControlProps, LayoutProps } from '@bedrock-core/ui'; +``` + +`LayoutProps` carries the flex layout properties; `ControlProps` extends it with `visible`, `enabled`, and `background`. Every built-in component's props type extends `ControlProps`. Individual types are also exported: + +```tsx +import type { + FlexDirection, FlexSize, FlexWrap, + JustifyContent, AlignItems, AlignContent, AlignSelf, + Display, Position, Spacing, +} from '@bedrock-core/ui'; +``` + +The underlying primitives (`Percent`, `FlexStyle`, …) live in the flexbox entry point: + +```tsx +import type { Percent, FlexStyle } from '@bedrock-core/ui/flexbox'; +``` diff --git a/docs/ui/components/deprecated/Dropdown.md b/docs/ui/components/deprecated/Dropdown.md new file mode 100644 index 0000000..f1f64c9 --- /dev/null +++ b/docs/ui/components/deprecated/Dropdown.md @@ -0,0 +1,94 @@ +--- +sidebar_position: 2 +description: "A select field backed by a modal dropdown." +--- +# Dropdown + +A select field backed by a modal dropdown. Pressing it opens a modal to choose one of a fixed set of options. Supports controlled and uncontrolled usage. + +:::caution Deprecated +This is the legacy one-modal-per-field pattern. For new screens, use [`Form.Dropdown`](../Form/FormDropdown.md) inside a [`Form`](../Form/Form.md). Still fully supported for existing screens. +::: + +## Import + +```tsx +import { Dropdown } from '@bedrock-core/ui'; +``` + +## Usage + +```tsx + console.log(value)} +/> +``` + +## How it works + +`Dropdown` renders as a [`Button`](../Button.md) whose face shows the current selection. Pressing it opens a single-dropdown `ModalFormData`; on confirm the chosen option is committed (internal state + `onChange`), on cancel nothing changes (`onCancel`). Either way the root form re-presents with the current selection. + +The native modal works on item *indices*; `Dropdown` maps the selected index back to the matching `options` entry, so its public API stays value-based like [`Input`](./Input.md). + +## Props + +### Component-Specific props + +| Prop | Type | Default | Description | +| --- | --- | --- | --- | +| `options` (required) | `string[]` | — | The selectable options. The face shows the current one; the modal lists them all | +| `value` | `string` | — | Controlled selection — should match one of `options`. When provided, the face reflects it on every render and `onChange` is your only way to update it | +| `defaultValue` | `string` | the first option | Initial selection when running uncontrolled | +| `onChange` | `(value: string, index: number) => void` | — | Called with the chosen option and its index in `options` when the player confirms the modal | +| `onCancel` | `() => void` | — | Called when the player cancels (X / Esc) the modal. The selection is left unchanged | +| `face` | `JSX.Node` | a `Text` showing the current selection | Overrides the content drawn on the button face. Lets a styled wrapper render its own face (e.g. the value plus a chevron) while reusing this component's modal + state logic. This is how [`@bedrock-core/ore-styled`](/docs/ore-styled/Dropdown) builds its themed `Dropdown` | + +### Modal field props + +Dropdown inherits all [modal field props](./modal-field-props.md) (`label`, `title`, `body`, `submitLabel`, `tooltip`) for configuring the modal. + +### Control props + +Dropdown inherits all standard [control props](../control-props.md). Use `enabled={false}` to make the field inert (no modal opens). + +## Examples + +### Controlled + +```tsx +function DifficultySetting() { + const [difficulty, setDifficulty] = useState('Normal'); + + return ( + + + {`Selected: ${difficulty}`} + + ); +} +``` + +### Uncontrolled + +```tsx + console.log(index, value)} +/> +``` + +## Notes + +- Keep `options` stable across renders; deriving it inline from changing data can shift indices unexpectedly. +- A controlled `value` should always be one of `options` — an unknown value falls back to the first option on the face. +- For two-state choices use a [`Toggle`](/docs/ore-styled/Toggle) instead of a two-item dropdown. diff --git a/docs/ui/components/deprecated/Input.md b/docs/ui/components/deprecated/Input.md new file mode 100644 index 0000000..6fcfdcb --- /dev/null +++ b/docs/ui/components/deprecated/Input.md @@ -0,0 +1,96 @@ +--- +sidebar_position: 1 +description: "A single-line text field." +--- +# Input + +A single-line text field. Pressing it opens a modal to edit the value. Supports controlled and uncontrolled usage. + +:::caution Deprecated +This is the legacy one-modal-per-field pattern. For new screens, use [`Form.Input`](../Form/FormInput.md) inside a [`Form`](../Form/Form.md). Still fully supported for existing screens. +::: + +## Import + +```tsx +import { Input } from '@bedrock-core/ui'; +``` + +## Usage + +```tsx + console.log(value)} +/> +``` + +## How it works + +Native `ActionFormData` can't take typed input, so `Input` renders as a [`Button`](../Button.md) whose face shows the current value (or the `placeholder` when empty). Pressing it opens a single-field `ModalFormData`; on confirm the typed text is committed (internal state + `onChange`), on cancel nothing changes (`onCancel`). Either way the root form re-presents with the current value. + +This is the unstyled runtime primitive — supply a `background` or compose a styled wrapper for a field-like appearance. + +## Props + +### Component-Specific props + +| Prop | Type | Default | Description | +| --- | --- | --- | --- | +| `value` | `string` | — | Controlled value. When provided, the face reflects this on every render and `onChange` is your only way to update it | +| `defaultValue` | `string` | `''` | Initial value when running uncontrolled | +| `onChange` | `(value: string) => void` | — | Called with the new text when the player confirms the modal | +| `onCancel` | `() => void` | — | Called when the player cancels (X / Esc) the modal. The value is left unchanged | +| `placeholder` | `string` | — | Shown on the button face when the value is empty, and inside the modal text field | +| `face` | `JSX.Node` | a `Text` showing the value (or `placeholder` when empty) | Overrides the content drawn on the button face. Lets a styled wrapper render its own face (e.g. colored value text) while reusing this component's modal + state logic. This is how [`@bedrock-core/ore-styled`](/docs/ore-styled/Input) builds its themed `Input` | + +### Modal field props + +Input inherits all [modal field props](./modal-field-props.md) (`label`, `title`, `body`, `submitLabel`, `tooltip`) for configuring the modal. + +### Control props + +Input inherits all standard [control props](../control-props.md). Use `enabled={false}` to make the field inert (no modal opens). + +## Examples + +### Controlled + +```tsx +function NameField() { + const [name, setName] = useState(''); + + return ( + + + {`Hello, ${name !== '' ? name : 'stranger'}`} + + ); +} +``` + +### Uncontrolled + +```tsx + console.log(v)} /> +``` + +### Disabled + +```tsx + +``` + +## Notes + +- Provide a `placeholder` so an empty field still reads as editable. +- Set `title` (or rely on `label`) so the modal has a clear heading. +- Use `value` + `onChange` (controlled) when the value is part of your screen state; reach for `defaultValue` when the field can manage itself. diff --git a/docs/ui/components/deprecated/Slider.md b/docs/ui/components/deprecated/Slider.md new file mode 100644 index 0000000..c4b0ef7 --- /dev/null +++ b/docs/ui/components/deprecated/Slider.md @@ -0,0 +1,94 @@ +--- +sidebar_position: 3 +description: "A numeric field backed by a modal slider." +--- +# Slider + +A numeric field backed by a modal slider. Pressing it opens a modal to pick a value within a range. Supports controlled and uncontrolled usage. + +:::caution Deprecated +This is the legacy one-modal-per-field pattern. For new screens, use [`Form.Slider`](../Form/FormSlider.md) inside a [`Form`](../Form/Form.md). Still fully supported for existing screens. +::: + +## Import + +```tsx +import { Slider } from '@bedrock-core/ui'; +``` + +## Usage + +```tsx + console.log(value)} +/> +``` + +## How it works + +`Slider` renders as a [`Button`](../Button.md) whose face shows the current value. Pressing it opens a single-slider `ModalFormData`; on confirm the chosen value is committed (internal state + `onChange`), on cancel nothing changes (`onCancel`). Either way the root form re-presents with the current value. + +## Props + +### Component-Specific props + +| Prop | Type | Default | Description | +| --- | --- | --- | --- | +| `min` (required) | `number` | — | Minimum selectable value | +| `max` (required) | `number` | — | Maximum selectable value | +| `step` | `number` | `1` | Increment between selectable values | +| `value` | `number` | — | Controlled value. When provided, the face reflects it on every render and `onChange` is your only way to update it | +| `defaultValue` | `number` | `min` | Initial value when running uncontrolled | +| `onChange` | `(value: number) => void` | — | Called with the new value when the player confirms the modal | +| `onCancel` | `() => void` | — | Called when the player cancels (X / Esc) the modal. The value is left unchanged | +| `face` | `JSX.Node` | a `Text` showing the current value | Overrides the content drawn on the button face. Lets a styled wrapper render its own face (e.g. a track and thumb positioned by the value) while reusing this component's modal + state logic. This is how [`@bedrock-core/ore-styled`](/docs/ore-styled/Slider) builds its themed `Slider` | + +### Modal field props + +Slider inherits all [modal field props](./modal-field-props.md) (`label`, `title`, `body`, `submitLabel`, `tooltip`) for configuring the modal. + +### Control props + +Slider inherits all standard [control props](../control-props.md). Use `enabled={false}` to make the field inert (no modal opens). + +## Examples + +### Controlled + +```tsx +function VolumeSetting() { + const [volume, setVolume] = useState(50); + + return ( + + + {`Volume: ${volume}%`} + + ); +} +``` + +### Uncontrolled + +```tsx + console.log(v)} /> +``` + +## Notes + +- Choose a `step` that matches the precision you actually need — players can only land on `min + n * step`. +- Make sure `defaultValue` (or a controlled `value`) sits within `[min, max]`. +- Pair the slider with a `Text` that echoes the value so the current setting stays visible without opening the modal. diff --git a/docs/ui/components/deprecated/_category_.json b/docs/ui/components/deprecated/_category_.json new file mode 100644 index 0000000..af816fd --- /dev/null +++ b/docs/ui/components/deprecated/_category_.json @@ -0,0 +1,11 @@ +{ + "position": 16, + "label": "Deprecated", + "collapsible": true, + "collapsed": true, + "link": { + "type": "generated-index", + "title": "Deprecated", + "description": "One-modal-per-field components, kept until the code removes them. Use Form.* instead." + } +} diff --git a/docs/ui/components/deprecated/modal-field-props.md b/docs/ui/components/deprecated/modal-field-props.md new file mode 100644 index 0000000..7eba04a --- /dev/null +++ b/docs/ui/components/deprecated/modal-field-props.md @@ -0,0 +1,48 @@ +--- +sidebar_position: 4 +description: "These props belong to the legacy one-modal-per-field components." +--- +# Modal Field Props + +:::caution Deprecated +These props belong to the legacy one-modal-per-field components. New [`Form`](../Form/Form.md) fields configure modal chrome differently — there's no per-field `label`/`title`/`body`/`submitLabel`/`tooltip`, since a `Form` has one shared modal and headings are authored as a `Text` node. +::: + +Shared props for the **modal-backed field** components — [`Input`](./Input.md), [`Dropdown`](./Dropdown.md), and [`Slider`](./Slider.md). + +Native `ActionFormData` (what this runtime renders to) can't take typed input, so each of these components is really a [`Button`](../Button.md) that *looks like* a form field. Pressing it opens a single-control `ModalFormData`; when the player confirms, the value is committed and the root form re-presents. These props configure that modal — they do **not** appear on the button face, which always shows the current value (or placeholder). + +`ModalFieldProps` extends [control props](../control-props.md), so every field also supports the full set of layout / visibility / background props. + +## Props + +| Prop | Type | Default | Description | +| --- | --- | --- | --- | +| `label` | `string` | — | Label for the control *inside* the modal. Not shown on the button face | +| `title` | `string` | the `label` | Title of the modal window | +| `body` | `string` | — | Descriptive text shown above the control. `ModalFormData` has no body, so this renders as a leading label line | +| `submitLabel` | `string` | — | Text on the modal's confirm/submit button | +| `tooltip` | `string` | — | Hover tooltip on the modal control | + +## Customizing the face + +Each field also accepts a component-specific `face` prop (`JSX.Node`) that overrides what's drawn on the button face — while the component keeps owning the modal flow and value state. This is the seam styled wrappers build on: run the field controlled (`value` + `onChange`) so you know the current value, then pass a `face` node that renders it however you like. + +```tsx +{`§f${name === '' ? '§7type a name' : name}`}} +/> +``` + +The themed [`@bedrock-core/ore-styled`](/docs/ore-styled) `Input`, `Dropdown`, and `Slider` are exactly this pattern: the chevron and the slider track/thumb are custom `face` nodes. + +## TypeScript + +```tsx +import type { ModalFieldProps } from '@bedrock-core/ui'; +``` + +Handy when building your own styled wrapper around `Input` / `Dropdown` / `Slider`. diff --git a/docs/ui/config/_category_.json b/docs/ui/config/_category_.json deleted file mode 100644 index 2ff0cd1..0000000 --- a/docs/ui/config/_category_.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "position": 7, - "label": "config", - "key": "config", - "collapsible": true, - "collapsed": true, - "link": { - "type": "doc", - "id": "config" - } -} diff --git a/docs/ui/container-screens/_category_.json b/docs/ui/container-screens/_category_.json deleted file mode 100644 index ff35916..0000000 --- a/docs/ui/container-screens/_category_.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "position": 9, - "label": "container screens", - "key": "container-screens", - "collapsible": true, - "collapsed": true, - "link": { - "type": "doc", - "id": "container-screens" - } -} diff --git a/docs/ui/container-screens/findings.md b/docs/ui/container-screens/findings.md deleted file mode 100644 index e5f57ef..0000000 --- a/docs/ui/container-screens/findings.md +++ /dev/null @@ -1,144 +0,0 @@ ---- -sidebar_position: 3 ---- - -# JSON UI and container facts - -The rules the container backend is built on: how a chest screen addresses its slots, what a slot publishes and in which type, what the Script API allows around a container, and which official schema artifacts are worth validating against. Every rule below was measured in game or checked against Mojang's published files, and the numbers are the ones observed. - -## Containers - -### Routing and size - -- `container_type: "container"` is the only `minecraft:inventory` type that routes to `chest_screen.json`. -- `private` must be `false`, or players cannot open the container at all. -- `inventory_size: 54` routes to `small_chest_screen`, not the large one. Its grid draws 9 × 3 = 27 cells while `#collection_total_items` reports the full 54 — 27 slots exist that no cell draws, with no grid patch and no effect on real double chests. -- `inventory_size: 200` works: the container opens, `#collection_total_items` reports 200, every index binds, and populating all 200 slots costs 14 ms once at spawn. No ceiling has been found. -- The undrawn slots are readable and live: a fill driven only by the durability of the item in slot 40 animates while the screen stays open. -- Over roughly 20,000 ticks and 11 sessions of shift-clicking, double-clicking to collect and drag-distributing across the grid, every item landed in a drawn slot; nothing ever reached the undrawn range. The undrawn range was kept full throughout, so "keep it full" and "the engine never addresses an undrawn slot" have not been separated. -- A one-tick poll over the whole container costs 0.3 ms at 54 slots and 3.3 ms at 200. The cost tracks container size, so a full scan does not scale — ten players on a 200-slot screen would eat two thirds of a tick. Polling the drawn range only brings it back to about 0.3 ms: the undrawn range has no cell, so nobody can touch it between sweeps, and a once-a-second integrity sweep covers it. -- The touch chest screen routes to `pocket_containers.small_chest_panel`, from the same `small_chest_screen` in `chest_screen.json`; one hook file covers both UI profiles. - -### The screen title - -- `$container_title` is the entity's live `nameTag`, and renders in controls inserted into the screen. An entity with no name tag falls back to `entity.unknown.name`. -- It cannot be used in a binding expression, so nothing can be routed on it. Routing goes through the marker slot instead. - -## Collection addressing - -- `collection_name` is legal on `stack_panel` and `grid` only. On `panel` and `image` the engine rejects it: *Unknown property [collection_name]*. -- `collection_index` is only accepted at an **instantiation site** — an entry in a parent's `controls`, inline or `@`-referenced. On a top-level definition the engine rejects it: *Unknown property [collection_index]*. It is rejected on an `image` in any position, and on a `label` it is accepted silently and does nothing. -- The index inherits down the subtree from wherever it is applied, so the control owning a binding sits *under* the control carrying the index. -- Consequently a compiled layout emits one small definition per control shape and applies the index, and the solved offset, at each reference: a slot grid costs one definition plus N references rather than N definitions. -- Bindings always name the collection themselves through `binding_collection_name`; the control tree only supplies the index. -- **A collection binding with no `collection_index` anywhere above it reads slot 0.** Measured on `chest.small_chest_panel` itself: `#item_id_aux` published the sentinel's aux with no index host in the tree, which is what lets vanilla's chest label and grid hide themselves on the protocol key without any control being inserted around them. -- **A binding expression can crash the client outright.** A probe carrying `(#count / 19)` and `('' + #count)` — a division and an empty string literal — closed the game on opening the screen; the same probe without those two forms ran. Keep expressions to `+ - *`, comparisons and non-empty literals. -- **`>=` is not a comparison the expression parser accepts.** `(#inventory_stack_count >= 100)` and `((#inventory_stack_count * 1) >= 100)` both held on a stack of 21, and `(… >= 2)` held on an empty slot: a binding whose expression fails leaves the property at its default, and `#visible` defaults to true. Only `=`, `<` and `>` are used anywhere. -- `#item_id_aux` of a command block item is `8978432`, exactly `137 × 65536` — a legacy block id, published unshifted. - -## Variables, modifications and replacements - -- **A `$variable` cannot be used inside a binding's `source_property_name` in a subtree inserted through `modifications`.** Six variations — quoted and bare, the engine-injected `$container_title` and a pack-defined variable, declared on the parent and on the binding's owner, with and without a `#property` in the expression — all fail identically: *Must define a source property name in the binding!* The same binding with no variable in it parses every time. -- The same constraint from the other side: a `$caption` in `text` substitutes fine, while a `$bind` inside a `bindings` array stays empty. **A shared, parameterised control template does not work in an inserted subtree.** Each control needs its own definition with literal binding names, which is what the compiler emits — compiled layouts bake literals into expressions rather than parameterise them. -- This is why the form protocol's variables work where an inserted binding does not: they live on a control the pack owns outright, not one grafted into a vanilla tree. -- A **derived or replaced** vanilla definition is a normal control tree: cross-namespace `@` bases resolve inside it, and variables are legal in its bindings. -- A vanilla definition must be re-declared in the file vanilla itself owns. JSON UI resolves a definition from the file that owns it, so a `small_chest_screen` declared in any other file — same namespace or not — is silently ignored and the vanilla chest renders. -- **`modifications` are resolved per file path, not per namespace.** A `modifications` entry in a file at another path — even in the same pack, even in a namespace the pack itself defines — is read as a definition of its own: the engine reported *Type not specified (or @-base not found)* and *Unknown property [modifications]* for a `chest_root` modification placed in a second file of the `core_ui_router` namespace, and it displaced the real definition. Only a modification in a copy of a file at the same path as the one being modified applies, and those stack across packs in pack order. That is why every edit to the chest lives in a copy of vanilla's own `chest_screen.json` — every pack's copy stacks on vanilla's — and why nothing else in the container pipeline uses `modifications`. -- **A `modifications` insert into an array the target does not declare itself creates that array — and it shadows the inherited one.** `chest.small_chest_screen` declares no `controls`; it inherits them, two levels up, from `common.base_screen`, whose single child carries the background, the safe-zone matrix and the `$screen_content` mount. A `controls` insert on `small_chest_screen` left the screen with only the inserted control: compiled screens, inserted at that level, rendered, while a plain chest — and vanilla's content under a compiled one — opened to nothing at all, no screen and nothing in the debug UI. The same happens on any derived definition. The library inserts only into definitions that declare the array, and switches the screen's content by re-declaring the screen, the way vanilla's own `shulker_box_screen` and `barrel_screen` do. -- **`variables` is not an array `modifications` reach.** Only `controls` and `bindings` are; an entry naming `variables` is ignored. -- **A `$variable` as a child's `@`-base, set from the reference site, mounts nothing.** A one-child host declaring `$gate|default` and a child `gate@$gate`, referenced twice with a different `$gate` each, rendered neither — no error, an empty screen on both paths. Vanilla only does this with variables the screen itself sets (`root_screen_panel@$screen_content`). The chest root spells every host out by name. -- **A `remove` of an inherited child drops the whole file, silently.** `pocket_containers.small_chest_panel@panel` has no children of its own; removing `panel`'s children through it produced no log line and none of the file's edits — the inserts included — applied. `insert_back` on the same derived definition works. Nothing in the container pipeline removes a vanilla control any more: vanilla's panel is referenced under a gate, and its label and grid hide themselves by a binding, the way the form hook hides `long_form` and `custom_form`. -- Variables substitute in ordinary properties only when the variable is the entire value: `"text": "$container_title"` works, `"text": "t: $container_title"` prints the dollar sign. - -## Binding types and text - -Per-slot binding types, measured: - -| Binding | Type | Concatenates into text? | -| --- | --- | --- | -| `#collection_total_items` | int | yes | -| `#item_id_aux` | int | yes — `-1` for an empty slot | -| `#item_lock_in_slot` | bool | prints `true` / `false` | -| stack count | string in expressions (see below) | as a key, yes | -| durability, current and total | float | no | -| storage | float | no | - -- Floats are a display limit only: the same float bindings work in arithmetic, comparisons and `#clip_ratio`. -- A label cannot render a raw numeric binding. Concatenate it with a string first — `"source_property_name": "('n=' + #raw)"` — and bind that to `text`. -- **string + float produces nothing.** Only ints concatenate. Rendering a float as text needs a comparison chain, `(0 + (#f > 0) + (#f > 1) + ...)`, which covers 1–10 and drops precision. For text, bucket a float with a comparison chain or carry the number on an int channel. -- Stack count cannot be displayed at all, even bound straight to `text` the way vanilla does it. `#inventory_stack_count` also reports nothing for a stack of one, which is why a live text cell's blank is the lowest code, keyed by the bare prefix. -- **`#inventory_stack_count` is a string inside a binding expression.** On a stack of 19, `(#count = '19')` held and nothing else did: `(#count = 19)`, `(#count = 19.0)`, `(#count > 2)`, `((#count * 1) = 19)`, `((#count * 1) > 2)` and `((#count - 19) = 0)` were all false. Arithmetic does not coerce it. The router's sentinel gates compare the stack size as a quoted literal, and a live text cell concatenates it into a key, which is the one thing a string does. -- string → number is any arithmetic except addition: `(#str * 1)`. -- Booleans are numbers in arithmetic: `true` is 1, `false` is 0. -- `#item_durability_total_amount` reads 2031 on a netherite pickaxe — a durability channel has that much resolution. -- **A vanilla item's `#item_id_aux` is only stable below 256.** Custom items registered by any addon take numeric ids from 256 upward and shift every vanilla item above them (wiki.bedrock.dev, *Numerical Item IDs*; the netherite pickaxe measured 622 in one environment and is listed as 641 in another). Every damageable item lives above 256, so no durability-carrying item can be a protocol marker in a world with other addons. The protocol rides three legacy-range blocks instead — command block, repeating and chain command block, ids 137/188/189, operator-only — and the layout key rides two stack sizes (2..64 each — a stack of one publishes no count — 3969 keys) in the first two container slots, read by two nested gates. -- Labels localize by default: literal text is looked up as a translation key first, so a literal label needs `"localize": false`. The container backend turns this around — a live text cell is a `localize: true` label whose key is built from a slot's stack size, and the `.lang` table turns the key into a glyph. A key with no entry prints itself. -- A `.lang` value of one space defines nothing, because the parser trims trailing whitespace. A blank glyph has to be wrapped in inert formatting codes (`§r §r`) to survive the file format. -- `('%.Ns' * X)` takes a prefix only when `X` is a binding, not a string literal. -- A container slot publishes no text: `#hover_text` is a single hover-driven screen value that any press steals, and `#group_item_group_name` is empty for a container. What a slot publishes is numbers. - -## Server forms - -- **A control the pack places itself can own a `form_buttons` entry — but only if the CONTROL carries the collection binding.** A `stack_panel` declaring `collection_name: "form_buttons"` with a child carrying a baked `collection_index` is enough to *read* that entry, and enough for a `button` in that subtree to be pressed. It is **not** enough for the press to be attributed: the button must itself carry `{ "binding_type": "collection_details", "binding_collection_name": "form_buttons" }`. Measured 2026-08-27 with four rows in one form — three carrying the binding returned `response.selection` 0, 1 and 2 respectively; a fourth, identical but for the binding, returned `canceled`. -- **A form button with no collection binding fails silently and misleadingly.** The click still routes and the form still closes; script sees `canceled`, which is exactly what Esc and the X produce. There is no log line and no visual difference, so a missing binding looks like a player dismissing the form. -- This is what `$cell_details_binding_type` is for in `core_ui_common.control`, which sets it to `collection_details` for buttons and leaves it `none` for panels: the per-cell collection index is what routes `button.form_button_click` to the right form button. -- **A form's content can be replaced without touching a vanilla file.** `server_form.main_screen_content` sizes the library's own container to the screen only when the title carries the protocol header, and `core_ui_common.action_container` — a definition the pack owns, which declares its own `controls` — accepts placed subtrees by ordinary reference. Nothing needs `modifications`, and nothing vanilla is re-declared, so the plain form path is untouched by construction. - -## Script API - -- **No lock mode makes a container slot read-only.** `ItemLockMode.slot` binds the item to a *player* slot, not the container slot: the player moves it out of the container freely and then cannot move it back — it is stuck wherever it landed in their inventory until script clears it. The lock does not stop the take and makes every escape worse. Poll-and-restore is the only mechanism, and items the runtime places carry `ItemLockMode.none`. -- **Restoring a taken slot while the player still holds the original duplicates the item.** Refilling the slot produced two: the copy reappeared in inventory slot 12 a tick later, and the sweep on close reclaimed 4 escaped items. A handler must reclaim the taken instance, not just refill the slot. -- **The cursor is readable.** `PlayerCursorInventoryComponent.item` is the stack in flight between slots and `clear()` removes it, so a reclaim completes in the same tick — container, then inventory, then cursor — confirmed end to end. It is not populated under touch controls, so a sweep on close remains the backstop. -- **`ItemStack.setDynamicProperty` throws on stackable items** (`UnsupportedFunctionalityError: Cannot set dynamic properties on stackable items`). Only max-stack-1 items can carry one; lore works on everything and is the portable fallback. The runtime marks the items it places with a dynamic property where the item can hold one and a lore line where it cannot. -- Non-stackable items in slots the runtime owns stop quick-move from merging into them, and are the only ones that can carry a dynamic property. A live text cell is the exception on purpose: its character *is* the stack size, so it rides a stackable item. - -## Official schema sources - -What a compiled layout can be validated against, and where each part comes from. Checked against `@minecraft/bedrock-schemas` `1.26.20-beta.21` and `1.26.40-beta.26`. - -| Artifact | Contains | Verdict | -| --- | --- | --- | -| `schemas/rp/ui/index.schema.json` | `namespace: string`, nothing else | Not usable: a UI file validates against it whatever is in it | -| `types/rp/ui/UiElement.d.ts` | 90 documented properties, doc comments, enum *declarations* | Usable as the emit type — but every enum is declared with no members | -| `forms/ui/ui_element.form.json` | The same fields plus the real **enum values** | The only official source of valid values. 30 KB | - -`schemas/rp/ui/global_variables.schema.json` documents three example colour variables and is otherwise a stub. A schema download that drops `forms/` as editor snippets loses the only authoritative enum values with it. - -### Enum values, from `forms/ui/ui_element.form.json` - -```txt -type panel, stack_panel, image, label, button, toggle, slider, - slider_box, edit_box, grid, scroll_view, scrollbar_box, - dropdown, input_panel, screen, custom -anchor_from, top_left, top_middle, top_right, left_middle, center, -anchor_to right_middle, bottom_left, bottom_middle, bottom_right -orientation horizontal, vertical -text_alignment left, center, right -font_type default, smooth, rune, unicode, MinecraftTen -font_size small, normal, large, extra_large -binding_type global, collection, collection_details, view, none -binding_condition always, visible, once, always_when_visible, visibility_changed -mapping_type pressed, double_pressed, global, focused -input_mode_condition not_gaze, gamepad_and_not_gaze -grid_rescaling_type none, horizontal, vertical -``` - -Against community-maintained lists: the official one has `slider_box`, which they tend to lack, and lacks `tab`, `carousel_label`, `grid_item` and `selection_wheel`, which they have. Neither is a superset of the other. - -### Used by vanilla, absent from every official artifact - -| Property | Why a compiled layout needs it | -| --- | --- | -| `collection_index` | Addressing a specific slot — the whole container backend. Only valid at an instantiation site, never on a definition | -| `localize` | Labels localize by default; literal text needs it off | -| `clip_ratio`, `clip_direction`, `clip_pixelperfect` | Every bar and gauge | -| `property_bag` | Seeding computed properties before bindings run | -| `modifications` | Patching vanilla screens at all | -| `variables` / `$vars` | Vanilla's own control parameterisation | -| `nineslice_size` | The official types have `nine_slice_left/right/top/buttom` — note the typo — but not the array form vanilla files use | - -### Validation, in three layers - -1. **Official types** as the emit type: `UiElement` from `types/rp/ui`, extended with the delta above in one clearly marked declaration. Anything in the extension is a property Mojang has not documented, which is exactly the set to re-check on each schema bump. -2. **Official enums** from `forms/ui/ui_element.form.json`. -3. **Vanilla sample packs as ground truth** for anything the first two miss. `ok = true` from a validator is not sufficient on its own. diff --git a/docs/ui/flexbox/_category_.json b/docs/ui/flexbox/_category_.json deleted file mode 100644 index 3a655bb..0000000 --- a/docs/ui/flexbox/_category_.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "position": 4, - "label": "flexbox", - "key": "flexbox", - "collapsible": true, - "collapsed": true, - "link": { - "type": "doc", - "id": "flexbox" - } -} diff --git a/docs/ui/flexbox/createNode.md b/docs/ui/flexbox/createNode.md deleted file mode 100644 index e0b6915..0000000 --- a/docs/ui/flexbox/createNode.md +++ /dev/null @@ -1,201 +0,0 @@ ---- -sidebar_position: 2 ---- - -# createNode - -Create a `LayoutNode` ready to be passed to [`computeLayout`](./computeLayout.md). - -## Import - -```ts -import { createNode } from '@bedrock-core/flexbox'; -``` - -## Signature - -```ts -function createNode( - style?: FlexStyle, - children?: LayoutNode[], - measure?: MeasureFunc, -): LayoutNode -``` - -### Parameters - -#### `style` -- Type: `FlexStyle` -- Default: `{}` -- Description: Flex style properties for this node. See the [FlexStyle reference](#flexstyle-reference) below. - -#### `children` -- Type: `LayoutNode[]` -- Default: `[]` -- Description: Child nodes. Their layout is computed relative to this node's content box. - -#### `measure` -- Type: `MeasureFunc` — `(availableWidth: number) => { width: number; height: number }` -- Description: Content measure for **leaf** nodes whose intrinsic size depends on the width they are granted (wrapping text is the canonical case: a narrower box means more lines means a taller node). Omit it for nodes sized by their children or by explicit `width`/`height`. - -### Returns - -A `LayoutNode` with `layout` zeroed out. Layout values are populated only after `computeLayout()` runs. - -```ts -interface LayoutNode { - style: FlexStyle; - children: LayoutNode[]; - layout: ComputedLayout; // zeroed until computeLayout() runs - measure?: MeasureFunc; // width-dependent content sizing, leaves only -} -``` - -## MeasureFunc - -`computeLayout()` calls a node's `measure` twice: first with `Infinity`, then with the width it actually granted — your function must handle both. Explicit `style.width` / `style.height` always win over the measured size, and a `measure` takes precedence over child-derived sizing. - -```ts -import { createNode, type MeasureFunc, type MeasuredSize } from '@bedrock-core/flexbox'; - -const measureLabel: MeasureFunc = (availableWidth): MeasuredSize => { - const lines = wrapToWidth(text, availableWidth); - - return { width: widestLine(lines), height: lines.length * LINE_HEIGHT }; -}; - -const label = createNode({ flexShrink: 1 }, [], measureLabel); -``` - -## ComputedLayout - -After `computeLayout()`, each node's `layout` field holds the resolved geometry. All values are rounded integers (no sub-pixel fractions). - -```ts -interface ComputedLayout { - x: number; // left edge, in texels, from screen origin - y: number; // top edge, in texels, from screen origin - width: number; // in texels - height: number; // in texels - zIndex: number; // resolved z-order (inherited from parent when not set) -} -``` - ---- - -## FlexStyle Reference - -All properties are optional. Defaults mirror CSS flexbox where applicable. - -### Sizing - -#### `width` / `height` -- Type: `number | Percent` (e.g. `200` or `'50%'`) -- Description: Explicit size in texels or as a percentage of the parent's content-box width/height. Omit to derive from content or flex rules. - -#### `minWidth` / `maxWidth` / `minHeight` / `maxHeight` -- Type: `number | Percent` -- Description: Clamps the resolved size to a lower or upper bound. - -#### `aspectRatio` -- Type: `number` (width ÷ height) -- Description: Derives the auto axis from the definite one. An explicit `width` drives the height, an explicit `height` drives the width, and with both auto the width drives (the axis the parent or flex growth resolves first). Ignored when both axes are explicit — matching CSS — and when the node has a `measure`, since the measure owns both dimensions there. - ---- - -### Positioning - -#### `position` -- Type: `'relative' | 'absolute'` -- Default: `'relative'` -- Description: `'relative'` participates in flex flow. `'absolute'` is removed from flow and positioned with `top` / `left` / `right` / `bottom` relative to its parent's content box. - -#### `top` / `right` / `bottom` / `left` -- Type: `number` -- Description: Edge offsets used when `position: 'absolute'`. Providing both `left` and `right` without an explicit `width` stretches the node horizontally. Same applies to `top` + `bottom` for height. - -#### `zIndex` -- Type: `number` -- Description: Z-order layer. Inherited from parent when not set. Higher values render on top. - -#### `display` -- Type: `'flex' | 'none'` -- Default: `'flex'` -- Description: `'none'` removes the node from layout entirely — it takes no space and is invisible to siblings. - ---- - -### Flex Container Props - -These affect how **children** are laid out inside this node. - -#### `flexDirection` -- Type: `'row' | 'row-reverse' | 'column' | 'column-reverse'` -- Default: `'column'` -- Description: Main axis direction. - -#### `wrap` -- Type: `'nowrap' | 'wrap' | 'wrap-reverse'` -- Default: `'nowrap'` -- Description: Whether children wrap onto multiple lines when they overflow the main axis. - -#### `justifyContent` -- Type: `'flex-start' | 'flex-end' | 'center' | 'space-between' | 'space-around' | 'space-evenly'` -- Default: `'flex-start'` -- Description: Distribution of children along the main axis. - -#### `alignItems` -- Type: `'flex-start' | 'flex-end' | 'center' | 'stretch'` -- Default: `'stretch'` -- Description: Alignment of children along the cross axis. `'stretch'` makes children fill the cross dimension. - -#### `alignContent` -- Type: `'flex-start' | 'flex-end' | 'center' | 'stretch' | 'space-between' | 'space-around'` -- Default: `'stretch'` -- Description: Alignment of flex lines when `wrap` is enabled and there are multiple lines. - -#### `gap` -- Type: `number | Percent` -- Description: Space between children on both axes. Use `rowGap` / `columnGap` to set axes independently. - -#### `rowGap` / `columnGap` -- Type: `number | Percent` -- Description: Space between rows / columns when `wrap` is enabled. `rowGap` also applies between children in a `column` container. - -#### `padding` -- Type: `number | Percent` -- Description: Inner spacing on all four sides. Use `paddingTop` / `paddingRight` / `paddingBottom` / `paddingLeft` for per-side control. Percentage values resolve against the **parent's content-box width** for all sides. - ---- - -### Flex Item Props - -These affect how **this node** is sized and positioned inside its parent flex container. - -#### `flex` -- Type: `number` -- Description: Shorthand for `flexGrow` when `flexGrow` is not explicitly set. - -#### `flexGrow` -- Type: `number` -- Default: `0` -- Description: Proportion of remaining free space this node claims. `flex: 1` on siblings shares space equally. - -#### `flexShrink` -- Type: `number` -- Default: `1` -- Description: How much this node shrinks relative to siblings when the container overflows. Set to `0` to prevent shrinking. - -#### `flexBasis` -- Type: `number | Percent | 'auto'` -- Default: `'auto'` -- Description: Hypothetical main-axis size before growing / shrinking is applied. `'auto'` uses `width` / `height` (depending on `flexDirection`). - -#### `alignSelf` -- Type: `'auto' | 'flex-start' | 'flex-end' | 'center' | 'stretch'` -- Default: `'auto'` -- Description: Overrides the parent's `alignItems` for this specific node. - -#### `margin` -- Type: `number | Percent` -- Description: Outer spacing on all four sides. Use `marginTop` / `marginRight` / `marginBottom` / `marginLeft` for per-side control. Percentage values resolve against the **parent's content-box width** for all sides. diff --git a/docs/ui/get-started/_category_.json b/docs/ui/get-started/_category_.json deleted file mode 100644 index 94b132d..0000000 --- a/docs/ui/get-started/_category_.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "position": 1, - "label": "Get started", - "key": "get-started", - "collapsible": true, - "collapsed": false, - "link": { - "type": "doc", - "id": "overview" - } -} \ No newline at end of file diff --git a/docs/ui/guides/_category_.json b/docs/ui/guides/_category_.json index 25ca041..bc1ca54 100644 --- a/docs/ui/guides/_category_.json +++ b/docs/ui/guides/_category_.json @@ -1,11 +1,11 @@ { - "position": 8, - "label": "guides", - "key": "guides", + "position": 3, + "label": "Guides", "collapsible": true, - "collapsed": true, + "collapsed": false, "link": { - "type": "doc", - "id": "guides" + "type": "generated-index", + "title": "Guides", + "description": "The render pack, container screens and native components." } } diff --git a/docs/ui/container-screens/container-screens.md b/docs/ui/guides/container-screens.md similarity index 69% rename from docs/ui/container-screens/container-screens.md rename to docs/ui/guides/container-screens.md index 97dcc1d..56e1b24 100644 --- a/docs/ui/container-screens/container-screens.md +++ b/docs/ui/guides/container-screens.md @@ -1,10 +1,11 @@ --- -sidebar_position: 1 +sidebar_position: 2 +description: "A container screen is a custom entity's chest screen, written in JSX with the same components as a form." --- # Container screens -A **container screen** is a custom entity's chest screen, written in JSX with the same components as a form. The [ui-compile Regolith filter](./regolith-filter.md) compiles it into static JSON UI at build time; at runtime `createContainerScreen` serves it to every player who opens the entity, and everything alive in it — text, buttons, entities, the items in its slots — travels through the container's own slots. +A **container screen** is a custom entity's chest screen, written in JSX with the same components as a form. The [ui-compile Regolith filter](/docs/filters/ui-compile) compiles it into static JSON UI at build time; at runtime `createContainerScreen` serves it to every player who opens the entity, and everything alive in it — text, buttons, entities, the items in its slots — travels through the container's own slots. It is the second backend of `@bedrock-core/ui`. A form is serialized per player when it is shown. A container screen cannot be: the chest screen has no string channel wide enough to carry a layout, so the layout is baked once and only state moves at runtime. What you get in exchange is what a form cannot give — real item slots the player drags into, a screen that stays open while its values change, and state that belongs to a thing in the world. @@ -45,12 +46,12 @@ export default function Furnace() { } ``` -Three things make it a container screen: the file name ends in `.screen.tsx` (that is how the filter finds it), the module default-exports the component, and the root is a [``](../ui-runtime/components/Container.md) naming the entity it opens from. Everything else is the component set you already know. +Three things make it a container screen: the file name ends in `.screen.tsx` (that is how the filter finds it), the module default-exports the component, and the root is a [``](../components/Container.md) naming the entity it opens from. Everything else is the component set you already know. The build runs the component once to decide the **shape**; the runtime runs it again, per viewer, to decide the **values**. The two walks line up position for position because a compiled screen cannot change shape — so nothing is named, nothing is registered, and there is no second file describing the same screen. :::caution A screen must not touch the world at import time -The build evaluates the module once, on the build machine, with `@minecraft/server` replaced by a stub. Hooks are fine; module-scope code that reaches for the game (`world.afterEvents.*.subscribe`, `system.run`, a dynamic property read next to an `import`) is not. Keep that in the module that calls `createContainerScreen` — see [the filter page](./regolith-filter.md#the-one-rule). +The build evaluates the module once, on the build machine, with `@minecraft/server` replaced by a stub. Hooks are fine; module-scope code that reaches for the game (`world.afterEvents.*.subscribe`, `system.run`, a dynamic property read next to an `import`) is not. Keep that in the module that calls `createContainerScreen` — see [the filter page](/docs/filters/ui-compile#the-one-rule). ::: ## Serving it @@ -83,22 +84,22 @@ function createContainerScreen( ## The components -The same set as a form, with four additions and a few container-specific behaviours: +The same set as a form, with four additions and a few container-specific behaviors: | Component | In a container screen | | --- | --- | -| [`Container`](../ui-runtime/components/Container.md) | The root. Names the entity, and is the screen's own panel: `padding`, `gap` and `background` apply. | -| [`Slot`](../ui-runtime/components/Slot.md) | A container cell of the screen's own container. `role` is `both` (storage), `input` (in only) or `output` (out only), enforced server-side; `interactive={false}` locks it inert. `onInsert(event)` and `onRemove(event)` fire after a move, with `event.stack`, `event.player` and `event.host`. Given a `collection`, it instead reads a foreign cell — see [Rendering other containers](#rendering-other-containers). | -| [`SlotGrid`](../ui-runtime/components/SlotGrid.md) | A grid of cells over a foreign collection — any collection the engine exposes. Not part of the screen's own container. | -| [`PlayerInventory`](../ui-runtime/components/PlayerInventory.md), [`Hotbar`](../ui-runtime/components/Hotbar.md) | The player's own grids — thin `SlotGrid` wrappers over `inventory_items` / `hotbar_items`. Placed by the layout engine. Not free: a screen owns the whole chest screen, so leave them out and they are gone. | -| [`Text`](../ui-runtime/components/Text.md) | Baked, unless it has `maxLength` — see [Live text](#live-text). | -| [`Image`](../ui-runtime/components/Image.md) | A texture, baked into the layout. | -| [`Scroll`](../ui-runtime/components/Scroll.md) | A region laid out at its own height that the client scrolls. Not inside another scroll. | -| [`Button`](../ui-runtime/components/Button.md) | A container slot with the item hidden: a press reaches script only as an item move, and the face is ordinary JSON UI. `enabled={false}` draws `backgroundLocked` and ignores presses. Its children are baked into the face, so they are static text or images — including their colour, which is why an [ore-styled](../ore-styled/ore-styled.md) button's caption keeps its enabled colour while its background swaps to the disabled one. | -| [`Background`](../ui-runtime/components/Background.md) | A full-screen texture behind everything, as in a form. | +| [`Container`](../components/Container.md) | The root. Names the entity, and is the screen's own panel: `padding`, `gap` and `background` apply. | +| [`Slot`](../components/Slot.md) | A container cell of the screen's own container. `role` is `both` (storage), `input` (in only) or `output` (out only), enforced server-side; `interactive={false}` locks it inert. `onInsert(event)` and `onRemove(event)` fire after a move, with `event.stack`, `event.player` and `event.host`. Given a `collection`, it instead reads a foreign cell — see [Rendering other containers](#rendering-other-containers). | +| [`SlotGrid`](../components/SlotGrid.md) | A grid of cells over a foreign collection — any collection the engine exposes. Not part of the screen's own container. | +| [`PlayerInventory`](../components/PlayerInventory.md), [`Hotbar`](../components/Hotbar.md) | The player's own grids — thin `SlotGrid` wrappers over `inventory_items` / `hotbar_items`. Placed by the layout engine. Not free: a screen owns the whole chest screen, so leave them out and they are gone. | +| [`Text`](../components/Text.md) | Baked, unless it has `maxLength` — see [Live text](#live-text). | +| [`Image`](../components/Image.md) | A texture, baked into the layout. | +| [`Scroll`](../components/Scroll.md) | A region laid out at its own height that the client scrolls. Not inside another scroll. | +| [`Button`](../components/Button.md) | A container slot with the item hidden: a press reaches script only as an item move, and the face is ordinary JSON UI. `enabled={false}` draws `backgroundLocked` and ignores presses. Its children are baked into the face, so they are static text or images — including their color, which is why an [ore-styled](/docs/ore-styled) button's caption keeps its enabled color while its background swaps to the disabled one. | +| [`Background`](../components/Background.md) | A full-screen texture behind everything, as in a form. | | `Panel`, `Fragment`, contexts | Exactly as in a form. | -[ore-styled](../ore-styled/ore-styled.md) components compose the same way: the `Button` above is ore-styled's, with `enabled` driving its disabled look. +[ore-styled](/docs/ore-styled) components compose the same way: the `Button` above is ore-styled's, with `enabled` driving its disabled look. ### Live text @@ -133,7 +134,7 @@ What *is* baked into the JSON UI is inertness. A container slot's take and place State is **entity-owned**. Hook state lives on the entity the screen is attached to, in a dynamic property, and persists on its own: close the screen and reopen it, leave and come back, restart the world — the furnace is still at the charge it was left at. Nothing has to be saved or restored, but it does mean state must be JSON-serializable: numbers, strings, booleans, plain objects and arrays. -There is no single viewer, so **the player reaches a screen through its handlers** rather than a hook: `Slot` and `Button` handlers receive an event carrying the player who moved the item, and the `Container` itself has `onOpen` / `onClose` carrying the player who came or went — keep what the screen needs (a name, a count of viewers) in state. [`usePlayer`](../ui-runtime/hooks/usePlayer.md) is unavailable, because a container screen has no player of its own. [`useExit`](../ui-runtime/hooks/useExit.md) hands back a press rather than a closer: nothing closes a container from script, but a ` - - -``` - -### Centered content - -```tsx - - {'Centered'} - -``` - -### Visibility Control - -```tsx -function ConditionalUI({ showButton }: { showButton: boolean }) { - return ( - - {'Some text'} - - - ); -} -``` - -### Display None vs Visible - -```tsx -{/* visible={false} keeps the space reserved */} - - -{/* display={'none'} removes from layout — siblings collapse */} - -``` - -### Absolute Positioning - -```tsx - - {'Main content'} - {/* Pinned to top-right, outside normal flow */} - - {'✕'} - - -``` - -## Visibility vs Display - -| | `visible={false}` | `display={'none'}` | -|---|---|---| -| Space reserved | Yes | No | -| Children executed | Yes | No | -| Use case | Hide visually | Remove from layout | - -## TypeScript - -```tsx -import type { ControlProps, LayoutProps } from '@bedrock-core/ui'; -``` - -`LayoutProps` carries the flex layout properties; `ControlProps` extends it with `visible`, `enabled`, and `background`. Every built-in component's props type extends `ControlProps`. Individual types are also exported: - -```tsx -import type { - FlexDirection, FlexSize, FlexWrap, - JustifyContent, AlignItems, AlignContent, AlignSelf, - Display, Position, Spacing, -} from '@bedrock-core/ui'; -``` - -The underlying primitives (`Percent`, `FlexStyle`, …) live in the flexbox entry point: - -```tsx -import type { Percent, FlexStyle } from '@bedrock-core/ui/flexbox'; -``` diff --git a/docs/ui/ui-runtime/components/modal-field-props.md b/docs/ui/ui-runtime/components/modal-field-props.md deleted file mode 100644 index ba97937..0000000 --- a/docs/ui/ui-runtime/components/modal-field-props.md +++ /dev/null @@ -1,60 +0,0 @@ ---- -sidebar_position: 19 ---- -# Modal Field Props - -:::caution Deprecated -These props belong to the legacy one-modal-per-field components. New [`Form`](./Form/Form.md) fields configure modal chrome differently — there's no per-field `label`/`title`/`body`/`submitLabel`/`tooltip`, since a `Form` has one shared modal and headings are authored as a `Text` node. -::: - -Shared props for the **modal-backed field** components — [`Input`](./Input.md), [`Dropdown`](./Dropdown.md), and [`Slider`](./Slider.md). - -Native `ActionFormData` (what this runtime renders to) can't take typed input, so each of these components is really a [`Button`](./Button.md) that *looks like* a form field. Pressing it opens a single-control `ModalFormData`; when the player confirms, the value is committed and the root form re-presents. These props configure that modal — they do **not** appear on the button face, which always shows the current value (or placeholder). - -`ModalFieldProps` extends [control props](./control-props.md), so every field also supports the full set of layout / visibility / background props. - -## Available Props - -#### `label` -- Type: `string` -- Description: Label for the control *inside* the modal. Not shown on the button face. - -#### `title` -- Type: `string` -- Default: the `label` -- Description: Title of the modal window. - -#### `body` -- Type: `string` -- Description: Descriptive text shown above the control. `ModalFormData` has no body, so this renders as a leading label line. - -#### `submitLabel` -- Type: `string` -- Description: Text on the modal's confirm/submit button. - -#### `tooltip` -- Type: `string` -- Description: Hover tooltip on the modal control. - -## Customizing the face - -Each field also accepts a component-specific `face` prop (`JSX.Node`) that overrides what's drawn on the button face — while the component keeps owning the modal flow and value state. This is the seam styled wrappers build on: run the field controlled (`value` + `onChange`) so you know the current value, then pass a `face` node that renders it however you like. - -```tsx -{`§f${name === '' ? '§7type a name' : name}`}} -/> -``` - -The themed [`@bedrock-core/ore-styled`](../../ore-styled/ore-styled.md) `Input`, `Dropdown`, and `Slider` are exactly this pattern: the chevron and the slider track/thumb are custom `face` nodes. - -## TypeScript - -```tsx -import type { ModalFieldProps } from '@bedrock-core/ui'; -``` - -Handy when building your own styled wrapper around `Input` / `Dropdown` / `Slider`. diff --git a/docs/ui/ui-runtime/hooks/hooks.md b/docs/ui/ui-runtime/hooks/hooks.md deleted file mode 100644 index 85ffd37..0000000 --- a/docs/ui/ui-runtime/hooks/hooks.md +++ /dev/null @@ -1,38 +0,0 @@ ---- -sidebar_position: 1 ---- -# Hooks - -State and effects management for your components. - -## Built-in Hooks - -### State Management - -- [`useState`](./useState.md) - Manage component state. -- [`useReducer`](./useReducer.md) - Manage complex state logic with a reducer function. -- [`useContext`](./useContext.md) - Access context values from Context. - -### Effects & Lifecycle - -- [`useEffect`](./useEffect.md) - Perform side effects in function components with cleanup support. -- [`useExit`](./useExit.md) - Request the UI to be closed. - -### References - -- [`useRef`](./useRef.md) - Create a mutable reference that is persisted across executions. - -### Minecraft specific - -- [`usePlayer`](./usePlayer.md) - Access the current player who is viewing the UI. -- [`useEvent`](./useEvent.md) - Subscribe to global Minecraft events within your UI components. - -### Localization - -- [`useTranslation`](./useTranslation.md) - Bind an addon's typed translation verbs to the viewing player. -- [`useTranslationResolver`](./useTranslationResolver.md) - Read the translation resolver active for this part of the tree. - -## Next Steps - -- [Components](../components/components.md) - Built-in components that you can use in your JSX -- [API](../api/api.md) - APIs that are useful for defining components diff --git a/docs/ui/ui-runtime/render-pack.md b/docs/ui/ui-runtime/render-pack.md deleted file mode 100644 index 66012c0..0000000 --- a/docs/ui/ui-runtime/render-pack.md +++ /dev/null @@ -1,182 +0,0 @@ ---- -sidebar_position: 4 ---- - -# Render pack - -`@bedrock-core/ui` renders through Minecraft's own server forms: the runtime serializes each component's props into a byte-addressed payload string, and the **render pack** decodes those bytes with JSON UI bindings and draws the screen. That wire format is versioned. - -This release ships **protocol v0008**. - -:::danger Existing projects must update the render pack -The protocol version is a hard gate, not a negotiation. A behavior pack emitting `bcuiv0008` payloads into a world running an older render pack renders **nothing** — the pack's decoders match on the header and drop everything else. Update the pack before (or with) the library. -::: - -## Getting the matching pack - -The render pack ships as the `core-ui-v*.mcpack` attached to each `@bedrock-core/ui` release, and the [CLI](../cli.md) downloads the latest one into new projects automatically. **Take the pack from the same release as the library** — that pairing is the compatibility contract. - -Its UUID never changes — `761ecd37-ad1c-4a64-862a-d6cc38767426` — so the dependency entry in your behavior pack's `manifest.json` stays as it is: - -```json -{ - "dependencies": [ - { - "uuid": "761ecd37-ad1c-4a64-862a-d6cc38767426", - "version": [1, 10, 0] - } - ] -} -``` - -### Which pack goes with which release - -The pack's version tracks the **library release it ships in**: pack `1.10.x` belongs to `@bedrock-core/ui` `0.10.x`. Match the minor and you have the right pack. - -| Pack version | Library | Protocol | -| --- | --- | --- | -| `1.10.x` | `0.10.x` | `v0008` | - -The protocol is not encoded in the version. To read a pack's protocol directly, look at its description in the in-game pack list: *"by DrAv0011 — protocol v0008"*. - -Ship the pack alongside your own, exactly as described in [Installation](../get-started/installation.md). - -:::caution One pack, one world -The render pack is world-scoped and shared by every addon in the world that uses `@bedrock-core/ui`. Whichever copy the world loads is the one every addon decodes against, so a world mixing addons built for different protocol versions can only satisfy one of them. Keep the framework version aligned across the addons you ship together. - -The pack decodes only payloads carrying its own header, so an addon on a different protocol falls through to the **plain vanilla form** (its payload rendered as raw text) rather than being decoded at the wrong offsets. Visibly broken for that one addon; nothing else in the world is affected. -::: - -## How to tell which version you are emitting - -The header is the first nine bytes of every payload the runtime writes. `serializer.ts` holds it as two constants: - -```ts -export const VERSION = 'v0008'; -export const PROTOCOL_HEADER = `bcui${VERSION}`; // 'bcuiv0008' -export const PROTOCOL_HEADER_LENGTH = 9; // bytes, all single-byte ASCII -``` - -The resource pack carries the same string as `$protocol_header` in its JSON UI definitions. If a screen opens completely blank while the script log shows no error, mismatched headers are the first thing to check. - -## What changed in v0008 - -Three changes, all breaking. - -### 1. Text is one channel, with an uncapped tail - -Before v0008, a payload was a sequence of **fixed-width** fields: every string occupied 83 bytes (`s:` prefix + 80 bytes of content + a 1-byte uniqueness marker), which capped any rendered text at 80 UTF-8 bytes. Longer copy had to go through a separate `localizationKey` prop that shipped a `.lang` key instead of the text. - -v0008 reorders the label field group to `[fontType, fontScale, x, y, text]` — **text last** — and makes the text of terminal payloads a **variable-length tail**: unpadded, unprefixed, uncapped. Everything before the tail still decodes at fixed offsets; the tail is simply "the rest". - -Because a key and a literal now share one wire format (both read by a `localize: true` label), there is nothing left to declare. `Text` has **one** text channel: - -```tsx -// v0007 and earlier — REMOVED - -{'Short literal'} - -// v0008 -{'Short literal'} {/* paints literally */} -{key($ => $.shop.title)} {/* resolver knows it → localized */} -{raw($ => $.shop.bought, { item, price })} {/* RawMessage → client resolves */} -``` - -`children` is now `DisplayText` (`string | RawMessage`). A string is **auto-detected**: if the active resolver knows it as a key, it is localized; otherwise it paints literally — which is exactly what Bedrock does with an unmatched `.lang` key. A `RawMessage` with arguments travels as a rawtext pair, `[{ text: }, ]`, and the **client** resolves and fills it: its own language, no length cap, `score`/`selector` parts included. - -See [`Text`](./components/Text.md) for the component and [i18n](../i18n/i18n.md) for where `key()` / `raw()` come from. - -### 2. A common `fontType` field at `[606-688]` - -The merged label cell mounts for **every** cell type, so its label decoded the font slot whatever the cell actually was. Read from the component-specific region at `[1024]`, that slot was an image's `texture` or a button's `backgroundHover` — and `#font_type` is engine-reserved, so the alias is validated the moment it is written. Opening a form logged one `Could not find font alias textures/…` line per image, divider and button to `NonAssertErrorLog`, which blocks Marketplace submission. - -`fontType` is now a **common control field**, carved out of the reserved block (418 → 335 bytes) the same way `region` was in v0006. Every component carries a valid alias at a fixed offset — non-text components default to `'default'` — so the label can decode it unconditionally and never sees a texture path. - -Critically, the control block still ends at 1024, so **every component-specific offset is unchanged**. - -### 3. `Image.texture` is the payload tail - -An `` cell is terminal — no children, one component field — so its `texture` now rides the same variable-length tail as a `Text` cell's content: emitted raw from `[1024]`, unpadded, unprefixed, uncapped. It was a fixed 83-byte string cell, which capped texture paths at 80 UTF-8 bytes and threw a `SerializationError` past it; deeply nested `textures/ui/…` paths hit that regularly. The render pack decodes it as the whole post-`[1024]` remainder. - -Nothing before `[1024]` moved, the common `fontType` slot included — the control block below is unchanged. - -### The v0008 control block - -```txt -[0-8]: Protocol header (9 bytes, 'bcuiv0008') -[9-91]: type (string, 83 bytes) -[92-174]: width (number, 83) — computed by the layout engine -[175-257]: height (number, 83) — computed by the layout engine -[258-340]: x (number, 83) — computed by the layout engine -[341-423]: y (number, 83) — computed by the layout engine -[424-431]: visible (bool, 8) -[432-439]: enabled (bool, 8) -[440-522]: background (string, 83) -[523-605]: region (number, 83) — scroll index this element belongs to -[606-688]: fontType (string, 83) — the cell's font alias ← new in v0008 -[689-1023]: Reserved (335 bytes) ← was 418 -[1024-]: Component-specific fields -``` - -For an `Image` cell the component-specific region is just the texture tail. For a `Text` cell it carries the label group: `labelFontType`, `fontScaleFactor`, `labelX` `[1190]`, `labelY` `[1273]`, and the text tail. `labelFontType` stays in the group even though the cell label now sources `[606]`, so every later group offset — and every sub-element group that still reads its own slot 1 — is unchanged. - -:::tip Custom native components are unaffected -Fields you define in a [custom native component](./api/custom-native-components.md) still start at `[1024]`. Both `region` (v0006) and `fontType` (v0008) were carved from the reserved block precisely so this offset never moves. If your resource pack decodes a custom component at a fixed offset from 1024, it keeps working — you only need the new render pack for the built-in components. -::: - -## Protocol history - -| Version | Change | -| --- | --- | -| `v0008` | Label group reordered to `[fontType, fontScale, x, y, text]`; terminal text is an uncapped variable tail; `Image.texture` is that tail too (uncapped); `RawMessage` tails serialize as rawtext for the client; common `fontType` field at `[606-688]` (reserved 418 → 335) | -| `v0007` | Scroll-component model — the title carries a flat list of scroll viewports (axis + geometry + content extent) instead of a screen type with per-region extents; a component's `region` field now holds the scroll index it belongs to | -| `v0006` | Common `region` field carved from the reserved block; title metadata generalized to one extent per region | - -## Upgrading your code - -Beyond the pack bump, three things changed at the API level. - -### `Text.localizationKey` is removed - -Replace it with a `children` value. If the string is a key your bundle publishes, the resolver detects it: - -```tsx -// before - - -// after — typed, namespace applied at runtime -{key($ => $.shop.title)} - -// after — if you genuinely only have the raw key string -{'drav0011_shop.shop.title'} -``` - -### The translation-keys plumbing is gone - -`TranslationKeysContext`, `resolveTranslationKeysForPlayer`, `TranslationKeysByLocale` and `TranslationKeysMap` were removed along with the `translation-keys` Regolith filter. Resolution is now `@bedrock-core/i18n`-native and lazy — there are no materialized key maps anywhere. - -```tsx -// before — a provider at the root, with a materialized map - - - - -// after — nothing at the root at all -export const i18n = createI18n(bundle); // registers the default translation source -render(App, player); // render() injects the resolver per player -``` - -Only override it deliberately, via [`TranslationContext`](./api/TranslationContext.md). - -### The 80-byte text cap no longer applies to rendered text - -Advice to "keep it under 80 bytes or use a localization key" is obsolete for `Text` children and for `Image.texture` — both are tails, both uncapped. Every **other** string field in a payload (`Background` and state textures, fonts, form labels routed through native channels) is still a fixed 83-byte field with an 80-byte content budget, and exceeding it still throws a `SerializationError` at serialize time. - -## Checklist - -1. Update `@bedrock-core/ui` (or `@bedrock-core/ui-runtime`) to this release. -2. Download the `core-ui-v*.mcpack` from the **same** release. -3. Replace the old pack in your `.mcaddon`, and **re-import** it into every test world and `com.mojang` install — the version number is unchanged, so nothing will prompt you to update. -4. Remove every `localizationKey` prop and the `TranslationKeysContext` provider. -5. Migrate your `.lang` authoring to the [i18n filter](../i18n/regolith-filter.md), or keep the keys and pass them as `Text` children. -6. Rebuild and open a screen. A blank screen with a clean log means the world is still loading an older pack. diff --git a/docs/ui/ui-runtime/ui-runtime.md b/docs/ui/ui-runtime/ui-runtime.md deleted file mode 100644 index 4836588..0000000 --- a/docs/ui/ui-runtime/ui-runtime.md +++ /dev/null @@ -1,21 +0,0 @@ ---- -sidebar_position: 1 ---- - -# ui-runtime - -`@bedrock-core/ui-runtime` is the core rendering and component system for building Bedrock UI. - -It provides the JSX component primitives, hook system, and the API surface used to mount and manage your UI trees. - -## Sections - -| Section | Description | -|---|---| -| [**Components**](./components/components.md) | Primitive building blocks: `Panel`, `Text`, `Button`, `Image`, `Background`, `Scroll`, `Fragment` | -| [**Hooks**](./hooks/hooks.md) | Reactive state and lifecycle: `useState`, `useEffect`, `useEvent`, `useReducer`, and more | -| [**API**](./api/api.md) | Top-level functions: `render`, `createContext` | - -## Localization - -Localized text is not a separate component set: `` accepts literal and localized children on one channel, and `render()` injects the viewing player's resolver at every root. Bind the typed verbs with [`useTranslation`](./hooks/useTranslation.md), or read the active resolver with [`useTranslationResolver`](./hooks/useTranslationResolver.md) / [`TranslationContext`](./api/TranslationContext.md). The authoring side — bundles, plurals, interpolation, locale resolution — lives in [i18n](../i18n/i18n.md). diff --git a/docusaurus.config.ts b/docusaurus.config.ts index ad8727b..f322e36 100644 --- a/docusaurus.config.ts +++ b/docusaurus.config.ts @@ -1,6 +1,14 @@ -import { themes as prismThemes } from 'prism-react-renderer'; import type { Config } from '@docusaurus/types'; import type * as Preset from '@docusaurus/preset-classic'; +import { existsSync } from 'node:fs'; +import { categories, publishedSections, sectionsOf } from './src/data/sections'; +import { redirects } from './src/data/redirects'; +import { bedrockPrism } from './src/prism/bedrock'; + +// Sections that have a docs/ folder today. Planned sections stay in the +// registry (menus, home page) without an instance. +const liveSections = publishedSections.filter((section) => existsSync(`docs/${section.id}`)); +const isLive = (id: string): boolean => liveSections.some((section) => section.id === id); // This runs in Node.js - Don't use client-side code here (browser APIs, JSX...) @@ -54,28 +62,19 @@ const config: Config = { ], ], + // One docs instance per section: docs/ served at /docs/ with its own sidebar. plugins: [ 'docusaurus-plugin-llms', - [ + ...liveSections.map((section) => [ '@docusaurus/plugin-content-docs', { - id: 'server', - path: 'docs/server', - routeBasePath: 'docs/server', + id: section.id, + path: `docs/${section.id}`, + routeBasePath: `docs/${section.id}`, sidebarPath: './sidebars.ts', - editUrl: 'https://github.com/bedrock-core/docs/edit/main/docs/server/', + editUrl: `https://github.com/bedrock-core/docs/edit/main/docs/${section.id}/`, }, - ], - [ - '@docusaurus/plugin-content-docs', - { - id: 'ui', - path: 'docs/ui', - routeBasePath: 'docs/ui', - sidebarPath: './sidebars.ts', - editUrl: 'https://github.com/bedrock-core/docs/edit/main/docs/ui/', - }, - ], + ]), [ '@docusaurus/plugin-client-redirects', { @@ -84,6 +83,7 @@ const config: Config = { to: 'https://discord.gg/xq9JpJ3', from: ['/discord'], }, + ...redirects, ], }, ], @@ -101,39 +101,26 @@ const config: Config = { src: 'img/logo/icon.png', }, items: [ - { - type: 'docSidebar', - sidebarId: 'serverSidebar', - docsPluginId: 'server', - position: 'left', - label: 'server', - }, - { - type: 'docSidebar', - sidebarId: 'uiSidebar', - docsPluginId: 'ui', - position: 'left', - label: 'ui', - }, - { - label: 'Discord', - href: 'https://bedrock-core.drav.dev/discord', - position: 'right', - }, - { - href: 'https://github.com/bedrock-core/', - label: 'GitHub', - position: 'right', - }, + { type: 'custom-docsMenu', position: 'left', label: 'Docs' }, + { to: '/showcase', label: 'Showcase', position: 'left' }, + { type: 'search', position: 'right' }, + { type: 'custom-iconLink', position: 'right', href: 'https://bedrock-core.drav.dev/discord', icon: 'discord', label: 'Discord' }, + { type: 'custom-iconLink', position: 'right', href: 'https://github.com/bedrock-core/', icon: 'github', label: 'GitHub' }, ], }, - footer: { - style: 'dark', - copyright: `Copyright © ${new Date().getFullYear()} @bedrock-core. Built with Docusaurus.`, + // DocSearch: apply at https://docsearch.algolia.com/apply/ and paste the + // credentials here; the search box stays inert until they are real. + algolia: { + appId: 'BEDROCKCORE', + apiKey: 'replace-with-the-docsearch-search-only-key', + indexName: 'bedrock-core', + contextualSearch: false, }, + // Code blocks stay dark in both themes; one palette serves both. prism: { - theme: prismThemes.github, - darkTheme: prismThemes.dracula, + theme: bedrockPrism, + darkTheme: bedrockPrism, + additionalLanguages: ['json5'], }, } satisfies Preset.ThemeConfig, }; diff --git a/sidebars.ts b/sidebars.ts index 8e0ccc1..e0dac8d 100644 --- a/sidebars.ts +++ b/sidebars.ts @@ -1,25 +1,9 @@ import type { SidebarsConfig } from '@docusaurus/plugin-content-docs'; -// This runs in Node.js - Don't use client-side code here (browser APIs, JSX...) - -/** - * Creating a sidebar enables you to: - - create an ordered group of docs - - render a sidebar for each doc of that group - - provide next/previous navigation - - The sidebars can be generated from the filesystem, or explicitly defined here. - - Create as many sidebars as you want. - */ +// Every docs instance reads this file and builds its `docs` sidebar from its +// own folder: `_category_.json` files group pages, `sidebar_position` orders them. const sidebars: SidebarsConfig = { - serverSidebar: [ - { - type: 'autogenerated', - dirName: '.', - }, - ], - uiSidebar: [ + docs: [ { type: 'autogenerated', dirName: '.', diff --git a/src/data/redirects.ts b/src/data/redirects.ts new file mode 100644 index 0000000..2ef05c4 --- /dev/null +++ b/src/data/redirects.ts @@ -0,0 +1,105 @@ +// Old routes from the two-tree layout, kept alive by plugin-client-redirects. + +export const redirects: { from: string; to: string }[] = [ + { from: '/docs/server/get-started/installation', to: '/docs/server/installation' }, + { from: '/docs/server/get-started/overview', to: '/docs/server' }, + { from: '/docs/server/server-runtime', to: '/docs/server/api/runtime' }, + { from: '/docs/server/server-runtime/config', to: '/docs/server/api/config' }, + { from: '/docs/server/server-runtime/features', to: '/docs/server/api/features' }, + { from: '/docs/server/server-runtime/guides', to: '/docs/server/api/guides' }, + { from: '/docs/server/server-runtime/host', to: '/docs/server/api/host' }, + { from: '/docs/server/server-runtime/registry', to: '/docs/server/api/registry' }, + { from: '/docs/server/server-runtime/shared', to: '/docs/server/api/shared' }, + { from: '/docs/server/server-runtime/translations', to: '/docs/server/api/translations' }, + { from: '/docs/server/sync', to: '/docs/sync' }, + { from: '/docs/server/sync/discovery', to: '/docs/sync/discovery' }, + { from: '/docs/server/sync/protocol', to: '/docs/sync/protocol' }, + { from: '/docs/server/sync/rpc', to: '/docs/sync/rpc' }, + { from: '/docs/server/sync/state', to: '/docs/sync/state' }, + { from: '/docs/server/ui-integration', to: '/docs/server/guides/ui-integration' }, + { from: '/docs/ui/cli', to: '/docs/cli' }, + { from: '/docs/ui/config', to: '/docs/config' }, + { from: '/docs/ui/container-screens', to: '/docs/ui/guides/container-screens' }, + { from: '/docs/ui/container-screens/findings', to: '/docs/ui/guides/container-screens' }, + { from: '/docs/ui/container-screens/regolith-filter', to: '/docs/filters/ui-compile' }, + { from: '/docs/ui/flexbox', to: '/docs/flexbox' }, + { from: '/docs/ui/flexbox/computeLayout', to: '/docs/flexbox/computeLayout' }, + { from: '/docs/ui/flexbox/createNode', to: '/docs/flexbox/createNode' }, + { from: '/docs/ui/get-started/installation', to: '/docs/ui/installation' }, + { from: '/docs/ui/get-started/overview', to: '/docs/ui' }, + { from: '/docs/ui/guides', to: '/docs/guides' }, + { from: '/docs/ui/guides/regolith-filter', to: '/docs/filters/guides' }, + { from: '/docs/ui/i18n', to: '/docs/i18n' }, + { from: '/docs/ui/i18n/regolith-filter', to: '/docs/filters/i18n' }, + { from: '/docs/ui/navigation', to: '/docs/navigation' }, + { from: '/docs/ui/navigation/createStackNavigator', to: '/docs/navigation/createStackNavigator' }, + { from: '/docs/ui/navigation/useNavigation', to: '/docs/navigation/useNavigation' }, + { from: '/docs/ui/navigation/useRoute', to: '/docs/navigation/useRoute' }, + { from: '/docs/ui/ore-styled', to: '/docs/ore-styled' }, + { from: '/docs/ui/ore-styled/Button', to: '/docs/ore-styled/Button' }, + { from: '/docs/ui/ore-styled/Card', to: '/docs/ore-styled/Card' }, + { from: '/docs/ui/ore-styled/Checkbox', to: '/docs/ore-styled/Checkbox' }, + { from: '/docs/ui/ore-styled/Divider', to: '/docs/ore-styled/Divider' }, + { from: '/docs/ui/ore-styled/Dropdown', to: '/docs/ore-styled/Dropdown' }, + { from: '/docs/ui/ore-styled/Form', to: '/docs/ore-styled/Form' }, + { from: '/docs/ui/ore-styled/Form/FormButton', to: '/docs/ore-styled/Form/FormButton' }, + { from: '/docs/ui/ore-styled/Form/FormCheckbox', to: '/docs/ore-styled/Form/FormCheckbox' }, + { from: '/docs/ui/ore-styled/Form/FormDropdown', to: '/docs/ore-styled/Form/FormDropdown' }, + { from: '/docs/ui/ore-styled/Form/FormInput', to: '/docs/ore-styled/Form/FormInput' }, + { from: '/docs/ui/ore-styled/Form/FormRadio', to: '/docs/ore-styled/Form/FormRadio' }, + { from: '/docs/ui/ore-styled/Form/FormSlider', to: '/docs/ore-styled/Form/FormSlider' }, + { from: '/docs/ui/ore-styled/Form/FormToggle', to: '/docs/ore-styled/Form/FormToggle' }, + { from: '/docs/ui/ore-styled/Form/FormToggleButton', to: '/docs/ore-styled/Form/FormToggleButton' }, + { from: '/docs/ui/ore-styled/Header', to: '/docs/ore-styled/Header' }, + { from: '/docs/ui/ore-styled/Input', to: '/docs/ore-styled/Input' }, + { from: '/docs/ui/ore-styled/MenuRow', to: '/docs/ore-styled/MenuRow' }, + { from: '/docs/ui/ore-styled/Radio', to: '/docs/ore-styled/Radio' }, + { from: '/docs/ui/ore-styled/Slider', to: '/docs/ore-styled/Slider' }, + { from: '/docs/ui/ore-styled/Toggle', to: '/docs/ore-styled/Toggle' }, + { from: '/docs/ui/ore-styled/ToggleButton', to: '/docs/ore-styled/ToggleButton' }, + { from: '/docs/ui/ore-styled/theme', to: '/docs/ore-styled/theme' }, + { from: '/docs/ui/ui-runtime', to: '/docs/ui' }, + { from: '/docs/ui/ui-runtime/api', to: '/docs/ui/api' }, + { from: '/docs/ui/ui-runtime/api/TranslationContext', to: '/docs/ui/api/TranslationContext' }, + { from: '/docs/ui/ui-runtime/api/createContext', to: '/docs/ui/api/createContext' }, + { from: '/docs/ui/ui-runtime/api/custom-native-components', to: '/docs/ui/guides/custom-native-components' }, + { from: '/docs/ui/ui-runtime/api/render', to: '/docs/ui/api/render' }, + { from: '/docs/ui/ui-runtime/components', to: '/docs/ui/components' }, + { from: '/docs/ui/ui-runtime/components/Background', to: '/docs/ui/components/Background' }, + { from: '/docs/ui/ui-runtime/components/Button', to: '/docs/ui/components/Button' }, + { from: '/docs/ui/ui-runtime/components/Container', to: '/docs/ui/components/Container' }, + { from: '/docs/ui/ui-runtime/components/Dropdown', to: '/docs/ui/components/deprecated/Dropdown' }, + { from: '/docs/ui/ui-runtime/components/Form', to: '/docs/ui/components/Form' }, + { from: '/docs/ui/ui-runtime/components/Form/FormButton', to: '/docs/ui/components/Form/FormButton' }, + { from: '/docs/ui/ui-runtime/components/Form/FormDropdown', to: '/docs/ui/components/Form/FormDropdown' }, + { from: '/docs/ui/ui-runtime/components/Form/FormInlineSelect', to: '/docs/ui/components/Form/FormInlineSelect' }, + { from: '/docs/ui/ui-runtime/components/Form/FormInput', to: '/docs/ui/components/Form/FormInput' }, + { from: '/docs/ui/ui-runtime/components/Form/FormOption', to: '/docs/ui/components/Form/FormOption' }, + { from: '/docs/ui/ui-runtime/components/Form/FormSlider', to: '/docs/ui/components/Form/FormSlider' }, + { from: '/docs/ui/ui-runtime/components/Form/FormToggle', to: '/docs/ui/components/Form/FormToggle' }, + { from: '/docs/ui/ui-runtime/components/Fragment', to: '/docs/ui/components/Fragment' }, + { from: '/docs/ui/ui-runtime/components/Hotbar', to: '/docs/ui/components/Hotbar' }, + { from: '/docs/ui/ui-runtime/components/Image', to: '/docs/ui/components/Image' }, + { from: '/docs/ui/ui-runtime/components/Input', to: '/docs/ui/components/deprecated/Input' }, + { from: '/docs/ui/ui-runtime/components/Panel', to: '/docs/ui/components/Panel' }, + { from: '/docs/ui/ui-runtime/components/PlayerInventory', to: '/docs/ui/components/PlayerInventory' }, + { from: '/docs/ui/ui-runtime/components/Scroll', to: '/docs/ui/components/Scroll' }, + { from: '/docs/ui/ui-runtime/components/Slider', to: '/docs/ui/components/deprecated/Slider' }, + { from: '/docs/ui/ui-runtime/components/Slot', to: '/docs/ui/components/Slot' }, + { from: '/docs/ui/ui-runtime/components/SlotGrid', to: '/docs/ui/components/SlotGrid' }, + { from: '/docs/ui/ui-runtime/components/Text', to: '/docs/ui/components/Text' }, + { from: '/docs/ui/ui-runtime/components/control-props', to: '/docs/ui/components/control-props' }, + { from: '/docs/ui/ui-runtime/components/modal-field-props', to: '/docs/ui/components/deprecated/modal-field-props' }, + { from: '/docs/ui/ui-runtime/hooks', to: '/docs/ui/hooks' }, + { from: '/docs/ui/ui-runtime/hooks/useContext', to: '/docs/ui/hooks/useContext' }, + { from: '/docs/ui/ui-runtime/hooks/useEffect', to: '/docs/ui/hooks/useEffect' }, + { from: '/docs/ui/ui-runtime/hooks/useEvent', to: '/docs/ui/hooks/useEvent' }, + { from: '/docs/ui/ui-runtime/hooks/useExit', to: '/docs/ui/hooks/useExit' }, + { from: '/docs/ui/ui-runtime/hooks/usePlayer', to: '/docs/ui/hooks/usePlayer' }, + { from: '/docs/ui/ui-runtime/hooks/useReducer', to: '/docs/ui/hooks/useReducer' }, + { from: '/docs/ui/ui-runtime/hooks/useRef', to: '/docs/ui/hooks/useRef' }, + { from: '/docs/ui/ui-runtime/hooks/useState', to: '/docs/ui/hooks/useState' }, + { from: '/docs/ui/ui-runtime/hooks/useTranslation', to: '/docs/ui/hooks/useTranslation' }, + { from: '/docs/ui/ui-runtime/hooks/useTranslationResolver', to: '/docs/ui/hooks/useTranslationResolver' }, + { from: '/docs/ui/ui-runtime/render-pack', to: '/docs/ui/guides/render-pack' }, +]; diff --git a/src/data/sections.ts b/src/data/sections.ts new file mode 100644 index 0000000..e381636 --- /dev/null +++ b/src/data/sections.ts @@ -0,0 +1,200 @@ +// The docs registry. One entry per section: a folder under docs/, a route, +// a sidebar, and a row in every menu. docusaurus.config.ts creates one +// docs-plugin instance per non-planned section from this list; the navbar, +// the sidebar switcher and the home page read it on the client. +// +// Plain data only — this file is imported from Node and from the browser. + +export type CategoryId = 'framework' | 'ui' | 'content' | 'tooling'; + +export type SectionStatus = 'pre-1.0' | '1.0' | 'planned'; + +export interface Category { + id: CategoryId; + label: string; + /** CSS custom property carrying the category colour, e.g. `--cat-framework`. */ + accent: string; +} + +export interface Section { + /** Folder under docs/, plugin id and route: /docs/. */ + id: string; + /** Package name as shown in menus, lowercase. */ + label: string; + /** Published package or repository name. */ + pkg: string; + category: CategoryId; + status: SectionStatus; + /** One line for menu rows and package cards. */ + description: string; + /** Lucide icon name. */ + icon: string; + /** Source repository. */ + repo: string; +} + +export const categories: Category[] = [ + { id: 'framework', label: 'Framework', accent: '--cat-framework' }, + { id: 'ui', label: 'UI', accent: '--cat-ui' }, + { id: 'content', label: 'Content', accent: '--cat-data' }, + { id: 'tooling', label: 'Tooling', accent: '--cat-tooling' }, +]; + +const GH = 'https://github.com/bedrock-core'; + +export const sections: Section[] = [ + // Framework + { + id: 'server', + label: 'server', + pkg: '@bedrock-core/server', + category: 'framework', + status: 'pre-1.0', + description: 'Registry, RPC, shared state and config across addon realms.', + icon: 'server', + repo: `${GH}/server`, + }, + { + id: 'sync', + label: 'sync', + pkg: '@bedrock-core/sync', + category: 'framework', + status: 'pre-1.0', + description: 'The script-event transport: bus, discovery, RPC, replicated state.', + icon: 'radio', + repo: `${GH}/server`, + }, + { + id: 'db', + label: 'db', + pkg: '@bedrock-core/db', + category: 'framework', + status: 'planned', + description: 'Persisted documents on dynamic properties.', + icon: 'database', + repo: `${GH}/server`, + }, + { + id: 'observable', + label: 'observable', + pkg: '@bedrock-core/observable', + category: 'framework', + status: 'planned', + description: 'Reactive values: observable, computed, effect, batch.', + icon: 'activity', + repo: `${GH}/server`, + }, + + // UI + { + id: 'ui', + label: 'ui', + pkg: '@bedrock-core/ui', + category: 'ui', + status: 'pre-1.0', + description: 'JSX screens for server forms and containers, drawn by the render pack.', + icon: 'layout-panel-left', + repo: `${GH}/ui`, + }, + { + id: 'ore-styled', + label: 'ore-styled', + pkg: '@bedrock-core/ore-styled', + category: 'ui', + status: 'pre-1.0', + description: 'Themed components with vanilla Minecraft textures.', + icon: 'palette', + repo: `${GH}/ui`, + }, + { + id: 'navigation', + label: 'navigation', + pkg: '@bedrock-core/navigation', + category: 'ui', + status: 'pre-1.0', + description: 'Stack navigation between screens.', + icon: 'navigation', + repo: `${GH}/ui`, + }, + { + id: 'flexbox', + label: 'flexbox', + pkg: '@bedrock-core/flexbox', + category: 'ui', + status: '1.0', + description: 'The layout engine under every screen.', + icon: 'layout-grid', + repo: `${GH}/ui`, + }, + + // Content + { + id: 'config', + label: 'config', + pkg: '@bedrock-core/config', + category: 'content', + status: 'pre-1.0', + description: 'The shared addon list, settings screens and guide viewer.', + icon: 'sliders-horizontal', + repo: `${GH}/ui`, + }, + { + id: 'guides', + label: 'guides', + pkg: '@bedrock-core/guides', + category: 'content', + status: 'pre-1.0', + description: 'In-game guides authored in MDX.', + icon: 'book-open', + repo: `${GH}/ui`, + }, + { + id: 'i18n', + label: 'i18n', + pkg: '@bedrock-core/i18n', + category: 'content', + status: 'pre-1.0', + description: 'Typed keys, interpolation and plurals, resolved per player.', + icon: 'languages', + repo: `${GH}/ui`, + }, + + // Tooling + { + id: 'filters', + label: 'filters', + pkg: 'bedrock-core/regolith-filters', + category: 'tooling', + status: 'pre-1.0', + description: 'Regolith filters: manifest, generator, guides, i18n, ui-compile, bundler.', + icon: 'funnel', + repo: `${GH}/regolith-filters`, + }, + { + id: 'cli', + label: 'cli', + pkg: '@bedrock-core/cli', + category: 'tooling', + status: 'pre-1.0', + description: 'Scaffold an addon with the whole stack wired.', + icon: 'terminal', + repo: `${GH}/ui`, + }, + { + id: 'bds-runner', + label: 'bds-runner', + pkg: '@bedrock-core/bds-runner', + category: 'tooling', + status: 'pre-1.0', + description: 'Run GameTests headlessly on a Bedrock Dedicated Server.', + icon: 'flask-conical', + repo: `${GH}/bds-runner`, + }, +]; + +/** Sections that have pages today. */ +export const publishedSections = sections.filter((s) => s.status !== 'planned'); + +export function sectionsOf(category: CategoryId): Section[] { + return sections.filter((s) => s.category === category); +} From 68b367b9388585d8a5393b9f623b6697906def01 Mon Sep 17 00:00:00 2001 From: DrAv0011 Date: Tue, 8 Sep 2026 06:26:54 +0200 Subject: [PATCH 10/48] docs: home page, header and design-system components Hero, package grid, feature cards, code tour and footer built from the design kit; Docs mega-menu, Showcase link, icon links and DocSearch in the navbar; Badge, Tag, Kbd, Icon, Button, FeatureCard and PackageCard usable from any page; npm/yarn/pnpm install tabs; ore syntax palette for code. Co-Authored-By: Claude Fable 5.1 --- package.json | 1 + src/components/Home/Stats.tsx | 72 ++++++ src/components/Home/home.module.css | 110 +++++++++ src/components/Home/index.tsx | 225 ++++++++++++++++++ src/components/HomepageFeatures/index.tsx | 69 ------ .../HomepageFeatures/styles.module.css | 11 - src/components/PackageGrid/index.tsx | 40 ++++ src/components/PackageGrid/styles.module.css | 28 +++ src/components/PackageManager.tsx | 70 ++++++ src/components/ds/Icon.tsx | 45 ++++ src/components/ds/ds.module.css | 145 +++++++++++ src/components/ds/index.tsx | 154 ++++++++++++ src/components/nav/DocsMenu.tsx | 86 +++++++ src/components/nav/IconLink.tsx | 21 ++ src/components/nav/nav.module.css | 99 ++++++++ src/css/bedrock/infima-bridge.css | 105 +++++++- src/pages/index.module.css | 44 ---- src/pages/index.tsx | 53 +---- src/pages/showcase.tsx | 19 ++ src/prism/bedrock.ts | 30 +++ src/theme/Footer/index.tsx | 52 ++++ src/theme/Footer/styles.module.css | 34 +++ src/theme/MDXComponents.tsx | 15 ++ src/theme/NavbarItem/ComponentTypes.tsx | 11 + src/theme/prism-include-languages.ts | 24 ++ yarn.lock | 10 + 26 files changed, 1401 insertions(+), 172 deletions(-) create mode 100644 src/components/Home/Stats.tsx create mode 100644 src/components/Home/home.module.css create mode 100644 src/components/Home/index.tsx delete mode 100644 src/components/HomepageFeatures/index.tsx delete mode 100644 src/components/HomepageFeatures/styles.module.css create mode 100644 src/components/PackageGrid/index.tsx create mode 100644 src/components/PackageGrid/styles.module.css create mode 100644 src/components/PackageManager.tsx create mode 100644 src/components/ds/Icon.tsx create mode 100644 src/components/ds/ds.module.css create mode 100644 src/components/ds/index.tsx create mode 100644 src/components/nav/DocsMenu.tsx create mode 100644 src/components/nav/IconLink.tsx create mode 100644 src/components/nav/nav.module.css delete mode 100644 src/pages/index.module.css create mode 100644 src/pages/showcase.tsx create mode 100644 src/prism/bedrock.ts create mode 100644 src/theme/Footer/index.tsx create mode 100644 src/theme/Footer/styles.module.css create mode 100644 src/theme/MDXComponents.tsx create mode 100644 src/theme/NavbarItem/ComponentTypes.tsx create mode 100644 src/theme/prism-include-languages.ts diff --git a/package.json b/package.json index 25a7926..fd509b1 100644 --- a/package.json +++ b/package.json @@ -21,6 +21,7 @@ "@docusaurus/preset-classic": "3.10.1", "@mdx-js/react": "^3.1.1", "clsx": "^2.1.1", + "lucide-react": "^1.42.0", "prism-react-renderer": "^2.4.1", "react": "^19.2.6", "react-dom": "^19.2.6" diff --git a/src/components/Home/Stats.tsx b/src/components/Home/Stats.tsx new file mode 100644 index 0000000..241b223 --- /dev/null +++ b/src/components/Home/Stats.tsx @@ -0,0 +1,72 @@ +import { useEffect, useState, type ReactNode } from 'react'; +import { Badge } from '../ds'; + +const REPOS = ['server', 'ui', 'regolith-filters', 'bds-runner']; +const PACKAGES = [ + 'server', 'server-runtime', 'sync', 'ui', 'ui-runtime', 'ore-styled', 'navigation', + 'flexbox', 'i18n', 'guides', 'config', 'cli', +]; +const CACHE = 'bedrock-core:stats'; + +interface Stats { + stars?: number; + downloads?: number; +} + +function compact(n: number): string { + return n >= 1000 ? `${(n / 1000).toFixed(n >= 10000 ? 0 : 1)}k` : String(n); +} + +async function sum(urls: string[], pick: (json: Record) => number): Promise { + const results = await Promise.all( + urls.map(async (url) => { + const res = await fetch(url); + if (!res.ok) throw new Error(url); + return pick((await res.json()) as Record); + }), + ); + return results.reduce((a, b) => a + b, 0); +} + +/** Live counters under the wordmark: GitHub stars, npm downloads, package count. */ +export default function Stats(): ReactNode { + const [stats, setStats] = useState({}); + + useEffect(() => { + try { + const cached = sessionStorage.getItem(CACHE); + if (cached) { + setStats(JSON.parse(cached) as Stats); + return; + } + } catch { + /* storage unavailable */ + } + const next: Stats = {}; + void Promise.allSettled([ + sum(REPOS.map((r) => `https://api.github.com/repos/bedrock-core/${r}`), (j) => Number(j.stargazers_count ?? 0)).then((v) => { + next.stars = v; + }), + sum(PACKAGES.map((p) => `https://api.npmjs.org/downloads/point/last-month/@bedrock-core/${p}`), (j) => Number(j.downloads ?? 0)).then((v) => { + next.downloads = v; + }), + ]).then(() => { + setStats({ ...next }); + try { + sessionStorage.setItem(CACHE, JSON.stringify(next)); + } catch { + /* storage unavailable */ + } + }); + }, []); + + return ( + <> + pre-1.0 + MIT + {PACKAGES.length} packages + {stats.stars !== undefined ? ★ {compact(stats.stars)} stars : null} + {stats.downloads !== undefined ? {compact(stats.downloads)} downloads / month : null} + + ); +} diff --git a/src/components/Home/home.module.css b/src/components/Home/home.module.css new file mode 100644 index 0000000..d2a2073 --- /dev/null +++ b/src/components/Home/home.module.css @@ -0,0 +1,110 @@ +/* hero */ +.hero { + position: relative; + overflow: hidden; + background: + var(--gradient-hero), + linear-gradient(var(--grid-line) 1px, transparent 1px) 0 0 / 40px 40px, + linear-gradient(90deg, var(--grid-line) 1px, transparent 1px) 0 0 / 40px 40px, + var(--bg-canvas); + border-bottom: 1px solid var(--border-subtle); + padding: var(--space-20) var(--space-8) var(--space-16); +} +.heroInner { + max-width: 1080px; + margin: 0 auto; + display: flex; + flex-direction: column; + align-items: center; + text-align: center; + gap: var(--space-6); +} +.wordmark { width: min(520px, 78%); height: auto; image-rendering: pixelated; } +.badges { display: flex; flex-wrap: wrap; justify-content: center; gap: var(--space-2); } +.headline { + margin: 0; + max-width: 18ch; + font-size: var(--text-display-2); + line-height: var(--leading-tight); + letter-spacing: var(--tracking-display); + font-weight: var(--weight-bold); +} +.lede { + margin: 0; + max-width: 640px; + font-size: var(--text-body-lg); + line-height: var(--leading-relaxed); + color: var(--text-muted); +} +.lede code { color: var(--text-strong); border: 0; background: transparent; padding: 0; } +.actions { display: flex; gap: var(--space-3); flex-wrap: wrap; justify-content: center; } +.command { width: min(520px, 100%); text-align: left; } +.command > div { margin: 0; } + +/* shared section chrome */ +.wrap { max-width: 1120px; margin: 0 auto; padding: var(--space-16) var(--space-8); } +.eyebrow { + margin: 0 0 var(--space-3); + font-family: var(--font-display); + font-size: var(--text-micro); + letter-spacing: var(--tracking-eyebrow); + text-transform: uppercase; + color: var(--text-faint); +} +.title { margin: 0 0 var(--space-3); font-size: var(--text-h1); font-weight: var(--weight-bold); letter-spacing: var(--tracking-display); } +.sub { margin: 0; max-width: 640px; color: var(--text-muted); font-size: var(--text-body-lg); line-height: var(--leading-relaxed); } +.head { margin-bottom: var(--space-8); } + +/* features */ +.sunken { border-top: 1px solid var(--border-subtle); border-bottom: 1px solid var(--border-subtle); background: var(--bg-sunken); } +.features { display: grid; grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); gap: var(--space-4); } + +/* code tour */ +.tour { display: grid; grid-template-columns: minmax(280px, 380px) 1fr; gap: var(--space-12); align-items: start; } +.tabs { display: flex; gap: var(--space-5); border-bottom: 1px solid var(--border-subtle); margin-bottom: var(--space-4); } +.tab { + appearance: none; + background: none; + border: 0; + border-bottom: 2px solid transparent; + margin-bottom: -1px; + padding: 0 0 9px; + cursor: pointer; + color: var(--text-muted); + font-family: var(--font-sans); + font-size: var(--text-body-sm); + font-weight: var(--weight-semibold); + transition: var(--transition-control); +} +.tabOn { color: var(--text-strong); border-bottom-color: var(--accent-solid); } +.caption { margin: 0 0 var(--space-4); min-height: calc(2 * var(--text-body-sm) * var(--leading-relaxed)); color: var(--text-muted); font-size: var(--text-body-sm); line-height: var(--leading-relaxed); } +.panes { display: grid; } +.pane { grid-area: 1 / 1; } +.pane[hidden] { display: block !important; visibility: hidden; pointer-events: none; } +.pane > div { margin: 0; } +.stepButton { + appearance: none; + background: none; + border: 0; + padding: 0; + cursor: pointer; + color: inherit; + font: inherit; + text-align: left; + transition: var(--transition-control); +} +.stepButton:hover { color: var(--text-strong); } +.steps { margin: var(--space-4) 0 var(--space-6); padding: 0; list-style: none; display: grid; gap: var(--space-2); } +.step { display: flex; gap: var(--space-3); align-items: baseline; color: var(--text-muted); font-size: var(--text-body-sm); } +.stepNo { font-family: var(--font-mono); color: var(--text-faint); } +.stepOn { color: var(--text-strong); } +.stepOn .stepNo { color: var(--accent-solid); } +@media (max-width: 996px) { + .tour { grid-template-columns: 1fr; gap: var(--space-6); } + .hero { padding: var(--space-12) var(--space-5) var(--space-10); } +} + +/* cta */ +.cta { border-top: 1px solid var(--border-subtle); background: var(--gradient-hero), var(--bg-canvas); text-align: center; } +.ctaTitle { margin: 0 0 var(--space-4); font-size: var(--text-h1); font-weight: var(--weight-bold); letter-spacing: var(--tracking-display); } +.ctaSub { margin: 0 auto var(--space-6); max-width: 520px; color: var(--text-muted); font-size: var(--text-body-lg); } diff --git a/src/components/Home/index.tsx b/src/components/Home/index.tsx new file mode 100644 index 0000000..a3e8966 --- /dev/null +++ b/src/components/Home/index.tsx @@ -0,0 +1,225 @@ +import { useState, type ReactNode } from 'react'; +import clsx from 'clsx'; +import useBaseUrl from '@docusaurus/useBaseUrl'; +import CodeBlock from '@theme/CodeBlock'; +import { Button, FeatureCard } from '../ds'; +import Stats from './Stats'; +import styles from './home.module.css'; + +const DISCORD = 'https://bedrock-core.drav.dev/discord'; +const GITHUB = 'https://github.com/bedrock-core/'; + +export function Hero(): ReactNode { + const wordmark = useBaseUrl('img/logo/title.png'); + return ( +
+
+ @bedrock-core +
+ +
+

Addons Better Connected

+

+ Behavior packs run in isolated realms. @bedrock-core lets yours find each other, call each other, + share state, and draw custom UI the whole world can use. +

+
+ + + +
+
+ npx @bedrock-core/cli +
+
+
+ ); +} + +export function SectionHead({ eyebrow, title, sub }: { eyebrow: string; title: string; sub?: string }): ReactNode { + return ( +
+

{eyebrow}

+

{title}

+ {sub ?

{sub}

: null} +
+ ); +} + +const FEATURES = [ + { icon: 'radio', title: 'Runtime discovery', accent: '--cat-framework', body: 'Register once. Every other bedrock-core addon in the world sees you, and you see them, the moment they load.' }, + { icon: 'arrow-left-right', title: 'Typed RPC', accent: '--cat-framework', body: 'Request/response calls to another addon, typed from the interface the peer publishes.' }, + { icon: 'database', title: 'Shared state', accent: '--cat-framework', body: 'A declared shape every realm mirrors locally as a typed tree. Reads are synchronous, writes broadcast a delta.' }, + { icon: 'layout-panel-left', title: 'JSX screens', accent: '--cat-ui', body: 'React-like components for forms and containers. Screens compile ahead of time; only state moves at runtime.' }, + { icon: 'sliders-horizontal', title: 'Config, guides and translations', accent: '--cat-data', body: 'Declare a settings schema, ship an MDX guide and a typed translation bundle; the shared UI renders all three for every addon in the world.' }, + { icon: 'terminal', title: 'One build chain', accent: '--cat-tooling', body: 'Regolith filters compile guides, localization and screens, bundle the scripts, and run your GameTests on a real dedicated server.' }, +]; + +export function Features(): ReactNode { + return ( +
+
+ +
+ {FEATURES.map((f) => ( + + {f.body} + + ))} +
+
+
+ ); +} + +const TOUR = [ + { + id: 'register', + label: 'Register', + step: 'The economy addon declares itself', + caption: 'One call brings the addon online: it validates the manifest, joins the world and starts every subsystem. The config schema becomes typed accessors and an in-game settings screen.', + language: 'ts', + code: `import { core } from '@bedrock-core/server'; + +export interface EconomyRPC { + getBalance(params: { player: string }): number; +} + +const { config } = core.register({ + manifest: { creator: 'drav0011', pack: 'economy', packName: 'Economy', version: '1.0.0' }, + config: { + server: { + economy: { + startingBalance: { type: 'number', default: 100, min: 0, max: 10000, label: 'Starting Balance' }, + }, + }, + } as const, +}); + +core.rpc.serve({ + getBalance: ({ player }) => balances.get(player) ?? config.server.economy.startingBalance.get(), +});`, + }, + { + id: 'call', + label: 'Call', + step: 'The shop addon calls it, without importing it', + caption: 'The shop names economy as a dependency and waits for it to appear. The RPC client is typed from an interface the economy addon publishes; the two packs never share a module.', + language: 'ts', + code: `import { core } from '@bedrock-core/server'; + +core.register({ + manifest: { + creator: 'drav0011', pack: 'shop', packName: 'Shop', version: '1.0.0', + dependencies: ['drav0011_economy'], + }, +}); + +core.registry.onDependenciesSatisfied(async () => { + const economy = core.rpc.typed('drav0011_economy'); + const balance = await economy.getBalance({ player: 'Steve' }); + + console.warn(\`[shop] balance: \${balance}\`); +});`, + }, + { + id: 'screen', + label: 'Screen', + step: 'A screen shows the result', + caption: 'Screens are components. The runtime serializes the tree into a server form and the render pack draws it; ore-styled gives the vanilla look.', + language: 'tsx', + code: `import { render, Text } from '@bedrock-core/ui'; +import { Button, Card } from '@bedrock-core/ore-styled'; + +function Shop({ balance }: { balance: number }) { + return ( + + {\`Balance: \${balance}\`} + + + ); +} + +render(() => , player);`, + }, +]; + +export function CodeTour(): ReactNode { + const [active, setActive] = useState(TOUR[0].id); + const current = TOUR.find((t) => t.id === active) ?? TOUR[0]; + return ( +
+
+
+ +
    + {TOUR.map((t, i) => ( +
  1. + 0{i + 1} + +
  2. + ))} +
+ +
+
+
+ {TOUR.map((t) => ( + + ))} +
+

{current.caption}

+
+ {TOUR.map((t) => ( + + ))} +
+
+
+
+ ); +} + +export function Cta(): ReactNode { + return ( +
+
+

Start with one package.

+

Pin an exact version while the stack is pre-1.0, and read the release notes before you upgrade.

+
+ + +
+
+
+ ); +} diff --git a/src/components/HomepageFeatures/index.tsx b/src/components/HomepageFeatures/index.tsx deleted file mode 100644 index 66cf3b3..0000000 --- a/src/components/HomepageFeatures/index.tsx +++ /dev/null @@ -1,69 +0,0 @@ -import type { ReactNode } from 'react'; -import clsx from 'clsx'; -import Heading from '@theme/Heading'; -import styles from './styles.module.css'; - -type FeatureItem = { - title: string; - Svg: React.ComponentType>; - description: ReactNode; -}; - -const FeatureList: FeatureItem[] = [ - { - title: 'TypeScript First', - Svg: require('@site/static/img/ts-logo.svg').default, - description: ( - <> - Strong typings, IntelliSense, and maintainable addon development. - - ), - }, - { - title: 'Zero Dependencies', - Svg: require('@site/static/img/minecraft-logo.svg').default, - description: ( - <> - Designed to stay lightweight and dependency-free. - Full control without unnecessary overhead. - - ), - }, - { - title: 'Cross-addon compatibility', - Svg: require('@site/static/img/addons-logo.svg').default, - description: ( - <> - Addon cross compatibility as our core principle. - - ), - }, -]; - -function Feature({ title, Svg, description }: FeatureItem) { - return ( -
-
- -
-
- {title} -

{description}

-
-
- ); -} - -export default function HomepageFeatures(): ReactNode { - return ( -
-
-
- {FeatureList.map((props, idx) => ( - - ))} -
-
-
- ); -} diff --git a/src/components/HomepageFeatures/styles.module.css b/src/components/HomepageFeatures/styles.module.css deleted file mode 100644 index b248eb2..0000000 --- a/src/components/HomepageFeatures/styles.module.css +++ /dev/null @@ -1,11 +0,0 @@ -.features { - display: flex; - align-items: center; - padding: 2rem 0; - width: 100%; -} - -.featureSvg { - height: 200px; - width: 200px; -} diff --git a/src/components/PackageGrid/index.tsx b/src/components/PackageGrid/index.tsx new file mode 100644 index 0000000..780e1d7 --- /dev/null +++ b/src/components/PackageGrid/index.tsx @@ -0,0 +1,40 @@ +import type { ReactNode } from 'react'; +import { categories, sectionsOf } from '../../data/sections'; +import { PackageCard } from '../ds'; +import { SectionHead } from '../Home'; +import styles from './styles.module.css'; + +/** The home-page package grid: one column per category, one card per section. */ +export default function PackageGrid(): ReactNode { + return ( +
+
+ +
+ {categories.map((category) => ( +
+

+ {category.label} +

+ {sectionsOf(category.id).map((section) => ( + + ))} +
+ ))} +
+
+
+ ); +} diff --git a/src/components/PackageGrid/styles.module.css b/src/components/PackageGrid/styles.module.css new file mode 100644 index 0000000..1029eb1 --- /dev/null +++ b/src/components/PackageGrid/styles.module.css @@ -0,0 +1,28 @@ +.grid { + padding: var(--space-12) 0; + border-top: 1px solid var(--border-subtle); +} +.columns { + display: grid; + grid-template-columns: repeat(4, minmax(0, 1fr)); + gap: var(--space-4); +} +.column { + display: flex; + flex-direction: column; + gap: var(--space-3); +} +.eyebrow { + margin: 0 0 var(--space-1); + font-family: var(--font-mono); + font-size: var(--text-micro); + font-weight: var(--weight-medium); + letter-spacing: var(--tracking-eyebrow); + text-transform: uppercase; +} +@media (max-width: 996px) { + .columns { grid-template-columns: repeat(2, minmax(0, 1fr)); } +} +@media (max-width: 600px) { + .columns { grid-template-columns: 1fr; } +} diff --git a/src/components/PackageManager.tsx b/src/components/PackageManager.tsx new file mode 100644 index 0000000..3f46aea --- /dev/null +++ b/src/components/PackageManager.tsx @@ -0,0 +1,70 @@ +import type { ReactNode } from 'react'; +import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem'; +import CodeBlock from '@theme/CodeBlock'; + +// Package-manager tabs. `groupId` keeps every instance on the site in sync +// with the reader's choice. +const managers = [ + { id: 'npm', label: 'npm' }, + { id: 'yarn', label: 'yarn' }, + { id: 'pnpm', label: 'pnpm' }, +] as const; + +type Manager = (typeof managers)[number]['id']; + +function installLine(manager: Manager, pkgs: string, dev: boolean): string { + switch (manager) { + case 'npm': + return `npm install ${dev ? '--save-dev ' : ''}${pkgs}`; + case 'yarn': + return `yarn add ${dev ? '--dev ' : ''}${pkgs}`; + case 'pnpm': + return `pnpm add ${dev ? '--save-dev ' : ''}${pkgs}`; + } +} + +function execLine(manager: Manager, cmd: string): string { + switch (manager) { + case 'npm': + return `npx ${cmd}`; + case 'yarn': + return `yarn dlx ${cmd}`; + case 'pnpm': + return `pnpm dlx ${cmd}`; + } +} + +function ManagerTabs({ line }: { line: (manager: Manager) => string }): ReactNode { + return ( + + {managers.map((manager) => ( + + {line(manager.id)} + + ))} + + ); +} + +export interface InstallProps { + /** One package, or several separated by spaces. */ + pkg: string; + /** Install as a dev dependency. */ + dev?: boolean; +} + +/** `npm install` / `yarn add` / `pnpm add` for one or more packages. */ +export function Install({ pkg, dev = false }: InstallProps): ReactNode { + return installLine(manager, pkg, dev)} />; +} + +export interface ExecProps { + /** The package and arguments to run without installing, e.g. `@bedrock-core/cli`. */ + cmd: string; +} + +/** `npx` / `yarn dlx` / `pnpm dlx` for a one-off command. */ +export function Exec({ cmd }: ExecProps): ReactNode { + return execLine(manager, cmd)} />; +} diff --git a/src/components/ds/Icon.tsx b/src/components/ds/Icon.tsx new file mode 100644 index 0000000..13e945d --- /dev/null +++ b/src/components/ds/Icon.tsx @@ -0,0 +1,45 @@ +import type { CSSProperties, ReactNode } from 'react'; +import { icons } from 'lucide-react'; + +const sizes = { xs: 12, sm: 14, md: 16, lg: 20, xl: 24 } as const; + +export interface IconProps { + /** Lucide icon name in kebab-case, e.g. `terminal`, `arrow-right`. */ + name: string; + size?: keyof typeof sizes | number; + /** Any CSS colour. Defaults to `currentColor`. */ + color?: string; + strokeWidth?: number; + style?: CSSProperties; + className?: string; +} + +// Brand marks Lucide does not ship. Paths from Simple Icons (CC0), 24px grid. +const brands: Record = { + discord: + 'M20.317 4.3698a19.7913 19.7913 0 00-4.8851-1.5152.0741.0741 0 00-.0785.0371c-.211.3753-.4447.8648-.6083 1.2495-1.8447-.2762-3.68-.2762-5.4868 0-.1636-.3933-.4058-.8742-.6177-1.2495a.077.077 0 00-.0785-.037 19.7363 19.7363 0 00-4.8852 1.515.0699.0699 0 00-.0321.0277C.5334 9.0458-.319 13.5799.0992 18.0578a.0824.0824 0 00.0312.0561c2.0528 1.5076 4.0413 2.4228 5.9929 3.0294a.0777.0777 0 00.0842-.0276c.4616-.6304.8731-1.2952 1.226-1.9942a.076.076 0 00-.0416-.1057c-.6528-.2476-1.2743-.5495-1.8722-.8923a.077.077 0 01-.0076-.1277c.1258-.0943.2517-.1923.3718-.2914a.0743.0743 0 01.0776-.0105c3.9278 1.7933 8.18 1.7933 12.0614 0a.0739.0739 0 01.0785.0095c.1202.099.246.1981.3728.2924a.077.077 0 01-.0066.1276 12.2986 12.2986 0 01-1.873.8914.0766.0766 0 00-.0407.1067c.3604.698.7719 1.3628 1.225 1.9932a.076.076 0 00.0842.0286c1.961-.6067 3.9495-1.5219 6.0023-3.0294a.077.077 0 00.0313-.0552c.5004-5.177-.8382-9.6739-3.5485-13.6604a.061.061 0 00-.0312-.0286zM8.02 15.3312c-1.1825 0-2.1569-1.0857-2.1569-2.419 0-1.3332.9555-2.4189 2.157-2.4189 1.2108 0 2.1757 1.0952 2.1568 2.419 0 1.3332-.9555 2.4189-2.1569 2.4189zm7.9748 0c-1.1825 0-2.1569-1.0857-2.1569-2.419 0-1.3332.9554-2.4189 2.1569-2.4189 1.2108 0 2.1757 1.0952 2.1568 2.419 0 1.3332-.946 2.4189-2.1568 2.4189Z', + github: + 'M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12', +}; + +function pascal(name: string): string { + return name.replace(/(^|-)([a-z0-9])/g, (_match, _sep, c: string) => c.toUpperCase()); +} + +/** Every glyph on the site goes through here, so a future icon set is a one-file swap. */ +export function Icon({ name, size = 'md', color, strokeWidth = 2, style, className }: IconProps): ReactNode { + const px = typeof size === 'number' ? size : sizes[size]; + const brand = brands[name]; + if (brand) { + return ( + + + + ); + } + const Glyph = icons[pascal(name) as keyof typeof icons]; + if (!Glyph) return null; + return ( + + ); +} diff --git a/src/components/ds/ds.module.css b/src/components/ds/ds.module.css new file mode 100644 index 0000000..f087f9a --- /dev/null +++ b/src/components/ds/ds.module.css @@ -0,0 +1,145 @@ +/* Badge */ +.badge { + display: inline-flex; + align-items: center; + height: 20px; + padding: 0 7px; + border-radius: var(--radius-xs); + border: 1px solid var(--border-default); + background: var(--bg-hover); + color: var(--text-muted); + font-family: var(--font-mono); + font-size: var(--text-micro); + font-weight: var(--weight-medium); + letter-spacing: var(--tracking-label); + text-transform: uppercase; + white-space: nowrap; + vertical-align: middle; +} +.accent { color: var(--accent-solid); border-color: var(--accent-soft-border); background: var(--accent-soft); } +.info { color: var(--status-info); border-color: var(--status-info-soft); background: var(--status-info-soft); } +.success { color: var(--status-success); border-color: var(--status-success-soft); background: var(--status-success-soft); } +.warning { color: var(--status-warning); border-color: var(--status-warning-soft); background: var(--status-warning-soft); } +.danger { color: var(--status-danger); border-color: var(--status-danger-soft); background: var(--status-danger-soft); } + +/* Tag */ +.tag { + display: inline-flex; + align-items: center; + gap: 6px; + height: 24px; + padding: 0 10px; + border-radius: var(--radius-pill); + border: 1px solid var(--border-default); + background: var(--bg-surface); + color: var(--text-body); + font-family: var(--font-mono); + font-size: var(--text-caption); + white-space: nowrap; + vertical-align: middle; +} +.dot { width: 6px; height: 6px; border-radius: 50%; background: var(--accent-alt); flex: none; } + +/* Kbd */ +.kbd { + display: inline-flex; + align-items: center; + justify-content: center; + min-width: 22px; + height: 22px; + padding: 0 6px; + border-radius: var(--radius-xs); + border: 1px solid var(--border-default); + border-bottom-width: 2px; + background: var(--bg-surface); + color: var(--text-muted); + font-family: var(--font-mono); + font-size: var(--text-micro); + vertical-align: middle; +} + +/* PackageCard */ +.card { + position: relative; + display: flex; + flex-direction: column; + gap: var(--space-3); + padding: var(--space-5); + border-radius: var(--radius-md); + background: var(--bg-surface); + border: 1px solid var(--border-subtle); + color: inherit; + text-decoration: none; + overflow: hidden; + transition: var(--transition-control); +} +.card:hover { background: var(--bg-raised); border-color: var(--border-strong); color: inherit; text-decoration: none; } +.card:hover .rule { opacity: 1; } +.card:hover .arrow { transform: translateX(3px); } +.planned { opacity: 0.55; pointer-events: none; } +.rule { position: absolute; top: 0; left: 0; width: 100%; height: 2px; background: var(--card-accent); opacity: 0.7; } +.head { display: flex; align-items: center; gap: var(--space-3); } +.glyph { + display: inline-flex; + align-items: center; + justify-content: center; + width: 30px; + height: 30px; + border-radius: var(--radius-sm); + background: var(--bg-hover); + border: 1px solid var(--border-subtle); + color: var(--card-accent); + flex: none; +} +.name { font-family: var(--font-mono); font-size: var(--text-body-md); color: var(--text-strong); } +.scope { color: var(--text-faint); } +.spacer { flex: 1; } +.desc { margin: 0; color: var(--text-muted); font-size: var(--text-body-sm); line-height: var(--leading-relaxed); } +.cta { display: inline-flex; align-items: center; gap: 6px; color: var(--card-accent); font-size: var(--text-body-sm); font-weight: var(--weight-semibold); } +.arrow { display: inline-flex; transition: transform var(--duration-fast) var(--ease-standard); } + +/* Button */ +.button { + display: inline-flex; + align-items: center; + justify-content: center; + gap: var(--space-2); + border-radius: var(--radius-sm); + border: 1px solid transparent; + font-family: var(--font-sans); + font-weight: var(--weight-semibold); + letter-spacing: var(--tracking-label); + line-height: 1; + white-space: nowrap; + text-decoration: none; + cursor: pointer; + transition: var(--transition-control), transform var(--duration-instant) var(--ease-standard); +} +.button:hover { text-decoration: none; } +.button:active { transform: translateY(1px); } +.sm { height: 28px; padding: 0 10px; font-size: var(--text-body-sm); } +.md { height: 34px; padding: 0 14px; font-size: var(--text-body-md); } +.lg { height: 44px; padding: 0 20px; font-size: var(--text-body-lg); } +.primary { background: var(--accent-solid); color: var(--accent-on-solid); } +.primary:hover { background: var(--accent-solid-hover); color: var(--accent-on-solid); } +.primary:active { background: var(--accent-solid-active); } +.secondary { background: var(--bg-raised); color: var(--text-strong); border-color: var(--border-default); } +.secondary:hover { background: var(--bg-active); border-color: var(--border-strong); color: var(--text-strong); } +.ghost { background: transparent; color: var(--text-body); } +.ghost:hover { background: var(--bg-hover); color: var(--text-body); } +.ghost:active { background: var(--bg-active); } +.accentSoft { background: var(--accent-soft); color: var(--text-accent); border-color: var(--accent-soft-border); } +.accentSoft:hover { border-color: var(--border-accent); color: var(--text-accent); } + +/* FeatureCard */ +.feature { + display: flex; + flex-direction: column; + gap: var(--space-3); + padding: var(--space-5); + border-radius: var(--radius-md); + border: 1px solid var(--border-subtle); + background: var(--bg-surface); +} +.featureTitle { margin: 0; font-size: var(--text-h4); font-weight: var(--weight-bold); color: var(--text-strong); } +.featureBody { margin: 0; color: var(--text-muted); font-size: var(--text-body-sm); line-height: var(--leading-relaxed); } diff --git a/src/components/ds/index.tsx b/src/components/ds/index.tsx new file mode 100644 index 0000000..d010204 --- /dev/null +++ b/src/components/ds/index.tsx @@ -0,0 +1,154 @@ +import type { CSSProperties, ReactNode } from 'react'; +import clsx from 'clsx'; +import Link from '@docusaurus/Link'; +import { Icon } from './Icon'; +import styles from './ds.module.css'; + +export { Icon } from './Icon'; + +/** Mono status pill for release state and stability markers. */ +export interface BadgeProps { + children?: ReactNode; + tone?: 'neutral' | 'accent' | 'info' | 'success' | 'warning' | 'danger'; + style?: CSSProperties; +} +export function Badge({ children, tone = 'neutral', style }: BadgeProps): ReactNode { + return ( + + {children} + + ); +} + +/** Chip for package names and topics; the dot carries the package accent. */ +export interface TagProps { + children?: ReactNode; + /** Colour of the leading dot: a `--pkg-*` or `--cat-*` token, or any CSS colour. */ + accent?: string; + dot?: boolean; + style?: CSSProperties; +} +export function Tag({ children, accent, dot = false, style }: TagProps): ReactNode { + return ( + + {dot ? : null} + {children} + + ); +} + +/** Key cap for shortcut hints. */ +export function Kbd({ children }: { children?: ReactNode }): ReactNode { + return {children}; +} + +/** Tile for one package in the home grid or a docs index. */ +export interface PackageCardProps { + /** Package name after the scope, e.g. `server`. */ + name: string; + scope?: string; + description?: string; + /** Lucide icon name. */ + icon?: string; + /** Any CSS colour; carries the 2px top rule, the glyph and the call to action. */ + accent?: string; + /** Short release-state label, e.g. `pre-1.0`. `planned` dims the card and disables it. */ + status?: string; + href?: string; +} +export function PackageCard({ + name, + scope = '@bedrock-core/', + description, + icon = 'package', + accent = 'var(--cat-framework)', + status, + href = '#', +}: PackageCardProps): ReactNode { + const planned = status === 'planned'; + const tone = planned ? 'neutral' : status === '1.0' ? 'success' : 'warning'; + return ( + + +
+ + + + + {scope} + {name} + + + {status ? {status} : null} +
+ {description ?

{description}

: null} + {planned ? null : ( + + Read the docs + + + + + )} + + ); +} + +/** The standard action control: `primary` once per view, `secondary` for the paired action, `ghost` in dense toolbars. */ +export interface ButtonProps { + children?: ReactNode; + variant?: 'primary' | 'secondary' | 'ghost' | 'accentSoft'; + size?: 'sm' | 'md' | 'lg'; + /** Lucide icon name rendered before the label. */ + iconLeft?: string; + /** Lucide icon name rendered after the label. */ + iconRight?: string; + href?: string; + onClick?: () => void; + style?: CSSProperties; +} +export function Button({ children, variant = 'primary', size = 'md', iconLeft, iconRight, href, onClick, style }: ButtonProps): ReactNode { + const className = clsx(styles.button, styles[size], styles[variant]); + const iconSize = size === 'lg' ? 'lg' : 'sm'; + const body = ( + <> + {iconLeft ? : null} + {children} + {iconRight ? : null} + + ); + if (href) { + return ( + + {body} + + ); + } + return ( + + ); +} + +/** Feature block for the home page's "what you get" grid: icon, title, body. */ +export interface FeatureCardProps { + icon?: string; + title: string; + children?: ReactNode; + accent?: string; +} +export function FeatureCard({ icon = 'box', title, children, accent = 'var(--accent-solid)' }: FeatureCardProps): ReactNode { + return ( +
+ +

{title}

+

{children}

+
+ ); +} diff --git a/src/components/nav/DocsMenu.tsx b/src/components/nav/DocsMenu.tsx new file mode 100644 index 0000000..b38fbda --- /dev/null +++ b/src/components/nav/DocsMenu.tsx @@ -0,0 +1,86 @@ +import { useEffect, useRef, useState, type ReactNode } from 'react'; +import clsx from 'clsx'; +import Link from '@docusaurus/Link'; +import { useLocation } from '@docusaurus/router'; +import { categories, sectionsOf } from '../../data/sections'; +import { Badge, Icon } from '../ds'; +import styles from './nav.module.css'; + +/** Header mega-menu: one column per category, one row per section. */ +export default function DocsMenu({ label = 'Docs' }: { label?: string }): ReactNode { + const [open, setOpen] = useState(false); + const ref = useRef(null); + const { pathname } = useLocation(); + const activeId = pathname.startsWith('/docs/') ? pathname.split('/')[2] : undefined; + + useEffect(() => { + if (!open) return undefined; + const onDown = (ev: MouseEvent): void => { + if (ref.current && !ref.current.contains(ev.target as Node)) setOpen(false); + }; + const onKey = (ev: KeyboardEvent): void => { + if (ev.key === 'Escape') setOpen(false); + }; + document.addEventListener('mousedown', onDown); + document.addEventListener('keydown', onKey); + return () => { + document.removeEventListener('mousedown', onDown); + document.removeEventListener('keydown', onKey); + }; + }, [open]); + + useEffect(() => { + setOpen(false); + }, [pathname]); + + return ( +
+ + {open ? ( +
+ {categories.map((category) => ( +
+
+ + {category.label} +
+ {sectionsOf(category.id).map((section) => { + const planned = section.status === 'planned'; + return ( + + + {section.label} + {planned ? planned : null} + + {section.description} + + ); + })} +
+ ))} + + Browse all packages + + +
+ ) : null} +
+ ); +} diff --git a/src/components/nav/IconLink.tsx b/src/components/nav/IconLink.tsx new file mode 100644 index 0000000..4e083a0 --- /dev/null +++ b/src/components/nav/IconLink.tsx @@ -0,0 +1,21 @@ +import type { ReactNode } from 'react'; +import Link from '@docusaurus/Link'; +import { Icon } from '../ds'; +import styles from './nav.module.css'; + +export interface IconLinkProps { + href: string; + /** Lucide or brand icon name. */ + icon: string; + /** Accessible label, also the tooltip. */ + label: string; +} + +/** Icon-only navbar link for GitHub, Discord and the like. */ +export default function IconLink({ href, icon, label }: IconLinkProps): ReactNode { + return ( + + + + ); +} diff --git a/src/components/nav/nav.module.css b/src/components/nav/nav.module.css new file mode 100644 index 0000000..c51978d --- /dev/null +++ b/src/components/nav/nav.module.css @@ -0,0 +1,99 @@ +/* DocsMenu trigger */ +.menu { position: relative; } +.trigger { + appearance: none; + cursor: pointer; + height: 30px; + padding: 0 10px; + display: inline-flex; + align-items: center; + gap: 6px; + border-radius: var(--radius-sm); + border: 1px solid transparent; + background: transparent; + color: var(--ifm-navbar-link-color); + font-family: var(--font-sans); + font-size: var(--text-body-sm); + font-weight: var(--weight-semibold); + transition: var(--transition-control); +} +.trigger:hover, .open { color: var(--text-strong); } +.open { background: var(--bg-hover); border-color: var(--border-default); } +.chevron { display: inline-flex; transition: transform var(--duration-fast) var(--ease-standard); } +.open .chevron { transform: rotate(180deg); } + +/* panel */ +.panel { + position: absolute; + top: calc(100% + 10px); + left: -12px; + z-index: 60; + display: grid; + grid-template-columns: repeat(4, minmax(180px, 1fr)); + gap: var(--space-6); + padding: var(--space-5); + background: var(--bg-raised); + border: 1px solid var(--border-default); + border-radius: var(--radius-lg); + box-shadow: var(--shadow-lg); +} +.col { display: grid; gap: 2px; align-content: start; } +.colHead { display: flex; align-items: center; gap: 7px; padding: 0 8px var(--space-2); } +.dot { width: 7px; height: 7px; border-radius: 2px; } +.colLabel { + font-family: var(--font-display); + font-size: var(--text-micro); + letter-spacing: var(--tracking-eyebrow); + text-transform: uppercase; + color: var(--text-faint); +} +.row { + display: grid; + gap: 1px; + padding: 7px 8px; + border-radius: var(--radius-sm); + text-decoration: none; + color: inherit; + transition: var(--transition-control); +} +.row:hover { background: var(--bg-hover); text-decoration: none; color: inherit; } +.rowActive { background: var(--bg-selected, var(--accent-soft)); } +.rowPlanned { opacity: 0.45; pointer-events: none; } +.rowTitle { display: flex; align-items: center; gap: 7px; } +.rowName { font-family: var(--font-mono); font-size: var(--text-body-sm); color: var(--text-strong); } +.rowActive .rowName { color: var(--text-accent); } +.rowDesc { font-size: var(--text-micro); color: var(--text-faint); line-height: 1.45; } +.all { + grid-column: 1 / -1; + display: inline-flex; + align-items: center; + justify-content: center; + gap: 6px; + margin-top: var(--space-2); + padding-top: var(--space-4); + border-top: 1px solid var(--border-subtle); + font-family: var(--font-mono); + font-size: var(--text-caption); + letter-spacing: var(--tracking-label); + text-transform: uppercase; + color: var(--text-muted); + text-decoration: none; +} +.all:hover { color: var(--text-strong); text-decoration: none; } + +@media (max-width: 996px) { + .panel { position: static; grid-template-columns: 1fr; box-shadow: none; border: 0; background: transparent; padding: var(--space-2) 0; } +} + +/* icon links */ +.iconLink { + display: inline-flex; + align-items: center; + justify-content: center; + width: 32px; + height: 32px; + border-radius: var(--radius-sm); + color: var(--ifm-navbar-link-color); + transition: var(--transition-control); +} +.iconLink:hover { color: var(--text-strong); background: var(--bg-hover); } diff --git a/src/css/bedrock/infima-bridge.css b/src/css/bedrock/infima-bridge.css index fb6c209..d7efbb8 100644 --- a/src/css/bedrock/infima-bridge.css +++ b/src/css/bedrock/infima-bridge.css @@ -210,6 +210,29 @@ div[class^='codeBlockTitle'] { font-size: var(--text-caption); border-bottom: 1px solid var(--border-subtle); } +/* language badge, top right, uppercase mono like the kit's CodeBlock title bar */ +.theme-code-block { position: relative; } +.theme-code-block::after { + position: absolute; + top: 6px; + right: 8px; + font-family: var(--font-mono); + font-size: var(--text-micro); + letter-spacing: var(--tracking-eyebrow); + text-transform: uppercase; + color: var(--text-faint); + pointer-events: none; +} +.theme-code-block.language-ts::after { content: 'ts'; } +.theme-code-block.language-tsx::after { content: 'tsx'; } +.theme-code-block.language-js::after { content: 'js'; } +.theme-code-block.language-json::after { content: 'json'; } +.theme-code-block.language-jsonc::after { content: 'jsonc'; } +.theme-code-block.language-bash::after { content: 'bash'; } +.theme-code-block.language-yaml::after { content: 'yaml'; } +.theme-code-block.language-mdx::after { content: 'mdx'; } +.theme-code-block:has(div[class^='codeBlockTitle'])::after { top: 8px; } +.theme-code-block:hover::after { opacity: 0; } :not(pre) > code { border: 1px solid var(--border-subtle); } /* cards, tables, prev/next: flat, bordered, no shadow */ @@ -239,6 +262,19 @@ table th { font-weight: var(--weight-semibold); } table td, table th { border: 0; border-bottom: 1px solid var(--border-subtle); } +/* tables: identifiers in mono without inline-code chrome; the first column is the name */ +table td { vertical-align: top; } +table td code { + background: transparent; + border: 0; + padding: 0; + font-size: var(--text-caption); + color: var(--text-body); +} +table td:first-child code { color: var(--accent-alt); font-weight: var(--weight-semibold); } +table td a code { color: var(--ifm-link-color); font-weight: var(--weight-semibold); } +table td a:hover code { color: var(--ifm-link-hover-color); text-decoration: underline; } +table td:first-child { white-space: nowrap; } /* buttons never bounce; they nudge 1px */ .button { font-weight: var(--weight-semibold); letter-spacing: var(--tracking-label); transition: var(--transition-control); } @@ -247,9 +283,72 @@ table td, table th { border: 0; border-bottom: 1px solid var(--border-subtle); } /* focus ring */ :focus-visible { outline: 2px solid var(--focus-ring); outline-offset: 2px; } -/* footer */ -.footer { border-top: 1px solid var(--border-subtle); } -.footer__copyright { font-size: var(--text-caption); color: var(--text-faint); } +/* navbar right cluster: room before the theme toggle; DocSearch button as the kit's SearchInput */ +.navbar__items--right { gap: var(--space-2); } +.navbar__items--right > * { margin: 0; } +.DocSearch-Button { + height: 32px; + width: 220px; + margin: 0; + padding: 0 8px 0 10px; + border-radius: var(--radius-sm); + background: var(--bg-surface); + border: 1px solid var(--border-default); + color: var(--text-faint); + font-family: var(--font-sans); + font-size: var(--text-body-sm); + box-shadow: none; + transition: var(--transition-control); +} +.DocSearch-Button:hover, .DocSearch-Button:focus-visible { + background: var(--bg-surface); + border-color: var(--border-accent); + box-shadow: var(--shadow-focus); + color: var(--text-faint); +} +.DocSearch-Button .DocSearch-Search-Icon { width: 14px; height: 14px; color: var(--text-faint); } +.DocSearch-Button-Placeholder { flex: 1; text-align: left; padding: 0 0 0 var(--space-2); font-size: var(--text-body-sm); } +.DocSearch-Button-Keys { min-width: 0; gap: 3px; } +.DocSearch-Button-Key { + width: auto; + min-width: 22px; + height: 22px; + padding: 0 6px; + margin: 0; + top: 0; + border-radius: var(--radius-xs); + border: 1px solid var(--border-default); + border-bottom-width: 2px; + background: var(--bg-surface); + box-shadow: none; + color: var(--text-muted); + font-family: var(--font-mono); + font-size: var(--text-micro); +} +@media (max-width: 996px) { .DocSearch-Button { width: 32px; padding: 0; justify-content: center; } .DocSearch-Button-Placeholder, .DocSearch-Button-Keys { display: none; } } +/* DocSearch modal on the same tokens */ +.DocSearch { + --docsearch-primary-color: var(--accent-solid); + --docsearch-text-color: var(--text-body); + --docsearch-muted-color: var(--text-muted); + --docsearch-container-background: var(--overlay-scrim); + --docsearch-modal-background: var(--bg-raised); + --docsearch-modal-shadow: var(--shadow-lg); + --docsearch-searchbox-background: var(--bg-surface); + --docsearch-searchbox-focus-background: var(--bg-surface); + --docsearch-searchbox-shadow: 0 0 0 1px var(--border-accent); + --docsearch-hit-color: var(--text-body); + --docsearch-hit-background: var(--bg-surface); + --docsearch-hit-active-color: var(--accent-on-solid); + --docsearch-hit-shadow: none; + --docsearch-key-gradient: var(--bg-surface); + --docsearch-key-shadow: 0 0 0 1px var(--border-default); + --docsearch-footer-background: var(--bg-sunken); + --docsearch-footer-shadow: 0 -1px 0 var(--border-subtle); + --docsearch-logo-color: var(--text-faint); +} +.DocSearch-Modal { border: 1px solid var(--border-default); border-radius: var(--radius-lg); } +.DocSearch-Hit a { border-radius: var(--radius-sm); } /* respect reduced motion */ @media (prefers-reduced-motion: reduce) { diff --git a/src/pages/index.module.css b/src/pages/index.module.css deleted file mode 100644 index 720fddf..0000000 --- a/src/pages/index.module.css +++ /dev/null @@ -1,44 +0,0 @@ -/** - * CSS files with the .module.css suffix will be treated as CSS modules - * and scoped locally. - */ - -.heroBanner { - padding: 4rem 0; - text-align: center; - position: relative; - overflow: hidden; -} - -@media screen and (max-width: 996px) { - .heroBanner { - padding: 2rem; - } -} - -.heroTitle { - margin-bottom: 1rem; -} - -.heroLogo { - display: block; - margin: 0 auto; - max-width: min(560px, 80%); - height: auto; - image-rendering: pixelated; -} - -.startUsing { - margin-bottom: 0.75rem; - font-size: 1.25rem; - font-weight: 700; -} - -.buttons { - display: flex; - align-items: center; - justify-content: center; - /* Wrap rather than overflow once the two package names stop fitting side by side. */ - flex-wrap: wrap; - gap: 1rem; -} \ No newline at end of file diff --git a/src/pages/index.tsx b/src/pages/index.tsx index 528e75b..53b770c 100644 --- a/src/pages/index.tsx +++ b/src/pages/index.tsx @@ -1,57 +1,20 @@ import type { ReactNode } from 'react'; -import clsx from 'clsx'; -import Link from '@docusaurus/Link'; -import useBaseUrl from '@docusaurus/useBaseUrl'; import useDocusaurusContext from '@docusaurus/useDocusaurusContext'; import Layout from '@theme/Layout'; -import HomepageFeatures from '@site/src/components/HomepageFeatures'; -import Heading from '@theme/Heading'; - -import styles from './index.module.css'; - -function HomepageHeader() { - const { siteConfig } = useDocusaurusContext(); - const logoSrc = useBaseUrl('img/logo/title.png'); - - return ( -
-
- - {siteConfig.title} - - -

{siteConfig.tagline}

-

Developing a future where addons interact between them

- -

Start using @bedrock-core/

- -
- - server - - - ui - -
-
-
- ); -} +import PackageGrid from '@site/src/components/PackageGrid'; +import { CodeTour, Cta, Features, Hero } from '@site/src/components/Home'; export default function Home(): ReactNode { const { siteConfig } = useDocusaurusContext(); return ( - - + +
- + + + +
); diff --git a/src/pages/showcase.tsx b/src/pages/showcase.tsx new file mode 100644 index 0000000..f79028f --- /dev/null +++ b/src/pages/showcase.tsx @@ -0,0 +1,19 @@ +import type { ReactNode } from 'react'; +import Layout from '@theme/Layout'; +import { Button } from '@site/src/components/ds'; + +export default function Showcase(): ReactNode { + return ( + +
+

Showcase

+

+ Addons built with @bedrock-core. Ship one and tell us on Discord to be listed here. +

+ +
+
+ ); +} diff --git a/src/prism/bedrock.ts b/src/prism/bedrock.ts new file mode 100644 index 0000000..2ef8203 --- /dev/null +++ b/src/prism/bedrock.ts @@ -0,0 +1,30 @@ +import type { PrismTheme } from 'prism-react-renderer'; + +// Syntax palette on the ore accents (colors.css). Code blocks are dark in both +// site themes, so one palette serves both. +const stone = { text: '#d3d3d8', muted: '#8b8b93', faint: '#6a6a72', bright: '#e9e9ec' }; +const ore = { + emerald: '#7ce2a8', + gold: '#ffd88a', + goldDeep: '#f2a83b', + amethyst: '#c6a6f2', + lapis: '#6f97ef', + redstone: '#f79ea1', +}; + +export const bedrockPrism: PrismTheme = { + plain: { color: stone.text, backgroundColor: '#0e0e10' }, + styles: [ + { types: ['comment', 'prolog', 'doctype', 'cdata'], style: { color: stone.faint, fontStyle: 'italic' } }, + { types: ['punctuation'], style: { color: stone.muted } }, + { types: ['operator', 'entity', 'url'], style: { color: stone.bright } }, + { types: ['keyword', 'atrule', 'important', 'rule'], style: { color: ore.amethyst } }, + { types: ['string', 'char', 'inserted', 'attr-value', 'template-string'], style: { color: ore.emerald } }, + { types: ['number', 'boolean', 'constant', 'symbol', 'regex'], style: { color: ore.gold } }, + { types: ['function', 'class-name', 'builtin', 'tag', 'maybe-class-name'], style: { color: ore.lapis } }, + { types: ['property', 'attr-name', 'selector', 'variable'], style: { color: ore.goldDeep } }, + { types: ['deleted'], style: { color: ore.redstone } }, + { types: ['bold'], style: { fontWeight: 'bold' } }, + { types: ['italic'], style: { fontStyle: 'italic' } }, + ], +}; diff --git a/src/theme/Footer/index.tsx b/src/theme/Footer/index.tsx new file mode 100644 index 0000000..9634980 --- /dev/null +++ b/src/theme/Footer/index.tsx @@ -0,0 +1,52 @@ +import type { ReactNode } from 'react'; +import Link from '@docusaurus/Link'; +import useBaseUrl from '@docusaurus/useBaseUrl'; +import { categories, publishedSections, sectionsOf } from '../../data/sections'; +import styles from './styles.module.css'; + +const community = [ + { label: 'GitHub', href: 'https://github.com/bedrock-core/' }, + { label: 'Discord', href: 'https://bedrock-core.drav.dev/discord' }, + { label: 'npm', href: 'https://www.npmjs.com/org/bedrock-core' }, +]; + +// Site footer: wordmark and tagline on the left, one column per category on +// the right, copyright on a hairline. Columns come from src/data/sections.ts. +export default function Footer(): ReactNode { + const wordmark = useBaseUrl('img/logo/title.png'); + const live = new Set(publishedSections.map((s) => s.id)); + return ( +
+
+
+ + @bedrock-core + +

Addons Better Connected

+
+ + {categories.map((category) => ( +
+
{category.label}
+ {sectionsOf(category.id) + .filter((section) => live.has(section.id)) + .map((section) => ( + + {section.label} + + ))} +
+ ))} +
+
Community
+ {community.map((item) => ( + + {item.label} + + ))} +
+
+
Copyright © {new Date().getFullYear()} @bedrock-core. Built with Docusaurus.
+
+ ); +} diff --git a/src/theme/Footer/styles.module.css b/src/theme/Footer/styles.module.css new file mode 100644 index 0000000..2c8780a --- /dev/null +++ b/src/theme/Footer/styles.module.css @@ -0,0 +1,34 @@ +.footer { + border-top: 1px solid var(--border-subtle); + background: var(--bg-sunken); + padding: var(--space-12) var(--space-8) var(--space-8); +} +.inner { max-width: 1120px; margin: 0 auto; display: flex; flex-wrap: wrap; gap: var(--space-12); } +.brand { min-width: 200px; max-width: 260px; } +.wordmark { height: 22px; width: auto; image-rendering: pixelated; opacity: 0.85; } +.tagline { margin: var(--space-4) 0 0; color: var(--text-faint); font-size: var(--text-body-sm); line-height: var(--leading-relaxed); } +.spacer { flex: 1; } +.col { display: grid; gap: var(--space-2); align-content: start; } +.title { + font-family: var(--font-display); + font-size: var(--text-micro); + letter-spacing: var(--tracking-eyebrow); + text-transform: uppercase; + color: var(--text-faint); + margin-bottom: 4px; +} +.link { color: var(--text-muted); font-size: var(--text-body-sm); text-decoration: none; font-family: var(--font-mono); transition: var(--transition-control); } +.link:hover { color: var(--text-strong); text-decoration: none; } +.sans { font-family: var(--font-sans); } +.bottom { + max-width: 1120px; + margin: var(--space-10) auto 0; + padding-top: var(--space-5); + border-top: 1px solid var(--border-subtle); + color: var(--text-faint); + font-size: var(--text-caption); +} +@media (max-width: 768px) { + .inner { gap: var(--space-8); } + .spacer { display: none; } +} diff --git a/src/theme/MDXComponents.tsx b/src/theme/MDXComponents.tsx new file mode 100644 index 0000000..d53e928 --- /dev/null +++ b/src/theme/MDXComponents.tsx @@ -0,0 +1,15 @@ +import MDXComponents from '@theme-original/MDXComponents'; +import { Exec, Install } from '../components/PackageManager'; +import { Badge, Icon, Kbd, PackageCard, Tag } from '../components/ds'; + +// Components every docs page can use without importing them. +export default { + ...MDXComponents, + Install, + Exec, + Badge, + Tag, + Kbd, + Icon, + PackageCard, +}; diff --git a/src/theme/NavbarItem/ComponentTypes.tsx b/src/theme/NavbarItem/ComponentTypes.tsx new file mode 100644 index 0000000..1d78d26 --- /dev/null +++ b/src/theme/NavbarItem/ComponentTypes.tsx @@ -0,0 +1,11 @@ +import ComponentTypes from '@theme-original/NavbarItem/ComponentTypes'; +import DocsMenu from '../../components/nav/DocsMenu'; +import IconLink from '../../components/nav/IconLink'; + +// Extra navbar item types: `custom-docsMenu` (the package mega-menu) and +// `custom-iconLink` (icon-only external links). +export default { + ...ComponentTypes, + 'custom-docsMenu': DocsMenu, + 'custom-iconLink': IconLink, +}; diff --git a/src/theme/prism-include-languages.ts b/src/theme/prism-include-languages.ts new file mode 100644 index 0000000..ca4d867 --- /dev/null +++ b/src/theme/prism-include-languages.ts @@ -0,0 +1,24 @@ +import siteConfig from '@generated/docusaurus.config'; +import type * as PrismNamespace from 'prismjs'; + +// Loads the extra Prism grammars named in themeConfig.prism.additionalLanguages +// and aliases `jsonc` (JSON with comments, used for Regolith and tsconfig +// snippets) to the json5 grammar, which tokenizes comments. +export default function prismIncludeLanguages(PrismObject: typeof PrismNamespace): void { + const { + themeConfig: { prism }, + } = siteConfig; + const { additionalLanguages } = prism as { additionalLanguages: string[] }; + + const PrismBefore = (globalThis as { Prism?: unknown }).Prism; + (globalThis as { Prism?: unknown }).Prism = PrismObject; + additionalLanguages.forEach((lang) => { + // eslint-disable-next-line @typescript-eslint/no-require-imports + require(`prismjs/components/prism-${lang}`); + }); + PrismObject.languages.jsonc = PrismObject.languages.json5; + delete (globalThis as { Prism?: unknown }).Prism; + if (typeof PrismBefore !== 'undefined') { + (globalThis as { Prism?: unknown }).Prism = PrismObject; + } +} diff --git a/yarn.lock b/yarn.lock index 88bb27d..9febc10 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1503,6 +1503,7 @@ __metadata: "@mdx-js/react": "npm:^3.1.1" clsx: "npm:^2.1.1" docusaurus-plugin-llms: "npm:^0.4.0" + lucide-react: "npm:^1.42.0" prism-react-renderer: "npm:^2.4.1" react: "npm:^19.2.6" react-dom: "npm:^19.2.6" @@ -8567,6 +8568,15 @@ __metadata: languageName: node linkType: hard +"lucide-react@npm:^1.42.0": + version: 1.42.0 + resolution: "lucide-react@npm:1.42.0" + peerDependencies: + react: ^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0 + checksum: 10c0/3d6ed3416e85937fc15fda2af926a3505bb0205038fdadf48beb43b4c6546a85f8d24fda3a4431acd78cdc1028075a8c75b86fbe495d40b46a8e812f245922d5 + languageName: node + linkType: hard + "make-fetch-happen@npm:^14.0.3": version: 14.0.3 resolution: "make-fetch-happen@npm:14.0.3" From c40b794467330162b1772f0627c1bed6804b5a53 Mon Sep 17 00:00:00 2001 From: DrAv0011 Date: Tue, 8 Sep 2026 07:54:43 +0200 Subject: [PATCH 11/48] docs: mark required props with an asterisk Props tables carry after the name instead of "(required)" in the name cell or in the default column. Co-Authored-By: Claude Opus 5 (1M context) --- STYLE.md | 2 +- docs/navigation/createStackNavigator.md | 2 +- docs/ore-styled/Dropdown.md | 2 +- docs/ore-styled/Form/FormButton.md | 2 +- docs/ore-styled/Form/FormCheckbox.md | 2 +- docs/ore-styled/Form/FormDropdown.md | 4 ++-- docs/ore-styled/Form/FormInput.md | 2 +- docs/ore-styled/Form/FormRadio.md | 4 ++-- docs/ore-styled/Form/FormSlider.md | 6 +++--- docs/ore-styled/Form/FormToggle.md | 2 +- docs/ore-styled/Form/FormToggleButton.md | 4 ++-- docs/ore-styled/Radio.md | 4 ++-- docs/ore-styled/Slider.md | 4 ++-- docs/ore-styled/ToggleButton.md | 6 +++--- docs/ui/components/Background.md | 2 +- docs/ui/components/Container.md | 2 +- docs/ui/components/Form/FormButton.md | 2 +- docs/ui/components/Form/FormDropdown.md | 2 +- docs/ui/components/Form/FormInlineSelect.md | 2 +- docs/ui/components/Form/FormInput.md | 2 +- docs/ui/components/Form/FormOption.md | 4 ++-- docs/ui/components/Form/FormSlider.md | 4 ++-- docs/ui/components/Form/FormToggle.md | 2 +- docs/ui/components/SlotGrid.md | 6 +++--- docs/ui/components/deprecated/Dropdown.md | 2 +- docs/ui/components/deprecated/Slider.md | 4 ++-- 26 files changed, 40 insertions(+), 40 deletions(-) diff --git a/STYLE.md b/STYLE.md index 8a89fe0..a4a8c51 100644 --- a/STYLE.md +++ b/STYLE.md @@ -99,7 +99,7 @@ Reference pages end when the content ends: no `Next steps`, no `Best practices`. | Export index | `\| Export \| Kind \| Description \|` | | Section index | `\| Page \| Description \|` | -Cell rules: types in backticks, `\|` inside unions; Default is `—` when none and `— (**required**)` when required; descriptions are one sentence with no trailing period; a compound component gets one table per part under `### RadioGroup`, `### Radio`. +Cell rules: types in backticks, `\|` inside unions; Default is `—` when none; a required prop carries `` after its name (a red asterisk) and `—` as its default; descriptions are one sentence with no trailing period; a compound component gets one table per part under `### RadioGroup`, `### Radio`. ## Voice and typography diff --git a/docs/navigation/createStackNavigator.md b/docs/navigation/createStackNavigator.md index 5e9b1d9..c6fe206 100644 --- a/docs/navigation/createStackNavigator.md +++ b/docs/navigation/createStackNavigator.md @@ -48,7 +48,7 @@ TypeScript uses this map to: | Option | Type | Default | Description | | --- | --- | --- | --- | -| `screens` | `ScreensMap` | — (**required**) | Maps each route name to a screen component, optionally with `initialParams` | +| `screens` | `ScreensMap` | — | Maps each route name to a screen component, optionally with `initialParams` | | `initialRouteName` | `keyof TRoutes` | first key in `screens` | The route shown first when the navigator mounts | ### `screens` diff --git a/docs/ore-styled/Dropdown.md b/docs/ore-styled/Dropdown.md index dd9b1f7..8fe4c94 100644 --- a/docs/ore-styled/Dropdown.md +++ b/docs/ore-styled/Dropdown.md @@ -37,7 +37,7 @@ Built on top of the [`Dropdown`](/docs/ui/components/deprecated/Dropdown) primit | Prop | Type | Default | Description | | --- | --- | --- | --- | -| `options` (required) | `string[]` | — | The selectable options. The face shows the current one; the modal lists them all | +| `options` | `string[]` | — | The selectable options. The face shows the current one; the modal lists them all | | `value` | `string` | — | Controlled selection — should match one of `options`. When provided, the face reflects it on every render and `onChange` is your only way to update it | | `defaultValue` | `string` | the first option | Initial selection when running uncontrolled | | `onChange` | `(value: string, index: number) => void` | — | Called with the chosen option and its index in `options` when the player confirms the modal | diff --git a/docs/ore-styled/Form/FormButton.md b/docs/ore-styled/Form/FormButton.md index 5eea090..faf750f 100644 --- a/docs/ore-styled/Form/FormButton.md +++ b/docs/ore-styled/Form/FormButton.md @@ -31,7 +31,7 @@ Wraps the runtime [`Form.Button`](/docs/ui/components/Form/FormButton) primitive | Prop | Type | Default | Description | | --- | --- | --- | --- | -| `type` (required) | `'submit' \| 'exit'` | — | `'submit'` presses the native submit; `'exit'` closes the form like Esc. A form must declare exactly one submit button and at most one exit button — see [`Form`'s Rules & Restrictions](./Form.md#rules) | +| `type` | `'submit' \| 'exit'` | — | `'submit'` presses the native submit; `'exit'` closes the form like Esc. A form must declare exactly one submit button and at most one exit button — see [`Form`'s Rules & Restrictions](./Form.md#rules) | | `variant` | `ButtonVariant` (`'hero' \| 'primary' \| 'secondary' \| 'contrast' \| 'danger' \| 'realm' \| 'transparent'`) | `'primary'` for `type="submit"`, `'secondary'` for `type="exit"` | Visual style, same variant set as the ore-styled [`Button`](../Button.md) | | `label` | `string` | `'Submit'` for `type="submit"`, `'Close'` for `type="exit"` | Button text | | `enabled` | `boolean` | `true` | Whether the button is interactive | diff --git a/docs/ore-styled/Form/FormCheckbox.md b/docs/ore-styled/Form/FormCheckbox.md index f01e1fe..14cecc8 100644 --- a/docs/ore-styled/Form/FormCheckbox.md +++ b/docs/ore-styled/Form/FormCheckbox.md @@ -32,7 +32,7 @@ Wraps the runtime [`Form.Toggle`](/docs/ui/components/Form/FormToggle) primitive | Prop | Type | Default | Description | | --- | --- | --- | --- | -| `name` (required) | `string` | — | Result key — the value appears at `values[name]` in the form's `onSubmit` | +| `name` | `string` | — | Result key — the value appears at `values[name]` in the form's `onSubmit` | | `defaultValue` | `boolean` | `false` | Initial checked state | | `label` | `string` | — | Caption rendered to the right of the box. Omit for a bare box | | `enabled` | `boolean` | `true` | Whether the control is interactive. When `false`, renders the disabled face and the caption in the theme's disabled color | diff --git a/docs/ore-styled/Form/FormDropdown.md b/docs/ore-styled/Form/FormDropdown.md index 666adce..62c9c4a 100644 --- a/docs/ore-styled/Form/FormDropdown.md +++ b/docs/ore-styled/Form/FormDropdown.md @@ -38,8 +38,8 @@ Wraps the runtime [`Form.Dropdown`](/docs/ui/components/Form/FormDropdown) primi | Prop | Type | Default | Description | | --- | --- | --- | --- | -| `name` (required) | `string` | — | Result key — the selected index appears at `values[name]` in the form's `onSubmit` | -| `options` (required) | `string[]` | — | The selectable options. The closed box shows the current one; the popup lists them all | +| `name` | `string` | — | Result key — the selected index appears at `values[name]` in the form's `onSubmit` | +| `options` | `string[]` | — | The selectable options. The closed box shows the current one; the popup lists them all | | `defaultValue` | `string` | the first option | Initial selection | | `label` | `string` | — | Caption rendered above the closed box | | `enabled` | `boolean` | `true` | Whether the field is interactive. When `false`, renders the disabled face and a dimmed chevron | diff --git a/docs/ore-styled/Form/FormInput.md b/docs/ore-styled/Form/FormInput.md index ab4e762..6bea77f 100644 --- a/docs/ore-styled/Form/FormInput.md +++ b/docs/ore-styled/Form/FormInput.md @@ -28,7 +28,7 @@ Wraps the runtime [`Form.Input`](/docs/ui/components/Form/FormInput) primitive w | Prop | Type | Default | Description | | --- | --- | --- | --- | -| `name` (required) | `string` | — | Result key — the value appears at `values[name]` in the form's `onSubmit` | +| `name` | `string` | — | Result key — the value appears at `values[name]` in the form's `onSubmit` | | `placeholder` | `string` | — | Text shown inside the field when empty | | `defaultValue` | `string` | `''` | Initial text | | `label` | `string` | — | Caption rendered above the field | diff --git a/docs/ore-styled/Form/FormRadio.md b/docs/ore-styled/Form/FormRadio.md index d0c7dfa..ceb2cb0 100644 --- a/docs/ore-styled/Form/FormRadio.md +++ b/docs/ore-styled/Form/FormRadio.md @@ -41,8 +41,8 @@ import { Form } from '@bedrock-core/ore-styled'; | Prop | Type | Default | Description | | --- | --- | --- | --- | -| `name` (required) | `string` | — | Result key — the selected index appears at `values[name]` in the form's `onSubmit` | -| `options` (required) | `{ value: string; label: string }[]` | — | The options, top to bottom | +| `name` | `string` | — | Result key — the selected index appears at `values[name]` in the form's `onSubmit` | +| `options` | `{ value: string; label: string }[]` | — | The options, top to bottom | | `defaultValue` | `string` | the first option | Initial selected value, matched to its index | | `enabled` | `boolean` | `true` | Whether the group is interactive | | `label` | `string` | — | Caption rendered above the group | diff --git a/docs/ore-styled/Form/FormSlider.md b/docs/ore-styled/Form/FormSlider.md index 885e3ca..2639278 100644 --- a/docs/ore-styled/Form/FormSlider.md +++ b/docs/ore-styled/Form/FormSlider.md @@ -28,9 +28,9 @@ Wraps the runtime [`Form.Slider`](/docs/ui/components/Form/FormSlider) primitive | Prop | Type | Default | Description | | --- | --- | --- | --- | -| `name` (required) | `string` | — | Result key — the value appears at `values[name]` in the form's `onSubmit` | -| `min` (required) | `number` | — | Minimum selectable value | -| `max` (required) | `number` | — | Maximum selectable value | +| `name` | `string` | — | Result key — the value appears at `values[name]` in the form's `onSubmit` | +| `min` | `number` | — | Minimum selectable value | +| `max` | `number` | — | Maximum selectable value | | `step` | `number` | `1` | Increment between selectable values | | `defaultValue` | `number` | `min` | Initial value | | `label` | `string` | — | Caption rendered above the slider | diff --git a/docs/ore-styled/Form/FormToggle.md b/docs/ore-styled/Form/FormToggle.md index daa1acd..16e41ce 100644 --- a/docs/ore-styled/Form/FormToggle.md +++ b/docs/ore-styled/Form/FormToggle.md @@ -30,7 +30,7 @@ Wraps the runtime [`Form.Toggle`](/docs/ui/components/Form/FormToggle) primitive | Prop | Type | Default | Description | | --- | --- | --- | --- | -| `name` (required) | `string` | — | Result key — the value appears at `values[name]` in the form's `onSubmit` | +| `name` | `string` | — | Result key — the value appears at `values[name]` in the form's `onSubmit` | | `defaultValue` | `boolean` | `false` | Initial on/off state | | `label` | `string` | — | Caption rendered to the left of the switch. Omit for a bare switch with no row | | `enabled` | `boolean` | `true` | Whether the control is interactive. When `false`, renders the disabled face and the caption in the theme's disabled color | diff --git a/docs/ore-styled/Form/FormToggleButton.md b/docs/ore-styled/Form/FormToggleButton.md index db820ea..ac33b7f 100644 --- a/docs/ore-styled/Form/FormToggleButton.md +++ b/docs/ore-styled/Form/FormToggleButton.md @@ -41,8 +41,8 @@ Like [`Form.Radio`](./FormRadio.md), `Form.ToggleButton` is a single composed co | Prop | Type | Default | Description | | --- | --- | --- | --- | -| `name` (required) | `string` | — | Result key — the selected index appears at `values[name]` in the form's `onSubmit` | -| `options` (required) | `{ value: string; label: string }[]` | — | The segments, left to right | +| `name` | `string` | — | Result key — the selected index appears at `values[name]` in the form's `onSubmit` | +| `options` | `{ value: string; label: string }[]` | — | The segments, left to right | | `defaultValue` | `string` | the first option | Initial selected value, matched to its index | | `enabled` | `boolean` | `true` | Whether the group is interactive | | `label` | `string` | — | Caption rendered above the group | diff --git a/docs/ore-styled/Radio.md b/docs/ore-styled/Radio.md index fa4c6ee..b183cd9 100644 --- a/docs/ore-styled/Radio.md +++ b/docs/ore-styled/Radio.md @@ -35,13 +35,13 @@ import { RadioGroup, Radio } from '@bedrock-core/ore-styled'; | `defaultValue` | `string` | `''` | Initial selected value when running uncontrolled | | `onChange` | `(value: string) => void` | — | Called whenever the player selects a different `Radio` | | `disabled` | `boolean` | `false` | Disables every `Radio` inside the group. Individual `Radio`s can still set their own `disabled={true}` regardless | -| `children` | `JSX.Node` | — (**required**) | One or more `Radio` items | +| `children` | `JSX.Node` | — | One or more `Radio` items | ### `Radio` | Prop | Type | Default | Description | | --- | --- | --- | --- | -| `value` | `string` | — (**required**) | Identifier matched against the group's selected value | +| `value` | `string` | — | Identifier matched against the group's selected value | | `label` | `string` | — | Text rendered next to the radio. Omit for an unlabeled bullet | | `disabled` | `boolean` | — | Disables this `Radio` only. Falls back to the group's `disabled` when unset | diff --git a/docs/ore-styled/Slider.md b/docs/ore-styled/Slider.md index 8488573..fd6be7e 100644 --- a/docs/ore-styled/Slider.md +++ b/docs/ore-styled/Slider.md @@ -38,8 +38,8 @@ Built on top of the [`Slider`](/docs/ui/components/deprecated/Slider) primitive | Prop | Type | Default | Description | | --- | --- | --- | --- | -| `min` (required) | `number` | — | Minimum selectable value; the left end of the track | -| `max` (required) | `number` | — | Maximum selectable value; the right end of the track | +| `min` | `number` | — | Minimum selectable value; the left end of the track | +| `max` | `number` | — | Maximum selectable value; the right end of the track | | `step` | `number` | `1` | Increment between selectable values in the modal | | `value` | `number` | — | Controlled value. When provided, the thumb reflects it on every render and `onChange` is your only way to update it | | `defaultValue` | `number` | `min` | Initial value when running uncontrolled | diff --git a/docs/ore-styled/ToggleButton.md b/docs/ore-styled/ToggleButton.md index a791e9f..284c305 100644 --- a/docs/ore-styled/ToggleButton.md +++ b/docs/ore-styled/ToggleButton.md @@ -36,15 +36,15 @@ The group lays its items out in a row with their edges flush, reading as a singl | `defaultValue` | `string` | `''` | Initial selected value when running uncontrolled | | `onChange` | `(value: string) => void` | — | Called whenever the player picks a different item | | `disabled` | `boolean` | `false` | Disables every item in the group. Individual items can still set their own `disabled={true}` regardless | -| `children` | `JSX.Node` | — (**required**) | One or more `ToggleButtonItem` children | +| `children` | `JSX.Node` | — | One or more `ToggleButtonItem` children | ### `ToggleButtonItem` | Prop | Type | Default | Description | | --- | --- | --- | --- | -| `value` | `string` | — (**required**) | Identifier matched against the group's selected value | +| `value` | `string` | — | Identifier matched against the group's selected value | | `disabled` | `boolean` | — | Disables this item only. Falls back to the group's `disabled` when unset | -| `children` | `JSX.Node` | — (**required**) | Item content. A string is auto-wrapped in a themed `Text` whose color reflects the selected/unselected/disabled state | +| `children` | `JSX.Node` | — | Item content. A string is auto-wrapped in a themed `Text` whose color reflects the selected/unselected/disabled state | ### Control props diff --git a/docs/ui/components/Background.md b/docs/ui/components/Background.md index f2c20e5..b4723d2 100644 --- a/docs/ui/components/Background.md +++ b/docs/ui/components/Background.md @@ -35,7 +35,7 @@ If a tree contains more than one ``, only the first is rendered; the | Prop | Type | Default | Description | | --- | --- | --- | --- | -| `texture` | `string` | — (**required**) | Resource-pack texture path drawn as the full-screen backdrop, e.g. `'textures/ui/my_background'` | +| `texture` | `string` | — | Resource-pack texture path drawn as the full-screen backdrop, e.g. `'textures/ui/my_background'` | - Constraints: The path must fit within 80 UTF-8 bytes and may not contain a `;` character. ## Examples diff --git a/docs/ui/components/Container.md b/docs/ui/components/Container.md index 170329c..51ff361 100644 --- a/docs/ui/components/Container.md +++ b/docs/ui/components/Container.md @@ -35,7 +35,7 @@ Its presence decides the backend, the way [`
`](./Form/Form.md) makes a scr | Prop | Type | Default | Description | | --- | --- | --- | --- | -| `entity` | `string` | — (**required**) | Type of the entity the screen opens from, e.g. `'core:furnace'`. The build sizes that entity's `minecraft:inventory` and stamps it with the screen's layout key; the runtime serves the screen when a player interacts with it. The entity must exist in the behavior pack, or the build fails | +| `entity` | `string` | — | Type of the entity the screen opens from, e.g. `'core:furnace'`. The build sizes that entity's `minecraft:inventory` and stamps it with the screen's layout key; the runtime serves the screen when a player interacts with it. The entity must exist in the behavior pack, or the build fails | | `onOpen` | `(event: ContainerEvent) => void` | `undefined` | Ran when a player opens the screen, and again for every further viewer. `event.player` is who opened it and `event.host` the entity it opened. One layout serves everyone looking, so this is where a screen learns who is there — keep what it needs in state | | `onClose` | `(event: ContainerEvent) => void` | `undefined` | Ran when a player closes the screen, or leaves the world with it open. `event.player` is who left, `event.host` the entity it belonged to | | `children` | `JSX.Node` | — | The screen. Anything a form can hold except the [form-only components](../guides/container-screens.md#not-supported), plus [`Slot`](./Slot.md), [`PlayerInventory`](./PlayerInventory.md) and [`Hotbar`](./Hotbar.md) | diff --git a/docs/ui/components/Form/FormButton.md b/docs/ui/components/Form/FormButton.md index c4f4b69..54ff852 100644 --- a/docs/ui/components/Form/FormButton.md +++ b/docs/ui/components/Form/FormButton.md @@ -33,7 +33,7 @@ A `Form` enforces the cardinality of these buttons at build time (see [`Form`'s | Prop | Type | Default | Description | | --- | --- | --- | --- | -| `type` (required) | `'submit' \| 'exit'` | — | `'submit'` presses the native submit — field values return via the form's `onSubmit`. `'exit'` closes the form like Esc — no values, the form's `onCancel` fires instead | +| `type` | `'submit' \| 'exit'` | — | `'submit'` presses the native submit — field values return via the form's `onSubmit`. `'exit'` closes the form like Esc — no values, the form's `onCancel` fires instead | | `label` | `string` | `'Submit'` for `type="submit"`, `'Close'` for `type="exit"` | Button text | ### Control props diff --git a/docs/ui/components/Form/FormDropdown.md b/docs/ui/components/Form/FormDropdown.md index aa9e13e..42c84fa 100644 --- a/docs/ui/components/Form/FormDropdown.md +++ b/docs/ui/components/Form/FormDropdown.md @@ -35,7 +35,7 @@ import { Form } from '@bedrock-core/ui'; | Prop | Type | Default | Description | | --- | --- | --- | --- | -| `name` (required) | `string` | — | Result key — the selected index appears at `values[name]` in the form's `onSubmit` | +| `name` | `string` | — | Result key — the selected index appears at `values[name]` in the form's `onSubmit` | | `defaultValue` | `string` | the first option | Initial selection, matched against a [`Form.Option`](./FormOption.md)'s `value` | | `children` | `JSX.Node` | — | The selectable options, authored as [`Form.Option`](./FormOption.md) elements. Popup rows flow at a fixed row height, so an option's own layout props are ignored here — only its `value`/`label`/style are read | | `popupBackground` | `string` | the unstyled placeholder texture | Background texture for the popup surface behind the option list | diff --git a/docs/ui/components/Form/FormInlineSelect.md b/docs/ui/components/Form/FormInlineSelect.md index 0ab7c50..518c45a 100644 --- a/docs/ui/components/Form/FormInlineSelect.md +++ b/docs/ui/components/Form/FormInlineSelect.md @@ -34,7 +34,7 @@ Just like [`Form.Dropdown`](./FormDropdown.md), `Form.InlineSelect` reports the | Prop | Type | Default | Description | | --- | --- | --- | --- | -| `name` (required) | `string` | — | Result key — the selected index appears at `values[name]` in the form's `onSubmit` | +| `name` | `string` | — | Result key — the selected index appears at `values[name]` in the form's `onSubmit` | | `defaultValue` | `string` | the first option | Initial selection, matched against a [`Form.Option`](./FormOption.md)'s `value` | | `children` | `JSX.Node` | — | The selectable options, authored as [`Form.Option`](./FormOption.md) elements. Unlike `Form.Dropdown`'s popup rows, each option here is laid out by the normal flex engine — position it with ordinary layout props (`flex`, `gap`, `width`, …) | | `optionBackground` / `optionHover` / `optionSelected` | `string` | — | Group-level default row textures for idle/hover/selected states. Any `Form.Option` can override its own | diff --git a/docs/ui/components/Form/FormInput.md b/docs/ui/components/Form/FormInput.md index 9e5b7a6..91e2fd9 100644 --- a/docs/ui/components/Form/FormInput.md +++ b/docs/ui/components/Form/FormInput.md @@ -31,7 +31,7 @@ import { Form } from '@bedrock-core/ui'; | Prop | Type | Default | Description | | --- | --- | --- | --- | -| `name` (required) | `string` | — | Result key — the value appears at `values[name]` in the form's `onSubmit` | +| `name` | `string` | — | Result key — the value appears at `values[name]` in the form's `onSubmit` | | `placeholder` | `string` | — | Text shown inside the native field when empty | | `defaultValue` | `string` | `''` | Initial text | | `font` | `LabelFont` | `'mojangles'` | Font family for the typed value and placeholder | diff --git a/docs/ui/components/Form/FormOption.md b/docs/ui/components/Form/FormOption.md index 65df012..52903d1 100644 --- a/docs/ui/components/Form/FormOption.md +++ b/docs/ui/components/Form/FormOption.md @@ -32,8 +32,8 @@ import { Form } from '@bedrock-core/ui'; | Prop | Type | Default | Description | | --- | --- | --- | --- | -| `value` (required) | `string` | — | The option's stable identifier — what a parent's `defaultValue` is matched against. The parent reports the SELECTED option's index on submit, not this value | -| `label` (required) | `string` | — | Option text rendered in the row | +| `value` | `string` | — | The option's stable identifier — what a parent's `defaultValue` is matched against. The parent reports the SELECTED option's index on submit, not this value | +| `label` | `string` | — | Option text rendered in the row | | `font` / `scale` / `align` | `LabelFont` / `number` / `'left' \| 'center' \| 'right'` | falls back to the parent's `optionFont` / `optionScale` / `optionAlign` | Per-option label style override | | `background` / `backgroundHover` / `backgroundSelected` | `string` | falls back to the parent's `optionBackground` / `optionHover` / `optionSelected` | Per-option row background override | | `bullet` / `bulletSelected` / `bulletHover` / `bulletSelectedHover` | `string` | falls back to the parent's matching group prop | Per-option bullet glyph override (only meaningful under `Form.InlineSelect`) | diff --git a/docs/ui/components/Form/FormSlider.md b/docs/ui/components/Form/FormSlider.md index 2eacf3a..3191d83 100644 --- a/docs/ui/components/Form/FormSlider.md +++ b/docs/ui/components/Form/FormSlider.md @@ -31,8 +31,8 @@ import { Form } from '@bedrock-core/ui'; | Prop | Type | Default | Description | | --- | --- | --- | --- | -| `min` (required) | `number` | — | Minimum selectable value | -| `max` (required) | `number` | — | Maximum selectable value | +| `min` | `number` | — | Minimum selectable value | +| `max` | `number` | — | Maximum selectable value | | `step` | `number` | `1` (native default) | Increment between selectable values | | `defaultValue` | `number` | `min` | Initial value | | `progress` | `string` | the resolved track base texture | Progress-fill texture, drawn to the left of the thumb | diff --git a/docs/ui/components/Form/FormToggle.md b/docs/ui/components/Form/FormToggle.md index 299277d..520651e 100644 --- a/docs/ui/components/Form/FormToggle.md +++ b/docs/ui/components/Form/FormToggle.md @@ -31,7 +31,7 @@ import { Form } from '@bedrock-core/ui'; | Prop | Type | Default | Description | | --- | --- | --- | --- | -| `name` (required) | `string` | — | Result key — the value appears at `values[name]` in the form's `onSubmit` | +| `name` | `string` | — | Result key — the value appears at `values[name]` in the form's `onSubmit` | | `defaultValue` | `boolean` | `false` | Initial on/off state | | `checkedBackground` | `string` | the resolved unchecked base texture | Checked (on) base texture | | `checkedHover` | `string` | the resolved checked base texture | Checked hover texture | diff --git a/docs/ui/components/SlotGrid.md b/docs/ui/components/SlotGrid.md index 4b8b245..b5bcef1 100644 --- a/docs/ui/components/SlotGrid.md +++ b/docs/ui/components/SlotGrid.md @@ -29,9 +29,9 @@ Its size is fixed by the cell: `columns × rows` cells of 18 texels each. Lay it | Prop | Type | Default | Description | | --- | --- | --- | --- | -| `collection` (required) | `string` | — | The JSON UI collection every cell reads, e.g. `inventory_items`, `hotbar_items`, or a custom one | -| `columns` (required) | `number` | — | Columns of cells. At least one | -| `rows` (required) | `number` | — | Rows of cells. At least one | +| `collection` | `string` | — | The JSON UI collection every cell reads, e.g. `inventory_items`, `hotbar_items`, or a custom one | +| `columns` | `number` | — | Columns of cells. At least one | +| `rows` | `number` | — | Rows of cells. At least one | | `interactive` | `boolean` | `true` | Whether the player can move items through the cells. `false` makes the grid inert — no take, no place, no drop | A container slot's take and place are one combined engine action, so there is no take-only or place-only grid; interactivity is all-or-nothing, and `false` is the way to make a grid purely a display. diff --git a/docs/ui/components/deprecated/Dropdown.md b/docs/ui/components/deprecated/Dropdown.md index f1f64c9..3cd0d6a 100644 --- a/docs/ui/components/deprecated/Dropdown.md +++ b/docs/ui/components/deprecated/Dropdown.md @@ -39,7 +39,7 @@ The native modal works on item *indices*; `Dropdown` maps the selected index bac | Prop | Type | Default | Description | | --- | --- | --- | --- | -| `options` (required) | `string[]` | — | The selectable options. The face shows the current one; the modal lists them all | +| `options` | `string[]` | — | The selectable options. The face shows the current one; the modal lists them all | | `value` | `string` | — | Controlled selection — should match one of `options`. When provided, the face reflects it on every render and `onChange` is your only way to update it | | `defaultValue` | `string` | the first option | Initial selection when running uncontrolled | | `onChange` | `(value: string, index: number) => void` | — | Called with the chosen option and its index in `options` when the player confirms the modal | diff --git a/docs/ui/components/deprecated/Slider.md b/docs/ui/components/deprecated/Slider.md index c4b0ef7..247d519 100644 --- a/docs/ui/components/deprecated/Slider.md +++ b/docs/ui/components/deprecated/Slider.md @@ -38,8 +38,8 @@ import { Slider } from '@bedrock-core/ui'; | Prop | Type | Default | Description | | --- | --- | --- | --- | -| `min` (required) | `number` | — | Minimum selectable value | -| `max` (required) | `number` | — | Maximum selectable value | +| `min` | `number` | — | Minimum selectable value | +| `max` | `number` | — | Maximum selectable value | | `step` | `number` | `1` | Increment between selectable values | | `value` | `number` | — | Controlled value. When provided, the face reflects it on every render and `onChange` is your only way to update it | | `defaultValue` | `number` | `min` | Initial value when running uncontrolled | From a07bfd79c0feca28982ea841a559b2ba36677987 Mon Sep 17 00:00:00 2001 From: DrAv0011 Date: Tue, 8 Sep 2026 07:54:53 +0200 Subject: [PATCH 12/48] feat(site): rework the header, footer and mobile navigation Header collapses in steps: full layout down to 996px, the right cluster becomes icons at 768px, the left links at 600px. Docs and Showcase share one shape, GitHub, Discord and the theme switch share one icon box, and the theme toggle is rebuilt on the site's own icon set. Docs pages get a drawer trigger that opens the section's page tree with the section switcher on top; below 600px the drawer also carries the social links and the theme switch. Footer lays out in three columns, then two with the wordmark centered. Release states are named beta, 1.0-rc and 1.0. Co-Authored-By: Claude Opus 5 (1M context) --- docusaurus.config.ts | 44 +++++++-- src/components/Home/Stats.tsx | 52 ++++++---- src/components/Home/home.module.css | 10 +- src/components/Home/index.tsx | 25 ++++- src/components/PackageGrid/index.tsx | 1 + src/components/ds/ds.module.css | 2 + src/components/ds/index.tsx | 17 +++- src/components/nav/DocsMenu.tsx | 43 ++++++++- src/components/nav/IconLink.tsx | 19 +++- src/components/nav/IconNav.tsx | 37 +++++++ src/components/nav/SectionSwitcher.tsx | 82 ++++++++++++++++ src/components/nav/nav.module.css | 46 ++++++++- src/components/nav/switcher.module.css | 55 +++++++++++ src/css/bedrock/colors.css | 6 +- src/css/bedrock/infima-bridge.css | 96 +++++++++++++++---- src/data/sections.ts | 25 ++--- src/prism/bedrock.ts | 2 +- src/theme/ColorModeToggle/index.tsx | 48 ++++++++++ src/theme/ColorModeToggle/styles.module.css | 23 +++++ .../DocSidebar/Desktop/Content/index.tsx | 17 ++++ src/theme/DocSidebar/Mobile/index.tsx | 34 +++++++ src/theme/Footer/index.tsx | 2 +- src/theme/Footer/styles.module.css | 26 ++++- src/theme/MDXComponents.tsx | 3 +- .../Navbar/MobileSidebar/Header/index.tsx | 35 +++++++ .../MobileSidebar/Header/styles.module.css | 28 ++++++ .../Navbar/MobileSidebar/Layout/index.tsx | 17 ++++ .../Navbar/MobileSidebar/Toggle/index.tsx | 20 ++++ src/theme/NavbarItem/ComponentTypes.tsx | 2 + 29 files changed, 731 insertions(+), 86 deletions(-) create mode 100644 src/components/nav/IconNav.tsx create mode 100644 src/components/nav/SectionSwitcher.tsx create mode 100644 src/components/nav/switcher.module.css create mode 100644 src/theme/ColorModeToggle/index.tsx create mode 100644 src/theme/ColorModeToggle/styles.module.css create mode 100644 src/theme/DocSidebar/Desktop/Content/index.tsx create mode 100644 src/theme/DocSidebar/Mobile/index.tsx create mode 100644 src/theme/Navbar/MobileSidebar/Header/index.tsx create mode 100644 src/theme/Navbar/MobileSidebar/Header/styles.module.css create mode 100644 src/theme/Navbar/MobileSidebar/Layout/index.tsx create mode 100644 src/theme/Navbar/MobileSidebar/Toggle/index.tsx diff --git a/docusaurus.config.ts b/docusaurus.config.ts index f322e36..f59f7f2 100644 --- a/docusaurus.config.ts +++ b/docusaurus.config.ts @@ -1,6 +1,6 @@ import type { Config } from '@docusaurus/types'; import type * as Preset from '@docusaurus/preset-classic'; -import { existsSync } from 'node:fs'; +import { existsSync, readFileSync } from 'node:fs'; import { categories, publishedSections, sectionsOf } from './src/data/sections'; import { redirects } from './src/data/redirects'; import { bedrockPrism } from './src/prism/bedrock'; @@ -10,6 +10,35 @@ import { bedrockPrism } from './src/prism/bedrock'; const liveSections = publishedSections.filter((section) => existsSync(`docs/${section.id}`)); const isLive = (id: string): boolean => liveSections.some((section) => section.id === id); +// Search credentials come from the environment; a local .env fills them in for +// development. Without them the algolia block is omitted, the search theme is +// never loaded and the search box disappears instead of rendering inert. +function envFile(): Record { + if (!existsSync('.env')) return {}; + return Object.fromEntries( + readFileSync('.env', 'utf8') + .split(/\r?\n/) + .map((line) => line.trim()) + .filter((line) => line && !line.startsWith('#')) + .map((line) => { + const at = line.indexOf('='); + return [line.slice(0, at).trim(), line.slice(at + 1).trim().replace(/^["']|["']$/g, '')]; + }) + .filter(([key]) => key), + ); +} + +const env = { ...envFile(), ...process.env } as Record; +const algolia = + env.ALGOLIA_APP_ID && env.ALGOLIA_SEARCH_API_KEY && env.ALGOLIA_INDEX_NAME + ? { + appId: env.ALGOLIA_APP_ID, + apiKey: env.ALGOLIA_SEARCH_API_KEY, + indexName: env.ALGOLIA_INDEX_NAME, + contextualSearch: false, + } + : undefined; + // This runs in Node.js - Don't use client-side code here (browser APIs, JSX...) const config: Config = { @@ -102,20 +131,15 @@ const config: Config = { }, items: [ { type: 'custom-docsMenu', position: 'left', label: 'Docs' }, - { to: '/showcase', label: 'Showcase', position: 'left' }, + { type: 'custom-iconNav', position: 'left', to: '/showcase', icon: 'blocks', label: 'Showcase' }, { type: 'search', position: 'right' }, { type: 'custom-iconLink', position: 'right', href: 'https://bedrock-core.drav.dev/discord', icon: 'discord', label: 'Discord' }, { type: 'custom-iconLink', position: 'right', href: 'https://github.com/bedrock-core/', icon: 'github', label: 'GitHub' }, ], }, - // DocSearch: apply at https://docsearch.algolia.com/apply/ and paste the - // credentials here; the search box stays inert until they are real. - algolia: { - appId: 'BEDROCKCORE', - apiKey: 'replace-with-the-docsearch-search-only-key', - indexName: 'bedrock-core', - contextualSearch: false, - }, + // DocSearch: apply at https://docsearch.algolia.com/apply/, then set the + // three ALGOLIA_ variables. See .env.example. + ...(algolia ? { algolia } : {}), // Code blocks stay dark in both themes; one palette serves both. prism: { theme: bedrockPrism, diff --git a/src/components/Home/Stats.tsx b/src/components/Home/Stats.tsx index 241b223..c255de0 100644 --- a/src/components/Home/Stats.tsx +++ b/src/components/Home/Stats.tsx @@ -1,12 +1,13 @@ import { useEffect, useState, type ReactNode } from 'react'; import { Badge } from '../ds'; -const REPOS = ['server', 'ui', 'regolith-filters', 'bds-runner']; +const ORG = 'bedrock-core'; const PACKAGES = [ 'server', 'server-runtime', 'sync', 'ui', 'ui-runtime', 'ore-styled', 'navigation', 'flexbox', 'i18n', 'guides', 'config', 'cli', ]; -const CACHE = 'bedrock-core:stats'; +const FIRST_PUBLISH = '2025-01-01'; +const CACHE = 'bedrock-core:stats:v2'; interface Stats { stars?: number; @@ -17,18 +18,38 @@ function compact(n: number): string { return n >= 1000 ? `${(n / 1000).toFixed(n >= 10000 ? 0 : 1)}k` : String(n); } -async function sum(urls: string[], pick: (json: Record) => number): Promise { - const results = await Promise.all( - urls.map(async (url) => { - const res = await fetch(url); - if (!res.ok) throw new Error(url); - return pick((await res.json()) as Record); - }), +async function json(url: string): Promise> { + const res = await fetch(url); + if (!res.ok) throw new Error(url); + return (await res.json()) as Record; +} + +/** Stars across every repository of the organization. */ +async function orgStars(): Promise { + const repos = (await json(`https://api.github.com/orgs/${ORG}/repos?per_page=100&type=public`)) as unknown as Array<{ stargazers_count: number }>; + return repos.reduce((sum, r) => sum + (r.stargazers_count ?? 0), 0); +} + +/** All-time downloads across the published packages; npm ranges are capped at 18 months, so sum consecutive windows. */ +async function totalDownloads(): Promise { + const windows: string[] = []; + let start = new Date(FIRST_PUBLISH); + const today = new Date(); + while (start < today) { + const end = new Date(start); + end.setMonth(end.getMonth() + 17); + const last = end < today ? end : today; + windows.push(`${start.toISOString().slice(0, 10)}:${last.toISOString().slice(0, 10)}`); + start = new Date(last); + start.setDate(start.getDate() + 1); + } + const counts = await Promise.all( + PACKAGES.flatMap((p) => windows.map((w) => json(`https://api.npmjs.org/downloads/point/${w}/@${ORG}/${p}`).then((j) => Number(j.downloads ?? 0)))), ); - return results.reduce((a, b) => a + b, 0); + return counts.reduce((a, b) => a + b, 0); } -/** Live counters under the wordmark: GitHub stars, npm downloads, package count. */ +/** Live counters under the wordmark: stars across the org, all-time npm downloads, package count. */ export default function Stats(): ReactNode { const [stats, setStats] = useState({}); @@ -44,10 +65,10 @@ export default function Stats(): ReactNode { } const next: Stats = {}; void Promise.allSettled([ - sum(REPOS.map((r) => `https://api.github.com/repos/bedrock-core/${r}`), (j) => Number(j.stargazers_count ?? 0)).then((v) => { + orgStars().then((v) => { next.stars = v; }), - sum(PACKAGES.map((p) => `https://api.npmjs.org/downloads/point/last-month/@bedrock-core/${p}`), (j) => Number(j.downloads ?? 0)).then((v) => { + totalDownloads().then((v) => { next.downloads = v; }), ]).then(() => { @@ -62,11 +83,10 @@ export default function Stats(): ReactNode { return ( <> - pre-1.0 + beta MIT - {PACKAGES.length} packages {stats.stars !== undefined ? ★ {compact(stats.stars)} stars : null} - {stats.downloads !== undefined ? {compact(stats.downloads)} downloads / month : null} + {stats.downloads !== undefined ? {compact(stats.downloads)} downloads : null} ); } diff --git a/src/components/Home/home.module.css b/src/components/Home/home.module.css index d2a2073..2e9a989 100644 --- a/src/components/Home/home.module.css +++ b/src/components/Home/home.module.css @@ -40,6 +40,8 @@ .actions { display: flex; gap: var(--space-3); flex-wrap: wrap; justify-content: center; } .command { width: min(520px, 100%); text-align: left; } .command > div { margin: 0; } +.trust { display: flex; flex-wrap: wrap; justify-content: center; gap: var(--space-3) var(--space-6); margin: var(--space-2) 0 0; padding: 0; list-style: none; } +.trustItem { display: inline-flex; align-items: center; gap: var(--space-2); color: var(--text-muted); font-size: var(--text-body-sm); } /* shared section chrome */ .wrap { max-width: 1120px; margin: 0 auto; padding: var(--space-16) var(--space-8); } @@ -54,13 +56,16 @@ .title { margin: 0 0 var(--space-3); font-size: var(--text-h1); font-weight: var(--weight-bold); letter-spacing: var(--tracking-display); } .sub { margin: 0; max-width: 640px; color: var(--text-muted); font-size: var(--text-body-lg); line-height: var(--leading-relaxed); } .head { margin-bottom: var(--space-8); } +.headWide .sub { max-width: none; } /* features */ .sunken { border-top: 1px solid var(--border-subtle); border-bottom: 1px solid var(--border-subtle); background: var(--bg-sunken); } .features { display: grid; grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); gap: var(--space-4); } /* code tour */ -.tour { display: grid; grid-template-columns: minmax(280px, 380px) 1fr; gap: var(--space-12); align-items: start; } +.tour { display: grid; grid-template-columns: minmax(280px, 380px) minmax(0, 1fr); gap: var(--space-12); align-items: start; } +.tour > div { min-width: 0; } +.pane > div { overflow-x: auto; } .tabs { display: flex; gap: var(--space-5); border-bottom: 1px solid var(--border-subtle); margin-bottom: var(--space-4); } .tab { appearance: none; @@ -78,7 +83,8 @@ } .tabOn { color: var(--text-strong); border-bottom-color: var(--accent-solid); } .caption { margin: 0 0 var(--space-4); min-height: calc(2 * var(--text-body-sm) * var(--leading-relaxed)); color: var(--text-muted); font-size: var(--text-body-sm); line-height: var(--leading-relaxed); } -.panes { display: grid; } +.panes { display: grid; grid-template-columns: minmax(0, 1fr); min-width: 0; } +.pane { min-width: 0; } .pane { grid-area: 1 / 1; } .pane[hidden] { display: block !important; visibility: hidden; pointer-events: none; } .pane > div { margin: 0; } diff --git a/src/components/Home/index.tsx b/src/components/Home/index.tsx index a3e8966..3db4b42 100644 --- a/src/components/Home/index.tsx +++ b/src/components/Home/index.tsx @@ -2,13 +2,19 @@ import { useState, type ReactNode } from 'react'; import clsx from 'clsx'; import useBaseUrl from '@docusaurus/useBaseUrl'; import CodeBlock from '@theme/CodeBlock'; -import { Button, FeatureCard } from '../ds'; +import { Badge, Button, FeatureCard, Icon } from '../ds'; import Stats from './Stats'; import styles from './home.module.css'; const DISCORD = 'https://bedrock-core.drav.dev/discord'; const GITHUB = 'https://github.com/bedrock-core/'; +const TRUST = [ + { icon: 'shield-check', label: 'Type-safe by design' }, + { icon: 'package', label: 'Zero dependencies at runtime' }, + { icon: 'store', label: 'Marketplace ready', pending: true }, +]; + export function Hero(): ReactNode { const wordmark = useBaseUrl('img/logo/title.png'); return ( @@ -30,21 +36,30 @@ export function Hero(): ReactNode { -
npx @bedrock-core/cli
+
    + {TRUST.map((item) => ( +
  • + + {item.label} + {item.pending ? soon : null} +
  • + ))} +
); } -export function SectionHead({ eyebrow, title, sub }: { eyebrow: string; title: string; sub?: string }): ReactNode { +export function SectionHead({ eyebrow, title, sub, wide = false }: { eyebrow: string; title: string; sub?: string; wide?: boolean }): ReactNode { return ( -
+

{eyebrow}

{title}

{sub ?

{sub}

: null} @@ -210,7 +225,7 @@ export function Cta(): ReactNode {

Start with one package.

-

Pin an exact version while the stack is pre-1.0, and read the release notes before you upgrade.

+

Pin an exact version while a package is in beta, and read the release notes before you upgrade.

))} - + setOpen(false)}> Browse all packages diff --git a/src/components/nav/IconLink.tsx b/src/components/nav/IconLink.tsx index 4e083a0..9a168e6 100644 --- a/src/components/nav/IconLink.tsx +++ b/src/components/nav/IconLink.tsx @@ -7,14 +7,25 @@ export interface IconLinkProps { href: string; /** Lucide or brand icon name. */ icon: string; - /** Accessible label, also the tooltip. */ + /** Accessible label, also the tooltip; the visible text in the mobile drawer. */ label: string; + mobile?: boolean; } -/** Icon-only navbar link for GitHub, Discord and the like. */ -export default function IconLink({ href, icon, label }: IconLinkProps): ReactNode { +/** Icon-only navbar link for GitHub, Discord and the like; icon plus text in the mobile drawer. */ +export default function IconLink({ href, icon, label, mobile = false }: IconLinkProps): ReactNode { + if (mobile) { + return ( +
  • + + + {label} + +
  • + ); + } return ( - + ); diff --git a/src/components/nav/IconNav.tsx b/src/components/nav/IconNav.tsx new file mode 100644 index 0000000..4acc3a6 --- /dev/null +++ b/src/components/nav/IconNav.tsx @@ -0,0 +1,37 @@ +import type { ReactNode } from 'react'; +import clsx from 'clsx'; +import Link from '@docusaurus/Link'; +import { Icon } from '../ds'; +import styles from './nav.module.css'; + +export interface IconNavProps { + to: string; + /** Lucide icon shown instead of the label on small screens. */ + icon: string; + label: string; + mobile?: boolean; +} + +/** A left navbar link that is text on desktop and an icon on small screens. */ +export default function IconNav({ to, icon, label, mobile = false }: IconNavProps): ReactNode { + if (mobile) { + return ( +
  • + + + {label} + +
  • + ); + } + return ( + <> + + {label} + + + + + + ); +} diff --git a/src/components/nav/SectionSwitcher.tsx b/src/components/nav/SectionSwitcher.tsx new file mode 100644 index 0000000..a55158f --- /dev/null +++ b/src/components/nav/SectionSwitcher.tsx @@ -0,0 +1,82 @@ +import { useEffect, useRef, useState, type ReactNode } from 'react'; +import clsx from 'clsx'; +import Link from '@docusaurus/Link'; +import { useLocation } from '@docusaurus/router'; +import { categories, sections } from '../../data/sections'; +import { Badge, Icon } from '../ds'; +import styles from './switcher.module.css'; + +/** Sidebar header: names the current docs section and drops down to switch. */ +export default function SectionSwitcher(): ReactNode { + const [open, setOpen] = useState(false); + const ref = useRef(null); + const { pathname } = useLocation(); + const id = pathname.startsWith('/docs/') ? pathname.split('/')[2] : undefined; + const current = sections.find((s) => s.id === id); + + useEffect(() => { + if (!open) return undefined; + const onDown = (ev: MouseEvent): void => { + if (ref.current && !ref.current.contains(ev.target as Node)) setOpen(false); + }; + const onKey = (ev: KeyboardEvent): void => { + if (ev.key === 'Escape') setOpen(false); + }; + document.addEventListener('mousedown', onDown); + document.addEventListener('keydown', onKey); + return () => { + document.removeEventListener('mousedown', onDown); + document.removeEventListener('keydown', onKey); + }; + }, [open]); + + if (!current) return null; + const accent = categories.find((c) => c.id === current.category)?.accent ?? '--cat-framework'; + + return ( +
    + + {open ? ( +
    + {categories.map((category) => + sections + .filter((s) => s.category === category.id) + .map((s) => { + const planned = s.status === 'planned'; + return ( + setOpen(false)} + > + + {s.label} + + {category.label} + + ); + }), + )} +
    + ) : null} +
    + ); +} diff --git a/src/components/nav/nav.module.css b/src/components/nav/nav.module.css index c51978d..42954b9 100644 --- a/src/components/nav/nav.module.css +++ b/src/components/nav/nav.module.css @@ -1,6 +1,7 @@ -/* DocsMenu trigger */ +/* DocsMenu trigger and the plain left links share one shape */ .menu { position: relative; } -.trigger { +.trigger, +.navLink { appearance: none; cursor: pointer; height: 30px; @@ -17,9 +18,13 @@ font-weight: var(--weight-semibold); transition: var(--transition-control); } -.trigger:hover, .open { color: var(--text-strong); } +.navLink { text-decoration: none; } +.trigger:hover, .navLink:hover, .open { color: var(--text-strong); text-decoration: none; } +.navLinkActive { color: var(--text-accent); } .open { background: var(--bg-hover); border-color: var(--border-default); } .chevron { display: inline-flex; transition: transform var(--duration-fast) var(--ease-standard); } +.triggerIcon { display: none; } +.triggerLabel { display: inline; } .open .chevron { transform: rotate(180deg); } /* panel */ @@ -81,12 +86,38 @@ } .all:hover { color: var(--text-strong); text-decoration: none; } +/* below the Docusaurus breakpoint the panel spans the viewport; the trigger keeps its label until 600px */ @media (max-width: 996px) { - .panel { position: static; grid-template-columns: 1fr; box-shadow: none; border: 0; background: transparent; padding: var(--space-2) 0; } + .menu { display: flex !important; } + .panel { + position: fixed; + top: var(--ifm-navbar-height); + left: 0; + right: 0; + max-height: calc(100vh - var(--ifm-navbar-height)); + overflow-y: auto; + grid-template-columns: repeat(2, minmax(0, 1fr)); + gap: var(--space-4); + border-radius: 0; + border-width: 1px 0; + } } +@media (max-width: 600px) { + .navLink { display: none; } + .trigger { width: 32px; height: 32px; padding: 0; justify-content: center; } + .triggerIcon { display: inline-flex; } + .triggerLabel, .chevron { display: none; } + .panel { grid-template-columns: 1fr; } + .iconNav { display: inline-flex !important; } + } /* icon links */ .iconLink { + appearance: none; + background: transparent; + border: 0; + padding: 0; + cursor: pointer; display: inline-flex; align-items: center; justify-content: center; @@ -97,3 +128,10 @@ transition: var(--transition-control); } .iconLink:hover { color: var(--text-strong); background: var(--bg-hover); } + +.mobileGroup { padding: var(--space-2) 0; } +.mobileLink { display: flex; align-items: center; gap: var(--space-2); font-family: var(--font-mono); } + +.desktopOnly { display: inline-flex; } + +.iconNav { display: none; } diff --git a/src/components/nav/switcher.module.css b/src/components/nav/switcher.module.css new file mode 100644 index 0000000..73364bb --- /dev/null +++ b/src/components/nav/switcher.module.css @@ -0,0 +1,55 @@ +.switcher { position: relative; padding: var(--space-3) 6px var(--space-2); } +.trigger { + appearance: none; + cursor: pointer; + width: 100%; + height: 36px; + display: flex; + align-items: center; + gap: var(--space-2); + padding: 0 8px; + border-radius: var(--radius-sm); + border: 1px solid var(--border-default); + background: var(--bg-surface); + transition: var(--transition-control); +} +.trigger:hover { border-color: var(--border-strong); } +.open { background: var(--bg-active); } +.dot { width: 7px; height: 7px; border-radius: 2px; flex: none; } +.dotSm { width: 6px; height: 6px; border-radius: 2px; flex: none; } +.name { font-family: var(--font-mono); font-size: var(--text-body-sm); color: var(--text-strong); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } +.scope { color: var(--text-faint); } +.spacer { flex: 1; } +.list { + position: absolute; + top: 100%; + left: 6px; + right: 6px; + z-index: 50; + margin-top: 2px; + padding: 4px; + background: var(--bg-raised); + border: 1px solid var(--border-default); + border-radius: var(--radius-md); + box-shadow: var(--shadow-md); + display: grid; + gap: 1px; + max-height: 340px; + overflow-y: auto; +} +.row { + display: flex; + align-items: center; + gap: 8px; + padding: 6px 8px; + border-radius: var(--radius-xs); + font-family: var(--font-mono); + font-size: var(--text-body-sm); + color: var(--text-body); + text-decoration: none; + transition: var(--transition-control); +} +.row:hover { background: var(--bg-hover); color: var(--text-strong); text-decoration: none; } +.rowActive { background: var(--bg-selected); color: var(--text-accent); } +.rowPlanned { opacity: 0.45; pointer-events: none; } +.cat { font-family: var(--font-sans); font-size: var(--text-micro); color: var(--text-faint); } diff --git a/src/css/bedrock/colors.css b/src/css/bedrock/colors.css index fd65a61..cc1fd5c 100644 --- a/src/css/bedrock/colors.css +++ b/src/css/bedrock/colors.css @@ -90,7 +90,7 @@ --text-strong:#f5f5f6; --text-body:#d3d3d8; --text-muted:#9a9aa2; - --text-faint:#6c6c74; + --text-faint:#8e8e96; --text-inverse:var(--stone-1000); --text-accent:var(--ore-diamond-400); --text-link:var(--ore-diamond-400); @@ -142,7 +142,7 @@ --text-strong:var(--stone-950); --text-body:var(--stone-700); --text-muted:var(--stone-500); - --text-faint:var(--stone-400); + --text-faint:var(--stone-500); --text-inverse:var(--stone-0); --text-accent:var(--ore-diamond-700); --text-link:var(--ore-diamond-700); @@ -156,7 +156,7 @@ --accent-solid:var(--ore-diamond-600); --accent-solid-hover:var(--ore-diamond-500); --accent-solid-active:var(--ore-diamond-700); - --accent-on-solid:#ffffff; + --accent-on-solid:#04191a; --accent-soft:rgba(44,149,153,.11); --accent-soft-border:rgba(44,149,153,.28); diff --git a/src/css/bedrock/infima-bridge.css b/src/css/bedrock/infima-bridge.css index d7efbb8..2b705bc 100644 --- a/src/css/bedrock/infima-bridge.css +++ b/src/css/bedrock/infima-bridge.css @@ -47,6 +47,7 @@ --ifm-alert-border-radius: var(--radius-md); --ifm-button-border-radius: var(--radius-sm); --ifm-navbar-height: var(--layout-header-h); + --ifm-navbar-padding-horizontal: var(--space-6); --ifm-spacing-horizontal: var(--space-6); --ifm-global-spacing: var(--space-6); --ifm-toc-padding-vertical: var(--space-4); @@ -97,7 +98,7 @@ --ifm-color-success-dark: var(--status-success); --ifm-color-warning-dark: var(--status-warning); --ifm-color-danger-dark: var(--status-danger); - --ifm-color-secondary-dark: var(--border-default); + --ifm-color-secondary-dark: var(--text-muted); --ifm-color-info-contrast-background: color-mix(in srgb, var(--status-info) 13%, var(--bg-canvas)); --ifm-color-success-contrast-background: color-mix(in srgb, var(--status-success) 13%, var(--bg-canvas)); --ifm-color-warning-contrast-background: color-mix(in srgb, var(--status-warning) 13%, var(--bg-canvas)); @@ -140,14 +141,14 @@ h1, h2, h3, h4, .markdown h1, .markdown h2 { backdrop-filter: var(--blur-overlay); -webkit-backdrop-filter: var(--blur-overlay); } -/* package + section names in the navbar are identifiers, so: mono */ -.navbar__title, -.navbar__item.navbar__link { +/* the site name is an identifier, so: mono */ +.navbar__title { font-family: var(--font-mono); font-size: var(--text-body-sm); } .navbar__title { font-weight: var(--weight-bold); color: var(--text-strong); } .navbar__logo img { image-rendering: pixelated; } +.navbar__brand { margin-right: var(--space-2); } /* sidebar: top-level groups sans, leaf pages mono (they are file names) */ .menu { font-size: var(--text-body-sm); } @@ -167,18 +168,9 @@ h1, h2, h3, h4, .markdown h1, .markdown h2 { } .table-of-contents__left-border { border-left-color: var(--border-subtle); } -/* breadcrumbs use a literal slash and mono type */ +/* breadcrumbs: mono type, default separator */ .breadcrumbs__item { font-family: var(--font-mono); font-size: var(--text-caption); } .breadcrumbs__link { background: transparent !important; padding-left: 0; padding-right: 0; } -.breadcrumbs__item:not(:first-child)::before { - content: '/'; - color: var(--text-faint); - background: none; - width: auto; - height: auto; - margin: 0 var(--space-2); - filter: none; -} /* admonitions: flat tinted panel with a 2px coloured top rule */ .theme-admonition { @@ -271,7 +263,8 @@ table td code { font-size: var(--text-caption); color: var(--text-body); } -table td:first-child code { color: var(--accent-alt); font-weight: var(--weight-semibold); } +table td:first-child code { color: var(--text-strong); font-weight: var(--weight-bold); } +.required { color: var(--status-danger); font-weight: var(--weight-bold); margin-left: 2px; } table td a code { color: var(--ifm-link-color); font-weight: var(--weight-semibold); } table td a:hover code { color: var(--ifm-link-hover-color); text-decoration: underline; } table td:first-child { white-space: nowrap; } @@ -325,7 +318,7 @@ table td:first-child { white-space: nowrap; } font-family: var(--font-mono); font-size: var(--text-micro); } -@media (max-width: 996px) { .DocSearch-Button { width: 32px; padding: 0; justify-content: center; } .DocSearch-Button-Placeholder, .DocSearch-Button-Keys { display: none; } } +@media (max-width: 768px) { .DocSearch-Button { width: 32px; padding: 0; justify-content: center; } .DocSearch-Button-Placeholder, .DocSearch-Button-Keys { display: none; } } /* DocSearch modal on the same tokens */ .DocSearch { --docsearch-primary-color: var(--accent-solid); @@ -350,6 +343,77 @@ table td:first-child { white-space: nowrap; } .DocSearch-Modal { border: 1px solid var(--border-default); border-radius: var(--radius-lg); } .DocSearch-Hit a { border-radius: var(--radius-sm); } +/* the navbar never uses the Docusaurus drawer: below 996px it keeps the desktop + layout, the right cluster collapses to icons at 768px and the left one at 600px */ +@media (max-width: 996px) { + /* the drawer carries the section's page tree, so its trigger belongs to docs pages */ + .navbar__toggle { display: none; } + html.docs-wrapper .navbar__toggle { display: inline-flex; } + html.docs-wrapper .navbar__title { display: none; } + .navbar__items .navbar__item { display: inline-block; } + .navbar__items--right [class*='colorModeToggle'] { display: inline-flex; } + .navbar__items--right [class*='navbarSearchContainer'] { position: static; } +} +@media (max-width: 768px) { + .navbar__items--right { gap: var(--space-1); } + .navbar__items--right > [class*='iconLink'] { order: 1; } + .navbar__items--right [class*='colorModeToggle'] { display: inline-flex; order: 2; } + .navbar__items--right [class*='navbarSearchContainer'] { order: 3; } +} +@media (max-width: 600px) { + :root { --ifm-navbar-padding-horizontal: var(--space-4); } + /* where the left links become icons the drawer takes over the social links and the theme */ + html.docs-wrapper .navbar__items--right > [class*='iconLink'], + html.docs-wrapper .navbar__items--right [class*='colorModeToggle'] { display: none; } + .navbar__items:not(.navbar__items--right) { gap: 2px; } + .navbar__brand { margin-right: 0; } + .navbar__title { font-size: var(--text-body-sm); } +} +@media (max-width: 420px) { + .navbar__title { display: none; } +} + +/* mobile "On this page" collapsible under the breadcrumbs */ +.theme-doc-toc-mobile { + background: var(--bg-surface); + border: 1px solid var(--border-default); + border-radius: var(--radius-md); +} +.theme-doc-toc-mobile > button { + color: var(--text-muted); + font-family: var(--font-mono); + font-size: var(--text-caption); + letter-spacing: var(--tracking-label); + text-transform: uppercase; +} +.theme-doc-toc-mobile > button:hover { color: var(--text-strong); } +.theme-doc-toc-mobile > button::after { filter: var(--ifm-menu-link-sublist-icon-filter); opacity: 0.7; } +.theme-doc-toc-mobile > div > ul { border-top: 1px solid var(--border-subtle); } + +/* the drawer trigger: the same icon box as the header's other icons, docs pages only */ +.navbar__toggle { + display: none; + align-items: center; + justify-content: center; + width: 32px; + height: 32px; + margin-right: var(--space-2); + padding: 0; + border: 0; + background: transparent; + border-radius: var(--radius-sm); + color: var(--ifm-navbar-link-color); + cursor: pointer; + transition: var(--transition-control); +} +.navbar__toggle:hover { color: var(--text-strong); background: var(--bg-hover); } + +/* mobile drawer: the section's page tree, on the kit's surfaces */ +.navbar-sidebar--show { background: var(--bg-canvas); backdrop-filter: none; -webkit-backdrop-filter: none; } +.navbar-sidebar { background: var(--bg-raised); box-shadow: var(--shadow-lg); } +.navbar-sidebar__brand { border-bottom: 1px solid var(--border-subtle); box-shadow: none; } +.navbar-sidebar__item { overflow-y: auto; } + /* respect reduced motion */ @media (prefers-reduced-motion: reduce) { * { transition-duration: 1ms !important; animation-duration: 1ms !important; } diff --git a/src/data/sections.ts b/src/data/sections.ts index e381636..87ff618 100644 --- a/src/data/sections.ts +++ b/src/data/sections.ts @@ -7,7 +7,8 @@ export type CategoryId = 'framework' | 'ui' | 'content' | 'tooling'; -export type SectionStatus = 'pre-1.0' | '1.0' | 'planned'; +/** `beta` is a 0.x package, `1.0-rc` a release candidate, `1.0` a released package. */ +export type SectionStatus = 'beta' | '1.0-rc' | '1.0' | 'planned'; export interface Category { id: CategoryId; @@ -49,7 +50,7 @@ export const sections: Section[] = [ label: 'server', pkg: '@bedrock-core/server', category: 'framework', - status: 'pre-1.0', + status: 'beta', description: 'Registry, RPC, shared state and config across addon realms.', icon: 'server', repo: `${GH}/server`, @@ -59,7 +60,7 @@ export const sections: Section[] = [ label: 'sync', pkg: '@bedrock-core/sync', category: 'framework', - status: 'pre-1.0', + status: 'beta', description: 'The script-event transport: bus, discovery, RPC, replicated state.', icon: 'radio', repo: `${GH}/server`, @@ -91,7 +92,7 @@ export const sections: Section[] = [ label: 'ui', pkg: '@bedrock-core/ui', category: 'ui', - status: 'pre-1.0', + status: 'beta', description: 'JSX screens for server forms and containers, drawn by the render pack.', icon: 'layout-panel-left', repo: `${GH}/ui`, @@ -101,7 +102,7 @@ export const sections: Section[] = [ label: 'ore-styled', pkg: '@bedrock-core/ore-styled', category: 'ui', - status: 'pre-1.0', + status: 'beta', description: 'Themed components with vanilla Minecraft textures.', icon: 'palette', repo: `${GH}/ui`, @@ -111,7 +112,7 @@ export const sections: Section[] = [ label: 'navigation', pkg: '@bedrock-core/navigation', category: 'ui', - status: 'pre-1.0', + status: 'beta', description: 'Stack navigation between screens.', icon: 'navigation', repo: `${GH}/ui`, @@ -133,7 +134,7 @@ export const sections: Section[] = [ label: 'config', pkg: '@bedrock-core/config', category: 'content', - status: 'pre-1.0', + status: 'beta', description: 'The shared addon list, settings screens and guide viewer.', icon: 'sliders-horizontal', repo: `${GH}/ui`, @@ -143,7 +144,7 @@ export const sections: Section[] = [ label: 'guides', pkg: '@bedrock-core/guides', category: 'content', - status: 'pre-1.0', + status: 'beta', description: 'In-game guides authored in MDX.', icon: 'book-open', repo: `${GH}/ui`, @@ -153,7 +154,7 @@ export const sections: Section[] = [ label: 'i18n', pkg: '@bedrock-core/i18n', category: 'content', - status: 'pre-1.0', + status: 'beta', description: 'Typed keys, interpolation and plurals, resolved per player.', icon: 'languages', repo: `${GH}/ui`, @@ -165,7 +166,7 @@ export const sections: Section[] = [ label: 'filters', pkg: 'bedrock-core/regolith-filters', category: 'tooling', - status: 'pre-1.0', + status: 'beta', description: 'Regolith filters: manifest, generator, guides, i18n, ui-compile, bundler.', icon: 'funnel', repo: `${GH}/regolith-filters`, @@ -175,7 +176,7 @@ export const sections: Section[] = [ label: 'cli', pkg: '@bedrock-core/cli', category: 'tooling', - status: 'pre-1.0', + status: 'beta', description: 'Scaffold an addon with the whole stack wired.', icon: 'terminal', repo: `${GH}/ui`, @@ -185,7 +186,7 @@ export const sections: Section[] = [ label: 'bds-runner', pkg: '@bedrock-core/bds-runner', category: 'tooling', - status: 'pre-1.0', + status: 'beta', description: 'Run GameTests headlessly on a Bedrock Dedicated Server.', icon: 'flask-conical', repo: `${GH}/bds-runner`, diff --git a/src/prism/bedrock.ts b/src/prism/bedrock.ts index 2ef8203..08a8c07 100644 --- a/src/prism/bedrock.ts +++ b/src/prism/bedrock.ts @@ -2,7 +2,7 @@ import type { PrismTheme } from 'prism-react-renderer'; // Syntax palette on the ore accents (colors.css). Code blocks are dark in both // site themes, so one palette serves both. -const stone = { text: '#d3d3d8', muted: '#8b8b93', faint: '#6a6a72', bright: '#e9e9ec' }; +const stone = { text: '#d3d3d8', muted: '#9a9aa2', faint: '#8b8b93', bright: '#e9e9ec' }; const ore = { emerald: '#7ce2a8', gold: '#ffd88a', diff --git a/src/theme/ColorModeToggle/index.tsx b/src/theme/ColorModeToggle/index.tsx new file mode 100644 index 0000000..4d790d9 --- /dev/null +++ b/src/theme/ColorModeToggle/index.tsx @@ -0,0 +1,48 @@ +import { memo, type ReactNode } from 'react'; +import clsx from 'clsx'; +import useIsBrowser from '@docusaurus/useIsBrowser'; +import type { Props } from '@theme/ColorModeToggle'; +import { Icon } from '../../components/ds'; +import styles from './styles.module.css'; + +type Choice = Props['value']; + +function nextMode(value: Choice, respectPrefersColorScheme: boolean): Choice { + if (!respectPrefersColorScheme) return value === 'dark' ? 'light' : 'dark'; + if (value === null) return 'light'; + return value === 'light' ? 'dark' : null; +} + +const LABEL: Record = { light: 'light mode', dark: 'dark mode', system: 'system mode' }; + +// The same glyph set and the same icon box as every other control in the header. +// All three icons are rendered and picked by `data-theme-choice` on the root, so +// the right one shows before React hydrates. +function ColorModeToggle({ className, buttonClassName, respectPrefersColorScheme, value, onChange }: Props): ReactNode { + const isBrowser = useIsBrowser(); + const label = LABEL[value ?? 'system']; + return ( +
    + +
    + ); +} + +export default memo(ColorModeToggle); diff --git a/src/theme/ColorModeToggle/styles.module.css b/src/theme/ColorModeToggle/styles.module.css new file mode 100644 index 0000000..ac581c9 --- /dev/null +++ b/src/theme/ColorModeToggle/styles.module.css @@ -0,0 +1,23 @@ +.toggle { display: inline-flex; width: 32px; height: 32px; } +.button { + appearance: none; + display: inline-flex; + align-items: center; + justify-content: center; + width: 100%; + height: 100%; + padding: 0; + border: 0; + background: transparent; + border-radius: var(--radius-sm); + color: var(--ifm-navbar-link-color); + cursor: pointer; + transition: var(--transition-control); + -webkit-tap-highlight-color: transparent; +} +.button:hover { color: var(--text-strong); background: var(--bg-hover); } +.button:disabled { cursor: not-allowed; } +.icon { display: none; } +[data-theme-choice='light'] .light, +[data-theme-choice='dark'] .dark, +[data-theme-choice='system'] .system { display: inline-flex; } diff --git a/src/theme/DocSidebar/Desktop/Content/index.tsx b/src/theme/DocSidebar/Desktop/Content/index.tsx new file mode 100644 index 0000000..da0bafb --- /dev/null +++ b/src/theme/DocSidebar/Desktop/Content/index.tsx @@ -0,0 +1,17 @@ +import type { ReactNode } from 'react'; +import Content from '@theme-original/DocSidebar/Desktop/Content'; +import type ContentType from '@theme/DocSidebar/Desktop/Content'; +import type { WrapperProps } from '@docusaurus/types'; +import SectionSwitcher from '../../../../components/nav/SectionSwitcher'; + +type Props = WrapperProps; + +// The section switcher sits above every docs sidebar tree. +export default function ContentWrapper(props: Props): ReactNode { + return ( + <> + + + + ); +} diff --git a/src/theme/DocSidebar/Mobile/index.tsx b/src/theme/DocSidebar/Mobile/index.tsx new file mode 100644 index 0000000..7b64bcb --- /dev/null +++ b/src/theme/DocSidebar/Mobile/index.tsx @@ -0,0 +1,34 @@ +import { memo, type ReactNode } from 'react'; +import clsx from 'clsx'; +import { NavbarSecondaryMenuFiller, ThemeClassNames } from '@docusaurus/theme-common'; +import { useNavbarMobileSidebar } from '@docusaurus/theme-common/internal'; +import DocSidebarItems from '@theme/DocSidebarItems'; +import type { Props } from '@theme/DocSidebar/Mobile'; +import SectionSwitcher from '../../../components/nav/SectionSwitcher'; + +// The drawer carries the same tree as the desktop sidebar, section switcher included. +function DocSidebarMobileMenu({ sidebar, path }: Props): ReactNode { + const mobileSidebar = useNavbarMobileSidebar(); + return ( + <> + +
      + { + if (item.type === 'category' && item.href) mobileSidebar.toggle(); + if (item.type === 'link') mobileSidebar.toggle(); + }} + level={1} + /> +
    + + ); +} + +function DocSidebarMobile(props: Props): ReactNode { + return ; +} + +export default memo(DocSidebarMobile); diff --git a/src/theme/Footer/index.tsx b/src/theme/Footer/index.tsx index 9634980..da796a1 100644 --- a/src/theme/Footer/index.tsx +++ b/src/theme/Footer/index.tsx @@ -40,7 +40,7 @@ export default function Footer(): ReactNode {
    Community
    {community.map((item) => ( - + {item.label} ))} diff --git a/src/theme/Footer/styles.module.css b/src/theme/Footer/styles.module.css index 2c8780a..35b255d 100644 --- a/src/theme/Footer/styles.module.css +++ b/src/theme/Footer/styles.module.css @@ -6,7 +6,15 @@ .inner { max-width: 1120px; margin: 0 auto; display: flex; flex-wrap: wrap; gap: var(--space-12); } .brand { min-width: 200px; max-width: 260px; } .wordmark { height: 22px; width: auto; image-rendering: pixelated; opacity: 0.85; } -.tagline { margin: var(--space-4) 0 0; color: var(--text-faint); font-size: var(--text-body-sm); line-height: var(--leading-relaxed); } +.tagline { + margin: var(--space-4) 0 0; + color: var(--text-faint); + font-family: var(--font-display); + font-size: var(--text-body-md); + font-weight: var(--weight-semibold); + letter-spacing: var(--tracking-heading); + line-height: var(--leading-snug); +} .spacer { flex: 1; } .col { display: grid; gap: var(--space-2); align-content: start; } .title { @@ -19,7 +27,6 @@ } .link { color: var(--text-muted); font-size: var(--text-body-sm); text-decoration: none; font-family: var(--font-mono); transition: var(--transition-control); } .link:hover { color: var(--text-strong); text-decoration: none; } -.sans { font-family: var(--font-sans); } .bottom { max-width: 1120px; margin: var(--space-10) auto 0; @@ -28,7 +35,18 @@ color: var(--text-faint); font-size: var(--text-caption); } -@media (max-width: 768px) { - .inner { gap: var(--space-8); } +/* narrow: three columns, the wordmark keeps the first cell */ +@media (max-width: 996px) { + .inner { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--space-8) var(--space-6); } + .brand { max-width: none; } .spacer { display: none; } } +/* phones: wordmark centered on its own row, then a centered pair of columns */ +@media (max-width: 768px) { + .inner { grid-template-columns: repeat(2, minmax(0, 150px)); justify-content: center; gap: var(--space-10) var(--space-8); } + .brand { grid-column: 1 / -1; justify-self: center; text-align: center; margin-bottom: var(--space-2); } + .col { justify-items: center; text-align: center; } + /* five columns in pairs leaves Community alone: give it the whole row */ + .col:last-child { grid-column: 1 / -1; } + .bottom { text-align: center; } +} diff --git a/src/theme/MDXComponents.tsx b/src/theme/MDXComponents.tsx index d53e928..1cc02a9 100644 --- a/src/theme/MDXComponents.tsx +++ b/src/theme/MDXComponents.tsx @@ -1,6 +1,6 @@ import MDXComponents from '@theme-original/MDXComponents'; import { Exec, Install } from '../components/PackageManager'; -import { Badge, Icon, Kbd, PackageCard, Tag } from '../components/ds'; +import { Badge, Icon, Kbd, PackageCard, Req, Tag } from '../components/ds'; // Components every docs page can use without importing them. export default { @@ -12,4 +12,5 @@ export default { Kbd, Icon, PackageCard, + Req, }; diff --git a/src/theme/Navbar/MobileSidebar/Header/index.tsx b/src/theme/Navbar/MobileSidebar/Header/index.tsx new file mode 100644 index 0000000..03c36a6 --- /dev/null +++ b/src/theme/Navbar/MobileSidebar/Header/index.tsx @@ -0,0 +1,35 @@ +import type { ReactNode } from 'react'; +import Link from '@docusaurus/Link'; +import { useNavbarMobileSidebar } from '@docusaurus/theme-common/internal'; +import NavbarColorModeToggle from '@theme/Navbar/ColorModeToggle'; +import { Icon } from '../../../../components/ds'; +import nav from '../../../../components/nav/nav.module.css'; +import styles from './styles.module.css'; + +const LINKS = [ + { href: 'https://github.com/bedrock-core/', icon: 'github', label: 'GitHub' }, + { href: 'https://bedrock-core.drav.dev/discord', icon: 'discord', label: 'Discord' }, +]; + +// Left stays empty: it sits over the trigger, so a second tap there does nothing. +// The middle takes over the social links and the theme switch at the widths where +// the navbar drops them for space. +export default function NavbarMobileSidebarHeader(): ReactNode { + const mobileSidebar = useNavbarMobileSidebar(); + return ( +
    + +
    + {LINKS.map((l) => ( + + + + ))} + +
    + +
    + ); +} diff --git a/src/theme/Navbar/MobileSidebar/Header/styles.module.css b/src/theme/Navbar/MobileSidebar/Header/styles.module.css new file mode 100644 index 0000000..89ef75a --- /dev/null +++ b/src/theme/Navbar/MobileSidebar/Header/styles.module.css @@ -0,0 +1,28 @@ +.header { + display: grid; + grid-template-columns: 1fr auto 1fr; + align-items: center; + gap: var(--space-2); +} +.links { grid-column: 2; display: none; justify-self: center; align-items: center; gap: var(--space-2); } +@media (max-width: 600px) { + .links { display: inline-flex; } +} +.close { + appearance: none; + display: inline-flex; + align-items: center; + justify-content: center; + grid-column: 3; + justify-self: end; + width: 32px; + height: 32px; + padding: 0; + border: 0; + background: transparent; + border-radius: var(--radius-sm); + color: var(--ifm-navbar-link-color); + cursor: pointer; + transition: var(--transition-control); +} +.close:hover { color: var(--text-strong); background: var(--bg-hover); } diff --git a/src/theme/Navbar/MobileSidebar/Layout/index.tsx b/src/theme/Navbar/MobileSidebar/Layout/index.tsx new file mode 100644 index 0000000..ca7be7e --- /dev/null +++ b/src/theme/Navbar/MobileSidebar/Layout/index.tsx @@ -0,0 +1,17 @@ +import type { ReactNode } from 'react'; +import { useNavbarSecondaryMenu } from '@docusaurus/theme-common/internal'; +import type { Props } from '@theme/Navbar/MobileSidebar/Layout'; + +// One pane. The drawer only opens where a docs sidebar exists, so its content is +// that sidebar; the site navigation stays in the header itself. +export default function NavbarMobileSidebarLayout({ header, primaryMenu }: Props): ReactNode { + const { content } = useNavbarSecondaryMenu(); + return ( +
    + {header} +
    +
    {content ?? primaryMenu}
    +
    +
    + ); +} diff --git a/src/theme/Navbar/MobileSidebar/Toggle/index.tsx b/src/theme/Navbar/MobileSidebar/Toggle/index.tsx new file mode 100644 index 0000000..a64f331 --- /dev/null +++ b/src/theme/Navbar/MobileSidebar/Toggle/index.tsx @@ -0,0 +1,20 @@ +import type { ReactNode } from 'react'; +import { useNavbarMobileSidebar } from '@docusaurus/theme-common/internal'; +import { Icon } from '../../../../components/ds'; + +// The drawer holds the section's page tree, so the trigger is a sidebar glyph +// rather than a hamburger. CSS shows it on docs pages only. +export default function MobileSidebarToggle(): ReactNode { + const { toggle, shown } = useNavbarMobileSidebar(); + return ( + + ); +} diff --git a/src/theme/NavbarItem/ComponentTypes.tsx b/src/theme/NavbarItem/ComponentTypes.tsx index 1d78d26..8b23b15 100644 --- a/src/theme/NavbarItem/ComponentTypes.tsx +++ b/src/theme/NavbarItem/ComponentTypes.tsx @@ -1,6 +1,7 @@ import ComponentTypes from '@theme-original/NavbarItem/ComponentTypes'; import DocsMenu from '../../components/nav/DocsMenu'; import IconLink from '../../components/nav/IconLink'; +import IconNav from '../../components/nav/IconNav'; // Extra navbar item types: `custom-docsMenu` (the package mega-menu) and // `custom-iconLink` (icon-only external links). @@ -8,4 +9,5 @@ export default { ...ComponentTypes, 'custom-docsMenu': DocsMenu, 'custom-iconLink': IconLink, + 'custom-iconNav': IconNav, }; From 9b0d930fa716b3719266e12966e26681778ef8d5 Mon Sep 17 00:00:00 2001 From: DrAv0011 Date: Tue, 8 Sep 2026 07:55:49 +0200 Subject: [PATCH 13/48] chore: read DocSearch credentials from the environment The three ALGOLIA_ variables come from a local .env or, in the deploy workflow, from repository variables and secrets. Without them the site builds with no search box. Co-Authored-By: Claude Opus 5 (1M context) --- .env.example | 7 +++++++ .github/workflows/deploy.yml | 21 +++++++++++++++------ .gitignore | 1 + README.md | 7 +++++++ 4 files changed, 30 insertions(+), 6 deletions(-) create mode 100644 .env.example diff --git a/.env.example b/.env.example new file mode 100644 index 0000000..638a231 --- /dev/null +++ b/.env.example @@ -0,0 +1,7 @@ +# DocSearch. Apply at https://docsearch.algolia.com/apply/ and copy the values +# from the Algolia dashboard. The key is the search-only one, which ships in the +# client bundle and is safe to expose; never use an admin or write key here. +# Leave these unset to build the site without a search box. +ALGOLIA_APP_ID= +ALGOLIA_SEARCH_API_KEY= +ALGOLIA_INDEX_NAME= diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index 32478db..b5f6bfb 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -8,7 +8,7 @@ jobs: name: Build Docusaurus runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v7 with: fetch-depth: 0 @@ -17,18 +17,27 @@ jobs: npm install -g corepack corepack enable - - uses: actions/setup-node@v4 + - uses: actions/setup-node@v7 with: - node-version: 20 + node-version: 22 cache: yarn - name: Install dependencies run: yarn install --frozen-lockfile - name: Build website run: yarn build - + env: + # DocSearch. Unset means the site builds without a search box. + ALGOLIA_APP_ID: ${{ vars.ALGOLIA_APP_ID }} + ALGOLIA_SEARCH_API_KEY: ${{ secrets.ALGOLIA_SEARCH_API_KEY }} + ALGOLIA_INDEX_NAME: ${{ vars.ALGOLIA_INDEX_NAME }} + + # From v4 this action excludes dotfiles, so Docusaurus's `.nojekyll` is not in the artifact. + # Harmless here: artifact deployments are served as-is and never run Jekyll, and the build + # output has no underscore-prefixed paths for Jekyll to strip. If a dotfile ever has to ship, + # build the artifact by hand instead of using this action. - name: Upload Build Artifact - uses: actions/upload-pages-artifact@v3 + uses: actions/upload-pages-artifact@v5 with: path: build @@ -50,4 +59,4 @@ jobs: steps: - name: Deploy to GitHub Pages id: deployment - uses: actions/deploy-pages@v4 \ No newline at end of file + uses: actions/deploy-pages@v5 \ No newline at end of file diff --git a/.gitignore b/.gitignore index b2d6de3..b083ed4 100644 --- a/.gitignore +++ b/.gitignore @@ -10,6 +10,7 @@ # Misc .DS_Store +.env .env.local .env.development.local .env.test.local diff --git a/README.md b/README.md index 677c23b..8d39b9c 100644 --- a/README.md +++ b/README.md @@ -18,6 +18,13 @@ yarn start This command starts a local development server and opens up a browser window. Most changes are reflected live without having to restart the server. +## Search + +DocSearch is configured from the environment. Copy `.env.example` to `.env` and +fill in the three values from the Algolia dashboard; without them the site builds +with no search box. The deploy workflow reads the same names from repository +variables and secrets. + ## Build ```bash From dea56088a6e7a83197e7f251cdee7db657d7a1cf Mon Sep 17 00:00:00 2001 From: DrAv0011 Date: Tue, 8 Sep 2026 08:27:58 +0200 Subject: [PATCH 14/48] feat(site): drop Showcase, add a page-outline heading and Next steps cards The Showcase route, its navbar item and the icon-nav component are gone; the Docs menu keeps its label at every width. Below 996px, where the search collapses to a button, the social links and the theme switch move into the drawer on the pages that have one. The page outline gains an "On this page" heading and the rule now hugs the list instead of the container's padding. Next steps items render as cards, each one clickable in full. Co-Authored-By: Claude Opus 5 (1M context) --- docusaurus.config.ts | 1 - src/components/nav/DocsMenu.tsx | 5 +- src/components/nav/IconLink.tsx | 2 +- src/components/nav/IconNav.tsx | 37 ----------- src/components/nav/nav.module.css | 13 +--- src/css/bedrock/infima-bridge.css | 66 +++++++++++++++++-- src/pages/showcase.tsx | 19 ------ .../MobileSidebar/Header/styles.module.css | 2 +- src/theme/NavbarItem/ComponentTypes.tsx | 2 - src/theme/TOC/index.tsx | 19 ++++++ src/theme/TOC/styles.module.css | 17 +++++ 11 files changed, 101 insertions(+), 82 deletions(-) delete mode 100644 src/components/nav/IconNav.tsx delete mode 100644 src/pages/showcase.tsx create mode 100644 src/theme/TOC/index.tsx create mode 100644 src/theme/TOC/styles.module.css diff --git a/docusaurus.config.ts b/docusaurus.config.ts index f59f7f2..8b2aa6c 100644 --- a/docusaurus.config.ts +++ b/docusaurus.config.ts @@ -131,7 +131,6 @@ const config: Config = { }, items: [ { type: 'custom-docsMenu', position: 'left', label: 'Docs' }, - { type: 'custom-iconNav', position: 'left', to: '/showcase', icon: 'blocks', label: 'Showcase' }, { type: 'search', position: 'right' }, { type: 'custom-iconLink', position: 'right', href: 'https://bedrock-core.drav.dev/discord', icon: 'discord', label: 'Discord' }, { type: 'custom-iconLink', position: 'right', href: 'https://github.com/bedrock-core/', icon: 'github', label: 'GitHub' }, diff --git a/src/components/nav/DocsMenu.tsx b/src/components/nav/DocsMenu.tsx index ae58927..d9d6dd4 100644 --- a/src/components/nav/DocsMenu.tsx +++ b/src/components/nav/DocsMenu.tsx @@ -75,10 +75,7 @@ export default function DocsMenu({ label = 'Docs', mobile = false }: { label?: s aria-haspopup="true" onClick={() => setOpen((v) => !v)} > - - - - {label} + {label} diff --git a/src/components/nav/IconLink.tsx b/src/components/nav/IconLink.tsx index 9a168e6..e1736f6 100644 --- a/src/components/nav/IconLink.tsx +++ b/src/components/nav/IconLink.tsx @@ -25,7 +25,7 @@ export default function IconLink({ href, icon, label, mobile = false }: IconLink ); } return ( - + ); diff --git a/src/components/nav/IconNav.tsx b/src/components/nav/IconNav.tsx deleted file mode 100644 index 4acc3a6..0000000 --- a/src/components/nav/IconNav.tsx +++ /dev/null @@ -1,37 +0,0 @@ -import type { ReactNode } from 'react'; -import clsx from 'clsx'; -import Link from '@docusaurus/Link'; -import { Icon } from '../ds'; -import styles from './nav.module.css'; - -export interface IconNavProps { - to: string; - /** Lucide icon shown instead of the label on small screens. */ - icon: string; - label: string; - mobile?: boolean; -} - -/** A left navbar link that is text on desktop and an icon on small screens. */ -export default function IconNav({ to, icon, label, mobile = false }: IconNavProps): ReactNode { - if (mobile) { - return ( -
  • - - - {label} - -
  • - ); - } - return ( - <> - - {label} - - - - - - ); -} diff --git a/src/components/nav/nav.module.css b/src/components/nav/nav.module.css index 42954b9..c5f1042 100644 --- a/src/components/nav/nav.module.css +++ b/src/components/nav/nav.module.css @@ -23,8 +23,6 @@ .navLinkActive { color: var(--text-accent); } .open { background: var(--bg-hover); border-color: var(--border-default); } .chevron { display: inline-flex; transition: transform var(--duration-fast) var(--ease-standard); } -.triggerIcon { display: none; } -.triggerLabel { display: inline; } .open .chevron { transform: rotate(180deg); } /* panel */ @@ -86,7 +84,7 @@ } .all:hover { color: var(--text-strong); text-decoration: none; } -/* below the Docusaurus breakpoint the panel spans the viewport; the trigger keeps its label until 600px */ +/* below the Docusaurus breakpoint the panel spans the viewport */ @media (max-width: 996px) { .menu { display: flex !important; } .panel { @@ -103,13 +101,8 @@ } } @media (max-width: 600px) { - .navLink { display: none; } - .trigger { width: 32px; height: 32px; padding: 0; justify-content: center; } - .triggerIcon { display: inline-flex; } - .triggerLabel, .chevron { display: none; } .panel { grid-template-columns: 1fr; } - .iconNav { display: inline-flex !important; } - } +} /* icon links */ .iconLink { @@ -132,6 +125,4 @@ .mobileGroup { padding: var(--space-2) 0; } .mobileLink { display: flex; align-items: center; gap: var(--space-2); font-family: var(--font-mono); } -.desktopOnly { display: inline-flex; } -.iconNav { display: none; } diff --git a/src/css/bedrock/infima-bridge.css b/src/css/bedrock/infima-bridge.css index 2b705bc..8a7372f 100644 --- a/src/css/bedrock/infima-bridge.css +++ b/src/css/bedrock/infima-bridge.css @@ -160,8 +160,15 @@ h1, h2, h3, h4, .markdown h1, .markdown h2 { .menu__link--active:not(.menu__link--sublist) { font-weight: var(--weight-semibold); } .theme-doc-sidebar-container { border-right: 1px solid var(--border-subtle) !important; } -/* TOC: active item takes an accent left rule, never a background */ -.table-of-contents { border-left: 1px solid var(--border-subtle); font-size: var(--text-body-sm); } +/* TOC: the rule hugs the list, one indent step, active item takes the accent */ +.table-of-contents { + border-left: 1px solid var(--border-subtle); + font-size: var(--text-body-sm); + padding: 0 0 0 var(--space-3); +} +.table-of-contents ul { padding-left: var(--space-3); } +.table-of-contents li { margin: 0; } +.table-of-contents__link { padding: 4px 0; line-height: var(--leading-snug); } .table-of-contents__link--active { color: var(--text-accent); font-weight: var(--weight-medium); @@ -269,6 +276,53 @@ table td a code { color: var(--ifm-link-color); font-weight: var(--weight-semibo table td a:hover code { color: var(--ifm-link-hover-color); text-decoration: underline; } table td:first-child { white-space: nowrap; } +/* Next steps closes a page: one card per link, mono title, description alongside */ +.markdown h2#next-steps ~ ul { + display: grid; + gap: var(--space-2); + list-style: none; + margin: var(--space-4) 0; + padding: 0; +} +.markdown h2#next-steps ~ ul > li { + position: relative; + cursor: pointer; + margin: 0; + padding: var(--space-3) var(--space-4); + border: 1px solid var(--border-subtle); + border-radius: var(--radius-sm); + background: var(--bg-surface); + color: var(--text-muted); + font-size: var(--text-body-sm); + line-height: var(--leading-relaxed); + transition: var(--transition-control); +} +.markdown h2#next-steps ~ ul > li:hover, +.markdown h2#next-steps ~ ul > li:focus-within { border-color: var(--border-accent); } +/* the whole card follows the first link; any other link in the row stays on top of it */ +.markdown h2#next-steps ~ ul > li > a:first-of-type::after { + content: ''; + position: absolute; + inset: 0; + border-radius: var(--radius-sm); +} +.markdown h2#next-steps ~ ul > li a:not(:first-of-type) { position: relative; z-index: 1; } +.markdown h2#next-steps ~ ul > li::before { + content: ''; + display: inline-block; + width: 14px; + height: 14px; + vertical-align: -2px; + margin-right: var(--space-3); + background: var(--text-faint); + mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m15 10 5 5-5 5'/%3E%3Cpath d='M4 4v7a4 4 0 0 0 4 4h12'/%3E%3C/svg%3E") center / contain no-repeat; + -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m15 10 5 5-5 5'/%3E%3Cpath d='M4 4v7a4 4 0 0 0 4 4h12'/%3E%3C/svg%3E") center / contain no-repeat; +} +.markdown h2#next-steps ~ ul > li a:first-of-type { + font-family: var(--font-mono); + font-weight: var(--weight-semibold); +} + /* buttons never bounce; they nudge 1px */ .button { font-weight: var(--weight-semibold); letter-spacing: var(--tracking-label); transition: var(--transition-control); } .button:active { transform: translateY(1px); } @@ -354,17 +408,17 @@ table td:first-child { white-space: nowrap; } .navbar__items--right [class*='colorModeToggle'] { display: inline-flex; } .navbar__items--right [class*='navbarSearchContainer'] { position: static; } } -@media (max-width: 768px) { +@media (max-width: 996px) { .navbar__items--right { gap: var(--space-1); } .navbar__items--right > [class*='iconLink'] { order: 1; } .navbar__items--right [class*='colorModeToggle'] { display: inline-flex; order: 2; } .navbar__items--right [class*='navbarSearchContainer'] { order: 3; } + /* where the search becomes a button the drawer takes over these, on the pages that have one */ + html.docs-wrapper .navbar__items--right > [class*='iconLink'], + html.docs-wrapper .navbar__items--right [class*='colorModeToggle'] { display: none; } } @media (max-width: 600px) { :root { --ifm-navbar-padding-horizontal: var(--space-4); } - /* where the left links become icons the drawer takes over the social links and the theme */ - html.docs-wrapper .navbar__items--right > [class*='iconLink'], - html.docs-wrapper .navbar__items--right [class*='colorModeToggle'] { display: none; } .navbar__items:not(.navbar__items--right) { gap: 2px; } .navbar__brand { margin-right: 0; } .navbar__title { font-size: var(--text-body-sm); } diff --git a/src/pages/showcase.tsx b/src/pages/showcase.tsx deleted file mode 100644 index f79028f..0000000 --- a/src/pages/showcase.tsx +++ /dev/null @@ -1,19 +0,0 @@ -import type { ReactNode } from 'react'; -import Layout from '@theme/Layout'; -import { Button } from '@site/src/components/ds'; - -export default function Showcase(): ReactNode { - return ( - -
    -

    Showcase

    -

    - Addons built with @bedrock-core. Ship one and tell us on Discord to be listed here. -

    - -
    -
    - ); -} diff --git a/src/theme/Navbar/MobileSidebar/Header/styles.module.css b/src/theme/Navbar/MobileSidebar/Header/styles.module.css index 89ef75a..4415b0a 100644 --- a/src/theme/Navbar/MobileSidebar/Header/styles.module.css +++ b/src/theme/Navbar/MobileSidebar/Header/styles.module.css @@ -5,7 +5,7 @@ gap: var(--space-2); } .links { grid-column: 2; display: none; justify-self: center; align-items: center; gap: var(--space-2); } -@media (max-width: 600px) { +@media (max-width: 996px) { .links { display: inline-flex; } } .close { diff --git a/src/theme/NavbarItem/ComponentTypes.tsx b/src/theme/NavbarItem/ComponentTypes.tsx index 8b23b15..1d78d26 100644 --- a/src/theme/NavbarItem/ComponentTypes.tsx +++ b/src/theme/NavbarItem/ComponentTypes.tsx @@ -1,7 +1,6 @@ import ComponentTypes from '@theme-original/NavbarItem/ComponentTypes'; import DocsMenu from '../../components/nav/DocsMenu'; import IconLink from '../../components/nav/IconLink'; -import IconNav from '../../components/nav/IconNav'; // Extra navbar item types: `custom-docsMenu` (the package mega-menu) and // `custom-iconLink` (icon-only external links). @@ -9,5 +8,4 @@ export default { ...ComponentTypes, 'custom-docsMenu': DocsMenu, 'custom-iconLink': IconLink, - 'custom-iconNav': IconNav, }; diff --git a/src/theme/TOC/index.tsx b/src/theme/TOC/index.tsx new file mode 100644 index 0000000..a1004fa --- /dev/null +++ b/src/theme/TOC/index.tsx @@ -0,0 +1,19 @@ +import type { ReactNode } from 'react'; +import clsx from 'clsx'; +import TOCItems from '@theme/TOCItems'; +import type { Props } from '@theme/TOC'; +import styles from './styles.module.css'; + +// A custom link class keeps TOCInline and TOCCollapsible out of the highlighter. +const LINK_CLASS_NAME = 'table-of-contents__link toc-highlight'; +const LINK_ACTIVE_CLASS_NAME = 'table-of-contents__link--active'; + +/** The page outline, with a heading over it. */ +export default function TOC({ className, ...props }: Props): ReactNode { + return ( +
    +
    On this page
    + +
    + ); +} diff --git a/src/theme/TOC/styles.module.css b/src/theme/TOC/styles.module.css new file mode 100644 index 0000000..694f45b --- /dev/null +++ b/src/theme/TOC/styles.module.css @@ -0,0 +1,17 @@ +.toc { + max-height: calc(100vh - (var(--ifm-navbar-height) + 2rem)); + overflow-y: auto; + position: sticky; + top: calc(var(--ifm-navbar-height) + 1rem); +} +.title { + padding: 0 0 var(--space-2) calc(var(--space-3) + 1px); + font-family: var(--font-display); + font-size: var(--text-micro); + letter-spacing: var(--tracking-eyebrow); + text-transform: uppercase; + color: var(--text-faint); +} +@media (max-width: 996px) { + .toc { display: none; } +} From 6ab463d23850cb6c10ec072acc23efe6ffcf6461 Mon Sep 17 00:00:00 2001 From: DrAv0011 Date: Tue, 8 Sep 2026 08:28:06 +0200 Subject: [PATCH 15/48] chore: stop tracking the yarn install state Yarn rewrites .yarn/install-state.gz on every install. It is a local cache, so it only produced a dirty file in every diff. Co-Authored-By: Claude Opus 5 (1M context) --- .gitignore | 3 +++ .yarn/install-state.gz | Bin 1442537 -> 0 bytes 2 files changed, 3 insertions(+) delete mode 100644 .yarn/install-state.gz diff --git a/.gitignore b/.gitignore index b083ed4..06ed8a3 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,9 @@ # Dependencies /node_modules +# Yarn writes this on every install; it is a local cache, not a lockfile +.yarn/install-state.gz + # Production /build diff --git a/.yarn/install-state.gz b/.yarn/install-state.gz deleted file mode 100644 index b7de631ca877059375df332bb1bddb7dde5cccdc..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1442537 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

    edFF4E?We|B*TVYvE=_Cv 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�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

    Z3Bc{n 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ĦTWWd(rlc2xXDx=eK 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Öh( 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�t#fisP#x|N@Ejrf8PC9^7&ISZSK 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¨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%0AW|*s`h51M@QgOD-rM+Z23I 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

  • k{xGZ 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

    ZQ!11TDwfU$o~eK@BhrY8r%;AcuppNO+9m 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 MQi5SIs-7xL>rF%ku3Bd>P^!@ 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 Qe(R From 6d713b393973a434f0453b4f00a9db35333c3adf Mon Sep 17 00:00:00 2001 From: DrAv0011 Date: Tue, 8 Sep 2026 08:43:01 +0200 Subject: [PATCH 16/48] docs(bds-runner): describe the run flow, server defaults, world and working directory Co-Authored-By: Claude Fable 5.1 --- docs/bds-runner/cli.md | 23 +++++++++++++++++---- docs/bds-runner/config.md | 42 ++++++++++++++++++++++++++++++++++++--- 2 files changed, 58 insertions(+), 7 deletions(-) diff --git a/docs/bds-runner/cli.md b/docs/bds-runner/cli.md index 22b7a5d..baf837a 100644 --- a/docs/bds-runner/cli.md +++ b/docs/bds-runner/cli.md @@ -1,6 +1,6 @@ --- sidebar_position: 2 -description: "The bc-bds commands, every run option, exit codes and how uncaught script errors are reported." +description: "The bc-bds commands, every run option, what a run does, exit codes and how uncaught script errors are reported." --- # Commands @@ -10,6 +10,8 @@ bc-bds fetch download and cache the server bc-bds where show which build will be used, and from where ``` +`bc-bds fetch` resolves the build and downloads it into the cache without running anything, so a CI job can warm the cache in a separate step. `bc-bds where` prints the selected build, the config file it came from, the cache and server tree paths, the schema path, and the current upstream builds; a pin that is not a published build gets a warning. + ## `run` options | Option | Effect | @@ -27,7 +29,7 @@ bc-bds where show which build will be used, | `--keep-alive` | After the results, keep the server running so you can join it. See [Looking at the plots](#looking-at-the-plots) | | `--offline` | Never download. Fail if the server is not already cached | | `--quiet` | Do not echo server output while the run is in progress | -| `--json ` | Also write the result as JSON: tag, server version, duration, per-test verdicts, regressions, and any infrastructure error | +| `--json ` | Also write the result as JSON: tag, server version, duration, per-test verdicts, regressions, uncaught script errors, and any infrastructure error | ### Build selection options @@ -45,6 +47,17 @@ Either a directory containing `BP/` and optionally `RP/`, which is what Regolith Passing `--packs` more than once installs several addons into the same world. That is how a test which asserts that *another* addon is present can pass. Each pack is copied into the world under a folder named after the addon it came from, so two addons that both export `BP/` do not collide. +## What a run does + +1. Resolves the server build and downloads it into the cache if it is not there. See [Choosing the server build](./config.md#choosing-the-server-build). +2. Copies the cached build into a server tree, one per version, and writes `server.properties` and `config/default/permissions.json` into it. See [Server properties](./config.md#server-properties). +3. On the first run for that tree, boots the server once to generate the world, then turns Beta APIs and the flat generator on in `level.dat`. Every later run is a single boot. +4. Deletes the world's chunks so the tests start on unmodified terrain, copies the packs into the world's `behavior_packs/` and `resource_packs/`, and writes the world pack references. +5. Boots the server, adds a ticking area around the origin so the playerless world simulates, and runs `gametest runset `. +6. Waits until every announced test has a verdict, the server has been quiet for `--idle` seconds, or `--timeout` elapses. Then stops the server and prints the verdicts. + +The full console transcript of every run is written to `.bds/logs/-.log`; the summary prints the path. + ## Looking at the plots A failure message says what the assertion was, not what the world looked like. `--keep-alive` keeps the server up after the results are printed so you can connect a client and see for yourself: @@ -77,11 +90,13 @@ CheckNetIsolation LoopbackExempt -a -n=Microsoft.MinecraftUWP_8wekyb3d8bbwe | --- | --- | | `0` | Every test passed, or the only failures were declared with `--known-failure` | | `1` | Tests failed | -| `2` | The run could not be trusted: no server, no boot, no tests announced, or the tag is unknown | +| `2` | The run could not be trusted: no server, no boot, no tests announced, an unknown tag, an `--expect-registered` mismatch, or an uncaught script error without `--allow-script-errors` | `1` and `2` are distinct so that a broken harness can never look like broken code. -Any test the engine announces but never reports a verdict for is counted as a failure. The run is over when every announced test has a verdict, or when the idle or wall-clock timeout fires. +Any test the engine announces but never reports a verdict for is counted as a failure. A test the engine counted but never placed a plot for, because its structure is missing or the plot could not be placed, is reported as `absent` and also fails the run. The run is over when every announced test has a verdict, or when the idle or wall-clock timeout fires. + +The verdicts come from the engine's own `onTestPassed` and `onTestFailed` console lines and the announced count from its `Running N tests with tag` line. If a newer engine renames those lines the result is exit code `2`, never a pass. Only the most recent `runset` in the console is read, so running the tag again from a held-open server does not mix results. ## Uncaught script errors diff --git a/docs/bds-runner/config.md b/docs/bds-runner/config.md index 3bdaf0e..a44f5c1 100644 --- a/docs/bds-runner/config.md +++ b/docs/bds-runner/config.md @@ -1,6 +1,6 @@ --- sidebar_position: 3 -description: "bds-runner.json, the server properties the runner sets, how a server build is chosen, and the environment variables." +description: "bds-runner.json, the server properties and world the runner sets up, how a build is chosen, the .bds working directory, and the environment variables." --- # Configuration @@ -24,14 +24,37 @@ Add a `bds-runner.json` at or above the directory you run the command from, usua | `channel` | `'stable' \| 'preview'` | `"stable"` | Which release channel `latest` resolves in | | `properties` | `object` | `{}` | Overrides written into `server.properties` before every run. Any key the server documents | -The schema file the `$schema` line points at is written by the runner on its first run. +The schema file the `$schema` line points at is generated from the selected server's own `server.properties`, so every key the build documents is typed and described in the editor, and the five keys the runner owns are marked deprecated. It is rewritten every time a build is resolved (`run`, `fetch`, and `where` once the build is cached), so it always describes the build the next run will use. ## Server properties -The runner sets creative mode, peaceful difficulty, cheats, operator permission, no Xbox Live sign-in, a small view and tick distance, no idle kick, and a raised script watchdog. Anything in `properties` is applied over those, so `"difficulty": "normal"` wins. +`server.properties` is rewritten before every run. Keys the runner does not list keep the value the build ships with. + +| Key | Value | Why | +| --- | --- | --- | +| `gamemode`, `force-gamemode` | `creative`, `true` | Nothing wanders into a plot; a joining player can edit it | +| `difficulty` | `peaceful` | No mob AI competes for ticks | +| `default-player-permission-level` | `operator` | A joining player can run commands | +| `allow-list` | `false` | Anyone on the LAN can join a held-open server | +| `view-distance`, `tick-distance`, `max-threads`, `max-players` | `5`, `4`, `4`, `1` | The tests run in one plot; the rest is wasted simulation | +| `player-idle-timeout` | `0` | A kick mid-run would look like a hang | +| `content-log-file-enabled` | `true` | A second copy of the log on disk, next to the server | +| `script-watchdog-hang-threshold` | `60000` | A long test is not killed by the 10 s default | +| `script-watchdog-enable-shutdown` | `false` | A hung script fails the run instead of taking the server down before it can report | +| `enable-lan-visibility` | `false`, `true` with `--keep-alive` | Advertised on the LAN only when someone is meant to join | + +Anything in `properties` is applied over those, so `"difficulty": "normal"` wins. `enable-lan-visibility` is forced back on by `--keep-alive` whatever the config says. Five keys cannot be overridden because the runner depends on them: `level-name`, `server-port` and `server-portv6` (use `--port`), `allow-cheats`, and `online-mode`. Setting one is an error that names what controls it. +The runner also writes `config/default/permissions.json` so the world's scripts may import `@minecraft/server`, `@minecraft/server-gametest`, `@minecraft/server-ui` and `@minecraft/debug-utilities`, whatever the build's default list says. + +## World + +The world is generated once per server tree, on the first run, and reused after that. `level.dat` carries the two settings the tests need and that `server.properties` cannot express: the Beta APIs experiment, without which `/gametest` does not exist, and a flat generator, which gives every plot a predictable ground plane. Both are written into the generated `level.dat` and read back to verify they stuck. + +Before every run the world's chunks are deleted and `level.dat` is kept, so each run starts on fresh terrain with the experiments still on. `--fresh` deletes the whole server tree instead, which forces a new copy of the build and a new world. + ## Choosing the server build By default the runner uses the newest stable build. For one run: @@ -52,6 +75,19 @@ Precedence, highest first: Build metadata comes from [Bedrock-OSS/BDS-Versions](https://github.com/Bedrock-OSS/BDS-Versions); the download itself comes from minecraft.net and is checked against the published SHA-1. If the index is unreachable the run fails rather than falling back to a build it already has. +## Working directory + +Everything the runner keeps lives under one directory, `/.bds` by default. The project is the directory holding the nearest `bds-runner.json`, else the nearest `package.json` or `.git`, else the working directory. + +| Path | Contents | +| --- | --- | +| `cache///` | The extracted download, one per build. Never run from | +| `server//` | The tree the server runs in: a copy of the cache plus the generated `server.properties` and world. Kept between runs | +| `logs/` | One console transcript per run, and a `.bootstrap` log for the world-generating boot | +| `schema/bds-runner.json` | The JSON Schema for the config file | + +Symlinks need elevation on Windows, so the server tree is a copy. With `BC_BDS_PATH` the tree is named after the directory the variable points at. + ## Environment variables | Variable | Effect | From 00ceef7f576e996404d721841accd91a39390568 Mon Sep 17 00:00:00 2001 From: DrAv0011 Date: Wed, 9 Sep 2026 01:03:58 +0200 Subject: [PATCH 17/48] docs(server): core.shared as it is, and no core.state MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The shared page still documented `open()`, `persisted()`, `leaf()`, branches and `patch`; the mirror is now a flat record, one observable per key, owner-writes-only and storing nothing — a value that must survive a restart is a db document mapped onto a key. `core.state` is removed, so its section, its row in the runtime table and the two RPC examples reading through it go with it. Co-Authored-By: Claude Opus 5 (1M context) --- docs/server/api/runtime.md | 3 +- docs/server/api/shared.md | 57 +++++++++++++++++-------------------- docs/server/installation.md | 12 ++++---- docs/sync/rpc.md | 6 +--- docs/sync/state.md | 4 +-- 5 files changed, 36 insertions(+), 46 deletions(-) diff --git a/docs/server/api/runtime.md b/docs/server/api/runtime.md index 24c80cf..ca29455 100644 --- a/docs/server/api/runtime.md +++ b/docs/server/api/runtime.md @@ -40,7 +40,6 @@ Every accessor below throws `runtime. is unavailable: call register() firs | `core.features` | [`FeatureManager`](./features.md) | Condition-driven togglable behavior. | | `core.host` | [`HostElection`](./host.md) | Which realm does the work only one realm may do. | | `core.shared` | [`SharedRegistry`](./shared.md) | The replicated mirror as typed trees: `of(ns)` for a peer's, `own` for this addon's. | -| `core.state` | `ScopedState` | Deprecated string-keyed access to this addon's namespace; declare `shared` in `register()` instead. | | `core.config` | [`ConfigRegistry`](./config.md) | Schema, scopes and cross-addon config access. | | `core.translations` | [`TranslationsRegistry`](./translations.md) | Cross-addon i18n bundles. | | `core.guides` | [`GuidesRegistry`](./guides.md) | Cross-addon compiled guides. | @@ -222,7 +221,7 @@ import { RUNTIME_VERSION, compareVersions } from '@bedrock-core/server-runtime'; | [Registry](./registry.md) | Enumerate peers, resolve dependencies, detect namespace collisions | | [FeatureManager](./features.md) | Behavior that toggles on a condition over registry and state | | [HostElection](./host.md) | `core.host` — deterministic "who does the shared work" | -| [Shared](./shared.md) | The replicated mirror as typed trees, owner-only writes, `open()` and `persisted()` | +| [Shared](./shared.md) | The replicated mirror as typed trees, one value per key, owner-only writes | | [ConfigRegistry](./config.md) | Schema, three scopes, persistence, cross-addon access, authorization | | [TranslationsRegistry](./translations.md) | Publish and resolve i18n bundles across addons | | [GuidesRegistry](./guides.md) | Publish and read compiled guide manifests across addons | diff --git a/docs/server/api/shared.md b/docs/server/api/shared.md index 285d75c..e62188c 100644 --- a/docs/server/api/shared.md +++ b/docs/server/api/shared.md @@ -5,32 +5,30 @@ description: "core.shared is the replicated mirror every realm holds, as typed t # core.shared -`core.shared` is the replicated mirror every realm holds, as typed trees. An addon declares a shape once, in `register()`, and gets a tree back whose every node reads, writes and subscribes; every other realm mirrors it and reads it through `core.shared.of()`. Reads are local and synchronous. Writes broadcast a delta over sync's [`State`](/docs/sync/state). +`core.shared` is the replicated mirror every realm holds, as typed trees. An addon declares a flat shape once, in `register()`, and gets a tree back whose every key reads, writes and subscribes; every other realm mirrors it and reads it through `core.shared.of()`. Reads are local and synchronous. Writes broadcast a delta over sync's [`State`](/docs/sync/state). -Two rules make it safe to build on: +The mirror does exactly one job: **the owner sets a value, every realm can read it now, and is told when it changes.** Two rules follow from it: -1. **Only the owner writes.** A mirror applies a change to a namespace only from the addon that owns it, unless the owner marked the leaf `open()`. -2. **`persisted()` survives restarts.** The owner writes those leaves to the world on change and restores them on boot; nobody else has to. +1. **Only the owner writes.** A mirror applies a change to a namespace only from the addon that owns it. A peer that wants a change asks over [RPC](/docs/sync/rpc). +2. **Nothing is stored.** The mirror never touches the world. A value that must survive a restart is a `@bedrock-core/db` document the owner maps onto a key. ## Import ```ts -import { core, open, persisted, leaf } from '@bedrock-core/server-runtime'; -import type { SharedTree, PeerSharedTree } from '@bedrock-core/server-runtime'; +import { core } from '@bedrock-core/server'; +import type { SharedTree, PeerSharedTree } from '@bedrock-core/server'; ``` ## Declare -Values are leaves, plain objects are branches, and three markers change how a leaf or a whole branch behaves: +A declaration is a flat record. Every top-level key is one value, and an object is one value too — replicated whole on every write. ```ts export const sharedDef = { currency: 'gold', spawnRate: 5, - tags: ['pvp', 'events'], // an array is one leaf - votes: open(0), // any realm may write it - event: persisted({ name: 'none', active: false }), // both leaves survive restarts - palette: leaf({ fg: '#fff', bg: '#000' }), // one object under one key, not a branch + tags: ['pvp', 'events'], + event: { name: 'none', active: false }, // one object under one key, written whole }; /** Export the type: a peer gets the typed tree from `core.shared.of()`. */ @@ -43,9 +41,9 @@ const { shared } = core.register({ }); ``` -`register()` returns the typed accessors of what was declared, one key each: `config` (the scope accessors, the same value `core.config.define()` returns) and `shared` (the tree). Markers nest (`persisted(open(0))`) and a marker on a branch applies to every leaf under it. Nested keys become dotted mirror keys (`event.active`), which is what a raw `core.node.state.get(ns, 'event.active')` sees. +`register()` returns the typed accessors of what was declared, one key each: `config` (the scope accessors, the same value `core.config.define()` returns) and `shared` (the tree). -A branch cannot have a child named `get`, `set`, `patch` or `subscribe`, and keys cannot contain a dot; `register()` throws on either. +A key may not begin `core-`, which is the framework's own announcement prefix; `register()` throws if one does. ## Use your own tree @@ -55,15 +53,13 @@ shared.currency.set('emerald'); // written to the mirror, broadcas shared.event.get(); // { name: 'none', active: false } shared.event.set({ name: 'race', active: true }); -shared.event.patch({ active: false }); // only the leaves given, at any depth -shared.patch({ event: { name: 'quiet' } }); -shared.currency.subscribe(kind => hud.setCurrency(kind)); // a leaf -shared.event.subscribe(event => …); // a branch — any leaf under it -shared.subscribe(all => …); // the whole namespace +shared.currency.subscribe((next, prev) => hud.setCurrency(next)); ``` -Every node has `get` and `subscribe`, so a leaf is a `ReadonlyObservable` for `@bedrock-core/observable`: `computed(() => …, [shared.spawnRate])`, `effect(…, [shared.event.active])` and `toNative(shared.spawnRate)` take it as it is. +Every key has `get` and `subscribe`, so it is a `ReadonlyObservable` for `@bedrock-core/observable`: `computed(() => …, [shared.spawnRate])`, `effect(…, [shared.event])` and `toNative(shared.spawnRate)` take it as it is. The backend subscription is attached with the first listener and released with the last, so a tree nobody watches costs nothing per change. + +The owner's tree falls back to the declared value while the mirror holds none, so it answers correctly before its first write lands. The tree is also reachable later as `core.shared.own`, untyped. @@ -76,26 +72,29 @@ const economy = core.shared.of('drav0011_economy'); // undefine economy?.currency.get(); // string | undefined economy?.event.subscribe(event => …); -economy?.votes.set(1); // only because the owner said open(); a compile error on any other leaf ``` -`of()` materializes the tree from the shape the owner announced under `core-shared/shape` when it registered; the type argument is the compile-time view over it, the same arrangement as `core.config.of()`. A peer's leaf reads `undefined` while its value has not arrived yet, and a peer's branch has no `set`. +`of()` materializes the tree from the key names the owner announced under `core-shared/shape` when it registered; the type argument is the compile-time view over it, the same arrangement as `core.config.of()`. A peer's key reads `undefined` while its value has not arrived — a peer never knows what the owner declared — and a peer's tree has no `set` at all, in the type and at runtime. Peers that only have the namespace, not the type, still get an untyped tree from `core.shared.of(ns)`. ## Who may write -The transport is last-write-wins, which is right for a mirror and wrong for data two realms disagree about. So the mirror applies an entry for a namespace only when it came from the namespace's owner — the addon whose id it is. A write from anyone else is dropped and counted in `core.node.state.droppedForeign`. +The transport is last-write-wins, which is right for a mirror and wrong for data two realms disagree about. So the mirror applies an entry for a namespace only when it came from the namespace's owner — the sending node for a delta, the recorded writer for a snapshot entry, so a snapshot relayed by a third party still names the original writer. A write from anyone else is dropped and counted in `core.node.state.droppedForeign`. -`open()` is the exception, declared by the owner: a mirror takes anyone's write for those leaves, last write wins, and the flag itself can only be set or cleared by the owner. Use it for the counter, the vote, the thing that genuinely has many writers. +The local mirror applies the same rule to its own writes, so a foreign write is visible locally exactly when it is visible everywhere, which is never. This is robustness against a buggy peer, not security: a pack can forge its id, and script events carry no sender identity. -## Persistence +## Persisting a shared value + +The mirror is not storage. When a value has to survive a restart, the owner keeps it in a `@bedrock-core/db` document and maps it across in one line: -`persisted()` leaves are written to the world as JSON on every change, under `core-shared::`, and written back into the mirror one tick after registration — dynamic properties are not readable before the first tick. Until then the owner's own tree answers with the declared value. Nothing else is saved: a leaf without the marker starts at its declared value on every boot. +```ts +settings.for(world).subscribe(doc => shared.event.set(doc.event)); +``` -A dynamic property string caps at 32 767 characters and throws past it. A persisted shared value is a small value by construction; documents belong in `@bedrock-core/db`. +A document's subscriber hears the document load, so that line is correct at boot as well as on every later change. ## Reserved keys @@ -108,14 +107,10 @@ Your namespace carries more than you put there. The framework replicates its own | `core-guide/manifest`, `core-guide/reference` | [GuidesRegistry](./guides.md) — the guide | | `core-addon/page` | PagesRegistry — the addon's page in the shared list | | `core-feature/` | [FeatureManager](./features.md) — one boolean per declared feature | -| `core-shared/shape` | the shared registry — every leaf path, and which are open | +| `core-shared/shape` | the shared registry — the owner's key names | The shared tree never sees them. To reach the raw namespace, framework keys included, use `core.node.state`: ```ts core.node.state.get(core.id, 'core-config/schema'); ``` - -## `core.state` - -The string-keyed `core.state` (`set` / `get` / `delete` / `getNamespace` / `subscribe` on this addon's namespace, framework keys hidden) is deprecated: a leaf of the tree covers each of its calls, and `persisted()` in the declaration replaces subscribing to save. It is removed in a later minor. diff --git a/docs/server/installation.md b/docs/server/installation.md index 61ea599..eb8c59a 100644 --- a/docs/server/installation.md +++ b/docs/server/installation.md @@ -123,12 +123,12 @@ const { config } = core.register({ // ─── Serve RPC ─────────────────────────────────────────────────────────────── -core.rpc.serve({ - getBalance: ({ player }) => { - const balance = core.state.get(`balance.${player}`); +// Whatever this addon keeps balances in — a plain map here; `@bedrock-core/db` +// when they have to survive a restart. +const balances = new Map(); - return typeof balance === 'number' ? balance : 0; - }, +core.rpc.serve({ + getBalance: ({ player }) => balances.get(player) ?? 0, }); // ─── React to config changes ───────────────────────────────────────────────── @@ -150,7 +150,7 @@ world.afterEvents.playerSpawn.subscribe(({ player, initialSpawn }) => { :::caution Dynamic properties are unreadable during early execution Anything that touches `world.getDynamicProperty` / `setDynamicProperty` — including your own persistence — must be deferred with `system.run()`. The runtime already does this for config: persisted values load one tick after registration, and change listeners fire for every key whose stored value differs from its default, so a subscriber attached right after `register()` still ends up seeing the real values. -Nothing in the shared mirror survives a reload unless the leaf is declared `persisted()` — see [Persistence](./api/shared.md#persistence). +Nothing in the shared mirror survives a reload: it is not storage. A shared value that must come back is a db document the owner maps onto a key — see [Persisting a shared value](./api/shared.md#persisting-a-shared-value). ::: ## Getting two addons talking diff --git a/docs/sync/rpc.md b/docs/sync/rpc.md index eb2394c..973ce96 100644 --- a/docs/sync/rpc.md +++ b/docs/sync/rpc.md @@ -72,11 +72,7 @@ export interface EconomyRPC { } core.rpc.serve({ - getBalance: ({ player }) => { - const balance = core.state.get(`balance.${player}`); - - return typeof balance === 'number' ? balance : 0; - }, + getBalance: ({ player }) => balances.get(player) ?? 0, transfer: ({ from, to, amount }) => moveFunds(from, to, amount), }); ``` diff --git a/docs/sync/state.md b/docs/sync/state.md index 6e0cf2d..7cb42de 100644 --- a/docs/sync/state.md +++ b/docs/sync/state.md @@ -201,7 +201,7 @@ By default **writes are open** — any node may write any namespace. With `stric [sync] cannot write to namespace 'drav0011_economy': not owned by this node (strictOwnership is enabled) ``` -The runtime creates its node with `ownedNamespaces: [namespace]` and leaves `strictOwnership` at its default, so `core.node.state` can still write anywhere. `core.state` narrows that by construction — it only ever addresses your own namespace. +The runtime creates its node with `ownedNamespaces: [namespace]` and leaves `strictOwnership` at its default, so `core.node.state` can still write anywhere. [`core.shared`](/docs/server/api/shared) narrows that by construction — its trees only ever address your own namespace, and a peer's tree has no `set`. :::note Ownership is a convention, not a security boundary `strictOwnership` guards *your* node against writing where it should not. It cannot stop another pack from writing your namespace — every addon in a world runs arbitrary script. Treat state as shared and cooperative; put anything that needs an authority check behind [RPC](./rpc.md), the way [config](/docs/server/api/config#authorization) does. @@ -234,4 +234,4 @@ system.run(() => { }); ``` -From an addon, `persisted()` on a [shared](/docs/server/api/shared#persistence) leaf does this per key, which is what you want once a namespace can grow past a dynamic property's 32767-character ceiling. +From an addon, `@bedrock-core/db` does this per document, on whatever dynamic property the target itself can hold — which is what you want once a namespace can grow past one property's 32767-character ceiling. A [shared](/docs/server/api/shared) key that must survive a restart is one such document, mirrored across in a line. From af2cc882ac1cca12fb1e830f8f72af8557de6bb1 Mon Sep 17 00:00:00 2001 From: DrAv0011 Date: Wed, 9 Sep 2026 05:57:23 +0200 Subject: [PATCH 18/48] docs(server): server, sync, db and observable as they are Server: config as three db collections with the nine core:config methods, translations and guides as announcements, and new pages for events, db, pages, Announcement and authorize; guides for the three channels and the trust model. Sync: the events subsystem. New sections for db (overview, collections, schema, targets, resolver) and observable (one page per export), both promoted from planned. Every import reads from the public package name. The section switcher drops the scope prefix. Co-Authored-By: Claude Fable 5.1 --- .gitignore | 2 + docs/db/collection.md | 139 +++++++++++++++ docs/db/index.md | 81 +++++++++ docs/db/resolver.md | 80 +++++++++ docs/db/schema.md | 75 ++++++++ docs/db/targets.md | 114 ++++++++++++ docs/observable/batch.md | 74 ++++++++ docs/observable/computed.md | 82 +++++++++ docs/observable/effect.md | 69 ++++++++ docs/observable/index.md | 70 ++++++++ docs/observable/last.md | 84 +++++++++ docs/observable/observable.md | 91 ++++++++++ docs/observable/toNative.md | 83 +++++++++ docs/server/api/announcement.md | 53 ++++++ docs/server/api/authorize.md | 92 ++++++++++ docs/server/api/config.md | 233 +++++++++---------------- docs/server/api/db.md | 82 +++++++++ docs/server/api/events.md | 116 ++++++++++++ docs/server/api/features.md | 36 ++-- docs/server/api/guides.md | 113 ++++-------- docs/server/api/host.md | 23 +-- docs/server/api/pages.md | 49 ++++++ docs/server/api/registry.md | 4 +- docs/server/api/runtime.md | 77 ++++---- docs/server/api/shared.md | 26 ++- docs/server/api/translations.md | 58 +++--- docs/server/guides/channels.md | 97 ++++++++++ docs/server/guides/trust-model.md | 62 +++++++ docs/server/guides/ui-integration.md | 10 +- docs/server/index.md | 24 +-- docs/server/installation.md | 39 +++-- docs/sync/events.md | 61 +++++++ docs/sync/index.md | 9 +- docs/sync/protocol.md | 2 +- docs/sync/rpc.md | 2 +- src/components/nav/SectionSwitcher.tsx | 5 +- src/components/nav/switcher.module.css | 1 - src/data/sections.ts | 4 +- 38 files changed, 1948 insertions(+), 374 deletions(-) create mode 100644 docs/db/collection.md create mode 100644 docs/db/index.md create mode 100644 docs/db/resolver.md create mode 100644 docs/db/schema.md create mode 100644 docs/db/targets.md create mode 100644 docs/observable/batch.md create mode 100644 docs/observable/computed.md create mode 100644 docs/observable/effect.md create mode 100644 docs/observable/index.md create mode 100644 docs/observable/last.md create mode 100644 docs/observable/observable.md create mode 100644 docs/observable/toNative.md create mode 100644 docs/server/api/announcement.md create mode 100644 docs/server/api/authorize.md create mode 100644 docs/server/api/db.md create mode 100644 docs/server/api/events.md create mode 100644 docs/server/api/pages.md create mode 100644 docs/server/guides/channels.md create mode 100644 docs/server/guides/trust-model.md create mode 100644 docs/sync/events.md diff --git a/.gitignore b/.gitignore index 06ed8a3..0dcc78c 100644 --- a/.gitignore +++ b/.gitignore @@ -22,3 +22,5 @@ npm-debug.log* yarn-debug.log* yarn-error.log* + +TODO \ No newline at end of file diff --git a/docs/db/collection.md b/docs/db/collection.md new file mode 100644 index 0000000..df6c2ab --- /dev/null +++ b/docs/db/collection.md @@ -0,0 +1,139 @@ +--- +sidebar_position: 2 +description: "A collection names a document type and which targets hold one; a document handle is an observable over one target's bytes." +--- + +# Collections + +A collection names a document type and which targets hold one. `for(target)` hands back a document handle: an [observable](/docs/observable) over that one target's bytes, with `get`, `set`, `patch`, `delete` and `subscribe`. + +## Import + +```ts +import { createEngineDb } from '@bedrock-core/db/minecraft'; +import type { Db, Collection, CollectionOptions, Document, IndexedDocument, Where } from '@bedrock-core/db'; +``` + +From an addon, [`core.db`](/docs/server/api/db) is the `Db`. + +## `db.collection` + +```ts +db.collection( + name: string, + options: CollectionOptions, +): Collection +``` + +| Option | Type | Default | Description | +|---|---|---|---| +| `schema` | `Schema` | — | The document type — see [schema](./schema.md) | +| `accept` | `Acceptor` | any storable target | Which targets `for()` takes — see [targets](./targets.md) | +| `require` | `Requirements` | `{}` | Capabilities the host must have: `own`, `enumerable`, `readableWhenUnloaded` | +| `coalesce` | `boolean` | `false` | Write-behind: one property write per dirty document per tick | + +The document type comes from `schema()`; `collection` takes no type argument. + +```ts +const balances = db.collection('balances', { + schema: schema<{ gold: number }>({ defaults: { gold: 0 } }), + accept: players(), +}); +``` + +### `coalesce` + +With `coalesce: true` a write marks the document dirty and one property write per dirty document happens at the end of the tick. Offered on the world and on entities only — a block or slot document could die with its target before the flush, so those targets are refused with a reason. An entity that unloads before the flush has its document parked and written on `entityLoad`; a leaving player is flushed in `beforeEvents.playerLeave`. `db.flush(target?)` writes now. + +## `Collection` + +| Member | Signature | Description | +|---|---|---| +| `name` | `string` | The collection's name | +| `for` | `(target: Target) => Document` | The handle for one target's document | +| `where` | `(target: Target) => Where` | Whether this collection would store on `target`, and with which capabilities, without touching it | +| `forget` | `(target: Target) => void` | Drop what the collection remembers about a target — its cached document and subscribers | +| `all` | `() => IterableIterator>` | Every target known to hold a document, lazily, from the index | +| `at` | `(kind: TargetKind, identity: string) => IndexedDocument \| undefined` | The document for one indexed identity, without holding the target | +| `size` | `number` | How many documents the index knows of | + +```ts +type Where + = { ok: true; kind: TargetKind; caps: Capabilities } + | { ok: false; kind: TargetKind; reason: string }; +``` + +### `all` + +`all()` iterates the collection's index, kept in chunked world properties and updated on a document's first write, on `delete`, and by [`blockCleanup`](./targets.md#blocks) when a block breaks; a block found replaced by another type is removed from it. The iterator is resumable, so a sweep can take a few per tick: + +```ts +for (const doc of elevators.all()) { + if (!doc.available) { continue; } // unloaded chunk, removed entity + + doc.patch({ configured: false }); +} +``` + +A target that cannot be reached right now is still yielded, with `available` false — or readable, when its document lives on the world. Slots are never indexed. + +### `at` + +What a remote caller has, since a `Block` or an `Entity` cannot travel over the wire: + +```ts +const doc = elevators.at('block', 'overworld:10,64,-3:papi:elevator'); +``` + +## `Document` + +| Member | Signature | Description | +|---|---|---| +| `available` | `boolean` | Whether the target can be reached and the collection accepts it right now | +| `reason` | `string \| undefined` | Why `available` is false | +| `get` | `() => T \| undefined` | The document with its defaults filled, `undefined` when there is none or the target cannot be reached | +| `set` | `(doc: T) => void` | Store `doc` as it is, after the schema's `normalize` | +| `patch` | `(changes: DeepPartial) => void` | Merge into the stored document, deep | +| `delete` | `() => void` | Remove the document; never throws | +| `subscribe` | `(listener: (doc: T \| undefined, prev: T \| undefined) => void) => Unsubscribe` | Local change events for this document | + +An `IndexedDocument` — what `all()` and `at()` yield — adds `kind: TargetKind` and `identity: string`. + +### `patch` + +A nested object merges key by key, an array replaces the one there, and `undefined` deletes a key — which puts it back to its default. What is stored is exactly what was written, after `normalize`. + +```ts +balances.for(player).patch({ gold: 10 }); // one key +settings.for(world).patch({ event: { active: false } }); // deep +settings.for(world).patch({ event: undefined }); // back to the default +``` + +### `subscribe` + +Fires with the new document, or `undefined` on delete, and the one before it. A listener attached before the document was first read hears it load, which is what makes this correct at boot as well as on every later change: + +```ts +settings.for(world).subscribe(doc => shared.event.set(doc?.event ?? defaults.event)); +``` + +`get` and `subscribe` together are a `ReadonlyObservable`, so a document can be [`computed`](/docs/observable/computed) over or handed to a UI hook directly. + +## `Db` + +| Member | Signature | Description | +|---|---|---| +| `collection` | see above | Declare a collection | +| `find` | `(name: string) => Collection \| undefined` | A collection by name, untyped | +| `flush` | `(target?: unknown) => void` | Write every coalesced document now, or one target's | +| `blockRemoved` | `(dimensionId, location, typeId) => void` | Tell every collection a block is gone; what `blockCleanup` calls | +| `resolver` | `Resolver` | The [host resolver](./resolver.md) | + +`createEngineDb(namespace, log?)` from `@bedrock-core/db/minecraft` builds one over the world, with the engine's classifier and locator and the lifecycle hooks for `entityLoad` and `playerLeave` wired only when a coalescing collection exists. The `namespace` prefixes every property key, so two packs never meet. + +## Notes + +- **Every operation re-resolves the target**, at most once per tick. A handle from `for()` keeps an identity, not the object: `get()` is `undefined` and `set()` throws `DbTargetError` once an entity is removed, a slot empties, or a block's chunk unloads — except a proxied document (dimension, vanilla block), which lives on the world and stays reachable. +- **Hold a handle when hammering one target.** `for()` is cheap, but the handle resolves its target once per tick and caches the parsed document. +- **A document that cannot be read** — bytes that are not the envelope, a migration that throws — is quarantined under `#bad`, logged, and reads as `undefined`. Nothing is deleted. +- **Budget.** A block entity holds about 950 bytes per pack; a document past it throws `DbBudgetError` naming the collection before the engine sees the write. On the world, entities and slots a document past 32 767 characters is chunked into `#0..n` transparently. diff --git a/docs/db/index.md b/docs/db/index.md new file mode 100644 index 0000000..df61cc3 --- /dev/null +++ b/docs/db/index.md @@ -0,0 +1,81 @@ +--- +slug: / +sidebar_position: 1 +sidebar_label: Overview +description: "@bedrock-core/db is persisted documents on dynamic properties: typed collections keyed by target, on whatever properties the target itself can hold." +--- + +# db + +`@bedrock-core/db` is persisted documents on dynamic properties: typed collections keyed by target, stored on whatever dynamic properties the target itself can hold. + +:::caution Pre-1.0 +`@bedrock-core/db` is under active development. Breaking changes can still land until `1.0.0` — pin exact versions and read the release notes before upgrading. +::: + +## What is @bedrock-core/db? + +The engine offers two ABIs for dynamic properties — six methods on the world, entities and container slots; three on a block entity's component — and nothing at all on a dimension or a vanilla block. This package puts one adapter over all of it: a [resolver](./resolver.md) that decides, per target, where a document can live, and typed [collections](./collection.md) on top, each document one JSON string with its version travelling in the bytes. + +A collection is local to the addon that declared it, and a document handle is an [observable](/docs/observable). + +From an addon, [`core.db`](/docs/server/api/db) is an instance of this keyed under the addon's namespace; this section is the package underneath. + +## Install + + + +`@minecraft/server` (`>=2.8.0`) is a peer dependency; block entities need `2.10.0` (Minecraft 1.26.50). + +Through the meta package the declaration API is on `@bedrock-core/server` and the rest at `@bedrock-core/server/db`. + +## Usage + +```ts +import { createEngineDb } from '@bedrock-core/db/minecraft'; +import { blockTypes, schema } from '@bedrock-core/db'; + +const db = createEngineDb('drav0011_economy'); + +// No acceptor: any storable target. The schema names the document type. +const balances = db.collection('balances', { schema: schema<{ gold: number; lastSeen: number }>() }); + +balances.for(player).get(); // undefined until written; cached after the first read +balances.for(player).patch({ gold: 10 }); // written through, one dynamic property; merges deep +balances.for(player).subscribe(doc => hud.refresh(doc)); + +// With an acceptor `for()` only takes a Block, and `require` is checked against what a Block can do. +const elevators = db.collection('elevators', { + schema: schema({ + version: 3, + defaults: { configured: false, facing: 'north' }, + migrate: { + 2: doc => ({ ...doc, facing: doc.facingDirection ?? 'north' }), + 3: ({ legacyMode: _, ...rest }) => rest, + }, + }), + accept: blockTypes('papi:elevator'), + require: { own: true }, // refuse a vanilla block instead of storing on the world +}); + +elevators.for(block).set({ configured: true, facing: 'east' }); +elevators.where(stone); // { ok: false, reason: "minecraft:stone is not accepted by 'elevators'" } +``` + +## What you get + +- **One JSON string per document**, `{"v":3,"d":{…}}` — the version travels with the bytes, so an old document is migrated lazily on first read, step by step, and rewritten once. Nothing has to be migrated at boot. +- **Deep semantics** — `patch` merges plain objects key by key, replaces arrays and scalars, and deletes on `undefined`; `defaults` fill at every depth on read and are never stored; `normalize` runs over every write, the place to clamp a value or drop one that should not be kept. +- **A subscriber hears the load** — attached before the first read, it fires when the document is read a tick later, so subscribing at registration works. +- **Quarantine, never deletion** — a document that cannot be read is moved under `#bad` and logged, so a bad write cannot destroy a player's data. +- **Budget checked before the engine sees it** — a block entity holds about 950 bytes per pack and more throws `DbBudgetError` naming the collection; on the world, entities and slots a document past 32 767 characters is chunked transparently. +- **`all()` iterates every document from an index** — resumable, so a sweep can take a few per tick, and healed when a block is found replaced. +- **A validity gate on every operation** — a handle keeps an identity, not the object: `get()` is `undefined` and `set()` throws `DbTargetError` once an entity is removed, a slot empties or a chunk unloads, so a stale handle cannot write into the void. +- **Compile-time target checks** — an acceptor narrows what `for()` takes, and a `require` the target type can never satisfy is a type error naming the missing capability. + +## Next steps + +- [Collections](./collection.md) — `collection`, `for`, `where`, `all`, and the document handle +- [Schema](./schema.md) — `schema()`, versions, migrations, defaults and `normalize` +- [Targets](./targets.md) — the acceptors, `require`, and what each kind of target can hold +- [Resolver](./resolver.md) — where a document lives and why diff --git a/docs/db/resolver.md b/docs/db/resolver.md new file mode 100644 index 0000000..ca01530 --- /dev/null +++ b/docs/db/resolver.md @@ -0,0 +1,80 @@ +--- +sidebar_position: 5 +description: "The resolver probes a target once per type for where its documents can live, and hands back a host with its capabilities or a refusal with its reason." +--- + +# Resolver + +The resolver decides, per target, where a document can live: on the target's own dynamic properties through one of the engine's two ABIs, or on a world property keyed by the target's identity when it has none — or nowhere, with a reason. + +Nothing is declared. A target is probed once **per type** — a block type either has a `minecraft:block_entity` or it does not, an item type is either stackable or not — and the decision is cached; a throw (a block in an unloaded chunk) is never cached. + +## Import + +```ts +import { createEngineResolver } from '@bedrock-core/db/minecraft'; +import type { Resolver, Resolution, Accepted, Refused, Capabilities, TargetKind } from '@bedrock-core/db'; +``` + +A `Db` carries its resolver as `db.resolver`; a collection asks it on every operation. + +## Usage + +```ts +const resolver = createEngineResolver('drav0011_economy'); +const resolution = resolver.resolve(block); + +if (resolution.ok) { + resolution.host.caps; // { own, enumerable, budget, readableWhenUnloaded, batch } + resolution.host.write('doc', json); +} else { + resolution.reason; // e.g. "a stackable item (minecraft:stone) cannot hold dynamic properties" +} +``` + +## `Resolver` + +| Member | Signature | Description | +|---|---|---| +| `resolve` | `(target: unknown) => Resolution` | Where this target's documents live, probing its type on first sight | +| `decision` | `(typeKey: string) => 'direct' \| 'component' \| 'proxied' \| undefined` | The cached decision for a type, or `undefined` before it was probed | +| `absent` | `(kind: TargetKind, typeId: string, identity: string) => Accepted \| undefined` | A host for an identity whose target is not in hand — a proxied document reachable while the target is unloaded | + +```ts +type Resolution = Accepted | Refused; + +interface Accepted { ok: true; kind: TargetKind; typeId: string; typeKey: string; identity: string; host: DpHost } +interface Refused { ok: false; kind: TargetKind; reason: string } +``` + +## Hosts + +| Target | Host | Why | +|---|---|---| +| `World`, `Entity`, `Player` | `own`, direct ABI | six methods, 32 767 characters per value | +| `ContainerSlot` with a non-stackable item | `own`, direct ABI | the slot is the item's place; a stackable item refuses properties | +| block whose type declares `minecraft:block_entity` | `own`, component ABI | about 950 bytes per block, dies with the block | +| `Dimension`, vanilla block | `proxied` | a world property keyed by the target's identity | +| `ItemStack` | **refused** | a detached copy — the write never reaches the world | + +A host's `caps` say what a collection may [`require`](./targets.md#require): + +```ts +interface Capabilities { + readonly own: boolean; // the target holds the bytes itself + readonly enumerable: boolean; // the host can list its keys + readonly budget: number; // characters per value before the engine throws + readonly readableWhenUnloaded: boolean; // the bytes are on the world, reachable without the target + readonly batch: boolean; // several keys can be written in one call +} +``` + +## Without the engine + +The main entry is structural and runs without `@minecraft/server`: `createResolver({ world, namespace, classify })` takes any `DirectDp` as the world and a `Classifier` that maps a target to its kind, which is how the package's own tests run in vitest. `@bedrock-core/db/minecraft` supplies the engine's `instanceof` classifier, the locator that finds an entity by id and a block by location again, and the world. + +## Notes + +- **Identity, not object.** An `Accepted` carries an `identity` — an entity id, `:,,:` for a block, a dimension id — which is what the index keeps and what a handle re-resolves from. +- **A refusal names its reason**, so `where()` can show it and a collection's `for()` can throw it. +- The `namespace` prefixes every property key the resolver hands out, so two packs' documents on one target never meet. diff --git a/docs/db/schema.md b/docs/db/schema.md new file mode 100644 index 0000000..c2bf2aa --- /dev/null +++ b/docs/db/schema.md @@ -0,0 +1,75 @@ +--- +sidebar_position: 3 +description: "schema names a collection's document type and carries its version, defaults, migration steps and normalize." +--- + +# schema + +`schema()` names a collection's document type and carries its version, its defaults, the migration steps between versions, and a `normalize` that runs over every write. + +## Import + +```ts +import { schema } from '@bedrock-core/db'; +import type { Schema, DocumentSchema, MigrateStep, DeepPartial } from '@bedrock-core/db'; +``` + +Also re-exported from `@bedrock-core/server`. + +## Signature + +```ts +schema(definition?: DocumentSchema): Schema +``` + +## Parameters + +| Option | Type | Default | Description | +|---|---|---|---| +| `version` | `number` | `1` | The version documents are stored at | +| `defaults` | `DeepPartial` | — | Filled on read, at every depth, and never stored | +| `migrate` | `Record` | — | A step per version, keyed by the version it produces | +| `normalize` | `(doc: T) => T` | — | Runs over every write; what it returns is what is stored | + +```ts +type MigrateStep = (doc: Record) => Record; +``` + +## Returns + +A `Schema` — the definition, branded with the document type so a collection infers `T` from it. + +## Usage + +```ts +interface ElevatorDoc { configured: boolean; facing: 'north' | 'east' | 'south' | 'west'; floors: number[] } + +const elevatorSchema = schema({ + version: 3, + defaults: { configured: false, facing: 'north', floors: [] }, + migrate: { + 2: doc => ({ ...doc, facing: doc.facingDirection ?? 'north' }), + 3: ({ legacyMode: _, ...rest }) => rest, + }, + normalize: doc => ({ ...doc, floors: doc.floors.slice(0, 16) }), +}); +``` + +## Versions and migrations + +Every document is stored as `{"v":,"d":{…}}`. The version travels with the bytes, so a document written at version 1 and read by a version-3 schema runs the step for `2`, then the step for `3`, and is rewritten once at 3. Migration is **lazy and per document**: a player who joins two versions late migrates as they load, and nothing sweeps the world at boot. + +A step takes the stored document as the previous version wrote it — overrides only, defaults not filled — and returns the next shape. A step that throws quarantines that one document under `#bad` rather than failing the read. + +## Defaults + +`defaults` fill missing keys on read, at every depth, and are never stored: a document holding `{ facing: 'east' }` reads as `{ configured: false, facing: 'east', floors: [] }`, and its bytes stay one key. A `patch` that sets a key to `undefined` deletes it, which puts it back to its default. + +## `normalize` + +`normalize` runs over the merged document on every write — `set`, `patch`, a write a peer's RPC handler makes — and what it returns is what is stored. It is the one place to clamp a value, drop one that should not be kept, or keep what is at a default out of the bytes; config's schema uses it to coerce every value to its entry and store only what differs from the default. + +## Notes + +- The document type comes from `schema()`; `collection` takes no type argument. +- Deep semantics — merge, fill, delete on `undefined` — treat plain objects as structure and everything else, arrays included, as a value. diff --git a/docs/db/targets.md b/docs/db/targets.md new file mode 100644 index 0000000..16ed032 --- /dev/null +++ b/docs/db/targets.md @@ -0,0 +1,114 @@ +--- +sidebar_position: 4 +description: "Acceptors say which targets a collection takes, checked in the IDE and at runtime; require says what the host must be able to do." +--- + +# Targets + +An acceptor says which targets a collection takes, and `require` says what their host must be able to do. Both are checked twice: at compile time against the target type, and at runtime per target type, cached beside the resolver's decision. + +## Import + +```ts +import { players, entityTypes, blockTypes, dimensions, worldTarget, slots, accepting, anyOf, allOf, except } from '@bedrock-core/db'; +import type { Acceptor, Requirements, StorableTarget, TargetKind } from '@bedrock-core/db'; +``` + +All re-exported from `@bedrock-core/server`. + +## What can hold a document + +```ts +type StorableTarget = World | Dimension | Entity | Block | ContainerSlot; +type TargetKind = 'world' | 'dimension' | 'entity' | 'block' | 'slot' | 'itemStack' | 'unknown'; +``` + +| Target | Where the document lives | Own properties | +|---|---|---| +| `World` | the world | ✅ | +| `Player`, `Entity` | the entity; dies with it | ✅ | +| `Block` whose type declares `minecraft:block_entity` | the block entity, about 950 bytes per pack; dies with the block | ✅ | +| `ContainerSlot` holding a non-stackable item | the slot's item | ✅ | +| `Dimension` | the world, keyed by the dimension id | ❌ | +| a vanilla block | the world, keyed by dimension and location | ❌ | +| `ItemStack` | refused — a detached copy; the write never reaches the world | — | +| `ContainerSlot` holding a stackable item | refused — a stackable item cannot hold properties | — | + +See the [resolver](./resolver.md) for how the decision is made. + +## Acceptors + +An acceptor is a rule over target *types*: it is asked once per type with the type id — block or entity type, the item type of a slot, `minecraft:overworld` for a dimension, `world` for the world — and cached. Types, not instances, which is what keeps the check free on the hot path. + +| Acceptor | Takes | Target type | +|---|---|---| +| `players()` | players | `Player` | +| `entityTypes(...ids)` | entities of the listed types; every entity when none is listed | `Entity` | +| `blockTypes(...ids)` | blocks of the listed types; every block when none is listed | `Block` | +| `dimensions(...ids)` | the listed dimensions; every dimension when none is listed | `Dimension` | +| `worldTarget()` | the world | `World` | +| `slots(...itemIds)` | container slots holding the listed items; any item when none is listed | `ContainerSlot` | +| `accepting(test, kinds?)` | any rule over type ids, for the target type the caller names | `T` | + +Without an `accept`, a collection takes any `StorableTarget`. + +```ts +const balances = db.collection('balances', { schema: balanceSchema, accept: players() }); + +balances.for(player); // ok +balances.for(block); // compile error: Block is not Player +``` + +### Combining + +| Combinator | Result | +|---|---| +| `anyOf(a, b)` | any of the rules; the target type is the union — `anyOf(players(), entityTypes('papi:merchant'))` takes a `Player \| Entity` | +| `allOf(a, b)` | all of the rules; the target type is the intersection | +| `except(base, excluded)` | the base rule minus another — `except(entityTypes(), players())` takes every entity but a player | + +`except` keeps the base type, since TypeScript cannot subtract a subclass: what is excluded is refused when `for()` runs, with a reason. + +## `require` + +```ts +interface Requirements { + readonly own?: true; // the target must hold its own properties + readonly enumerable?: true; // the host must be able to list its keys + readonly readableWhenUnloaded?: true; // the document must be readable while the target is not loaded +} +``` + +Only `true` is a demand; an omitted key is indifferent. A target whose host lacks a required capability is refused by `for()` with a reason — a vanilla block under `require: { own: true }` is refused instead of stored on the world. + +The check also runs in the IDE: a requirement the acceptor's target type can *never* satisfy is a compile error whose missing-property name is the reason. `own` on a `dimensions()` collection and `readableWhenUnloaded` on an `entityTypes()` collection are both type errors. + +```ts +db.collection('elevators', { + schema: elevatorSchema, + accept: blockTypes('papi:elevator'), + require: { own: true }, +}); +``` + +## Blocks + +A block document lives on the block entity, so the block's type must declare `minecraft:block_entity` in its JSON. Two more things a block collection needs from the pack: + +- **`blockCleanup`** — a custom component to register and list on every accepted block type. Its `onBreak` fires for every removal, `/setblock` and script `setPermutation` included, and is what keeps the [index](./collection.md#all) honest: + + ```ts + import { blockCleanup } from '@bedrock-core/db/minecraft'; + + system.beforeEvents.startup.subscribe(({ blockComponentRegistry }) => { + blockComponentRegistry.registerCustomComponent('papi:db_cleanup', blockCleanup(db)); + }); + ``` + +- **A loot function**, if a mined block should carry its document on the dropped item. By default a mined block-entity item carries none. + +An unregistered custom component named in block JSON removes the block from the world, so register it before the pack's blocks load. + +## Slots + +A `ContainerSlot` is a runtime-decided host: the same slot holds a document while it holds a non-stackable item and refuses one while it holds a stackable item. `where(slot)` answers for the item there now. Slot documents are never indexed, so `all()` does not yield them. diff --git a/docs/observable/batch.md b/docs/observable/batch.md new file mode 100644 index 0000000..cb69ba1 --- /dev/null +++ b/docs/observable/batch.md @@ -0,0 +1,74 @@ +--- +sidebar_position: 5 +description: "batch runs several writes and delivers every notification they caused once, afterwards, in order." +--- + +# batch + +`batch` runs several writes and delivers every notification they caused once, afterwards, in order. + +## Import + +```ts +import { batch } from '@bedrock-core/observable'; +``` + +## Signature + +```ts +batch(fn: () => void): void +``` + +## Parameters + +| Parameter | Type | Default | Description | +|---|---|---|---| +| `fn` | `() => void` | — | The writes to group; runs immediately | + +## Returns + +Nothing. Every listener the writes affected has run by the time `batch` returns. + +## Usage + +```ts +const phase = observable('fight'); +const alive = observable(new Set(['steve', 'alex'])); + +batch(() => { + phase.set('end'); + alive.set(new Set()); +}); +// phase's listeners ran once with ('end', 'fight'); alive's ran once +``` + +## Examples + +### A value that changes and changes back + +```ts +batch(() => { + volume.set(0); + volume.set(50); // back to what listeners last saw +}); +// nobody is notified +``` + +### A computed over two changed inputs + +```ts +const total = computed(() => price.get() * quantity.get(), [price, quantity]); + +batch(() => { + price.set(10); + quantity.set(3); +}); +// total recomputed once, from (10, 3) +``` + +## Notes + +- **Nested batches flush at the outermost.** A `batch` inside a `batch` is part of the outer one. +- **Order is preserved.** Notifications are delivered in the order the observables were first written. +- **A flush is itself a batching window.** A listener that sets another observable during delivery queues it behind the current one instead of interleaving, and it is delivered in the same synchronous pass. +- Outside a batch, delivery is synchronous inside `set`; `batch` is the only thing that defers. diff --git a/docs/observable/computed.md b/docs/observable/computed.md new file mode 100644 index 0000000..4127b0f --- /dev/null +++ b/docs/observable/computed.md @@ -0,0 +1,82 @@ +--- +sidebar_position: 3 +description: "computed derives a read-only value from other observables, recomputing when any of its listed dependencies changes." +--- + +# computed + +`computed` derives a read-only value from other observables, recomputing when any of its listed dependencies changes. + +## Import + +```ts +import { computed } from '@bedrock-core/observable'; +import type { Computed } from '@bedrock-core/observable'; +``` + +## Signature + +```ts +computed(compute: () => T, deps: readonly ReadonlyObservable[], options?: ObservableOptions): Computed +``` + +## Parameters + +| Parameter | Type | Default | Description | +|---|---|---|---| +| `compute` | `() => T` | — | Produces the value; runs once now, then on every dependency change | +| `deps` | `readonly ReadonlyObservable[]` | — | What it depends on — anything with `get` and `subscribe` | +| `options.equals` | `Equals` | `Object.is` | What counts as a change of the derived value | +| `options.label` | `string` | `'computed'` | Named in the log when `compute` or a listener throws | + +## Returns + +```ts +interface Computed extends ReadonlyObservable { + dispose(): void; // stop following the dependencies; the last value stays readable +} +``` + +## Usage + +```ts +const alive = observable(new Set()); +const aliveCount = computed(() => alive.get().size, [alive]); + +aliveCount.get(); // 0 +aliveCount.subscribe(n => scoreboard.set(n)); + +alive.set(new Set(['steve'])); // recomputes; listeners hear 1 + +aliveCount.dispose(); +``` + +## Examples + +### Over a config leaf and a shared key + +Every accessor in the stack is a `ReadonlyObservable`, so dependencies mix freely: + +```ts +const total = computed( + () => shared.price.get() * config.server.taxRate.get(), + [shared.price, config.server.taxRate], +); +``` + +### A derived value that rarely changes + +`equals` on the result keeps downstream listeners quiet when the input moved but the answer did not: + +```ts +const tier = computed(() => (balance.get() > 1000 ? 'gold' : 'iron'), [balance]); +``` + +The default `Object.is` already does this for a primitive; pass `equals` when the result is an object. + +## Notes + +- **Dependencies are listed, not tracked.** A read inside `compute` of an observable not in `deps` is a stale read: it will not trigger a recompute. +- **A `compute` that throws** is reported under `label` and the previous value is kept. +- **Inside a [`batch`](./batch.md)**, a computed whose dependencies both changed recomputes exactly once, at the end. +- **`dispose()`** releases the dependency subscriptions. The computed's own listeners are not released — the value simply stops changing. diff --git a/docs/observable/effect.md b/docs/observable/effect.md new file mode 100644 index 0000000..cc2e047 --- /dev/null +++ b/docs/observable/effect.md @@ -0,0 +1,69 @@ +--- +sidebar_position: 4 +description: "effect runs a function now and again whenever one of its listed dependencies changes." +--- + +# effect + +`effect` runs a function now and again whenever one of its listed dependencies changes. + +## Import + +```ts +import { effect } from '@bedrock-core/observable'; +``` + +## Signature + +```ts +effect(run: () => void, deps: readonly ReadonlyObservable[], options?: { label?: string }): Unsubscribe +``` + +## Parameters + +| Parameter | Type | Default | Description | +|---|---|---|---| +| `run` | `() => void` | — | The side effect; runs once now, then on every dependency change | +| `deps` | `readonly ReadonlyObservable[]` | — | What it reacts to — anything with `get` and `subscribe` | +| `options.label` | `string` | `'effect'` | Named in the log when `run` throws | + +## Returns + +An `Unsubscribe` that stops the effect. It does not run `run` again. + +## Usage + +```ts +const phase = observable<'lobby' | 'fight' | 'end'>('lobby'); + +const stop = effect(() => { + bossBar.setTitle(phase.get()); // runs now with 'lobby', then on every change +}, [phase]); + +stop(); +``` + +## Examples + +### Keeping engine state in step with a value + +```ts +effect(() => { + world.gameRules.pvp = config.server.pvp.get(); +}, [config.server.pvp]); +``` + +### Several dependencies + +```ts +effect(() => { + hud.render(shared.event.get(), aliveCount.get()); +}, [shared.event, aliveCount]); +``` + +## Notes + +- **Dependencies are listed, not tracked.** A read inside `run` of an observable not in `deps` does not re-run the effect. +- **A `run` that throws** is reported under `label`; the effect stays subscribed. +- **Inside a [`batch`](./batch.md)**, an effect whose dependencies both changed runs exactly once, at the end. +- `effect` is [`computed`](./computed.md) without a value: the same scheduling, no result. diff --git a/docs/observable/index.md b/docs/observable/index.md new file mode 100644 index 0000000..9e26d53 --- /dev/null +++ b/docs/observable/index.md @@ -0,0 +1,70 @@ +--- +slug: / +sidebar_position: 1 +sidebar_label: Overview +description: "@bedrock-core/observable is the reactive primitive the stack notifies through: a value with get, set and subscribe, plus computed, effect, batch and last." +--- + +# observable + +`@bedrock-core/observable` is the reactive primitive the stack notifies through: a value with three verbs — `get` / `set` / `subscribe` — the same three a config leaf has, a shared key has, a db document has, and Minecraft's own data-driven UI observables have. + +:::caution Pre-1.0 +`@bedrock-core/observable` is under active development. Breaking changes can still land until `1.0.0` — pin exact versions and read the release notes before upgrading. +::: + +## What is @bedrock-core/observable? + +Every accessor in the server stack *is* one of these, so what you learn here applies to `config.server.taxRate`, `shared.price` and `balances.for(player)` alike, and the derived forms — `computed`, `effect`, `last` — compose with all of them. + +Pure TypeScript. Nothing in the main entry imports the engine, so it runs in vitest exactly as it runs in a realm. The one bridge to `@minecraft/server-ui` is a separate entry, `@bedrock-core/observable/minecraft`. + +## Install + + + +Or reach it through the meta package, which pins a matching version: + +```ts +import { observable, computed, effect, batch, last, toNative } from '@bedrock-core/server/observable'; +``` + +`@minecraft/server-ui` (`>=2.1.0`) is an optional peer dependency, needed only by [`toNative`](./toNative.md). + +## Usage + +```ts +import { observable, computed, effect, batch, last } from '@bedrock-core/observable'; + +const phase = observable<'lobby' | 'fight' | 'end'>('lobby'); +const alive = observable(new Set()); +const aliveCount = computed(() => alive.get().size, [alive]); + +effect(() => bossBar.setTitle(phase.get()), [phase]); // runs now and on every change +aliveCount.subscribe((next, prev) => scoreboard.set(next)); + +batch(() => { // one notification per observable + phase.set('end'); + alive.set(new Set()); +}); + +const spawn = last(world.afterEvents.playerSpawn); // undefined, then each payload +``` + +## What you get + +- **Synchronous** — a listener runs inside the `set` that changed the value, in the same tick, so what you read after a write is what every listener has already seen. [`batch`](./batch.md) is the only thing that defers, and it delivers at its end, in order. +- **Immutable values, `Object.is` by default** — `set` replaces; an observable of an object gets a new object. Pass `equals` to change what counts as a change, so a listener never fires for a value that did not. +- **Listed dependencies** — [`computed`](./computed.md) and [`effect`](./effect.md) take their dependencies explicitly: no proxy, no tracking, no cost on reads. +- **Isolated listeners** — one that throws is reported with the observable's `label` and skipped; the rest still run, so one screen's bug cannot stop another's update. +- **`ReadonlyObservable`** — what `computed` returns and what anything exposing a value it owns hands out, so a consumer cannot `set` what is not theirs. +- **[`last`](./last.md)** — an event as a value: the most recent payload, `undefined` before the first, from any signal with `subscribe`. + +## Next steps + +- [`observable`](./observable.md) — a value with `get`, `set` and `subscribe` +- [`computed`](./computed.md) — a read-only value derived from others +- [`effect`](./effect.md) — run something now and whenever a dependency changes +- [`batch`](./batch.md) — several writes, one notification each +- [`last`](./last.md) — an event's most recent payload as a value +- [`toNative`](./toNative.md) — bind one to a data-driven form's own observable diff --git a/docs/observable/last.md b/docs/observable/last.md new file mode 100644 index 0000000..ebcf4dd --- /dev/null +++ b/docs/observable/last.md @@ -0,0 +1,84 @@ +--- +sidebar_position: 6 +description: "last turns an event into a value: the most recent payload from any signal with subscribe, undefined before the first." +--- + +# last + +`last` turns an event into a value: the most recent payload from any signal with `subscribe`, `undefined` before the first. + +## Import + +```ts +import { last } from '@bedrock-core/observable'; +import type { Last, Signal } from '@bedrock-core/observable'; +``` + +## Signature + +```ts +last(signal: Signal, options?: ObservableOptions & { on?: O }): Last +``` + +## Parameters + +| Parameter | Type | Default | Description | +|---|---|---|---| +| `signal` | `Signal` | — | Anything with `subscribe(callback)` — an engine event signal, a `core.events` node, your own | +| `options.on` | `O` | — | Passed to `subscribe` as its second argument, for a signal that filters (the engine's `EntityEventOptions`) | +| `options.equals` | `Equals` | `Object.is` | What counts as a new payload | +| `options.label` | `string` | — | Named in the log when a listener throws | + +```ts +interface Signal { + subscribe(callback: (event: E) => void, options?: O): unknown; + unsubscribe?(callback: (event: E) => void): void; +} +``` + +## Returns + +```ts +interface Last extends ReadonlyObservable { + dispose(): void; // stop following the signal; the last value stays readable +} +``` + +## Usage + +```ts +import { world } from '@minecraft/server'; + +const spawn = last(world.afterEvents.playerSpawn); + +spawn.get(); // undefined until someone spawns +spawn.subscribe(event => console.warn(event?.player.name)); + +const lastName = computed(() => spawn.get()?.player.name, [spawn]); + +spawn.dispose(); // releases the engine subscription +``` + +## Examples + +### A filtered engine event + +```ts +const hurt = last(world.afterEvents.entityHurt, { on: { entityTypes: ['minecraft:player'] } }); +``` + +### A peer's event as a value + +```ts +const purchases = core.events.of('drav0011_economy'); +const lastPurchase = last(purchases.purchase); + +effect(() => hud.setLastSale(lastPurchase.get()), [lastPurchase]); +``` + +## Notes + +- **Eager.** The subscription is taken when `last` is called, so nothing is missed between creation and the first read; `dispose()` ends it. +- **Both signal shapes work.** The engine's `subscribe` returns the callback and releases through `unsubscribe(callback)`; the framework's returns a release function. `dispose` tells them apart by identity. +- **Use it on `afterEvents`, never `beforeEvents`.** A before-event payload is the event in flight; keeping it past the handler is a stale handle. +- A payload equal to the previous one — by `Object.is` unless `equals` says otherwise — notifies nobody. Engine payloads are fresh objects each time, so every event counts. diff --git a/docs/observable/observable.md b/docs/observable/observable.md new file mode 100644 index 0000000..12c7c7a --- /dev/null +++ b/docs/observable/observable.md @@ -0,0 +1,91 @@ +--- +sidebar_position: 2 +description: "observable creates a value with get, set and subscribe, delivering synchronously to listeners that are isolated from each other." +--- + +# observable + +`observable` creates a value with `get`, `set` and `subscribe`, delivering to its listeners synchronously and isolating each from the others. + +## Import + +```ts +import { observable } from '@bedrock-core/observable'; +import type { Observable, ReadonlyObservable, Listener, Unsubscribe, Equals, ObservableOptions } from '@bedrock-core/observable'; +``` + +## Signature + +```ts +observable(initial: T, options?: ObservableOptions): Observable +``` + +## Parameters + +| Parameter | Type | Default | Description | +|---|---|---|---| +| `initial` | `T` | — | The value it starts with | +| `options.equals` | `Equals` | `Object.is` | What counts as a change; a `set` to an equal value notifies nobody | +| `options.label` | `string` | — | Named in the log when a listener throws | + +## Returns + +```ts +interface ReadonlyObservable { + get(): T; + subscribe(listener: Listener): Unsubscribe; +} + +interface Observable extends ReadonlyObservable { + set(next: T | ((prev: T) => T)): void; +} + +type Listener = (next: T, prev: T) => void; +``` + +## Usage + +```ts +const phase = observable<'lobby' | 'fight' | 'end'>('lobby'); + +phase.get(); // 'lobby' + +const release = phase.subscribe((next, prev) => { + console.warn(`${prev} → ${next}`); +}); + +phase.set('fight'); // listener runs here, before set returns +phase.set(prev => (prev === 'fight' ? 'end' : prev)); + +release(); +``` + +## Examples + +### An object value + +`set` replaces; a listener sees the new object and the one before it. To change one field, build a new object. + +```ts +const settings = observable({ volume: 50, muted: false }); + +settings.set(prev => ({ ...prev, muted: true })); +``` + +### A custom equality + +```ts +const position = observable({ x: 0, y: 0 }, { + equals: (a, b) => a.x === b.x && a.y === b.y, + label: 'position', +}); + +position.set({ x: 0, y: 0 }); // equal: nobody is notified +``` + +## Notes + +- **Synchronous.** A listener runs inside the `set` that changed the value. Inside a [`batch`](./batch.md), delivery waits for the batch to end and happens once per observable with the value it last saw. +- **Isolated.** A listener that throws is reported — `[observable] X9zR| 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

    OQN@BE-dTRKJKAk%>Eisn(xTguji181 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 D0BXs+ diff --git a/static/img/ts-logo.svg b/static/img/ts-logo.svg deleted file mode 100644 index 5bfc07d..0000000 --- a/static/img/ts-logo.svg +++ /dev/null @@ -1,8 +0,0 @@ - - - - \ No newline at end of file From 6df939df46b8ef0ae19e3e172a7eb71d176155e9 Mon Sep 17 00:00:00 2001 From: DrAv0011 Date: Wed, 9 Sep 2026 07:46:35 +0200 Subject: [PATCH 20/48] docs(ui): color and textAlign on Text Co-Authored-By: Claude Fable 5.1 --- docs/ui/components/Text.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/ui/components/Text.md b/docs/ui/components/Text.md index 0a307b2..5e84707 100644 --- a/docs/ui/components/Text.md +++ b/docs/ui/components/Text.md @@ -34,6 +34,8 @@ import { Text } from '@bedrock-core/ui'; | `maxLines` | `number` | — | Limit rendered text to N lines. The last line is always ellipsized when content overflows | | `maxLength` | `number` | — | The most characters the text will ever need. In a [container screen](../guides/container-screens.md) this is what makes the text **live**: a compiled layout cannot grow, so a string that changes at runtime reserves its cells before the build knows what it will say — one container slot per character, decoded through a 64-glyph table (space, `A–Z`, `a–z`, `0–9`, `.`; anything else, formatting codes included, draws as a blank). Leave it off for text that never changes, which is baked and may use any character at all. In a server form the text is live anyway; a literal string is cut to this length so the two backends agree on what fits, while keys and `RawMessage`s the client resolves are left whole | | `shadow` | `boolean` | `false` | Draw a drop shadow behind the glyphs. Purely visual — it does not affect layout or text metrics | +| `color` | `[number, number, number]` | — | Glyph colour as RGB in `0..1`. For text a `§` code cannot colour: a localization key, whose value the client resolves. Compiled screens only | +| `textAlign` | `'left' \| 'center' \| 'right'` | `'left'` | Where the glyphs sit in the label's box. Only shows when the box is wider than the text: give the text a `width`, or let it grow. Compiled screens only | | `offsetX` / `offsetY` | `number` | `0` | Fine-tune the pixel nudge of the rendered label inside its layout box. The box itself does not move | ### Control props From 967a3eaa97c4197651882bcb85a80ba5e886c255 Mon Sep 17 00:00:00 2001 From: DrAv0011 Date: Wed, 9 Sep 2026 09:16:29 +0200 Subject: [PATCH 21/48] docs(ui): Screen root page; every screen example starts with a root Co-Authored-By: Claude Fable 5.1 --- docs/navigation/index.md | 33 +++++++++------- docs/ui/api/render.md | 12 +++--- docs/ui/components/Background.md | 2 +- docs/ui/components/Button.md | 2 +- docs/ui/components/Container.md | 4 +- docs/ui/components/Form/Form.md | 4 +- docs/ui/components/Fragment.md | 2 +- docs/ui/components/Image.md | 2 +- docs/ui/components/Panel.md | 2 +- docs/ui/components/Screen.md | 64 ++++++++++++++++++++++++++++++++ docs/ui/components/Scroll.md | 2 +- docs/ui/components/Text.md | 2 +- docs/ui/components/components.md | 8 ++++ docs/ui/index.md | 20 +++++----- docs/ui/installation.md | 10 +++-- 15 files changed, 126 insertions(+), 43 deletions(-) create mode 100644 docs/ui/components/Screen.md diff --git a/docs/navigation/index.md b/docs/navigation/index.md index e100871..7961c9e 100644 --- a/docs/navigation/index.md +++ b/docs/navigation/index.md @@ -22,7 +22,7 @@ This package covers stack navigation only. There is no support for animations, t The example below wires up a two-screen stack: a `Home` screen that navigates to a `Details` screen and back. ```tsx -import { render, Panel, Text, Button } from '@bedrock-core/ui'; +import { render, Panel, Screen, Text, Button } from '@bedrock-core/ui'; import { NavigationContainer, createStackNavigator, @@ -45,26 +45,31 @@ const Stack = createStackNavigator({ initialRouteName: 'Home', }); -// 3. Screen components receive navigation + route as props +// 3. Screen components receive navigation + route as props. Each is a whole +// screen, so each starts with a root: here, for a modal. function HomeScreen({ navigation }: ScreenProps) { return ( - - {'Home Screen'} - - + + + {'Home Screen'} + + + ); } function DetailsScreen({ navigation, route }: ScreenProps) { return ( - - {`Details — ${route.params.title}`} - - + + + {`Details — ${route.params.title}`} + + + ); } diff --git a/docs/ui/api/render.md b/docs/ui/api/render.md index 713e8ae..59e2f87 100644 --- a/docs/ui/api/render.md +++ b/docs/ui/api/render.md @@ -23,7 +23,7 @@ function render(root: FunctionComponent | JSX.Element, player: Player): void | Parameter | Type | Description | | --- | --- | --- | -| `root` | `FunctionComponent \| JSX.Element` | The root component or element to render | +| `root` | `FunctionComponent \| JSX.Element` | The screen: a component or element whose root is [``](../components/Screen.md) or [``](../components/Form/Form.md). Anything else is refused with the list of roots; a [``](../components/Container.md) is served by `createContainerScreen` instead | | `player` | `Player` (from `@minecraft/server`) | The player who will see the UI | ### Scrolls @@ -61,14 +61,16 @@ When the handoff goes through an async opener (a prefetch, an RPC), **return the ## Usage ```tsx -import { render, Panel, Text } from '@bedrock-core/ui'; +import { render, Panel, Screen, Text } from '@bedrock-core/ui'; import { world } from '@minecraft/server'; function WelcomeScreen() { return ( - - {'Hello, Minecraft!'} - + + + {'Hello, Minecraft!'} + + ); } diff --git a/docs/ui/components/Background.md b/docs/ui/components/Background.md index b4723d2..66e3a46 100644 --- a/docs/ui/components/Background.md +++ b/docs/ui/components/Background.md @@ -1,5 +1,5 @@ --- -sidebar_position: 6 +sidebar_position: 7 description: "Draw a full-screen texture behind everything in a form." --- # Background diff --git a/docs/ui/components/Button.md b/docs/ui/components/Button.md index 8deef88..e1ed118 100644 --- a/docs/ui/components/Button.md +++ b/docs/ui/components/Button.md @@ -1,5 +1,5 @@ --- -sidebar_position: 4 +sidebar_position: 5 description: "Interactive button component that responds to player interactions." --- # Button diff --git a/docs/ui/components/Container.md b/docs/ui/components/Container.md index 51ff361..bccfc0a 100644 --- a/docs/ui/components/Container.md +++ b/docs/ui/components/Container.md @@ -48,8 +48,8 @@ Container inherits all standard [control props](./control-props.md). It is the s The build enforces these, with a message naming the fix: -- **Exactly one, at the root.** Providers and fragments above it are looked through; anything else beside it, or a screen without one, is rejected. -- **No nesting.** One entity opens one screen — compose the inner part as a component instead. +- **Exactly one, at the root.** Providers and fragments above it are looked through; anything else beside it is rejected, and a screen with no root at all is refused with the list of roots. +- **No nesting.** One entity opens one screen, and no root sits inside another — compose the inner part as a component instead. - **The content fits the canvas.** A container screen is laid out on the same 320 × 210 canvas as a form, but it cannot scroll: content past the canvas fails the build rather than clipping. ## Examples diff --git a/docs/ui/components/Form/Form.md b/docs/ui/components/Form/Form.md index 9be8dc5..12048f8 100644 --- a/docs/ui/components/Form/Form.md +++ b/docs/ui/components/Form/Form.md @@ -59,8 +59,8 @@ These are enforced at build time — violating them throws a `ModalFormError`, n - Exactly **one** `Form.Button type="submit"` is required. The native modal has no built-in submit control. - At most **one** `Form.Button type="exit"` is allowed. -- A `Form` cannot be nested inside another `Form`. -- A plain `Button` cannot appear inside a `Form` — only `Form.*` field members and decorative nodes are allowed. If you need an `ActionFormData`-style screen with regular buttons, use a separate screen (switch via navigation) instead of nesting form kinds. +- A `Form` is a root, the way [`Screen`](../Screen.md) and [`Container`](../Container.md) are: it sits at the top of the tree, and no root sits inside another. A `Form` inside a `Form` or a `Screen` is refused as a root. +- A plain `Button` cannot appear inside a `Form` — only `Form.*` field members and decorative nodes are allowed. If you need a `Screen` with regular buttons, use a separate screen (switch via navigation) instead of nesting form kinds. ## Notes diff --git a/docs/ui/components/Fragment.md b/docs/ui/components/Fragment.md index 696e135..a6c6f7c 100644 --- a/docs/ui/components/Fragment.md +++ b/docs/ui/components/Fragment.md @@ -1,5 +1,5 @@ --- -sidebar_position: 7 +sidebar_position: 8 description: "A logical grouping component that doesn't render any visual container." --- # Fragment diff --git a/docs/ui/components/Image.md b/docs/ui/components/Image.md index b905905..8caddda 100644 --- a/docs/ui/components/Image.md +++ b/docs/ui/components/Image.md @@ -1,5 +1,5 @@ --- -sidebar_position: 5 +sidebar_position: 6 description: "Display images and textures in your UI." --- # Image diff --git a/docs/ui/components/Panel.md b/docs/ui/components/Panel.md index 6d4aae6..ae2639a 100644 --- a/docs/ui/components/Panel.md +++ b/docs/ui/components/Panel.md @@ -1,5 +1,5 @@ --- -sidebar_position: 2 +sidebar_position: 3 description: "A flex container for organizing and grouping other UI elements." --- # Panel diff --git a/docs/ui/components/Screen.md b/docs/ui/components/Screen.md new file mode 100644 index 0000000..ecbf8ba --- /dev/null +++ b/docs/ui/components/Screen.md @@ -0,0 +1,64 @@ +--- +sidebar_position: 2 +description: "The root of an action form: buttons, decoration and the lists and scrolls between them, shown to one player with render()." +--- +# Screen + +The root of an action form: buttons, decoration and the lists and scrolls between them, shown to one player with [`render()`](../api/render.md). + +## Import + +```tsx +import { Screen } from '@bedrock-core/ui'; +``` + +## Usage + +```tsx +export default function Players() { + return ( + + + {'Players online'} + + + + ); +} +``` + +A screen's root names its host, and there is no default. `` makes it an action form the way [``](./Form/Form.md) makes it a native modal and [``](./Container.md) a compiled container screen. It has no box of its own: its children are laid out against the form canvas exactly as they would be at the top of the tree. + +## Props + +| Prop | Type | Default | Description | +| --- | --- | --- | --- | +| `children` | `JSX.Node` | — | The screen's content | + +`Screen` takes no [control props](./control-props.md): it is a marker, not a panel. Put a `Panel` inside it for a background, padding or a direction. + +## Rules + +The build and `render()` enforce these, with a message naming the fix: + +- **One root, at the top.** Providers and fragments above it are looked through. A tree that starts with anything else — a `Panel`, a `Card`, two elements side by side — is refused with the list of roots. +- **No root below the root.** A `` or a `` inside a `` is refused: compose the inner part as a component, or give it a screen of its own. +- **A component library never renders one.** The root is the one element an author writes at the top of a `*.screen.tsx`; a component that is used inside screens returns what goes under the root. + +## Examples + +### An embedded page + +A page drawn into an area another screen leaves is still a screen of its own, so it starts with ``; the `Embed` inside it is what fills the area. + +```tsx +export default function FrameworkPage() { + return ( + + + + ); +} +``` diff --git a/docs/ui/components/Scroll.md b/docs/ui/components/Scroll.md index 76864ec..66addd9 100644 --- a/docs/ui/components/Scroll.md +++ b/docs/ui/components/Scroll.md @@ -1,5 +1,5 @@ --- -sidebar_position: 8 +sidebar_position: 9 description: " declares an independent scroll region." --- diff --git a/docs/ui/components/Text.md b/docs/ui/components/Text.md index 5e84707..ed729d5 100644 --- a/docs/ui/components/Text.md +++ b/docs/ui/components/Text.md @@ -1,5 +1,5 @@ --- -sidebar_position: 3 +sidebar_position: 4 description: "Display text content in your UI." --- # Text diff --git a/docs/ui/components/components.md b/docs/ui/components/components.md index e2f321f..f106be6 100644 --- a/docs/ui/components/components.md +++ b/docs/ui/components/components.md @@ -6,6 +6,14 @@ description: "Built-in JSX components for layout, text, and interactivity." Built-in JSX components for layout, text, and interactivity. +## Roots + +A screen's root names its host, and there is no default: a tree that starts with anything else is refused with the list of roots. + +- [**``**](./Screen.md) — an action form: buttons, decoration, lists and scrolls, shown with `render()`. +- [**``**](./Form/Form.md) — a native modal form, shown with `render()`. +- [**``**](./Container.md) — a compiled container screen, served with `createContainerScreen()`. + ## Components - [**``**](./Panel.md) — basic container with optional background and flexbox layout. diff --git a/docs/ui/index.md b/docs/ui/index.md index b1135fe..d76bd7f 100644 --- a/docs/ui/index.md +++ b/docs/ui/index.md @@ -39,20 +39,22 @@ So your component logic keeps running in the background, but the player only see Here's a simple example to get you started: ```tsx -import { render, Panel, Text, Button } from '@bedrock-core/ui'; +import { render, Panel, Screen, Text, Button } from '@bedrock-core/ui'; import { world, Player, Entity, ButtonPushAfterEvent } from '@minecraft/server'; import { MinecraftEntityTypes } from '@minecraft/vanilla-data'; -// Create a simple UI component +// Create a simple UI component. at the root makes it an action form. function WelcomeScreen() { return ( - - {'Welcome to Bedrock UI!'} - - - + + + {'Welcome to Bedrock UI!'} + + + + ); } diff --git a/docs/ui/installation.md b/docs/ui/installation.md index 8d2f6c5..a9009f9 100644 --- a/docs/ui/installation.md +++ b/docs/ui/installation.md @@ -81,14 +81,16 @@ If you also run the i18n Regolith filter, it needs one more `paths` alias and an Test your installation with a simple render: ```tsx -import { render, Panel, Text } from '@bedrock-core/ui'; +import { render, Panel, Screen, Text } from '@bedrock-core/ui'; import { world, Player, Entity, ButtonPushAfterEvent } from '@minecraft/server'; import { MinecraftEntityTypes } from '@minecraft/vanilla-data'; const HelloWorld = ( - - {'Hello from @bedrock-core/ui!'} - + + + {'Hello from @bedrock-core/ui!'} + + ); const isPlayer = (source: Entity): source is Player => source.typeId === MinecraftEntityTypes.Player; From df7c3d4e4d9039da51b7d44bd5ee0ed7dd7d1567 Mon Sep 17 00:00:00 2001 From: DrAv0011 Date: Fri, 11 Sep 2026 07:20:34 +0200 Subject: [PATCH 22/48] feat(site): credit the author in the footer A `by drav.dev` wordmark under the tagline, themed light and dark. The hero says "addons" rather than "behavior packs", and `sync` sits with the rest of the transport packages in the section list. Co-Authored-By: Claude Opus 5 (1M context) --- src/components/Home/index.tsx | 2 +- src/data/sections.ts | 22 +++++++++++----------- src/theme/Footer/index.tsx | 12 ++++++++++-- src/theme/Footer/styles.module.css | 21 +++++++++++++++++++++ static/img/drav/wordmark-dark.svg | 5 +++++ static/img/drav/wordmark-light.svg | 5 +++++ 6 files changed, 53 insertions(+), 14 deletions(-) create mode 100644 static/img/drav/wordmark-dark.svg create mode 100644 static/img/drav/wordmark-light.svg diff --git a/src/components/Home/index.tsx b/src/components/Home/index.tsx index 3db4b42..f474e52 100644 --- a/src/components/Home/index.tsx +++ b/src/components/Home/index.tsx @@ -26,7 +26,7 @@ export function Hero(): ReactNode {

    NZb3evzzm2 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 P^y#V9Ezt`tsfH z)O&pNaelOxLU*+k`We(x?(WT_ALqGy^A{h=81FvMcv&yw<@+x`R?7gP>YLtjrV*kO zamxl~BPQs2-@@DpJ(Sx@=4D$7M*z@{wPo(j)GtjtkvRBjV^s;G%{a<9dzfe8)&&Ds zirSKybGGO>E&nb^;IC>KKZ5GeRjj&-RS$oh3k6;%@Mn$!yK}Qw^?*?RfFGFZ1s{fAjYJi!WZkeE$>-KKN9h zfI<2N{9=9!41V?b`-8!eI@$<5q9RMEcb|_Z`oXQC6x0qV>3rHV^{DKC3Cne_1Dpkz ziavatNqhR?oeK)rSuJ(uz7Sxv_gkn6CoLA&3uU@`?nIBDE3&d-h+uSNO_ufYMmC-yb=rFd1wT8`V(neYb*A80d%JaK01uvL#!ITT8TrlOEo#CY2uSol4 z%pGl)5~oB6@;J$`4S-|Du4oHUT?>=fRH7CEl}Z`Jn~iLgOeRsdX@47AL7bB@C&Vn) zy@vQXjSMU{`5N0X?<4$}CxP-NCsqM%J0?^bvpqOgAZ?7Z$hOQ@<2otZmkSJUAM}F` z(8Y;W2VD@32~!sw&@D|X2V!@;aENkk)EW%5`(nA7!*db-zxoEIyv}#;^SlUu6;D=( zAAFR5Fs-x;75qS`;78CAyc(2OgYv?B7v{S#-w%iRcC@^?jW$K4RBW3xT;8f=Iy+h( zSk@cXS+!D8joC*bpVOs*z1RmTMh@^8ScTBrO|}yF+~QI~bU+Ty-qsp>w7BXf=Qj7d z??9Z@`l&Jx>~T)DTpSU(z@8I~dCI9ZL@=x)^>Mym{+=q|d9#J^EljiU8>j z0scN(m3A{+jXzxe*d6X@547!Zd=Nyz!BP`&v`8%vaP$=RGN`{aMWhN&*Ba$%JVt6W&+=Z#ftREijesF(KC z1u6}lz+OCktw;-qso@3`iCMcfVr;Ehiz8!A*}K=sHkPIJpt4d9Z715H(&qMf03>|3 zYp@S7*#$#N$e)PbkCD9c%&jBOIxREPuWWW(3=!8>$?mbNEgOSwD`w`$F?xn%Y@(^) z%C$DOnEe#dkh2@-giqe2qkpGECQE9^XfPl^IOuG8ZdxMVyn6HY#jo=>FZ|W#zxI1z z^5|3iCsen4bT#NIPF=;R3-Dcl?*e=m;JX0de?oBzxYh7jvc>V%+@r?Ey%-R7k!(J3 zx*K?O_4KxZ9IT$!8M@a_-o~-fsNcsP#T{xaoXdxfo(=ch%(1s`3qirPu{bJlVpZ9F z{^sSwvkN!@;1$HtTX8vC_4lChl;Wv?YedNe7-1PaNE|25m{XEg*P!;Yz0Psr>1lHs z!zz+h+4DCDQ^!FLz?;BNEXcX;$7BEPcLCqq+!^7YfARM7r>4k{KFJI8U7+s*eHZAv zK;H%WF3@*@zTc%jHTIfCLVShvd!-6~|)jH9Ya2TP^ z-p~12z5L8S%@^7)o5Z{IPF2r{szCT#R zr){^1V|=|+bY)?bH5#L0r{Yv>+fG$fv29xwqhhOK+qTUU^Tf836X#F&?a_bty<^;$ zJ;t6-`+NA-UTe*{=8~;h8iiRSE9x{xn8oWL?4~)=Oko=wMMT!rwq+1O_h00onUF}~ zkC8~oqlrz-z`eDAIpLLEBg)^_e#kv2B~fX|8Jn4h*(A@j6_&3L`Lh!!zS(@@Fnr(k z_^V~sXU6%qR;d;7FBZB?I5+pW^rMCM^4Yg)AQJs*2z9>1F%R}Q?~$#QRm^@@&eRrh z=C50>uM3q`v(f;Nq-`wX8J z?+krfESR$9m7h^$O|Rq>6`NUzoX&56 zP3JqRPpRpgq3!hXSOewzpQqmEd;B2Ecbt}=04~3* zFH;!>;vt#8xMM4I>{9!`oRTzEV2q=i(d*qHDpPv{$_8=iNfwUya z>{ngsVd^_RchWK#1ZfZyu4;^n*+2lq-2afa2<(17EBHQ_;OMnq&;9-Pv3)a_3X83z zCfCBIt&YL|NTS{DF-ky|OE?GN?g!pWqs$q>kp}`Uks!vYUCQQo3U9B20@&X|Q~2VU34H6Y)yX0kq> zb5hHvTL)!YW*FDZk{G@8k*a#RrJ9$r;NbHZiXLG({@t6Fc>a9B@4PSbdmMVj$$37? z>G6I)!N3ZKB|c09SnTEB*h;n3e9dsgE1mPU()B7Vg@ln)kd&cH9qYmmj!yyIn?IIp zD(8QF@9)k_GFO3D=wnFI4vVEpxC}72lDw2tc1yxZa2H^68?IJ6q7r}G|9oK~De3^e z9*=lFK5p{E+e2sJe4Ng6+3Rrd2U0;)O3gEdAHiZ67$R%9K+HWm+Y zol%I7+l~zg^Sh3vTV8QIH5fN5r7B>tqHHlyF{a~B26tg|gSvh>^h9dUXB%O4Q`AcZ z^&mv*Y244oIvdU+M1FME9cL1<;0(kV=K7j(Cm~Kyv?{;jG7lmlxxvf+2-Ug>^4=b$ z0kXUMdC@ftYZ&LD@M2h$-u5>p=^7V#*eQ-_Q`pMs;oGe1qb^f?1K!nl;v6;9eZ=)uSBwlaCq8 z${aT6iG1FQ0XglA%s|xlvm;NlwzHls3@@)UtiZ0o4w2Lj;&z6h$IJ>6?Cr_iS)8=x zG#;mkm8!E7qvoQZOM-#9Nm~VH{`RHDFo_WX*q0dRYXT)|CACU9nF1V5li1lX&}BFO z%U9yU^!W~}e%fL$=#z2v#dH9@(eyjLJ`Wo{W{;j9(**6<(0S-OF57g(J5sU|+F0tq zLhb74o6|U*4LstEgC8NPp*c$}(2lT9beoCT+q=ts>~rTQNwX#_dvP5e8zG z@D%ub_ELTkZD98NxmS<$(*?{XU2(N0fvGo#)U>^I*86*u-cPLbF~O(Gd<9O)POvdl5U>fMdX~* zqaLO4V?JVOQ@aZqg3KE2yeawsQ)`*pvr_pkEN64*hU4aZJPnE?Iqto5a9mg5aI_88 z(3Cq>RF_uIq4cv98tK7M2%hGm4gAs zXsAz&ng^KE39vk6lI;{;3l0REkjP-|RCjs5Iyg3RqmA+)U$2}m7E81mYFW*dNmwJ= zb#iVee!i;XNOuXJLMt)Fy-1-J8TW6aouAiPh*IXHOB&mQQ#85JWI5%Vq_t~CO+rHU zJ0x7}#7{VMNRw7eSd=@f!q&@X6%x&H=~ST~<{!?)CC}aK zMRKFWK_(JhsGPlg4UzJS0jaYeb9FSEs(LcpY~9!i3q;aa0)}fxl8wk4!|8wH;}T+^ zEMXxlO&_GA{1UN$fAG9pZ9ou@6$He_#Km-=&25bs3>HX9Ux`fw{b!A0&Q%wn#`h^5 zSGPnOE6gjeQOjlFh>R`hHKx@vu5G-l=Nf4>vtOxwWCuO@7=Cx6Ipt|`v>tQ!G#5Mt z94{spMwvkk-IpvCSk^+IiaMaWv`*Z!_PDjs@tci`G}B?D{BzR%mv(CHW4^7DK6ic&4#{0y#OYgjq7Pr_zM-Of7n-;*iX~Jau5JKZ96L?lrwNbNLmuS}4C?7Iz9CWV1Bdg7BcoJ?yHR>Ca z*YW%4`a}gE7bkT*eq3o2(fL7EriP!W`6&NQ-=`OJb$2&?=PjW1L_gzqU+3%6zJ6Ie z;fJh+iZj#W{{el^lp2yy8?k91Oy$6>-T#ch7M>%%d4t>fbEmnRs>G^i4@yuK|}& z)nf2sVaVg!;5KOV2C~wyrf`mENr;8v;7K?2hF7GRKXJwp{Q=Jk?lj$AIfitU%b8`h z4%M>TJHBV07dh(Hs=$Dp(s?-NeumBc{J5A<*y{AX)9m(pWzB|ti4|P>@6Z09C;7~S z^bvC0^)CT~Z)`Z91RowDuPyca6JjWlWUo_I&@%j8a4z|~jWq#tIUx%yojF1gTv}22 ze1Odai{3ZqxxTM@fgK(djVjX1_UK^SI2pETN)&P}sJr4dIW422&W@$IT|cACGUM@E zAV~Bi_hO~UTToL?&?@#Ev~LssSc{@jhzg? z9b`H)?ezXUkm{ES{5@7i)G!A(8{TRP*?@*Yo!n?99SD(wJCm#S-%SQ`>%XGfs;>!O zdZfnhQrePCH2STseZ9%~%_fJL7l_hl$mrLwd8nFBaLPd*12ii~m35C1gVD_3okPi! z9cki7aGWO5xopccw}3Ns6gSvy=C=Rw zy@;Jc-V@VSe+yfX6)hExZf-%poc8dal z-Z{^^eyn#{S2Za5orfi`K+|&l!T;#1{>^<-%i;ct=PtKJahdqk^GP|J^R?br{dxC} z>&mVaG*n{$-Z{B^m4kf5|HPl;|K>{d-pY6~BJ*;S;M-Y9%ycq>a4ke+sPF#?@rJYg zNd@&*l~2vC3E6S50dE`32pu@gLJ-Wl`p@eJQLH0fHcG&})***6B3bs*#tgKHaAool z^@EPEWZ+U#7E(jJbB9>)I`afKDX5&+Ico86#SFjjVaf+HQ#rvrR}Pw{Xx2@zL!i9L zO!m^Lvh6-|fIsVAqrj&P#51WJ!pc4EQ~$~2QuCcnjj+~q##KmyME$!9%99XvN6%M# zL1>rh{&?PNmx;YyB68~%=j8=t&UjP+>zKdhI-f}C+LSY0&iAO zU9Dn$?ys`UqAJ`$4AoFKW=f~CP46mjIt<6^Om@$zWOD3I*JwP1i^R_(b)mrB_eGi3 zKk({IJ6@0IjMtt4(+J*r+jp@lh~^azWcBp&MGRH5U4b5E;Icd#y8pg5MU_E5P@~sV zL~HGus>8?1cT`c(IvEVkX=v^j);C|?~pr-W-e$Wqc855uu zXT3F(Sj9@+ArCEUeD89e>SK;~pUi%yNOMu%+zj@q=XpfqGj=w$wIRFk5%WzGBRoza zEq^ds(%a-{jy1pYyOZmT<*L~_Is<*x=&v|ecU%flAw)je#EUKqd~#A<_d_)-yVg-p zcw`@Fjh5Bbvx^)rX#9Zb66^a3p^nlGi3>(65Uj$5k>WXxL__5HTG#U4dSGg>^l?LR zHX9C3`pXi}1EsVOw(aTfVeIilidfN6=?JysGLBd%rR0lrk|ewz&i%pSS*UHAWjeI?)IC4`UiJC&p)<&pZ~+q@G6J6&!lnn%Gd}{CVuc|+?jz! z+r(eySCDk3;yT2q3Vd>mZ!ensO;XRFi)eW52 zP`OtOa!+pLh%W!-t|LzD89$U|KdLgh?H~5Z9c6r&y<;EOmG^^G`pl)yQx$!KNc8JU z_;#LHE<92sa>bJE0<-*4&9h_N41>CyHcZEuAnjV0M8@vvql^)97Ty?5>mzc>V$KyX zEmJLX$X?CkGXf$LK}8A(=8<)ADFLrgi+h#)!n63XP%AqPR6+#?&S(NfCz3@jd^)z- zyxXoE;LTe*u2=>B3>>d6J(;tj&LuDc8Bei5ZxDB!M1z-DDB#%3NTV5puRHIAl) zY^yB#8!o2;PTv46%2mBy{2USg-#S|8VtZ5Jqo#y}vlv9%#$iq(Bc)0yIBu`MCJ^WLPQ^g=k z!||s~_b2}^r$vqL+M2`i<+;)B>ib*kj?wlhUOBv8LQl9kjggILz?L-$eV>n$hUkvh z+pl67nfT50spC44N$>gJ^P|M)xo2>0VRiATR3EBBs#v1RI;^*vpO$1d?_9JM18)!q zeWQ0q6*kLw-Hz~zw3?kQ-$~!Hsd&(k1wLk6wlM2&zUIKLD%T|1k@+(8?iVSXk`C^T z>EL+*E!sV$%O{a!K1N!1#kR(RLJi}NE?A{|Y^Ly{C8_?bCCDIsE&SDtlv zUF_7)*+X(Wi+VG3QiFf1{MK>=5(mfJyO{)kmNf4;D;oj0UK(}=nr@%{>Qs9ir7NnI zZHAA%L?LKoVAp*g7UCOwsOb&|eVpFuzcys(#tKeRMOD8_Y-ydpB!2A_C32U7 zZE_x^E6NFX<7@TRG`L%DdS>cD_wsz`xDFUU2lt&5{YhW80^|hDGY@ISO0cMo$16BE z?C=|d<$8R%jdIX{%s3gEA!zb#&PdK2cy_lXPpRQpR;F=DvC*NM5n?aAz_`0p?7Y~W z+r!o+_8EV;S6%8>crBl9HnoE;7P~&*b}w<0;HhU6JEu!yi zbE&|{i0vGG3&Tx%Cgei41YgxuE)+73XDvdN!$Q`!fl|08=!6H_;x)B8k@qCJ_r8dK z1SawVm4m@>_ZKWaixKfZ7*S(m0i2!B(5-SiPPEsMjvj8NEuW9^9`75TE{}&>*B77{ z=jZWV*UH<_Arq%x-E-uWzRicx9Zp8i|A0OTR=wk9x*6OM&-zHfQzmJ4+;VmLU$k+x z#2$;S_>3NLb9q(^tL7vjXIH=R)`4f~z{X?D*JEUu#jwygYhH0>&ru9ia43AGRNWZF zyavnC=gu?Hp$8Tj7>V0I_Z|C9vukZx;RpeeJ7f@OuJh_eV@mJu#PWC(W87)8;+j9d zW>o2Sm(IBOo-?D{K$qYLg%2RN-JXfV9E(c9C-$6kr$^+er{+B1vQX>F>(D0Cqi-E3 zvP=K`-RKI(tLJ|}pM@*05M`|WH0+~>jQ&I%IiYxXyMhCBv?8*xe1!Uparhyy#0qE@ zedP4TnNdc()6zlLq?iOFjfI^!!I7hjr5lZ)biC$%=k=Oa>?;u%YfaVkDrm@l$S+aN zN51yB)e~ZXqySfkL4+{PapBa=o%-e2lwrNLR6#MAd^7o zRt1XKqG4A|Id^)gA2jQT@KPm{lyKZ+Q9}arQxa30xWL;oUT2($i$ZW^XM?$<4^>U$ ziwoAGe{&h7k_6_>?}eY;FeT%t0xr}x45Yk_62DU66Jz)D0uY0EmXosN{&A!rYP#%^ zj}E=NWpQ+sTxDR*vT6Z3MYsxYaDxDam704CwKn@uM{RJQyEH+c+J3Kd(-Th@7F|8> z_mR_I6fsqTd92`mY|O&mhV;9{3DYk>#h1uA{iKildz_*k>i-2%NuD6J5Oae~xHJAb zrF>A!{Iihh)O>iO(T3);Nj+&WUM}#<0({ua9CA*@fNvx?>eoMYYD5-(Kp}VPGHHt? zC#eNu5u3%(JJ#$x|4Hy2HupeG8GRmYn&xo*H(BHFwy8n?GMlg_PZ~RB09u7~%ly`i z5Hsn@rSFvdQjG*26#+Hf?1;8l9g;0i%d4)Vrz;KQ=QX}EC;B~pXJ1>>1sWc{icqR7 z&(5pKy~VU1i#LfqCOp5{r^sP__K*A=9Ef(CJ)fp9{_~_I3KgId1!$P> zCO}I7v@S_qd!c7nP$<_7n^6M>XOPRI`n&3hc-Jmi8bg=E*&33Lw<)t&DFd&xKn)KE z4#T3dy6_VLVWCu+d02JWb8B?A`EFz#KW+$S+l-{$&bq47TH9(wkSsnXGj^Zi*pF6Z zI7~_sHud-yRhw2ZOc3T5%;SN6Pm~RQFH6%Cm)$)c&o4gR?{8CdJ+22r6QCYn=gZZ% z0tFC!#*r82^#8v7|DS-6Lz0nGj#pc@j;4@d!L*v~nNlL@5HV~+;j!K2(GhRW;}G~Q zM?7-u-L?OFc%Nj<_j=SK-P!!%`^OnZjg_!pp`q~jQ#`OlL9cZ6o#ps|i^3Enca;8Y z$kAq*&%Gi>>nR_zDpkwvM94MkL^2lU;;JqxRBR)(N^(w+Xwq1lRBg?=L%+g}qrY<} z>5QIW2>(}z+s&B#IO_pUyX_MDr2HG-7}{XE^mPP9cIdCa|5s@KZ|IZ1%?nRC?r3MK zj&dZpEiNX5n8clJqpejL0Klcgz6ug}Csc%7mPX~z^?^)=l47d5S_g-ymjjPzMywxO zsl}V+91hzvit#4iIl>f2Ll(t6qi-=?K`vJ!mUw!{ZGLXmyvW!;O&(0MKd`uA88nbPckDR67FGNTPnkROj^oicMS}IIW(T6 zXQuDZaKs+Y2(hS`ZJ;8TB=iQE3)ShcM}99HBX=L9jd1e{a9mRovdjr-w@(`mo6C0u zOJawg8o?FmI@}99oZ}nw8g#%s*nA8EQVyNMR8dr%bej_Nh;Q@V$Cgjx>XsP_z+J0{ zrQTh?+xM!cjp`;=a6zW{v)83C^1W-WC^ zgWhrn&LqsR3MPbcBNj~;X;<)B>aihN95P92QnZ>FuOs~uh?Y_==cvRa*i(_iX6G7k zDh1wQX|FzJH36&H))4^?@^D#(t)T=lilu>V>4z3>|2o_!&4(Z=F#7>{eMVJU3ayhq zKc&{w*6z-<obx1MEHOk1Z!RH*P73v&i z@d-st8Q2MC_2nfeziWGB7neD<5mTXk^g zb`@geZW;jI zOBmGAR~)^SWFq^OaMBvA@JHwNmoI-Chk&i9`OB*t8!mV#G7EAD3cMNUUO^q z7}NcVppDYiFzBV)nOoatE2I4t2ND}{I&Ci^{|I_AJbFoBuKzt$Lcm%b*12fsSB9$` z*NYR-1NSDe?MDgqF*|wk!$}A={%p5ToH^o4-knUTt^Ex3_tnNSE8Y;7-7RKT%=_#q z4IkCAH&2UQxPlz>ahC_cXum-e0Up)LZxgHK?S{g)bYF+q8rUf*U+D_k5PWgGBw2^u z$?thk*MEyajN){nRW4C73xYAauuO8!3f4lmwc=L`tAyOVOHvMU!G5-7ws-G zRe$j9|9K_3YoH(1NqWye$1&}pekBfg7PrEL)QVK|@Q=-$ak6T9KF;QZm1o}`?p@+g z5W)WaEhzwuR*>`?7gr+O;l7CX?{@w&RO{j>f^OR|rFswOK@H%v0K9Q}r(6T(VQtgD zs@w1a!fpK7!GwYTkjkyRo_QJeg5#ZqMIJWF60(B?Ln`P2noj7g(3iW?(GFRVSt!)5 zH4AofHlUR|&EStO@?CZKRnOv+f6ufl>fcpQ=h0=X;Do(1Na%AI6WLd0<8!}adMmN* z^ESta-!-$AQrY`{y}Cuk-AN!|ULjNWJ0d$B2RYZsD)}qiJ-&l{HV^E^hdb`%r4uCn z8WM2LC>G1u+KH<|u~$WWBc)n6kiyQL>*TAfm|eK3=>ZQTuAXm5>ZS>IZSX$N;}}lL z{7Qghud(}>O&l2Q_aJVSMnBjNL+Wu4^6D(>JqF9-pczYa6iVlyxH0XlE1OK8LQq3a zlqrp%quXUD>i1ELVVV$4`UK6Ro7Bneg5kI6EK;Si9OttvU=n$JgjHsT%YRoXSI$U; zvv@fltUw9ZlIj9@owI)A=&1xN^FgR9eKv!Nx}<~vy0p(y-ZgctEnZduf7_+y!BaNe z?I2{dr6zw4s|6`r%4HLz(eKmpB)Q`)=eeb?vntqKl4dXn2twGwVXfF<23T+NjLs*_ zdT*?}!G>Lz9ZnKH1PoD%H+3JCL!k>>{Mdu{@E3F^V_~ZU~u*-EU z2<7@`NM8qHkdR4;Cp&)Y=$M2&qtmSd&m&)ls}o$u-()@b2yMqvjb19sMNEfiw4Zk_ zKNFY3+)S5{#Eze|%3R?3mFTfeuP?q&1&? z4?%sQPvqw7OgD^N(7K2wgsx>157ILU;(G4h z=r(scpG2?rETT-xS_R zDo&=QWOijbCBSV*Ms}Si`hF!nH`CkyUqYlh9&zp(=!J(}T^pIMC3Ly0#6K%Q`R~b0 zkYH=*M&{!>EQ&BKI>5VsS4-({uH7&ETY}*9v4VrKzjqy_!beb`G`g1$=FwQQJfcK+ z`}s}6+=YyO-TS^rG>Iw{R_(N0PN!jIXLToh)4-M^8`|*xEv@M??c<>$v8YMLGIFC! zkAN?h4F(w$2G)T??|(@N_a*Qs>c~T^u;B9L*4k*QH4%i6H65K2cB$9=o|#v)_M79I z@?1WqeLdI@v-gdf#dIiOYS|GBo&o#D?O4V3xd4}t`}4>75`K?+ApJ%ioQ0 z|D_;-1V4}hwfVW(g2c6(GfScxzRbZe<`lW!s`9&v;HZeE@gyUh*pr^~RoWpg2Z|g7 zM@6`1#)9eO?qE?@M@WSYI@%I z`1xR5oz-|n`$@#5a?ggx?`i^Bs^S$`zK(A2c^#iK39St`U7P9yUq5PMrc^(W_J=N0 z{d9v0P81$c9fq3?1u1AgD0ky*b#nk!q%s8|RkV_d{I_MWT}sesS^{8(@n<*-6t4nd zjS+e5tb=C^e)wgfGyl3Zvi=cp>yqj7oOmewb6`31>8fpR>tLLiwr-kWmaySt?`m7- zs#RqJkwqVRyuKaE2T;toX>r4kW(?`M-i(HYQ^`;Z5EdMq!60w*T!O&cB{%lSHwDqR zuLzD1k+r-+od=|&^$YxhbL_l?{o`u{w}WgW_`)nSUi%zlc!#2%+~q$yjTOevOQl0| z8Y-jsX=&Tzr&0fG_Z`P4Z-^*&fO2Nld0JWUIZCcu5{aRZ{eF&wno)l|x@@>Fa|lDk zk&sW@))mM0)vSpq2gP`L3X;IXF0)O9qoojiY?#Q$kJZ>|#$(}TzQL80Xw?f_>Wsi$ zce1gew;|FDQBb@0KNJG*jAOznwEenX&yPF17LGsSoC&t;R;}d({!<}vVj0KMnjrw0 z9f|t+(!kI3KD6Z>Z~xVMIX&nAZL!B+%}o`=-u-O19D{jLYkxkyQw2Vu{rFeW>?jiP z^;qPrUK@rc@T+b@qAfH`a^)mD+a$6X7gvTJ7S-t@2+Hu%D<~dZ9pzLiS(;r#P@k;( zLtg9tH)VjANLaq{S>wDpL6Qd8I6QW1R}(tz8iFaLnBJQj)~30DEOMrf|H^V zWD3InlanE8^TVHRzLep2CT2{H^SbQtUw%QC{3j#$dcs_` z7H*J5k}2Hw>~z(=NarbNa;;$G&d&)5K}=(?f~Tu2`oB~dT#DPpj2z$d@wRx+mfBb< zw0!$Z%y*)avYhz<^8KrhUsh)1U~u4$>W8RS(@jhL@W#*KUdh=vQ&t-iXiO0vii43q z^e}Jo!*C=zsdt6qen_e}K)P)QJg(1PQavm(*lC%zk2@GO*X|R+%3L?|^9>;9E#MaX zazx=|l?40AJ_XjFZhp}f&~H)N=-w|at_cmyf2euVvmDam&NyGs7VUU|96a0$F14sJ zwgL*zM+vx>>|$R;nc8alAGB1oy4-Nu|J-Y2>s0b|7ka~lJWFM^lpSXK0TaPQJi(Sn z3(_?{i|x6e))O!cLJ_Qwbs;>L*B`)|G29uW@2rE*-D!1 z&G!LVBAo=Cj9QNz+98^*5YlY6c&;fGyCjL>1rK?+a90snw>i@-dPF8*+VMM>gw`Hh zF09vc!8SJwE12H;40xkDl%5$7(JAC6I~QE<=gH((RS3(Zn({qtwQ0SCHsQ+{_le_z znLA~;6;=YR57U&F0-->-B-0Ji~JqHuY=J2y<$5a}{MV(KvtWw}^2P+*j`gQ-O}IhnI2B00#-o!~6F0{q*1G8>p*>iNjmbx=w8k zo!?w@Io@f>ft?VqBL(1?i34T6foZ^7TV{ir#c~us%gK7F#m!E+AN~z}FVk2!*-n6M zRr~h0&tq!uYP9^N^LxSc)8*3V#QPGN{=U5+X!%Oe?9cV~{OfV^M=NlNxF@tjC;&T3 zb40sNre*9Kq362fc(?)dqsdBL3Q26QECEReaP5o4-JO&XXIJWM%75`XhOQ?wlj~E6 z7{-i7FUFM?D|sP-p7c@z9gnniP<|S{()kg3>Um?4<{0%>r{ggkB0Du>PZl6Xk!kfv z62#iHd`v4U%N%kZt&9zjteddTL0#nnI`YZ^b-U-%Mi~sXSqyYUN)-VtpxT96!@|g) za3>wA={FChV^>1ymE%swMh#g3y}xRg98~l}J!qk_7$ai^2*l-`XV(;Y4cCiF%~1Q- z1B0+*@tO?X-mB!5WO`JM)Bs7C+T|((;~L0A_f&5V9pyEZ0`|&31Xr&ov5P{g6iX`V ze$FKFfVY46J#I3XEz|R$phLt`jMU}V{hYjT*qAC;RjpV$rDNo@J&36L^QT%er^`xp zv6auOSgOP8d>-ep>tovDbq7>sANIw+H04rKPGM0PB_j2o36mfw*+7lk=}P2^5v*kaIc*>usno+G;e>YAoP3>+#Bd|*z`!aDyIZ_gElqg ze7AF60n6E)4=3+W6dQ`VR9D4>(CRFoUzAE_+;Z@kk@kM<)b#r zyzsl^cFwVO3ls zt$*0+NVu_f7GWAk7wI*ibQTIyj76o}o_P2S{|M&ggUM!f7Gj8hVk2zIGCj#==NH?*y>ZQ&BCxc`%RMNaIiX6tW@Lq0%bNC$tCPM z$!eC)?!?G4k;F+F$RyA1CtQZt5EF)NOR|_h<>tN2&6(%4uG=oIM7(hBU#0i{Xzz{t z@Iy@%s4?phfBZNGmaEIT9I<3? zHn%i-zPh#+A`~=QY_%ejqY=+P_ZnBEHL#{>ZP<2dsWr+IV47T?)}M2`{=wWGFP~3l z>l!BApbunNxH;}t!kne`{6>tIA(!m)eI#4J)5B1vLZq_IeW20SEI7Y;LunCzcgd=;TKR?u&_be&H$ z8U0Hf&ylaSTN;&cF{FS`;U0JCdAU6R#KfXXNe>VEt&4wu^~b>SWU7}z8Ntg-!{3%pOAWB?N8cC z$v!`B?cyt1FOY(5ufv*#%N^)^f48`BU_h-R~xN&xzWR)qPOkvV8chk4zS(4TYNx*>n%)?#HG zz(DxMq18*QR>E`M756+r`zFN*^GvxVi2^6VS8ehQ5{?u>a#Wd2RveDLHdvnDvg|NtZDAWAMNKRT z$~oILm7$nN(=B5xp61e>;X}exG^6m_mxrZWLYbhrDzR+lIiEOvwN5VVclDy|2%>A! z7B~lCbTrF5DQ>DXRLe|T)a zcP+~QhS1haFn|x6#cP??vA5FS-@7MU;xiqhoPoJssTdL||C?M4-HcAD&8;&;NEHSuSNovB&}Tz3c{jev zec!n9y}Pd9Y?KT+M%tVH4#VYeG-Wll0pwUMXq`E_RQGWW^+_Za+RFZY;OKkT_rK`O z*o@?sOFM;bui8xdIN*xY_Fz^*YKA zGL`?xNNV%8+asd9uSxtUxU<;W;XOA{ZXhUx5T{!n2ZDUgl1n+f@neI`)jf~W4;Hyp zDC_afg6W0xeB0%fW#nueBg=X(cz6^}Q-=Bf&FIWC|L%`jFxDe0eDtaMX-({sy{JZ~ zXY7s-EISUuY!m9j`D2QMm8?Q*r(B8$||n>jZvP(q)%OPBZINOsjKZ_Cwyvm%j~nkcpN>K{7!9n|2^rfiP| zkJ{xm2&2vZG7+&i|5|3wYzwe2b1NGk`utTO_y z>#OQI0{U;U(W0ELDygAUA5As)l*FKaEHG}&^eWCG*!%ppNQEjWs~3|$HU&8Ql8kej ze1^t^O;WDcgkK;XT2KZu(9?}P2BejqA6p!;_$&aaWJaguT3~~Vpwp8e>mm>J-u)zu zckpXEn1Uby`WtqbpK{IuB#eR033mjv8Nv!ua&v63n>0lINP_Rql`-3lRY|_DmHOZQ zb>Zb$a?FtrYTa{OtD0?9MQi%HZ8Ku9jz*W<5CJ$7Smy1{Q{9fb5r=%V!H~}UcO_j5 z=h^{WVx6~CtewZEyxc7q}?iUhglugx)hT#rYYos^AYpvK=8T#2!)ocoyk3nWwDamF3 zVH)o$S>5e%G>SJ7H@k`|5gdw-(`|FPTlI$kd2|dx!G;W@2?+8#dvIybjXmAjK>(LJ zezI-$1e2?UV$+XdcYA?Ht8#A457?td0BmCF!UTq6s3;rdeG@*D#ST_lx1#&f{aSnc zdQhXKKBWEg8epxJ^35fqpxO8-ZhL_M_U9O!LH*cf6rrsK&~||~jeb!>KDUTk;vT9% zj5;0i0z6qEAz%+`x(q6$JhibM6cD0+TUpF-dVS&i_0LhLs1CfX1;LAY)zCTA|Fp&+ z?-c|WMlU$*op;BwR|Zehw6$SsAnfAP<^|NMBT;1X*_D6Jp}aY;X)kIEJ;j zzVcW1y9Pw6;QHA{>G9q^9X|ma8#&|HW7+j~q&yebCw0I%_u{b6FcUJJDt@^FS+B>p z3y2>!+YncM44_chM%ed~Lo{WnrG_tHYmSUOjh-`|2x{^w>q-v)sx0$!SCoyd;1h-- zlBFvF!WXtkq;1}>b)eirPUpipARBZE=`uS58mNc*$w@mol{}UYB*u$?N57lY#QJ)P zBDlYc6R@zY&}{)D;=u1fGV3nJruTfGd?se(iXtm z1KLixTohSycjBvnvYam!k2A{ta&BvYO|iDFKk8VvCi+xyNZ9#(o;sj76j%ghQBmoNE$NFhKof|x6Fii> z^GakEVTuIKC>ci{)R8IHh8K6DYOXhJb$<4pm*%p?&)T&r4k$88QLe_nvs>iwi3N-zy|W#r%ogL(DVM7abXn|2*d^ln_KC_MFsV1kG|9N z!=1a|IhM-~mAN!wP>e*atw!`Vtw~ zH$((VN{>imR=O=)3n)lNNh*o(I&`Zm$7pXoog$2pQqs~LBl~ErFHbpqf6<$ZP)DX< zFQa9Sq%O|l?C=k(Tud)IL;P)q1xaXLSU(wCdhT1W=oN&Glq$VLa-<2(DCcSqcjG-y zt~`@V>lPib_(z`lalTmoX8WF-TNz?6LHFm)z8hj+)a$+2ZCaTAHAA#e@yn)r8=(U85ZZ$q9>>Y|m$3Wu7ryCxXF&PBQl|Mh9%oXO zQ-TNd;K6DwO3G~lCBAxWl$OUIT4rS!5TF7$2y3cRAjuV&e+WGCfB=H}pbJHNK8wZ#4_P zcU9g_ua=)PJ@--4&qG^p&Guf89YTA=FU96Pui;NYOr0NxEk3}+^`k1_^h;>>$ErR5 zd*AePsP8nN-?eDxO*jzet*FLJGQ{i1=_Tl6jcV(rrYneWS^esm)RXx-w79@_tspYb zd+uB@aoMHypDcC~G#OO>p3OrfgOU;lft}w* z&}nd`AQm%69POL2yROSdaz37{uYP>l^x3`< zw(SaqMc1z~(O}<1Y|_SZ^HK>|EB3KbUsOWy;+32z{cir{A|l7!iGJJ0?{jB!W}vh_ zl;*l_Svjmp0l_YqS7E3f*Y`YI6>2YZGcIP)`FUIbN-_lpYQuT&m2sa?V*AAG75yv^ zqGV&)At6APAvyc|nmLdzr9oPU&q{NZ6o*`}|M@+!F*MN4RH2{yBC2%pwQ%wmVf#D@g7r|VgR+GB9}XaReUC%Mh*CJ zD&a`L=feGx$T;7Be-Q`9#5;8q2Kf?Ny@}C1M?M?(lojt`+C}h!HJCdhTASkr>Bu0{ zVtU#6E<^&pW6*eRE2FQHdlV(6;V>nrAiqYKV7wDFwUdqaw7HGs^OkUg?w!IZ2OFYh z7TzmVN)STqAf1F}2Ike@RVDv#mJY51hT1Q5%NK^DBY7$~X_~;9LalyHtpQa`0fk2z zZ*0@;qUOtLUE3jv>^SK#l_Q#)q|x=90Ro6y3620apoWXe$n1EH8B|I!UmF`nWIldj zuHQzo8Pp1u)=Dh19NeWk4qmaj9b)Eq&0w&+WE$EML1xGIk`K+{sa`?z7_WrC`1?mVRG~CN6eV>5pD8gnzPeFI zBU;o^TZeyQ$Q83QM~8<~49D*62B-Hc-q@}nG^o?mTGn>4cE~(dbdo<>K6O&p&JRyr z(ZBVtBuB{iB}bEA^vuTa7+VYT^CBmhfp;c};J)0l>z$Fy@boA7C{>-s9T+RW9nX9S zca+x*-kOgxLwa}Dq$n*QASl$IT5hPLSYkW5(h_e_i)#WOIuV^247xwTXE+w9;ll?#W!W z@jR?8+(!ML8^OL}3Dci- zp+nz!5J;B8 znvuiyt|!#?o~(Ywu65#*A$ldB2xyBlji2fkj+$OwM0CcL5L#oI&PQr4xVEwueYd#oDs-29FvD~F4(4u=kin>swJc<`z5WjX zb3ly0gE?YZ2P!AFA^X}~wKHX%G4bsB+La^v>1#~!Ro!}D#GJCmTpiqKvI}8Ohr7V? zv@;HF{yMbH4)y?@>h|-G9s-v63y&^Z=>e~FS&LGE9?QfxltxOq>zo0B5U3O)eOCq# z9HN&mR1eXH14S^p&h%oqEL6Z3sws%kXB?f`r?5!e)6pso@BiCB+py#4x7K{8~Qu4+Kk?`x$jtuzM-M?}_9q`b1ew{Ndh`&a692)YhaeC54<9`QGWvh?)gJgud*FM= z{C@G(mwxX9?LPnXs}Es>{iO%d1OJ%^(F6aduf9*)vo9sk{JB@3(-i;tSML~?!9YYk zV&<8b=R$+5@G`QIg^~SYVv|qk_b7DC&Jg;AVl_R-#6z?jd^#JEu!@38XGWHDZ9J0; z1$q@W9*H&urlU|OLUVW*f&>fRPP4%{!T}qQ%ZwI548q-l>s%umO|7-+Yaj4rq|eh? z!8Xx0m7ovh(+9w!=}VHH6st|Fbs!^@(}lu$_vVvtzxv80t%uQHU-OcV z3ooyxA&Y^69PB6sa*foilZ$Gv!MPlh*~b3|-NhMhFxyTWMhf)_w=og#vv4dN*hkOB zU6(sDjJLyz>bNlEUKbJz`#+tVVGKAoFWC6PIB?l>4MS+4_P!w{ z?qd6B`UnW{o_1c1SCxj>!hs8h5>~Xr0{j)M9;lvI2hO!2*N$p3ZQ%o!j~PzTSSrZQ zdCE63x;)sBD3u@wV(-$on=sb2J4QcJ9%~`&?e;%j&qa>y21O_0mhgPku{E@T$#meO zPqjvJ^*-QwfC&T^@HR#QJpfA^dg2W>4Ll$l7XM6I&B zvAF%6SDrQ&eRH;?oCrEfV#sIUg|)xHy|lsN3P;HU>!Tk$U>s6EJ5S3m7DPYk$k3k;QKlL2*;8R@omYIAQ453K|3Zd=W# zoW2QL4WAKf!9W*wnhQQ)S$Mx-?0s&3|CLL0Mtw$ag0haT&9LT6=gh>!HU~Ey-lkxY z)4~osIpIl5+#I^HhC%f}kk2)1!1HNLFyl7VT5to#{GHTlU3ziuYHPCV-ZS*}4=$!k zpb!RT&4uj5rF&ZU!H3lpY9gcVFduV>mb+xtUWUK;Q;TBlz}~*b6U@IS|m@c zt0WstN+MSISSPs6blK#`i{J(6*AubfJaLw2gQS%Xiy(1h!8xR#NRPVx`c<`{8CGny z;Ai16#B&r_e~j9_2^}ZF^1LsZP4YBQJ!yd4HV3Ri>`a-t7oR{UtWAA%@dIr!+V+KW zV79q=I`SW5RLJUt#x-ug@ybKk=>6s^525*fC{yc8A9|qk;(!0qhcGYx%10l<*Yv9& zeF%^2-~Q;AH81|1k3MH!{JS5$GcR`Gi4p9yUTnb0ym~d77JCN3*Pxl`p^+j}W*if~ z_WjV9XyF@lO4>FxzRV#&6EG0LT@9E&y!*gbvhq$Ac6uD!j(%W^ky z#F7lD2G_)k^}{v?2qKGjgH&@yW+7N(C~^y$7T4|1K6(fwm0!M4t)@d|HMA2Ez%^6w zohO)0JGm+jcJF?ryr!I5$43of>6euxGF^M?NvBJkM9>o&bh?azw5RmCVEI6t7-1!I zvXSvvm@3BY&pimL%wK=?A^3g$`HLEiQ>Byj1+PW;*GrQFo4dACTz2orjvh1QOyl_g zs6^ewGW=sYQ$b7cI>Odw* z?PDHB3{#fGGa@EVB&9IHfG$4;T|v?e>7>TmS4YN$wY%YO_wA(ccE|gHr~2);yWQ&s zK4&R%uea`<-R}24xNi4L5)b$*lz7l+QpB<<18_bs4p_;#jAo)~d0c8pKFEyJvglU4 zcg_0E0YPX+!Al<}!iH7gJ z_58JuJcJwc>+e%Ed?ztsV@G9&q@_$UDlJA(MZ)1#*X&hAw%5RuS1sXmpy~`cbvg!B zi;<3pkho7WC<2$kW)g{h=S<$+50)MQVo#p4xPrRdfUVe_q8JPPxYdDJ#b@FbUbAHp zD3sg}5Z`vZ<-~N~hZQt|2MB@LbgY@t7Q3{*yAn;~8qR$P)I+-1yFsZ*d1&_9lR)UH zu`Nt{yA!POd%uVVJTp{y;ql{7ybBDt@0<95%VT>{z9ft5>92nqY>fZUD=J_t$S*bm zc1G6_&t2NDJ6hPIEKYGcfn3*zBxtRy^ux;kX03CiL*5o5wQPt6Gq zV^GO_?dw*Cy|LT>KcVtAvNTq`y z$?d2|oHnvo6tiU4B=5)s9z0e+LL3J(A3@D{AUU4FIg4BKJ*+7R2FTvsjW+ig=0K#n zFxo|6qsc1p!&hiUM!e(Z|*U=l)AX>o9FPwi*%=8m%23V=#26 ztss+Yq~HWYh3j0^fwN9N3B`n01I%&G?WZq1IYPQIT#=KJ`08^<#|Up07R_CUz;WNG z!Pc(ti#*n(&%rQD*~yK!fI|^s!<|_F0l6L2g9aT=&4Hf~?5O zb<&;z?pDt|qz`np-Nv~pYMh+Ta5n2x7lAE9aPXd85F9b}IMLQ#3w(yVQMdPveBBKk z{VgQvZlS*K`}TlWf3#lgFOGMt{+|8dE70%X_uF@^HI~Do-XM2gI0ZWX@|+vS&YC{Y zfs`(gb6(TW6iY`#P3X%GcyY)_Vp_XoMIW%Mz(2TGi!sdLiUInuz_7=dMHkf^R$yip z%k8HgE*$cY9z>D+U%tE|`M=&Rl9@i%9%oJ-ElBZ-kJ!<{)KuS~ecO~Rt6hQ->Ncyd z*%u-cDjp)&(HRN48pwu_En(%0V8IDdC(TA-6B*qIi~~P6Qey4Z!(tumpJ6IKB`jwQ z(LHM{#D(l6tW)bQKJw{L#eOSa@F#D4*PHp|&Bw33`PK{J?{f6G=bQNa*4B`HmAM7^qyc#Y@OJQ%+W+cZr}U(y;|GSf#oaP(H-HvD?X!`f(P1< zfSJ-_iq9se$Q)3KPw`WFaJD1KH)k8j21da2c0|N<+7jYxH%=pK!^ap4p)=yp%J#Mm z)c1b-?Bj>XnVTyjZ5a<)sT8+`c zz?YyCs3^EiXG76EmQwZE5F)b3Xq48*_>bpo7k6`>F$xb0xNDBUox^0PN(O3usYe|u zNMAeBxrxW!;@-PPQ(rWd;HtE7vQk2Kv?Zs)NDcWP14$swXK9D3Rt!0Dmv|W*Cp}Dp zMe_nU9;zjAOl)D!6c`Z{np16I7H|{5;Oa&DZmRUxMEa*cez%t2_dR=lE$^;`SDwd~ zegKRx9)C3?Ga=ceay6_lX9>8~#a3rUEYO^qLqK+7=|ZO5IW^C0zC6_w23fgVYl681 zzVl&ty@jEMrvU%3;;QBHqP)oOsO3+8{S^p5_s)8PkJgz@`&i?;eCdl>%cVNChAIf| zNiMpM+JGOAgSjwtX2e{`14a%`@Hi%rlLO)e*Ih=lj7D8~o@u+*Ao%eO8sTyKYyaAF zqq;BVm2c%mjN&zm68Nd?RNk>B=z6DDABH%LR*0Nz(cOT)=9LU7OzR9uDoZ~KJx|qa zYn#Ga2*0lzT$gIZ3qqEu0lQp=pBdf0?_(D)&?|tgENvG)Zf8T-QUlb=oz;QyP8kkg zM6j&_<`oINwfDYiwuap*z?%VzzBu?-wY)%VxkkBC;zO4qu#l`;%x541(@buk{n-1g zU*GWNr$6mk+~{ZoN&ly>o5I!)Od*wSgs66i@EioIyTV zotF;{zw3SyfuP3B=!nr6V_}&bysuzDvc2H}ZhIg-4bfk5Iba_fn-?9K6C<(VW}|K~ zHXqkg0`$cbt7A>q@v(wt8`@6T&ZE7#`8IibZ2!>L`1XAKtaN?zcjV(w<&ziQcAI;$ zKlx_8@#Ni`yZgSG&!6Ry&V8;$J-h=NjN#D)v~F>FSsNXe7o87fG;0dd+2ppm)+)s5 z`j&BEwgAhdN+j5cttH1;)-v;|$~LDJf?l!|)_9k>CyY(kRn6?hKHpi+KJe@ZUx9k2 z*kc*AIbwfm^ha$2!Y&L9HV zWh#`9Vn`mNxm?K<+O0Xd-~JM=0!|tPHe$`XSUh`H-_gs{1S&8XhV)Xn%?)ogR#uO- zG(?QVH*xQ}Xq{*|^;lbJ0iYU4m(3;~9SNo24=wEjoF<&ZBX_rIw?Faw-)nbw?+?pg z#toXDt{b!TnX`GwDf|&QNyt21F>9`+OmkA-wON;kMSg=p+$ zEvLU*2FDG7|t8mHvpvh?orp*fI zYrT-8C6;DmA(&c#O(K2)WJA!Py#;1@Tg?|4vS=Y>jR>AIQ4iF{S4ALS6@h$J1ahw; zkb4(Ce9wo!Dtvfb`0$wzKM>)=d-%hDRrv7RT=;MV){dvLpYxPXgh=?g!TSdOVpn>2 zXhVbp1-NfXI@av8++`xQ-7|JMT6sONyjyU~KxWPGrpHFdm=Bj2jH(^bnvaDClFwb3 z^9n?Q8wBV|pdU4Bv~2^)RwaeYllC*QE16X;t5nZq_^YP(hOCqHvpS+xz;!7rKA0w2 zSidaYwr-?1c~C!&R_V%I>mB^Lad*+b&l^uZ`NHdO{=vKL-F@G;=R=)`GU1>CjR!U< zvcJAIK~?C*d&pZ@wQu;zEqI@sfI-)Ahi@J&O1hM!;+$g}$F(4$~N z<~C}~Ig9(ANZSM;B7v16rp_SJG`LenZ48_Tj-YYQ9&Pr86(m9o3{IQAIr#QHZ@d@O ziLgG4hJVpu$5MgFvfc=WCr(&ss!#TyNsdrIFIDXL$B4!Q2U3#Jg@c`$yYxtR%gY1Ch zpPC9M*`|%)e=e*$SDUrnV$G;+#yuq(Vk?kQviETB@@^K=`NV!+ak}sO_Wa^R0!Qk( zYcw*SDI0)VZKfl_C-%v)7qMU=bFIxg)}|J70uCOS#2s1oThUX}s6Hnr^(Ka>!#*-S zb8(K&2Rf)Z5=?UkD`2;0JM}LaJ-_DZuYVg9r!Tzx0FKYwcVGQ%VacZLda!MCBQ*4F zk47@vl|kt;aa=}Yf?1Lits?F%6dWpREQoSB;+S1`wvBC5ICho5P8xPyyIWH8gJ+>5 zer*8`JDYAl`f>2FSjv%9Zr;aSJfS7j%s!T2ED1L*G~{RPLuy#5@8*rdr$uiU6xYSz zN!~{6+NTM8*H4E-ha;vCK5D_FFrcKpW^GKtfO^}x{e^DQYXJ)=tK}2VM8`3)=G84{SPl|Og?a0YbCefs;vJ*$8KWCI6^BvWy8ZaaU;6q7dUXEe#~;G$`%@qPvX0K5 z{`g&P+8U5|La=!;k){sHb4)i7pE0*!gg>*xMsYX8nzUS7Yg>U(CJ#;>vM(oVABaka zQncot0fWB2VSwI7!W-PHl`Ng=W5LqB-zD${020F8`z)(G%Z-V0JvCsMAO-P@?2a4py1o+?bp8f z_>Cu?Po5p2AAC9)eMdh2M85UHe)A7~@?D;<_kAOuf0o`iy8P@c|$YA=RwhqBczwNV*Z*C$TdjPYkXETqfNu@L}mkM7w z1JcME5u$!FV0b^wrtRBrURuU3ySL0JcrIgHJtUjPq1qe44YQE?dm1t;aN1_Vj<#j@ zzI=>;$`K@%w$4gOpOSdn(KZDZinBzFPc5`F!2)TRD#LLg!0NgE!z&2_X?H}3q3Uyv znmR25%Ywb#_ZDf1?5tk1Lk~2MfC48-N9W3cm3{EW`nQXYUI5;Yciq`NHV`xcf;q%dNIO(0Y|LM_tou&7V*8Tc}@C*En2jLg^n-9V-@E?A8eu4k<^ZWw;(Othl z({psWCHDoRUN}h$#SC=Jy61)n7j~|l_QY;=X&}y{Q#nf6JcHb@liWt0wMXO?#5iI5 zD&Qj+BE1hyd@3ZnXgTa#k=;J>uEO)4QT;n}`qzF}`lt5!1Mf-@zvsL5&d%a<5394# z7pe7k&gozK_D{b2?gDm;r-nQFIo@8psLDC?XQ`A-WK-RT~-M$-FF&i{&tejelwy>^IfuWC)Wxk}t zyQl@E8v|lG&21CxIa(dY#^AW8I!`M}Hml5C++xNugd^>99q=u z`<|CCXXd92x^7|C5JK)6c)$0g15T}7nNKcz*lSbU??dJ!f&5>`RXnZ?AGA?Q7NiX;Pub$$!R^0jY?h& zDf)4+mis_PIKe+5bu69(Qsi;Ph6AdI>4;ZM=xZXE?qDQ>5A6kS?Z#ct$iqXHZSA-3 zefc4b!=HWmLU0;q%Aj|{7d6bGm4788207bvr9lOyMgLpH@-5soFBx!-!0n?}z z+f;|o*~LsIG)EY}IP`!Jqu5UGz~3fXeW(%9?Xw?#5CVv&-^d=0X;KKw7$dyNr$8ec zrD2ejm_-*j$ed=@&>lH#vc!VJrnNp1Lg?qT;eq5mf>r#4)7BYBCR}mGa5Q0Yc3ZVZ z*zREO^X&(&t4Q8s97>xsgn|ZK5|BUZLQpWSjWn%|U49xJoi-KzHns+0-N{84vfG(` zBxo-?b!HpckidX&TB8ms>gW}X7S+Mfuu*ecJGal_Dv&FfnESCbm&1vvX3HiTFh#M& zH31()O)xk(Z6n|rUjgt;ztU&Kx-F!!p~6`Y)orKG*jIq_%A z&h7IrU!0QY1v`IKfI6F-@<3P~JcDYS-Ajmzt07X%tvq*9i|8=pqSFLqBd#hIS2slr z!F3};DH-AB5Q0wYU@Q5;dFw12hbRZl+Yeq>v3sF@Z@IA8BW*&GU~LM#)_fHh@B0kuKK*67F*P+PU550VO z-GFIw5XvBzAQ|KXk)~VF0w`{co@EA?fq+w4bh=nG9riA{wWf72zDEM^1nas9^8tqh zEaVXz%0rmpDN!1p-kQFTPi#1DKYTr%gtHfcddX{zF%A9;duT(DUlTtBg^C{9i(4J- zeO3;GqPBy1YLhvTpDDPGg9JC6VWcgG)m*0)%R;<7!op>xjdqZ@xzCJEw;#E_5w(Ky z;MB zgtMBZGg^IcKWxs#gWq!8e)Q!l1!E~8#RRE!0?Zvk4{VyncS$cB*|;O%g_Ux~VO0CM z*|j*9^V*0x8DdsM%Vy(daeVF-Taih$@*(a9jBMRs)>~s`e7+UEuBv93pg1BLMrP;s~0QF;s>O zBpftZ(Dc+nnOghy z*(Nvbb0J_0+9bfFD1%8dS65}Uiy(wKB6T;PM80FLa9Qb7d`W;~c0ZP!eE~(y}2EUDpu=a5?_9c@U)|+u)U=n>Vyyl&7De-4VjOK$wl* zW1^$3?yz`*stj1ev5GEkR*((N#sPJ7_EXlnyWShs)t z?eB9p^Sho+{0LXR{U6`{TYUR>{`jAK``aMO7XgBA@Yg>1_8A+K6sy%Z7~bNow`9o9cIbenHY|% zhFmgam5j@TNm!DGkv*U@+~?d!?79 zin*f8Tf&ud&%=p!bHI;lp1EbL%7J`Yqb6yz*2p{P%J15*f9DI(Z|&z~SKsrUd;ac5 zmdcTBa8`M`2RpsTW`~dEUTifRSQOp=wcEVc>>0mOmcU3(;t=S-;yU5cu?Hdk- zKI#A@?#Xgy*I00P(1FM!8}nfNueBCJG_nJcsOr>htf>qP45d5KI5)0XgG9nlzx~j+ zycbDpz;Y)J*tXMKbM{tk8))%(A|?XUNuxW|P1{mxM-@sQybXs=>zg+MpU1&rz43q? zPKArGr=%t!t2v{+0zwr7)xIzEk`z2}p^ZWJhy#2}7KlF8PZ=7HM z&fA}Q{SE}|HPbqJ+l>%|$6D2X}Jx zMl+z9Yp{9NFcFslN;vy24vOYAKvq~7!E4-A3#|rT6}*p|oiiLN%Z(=C`nFfB)3tA% zpvrjfxUFoC5wT0b_;_Vy#L1ZWCqoX+g8$x`yKRCKoWuOFuWYb&&7OTKo6gzMB-|-d zUyma72l5Yn*Bejb-AbW*zI6|{O6iOAB^&0azy57erO^3})({;5T?-cG|YbX{*01XNTH#)EIyQw@A4w1v7XUIUrCvR^ylQoEDpAZ@qfkeb( zr^USe({Fh%$EbU+mH+XBsFlC?erx4BYveE8rL&F|j4((=4rnQKK(JXl+PrTb+_h^P zlO{p=wYS$~Y)lde2^^dZOIpLmezggdRfobmqZ|8Px*d2f1+S8lk-!L5D_bnX(EgXcn4jd zU9DRyJKMGqw174oqfbR)}9PoCzJdmq2cU!ni67pikV!`t287g4BS2cl1@RBwL% z2fy=DrPUY?c2FIL409Ks%WJLpwpT0IW;vn#$8opNeQk4@eQ4{eu$R$nU^b-yQo-O< zRtjK$1@pGqCzYnVlOd;F42tvCp_q!H`}E!D>gwD~hD??TS(r~R;4fpT5Ht6t9K;<2 ztku^@@I7{m-jEE5ZwB?LBx!DMTHzR%$+C=M^)`W`=!#;{X==eO1qSXGxqZ?$EvN7K z>`Rz7fA42s;cy|T(9J$+E){8b`7l`K?Y;KM3PIq2POBgr8BrPHk#!DnDwJtsOKY?j zM0us;o^9o9P^gty%LsU{NDMqN;spJE_u|Rya{9ijXHohZt75l+rA#w~8?0e{Xo{O1 zA?Ym#k6l(<1p?n<%+0zuHoQpZrWCH@038HAYirx~1PNTo#UjyrHQAjk*sV@B@7aZE1Q zgBlak!`B?mHoWI_?A8@%x-upg$(g(JEaq9nvl9wXn~RE8P2H=BBR9eDG1c&2Sgw68 z!#Ljh1}sWX@40`Nv8h&LKoHw7=>_WU2EPfSTtO6xMH@mLB!njxC50LW2A%hwU1t>v zBvm*(?kTP^Z6I{KEI~t}+Z`*n+MrYJfYgAmq;9snoc^=Jyi({0eVAOE95-(3q+Fy% z$JelGPSDN-+95yaJZre;F1!bpi>nl9p{v%cM%ao$M_-B;83_YcQ`y4_DFGe9TuxR( zL3yRAd3x{tBghu-yMdoF3YwEH?U?Zn%uv8BLi6p2AIMVF#wfakd#ON1VE3Ua?j4B& zZF`pmV9?~lAJ^)V)?#MLu*tb{jtcd=LPtQGmY?2tcry+se{8LkAoSQl#&DGK0Yo7I zs=Ca}9LAU*7-73A3J5Gu!$cW1Xhl0vS(_=a#)3p<~du3aEBAWJ?>tE@Sn8a#k_r=pw|@ zX?2K+Eh5xFQJHh$^Ezf%fGE=^LPKpPv7DH(SaEH z^826lFXmHw<-x-^eZ~FH`rWVGfB0a(>)z)+J^j)9pY@rq-jSUC*!@o^PoKWSpF@h? z|H*&vD1^nx9uEIN!JloMi2;r+j@W-2;J7`J$$VrnW>H&iPi&}0NDd- zajwNzb_Kjxhj#QUqEPY=sgx6R!^7sV@oULpfJJaE+h%Ytj{GXEzNj7K+)TLdtO2&= z$S5ILwJB$-J+|uXv)1c7l>Ojg-h231<7V{8xu4waS8mXJOxMIBI++f4diGMvf$Vi& z%10s!(9FjrV8GM}C5SL*sf9N+(zUCwu7))wWB{-mHI&6&vqqW?C@vfDWgV$P(*oG& zyi%$5x71fnC$IkbcizV$nrt64-9Agz$;Az#31E`BfN3%dV{oOwS~nPo;7#nEDRtQ> zeK)AV1WqE|OZtf11YsBaf(6K{Vc7lKB4^||^cr3?YYWdbT{dTf6ol7`;8~$6Z&r%LET!c2ziyLmcm1@NS1UC!j^3sqig);zj z!&b}gh{xm2UR*06nq@h%dk5rtD^(3tst(n5tx!alJ$wKJs%+kk682?T45dHf`P}yZ zk7Xn0esr&K*jK|cZEWhzWE`XMM!g9hQaeWQjTBPswK6foLvl|=yENMp2UneI;aqTO zd)@npU|CM%=tvl0Xb7k@g4Pq63zE{Xr*N+<&jGXYDgxQnKfexSBOkb2aodl+?Ghf) zkG<`8AlUecw_Ur42!UOsQhg!pLmNiBbpx?53nG=RBNw7H4(LM#$$qRlouzEZC5B2b zGo^}ecytD-l^}o?Dn=m0h9C(g(FRL+4_i2<0{Lzh*ZE^$?o~(ZYgSJp0-E3Ol$ADT zRqIo6-tjsqA~%dPHOHZoxcf_P>LT5uJlmp<1( z4&&-GpGPXZDpBEgUH$XxB~XFeDtls=x#vU@E~L^OdzB$f1YS69oo;}V=PadS=`sM9 z9@cw9)*2GM;oY?+K58#I*r4*69J*@5QWOd}fZsYxKtB-z=TfSizU)7FEvehtAJ9*~ z;}Svye&!u_5F+q%@3^id8AuUD7`z}SWlVguvZGC2Gq_qU3TZ*l##|bvBe-pX@Vscj zS_Xi?>JHYA9`c%Aum+osH`ZljgOAw(QrT2Xq^yk+1~^R6jTEhk`AY}!1|IJOh+374#EHH20po^61$E%;m3jd}n@`w~I zFZ+T^sN!FKe2P)HkL|(D2DrwNAco1Th@a?NGISwgy_XH!@7O({pFz%YjV=j5B7B{P zmL556N)YTVMZQ=80gO^7x3#rM1BbOzkitY9&UE_fmyUwH>PpP0hEJ@4)g4iC$Y<2R z>>@XKvA{BH_T``H9mU7FCyyAML12#oKYgT9O{LRU ze8F2k^FmMeKlTNeaJs+$3+~`_|Kne9UC=&ZFW49&*9EcDZc`C?jmw-voZEP)EGe@o zZHVZ6;6<%493y^|bQ-v(D!u1!z4=&sO=^l8OCsA4(|tpVFX5Oouc$wxX4LD88g8@V zsH!e%(|ReRSm|xkOj_{HESi{8xm9SDTI_Dv4r=xwz;A8Yg~J}%qh-F z$y!Z%YzRbSN8`YMYk+T5`>m(@XT1C*pXRfB`RMa+sM*i__}-A`IdI5zw-%c=w~`j2 z2S3F+dGYX(RW18)q*_bkh9}$*Z_~%D)%PMCu_lI0px6zplw-y$p<&aaEeH%V;~<(W zIEiBc3y7)T>FfT`C6uM3tMHCwV09rMb?&yOEKy2OpZ0d-E9wA`PY}=CTFIHM*MrGf zbo6d3pytDVrEn`i-!yzoq-L(e&jgwnuu9R(WEiw@GPkU}lJoS{A9&Lxv=v`-d<+!Z zC=}772Y4VNlem$B`e zg5BBxThUe5ZixV!TpAo>$2fiM)ziS?kWd>|U8Ld@aKJ33XJsz4;~i#$eh@LuS+*p3 zgRpHxG#m~DvO(=LCQlsulL2e!GrJo#@riigL8BWoEMbh+-sVEI0Ue|(r9Dz+F-QlsuNfoD%Jsm?+K6ymb}$E!d_!Q+PLOQuae0*0X7=E@k269Aa@Z^ z9uesVhA19su}n#bQH!6x?xkZ%1VJ8wF=~5dL2E(a9Z&>-D09^ueb3x#eOpuaL7TF8 zBugKRa@A?h>fZ4CP|zLJ0h5OYbH!Q}KqU|Z+J3}~gE?1|G}fvh(AKqu zGFnVyLxR?jtRRb=z8;^VS=-Qy2gfuB|7Fr(NSd?GdVteGXxR=jkFKRGJEt+(2Fzx+ zP0=8TMgLWS>gNQtZ%k|;7{ot>j8wyNc!6701V~k62(@T*`i7T|3@gK&ZZe!$6)5K| z!^Bo^U{?+qh*S%wMp5J7@e~Uyea~KM-8hqb;nhpmG1*Jz;+W5EgoRv>I?VB1W)}WRGADp=b9XqU@67_Yq4wy$JCuyw3<6##EY1b4(Jbn1QW)(-+g z2IymZIne=zO*EJtm3%Sc;*et7v*S0lHl()AbILS5{Wn)vfa)Qw;G55>l91th*qUuR zaA+L?H_W)V^5`J><3AyWC)l|!FSHx2iF7$f9=X@rqhOyK#epmW43I_#Y^)>xd2L1n zPfagAPk;VM9th?IaIkwTwL{zuP`?dX$c&&WoRlLF8{GlDNA@jJ$gy0mkcc0v2Bpwm z>`2a7!Da(WlPRI24F~c>OI;J&tZ>k0@ygBF`1BVJHAe5jYO!`|Gw$;k(I6!FSfB`E z(WM@CnIPyerldy*I7J4#t`TmozVNZ4Da$G`okAuOx;5(D3oHsO%fyPv0=i6)S-EN} zr*AsyMIs@Pv1dI^a@dsmn`TU`}oE{a?zEe&zV zE(lJ*0xz8=QHU48g_~i#lmQ4vLx;ut^vwr7Pa>q&72Ft5u9B-62%?CXjoes6QNbE& z^}$|?(XLhjc1f06H)at{(G*ZDEx^OLI~1u1iV%XxyVa%?7FBl5X1x#%Mk?i+r@x3# zkp)zuitX5HL?Q?o*O*#s%>kg|(M+4?p0F#8oS8K5|CcqD-?2_??}VFv&nC4ga_(m_X^yen{S4cqKV zlBKrkFxa$R6f%RH1$rW*e)@0mDIl5`EN)Vn_N)n@$_~x3$N-5ZAlGWlbpX#0XBdu* zyj(EPA)A8m+h|&qa!t{-cGHBq%|@Ur*4Bm43QCy~bp>>8ItLAWBj0+(cI+*|eHCJa zX!L@#3XjzgBY=E@M|%rTwSmM{s0tZxW{QbQAa5|%k@V6sS>2E=jo?Ctazzcc z&0Pn|HOJ}O@hLp0vn~J~a{;tQa&YMJmonDPh?8!0C4oH!_-n1qQdH}~p${)>O1G`( z0a57Sv8}PnFvR)7EJvLiZqSp~((W^etF^qPO{adE?+x~cMoq6 zV4S}5=sRnftCdnIHZDR;oL#taMM6vmtJ1yIsRS}5f{>A#>AII=oX{9rRg>alj|2Iz zX0}XZkJ=2Jk}+(u#Dz%^!qJuiQ72Av25#_mhs%DAP zcVE4!!O5uvx<0bR+oT3m6u2eL-n~`immyPNPm2+_^FTR( z;28HSVTNO)ja<7%I6jk2l_B(zO{OOeqen3ZqCs478FhGwb-jew3% zMyv$hn#P>!Zc&gbTTVZ4yr~1A@E#^obf8T@;YEg7O|-azOKmTh>i2@&T_ZUE=VUMn zD%3KJ{xaCDL4v!QA+mr0xox{H#8?o!<%UdRWE)dS(cw2N98N!Y)J}|58ccixfCAm! zm&4iG%&^~N$+2+idjY^0d2c%Aq+M)n$M*qGU=i$ObG^{X~*v710o z4vah?JV|Q3`>q|_o7xC5bamrbAq`X9i8p^oqKUWN7njoyU7e|tHM}*{Uz{?8t*>TM zBBhH86117I@9kl}fn(lSmLaPI<3V){Ro2qfQFb@Q3yGZg#QCwHj{=aVZNW&yk-M-2 zo0{fzL_huT@r}&xNyY^!p6DCFk1kO9CvG2-v|t{i)KNHNEkDeqAmtSq)G&H6pxifhOs5~gr$GDX6b>;KFnB)Dz(z-KMAZU! zBE3!K$dslB#ck)(<>HZCX)<*GE;xhJ1~?C3koqEfO|HMC&bHZ5Goi3e*kN}unE z;l#*L(J}3am)bM&af@gH(*eFU*gYF}bJ;n{0^t;pPwriJgD|xE6mtBU-`kr_`}@6a>|^JwdzFj*ATPUM&zbRd*0n z$gLB~ND&rFRjGzFdT{tFQW?;2Q0LQ+ANN#l=;tT00jHQC^kDWxZb&ZEoV+^_Q^B;# zrWQ$r`wqIj>6->4(Xm4gi`CP@5;FSEDLn@yeUR&Kin^e&E)7w!5jx%RK5jbw#8EHs zm4QoYJ9KW~M5oEbmx8PC#O0%@<<6FdbWN=Zhs#j5J{RPU)qxzf1I_DJ(iWRmW-Kw# z0pUMd#B5{hDd;{eoeA0QZl}L;%rDUK1vaRjK%iF$(|IT(RBF*dQ(Hvq^pjV8XH1b| zr5u8U4$n3rS&5I23NChM0m2Fytauw$kWw)m|8IlBY>;O?-`X zl}d0e4NN6@C*Xbf$|Fb<#{Q{L({9B1)KxGI)nc_8mc_A-EUx6!Upvkb2y;tx6*$Jm zz}-y{Yt|RWo(&LY9%Pk~El_bkUxd;EFOX60D2w|xn+TIy(-p6ltY8dvph4&m@ye7* zR5qxCb(AA58gqR={q^G;DM%>LC>r3m_m*=Z-b4oG%s{p4*5Qf$>#R~}HJ05PX!k%c z#q=_8T3Kg=(;FeXD1n^ExFmQO5Gg3dtfj2Zn8`ylZnZGU>2DmrPT1N^I!Yd6SdJTA z;4N6f7`fZBUNNg;@}s4$NP;Rz60=G+J^Mz^g4B*Svk}s$6s^|qX-!&%40c=&=g4h)8H9D&P@geNOAj9bUYR;`gVCw4cT+LW3Y7cEylgz$`Gtsvn6 zbp|-AYC!MTEUTV=>Ub7t4`wO4WznJzcsKekVQ?-g znd$K`8KVsiYtE&{sB_H%2{6{r*xX5H#F9^1@O?!edymOTAw_7Rd%+~G7+4w<&FT(} zj&`2@=Fw|u9fZWxnFI7^B`-9*Z0&;R6rs8h$5Oc49J>;=vbi)pKyg&iZ;e(_bzzIZ zl4hg=Hne3I^-X&xfzqKK6FekrN_e=m-GuG*)5kaBbIM2*M{hQeyhDvRiE)t09G$WF z$HAgi8pRZy4TeO%YA_0rG#pHhLC=Kwe3CAFeGN;4q#hlDzP-AGdOpVN=pcsDN_?}(DiufRLI(*% zxdR!=5aTRIYV5{URSUYR5T0iJ^s`5Q0mMg%vJhnv+_Q~Q8hJzHlK)5tBSEj z@6jCAK}Y@sLUj??XPk=^3+P}ky4squs-fqC>kD~yw#OV$`s_U!iNU%%pZ?ZSFUa^9 z!|D-}ncanS!~WDn9o8|V@(zk2+pC37TcdX5_6gF0mAzRi1xCap$B-)3YU8B=Od3#5 zmD#p}m#K+G!r^ly;<0m`e(vaU<^p#R`}WSsNBVRkVbV}6x=XdOkS&dY_y9EsX&Ip8 zFE5LFi>@2dRh=|jMO-mbmV;9W4md;yvA%HjFe&c* zTY6Lju@jRgOk)+Uw6&tqVzB2$%0?J!2n=NyY>cw8b*RYqS%b4T@xB+Dwf~Ij#*|%k`C`At-BcICqT4!9qf4$Lb7oE7R%ky>tm;#{c;u#Ek#TMTi-H z;cBZ(5c7;NOG!6K4{9rZjFU?iKHhUqs2WO3Oucb2s=0klUnB7nv5D&lnbsQgKo~I1 zD)6l}OrNU39EI%wh*uC;_vKbFW|GsNIbb;vuNmU46q%?_eh3;FalZwfcWGo5WP4;&8<%M-W}OVBparU)V7(M>;?oCN#EKr z&%>~l|KK6k~xtkpeu`R11!>pDBfu%Awn6?}v zPl9D)%^HAXF6zO1ZE;+TF}rIaVP7svV=_gMc&`x1`zZvjd=I)nzjVs+6JalmWhM~o!wQ7g^0mmr=OT8RQ6 zLWOj%tT2~WD)Oxxxe!#n=Ey$)zz7(Qg%>JonX|Xi(rRVnSdfv7YQTDyK2GoboJ&}- zzYm{+jrs(3X%GP7(9{gV0+g(=&}Jebq>~$l6AG-;A!C$*lQwZp=?54LUzY7yO*ird zNZ_{u&&;irX8W*!l{GO0OGt-%kWD*%@#nl2R{QKP&M)svI8gubzJmkxf7{m%R2yj9 zm`yqfHoi#LfHqOo>gMANGl-i}VhJM7z2RnVNt2j>z`<%vjCPYKWn$LYK)yjN&+)F2qkhlv?4E~H+as8O+M1i=+zip7&z z#_7Mj2pjwV^F_e$UF1>nD_?X8N6D{#(H$Hmzwt%adBc59#N14T223asTix&^64tXv zfK0{TniPuZQn`SF3wugy#>c125=%EEvjxdL3OxZt1h98Qj)xy|pO}Lp+QsVV{Sl@m054;vI{_J1V zhcBXtf8;KT_@BI9#7ke9P1`zFQ)Pj>Yn3ur@#&mRfo%?})}=JZzFu1E(DqjlBnL(~ ztGU7SSOi|E4ZlivvY8xKT2&a{WGV?p^k^BK~`CFXB(~em=@4 zsNXkoKhFF-Z$~v=NFnc^I%)e|SO5H?jNefi|I;sBEUNK)zwiu)-BA47Z_9@-=aYMp`@y69WF39^$>Yy| za7!S^xu5CnMfBX`o;N@dJv&+HN8fu9WThWFK1Qt)Md0EPg6~@AcBkwJ;p3bFABi9RV9uYd5S! zR$aDDRMYD^0RXHrM{2KI{rQ5FkF%uW!#TCnaIFk+s*_zzy} zzT(HpLp+GsQUiud#|hdwpPG+qLQ*F4t?sC`Q00hPXN8Y% zZ;R}{uQb?5PLjC7D)kuyQPqecfa~oC}1v)>B!`rTl$``wIX(7TMmR2v1g0AMcDKx^D8&3+{l+gf&maGh%sA^ z>>%+`U>vRLtJ6?qC0W!!8+a(lYESBY;Fq3|mXy=4ebt*Tb_VquUv&{R{@owGiyHsl z4_~kGYsfa+2gpp)ZOzJyVKb{5hbyic6#eL&e-0!>Kiu(hXQE`9p zPAcvX->A3@c8sSM2z$Ya5Xk~=vGlYGs$_}A6EKKI00&w&b7S6pf#^hIBR;#+O!I6& z!WcR5$I}NW(h4$kz?U>j>x)HZM{@_Jku<&D&z>2@eQU)XudcYCKkq$#`AKTrds(08 z+w)mIIYt+cU&d>$5AXTg^uePCkM3VDvFCo)FG}nix5WP9N8WVxFvi|1yyToPB@Co- z`&=ohSg4(F3e|UV1vjeF9{!14t#Qdd?T*P_v%OAOm^X8v^YNGhAA zZC*ZLi;9@!3w{>v3xM|m{niEprBp0V#Ps5c=Gq3%8y({pNY|OrJgQPaUB=z4s)aZ>ez2PMcUaE}*YfavF3Mu98u;F6S{j@Qy%5ks_u;wmV z9gwsTxh}dtcdpH?h5kSMxL)(g>Lx-03al-pdcw^KFkGMn1W>A3wSG$(+8o)K6Ca-}hVjw_g{>!dw4^3oV52y^IOV z`|f1I@+G&-v=`4##y&Nv5_CLeBJKefd%V2rWo-p!ZhKiV53h{4Mrnf!*oHuAaxW-F zaafh@NV8A@{+8fi>j+86vb(@4G;D0LxxLEuj`!TrTDR*ipBKWX?|Sr1-+AxB+h2bC zxa`ZS*$Z`93U^?9G^Ww*93CMloJ*7h%7@UZ$PE~AwGl{+b=KY62+>S7Mf*%z`! zK%1dX6V_?k1i@_O0lpN~RuBud4lFUl^t-K;nrjRA``lYmFDl~zP}tx>y@He88p(`C zvvRdk3pFtiKm_mLy6yowb3Wj2r<6W>_T+)R@+@zZ(sMu47p3%#TT1`N1((vFx{Ol# zH}9mB{_M@Jv?<_1K&GQeB{}Yb)a@W)`6?CPt|4Y%B9$YvAK68EI0BJ`vLPF*VavC| z<2{@LqWn>+u7!C#=)c`Hq`y4u=KqMV*(bp=wNTZ=YP0A&Kc=G8hiq=1dJ zlooy`M|N_0hnGmLcLTQu=o;xH`O-kmhZzi^{D z2FWXG=TXM0lM|Uyv%1zvoyy8y5Z3ow(GP$O2U-h zs@FDL=H%Jt9LSeJJY!pq92gj}rC%4tojdjZH{D%*N-cf*u19|F6Tp$zuBzvLyq8^7 z=c^b}&;Q^>RlTFC`hOhqDn!rAIMSd(wj4=nh4$v%%0}{bZEZFj>Q!BGSBVSa1(OQ$Q&|xKn-f+fgo3U$hmO`6jGwWgG1?szAM(>bcx z$8cc;e@;e*UhTsnZ-%%T4|`@`Ub!MIy%X6aLR#|-mFd?f*@8ebwOAXWVch3ITw+YB z5e*@|+CaXY>I_ncAvzri(5o&>WK9yVw+@k*MpKqmVmgJ)1`u@AxtIFNPHl?;%P_o7 z0nB;TR&G6Ee&1`HFwY*}drhjNjtY0I>%n6&Ui3Fd@RMI;SDG~!eSH%1{kk~nE&@Uz0Ni}L^6uZiakkjQ$NqU&X7qUNtIN5c?Tho}jeB+Z z#S0z?{iDkm2>sHX421s4je$@>R?6-cy&M;_Ms18*yCDB-YRpv{%7AAufjz7p2#UJ< zU@su!RhHh6^-?#Fo;-^o!j`1T;rZTKbd4dF9YN7nY=G)zUWDiMc0D9QYF)vN+giQk zYE~z}Yv3d9tw>ZxH15I&sKsbktD6dg#9cSKm!|j)Q!FjDY8^SXVw{%`#zCG{3FzoxRU;#mr+Uo*_~9<|NBNI z&0*7I?_S&VLm#0s6!uVzXe*B}vjqRzjR%)f`>Ztvu4R}dv@D5Om9Z9_s?+tDgEQh4 z3xX^=V!gXk%@q^aH>WkH8s!{yT~|YAL6~LbR&zBXks53oQ){g`vaPFE+C2B{nL2Xj zXdyOpa_Q4eXyWl(S5=-gYMDb|m5bU_w*Yww_AK>ek|JwoBBopzaqhQP(%*Zdl3p4A zp1VRG+!XPh`>9@bF@0UPrE_Ly?bIYvMzaF!%n(9!)LQs2lpekI*>pkRNt?!Ob0f+o zhe7(ut98c^d9i|vxSIG{J-Eh(mD;SrKg#B%RcphCPxTU&B**C=UWD-EV;Ai7`|8V3 zo_x)nC{O;>4dsa}vFP1t?ztAtsi3j>v`Uqbu(x*|4eVR+juZD|sysIi>BeB;))6do@gZU#OoSBknG&nggOIsAc7jTQVS5?gcoa4udPGS z{9Bu4UzPOd#_pq2zFySN{ai1*sK2iL+h;H8zjP5r{p&8csDJ%s6!mYolcN5OH;TFy zqr|XtL)MxBOp@-pG!R2B0e7=hl1kY6nNw$^yG$5Gq=}WDz%A2ss=iy1(aRv(y(cnR z+%2smkgu0b(F0|HBQr+zXgB)wU2_R`an*JiR(9R9S&U{ilso}(rT}|J2HDa!75_Jn z+`YZnGBF%U#|&D^aCV=(Yfeluw!-Zxx$&P88 zZ{1l&%+|zUBkNIm7M~+LJF!o(JrqvWzIhBOWQKtm6;(O?`myXfdtSwF93MkAQQv#f zAgwbxWbj4Dp`@k7qt#fc-c&Yz#V%R#wbfN{RDlTBtfU5Nq$8(c*P(s%Hi^TcSX;8H zrW-cBg>qv_#MyZY%dDq&f9xW5wC_1S#?rpsGy7c2Vgwa+(~=ET3OC({jUZzJKNBDJ%Jx3YZ3?Qw_99fW?H@AzY+Ub`sLWT6+ zkG<)wpLwCD{1<=hB2M`~^0B)(<-hD>*H8IIJN(11A0}-w?_pki#)A)U)bjE=xukaV~yxoeimVZ51((G@&{TZ zXduCn_N-}C#}3W0$Z9jDgsuU*0qPPfI)&H9aK>&MELEo2UH8Gb&ztAb0Kud)X)c>v|w}_QU0yj+;ry-da?; z7o?+fPpd0jW*K8#74Q-keb}01r%Uat*_6ehCLkQaWMIgPQHcSjwkEEnjRwuhPbn zRwQx}7bI*^R*L~q91;-*BOW5w*fctnC_7+gMRl>>qX+efJ*n+BhLy@Wh;?LbRsb;= zY`x^ZUe#mwmTZHCc!LLC8rS8qS}t*HseK@X4u;v)qml`#m=c`r~K%JOld%so~sD^s?*u>$*QbJE`FxU&LjB3H56l2yltUwFWOzv}ef!#N8{{`t zXve6usO=Fgit-$}GmSBTSmd*JOq(a7KZEA<#W!{v$qB)Eug=KRu(9zC zmm@)%K>Dr}vgQ_^YNHYb8KHBnE5$@5>e3R6=aSkoS>1++VjjsOSE`lS%B};BW{%$! zWA-WK{FRp91Xeob=c4L{9pi58a59aLiMU zc-2|9>MqPft4iCzt2n0&U1;-!w{_|%hn5dQ;iTA345#el#HyYY2tef zt9?k5I; z4KHg-x2=efgFR~I)mCSiu_u7v)VZNLOj_9e&LFPV4tA~lrtw9$l~Vi*anJST=c#e` zpFDo$<=3E_o%>n8D6wzcp820#M9=(_7u+-dwae(4|N5Qu%s+LbXNC_{4Mf?FK>CA7 zK6QkMO$K!f!pGu`Y?-w{{+r6$x~wiGi4B_KngWl1i`o&F+;Pn}7_%&N1-hDB2Q&JI^QVM*-6 zOPPbRZe%7XbuydTW|>r}7IMk5gjVLqn>U61^% z2p21*Qf&P8m^iy|<2qeHswf4q!c%FAX!N#%r@J1p?*kbQi`As~*rRo5MP|0l(NF~f zr6!Q5xjR=jmB=!OV=3NsXYRbUl-|2hO7orQnIAm6_avV_e&vbhy|?Qly`OK-M>h)V zxu5W57uFYmvrlJX{n;z^$C-ETr+@m=#dgX+cNv}X-@cPh`R8wR$~~a+aphjK^%guw z?UPrn+#*I@Yj|&3wheTwUdckn%2Ap%omdu^N<4x7GL#)x@582!^z5?~0wv5+)-ImA z^fCq)tC@wS+x7C^)R3jwV;3W-yp*iQo(-|CoydEY*-~8F6dj?m>)_TTb4=^nsdQ+6 z2bAx*O33J402M0&C2}nY(jXs$X)Cv$wYTkc^;FGr`*is~xUIZDew2@%Jy6t_d(idW z#uq#H!@cy%{z3=x>8tEtdBH97AHR&2`2%;-GJo(!%e-4(%W;CX(RyQ>!r3-ulxbeJ zQ486|sXp^F;RqoDO^<69s%oW-&t#`FtpB+YjCZ_n|8ob z%50L}k|Qgu1+_PxW%ZQeQr#iT*oAj(x7O5u@79|7M}e)_U{-rG+ezx{eeJ@=!% z?27tg2=VExs2{oDiu$q3sHlJPPAclx-l(Wt&3O9G3ic{ET@Y#W5b#caD{d!Se@7IvroKZOY7d&71ripnrpT;b_8_CzNh;fz-^R>gtxmJ zH~g;EXc&=j0pf_Jp8oy?Z|45NWy~9X@lNIqzjR~XP^xK0W1XcZZxd%8lX~_MNYUlx zomBBQi`Q)`5X=_OVnD&Jf}C^~MR0H#Q}KK!4D;j)lwV{Ww92F+tG6Y4My*SB+9*x> zye>`-aJ2}q;zr9jyY&P_c971<$#BJ2TW~zftOVpYq-eu}xvo(chiUg#HFD3UxhKrI z8ZA|L6GzihqU~($=#)pAiK$<&S6l|g{EyxV#r!L8P|SyV+g^h3x9)0#b`UuJJ#{&aS*h#P zseNkO?%OjDSZ&TRY42{VrZjtpYDrf#1aF2|BSG46^CKq0M68wWmfcNVKt|lw_&UWr zj$G!B_@FUr2%)E^#g%l8v{q#+jXH>E?Pf{SlYrO-r)e8+q$@ACj2bc6!OnNHQTn1< zjyK-8)5Ml=d6pKd@9y1TsMUV^v2xS%^0`kRKf3qy8MJ&iB+}=8qAyOBH|{mzPhaq) zL2vt!`f_r67Efbu(HOi_!ip7|n9q+eFfiuO-)U$He4SrJ4h#gKcVr7*cH0D%y zi!y4~+oOj5jT?pZ;e%)SL?7M+dz|@cz9^z^+#>qtFSv+)(`6LVZ@!Zv`Ykt#Xi)<# zwU!2}^I%-h-3v9sP0W;icEhYRZ7dF{aqwa1>Vc~mr_`ifsg^bN9=j=dUrV>I%0aO$ z6afWE-X?e}>dX~g1o$+;&v5iL!)qc!S;`)>7Y;7H&@?g1q&+9N zf>L>AWh8&b5kD_eSF-~f+bLk@Sh}?kyX7wMu)y%Fq`cG`54l}_d{Z;`@bUczt`G0& z)29#aKY~*36T*rch4tJ|__7P@3uVQpv#@^K1sB%uxQxR3op(}Lzvrg1Vs?lmJnPCchq%JE>Z=YSpTF&Vxf9#*;tbp!&6# zp6T0t)%UjTmNk+Y6FY$r2}~G|C!jb11A)Y{0THleC&u>RpV*cytPlbTA&HHV0b@J< zl|;3>$KyHYv@#agK3j9|^wZoveeT|CfA^2WubN@*w}xY15~C`+{O zq>C<_T%zqk8(=tiH;GdA#sjV=`jT&a1US|)W!@92y(^WN_{^9%UG|8P2Gh4j*{D5@ zVRbZ`-%m#Vx9cwwnNVvVe&EES>jX`v2v- zu=;ww`D#6VWRLR>@%Mob^d*iy7>;JTpLSCpgHNv2kxJTWA!q49F~dO@8|uv&XLBl& zX2>#9jJbEK+r{_MptiY+%)N2J$!L^c{*tEduj#7v8!gS zi`XI6E1Hg~w)UwUnW|d4w9}#6Wm%Ur^!S`wV?|gct_ALQ{NK1n22o3w+sFr@**R5M z`xO4neyIZJj?^NH8TW^JOo1TMm zktD^Cyg!WLZfM%4&^%s${P^|PK6E!U?SW7AC8WQ&kp2&^0@8o%B0nq>E zho1wU|1TfD9ncOr<`SL@0mlIruGR|ko{T5PPH&S;;Hl8oYJsw9NH3W>5(-33hi_ZV z13HOpr_4>~jI=|`HI|}_)&liLlNh>JEaSe=%kAbo_KHHEK)SRuEKAmcbjM;db$bRFEiZ~mIkd*A0@X?6RS>)`Hv>vQ4mecK)G-aK{M{P2|9i5 z!hqOlI9o`P(lqVVmP2z**{5XzAhIXEa{Bb<-RaXqALw=0wwG6xU(4F|kFTP({rnYA zpMLQ=rcb~0T&7Q7_VK$?O=v!IVo-2PUYdud6dk06o;zS&un6{+tO0S-tsRNDQ~6R@ zJiS+gyejm}-Q`_*@9rV2PD>Qod|zS!QZ_6xn1M$&bF)GR}sU;Zz#;3N};6Ji9Id zr)=QNGZ9bQ@6lWyd`du-yy-VG*Xn^zYvMaQ7iSc<^w?KTzF%nbJMO}Jeet7b_Qvn2 zJLZ26eV#AD{KaM5e9sj#Zocn27&qVlTo^Y$csGflDc2kK@l0&4%dA8lLZ_V*IijT> zC}Ympt^Qk-vbPrpm+l#|2XlxWAVc3#WG1EC=UlOu%vhG${{M2O3uAY_Qa!s~Yr<{4 zqVH9JCJ-5J+(BENDu}&d)xh4i&SX5z6)vRFY94B5St+*Q&V~$89kCwpbWp){DTyJ}q2)Had zY#hvU6R%~XTI@WKXdnnKri0UWOe0CwXy>`n?)<}-!I(68U-UF~yFKMeN2l*B=FQH* zvG%Hc)+lwWJA^MAH`+P5<^4qv`*89ccQ$Jr^|n zdw0-O3rLUKSxYu580APo&EcLoMoC@Ncb(9BQn&WmE3|lS6ro619&6jTtwn9JycXI3 z2ihA}FQSZL=i=!?7P5%ipQxijc-iePwR+478>gS%4_n~e&b#mX#Od4Bh|KF0mAj_d zs1#me)7RG84x=OZmS?Ub;ZW^@Z(~l%%FYF7@C0^0uC2{!{b0q!@`SiQN%mj6gQl3;9LO+J~QGjRIgj!l2#LMC`{RR7Vhxr*R{fAWPF z)A`)Y-~j20du2?;s&iEgZ_f{89=)U&MlXYo1gx|YoNe<#rxm)8?Us^{?FIJfcaa`g#q(-?z&fz z_m^UwTp*YyZJia4<%+(G-g}15^i=)ku&F%m1?${YhPeTn4CI#H-=Op zX0ttfP=93PW5w11rt8cYId3!et>elv&a|l20D}QO#pdq)5E5u-O!8%7Vli@0lp|sg z<1&RtuQO4yC-Eo6*0C{|CC-?@G{E-eemFf~IzWG?*b&zn3sLTuwcd5FdZ*4lee+4( zxv)I+iC%YweR*N|HBDZ)Yyj2PiKtpzwH-kbEZm^Tdxz_B25UONIv`}zV6}3EwYHqx z%i2@lnw@2P6N0=Q?7Aa|h&r}taSMo%^Bj9zwpk(@_6d$MzxkQ#&D8nB*Rdo0s^_vJ z{iAnwq$85sAf?yvyNU`1o^uX*OrCp8t8wJ;&aUl8t;4u@+6c6qZCJwntdiH>+r6wd zN_R&E!VFXYhL$i>D!0%6PzdP6eG^BpeUU}^v zG=1n}y>2x9oK`_SIGTRV$FCv_;uBZQCH!O8(I@}$=h7#C?VUckKkT6a=oE=weN&&( zM2r4>lGkE{aSGbqZ^b!%a0z>z;N%JI%eUav4)vb+2MZZXUzuQv%7kT&LQUs(IDV*t z82hj`7~SrZA9@VA>hd$5iMssuFnadb5uAd%Jq*R{@M`($ez`s$Mx)kujd^sedt5Ib}aoIo-^!SYg)TJWU-LLlDVbpxuRzE!u!%0G7TR;xvlAE8s z3X#p%U2$Xlr>~|G5&LR8spBmMS)=<(ktzZHAqG&%04`{%qiw;Lnors;u7k! z;d3tO2b+eoFhpR$ESr{gx?>A-D(o3(U=5w5m@H#CiPFTd>Lj#%$MU6hg^U>*0ZdR%u{({)&LBKf-58XnEXn>QjH zo4SVp#gZ~-zrQiQYjgW4M1S%|lfs|9_2`w?-q{h}v1feX^L+{K4+idVoPBb}n$*zF z1ZZ1595t6?6Kl#R3e6*(5OOw1aN8(wt#P)-u~Q(qiP%-KW&Q^&XF{sN3 zO@sm6>k>e1#y4N}HkIL_Ys~+B6*cBRzv9HSk6j1n%*c1OgV1vP=YDQsbn&>2nLT+6$~owQ-3d+f7HwkzyO z&ZF%XrfUFKjrP7xJ+ZhGB*C4IES`PL;q0K|NVGw`1aQ`w+B4|e`^m$=&Z}jZlX80t z6|+el%Cq(n?|oiBofG4dH$MceF<7>bi{5b^3R^r@$4$1cc!YJ}kHmK3?ttfzw`uda zGdbOIw&HSF-mg2l>tWUQCa=AVe)EA3^ty5MbDARm;5hn~AG=;0{ZBr26*&6)p9_xu z!8N7(6Bv0*b^Z@&!LrP zc(xgiFGTdQdJGLGJ$%v`&eVFEk;86#0h;yFYq$MV;;3FKJM8q?BJbLry->LKPQ`_^ zd6ck#hV^8FXts?M;Hn-J_@1_nZFe4fh?PM5lHh9FT$PU6Rqdg3TQ8}N0v(^F+3m$9 z>PcGyzH(lK!!1bBlHF>vowD%vPgW6Obm1l(BV# zOp1oAR^IWNsO}q8vQDm!k=&D^DnV96n}Q#3D?6Cvg?9e?ajcf8^(4;+(h@Hyjnv z8}6ELqzkRuG?bO7%JVG&syFQjNxK zC`B9n`yqGx9#t9!padLSj6uRU^bjP>wxd7q z0~QC*=>W+#xXXQ9O%LOgU^>L}em(xbaR*ADe(?1-o_)|>%TG;jU#UBQ`p_r)5>Q`U zK>frO1L_~U4nY0m&jnDw_70#1a3c^xZWu5HDj18bw<_Y`UKHdK0;vO4k6AmyjaEQ} zPDN;O*s>KaqoM-gaLb@OyLa%x(;m=_la~xyn$of4p4O6!k+%WWVsDmeDPI4ze%3(3 zSvcD%s@;$#hF3eD*x>dGW!qGpEAX~kHOv$3b%)Vj346%&jix=Dpnh%&SFSVLFM7r3 zmRI&_*HkgoccISxi+2I_UQ?5YKFgO7`r<<9H(iI8mrgys z#oy_nbIH;^-`KpT*G|*Un!H1q12Jaj(=jpum9k3bJkDb>!<@0iRnyX9PJp8ZCD!?4 zZG+Lx@UR(|xMLj%(SnjrT?;ggSO60OJ8pg)I=YGtI_4mGZuk2`FYj7tJbm^`eE6;V zV+J1jL|@|hi;L%f@`_vHKXn}~@t=M!E%Bed(-Pw;3~}^PR=@|MXt46x#Tb)eOcmUs z9irlFu+)-}Vnq&&H8we~nxzt=2*@rc2_Up-Ok>)12=?V$X}6Wh#K1L5W-x``cBZZc z2-$o{Zw^)KJq*=j2}jHEtk!nihs1}uELkflVAzg{$sU7@VEQaY>jxrdfGO!_9i7s9 zz}7T6P&4mAD7 z=Ypnx@eZ1*%`y5OKF}6W?)I#iYqvu}-zVB#rrnfTx1O9_i`rqQILFGhSDHl#3Ki{n z!iFwM@jTX(P|Gr(aG1Ki>SrtrS0;*N8B*N#qbBq@bDSP-+QeGHXotp1VhadZO1np! z!Y77jY*!g;jVcCP&>m`DhMA`=sYH12@Ig~86OjX1$DDp_a$E6;thsx%i#X+!-ixOH z%3U;l>q)(S9zA{QvA_Q69rM%&KGK&+`r;z#U%p}_{if?c(rkE+&Jzvu9f@BbM`#vbIny*<1D= zYOL7_=6lsrr?`N|JaOCEe`^PS^k=><$tZomxb_$R{V3vD_IX&Ssh-F84458VaaX?6{d(__ptCetk}Z8kvL zasvw-7`g{X-=k;ue6f0|H1~`S zJhd5TChcwq*PcBxX!~_2#`pX)y`^Tmae6}wk^~L4d{`^&NZ9jR%Td?oC zjxE@CKbI}o_ubiofx#K8<*{>T?TJnm+JT>1xoxS!T4Mu`USJ;BR4|j*DWv}3kJ$;j z80CThL&y3h?7f06i=B%~p2`;(w;yF&w=b44lUhA>dw9FlIhhNE)XK<(bFH)6E$pI8 z-<5ldiXr)!opS1}@!h;87%e{(MPU}EVLX{#T!d{K_}WWNlzk)7RFOQ>S~Hf|!uLS> zY{w0s0``0H{GpHZC7!>yc>W7lf#*MT#d!Y1*Ma9h@?7xzNAKYIwnIiX&UQVvJlERb zG@yu}v!Nhx`)0RZ$lEZfEdvUQp>`~uW0udYV^z7bte$ZmZC!#-KfZcv)Hi*S<&?s7 z6i*wtH=Fe~tAP*HSqsHwm@L#uD=s85;WEel{Ec? zyJ2tXWahLrnx}S(mYrY;ckl3@lO%12LPO4waldxrZUEP(@cd~#dwM^pKlHi21oame z)PM0RK>crBF{uCT>j3q?^ISmv@7@7*ZBOCqq?QFXY-YPK;Gq$I)Yj+-LuK0?6vKq8 zk#uB1BH0OrvHH(;8|9qB)7gJ>sF=D#0s%@#HH`%aa2p&Ry|A-wJ(^hi_Vh()W^lIwy2y z%pUo+m*%MhqN@#uW8Uu-@tdBs0Pa~!n%{i&?%evJkMLLG_t#w)e#3k5z3b6yuRp3U zc~)<<`TyJX@#&`_{kOgQ&wQ?+{Db4`N8jJ^hOWFlD}1E-!kP*>Pn&83;)TB+b>`l= zmu57tT@Ap%6+(1z#RODXlpJm|U^(L6+WBe&MmH6$M$)7X@#_FK6KXJ$8Etr>uFAyw(ptiGU zay(LnFYMe+>r4{G_C%BbM#;1Zu*RV_y-z-Va?#fQ8jLXq&Qp8Ig0-L@7z?Nl5Qz~N zR|`GNRldl!-6}N?-Fw|zYX0>P)~iqIjYsiDHG%IPFO5_7?9Dgo={v}HN9^*z2Ydeo zBFL1iokkswaACx}i8q*ya4$q~%7Z(I{@G77W-UL=$qwG8Gc@pkO)4xs zWMgJ}rM9To(J^a=H}*|kwz--`yUvb+!3cAi&4V?UAntjbYLD89HAl3gsp1l4 z=CU*RRQk?wLOQ$?6JxG+TbF*6#PvFe{&%0aisJJ1pLia{#%+~zheIfLcGwMjmFvGM>sXC8tBYwtm{sqKn}1((!@ ziRjGKyVqVUx5end37ybV2xN$}Eid|}AqF!FRkxT>yX&5kLpeK+pqu^sU8;ZQJH_RV zdTdV~+0(aPi$~91fAp@lcMpB0?=qN*PBU9mKy>U`?f{09?{h zktE#nva^S*%B&e3Y~BGfWBU>)T_7}KkOc2NH|?IW^*fVI8ok@Eb2cw~AqG7 z?Ybg%6s?w;az)pWz@jmQkg<@P+dF#-x{vb$KH}*PYfpDoYC&3uxyN#kKC9K9y`!cF z>BOT;q=a2;fn*X9cH1U2h-xml`ReyyLm2w^UU6Od{_ChKfBm`Cl^?oOS8z0wdpne9 zY1%>&-lsf-y79;DF)h!=khwT_>jwFxV2yL&Ag@|7jdCGZjNt<-CMpIVt|iFf-am>_ zv*qPsV*oeNjX=Js7 zyFrKnt*vmdIdQoFTdUCz%hqK807u*t5p^vc#zd3XmUHu8{jPo$YzgN;QD^m?Xc!gl znQ)-QUQ@^^2`GC7Xjb9mqr*-Y>7H!4h#}LoReM1vI(VIeWGW6`y|L`U1XV^{Vgrx( zObJP~UFYV%{$1A)5C3CdcnyvTfAXzsDE43X)-_yZ|I}OW`^{I{ar~LLuA$-hZ{B(i z{lCm`pfx&YVPu>k{n2LVAa+2N6UwcT1d45suYqLBtD$m+rO8_v}y*k(O?oShoFy zhsNCMV^WN>`vyhO5)+s>IdX|2&rOG#3$25~9N3Js2Fk3M%M?f6Ur6qf_1-9pXOHrg zr%ztBw;o-7=vG;I=yScltnAc3b{OzPG~XOj&tw8ppSP z_-ZwZ-}&KdfYMKX_&Gr7cYpXc?-|v!*DuJU<;A_25lK6%xwTwt?o2V6F=;8UcGev! zSvMY6HUfp>w$bdblN-z>21+?<-sUZ^>BtFTvp-2_ zvrW6~PkE5=u^>RGwYdxU8pGRD;ScDe4o!1@l>={DL=7gG4h}0TlYvvvS9k#R- z2DF34Y%k?Ch;!cyrN8}Mp!7pe@6w$g_&Bc{K|iM(^9P^&{o?Cg!iUyu7wkdRA}&Eu z!UX7)#3_J$$;mMyAf#Ce%rkARjg9l;GfWfFs*-A9x?(@3 z>S22XWsQ0B2d<);{8FDqu9o_)(eHw6kc#f!v0;ahje%Q_^29{%Xv(90hT&1r^k9M^ z0!SE))K9cJY2Fmarm&1~q-}`}UpeFvO|Ni@aNc@CBJ_dU5)S$VdmvQtm8I-hDs^o|y}X~v!lHzYOtp$SDrFmQH4w+*-1 zhDZjBuso>71SM#EIgSwMilYh%U#&#*qmQov)W7`k za{%?Pczipsa3O|ZEj~0h2dG3gGeDqi>?HS$wOhcq>9m*AnXC5c&a=r57&TI~N940v zUjW>57mC&UBwZPSw1CN+V=*+%)vY6{(Q^*I4eAelU%VI8f6F_d{`9Tap4pe&H*pEA>A|zxdn0{9=ZuV{>#Vd2@D8Bfb1KRTbB&p6VuJHP6~(PB4zw~Kvw36& zW3F|^Ir|oHPRI5x4HX33M~XYHZ~~*#WIPj*acQE1Pc>U{0nW)6o=gc+E$+l?T_k=| z$&Tx#83RJ=kS-@6KYMdb(A|DjWrlkt`o4bw`aAA5yM7vPyz=DEK;fa!^L_|TOhI<{ zAw0u!w8cv)jCNn7v!!&{-e-=m1ECWy9w>9x8se9q?p&{(RypX*NnIhjqVYPmI(oNn z!>HZRM@Xm)q-JZhh!Nl=VfWXg1OB-$xB}|?%~yQj8p_EJy><;$*nX3hg<~CV3U-^Nn9ozr#Yu8X(f8@32;RN>DZO<6&L7|*Nh1`}p#zdI83}g15 zWyaB&IWjv+X3Z%{ySz7I9l#(%wgp-<^41zMR%O+YfWb#k%$%LzyLR}Z{`h&rk}*Tk zbJLv=^#^_o?=7wW(r4aD-o36q^kLp#S0B3Czr33Kdeo9X`t)kACSU#Z8u0VuPoD#R z{ufVg;iq{{^8xL<;e%n>!GLAGiXMbB;0)_a0H;)j`@~Z^#c&!oEpTp>Wr9m$1?eiH zA#t2sOPAx8#1ZTC;(Rd+sBm(wsd;>y+c`XZ4xPla`FKnn5qlY%dVs=i+w;Dz%(=C)|opDRpn1Dy3<{*|oDf9~!7|4)yR zuqO&Mg!lQN&Jo=hhm+w7n%R!{vT80AokP=D#gD;RGO4YGcgu-tYeHJiiUK^jjQUgP zP0j-JI;RQ2drhceQBH7V&pdYXE&sv$e#8CfbhcBrWkTP1L1}D|9fgN5v$oG1lwA{j z&$UG-qGib0=PpW9Mp)0+m32Fx@ti5GXbTZ=J*&azXdeeNmRX|^h7tQHl z!730gaOOp(;8?fUip;}v9&X9Q%+)LeJR2NYS#)_I!{({c{hPY(U49S;3kb?31k6cF ztB!6{qX`!`Ju`<27~))m4-7lG@YrZO>=f>tv9!8{R=?qk@9YX6`oQk*=v3hBPM6#Z zvs**TXwX3)$J+uuE5-D5w7WsHJQ*oE`gdAyJv%;vX_9S73~n`5#X%+M?V#`hAE(oD zI~09;)xo{yZXI+r9>3Gk@q6(zDdLwu_@_jx_x&^X;{>9g)<&Y%$vtw~nS~`d!=i`h zGviD&Suuyv!nS}2lb*0mflHY2@zL?egDY#M(uPf^@^}PFXJ9nL9|Y!}OvI(k9SqV5 z%YO3>Z*~_m1KNX&R`+UkndvWe5b4hpv{OL{8;jcLv0UkhZfZeJB3t{)!-2haYB`wo zPWTHD&IQ!cD^OGq@dmP_DCty5%L)o4@d8%aMK+i23>c<~jAoo6lZ(_2w_V`JUhO=Cku? zKl&nj^_8?|b@Si9`JUhMsh;oCKlqp5e9v!v=TC3_{9oz6|1%bRr@-=r8WO;mnZY%W zFm(PvmCFG`DW#5yi4~_inUr}^B&HBg!@hJag5J!Ji{zazn*l__ zw`+&jR@{yf^BK7``;M`tt^d=Fa~%MVx1a5`3u2t&kXmE*tj~{95X@m)cluUvJQ>+3 z1EOb5J#(Nero?t^skD(~y4wKhOq4qNWCwfyGHc`W^YwW1slEBen@`_C+JD~Pd@WzC zJFVeEAK<%PpidnGYE4t(0Nw;^p^a^wZ#g$K8Q8ro2Mt70h2VIcJpl)t@EJ5hWg`V_YgwMD@zw-y50~hG;_|kq@+ci|F z#~FHPsBcsbR^L>8fnL)mfwI$HHk6k6N@)YZS(Dd1xW)D$ma!WjQGknPKQ=wxN0XA4 zh#rJ}vNyV_v?JHfBGGg6o&72nZwn=>>X-~?j@zMqA;# z)4|a|jZv^iyDO>6%`dc7(g37B(KVs(ilT-^p+d$sERLpDf7=eF4Y9M^K{J?TMb2b7 zO=p5OueUQ~ySL14mbXW-;o5DQ0$p1?6MA94Y|UGdX9Fg#;uAg z)|$O>>CoFYu!gkRxng^EtEPmMnXSZHrQOuLP zX%i;zoA2neSk@V56J+U`B|WLt-Nby8==TzBBj9?uT}8w;tg%`GP`Yj8nS-R4HbFjn zsn^14wo$#3=sL0nk7GNGgn9s^cs!*wr-qPmZocjE9SPOFSW9_kuF}vLyVc8}v*&4h z70qa?jD#A|w8SwilQS!bM~n$$61Aa*H{V-_^n0pi7xutb z$IW+s;36S4q&6OdDN}n|F`TE^*tKGC2>BT&+EkY3(lA4e)-C7>2W|gy&lp;5RTK=7 zj?u2EZ~ss8V0(x3y+E5aGW$(Vk+$vTWp?w)eia0?(^gw0C-g8F#%xJ@AM9A>aw@9h zBGzt~BRd^W53$gQ26aS|$i`xGuS~B#%5}Uw{PHLtFv%Qn+H;)B=Ba{?-9#BDissE< z>sJAgz~m{Sn5AAhiraTLFG}}ZLM^z(1MFGso$}nk!rDvRIF~jMn(-NHATC`#O@5hGLa5!FXV8aaRP+L@!Z@#C`Vt0QTBIvS~ zZEZXJ)J0BX9s}LupmprYVSv*c8^fLuA6*M63%yHZh?|WF>uD}Z9z9&?cuE{PEk!$| z(7>`gTbf#Y0#@0&`QFRZX*^(7?rcw54EMA?;hAl#zjRdl3-0QR{^ko$s|bi>PCaM# z!MD~3TXr!vPH#(4;jx2H$8_nQwPB0}Gumvqzv0Up!`84l&&~HVg73cdo5Rs{&Y;5H zddC2f9v>V!2lml3JBG3u$q7@-dlVk9>$F!xcVG;~9eu-=dvzP)6UWXxGJGp{r`5xB zo^(oN8105;jeYZdmrrENg$`GllZJ*3Lye#@Qu|k`xpn?KX6f4Orji}kWijmio3(XO>Au)*E5DKc;Kv}wdR4R8Cqw#+PhA z+$M~e^XQ!-DSMnY;ls);;wV~#Ex6LwvFN6oAG~~1HKrzWYPU(D)E{E?w_%(^TP__q z_wOYF@Sv7?_NpCTAp|W3xDigq~fUG)-C2j$1vPPyx94 zp%1)o+&_eR@W%WHE|(OkaoU7lx(QYe^NTPonlM5anl520dsfe~ZLBSPrq6{t#zk|{ zSi1=z4&vK`tl8}#QTMQNHo}cCqePp7Tf@1vQru4G6V5b+AQ`vawDulSv|0O0 zRu#$R$RLf+-B)&jY1vC2ilKx+Yxb47zc6XLE>fC?Ot>`LDGfS<4{Hs>Rg;)^Q*`z| z0O%wgVqkNy?H;wf`)uX&ALo}mdi8b7yW^FIKEoGsyz=1J=%0Fg4Hwv-?pM)HK0V;U zh9+e{yE%R}ea}J>1hF}KSh=(vyx8{|aC&kSPzThvM|-PH<%Me(=ajQs^f)e>Sg_@7 zg0)XaNi@4{*-q+%7)_VE`6rJr>9IXPYUT>&N<2L)w9%zQ&ooKQOoLKhirsGRbH=j5 zm;&u8&=s+NGfZy@<(db2=;XbaCfSSDC?x}Io?`a)B+p)4$NQDgx%ruk$OR@Vtms&% zDF99fcy)sgKy1B003Ij`yblZInWx(X+tQQJ%X>rFmas1O982lhMUL&xYe^6GW%QDv z{n6WU$r&eHn%B8T-2C0<{iVeQ>=iyvq*1i6hb3J>cA!tM9+@589T2X~@$6-5y7MIG zMQ%r+GjuOWg^T-gp^!`=04%fDD+Y@^7EQ0&gST{f0XVDh!QN4tU_FY&I zOIF(g?ATK~x0faJ?B4v7waOYsdGlk;SJ(57>t$XQ;|wvE&YVCwX%VMqKpePdM9FDV z3DMBv)vVMLfWkNb`xjip)$y19!*+QaioQAxrA0V((zu&4QHdAcBT%+r6fi^6n_{(_&Rl|j&()9lemE~mKpx&B1RJ%!wR zl{Es_T)jz?q=9`!MN2Ybo3J{Vj1O}47&8I-HVYi9+rqkR=nDog8bYkCtmJ;?tfr){ zR=y~6&Vh=AmX&i2WW4!%{fS_ADAN3&Ae*IiT9l;IM2KNqIxxi%b5n*o30z}{+rZ3}8sS<%oxEx&K6nEk z%u3dsE021po`&SvTrF$-%(NAUXU}?84nogb=u9EVo5mREOF}qLa~^wtKl>6g%rqkp z`?jfNH(&mR7cW!Xrciy)^$F`TSm(DTvpw_=>&)-BCxoLfIJ?!mV^hhkH`en0;&=E4&mM_!kDIi=PuMcEG&nc^=Y=zUd>&}3$f0$_=?su&kA$8$ zTlU33)U|pHkTILAxff*b<906}WX2ieq+?l@9$~E7Rh0c;998UjrOR2fW5D~uurYdq zvGOF|{9pYlMrVoaHmV?VWo=G)OUcw+2k=N5wEF&Qm;XAl_%wiY`bXx9Wy`crL5QOb zP)C~zh-On)d28naLQPsDu?H<^SkBQllGbVDH$QgKv>sB(OkX*1bts(s9y|ajqB{`) z-{Um9p$CW^KxGTtXR`+f*d1Tr=$rL$@eoAnK$M=wS6_0?Wt!!YTo(a@uGY%Ax6@B6 z0ng2k_p7M6M>V?8TNTffq5U^6kAAbqqRD7=(3<_Q zR(~m%)I1f791;5RPAh0|J8(2tm#Il6f^qZr`&FDZ*8=ly<+$6{%a&o#@_EIFCG#){QVH=DB`}2MbYwIZXDWkI1y*$t?iyjJCp{_e!>h()oy;` z3$9_X@e7Tee*DstF4&tS(A{B6?+db2h@owgJl7p*gmr>~A=mO|wK%a_gOn?@|rtIM*g#rnMka(8WY3 zA?Tqkb5L6<8=X*>Ho^vlMnbEFrb;*Jj455oikA{x>zLlA*3-M;HvvWnlu*WK4BeN4 zBfF;8QMoc06brCm2vMarhON(g?tg+xqtAS~vvm+jPG52Vrqf35IYG?2O&H#~S1?nodMs73Ya2pBcC- zyWr0D>`9|F6sw$rgD@}{ghesSAkOpHvuYzJ?G|;;-E5+_6#_%%c9l^FqL+vZisPP` zKtaEaUc#bbQ4Pcxc-kN&3r1U`Dmf%IAQ&{GoyYJ;tx8j>#iZNlYt+b|3+J=x6X*JXY773|<*i%B zVp19V^iRIv8pf@^j;m<17wN7Q?;MWO1O0WayMTP8&^-D`gZILBD8p_$)^KWvnHg$Z zY+%tKYqnGqCt)w?Pyk;^XXq9#5EI8TZh@kXm- z6z15wi_Crcr^gfNohWFF>Qqbi=Lg7}^&N`u9eWSOCk77+gKt!} zK=z^9YZL5EOGUVBAaGE6n~rl*jmFql69l&o6*Qmz*%w^HF5@Flb+v*XsDT&0;uu%_TqjPMILs*e%$S?i zk}_?%OiG&T^s&3w@Up!79iQ+n#arTmS@(9CiRS2CQE5dtrWP?r4#jjKm(xA z?M{=ARw=KSrF5i|YL{6D;^12Yr>q0E3C;S18Ah1`BU2>qz8{$;M z(XhZy6}yWg2ed~v*Ig5_9t6+T8Ur>#85uZzmcC}RfE`f9ymT;q_pAZ{En8&Fwxor# z`rt7c0jyS^Oxix<(Y*%`Js!TiANjqHcXDr!d(XuSj{{h5sF^Q(Bd>TnLeKE4jBbyA zzWsKDmK8Kxk@Q|QD$yvk8N(Eny}^gb%j!c8XN7o{Jw9AP4B=v+X$V347d z7K)*Qm6D4f6Tlv+0_m3}l@bn)=(aUFL8&G-sfM#+3kwj)>OqR#Nm*5c?#D>0)HW;8D^#M&M6rZ9#_ROnx3;D{)+lq$*i0P6rmK}9-m8ohQC>N%R^BWFP@=|CsqKbA!r%Y= zgPA_05fS&OWAwx>Il$@`Gj|NXN<k>f*arY>v`*Cd0~etHWa(+RpB^EYOP3x1;i$H!YWk~*jG$XXG2_jE3(!C zKU+6U!7z(A?o{?}xsWu_`?dmMxH<%9Ddm_P@7BejNE_Bm(3&d1E$v2S8e5mlo_M7hnDYRJaLhzTlSpUAVR#{)2qN*S5J^Bf zIe`}3*2dGtMW6NfCPH3he(y%2(xva?74LZZGv&k1>2A*n5>FBdr#* zit%0!&bHwU>8r)#J_7H(s3i~Jyb)V1=J*O-F-;cye_M~eOm5gqAatF3do#vK(`}NaabrfL#0l-30>xr*1)VLFaScb zmTb~!Nt1Tg7XA-kU6AfPdi3y)?fu~Xop-i7Pfl#-n5GNg(JQV}^h|k%Uv)0S&#!}X z*>@Zb+J?#RT5B;t9&@KAO-0iYQjMzY;xN$7Vo-0D)p~=#iY$D}yN?#Q9eB8F#L z6ru~5HIS!3)ETM1=bcB%9rf_l!cLs9gtzF+XhER5buj2+4yAIzd}O8!mMko5FZeGT z=^}<75(E{RIVgRQbPr1GA!Hjm;e%!cue2yhEYPNQE!XuN0zGLvd+(!}aOxg=l2q)3gnX*LU}2n`eRp0(A3 ztunIA$xt5=HyHAqj^@Cy)(P}^0J9<(f~d5^mIQB+XM)DlBTw(Ue;oXlfJmv1V`lDw z?*>7*wyD89Ivd(kZ5-mjEXEDW{;kChd~4x{fSo0|_kc5gcvMf2BjoY0zj&{uZfhctTBVmwdy*qo z9VbsHAsL?yTop1Ka<4%@BohSmoftEd0_5M=U#F~z)c z=@M}6sI>sGrgnv<7qqDbjA|#s)~d6#oS>-GTo`_dJGIu$>jWng>iQVa35KkuZl&sU zvtcSVc

  • Addons Better Connected

    - Behavior packs run in isolated realms. @bedrock-core lets yours find each other, call each other, + Addons run in isolated realms. @bedrock-core lets yours find each other, call each other, share state, and draw custom UI the whole world can use.

    diff --git a/src/data/sections.ts b/src/data/sections.ts index 6aca4d7..8378c5a 100644 --- a/src/data/sections.ts +++ b/src/data/sections.ts @@ -55,16 +55,6 @@ export const sections: Section[] = [ icon: 'server', repo: `${GH}/server`, }, - { - id: 'sync', - label: 'sync', - pkg: '@bedrock-core/sync', - category: 'framework', - status: 'beta', - description: 'The script-event transport: bus, discovery, RPC, replicated state.', - icon: 'radio', - repo: `${GH}/server`, - }, { id: 'db', label: 'db', @@ -85,6 +75,16 @@ export const sections: Section[] = [ icon: 'activity', repo: `${GH}/server`, }, + { + id: 'sync', + label: 'sync', + pkg: '@bedrock-core/sync', + category: 'framework', + status: 'beta', + description: 'The script-event transport: bus, discovery, RPC, replicated state.', + icon: 'radio', + repo: `${GH}/server`, + }, // UI { @@ -93,7 +93,7 @@ export const sections: Section[] = [ pkg: '@bedrock-core/ui', category: 'ui', status: 'beta', - description: 'JSX screens for server forms and containers, drawn by the render pack.', + description: 'JSX screens, forms and containers.', icon: 'layout-panel-left', repo: `${GH}/ui`, }, diff --git a/src/theme/Footer/index.tsx b/src/theme/Footer/index.tsx index da796a1..40afe51 100644 --- a/src/theme/Footer/index.tsx +++ b/src/theme/Footer/index.tsx @@ -1,6 +1,7 @@ import type { ReactNode } from 'react'; import Link from '@docusaurus/Link'; import useBaseUrl from '@docusaurus/useBaseUrl'; +import ThemedImage from '@theme/ThemedImage'; import { categories, publishedSections, sectionsOf } from '../../data/sections'; import styles from './styles.module.css'; @@ -10,10 +11,13 @@ const community = [ { label: 'npm', href: 'https://www.npmjs.com/org/bedrock-core' }, ]; -// Site footer: wordmark and tagline on the left, one column per category on -// the right, copyright on a hairline. Columns come from src/data/sections.ts. +// Site footer: wordmark, tagline and author credit on the left, one column per +// category on the right, copyright on a hairline. Columns come from +// src/data/sections.ts. export default function Footer(): ReactNode { const wordmark = useBaseUrl('img/logo/title.png'); + const dravLight = useBaseUrl('img/drav/wordmark-light.svg'); + const dravDark = useBaseUrl('img/drav/wordmark-dark.svg'); const live = new Set(publishedSections.map((s) => s.id)); return (
    @@ -23,6 +27,10 @@ export default function Footer(): ReactNode { @bedrock-core

    Addons Better Connected

    + + by + +
    {categories.map((category) => ( diff --git a/src/theme/Footer/styles.module.css b/src/theme/Footer/styles.module.css index 35b255d..fc02032 100644 --- a/src/theme/Footer/styles.module.css +++ b/src/theme/Footer/styles.module.css @@ -15,6 +15,27 @@ letter-spacing: var(--tracking-heading); line-height: var(--leading-snug); } +.author { + display: inline-block; + margin-top: var(--space-3); + color: var(--text-faint); + font-size: var(--text-body-sm); + text-decoration: none; + transition: var(--transition-control); +} +.author:hover { color: var(--text-muted); text-decoration: none; } +/* The wordmark is scaled and dropped so its lettering shares the x-height and + baseline of the "by" beside it. In the 154-unit artwork the glyphs have a + 49.34-unit x-height and sit on a baseline 48 units above the bottom edge. */ +.authorMark { + height: 3.121ex; + width: auto; + margin-left: 0.45em; + vertical-align: -0.973ex; + opacity: 0.75; + transition: var(--transition-control); +} +.author:hover .authorMark { opacity: 1; } .spacer { flex: 1; } .col { display: grid; gap: var(--space-2); align-content: start; } .title { diff --git a/static/img/drav/wordmark-dark.svg b/static/img/drav/wordmark-dark.svg new file mode 100644 index 0000000..5c3ee51 --- /dev/null +++ b/static/img/drav/wordmark-dark.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/static/img/drav/wordmark-light.svg b/static/img/drav/wordmark-light.svg new file mode 100644 index 0000000..d10ce1b --- /dev/null +++ b/static/img/drav/wordmark-light.svg @@ -0,0 +1,5 @@ + + + + + From 82d9f768c24282ac44905ac72e685adcc80e4e38 Mon Sep 17 00:00:00 2001 From: DrAv0011 Date: Fri, 11 Sep 2026 08:39:23 +0200 Subject: [PATCH 23/48] chore: add a clean script that clears regenerated output Co-Authored-By: Claude Opus 5 (1M context) --- package.json | 103 +++++++++++++++++++++++----------------------- scripts/clean.mjs | 47 +++++++++++++++++++++ 2 files changed, 99 insertions(+), 51 deletions(-) create mode 100644 scripts/clean.mjs diff --git a/package.json b/package.json index fd509b1..2138ae2 100644 --- a/package.json +++ b/package.json @@ -1,53 +1,54 @@ { - "name": "@bedrock-core/docs", - "version": "1.0.0", - "private": true, - "scripts": { - "docusaurus": "docusaurus", - "start": "docusaurus start", - "build": "docusaurus build", - "swizzle": "docusaurus swizzle", - "deploy": "docusaurus deploy", - "clear": "docusaurus clear", - "serve": "docusaurus serve", - "write-translations": "docusaurus write-translations", - "write-heading-ids": "docusaurus write-heading-ids", - "typecheck": "tsc" - }, - "dependencies": { - "@docusaurus/core": "3.10.1", - "@docusaurus/faster": "^3.10.1", - "@docusaurus/plugin-client-redirects": "^3.10.1", - "@docusaurus/preset-classic": "3.10.1", - "@mdx-js/react": "^3.1.1", - "clsx": "^2.1.1", - "lucide-react": "^1.42.0", - "prism-react-renderer": "^2.4.1", - "react": "^19.2.6", - "react-dom": "^19.2.6" - }, - "devDependencies": { - "@docusaurus/eslint-plugin": "^3.10.1", - "@docusaurus/module-type-aliases": "3.10.1", - "@docusaurus/tsconfig": "3.10.1", - "@docusaurus/types": "3.10.1", - "docusaurus-plugin-llms": "^0.4.0", - "typescript": "~6.0.3" - }, - "browserslist": { - "production": [ - ">0.5%", - "not dead", - "not op_mini all" - ], - "development": [ - "last 3 chrome version", - "last 3 firefox version", - "last 5 safari version" - ] - }, - "engines": { - "node": ">=20.0" - }, - "packageManager": "yarn@4.10.3" + "name": "@bedrock-core/docs", + "version": "1.0.0", + "private": true, + "scripts": { + "docusaurus": "docusaurus", + "start": "docusaurus start", + "build": "docusaurus build", + "swizzle": "docusaurus swizzle", + "deploy": "docusaurus deploy", + "clear": "docusaurus clear", + "serve": "docusaurus serve", + "write-translations": "docusaurus write-translations", + "write-heading-ids": "docusaurus write-heading-ids", + "typecheck": "tsc", + "clean": "node scripts/clean.mjs" + }, + "dependencies": { + "@docusaurus/core": "3.10.1", + "@docusaurus/faster": "^3.10.1", + "@docusaurus/plugin-client-redirects": "^3.10.1", + "@docusaurus/preset-classic": "3.10.1", + "@mdx-js/react": "^3.1.1", + "clsx": "^2.1.1", + "lucide-react": "^1.42.0", + "prism-react-renderer": "^2.4.1", + "react": "^19.2.6", + "react-dom": "^19.2.6" + }, + "devDependencies": { + "@docusaurus/eslint-plugin": "^3.10.1", + "@docusaurus/module-type-aliases": "3.10.1", + "@docusaurus/tsconfig": "3.10.1", + "@docusaurus/types": "3.10.1", + "docusaurus-plugin-llms": "^0.4.0", + "typescript": "~6.0.3" + }, + "browserslist": { + "production": [ + ">0.5%", + "not dead", + "not op_mini all" + ], + "development": [ + "last 3 chrome version", + "last 3 firefox version", + "last 5 safari version" + ] + }, + "engines": { + "node": ">=20.0" + }, + "packageManager": "yarn@4.10.3" } diff --git a/scripts/clean.mjs b/scripts/clean.mjs new file mode 100644 index 0000000..4bd186a --- /dev/null +++ b/scripts/clean.mjs @@ -0,0 +1,47 @@ +/** + * Removes what an install or a build regenerates in this repository: the dependency tree, the + * rendered site, and Docusaurus’ own caches. + * + * yarn clean + * + * Sources, configuration and anything git tracks are never touched. + */ +import { existsSync, readdirSync, rmSync } from 'node:fs'; +import { dirname, join, relative } from 'node:path'; +import { fileURLToPath } from 'node:url'; + +/** Directory names a tool here rewrites from scratch, wherever they appear. */ +const DISPOSABLE = new Set(['node_modules', 'build', '.docusaurus', '.cache-loader']); + +/** Never descended into: it holds the repository itself, not anything regenerable. */ +const SKIP = new Set(['.git']); + +const root = join(dirname(fileURLToPath(import.meta.url)), '..'); + +let removed = 0; + +function drop(target) { + rmSync(target, { recursive: true, force: true }); + console.log(`removed ${relative(root, target)}`); + removed++; +} + +/** Depth-first, and a disposable directory is dropped whole rather than walked into. */ +function sweep(dir) { + for (const entry of readdirSync(dir, { withFileTypes: true })) { + const target = join(dir, entry.name); + + if (entry.isDirectory()) { + if (SKIP.has(entry.name)) continue; + + if (DISPOSABLE.has(entry.name)) { drop(target); continue; } + + sweep(target); + continue; + } + } +} + +sweep(root); + +console.log(removed === 0 ? 'nothing to remove' : `${removed} ${removed === 1 ? 'path' : 'paths'} removed`); From bfbf7f352fdd93bc035ce048eed1df13256a4752 Mon Sep 17 00:00:00 2001 From: DrAv0011 Date: Sat, 12 Sep 2026 11:51:37 +0200 Subject: [PATCH 24/48] chore(deps): move the Docusaurus packages to ^3.10.2 Co-Authored-By: Claude Opus 5 (1M context) --- package.json | 16 +- yarn.lock | 781 ++++++++++++++++++++++++++------------------------- 2 files changed, 400 insertions(+), 397 deletions(-) diff --git a/package.json b/package.json index 2138ae2..3815cc4 100644 --- a/package.json +++ b/package.json @@ -16,10 +16,10 @@ "clean": "node scripts/clean.mjs" }, "dependencies": { - "@docusaurus/core": "3.10.1", - "@docusaurus/faster": "^3.10.1", - "@docusaurus/plugin-client-redirects": "^3.10.1", - "@docusaurus/preset-classic": "3.10.1", + "@docusaurus/core": "^3.10.2", + "@docusaurus/faster": "^3.10.2", + "@docusaurus/plugin-client-redirects": "^3.10.2", + "@docusaurus/preset-classic": "^3.10.2", "@mdx-js/react": "^3.1.1", "clsx": "^2.1.1", "lucide-react": "^1.42.0", @@ -28,10 +28,10 @@ "react-dom": "^19.2.6" }, "devDependencies": { - "@docusaurus/eslint-plugin": "^3.10.1", - "@docusaurus/module-type-aliases": "3.10.1", - "@docusaurus/tsconfig": "3.10.1", - "@docusaurus/types": "3.10.1", + "@docusaurus/eslint-plugin": "^3.10.2", + "@docusaurus/module-type-aliases": "^3.10.2", + "@docusaurus/tsconfig": "^3.10.2", + "@docusaurus/types": "^3.10.2", "docusaurus-plugin-llms": "^0.4.0", "typescript": "~6.0.3" }, diff --git a/yarn.lock b/yarn.lock index 9febc10..25171c5 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5,6 +5,18 @@ __metadata: version: 8 cacheKey: 10c0 +"@11ty/gray-matter@npm:^1.0.0": + version: 1.0.0 + resolution: "@11ty/gray-matter@npm:1.0.0" + dependencies: + js-yaml: "npm:^4.1.0" + kind-of: "npm:^6.0.3" + section-matter: "npm:^1.0.0" + strip-bom-string: "npm:^1.0.0" + checksum: 10c0/734361398905ff53ab5827d870bf83e010567f0b397ee853b67b749f76c2ae4be21eda4f2eb0e3909609cd22962adc377fbbf9ceb7e86cc5dd5cce48bd2bcfb9 + languageName: node + linkType: hard + "@algolia/abtesting@npm:1.8.0": version: 1.8.0 resolution: "@algolia/abtesting@npm:1.8.0" @@ -1492,14 +1504,14 @@ __metadata: version: 0.0.0-use.local resolution: "@bedrock-core/docs@workspace:." dependencies: - "@docusaurus/core": "npm:3.10.1" - "@docusaurus/eslint-plugin": "npm:^3.10.1" - "@docusaurus/faster": "npm:^3.10.1" - "@docusaurus/module-type-aliases": "npm:3.10.1" - "@docusaurus/plugin-client-redirects": "npm:^3.10.1" - "@docusaurus/preset-classic": "npm:3.10.1" - "@docusaurus/tsconfig": "npm:3.10.1" - "@docusaurus/types": "npm:3.10.1" + "@docusaurus/core": "npm:^3.10.2" + "@docusaurus/eslint-plugin": "npm:^3.10.2" + "@docusaurus/faster": "npm:^3.10.2" + "@docusaurus/module-type-aliases": "npm:^3.10.2" + "@docusaurus/plugin-client-redirects": "npm:^3.10.2" + "@docusaurus/preset-classic": "npm:^3.10.2" + "@docusaurus/tsconfig": "npm:^3.10.2" + "@docusaurus/types": "npm:^3.10.2" "@mdx-js/react": "npm:^3.1.1" clsx: "npm:^2.1.1" docusaurus-plugin-llms: "npm:^0.4.0" @@ -2125,9 +2137,9 @@ __metadata: languageName: node linkType: hard -"@docusaurus/babel@npm:3.10.1": - version: 3.10.1 - resolution: "@docusaurus/babel@npm:3.10.1" +"@docusaurus/babel@npm:3.10.2": + version: 3.10.2 + resolution: "@docusaurus/babel@npm:3.10.2" dependencies: "@babel/core": "npm:^7.25.9" "@babel/generator": "npm:^7.25.9" @@ -2138,25 +2150,25 @@ __metadata: "@babel/preset-typescript": "npm:^7.25.9" "@babel/runtime": "npm:^7.25.9" "@babel/traverse": "npm:^7.25.9" - "@docusaurus/logger": "npm:3.10.1" - "@docusaurus/utils": "npm:3.10.1" + "@docusaurus/logger": "npm:3.10.2" + "@docusaurus/utils": "npm:3.10.2" babel-plugin-dynamic-import-node: "npm:^2.3.3" fs-extra: "npm:^11.1.1" tslib: "npm:^2.6.0" - checksum: 10c0/3f6d2fdd6bc9c3a47683c1517e2afc7bca4b95d7b1817d68e91c1c2eaf944971d925ec03f2de8d88d40f97a0d88a1415cb2b9c64ac335c7cb6e37e6258c6f97a + checksum: 10c0/5d6f5938bc3220e8f3664169e77ee0b1f11423a9adfc19409f8e7b3f4264afa8e8cd111f744fe54562278a8b276f6b4b6506f509cfdc3c31cc2ade36a6171dbd languageName: node linkType: hard -"@docusaurus/bundler@npm:3.10.1": - version: 3.10.1 - resolution: "@docusaurus/bundler@npm:3.10.1" +"@docusaurus/bundler@npm:3.10.2": + version: 3.10.2 + resolution: "@docusaurus/bundler@npm:3.10.2" dependencies: "@babel/core": "npm:^7.25.9" - "@docusaurus/babel": "npm:3.10.1" - "@docusaurus/cssnano-preset": "npm:3.10.1" - "@docusaurus/logger": "npm:3.10.1" - "@docusaurus/types": "npm:3.10.1" - "@docusaurus/utils": "npm:3.10.1" + "@docusaurus/babel": "npm:3.10.2" + "@docusaurus/cssnano-preset": "npm:3.10.2" + "@docusaurus/logger": "npm:3.10.2" + "@docusaurus/types": "npm:3.10.2" + "@docusaurus/utils": "npm:3.10.2" babel-loader: "npm:^9.2.1" clean-css: "npm:^5.3.3" copy-webpack-plugin: "npm:^11.0.0" @@ -2180,21 +2192,21 @@ __metadata: peerDependenciesMeta: "@docusaurus/faster": optional: true - checksum: 10c0/20655bd64a5716cc3603d9097e7ca3d2526ccd7265ce3e9d23dfc9679faa08752a5604b98ba2b47eea5e183a3c4f0e383300899ae2f3897513493ec97a6beab2 + checksum: 10c0/141513e97d317ba2c2e2793dd4abae12b72132cf8e7c61e8f1d8d3521b6c6b162a5c5aa36ab02fbc41bad01bd8a50978133d58c9c420f1e10ec937a6d8b75109 languageName: node linkType: hard -"@docusaurus/core@npm:3.10.1": - version: 3.10.1 - resolution: "@docusaurus/core@npm:3.10.1" +"@docusaurus/core@npm:3.10.2, @docusaurus/core@npm:^3.10.2": + version: 3.10.2 + resolution: "@docusaurus/core@npm:3.10.2" dependencies: - "@docusaurus/babel": "npm:3.10.1" - "@docusaurus/bundler": "npm:3.10.1" - "@docusaurus/logger": "npm:3.10.1" - "@docusaurus/mdx-loader": "npm:3.10.1" - "@docusaurus/utils": "npm:3.10.1" - "@docusaurus/utils-common": "npm:3.10.1" - "@docusaurus/utils-validation": "npm:3.10.1" + "@docusaurus/babel": "npm:3.10.2" + "@docusaurus/bundler": "npm:3.10.2" + "@docusaurus/logger": "npm:3.10.2" + "@docusaurus/mdx-loader": "npm:3.10.2" + "@docusaurus/utils": "npm:3.10.2" + "@docusaurus/utils-common": "npm:3.10.2" + "@docusaurus/utils-validation": "npm:3.10.2" boxen: "npm:^6.2.1" chalk: "npm:^4.1.2" chokidar: "npm:^3.5.3" @@ -2202,7 +2214,7 @@ __metadata: combine-promises: "npm:^1.1.0" commander: "npm:^5.1.0" core-js: "npm:^3.31.1" - detect-port: "npm:^1.5.1" + detect-port: "npm:^2.1.0" escape-html: "npm:^1.0.3" eta: "npm:^2.2.0" eval: "npm:^0.1.8" @@ -2240,42 +2252,42 @@ __metadata: optional: true bin: docusaurus: bin/docusaurus.mjs - checksum: 10c0/006d9f57357c3196d0c33f7c5d0ce33b9f032358ed070b8ce212186169c356847cf768b3ac95b54433815c0076eda2eb94805a64bf4b2f5e47376556164e5362 + checksum: 10c0/e788635b2b6705fb6ecb6ba22f09930eed0148f4e27ee5c435742e1228e27ab2aeb539bc623355e0edba2978bffde60ead1eff2464283f3a0d14eaeb108131e4 languageName: node linkType: hard -"@docusaurus/cssnano-preset@npm:3.10.1": - version: 3.10.1 - resolution: "@docusaurus/cssnano-preset@npm:3.10.1" +"@docusaurus/cssnano-preset@npm:3.10.2": + version: 3.10.2 + resolution: "@docusaurus/cssnano-preset@npm:3.10.2" dependencies: cssnano-preset-advanced: "npm:^6.1.2" postcss: "npm:^8.5.4" postcss-sort-media-queries: "npm:^5.2.0" tslib: "npm:^2.6.0" - checksum: 10c0/549cf594fd9cfddd2f57bd177896c6bde8cc3821f7f07e7573d55d4c5841d7eb90d38c1b888b81479ffe33f0015b848c031ad4185f54feedf8ae2f1e2269e2ce + checksum: 10c0/55d288fbe37abcac181323c59c03bb7c53f0f34531abe1bf35f537e4c926a6b97b8c597fd6044344b16fd5aa40f7a566032576857d0fa7c121651569631936ea languageName: node linkType: hard -"@docusaurus/eslint-plugin@npm:^3.10.1": - version: 3.10.1 - resolution: "@docusaurus/eslint-plugin@npm:3.10.1" +"@docusaurus/eslint-plugin@npm:^3.10.2": + version: 3.10.2 + resolution: "@docusaurus/eslint-plugin@npm:3.10.2" dependencies: "@typescript-eslint/utils": "npm:^5.62.0" tslib: "npm:^2.6.0" peerDependencies: eslint: ">=6" - checksum: 10c0/9bf1e38513222a0c5a8dd3b056a383f4d21ffcc225e15b5b641dabfd4b10d68e889739d590b4f1bd2a7b06c9fc886090a27dd2deef86ef7e9fc3362460d7e9ba + checksum: 10c0/d1a26dab5434fc1651d9243453cec146bef1a04d9d613402ad17e9b0ad8ef7f0c0af427095d8635990b3cf4b0878bba1a0ee7e11e041b5a612d06850279bcd43 languageName: node linkType: hard -"@docusaurus/faster@npm:^3.10.1": - version: 3.10.1 - resolution: "@docusaurus/faster@npm:3.10.1" +"@docusaurus/faster@npm:^3.10.2": + version: 3.10.2 + resolution: "@docusaurus/faster@npm:3.10.2" dependencies: - "@docusaurus/types": "npm:3.10.1" + "@docusaurus/types": "npm:3.10.2" "@rspack/core": "npm:^1.7.10" - "@swc/core": "npm:^1.7.39" - "@swc/html": "npm:^1.13.5" + "@swc/core": "npm:^1.15.40" + "@swc/html": "npm:^1.15.40" browserslist: "npm:^4.24.2" lightningcss: "npm:^1.27.0" semver: "npm:^7.5.4" @@ -2284,27 +2296,27 @@ __metadata: webpack: "npm:^5.95.0" peerDependencies: "@docusaurus/types": "*" - checksum: 10c0/98d8ca36cd4bcd775be37109c8cd3117ff8ba62446ec50b2901bca7653fbbf690ec9aa494524a27c17744a1744a3e520804100aba014e7aa5621ef3df4679359 + checksum: 10c0/52a8942243839981d5896b7ff117d9ed09584d2a6ae5c2f525b1bc7907b58f3b15d654951ab777e6c33c1d04b6943bbf41589922786b76c9abe1632c265f0ef8 languageName: node linkType: hard -"@docusaurus/logger@npm:3.10.1": - version: 3.10.1 - resolution: "@docusaurus/logger@npm:3.10.1" +"@docusaurus/logger@npm:3.10.2": + version: 3.10.2 + resolution: "@docusaurus/logger@npm:3.10.2" dependencies: chalk: "npm:^4.1.2" tslib: "npm:^2.6.0" - checksum: 10c0/c78c676de0cf11ba5737abe8d13ebb67c4fdd8019ac8512ee18b34c27fdd5aaf32b703da3596271592be8615094507754791ac16587a24146f3830e1558a24c3 + checksum: 10c0/77f4751a9b7dba4b40f61c859f1696c0eb3b180551e73f4af624481e4f17613523ca6d2a9e2595dc9e5a9908a44c1d90f61455d970bbeee47b509cacea76dc7e languageName: node linkType: hard -"@docusaurus/mdx-loader@npm:3.10.1": - version: 3.10.1 - resolution: "@docusaurus/mdx-loader@npm:3.10.1" +"@docusaurus/mdx-loader@npm:3.10.2": + version: 3.10.2 + resolution: "@docusaurus/mdx-loader@npm:3.10.2" dependencies: - "@docusaurus/logger": "npm:3.10.1" - "@docusaurus/utils": "npm:3.10.1" - "@docusaurus/utils-validation": "npm:3.10.1" + "@docusaurus/logger": "npm:3.10.2" + "@docusaurus/utils": "npm:3.10.2" + "@docusaurus/utils-validation": "npm:3.10.2" "@mdx-js/mdx": "npm:^3.0.0" "@slorber/remark-comment": "npm:^1.0.0" escape-html: "npm:^1.0.3" @@ -2329,15 +2341,15 @@ __metadata: peerDependencies: react: ^18.0.0 || ^19.0.0 react-dom: ^18.0.0 || ^19.0.0 - checksum: 10c0/2764e3e1a6fc4856746aacd627d43a403cbad87d6ec7400d30092197f36c028207cc5d267e0af2ce34df31f0a68bb2f082bbd5d308d14bedc0d874bc95a89c7b + checksum: 10c0/eb37eebb858319d55d1493724a92dee6325d24f4badb334095d41260b0cb9601c4a9f64d4718616dc4c6829f5c062f91799452c1390c2b019f604ddc1c67a026 languageName: node linkType: hard -"@docusaurus/module-type-aliases@npm:3.10.1": - version: 3.10.1 - resolution: "@docusaurus/module-type-aliases@npm:3.10.1" +"@docusaurus/module-type-aliases@npm:3.10.2, @docusaurus/module-type-aliases@npm:^3.10.2": + version: 3.10.2 + resolution: "@docusaurus/module-type-aliases@npm:3.10.2" dependencies: - "@docusaurus/types": "npm:3.10.1" + "@docusaurus/types": "npm:3.10.2" "@types/history": "npm:^4.7.11" "@types/react": "npm:*" "@types/react-router-config": "npm:*" @@ -2347,19 +2359,19 @@ __metadata: peerDependencies: react: "*" react-dom: "*" - checksum: 10c0/837faf66e24b9b0e2d2d276956f00cf5395a752682396013876935b6b0275b573d4cc3e9667a5110f9077c5943ddd1f47b462217a8418a5e6bdd013de8afd918 + checksum: 10c0/3a6a4cc350c48a4e4ba6826976f24e15fc833509533a958252f84b71f7b742d2d65813dde2bb0bc84f44b6918c891997b0fc4174d4b83edb0ef6aeed3330ca13 languageName: node linkType: hard -"@docusaurus/plugin-client-redirects@npm:^3.10.1": - version: 3.10.1 - resolution: "@docusaurus/plugin-client-redirects@npm:3.10.1" +"@docusaurus/plugin-client-redirects@npm:^3.10.2": + version: 3.10.2 + resolution: "@docusaurus/plugin-client-redirects@npm:3.10.2" dependencies: - "@docusaurus/core": "npm:3.10.1" - "@docusaurus/logger": "npm:3.10.1" - "@docusaurus/utils": "npm:3.10.1" - "@docusaurus/utils-common": "npm:3.10.1" - "@docusaurus/utils-validation": "npm:3.10.1" + "@docusaurus/core": "npm:3.10.2" + "@docusaurus/logger": "npm:3.10.2" + "@docusaurus/utils": "npm:3.10.2" + "@docusaurus/utils-common": "npm:3.10.2" + "@docusaurus/utils-validation": "npm:3.10.2" eta: "npm:^2.2.0" fs-extra: "npm:^11.1.1" lodash: "npm:^4.17.21" @@ -2367,22 +2379,22 @@ __metadata: peerDependencies: react: ^18.0.0 || ^19.0.0 react-dom: ^18.0.0 || ^19.0.0 - checksum: 10c0/0bcd7387b6ae3132ab76c7715d440bb6b769ab509fa241720a90575b01541eefe3cd47281da812c546db0e31cffc002c4fb8629430fd1191e5d6f27ef2037483 + checksum: 10c0/ab5ded6b97561047d35edf7fb6bee7e7bd795a38223873c89824e06597e762628d1ce3e72cf2c8c212c5579406a026bbacb3392d9c3b6dccbcace8239cd48801 languageName: node linkType: hard -"@docusaurus/plugin-content-blog@npm:3.10.1": - version: 3.10.1 - resolution: "@docusaurus/plugin-content-blog@npm:3.10.1" +"@docusaurus/plugin-content-blog@npm:3.10.2": + version: 3.10.2 + resolution: "@docusaurus/plugin-content-blog@npm:3.10.2" dependencies: - "@docusaurus/core": "npm:3.10.1" - "@docusaurus/logger": "npm:3.10.1" - "@docusaurus/mdx-loader": "npm:3.10.1" - "@docusaurus/theme-common": "npm:3.10.1" - "@docusaurus/types": "npm:3.10.1" - "@docusaurus/utils": "npm:3.10.1" - "@docusaurus/utils-common": "npm:3.10.1" - "@docusaurus/utils-validation": "npm:3.10.1" + "@docusaurus/core": "npm:3.10.2" + "@docusaurus/logger": "npm:3.10.2" + "@docusaurus/mdx-loader": "npm:3.10.2" + "@docusaurus/theme-common": "npm:3.10.2" + "@docusaurus/types": "npm:3.10.2" + "@docusaurus/utils": "npm:3.10.2" + "@docusaurus/utils-common": "npm:3.10.2" + "@docusaurus/utils-validation": "npm:3.10.2" cheerio: "npm:1.0.0-rc.12" combine-promises: "npm:^1.1.0" feed: "npm:^4.2.2" @@ -2398,23 +2410,23 @@ __metadata: "@docusaurus/plugin-content-docs": "*" react: ^18.0.0 || ^19.0.0 react-dom: ^18.0.0 || ^19.0.0 - checksum: 10c0/5c6d912bbcbbc9efa5c81e256f4074e70980c85623f5fd72a344b90bd5f23ed2c03030d8d0cb1ce38bdb2263fdf74ac3e7801a66050184ed11005adc5f49bcb2 + checksum: 10c0/ef6b0aae35854fdc41e6e10b4e4fad837134e0431aee12324d94b3898db3048dba56316e172f878b97c575a1696242446e29554a6e900c7519eaa5c88b6d46ff languageName: node linkType: hard -"@docusaurus/plugin-content-docs@npm:3.10.1": - version: 3.10.1 - resolution: "@docusaurus/plugin-content-docs@npm:3.10.1" +"@docusaurus/plugin-content-docs@npm:3.10.2": + version: 3.10.2 + resolution: "@docusaurus/plugin-content-docs@npm:3.10.2" dependencies: - "@docusaurus/core": "npm:3.10.1" - "@docusaurus/logger": "npm:3.10.1" - "@docusaurus/mdx-loader": "npm:3.10.1" - "@docusaurus/module-type-aliases": "npm:3.10.1" - "@docusaurus/theme-common": "npm:3.10.1" - "@docusaurus/types": "npm:3.10.1" - "@docusaurus/utils": "npm:3.10.1" - "@docusaurus/utils-common": "npm:3.10.1" - "@docusaurus/utils-validation": "npm:3.10.1" + "@docusaurus/core": "npm:3.10.2" + "@docusaurus/logger": "npm:3.10.2" + "@docusaurus/mdx-loader": "npm:3.10.2" + "@docusaurus/module-type-aliases": "npm:3.10.2" + "@docusaurus/theme-common": "npm:3.10.2" + "@docusaurus/types": "npm:3.10.2" + "@docusaurus/utils": "npm:3.10.2" + "@docusaurus/utils-common": "npm:3.10.2" + "@docusaurus/utils-validation": "npm:3.10.2" "@types/react-router-config": "npm:^5.0.7" combine-promises: "npm:^1.1.0" fs-extra: "npm:^11.1.1" @@ -2427,133 +2439,132 @@ __metadata: peerDependencies: react: ^18.0.0 || ^19.0.0 react-dom: ^18.0.0 || ^19.0.0 - checksum: 10c0/a9d78f6979cc64aef1210f51979f2ed5100ce4a49ba266386e35e9109e4415e66bd9a9448696078f247d204949a29197faa9396bd1f014c88fcdd1aa1e98a3f8 + checksum: 10c0/800674266633e204bfddddd7ce0a35cfbe308b0f05191e96be02d4968c2b0c92e677887dd4ddfc3cecbb0ae46e7e1248084c5a00a9db798274faa9531ed17f48 languageName: node linkType: hard -"@docusaurus/plugin-content-pages@npm:3.10.1": - version: 3.10.1 - resolution: "@docusaurus/plugin-content-pages@npm:3.10.1" +"@docusaurus/plugin-content-pages@npm:3.10.2": + version: 3.10.2 + resolution: "@docusaurus/plugin-content-pages@npm:3.10.2" dependencies: - "@docusaurus/core": "npm:3.10.1" - "@docusaurus/mdx-loader": "npm:3.10.1" - "@docusaurus/types": "npm:3.10.1" - "@docusaurus/utils": "npm:3.10.1" - "@docusaurus/utils-validation": "npm:3.10.1" + "@docusaurus/core": "npm:3.10.2" + "@docusaurus/mdx-loader": "npm:3.10.2" + "@docusaurus/types": "npm:3.10.2" + "@docusaurus/utils": "npm:3.10.2" + "@docusaurus/utils-validation": "npm:3.10.2" fs-extra: "npm:^11.1.1" tslib: "npm:^2.6.0" webpack: "npm:^5.88.1" peerDependencies: react: ^18.0.0 || ^19.0.0 react-dom: ^18.0.0 || ^19.0.0 - checksum: 10c0/00dab7af101b0607746d820c399bc3062279165b1b79009f2c6c8439a627818748da52f43eee0a4a874923707c89c9fce17aab72a7c88d298fa36b6efc0bacc7 + checksum: 10c0/68974ebe1446813f37cff5aa77163dfd82b46e62e724b829b7fc1461a33c5e54391699b3adf9ff9696f6d5bd1da50df8c66299ed3a6db3f7c2ca6356e77a6118 languageName: node linkType: hard -"@docusaurus/plugin-css-cascade-layers@npm:3.10.1": - version: 3.10.1 - resolution: "@docusaurus/plugin-css-cascade-layers@npm:3.10.1" +"@docusaurus/plugin-css-cascade-layers@npm:3.10.2": + version: 3.10.2 + resolution: "@docusaurus/plugin-css-cascade-layers@npm:3.10.2" dependencies: - "@docusaurus/core": "npm:3.10.1" - "@docusaurus/types": "npm:3.10.1" - "@docusaurus/utils": "npm:3.10.1" - "@docusaurus/utils-validation": "npm:3.10.1" + "@docusaurus/core": "npm:3.10.2" + "@docusaurus/types": "npm:3.10.2" + "@docusaurus/utils": "npm:3.10.2" + "@docusaurus/utils-validation": "npm:3.10.2" tslib: "npm:^2.6.0" - checksum: 10c0/fd11a7488029226276bbdbeb1de4035ed425b8d7be0fbad3d5a0aa3a18646064f1930835bfc951837bfc813873548e1a8b23d9f52cb20120e1239a1d93128d79 + checksum: 10c0/2c7429b24edc1ef02aaa8e26734a429f117eb053e43b9b8a586be5285a897236560e7e0174277abedf6c364ccd10850dc728d851e48075eca3afbe1ac0ec77e3 languageName: node linkType: hard -"@docusaurus/plugin-debug@npm:3.10.1": - version: 3.10.1 - resolution: "@docusaurus/plugin-debug@npm:3.10.1" +"@docusaurus/plugin-debug@npm:3.10.2": + version: 3.10.2 + resolution: "@docusaurus/plugin-debug@npm:3.10.2" dependencies: - "@docusaurus/core": "npm:3.10.1" - "@docusaurus/types": "npm:3.10.1" - "@docusaurus/utils": "npm:3.10.1" + "@docusaurus/core": "npm:3.10.2" + "@docusaurus/types": "npm:3.10.2" + "@docusaurus/utils": "npm:3.10.2" fs-extra: "npm:^11.1.1" react-json-view-lite: "npm:^2.3.0" tslib: "npm:^2.6.0" peerDependencies: react: ^18.0.0 || ^19.0.0 react-dom: ^18.0.0 || ^19.0.0 - checksum: 10c0/d2978e40e83c1c4fd904dc3bc62ef1b6d52cf28e391e9dacad40712d7b14ce9ad22f0ad710631021066c296d10c364621b2c11a186694d8f5c6e59f35043f99a + checksum: 10c0/df6acce06f265a65a46986a2d47d60546a13b03b3204c472ff9e48b38cb140c939b6a8249e7aba64c387aa63ffdbd2122194e55f617dc34414303421dbb82554 languageName: node linkType: hard -"@docusaurus/plugin-google-analytics@npm:3.10.1": - version: 3.10.1 - resolution: "@docusaurus/plugin-google-analytics@npm:3.10.1" +"@docusaurus/plugin-google-analytics@npm:3.10.2": + version: 3.10.2 + resolution: "@docusaurus/plugin-google-analytics@npm:3.10.2" dependencies: - "@docusaurus/core": "npm:3.10.1" - "@docusaurus/types": "npm:3.10.1" - "@docusaurus/utils-validation": "npm:3.10.1" + "@docusaurus/core": "npm:3.10.2" + "@docusaurus/types": "npm:3.10.2" + "@docusaurus/utils-validation": "npm:3.10.2" tslib: "npm:^2.6.0" peerDependencies: react: ^18.0.0 || ^19.0.0 react-dom: ^18.0.0 || ^19.0.0 - checksum: 10c0/c9aff3f3467d3e76a1dd8e1518e8a11b0d488b1761f0302a6cc9fdb94635b6e5673b3d993434205dc65cd6eb9677f795157887d508f01ba175c3f5e411aab2e6 + checksum: 10c0/0b2f472203e16103ba8cebc3a32caddaecb783bca35162096ae6ad2d5fdcb724fcfce0b79682038394a664a0b38864e63e5e7a8d0d14024939891360e77ff49d languageName: node linkType: hard -"@docusaurus/plugin-google-gtag@npm:3.10.1": - version: 3.10.1 - resolution: "@docusaurus/plugin-google-gtag@npm:3.10.1" +"@docusaurus/plugin-google-gtag@npm:3.10.2": + version: 3.10.2 + resolution: "@docusaurus/plugin-google-gtag@npm:3.10.2" dependencies: - "@docusaurus/core": "npm:3.10.1" - "@docusaurus/types": "npm:3.10.1" - "@docusaurus/utils-validation": "npm:3.10.1" - "@types/gtag.js": "npm:^0.0.20" + "@docusaurus/core": "npm:3.10.2" + "@docusaurus/types": "npm:3.10.2" + "@docusaurus/utils-validation": "npm:3.10.2" tslib: "npm:^2.6.0" peerDependencies: react: ^18.0.0 || ^19.0.0 react-dom: ^18.0.0 || ^19.0.0 - checksum: 10c0/6792713f813cb06dcc54ece92ac81faed01017a71079726f97adade1fa2b6665626369c788e108dee9c02e0cbfc4cc71a2e87db5d3e43f47944e7b0921bb71db + checksum: 10c0/029b9b18e4c588daa0dd0cd79cb8b3682cc8c44a83b28f0179eb45c9717619e104d276df3f0ce7dadea01cdae4a61c8ef3fb993f59be5daa5365df3317ef2be8 languageName: node linkType: hard -"@docusaurus/plugin-google-tag-manager@npm:3.10.1": - version: 3.10.1 - resolution: "@docusaurus/plugin-google-tag-manager@npm:3.10.1" +"@docusaurus/plugin-google-tag-manager@npm:3.10.2": + version: 3.10.2 + resolution: "@docusaurus/plugin-google-tag-manager@npm:3.10.2" dependencies: - "@docusaurus/core": "npm:3.10.1" - "@docusaurus/types": "npm:3.10.1" - "@docusaurus/utils-validation": "npm:3.10.1" + "@docusaurus/core": "npm:3.10.2" + "@docusaurus/types": "npm:3.10.2" + "@docusaurus/utils-validation": "npm:3.10.2" tslib: "npm:^2.6.0" peerDependencies: react: ^18.0.0 || ^19.0.0 react-dom: ^18.0.0 || ^19.0.0 - checksum: 10c0/a1a01de5f876d63fec022d312c711525523ee380af3382e35d1953a577450da36039dfcd1ff7f0af0cd189cc14d268c64276def573bdc70d091db2cad56edf9f + checksum: 10c0/1cf911e6b91dd76fe8283d1c16643d1c46435fc03a89b786968b2f93606ae1af58c3cd1208f548e980025c45b4ff5c9b307be71ab56c0102c4c2e8e91f052370 languageName: node linkType: hard -"@docusaurus/plugin-sitemap@npm:3.10.1": - version: 3.10.1 - resolution: "@docusaurus/plugin-sitemap@npm:3.10.1" +"@docusaurus/plugin-sitemap@npm:3.10.2": + version: 3.10.2 + resolution: "@docusaurus/plugin-sitemap@npm:3.10.2" dependencies: - "@docusaurus/core": "npm:3.10.1" - "@docusaurus/logger": "npm:3.10.1" - "@docusaurus/types": "npm:3.10.1" - "@docusaurus/utils": "npm:3.10.1" - "@docusaurus/utils-common": "npm:3.10.1" - "@docusaurus/utils-validation": "npm:3.10.1" + "@docusaurus/core": "npm:3.10.2" + "@docusaurus/logger": "npm:3.10.2" + "@docusaurus/types": "npm:3.10.2" + "@docusaurus/utils": "npm:3.10.2" + "@docusaurus/utils-common": "npm:3.10.2" + "@docusaurus/utils-validation": "npm:3.10.2" fs-extra: "npm:^11.1.1" sitemap: "npm:^7.1.1" tslib: "npm:^2.6.0" peerDependencies: react: ^18.0.0 || ^19.0.0 react-dom: ^18.0.0 || ^19.0.0 - checksum: 10c0/22c04be000a1577f9a0c169fb67ff0d4deaf618aa2a3839336cfaed667558f1db3ada5bed23ee7245596a307bbddbed62ede8e342120aa8efebe0b9d35f4da75 + checksum: 10c0/4d1c28458303ec439ef31ab9f7f23a18e7ee2d355c4331a739a42aae9cf19f5506415ea631d7569580008e0215274c15f4148b84d6cd0c5f8dd208f7f49e7349 languageName: node linkType: hard -"@docusaurus/plugin-svgr@npm:3.10.1": - version: 3.10.1 - resolution: "@docusaurus/plugin-svgr@npm:3.10.1" +"@docusaurus/plugin-svgr@npm:3.10.2": + version: 3.10.2 + resolution: "@docusaurus/plugin-svgr@npm:3.10.2" dependencies: - "@docusaurus/core": "npm:3.10.1" - "@docusaurus/types": "npm:3.10.1" - "@docusaurus/utils": "npm:3.10.1" - "@docusaurus/utils-validation": "npm:3.10.1" + "@docusaurus/core": "npm:3.10.2" + "@docusaurus/types": "npm:3.10.2" + "@docusaurus/utils": "npm:3.10.2" + "@docusaurus/utils-validation": "npm:3.10.2" "@svgr/core": "npm:8.1.0" "@svgr/webpack": "npm:^8.1.0" tslib: "npm:^2.6.0" @@ -2561,53 +2572,53 @@ __metadata: peerDependencies: react: ^18.0.0 || ^19.0.0 react-dom: ^18.0.0 || ^19.0.0 - checksum: 10c0/d866efe42351d1a66febacd6c33753f5ace2056fe86259365408edd354fb67994208a4e2c9939a921c2a20cb11b64fdd3584d34dde8d0329a63a55c9a74c488f - languageName: node - linkType: hard - -"@docusaurus/preset-classic@npm:3.10.1": - version: 3.10.1 - resolution: "@docusaurus/preset-classic@npm:3.10.1" - dependencies: - "@docusaurus/core": "npm:3.10.1" - "@docusaurus/plugin-content-blog": "npm:3.10.1" - "@docusaurus/plugin-content-docs": "npm:3.10.1" - "@docusaurus/plugin-content-pages": "npm:3.10.1" - "@docusaurus/plugin-css-cascade-layers": "npm:3.10.1" - "@docusaurus/plugin-debug": "npm:3.10.1" - "@docusaurus/plugin-google-analytics": "npm:3.10.1" - "@docusaurus/plugin-google-gtag": "npm:3.10.1" - "@docusaurus/plugin-google-tag-manager": "npm:3.10.1" - "@docusaurus/plugin-sitemap": "npm:3.10.1" - "@docusaurus/plugin-svgr": "npm:3.10.1" - "@docusaurus/theme-classic": "npm:3.10.1" - "@docusaurus/theme-common": "npm:3.10.1" - "@docusaurus/theme-search-algolia": "npm:3.10.1" - "@docusaurus/types": "npm:3.10.1" + checksum: 10c0/2817f91f641336dab5d6874ee513e288d599a0be4e1a9c59698befcf41f91aeb73b3660198777c09f4470a6ba31c2d57e9fc1cfd482e0067372bb137932c6307 + languageName: node + linkType: hard + +"@docusaurus/preset-classic@npm:^3.10.2": + version: 3.10.2 + resolution: "@docusaurus/preset-classic@npm:3.10.2" + dependencies: + "@docusaurus/core": "npm:3.10.2" + "@docusaurus/plugin-content-blog": "npm:3.10.2" + "@docusaurus/plugin-content-docs": "npm:3.10.2" + "@docusaurus/plugin-content-pages": "npm:3.10.2" + "@docusaurus/plugin-css-cascade-layers": "npm:3.10.2" + "@docusaurus/plugin-debug": "npm:3.10.2" + "@docusaurus/plugin-google-analytics": "npm:3.10.2" + "@docusaurus/plugin-google-gtag": "npm:3.10.2" + "@docusaurus/plugin-google-tag-manager": "npm:3.10.2" + "@docusaurus/plugin-sitemap": "npm:3.10.2" + "@docusaurus/plugin-svgr": "npm:3.10.2" + "@docusaurus/theme-classic": "npm:3.10.2" + "@docusaurus/theme-common": "npm:3.10.2" + "@docusaurus/theme-search-algolia": "npm:3.10.2" + "@docusaurus/types": "npm:3.10.2" peerDependencies: react: ^18.0.0 || ^19.0.0 react-dom: ^18.0.0 || ^19.0.0 - checksum: 10c0/524675229e33f24f678ca104eab1b6328ca31c2572e5cb2a598a330bd990a8d50eb1929aaef9031c37827a22ddaf6bb19484b75ac2a5b0936f6322d951f33559 - languageName: node - linkType: hard - -"@docusaurus/theme-classic@npm:3.10.1": - version: 3.10.1 - resolution: "@docusaurus/theme-classic@npm:3.10.1" - dependencies: - "@docusaurus/core": "npm:3.10.1" - "@docusaurus/logger": "npm:3.10.1" - "@docusaurus/mdx-loader": "npm:3.10.1" - "@docusaurus/module-type-aliases": "npm:3.10.1" - "@docusaurus/plugin-content-blog": "npm:3.10.1" - "@docusaurus/plugin-content-docs": "npm:3.10.1" - "@docusaurus/plugin-content-pages": "npm:3.10.1" - "@docusaurus/theme-common": "npm:3.10.1" - "@docusaurus/theme-translations": "npm:3.10.1" - "@docusaurus/types": "npm:3.10.1" - "@docusaurus/utils": "npm:3.10.1" - "@docusaurus/utils-common": "npm:3.10.1" - "@docusaurus/utils-validation": "npm:3.10.1" + checksum: 10c0/455b1dea7a9867a69e2634aef4286116c5aef6612e76277ebe82538ee14517ca9a6f2e0421196bd15f7cde6376160fd6284dfe83c03a3c0d1ee00bbc642d4d35 + languageName: node + linkType: hard + +"@docusaurus/theme-classic@npm:3.10.2": + version: 3.10.2 + resolution: "@docusaurus/theme-classic@npm:3.10.2" + dependencies: + "@docusaurus/core": "npm:3.10.2" + "@docusaurus/logger": "npm:3.10.2" + "@docusaurus/mdx-loader": "npm:3.10.2" + "@docusaurus/module-type-aliases": "npm:3.10.2" + "@docusaurus/plugin-content-blog": "npm:3.10.2" + "@docusaurus/plugin-content-docs": "npm:3.10.2" + "@docusaurus/plugin-content-pages": "npm:3.10.2" + "@docusaurus/theme-common": "npm:3.10.2" + "@docusaurus/theme-translations": "npm:3.10.2" + "@docusaurus/types": "npm:3.10.2" + "@docusaurus/utils": "npm:3.10.2" + "@docusaurus/utils-common": "npm:3.10.2" + "@docusaurus/utils-validation": "npm:3.10.2" "@mdx-js/react": "npm:^3.0.0" clsx: "npm:^2.0.0" copy-text-to-clipboard: "npm:^3.2.0" @@ -2624,18 +2635,18 @@ __metadata: peerDependencies: react: ^18.0.0 || ^19.0.0 react-dom: ^18.0.0 || ^19.0.0 - checksum: 10c0/55be80ca9a1880c0a923c519243233bb52025e4a0ae312907c9df52b8ab3594819da164a71377e6ed5b02eef740496eff006da41462603195c0284b977515ceb + checksum: 10c0/c9a19f52ddf8323c22f4bd8765fbcf552cf1ac215949dd50df60e2131ff7f942365e8ac5b4f7fa8230e22b73df5400b97f0fa915fba8ad56445b9ff4eb3946cc languageName: node linkType: hard -"@docusaurus/theme-common@npm:3.10.1": - version: 3.10.1 - resolution: "@docusaurus/theme-common@npm:3.10.1" +"@docusaurus/theme-common@npm:3.10.2": + version: 3.10.2 + resolution: "@docusaurus/theme-common@npm:3.10.2" dependencies: - "@docusaurus/mdx-loader": "npm:3.10.1" - "@docusaurus/module-type-aliases": "npm:3.10.1" - "@docusaurus/utils": "npm:3.10.1" - "@docusaurus/utils-common": "npm:3.10.1" + "@docusaurus/mdx-loader": "npm:3.10.2" + "@docusaurus/module-type-aliases": "npm:3.10.2" + "@docusaurus/utils": "npm:3.10.2" + "@docusaurus/utils-common": "npm:3.10.2" "@types/history": "npm:^4.7.11" "@types/react": "npm:*" "@types/react-router-config": "npm:*" @@ -2648,23 +2659,23 @@ __metadata: "@docusaurus/plugin-content-docs": "*" react: ^18.0.0 || ^19.0.0 react-dom: ^18.0.0 || ^19.0.0 - checksum: 10c0/f66e25b6449e03b5c8812be407e80c1c9ffc87b07395273d009a40761302e6230ab357096de95b47f77aef1d7e4d0363220cca07b7fbdeb9679770e20e0ab7a4 + checksum: 10c0/2ec64449ff69beb3c506f3f7de837afe6a38fc904b1d38547415fb32cd3dcac7d868b14b59d6fc14e0eb3d47c2091bd05fecd294455b765a4bc9b2af9cdadf0a languageName: node linkType: hard -"@docusaurus/theme-search-algolia@npm:3.10.1": - version: 3.10.1 - resolution: "@docusaurus/theme-search-algolia@npm:3.10.1" +"@docusaurus/theme-search-algolia@npm:3.10.2": + version: 3.10.2 + resolution: "@docusaurus/theme-search-algolia@npm:3.10.2" dependencies: "@algolia/autocomplete-core": "npm:^1.19.2" "@docsearch/react": "npm:^3.9.0 || ^4.3.2" - "@docusaurus/core": "npm:3.10.1" - "@docusaurus/logger": "npm:3.10.1" - "@docusaurus/plugin-content-docs": "npm:3.10.1" - "@docusaurus/theme-common": "npm:3.10.1" - "@docusaurus/theme-translations": "npm:3.10.1" - "@docusaurus/utils": "npm:3.10.1" - "@docusaurus/utils-validation": "npm:3.10.1" + "@docusaurus/core": "npm:3.10.2" + "@docusaurus/logger": "npm:3.10.2" + "@docusaurus/plugin-content-docs": "npm:3.10.2" + "@docusaurus/theme-common": "npm:3.10.2" + "@docusaurus/theme-translations": "npm:3.10.2" + "@docusaurus/utils": "npm:3.10.2" + "@docusaurus/utils-validation": "npm:3.10.2" algoliasearch: "npm:^5.37.0" algoliasearch-helper: "npm:^3.26.0" clsx: "npm:^2.0.0" @@ -2676,30 +2687,30 @@ __metadata: peerDependencies: react: ^18.0.0 || ^19.0.0 react-dom: ^18.0.0 || ^19.0.0 - checksum: 10c0/dd558ac0c50f2374b8285f463ec23e1996247f4436cd9147fd313689d02d9113214e0368c64fdc8ca106f10b6ef93589814980ea0121cb3583ca87feae4b19c3 + checksum: 10c0/2097c7a0e80e251392b6e6c4a6d5d79eb88072dab002df6ce1dff0ec22e0660f0ba8c32e5a57605a51afe4461188ae998a49740cc97df5dcd803bb0853a536ad languageName: node linkType: hard -"@docusaurus/theme-translations@npm:3.10.1": - version: 3.10.1 - resolution: "@docusaurus/theme-translations@npm:3.10.1" +"@docusaurus/theme-translations@npm:3.10.2": + version: 3.10.2 + resolution: "@docusaurus/theme-translations@npm:3.10.2" dependencies: fs-extra: "npm:^11.1.1" tslib: "npm:^2.6.0" - checksum: 10c0/2a1c871e883a82c4c5071820dcdc3bbeea5a3571978d022c1d1b820ae8b676ea5dd173b9c17542a032b9a5ec7e06f5d8a3b9de31a1e1f474f527baccfb5f9deb + checksum: 10c0/f063b75d700f70a4dc5203268962ceef84a5ba873109c5b9de0ffea7cc70ddd8fea74fa3676ffc27f736568d51219a3791486bee9f3ea6c4d925fa60e4300f54 languageName: node linkType: hard -"@docusaurus/tsconfig@npm:3.10.1": - version: 3.10.1 - resolution: "@docusaurus/tsconfig@npm:3.10.1" - checksum: 10c0/557eab379f82cc36e14d956f71b3ba81c71d535244b664a75fd1d2cc5e9c20c400b4ddf1f2b62a2c8c6c0b854d9192da5c651c719a51213cadcda94ca7f587b5 +"@docusaurus/tsconfig@npm:^3.10.2": + version: 3.10.2 + resolution: "@docusaurus/tsconfig@npm:3.10.2" + checksum: 10c0/f73d11ce6440d8ad3d8a87a87661e39d1d16451db0f16cd15a1856b331608b429e4b35ab1e8d1fae4c4e2b5bb4b8c238bac3900a8f024a68ba942c633c228361 languageName: node linkType: hard -"@docusaurus/types@npm:3.10.1": - version: 3.10.1 - resolution: "@docusaurus/types@npm:3.10.1" +"@docusaurus/types@npm:3.10.2, @docusaurus/types@npm:^3.10.2": + version: 3.10.2 + resolution: "@docusaurus/types@npm:3.10.2" dependencies: "@mdx-js/mdx": "npm:^3.0.0" "@types/history": "npm:^4.7.11" @@ -2714,50 +2725,50 @@ __metadata: peerDependencies: react: ^18.0.0 || ^19.0.0 react-dom: ^18.0.0 || ^19.0.0 - checksum: 10c0/63cc1d92ec775fb0e58f156b4edc7075612943a94d15d4648b60effcbc34c70a1092569d66d552878779b48d5111abe2fc154ba6a3bca2af0383550c9f9a015b + checksum: 10c0/29672542109c69c7527a14767f0acbfac6635e650be6da75998f97cda7987deda30f402c04438879492a798975c9484265139f603631a2df0575a49f29a7345d languageName: node linkType: hard -"@docusaurus/utils-common@npm:3.10.1": - version: 3.10.1 - resolution: "@docusaurus/utils-common@npm:3.10.1" +"@docusaurus/utils-common@npm:3.10.2": + version: 3.10.2 + resolution: "@docusaurus/utils-common@npm:3.10.2" dependencies: - "@docusaurus/types": "npm:3.10.1" + "@docusaurus/types": "npm:3.10.2" tslib: "npm:^2.6.0" - checksum: 10c0/1dde7a5c538a2cbe9eba46c9a3991a773e2d9d5b9c489cb010f9284c33cba7d494c1300557f850fa6a6e857747ca835b91f6036b02a726e13d296d7a65f8d8db + checksum: 10c0/65727f7acf200a2d026475e2f81a78fbe37b757c869f187122a69cfc40b4b1936699d83a2e701c2de856f9c68e7c8f307a3fb56a473bde9c883e865887b9e8c6 languageName: node linkType: hard -"@docusaurus/utils-validation@npm:3.10.1": - version: 3.10.1 - resolution: "@docusaurus/utils-validation@npm:3.10.1" +"@docusaurus/utils-validation@npm:3.10.2": + version: 3.10.2 + resolution: "@docusaurus/utils-validation@npm:3.10.2" dependencies: - "@docusaurus/logger": "npm:3.10.1" - "@docusaurus/utils": "npm:3.10.1" - "@docusaurus/utils-common": "npm:3.10.1" + "@docusaurus/logger": "npm:3.10.2" + "@docusaurus/utils": "npm:3.10.2" + "@docusaurus/utils-common": "npm:3.10.2" fs-extra: "npm:^11.2.0" joi: "npm:^17.9.2" js-yaml: "npm:^4.1.0" lodash: "npm:^4.17.21" tslib: "npm:^2.6.0" - checksum: 10c0/6368eb2a879fc1c4a507873689bd0a08257e2bc72a2ba53b3629d633d97d368168720fc504a54f96a0652982fc098f29675076e1fbcaf0244947645131a3d2f9 + checksum: 10c0/67deae60e3338acae79928655d68db52bb1691ed467bf66ac9d1ed45a5b95d927af71f68c0d6120e908bea1d5e97562b3c3edbca93ebf07adc02012ec2da8277 languageName: node linkType: hard -"@docusaurus/utils@npm:3.10.1": - version: 3.10.1 - resolution: "@docusaurus/utils@npm:3.10.1" +"@docusaurus/utils@npm:3.10.2": + version: 3.10.2 + resolution: "@docusaurus/utils@npm:3.10.2" dependencies: - "@docusaurus/logger": "npm:3.10.1" - "@docusaurus/types": "npm:3.10.1" - "@docusaurus/utils-common": "npm:3.10.1" + "@11ty/gray-matter": "npm:^1.0.0" + "@docusaurus/logger": "npm:3.10.2" + "@docusaurus/types": "npm:3.10.2" + "@docusaurus/utils-common": "npm:3.10.2" escape-string-regexp: "npm:^4.0.0" execa: "npm:^5.1.1" file-loader: "npm:^6.2.0" fs-extra: "npm:^11.1.1" github-slugger: "npm:^1.5.0" globby: "npm:^11.1.0" - gray-matter: "npm:^4.0.3" jiti: "npm:^1.20.0" js-yaml: "npm:^4.1.0" lodash: "npm:^4.17.21" @@ -2769,7 +2780,7 @@ __metadata: url-loader: "npm:^4.1.1" utility-types: "npm:^3.10.0" webpack: "npm:^5.88.1" - checksum: 10c0/97d51da30035ef34eced1dbc937f829309a8165a07a9c66d87c5deec03fb62150cbc70b2763ffdec0286b21f1be53f4011a036e4265cb971a892f0ab12172e0a + checksum: 10c0/7d72ab04b8587a001d57efe71f40f8c0ae7e0087a51af791372455368726a8ea1c18473e0af5331aa30ea6a298d386a07417163597e2461a0213e14befb3609a languageName: node linkType: hard @@ -3550,108 +3561,108 @@ __metadata: languageName: node linkType: hard -"@swc/core-darwin-arm64@npm:1.15.33": - version: 1.15.33 - resolution: "@swc/core-darwin-arm64@npm:1.15.33" +"@swc/core-darwin-arm64@npm:1.16.2": + version: 1.16.2 + resolution: "@swc/core-darwin-arm64@npm:1.16.2" conditions: os=darwin & cpu=arm64 languageName: node linkType: hard -"@swc/core-darwin-x64@npm:1.15.33": - version: 1.15.33 - resolution: "@swc/core-darwin-x64@npm:1.15.33" +"@swc/core-darwin-x64@npm:1.16.2": + version: 1.16.2 + resolution: "@swc/core-darwin-x64@npm:1.16.2" conditions: os=darwin & cpu=x64 languageName: node linkType: hard -"@swc/core-linux-arm-gnueabihf@npm:1.15.33": - version: 1.15.33 - resolution: "@swc/core-linux-arm-gnueabihf@npm:1.15.33" +"@swc/core-linux-arm-gnueabihf@npm:1.16.2": + version: 1.16.2 + resolution: "@swc/core-linux-arm-gnueabihf@npm:1.16.2" conditions: os=linux & cpu=arm languageName: node linkType: hard -"@swc/core-linux-arm64-gnu@npm:1.15.33": - version: 1.15.33 - resolution: "@swc/core-linux-arm64-gnu@npm:1.15.33" +"@swc/core-linux-arm64-gnu@npm:1.16.2": + version: 1.16.2 + resolution: "@swc/core-linux-arm64-gnu@npm:1.16.2" conditions: os=linux & cpu=arm64 & libc=glibc languageName: node linkType: hard -"@swc/core-linux-arm64-musl@npm:1.15.33": - version: 1.15.33 - resolution: "@swc/core-linux-arm64-musl@npm:1.15.33" +"@swc/core-linux-arm64-musl@npm:1.16.2": + version: 1.16.2 + resolution: "@swc/core-linux-arm64-musl@npm:1.16.2" conditions: os=linux & cpu=arm64 & libc=musl languageName: node linkType: hard -"@swc/core-linux-ppc64-gnu@npm:1.15.33": - version: 1.15.33 - resolution: "@swc/core-linux-ppc64-gnu@npm:1.15.33" +"@swc/core-linux-ppc64-gnu@npm:1.16.2": + version: 1.16.2 + resolution: "@swc/core-linux-ppc64-gnu@npm:1.16.2" conditions: os=linux & cpu=ppc64 & libc=glibc languageName: node linkType: hard -"@swc/core-linux-s390x-gnu@npm:1.15.33": - version: 1.15.33 - resolution: "@swc/core-linux-s390x-gnu@npm:1.15.33" +"@swc/core-linux-s390x-gnu@npm:1.16.2": + version: 1.16.2 + resolution: "@swc/core-linux-s390x-gnu@npm:1.16.2" conditions: os=linux & cpu=s390x & libc=glibc languageName: node linkType: hard -"@swc/core-linux-x64-gnu@npm:1.15.33": - version: 1.15.33 - resolution: "@swc/core-linux-x64-gnu@npm:1.15.33" +"@swc/core-linux-x64-gnu@npm:1.16.2": + version: 1.16.2 + resolution: "@swc/core-linux-x64-gnu@npm:1.16.2" conditions: os=linux & cpu=x64 & libc=glibc languageName: node linkType: hard -"@swc/core-linux-x64-musl@npm:1.15.33": - version: 1.15.33 - resolution: "@swc/core-linux-x64-musl@npm:1.15.33" +"@swc/core-linux-x64-musl@npm:1.16.2": + version: 1.16.2 + resolution: "@swc/core-linux-x64-musl@npm:1.16.2" conditions: os=linux & cpu=x64 & libc=musl languageName: node linkType: hard -"@swc/core-win32-arm64-msvc@npm:1.15.33": - version: 1.15.33 - resolution: "@swc/core-win32-arm64-msvc@npm:1.15.33" +"@swc/core-win32-arm64-msvc@npm:1.16.2": + version: 1.16.2 + resolution: "@swc/core-win32-arm64-msvc@npm:1.16.2" conditions: os=win32 & cpu=arm64 languageName: node linkType: hard -"@swc/core-win32-ia32-msvc@npm:1.15.33": - version: 1.15.33 - resolution: "@swc/core-win32-ia32-msvc@npm:1.15.33" +"@swc/core-win32-ia32-msvc@npm:1.16.2": + version: 1.16.2 + resolution: "@swc/core-win32-ia32-msvc@npm:1.16.2" conditions: os=win32 & cpu=ia32 languageName: node linkType: hard -"@swc/core-win32-x64-msvc@npm:1.15.33": - version: 1.15.33 - resolution: "@swc/core-win32-x64-msvc@npm:1.15.33" +"@swc/core-win32-x64-msvc@npm:1.16.2": + version: 1.16.2 + resolution: "@swc/core-win32-x64-msvc@npm:1.16.2" conditions: os=win32 & cpu=x64 languageName: node linkType: hard -"@swc/core@npm:^1.7.39": - version: 1.15.33 - resolution: "@swc/core@npm:1.15.33" - dependencies: - "@swc/core-darwin-arm64": "npm:1.15.33" - "@swc/core-darwin-x64": "npm:1.15.33" - "@swc/core-linux-arm-gnueabihf": "npm:1.15.33" - "@swc/core-linux-arm64-gnu": "npm:1.15.33" - "@swc/core-linux-arm64-musl": "npm:1.15.33" - "@swc/core-linux-ppc64-gnu": "npm:1.15.33" - "@swc/core-linux-s390x-gnu": "npm:1.15.33" - "@swc/core-linux-x64-gnu": "npm:1.15.33" - "@swc/core-linux-x64-musl": "npm:1.15.33" - "@swc/core-win32-arm64-msvc": "npm:1.15.33" - "@swc/core-win32-ia32-msvc": "npm:1.15.33" - "@swc/core-win32-x64-msvc": "npm:1.15.33" +"@swc/core@npm:^1.15.40": + version: 1.16.2 + resolution: "@swc/core@npm:1.16.2" + dependencies: + "@swc/core-darwin-arm64": "npm:1.16.2" + "@swc/core-darwin-x64": "npm:1.16.2" + "@swc/core-linux-arm-gnueabihf": "npm:1.16.2" + "@swc/core-linux-arm64-gnu": "npm:1.16.2" + "@swc/core-linux-arm64-musl": "npm:1.16.2" + "@swc/core-linux-ppc64-gnu": "npm:1.16.2" + "@swc/core-linux-s390x-gnu": "npm:1.16.2" + "@swc/core-linux-x64-gnu": "npm:1.16.2" + "@swc/core-linux-x64-musl": "npm:1.16.2" + "@swc/core-win32-arm64-msvc": "npm:1.16.2" + "@swc/core-win32-ia32-msvc": "npm:1.16.2" + "@swc/core-win32-x64-msvc": "npm:1.16.2" "@swc/counter": "npm:^0.1.3" - "@swc/types": "npm:^0.1.26" + "@swc/types": "npm:^0.1.28" peerDependencies: "@swc/helpers": ">=0.5.17" dependenciesMeta: @@ -3682,7 +3693,7 @@ __metadata: peerDependenciesMeta: "@swc/helpers": optional: true - checksum: 10c0/7d6771fdf8f1e1d41665fb84b3e718feec05e72ed448b1fbc95d3f9f4c0e80ea495e66e778436201e8ab902478042f517da4bd3f6890127248788d8b985f9a52 + checksum: 10c0/8019735e27852f03b0e09ae7f8c3f00e6a2e3f49b72127e09c20cffde335fe3b776afb20bfd3b3f5c540d42667f1b7467a4e10aa11c50ff59c6f86a9513544a8 languageName: node linkType: hard @@ -3693,107 +3704,107 @@ __metadata: languageName: node linkType: hard -"@swc/html-darwin-arm64@npm:1.15.33": - version: 1.15.33 - resolution: "@swc/html-darwin-arm64@npm:1.15.33" +"@swc/html-darwin-arm64@npm:1.16.2": + version: 1.16.2 + resolution: "@swc/html-darwin-arm64@npm:1.16.2" conditions: os=darwin & cpu=arm64 languageName: node linkType: hard -"@swc/html-darwin-x64@npm:1.15.33": - version: 1.15.33 - resolution: "@swc/html-darwin-x64@npm:1.15.33" +"@swc/html-darwin-x64@npm:1.16.2": + version: 1.16.2 + resolution: "@swc/html-darwin-x64@npm:1.16.2" conditions: os=darwin & cpu=x64 languageName: node linkType: hard -"@swc/html-linux-arm-gnueabihf@npm:1.15.33": - version: 1.15.33 - resolution: "@swc/html-linux-arm-gnueabihf@npm:1.15.33" +"@swc/html-linux-arm-gnueabihf@npm:1.16.2": + version: 1.16.2 + resolution: "@swc/html-linux-arm-gnueabihf@npm:1.16.2" conditions: os=linux & cpu=arm languageName: node linkType: hard -"@swc/html-linux-arm64-gnu@npm:1.15.33": - version: 1.15.33 - resolution: "@swc/html-linux-arm64-gnu@npm:1.15.33" +"@swc/html-linux-arm64-gnu@npm:1.16.2": + version: 1.16.2 + resolution: "@swc/html-linux-arm64-gnu@npm:1.16.2" conditions: os=linux & cpu=arm64 & libc=glibc languageName: node linkType: hard -"@swc/html-linux-arm64-musl@npm:1.15.33": - version: 1.15.33 - resolution: "@swc/html-linux-arm64-musl@npm:1.15.33" +"@swc/html-linux-arm64-musl@npm:1.16.2": + version: 1.16.2 + resolution: "@swc/html-linux-arm64-musl@npm:1.16.2" conditions: os=linux & cpu=arm64 & libc=musl languageName: node linkType: hard -"@swc/html-linux-ppc64-gnu@npm:1.15.33": - version: 1.15.33 - resolution: "@swc/html-linux-ppc64-gnu@npm:1.15.33" +"@swc/html-linux-ppc64-gnu@npm:1.16.2": + version: 1.16.2 + resolution: "@swc/html-linux-ppc64-gnu@npm:1.16.2" conditions: os=linux & cpu=ppc64 & libc=glibc languageName: node linkType: hard -"@swc/html-linux-s390x-gnu@npm:1.15.33": - version: 1.15.33 - resolution: "@swc/html-linux-s390x-gnu@npm:1.15.33" +"@swc/html-linux-s390x-gnu@npm:1.16.2": + version: 1.16.2 + resolution: "@swc/html-linux-s390x-gnu@npm:1.16.2" conditions: os=linux & cpu=s390x & libc=glibc languageName: node linkType: hard -"@swc/html-linux-x64-gnu@npm:1.15.33": - version: 1.15.33 - resolution: "@swc/html-linux-x64-gnu@npm:1.15.33" +"@swc/html-linux-x64-gnu@npm:1.16.2": + version: 1.16.2 + resolution: "@swc/html-linux-x64-gnu@npm:1.16.2" conditions: os=linux & cpu=x64 & libc=glibc languageName: node linkType: hard -"@swc/html-linux-x64-musl@npm:1.15.33": - version: 1.15.33 - resolution: "@swc/html-linux-x64-musl@npm:1.15.33" +"@swc/html-linux-x64-musl@npm:1.16.2": + version: 1.16.2 + resolution: "@swc/html-linux-x64-musl@npm:1.16.2" conditions: os=linux & cpu=x64 & libc=musl languageName: node linkType: hard -"@swc/html-win32-arm64-msvc@npm:1.15.33": - version: 1.15.33 - resolution: "@swc/html-win32-arm64-msvc@npm:1.15.33" +"@swc/html-win32-arm64-msvc@npm:1.16.2": + version: 1.16.2 + resolution: "@swc/html-win32-arm64-msvc@npm:1.16.2" conditions: os=win32 & cpu=arm64 languageName: node linkType: hard -"@swc/html-win32-ia32-msvc@npm:1.15.33": - version: 1.15.33 - resolution: "@swc/html-win32-ia32-msvc@npm:1.15.33" +"@swc/html-win32-ia32-msvc@npm:1.16.2": + version: 1.16.2 + resolution: "@swc/html-win32-ia32-msvc@npm:1.16.2" conditions: os=win32 & cpu=ia32 languageName: node linkType: hard -"@swc/html-win32-x64-msvc@npm:1.15.33": - version: 1.15.33 - resolution: "@swc/html-win32-x64-msvc@npm:1.15.33" +"@swc/html-win32-x64-msvc@npm:1.16.2": + version: 1.16.2 + resolution: "@swc/html-win32-x64-msvc@npm:1.16.2" conditions: os=win32 & cpu=x64 languageName: node linkType: hard -"@swc/html@npm:^1.13.5": - version: 1.15.33 - resolution: "@swc/html@npm:1.15.33" +"@swc/html@npm:^1.15.40": + version: 1.16.2 + resolution: "@swc/html@npm:1.16.2" dependencies: "@swc/counter": "npm:^0.1.3" - "@swc/html-darwin-arm64": "npm:1.15.33" - "@swc/html-darwin-x64": "npm:1.15.33" - "@swc/html-linux-arm-gnueabihf": "npm:1.15.33" - "@swc/html-linux-arm64-gnu": "npm:1.15.33" - "@swc/html-linux-arm64-musl": "npm:1.15.33" - "@swc/html-linux-ppc64-gnu": "npm:1.15.33" - "@swc/html-linux-s390x-gnu": "npm:1.15.33" - "@swc/html-linux-x64-gnu": "npm:1.15.33" - "@swc/html-linux-x64-musl": "npm:1.15.33" - "@swc/html-win32-arm64-msvc": "npm:1.15.33" - "@swc/html-win32-ia32-msvc": "npm:1.15.33" - "@swc/html-win32-x64-msvc": "npm:1.15.33" + "@swc/html-darwin-arm64": "npm:1.16.2" + "@swc/html-darwin-x64": "npm:1.16.2" + "@swc/html-linux-arm-gnueabihf": "npm:1.16.2" + "@swc/html-linux-arm64-gnu": "npm:1.16.2" + "@swc/html-linux-arm64-musl": "npm:1.16.2" + "@swc/html-linux-ppc64-gnu": "npm:1.16.2" + "@swc/html-linux-s390x-gnu": "npm:1.16.2" + "@swc/html-linux-x64-gnu": "npm:1.16.2" + "@swc/html-linux-x64-musl": "npm:1.16.2" + "@swc/html-win32-arm64-msvc": "npm:1.16.2" + "@swc/html-win32-ia32-msvc": "npm:1.16.2" + "@swc/html-win32-x64-msvc": "npm:1.16.2" dependenciesMeta: "@swc/html-darwin-arm64": optional: true @@ -3819,16 +3830,16 @@ __metadata: optional: true "@swc/html-win32-x64-msvc": optional: true - checksum: 10c0/e0944b2c832f83c4178ed5b8eb7dc71d2759c2c8cdc0cc75b425dbeefd5413ea9e721427250d8a9afb5730771ec05ac15bf8092d8728f3cff17d7682d79e6e36 + checksum: 10c0/78f761db964b0e9e4ba694ba2fa1fb099a01bb13a7acdd7b5cbd99eb54e91cee68ca5a106fd43b8ecb247a73d8074c0dcd0cbfad2b0e074baeaec3045d4f2d1d languageName: node linkType: hard -"@swc/types@npm:^0.1.26": - version: 0.1.26 - resolution: "@swc/types@npm:0.1.26" +"@swc/types@npm:^0.1.28": + version: 0.1.28 + resolution: "@swc/types@npm:0.1.28" dependencies: "@swc/counter": "npm:^0.1.3" - checksum: 10c0/8449341e8bbff81c14e9918c25421143cf605dff20f70f048847e1f7cede396f8dd73903cbef331a809b4a8e15d0db374a5f6809003e7b440f93df1dd4934d28 + checksum: 10c0/7f2e959a7ee000ec4216acc6b7634e2d2fbe404b6ad3adf72bb91970a67359d7d429f60556342784dbe66912c7c987426683159e749332581a87e04de0524357 languageName: node linkType: hard @@ -3987,13 +3998,6 @@ __metadata: languageName: node linkType: hard -"@types/gtag.js@npm:^0.0.20": - version: 0.0.20 - resolution: "@types/gtag.js@npm:0.0.20" - checksum: 10c0/eb878aa3cfab6b98f5e69ef3383e9788aaea6a4d0611c72078678374dcbb4731f533ff2bf479a865536f1626a57887b1198279ff35a65d223fe4f93d9c76dbdd - languageName: node - linkType: hard - "@types/hast@npm:^3.0.0": version: 3.0.4 resolution: "@types/hast@npm:3.0.4" @@ -4587,10 +4591,10 @@ __metadata: languageName: node linkType: hard -"address@npm:^1.0.1": - version: 1.2.2 - resolution: "address@npm:1.2.2" - checksum: 10c0/1c8056b77fb124456997b78ed682ecc19d2fd7ea8bd5850a2aa8c3e3134c913847c57bcae418622efd32ba858fa1e242a40a251ac31da0515664fc0ac03a047d +"address@npm:^2.0.1": + version: 2.0.3 + resolution: "address@npm:2.0.3" + checksum: 10c0/e95c8d989812a9b1cef5e167328a1dd6fd2c41b02005793b7b4631d32dbf7de30bd17685d2f17fbfb94b67f3c422f9a0399caee3c1fbfa18c8e20dc0c8c77d3b languageName: node linkType: hard @@ -6143,16 +6147,15 @@ __metadata: languageName: node linkType: hard -"detect-port@npm:^1.5.1": - version: 1.6.1 - resolution: "detect-port@npm:1.6.1" +"detect-port@npm:^2.1.0": + version: 2.1.0 + resolution: "detect-port@npm:2.1.0" dependencies: - address: "npm:^1.0.1" - debug: "npm:4" + address: "npm:^2.0.1" bin: - detect: bin/detect-port.js - detect-port: bin/detect-port.js - checksum: 10c0/4ea9eb46a637cb21220dd0a62b6074792894fc77b2cacbc9de533d1908b2eedafa7bfd7547baaa2ac1e9c7ba7c289b34b17db896dca6da142f4fc6e2060eee17 + detect: dist/commonjs/bin/detect-port.js + detect-port: dist/commonjs/bin/detect-port.js + checksum: 10c0/06236ff1197ffea038d4a1c0ab60200ece1ac234eb00a507f93e986483c06989b9efd424cc2bbb8e9556c3984ce906e8a663799797e415626eefb26f040bd5d8 languageName: node linkType: hard @@ -8289,7 +8292,7 @@ __metadata: languageName: node linkType: hard -"kind-of@npm:^6.0.0, kind-of@npm:^6.0.2": +"kind-of@npm:^6.0.0, kind-of@npm:^6.0.2, kind-of@npm:^6.0.3": version: 6.0.3 resolution: "kind-of@npm:6.0.3" checksum: 10c0/61cdff9623dabf3568b6445e93e31376bee1cdb93f8ba7033d86022c2a9b1791a1d9510e026e6465ebd701a6dd2f7b0808483ad8838341ac52f003f512e0b4c4 From 80200366841edbec0301d30b34c3e8ac35ddbd64 Mon Sep 17 00:00:00 2001 From: DrAv0011 Date: Sat, 12 Sep 2026 11:52:01 +0200 Subject: [PATCH 25/48] docs: fold the compiler into the ui section and rewrite it for compiled screens `ui-compile` is `ui-compiler` throughout. The compiler is a `Compiler` group under `/docs/ui` rather than a section of its own, and the runtime half that section carried becomes three guides: hosts, navigation and state. New pages: Link, List, Tabs, Disclosure, Expect, Embed, useObservable, useMechanism, api/errors and api/compiled-screens. Co-Authored-By: Claude Opus 5 (1M context) --- docs/config/index.md | 2 +- docs/filters/bundler.md | 4 +- docs/filters/ci.md | 2 +- docs/filters/core.md | 10 +- docs/filters/index.md | 6 +- docs/filters/ui-compile.md | 145 -------- docs/filters/ui-compiler.md | 313 ++++++++++++++++++ docs/ui/api/api.md | 48 ++- docs/ui/api/compiled-screens.md | 79 +++++ docs/ui/api/errors.md | 59 ++++ docs/ui/api/render.md | 93 +++--- docs/ui/compiler/_category_.json | 10 + docs/ui/compiler/api.md | 71 ++++ docs/ui/compiler/index.md | 42 +++ docs/ui/compiler/passes.md | 98 ++++++ docs/ui/components/Background.md | 4 +- docs/ui/components/Button.md | 73 ++-- docs/ui/components/Container.md | 10 +- docs/ui/components/Disclosure.md | 53 +++ docs/ui/components/Embed.md | 73 ++++ docs/ui/components/Expect.md | 42 +++ docs/ui/components/Form/Form.md | 12 +- docs/ui/components/Form/FormButton.md | 6 +- docs/ui/components/Form/FormDropdown.md | 12 +- docs/ui/components/Form/FormInlineSelect.md | 10 +- docs/ui/components/Form/FormInput.md | 8 +- docs/ui/components/Form/FormOption.md | 6 +- docs/ui/components/Form/FormSlider.md | 8 +- docs/ui/components/Form/FormToggle.md | 8 +- docs/ui/components/Form/_category_.json | 2 +- docs/ui/components/Fragment.md | 12 +- docs/ui/components/Hotbar.md | 6 +- docs/ui/components/Image.md | 110 +++--- docs/ui/components/Link.md | 68 ++++ docs/ui/components/List.md | 60 ++++ docs/ui/components/Panel.md | 71 ++-- docs/ui/components/PlayerInventory.md | 6 +- docs/ui/components/Screen.md | 34 +- docs/ui/components/Scroll.md | 30 +- docs/ui/components/Slot.md | 38 +-- docs/ui/components/SlotGrid.md | 13 +- docs/ui/components/Tabs.md | 65 ++++ docs/ui/components/Text.md | 11 +- docs/ui/components/components.md | 98 +++--- docs/ui/components/control-props.md | 53 ++- docs/ui/components/deprecated/Dropdown.md | 10 +- docs/ui/components/deprecated/Input.md | 10 +- docs/ui/components/deprecated/Slider.md | 10 +- docs/ui/components/deprecated/_category_.json | 2 +- .../deprecated/modal-field-props.md | 2 +- docs/ui/guides/_category_.json | 2 +- docs/ui/guides/container-screens.md | 16 +- docs/ui/guides/custom-native-components.md | 4 +- docs/ui/guides/handler-events.md | 2 +- docs/ui/guides/hosts.md | 67 ++++ docs/ui/guides/navigation.md | 93 ++++++ docs/ui/guides/render-pack.md | 2 +- docs/ui/guides/state.md | 72 ++++ docs/ui/hooks/hooks.md | 50 +-- docs/ui/hooks/useEffect.md | 14 +- docs/ui/hooks/useEvent.md | 4 +- docs/ui/hooks/useExit.md | 4 +- docs/ui/hooks/useMechanism.md | 61 ++++ docs/ui/hooks/useObservable.md | 82 +++++ docs/ui/hooks/usePlayer.md | 2 +- docs/ui/hooks/useRef.md | 6 +- docs/ui/hooks/useTranslation.md | 2 +- docs/ui/hooks/useTranslationResolver.md | 2 +- docs/ui/index.md | 89 ++--- docs/ui/installation.md | 128 ++++--- src/data/redirects.ts | 5 +- src/data/sections.ts | 3 +- 72 files changed, 2019 insertions(+), 709 deletions(-) delete mode 100644 docs/filters/ui-compile.md create mode 100644 docs/filters/ui-compiler.md create mode 100644 docs/ui/api/compiled-screens.md create mode 100644 docs/ui/api/errors.md create mode 100644 docs/ui/compiler/_category_.json create mode 100644 docs/ui/compiler/api.md create mode 100644 docs/ui/compiler/index.md create mode 100644 docs/ui/compiler/passes.md create mode 100644 docs/ui/components/Disclosure.md create mode 100644 docs/ui/components/Embed.md create mode 100644 docs/ui/components/Expect.md create mode 100644 docs/ui/components/Link.md create mode 100644 docs/ui/components/List.md create mode 100644 docs/ui/components/Tabs.md create mode 100644 docs/ui/guides/hosts.md create mode 100644 docs/ui/guides/navigation.md create mode 100644 docs/ui/guides/state.md create mode 100644 docs/ui/hooks/useMechanism.md create mode 100644 docs/ui/hooks/useObservable.md diff --git a/docs/config/index.md b/docs/config/index.md index d9681d9..24529e6 100644 --- a/docs/config/index.md +++ b/docs/config/index.md @@ -168,7 +168,7 @@ world.afterEvents.itemUse.subscribe(({ source, itemStack }) => { The UI itself stays fully available — `openUi` is the same funnel the commands go through, permission clamp included — and any *other* installed bedrock-core addon's `:list` still shows your row. It frees the four names, not the namespace: your own commands still belong under `core.id`. -`openUi` returns a `Promise` that settles once the screen is handed to the renderer. From a ui-runtime presser, **return it** — `onPress={() => openUi(core, player, target)}` — so the handoff lands inside the press's interactive transaction: deterministic, flash-free, and no `useExit` call needed, because the renderer [swaps the running app out itself](/docs/ui/api/render#one-ui-slot-per-player). Outside a presser (commands, events), `void openUi(...)` is fine — the promise never rejects. +`openUi` returns a `Promise` that settles once the screen is handed to the renderer. From a ui-runtime presser, **return it** — `onPress={() => openUi(core, player, target)}` — so the handoff lands inside the press's interactive transaction: deterministic, flash-free, and no `useExit` call needed, because the renderer [swaps the running app out itself](/docs/ui/guides/state#one-ui-slot-per-player). Outside a presser (commands, events), `void openUi(...)` is fine — the promise never rejects. ## Permissions diff --git a/docs/filters/bundler.md b/docs/filters/bundler.md index 50a31d2..b5181e9 100644 --- a/docs/filters/bundler.md +++ b/docs/filters/bundler.md @@ -1,5 +1,5 @@ --- -sidebar_position: 8 +sidebar_position: 9 description: "Bundles the behavior pack's TypeScript into one main.js with esbuild." --- # bundler @@ -22,7 +22,7 @@ It runs last, after every filter that writes something the scripts import: "filters": [ { "filter": "guides" }, { "filter": "i18n" }, - { "filter": "ui-compile" }, + { "filter": "ui-compiler" }, { "filter": "bundler" } ] } diff --git a/docs/filters/ci.md b/docs/filters/ci.md index a50e2a5..a0753da 100644 --- a/docs/filters/ci.md +++ b/docs/filters/ci.md @@ -1,5 +1,5 @@ --- -sidebar_position: 9 +sidebar_position: 10 description: "Run Regolith in GitHub Actions with the setup-regolith action." --- # Running in CI diff --git a/docs/filters/core.md b/docs/filters/core.md index c572760..700b614 100644 --- a/docs/filters/core.md +++ b/docs/filters/core.md @@ -12,7 +12,7 @@ One filter that runs the whole stack in the order the filters depend on, with th | 2 | [`generator`](./generator.md) | opt-in: templates become JSON before the scripts are bundled | | 3 | [`guides`](./guides.md) | guide keys have to land before i18n collects them | | 4 | [`i18n`](./i18n.md) | `.lang` files, the runtime bundle and the key types | -| 5 | [`ui-compile`](./ui-compile.md) | screens bake against the keys i18n emitted | +| 5 | [`ui-compiler`](./ui-compiler.md) | screens bake against the keys i18n emitted | | 6 | [`bundler`](./bundler.md) | last: it inlines the generated bundles and strips the sources | Each stage runs in its own Node process, exactly as Regolith runs it: same temp workspace, same `ROOT_DIR`, same settings JSON, same exit code. A stage whose inputs are absent says it has nothing to do and the run continues, so the full stack is a safe default for a project that uses part of it. A project that needs a step of its own between two stages lists the filters one by one in `config.json` and puts its own filter where it belongs. @@ -23,7 +23,7 @@ Register the resolver once per machine, then install the whole set — `core` ru ```bash regolith config resolvers --append github.com/bedrock-core/regolith-filters/resolver.json -regolith install core manifest generator guides i18n ui-compile bundler +regolith install core manifest generator guides i18n ui-compiler bundler ``` Then one entry per profile replaces the six: @@ -38,7 +38,7 @@ Then one entry per profile replaces the six: "filter": "core", "settings": { "shared": { "namespace": "drav0011_economy" }, - "ui-compile": { "screens": ["@bedrock-core/config/compiled"] }, + "ui-compiler": { "screens": ["@bedrock-core/config/compiled"] }, "bundler": { "debug": true } } } @@ -51,7 +51,7 @@ Then one entry per profile replaces the six: "settings": { "shared": { "namespace": "drav0011_economy" }, "manifest": { "manifestPath": "BP/manifest.test.json" }, - "ui-compile": { "screens": ["@bedrock-core/config/compiled"] }, + "ui-compiler": { "screens": ["@bedrock-core/config/compiled"] }, "bundler": { "debug": true, "tsConfigPath": "tsconfig.test.json" } } } @@ -67,7 +67,7 @@ Then one entry per profile replaces the six: | Setting | Type | Default | Description | | --- | --- | --- | --- | | `shared` | `object` | `{}` | Merged into every stage. The addon's `namespace` belongs here; a stage that does not read a key ignores it | -| `manifest`, `guides`, `i18n`, `ui-compile`, `bundler` | `object \| false` | `{}` | Settings for that stage, merged over `shared`. `false` skips the stage | +| `manifest`, `guides`, `i18n`, `ui-compiler`, `bundler` | `object \| false` | `{}` | Settings for that stage, merged over `shared`. `false` skips the stage | | `generator` | `object \| true` | off | The generator runs only when this key is present — it writes schema types into the project, so a project opts in. `true` runs it with defaults | Each stage's own settings are documented on its page; the keys are unchanged here. diff --git a/docs/filters/index.md b/docs/filters/index.md index 596b7e2..aa3eca1 100644 --- a/docs/filters/index.md +++ b/docs/filters/index.md @@ -33,9 +33,11 @@ Filters run in dependency order. [`core`](./core.md) runs the whole chain as one | 2 | [`generator`](./generator.md) | Writes Minecraft JSON from TypeScript templates typed against Mojang's schemas (opt-in) | | 3 | [`guides`](./guides.md) | Compiles MDX guides into a manifest and auto-localized `.lang` entries | | 4 | [`i18n`](./i18n.md) | Turns TypeScript resources into `.lang` files, a typed runtime bundle and vanilla-key types | -| 5 | [`ui-compile`](./ui-compile.md) | Compiles `*.screen.tsx` into static JSON UI and routes the chest screen to it | +| 5 | [`ui-compiler`](./ui-compiler.md) | Compiles `*.screen.tsx` into static JSON UI and registers each screen with the host that serves it | | 6 | [`bundler`](./bundler.md) | Bundles `BP/scripts/` into one `main.js` with esbuild | -`guides`, `i18n` and `ui-compile` share one `namespace` setting: the addon's `creator_pack` string, the same one passed to `core.register()`. Each of them reads it from the register call in `BP/scripts` and needs no settings when that scan succeeds; set `namespace` only to override it. +`guides`, `i18n` and `ui-compiler` share one `namespace` setting: the addon's `creator_pack` string, the same one passed to `core.register()`. Each of them reads it from the register call in `BP/scripts` and needs no settings when that scan succeeds; set `namespace` only to override it. + +The compiler `ui-compiler` runs is a library of its own; its passes, layers and entry points are in [Compiler](/docs/ui/compiler). For GitHub Actions, [Running in CI](./ci.md) sets up the Regolith CLI and the resolver. diff --git a/docs/filters/ui-compile.md b/docs/filters/ui-compile.md deleted file mode 100644 index 7be4c19..0000000 --- a/docs/filters/ui-compile.md +++ /dev/null @@ -1,145 +0,0 @@ ---- -sidebar_position: 7 -description: "Compiles *.screen.tsx into static JSON UI and routes the chest screen to it." ---- -# ui-compile - -The build half of [container screens](/docs/ui/guides/container-screens). It compiles every `*.screen.tsx` under `BP/scripts` into static JSON UI, and prepares everything the runtime needs to drive them: the router that puts a compiled layout on the vanilla chest screen, the character table live text decodes through, and the entity each screen opens from. - -A server form is serialized per player at runtime. A container screen cannot be — the chest screen has no string channel wide enough to carry a layout — so the layout is baked at build time and only state travels at runtime, through the container's own slots. This filter is the baking. - -## Installation - -```bash -regolith install github.com/bedrock-core/regolith-filters/ui-compile -``` - -Add it to `config.json` **before** the `bundler` filter — it reads the screen sources the bundler strips — and **after** `i18n` if you use it, so the character table is not carried into the translation bundle: - -```jsonc title="config.json" -{ - "regolith": { - "profiles": { - "default": { - "filters": [ - { "filter": "guides" }, - { "filter": "i18n" }, - { "filter": "ui-compile" }, - { "filter": "bundler" } - ] - } - } - } -} -``` - -No settings are required. - -## Authoring - -A screen is a script module ending in `.screen.tsx`, anywhere under `BP/scripts`, that default-exports a component rendering a [``](/docs/ui/components/Container) at its root: - -```tsx title="packs/BP/scripts/screens/furnace.screen.tsx" -/** @jsxImportSource @bedrock-core/ui */ -import { Container, Slot, Text, useState } from '@bedrock-core/ui'; - -export default function Furnace() { - const [count, setCount] = useState(0); - - return ( - - {`smelted ${count}`} - setCount(value => value + 1)} /> - - ); -} -``` - -The same module is imported by the behavior pack and handed to `createContainerScreen`. The filter compiles it against the **project's own** copy of `@bedrock-core/ui` and `@bedrock-core/ui-compile` — it bundles the screen together with the compiler from your `node_modules` — so a screen is always compiled against the library version the addon actually ships. - -### How a screen is discovered - -Every `**/*.screen.tsx` under `BP/scripts`, sorted by path. Ordinary `.tsx` helpers can sit beside a screen; only the suffix marks one. - -A screen's **name** is its file name without the suffix — `furnace.screen.tsx` is `furnace`. It becomes the screen's output file and part of its JSON UI namespace, `_furnace`, so it has to be unique across the addon whatever directory the screen sits in. The **namespace** is the addon's own — the `namespace` setting, or the `creator_pack` from `core.register()` — so a screen carries your name, not the library's. - -A screen's **layout key** — the number the router picks it by and the build stamps on its entity — is derived from its JSON UI namespace, `_`, by a hash folded into 1..3969. Nothing is handed out in sequence: two addons built apart never claim the same key for their first screens, a rebuild never moves a key, and an entity placed in a world keeps opening the screen it was stamped with. Two screens of one addon hashing to the same key is a build failure naming both; rename one. - -### The one rule - -:::caution A screen module — and everything it imports — must not touch the world at import time -The filter evaluates the module once, on the build machine, with `@minecraft/server` and `@minecraft/server-ui` replaced by a stub that answers any name with nothing. Hooks are fine: the compiler renders the component with its initial state. What breaks is module-scope code that reaches for the game — `world.afterEvents.*.subscribe(...)`, `system.run(...)`, a dynamic property read next to an `import`. Keep that in the module that calls `createContainerScreen`; a screen's handlers and effects only ever run in game. -::: - -## What it generates - -The screen module is the only file you own; the bundler inlines it and strips the sources like any other script. - -| Output | Why | -| --- | --- | -| `RP/ui/core-ui/screens/.json` | the compiled screen — one JSON UI namespace, `_`, per screen. It references only the library's own definitions (`core_ui_container.*`, shipped as static files under `RP/ui/core-ui/container/`) and its own | -| `RP/ui/core-ui/screens/_router.json` | the addon's router — one gated host per screen, gathered under the addon's root — see [The router](#the-router) | -| `RP/ui/chest_screen.json` | the hook: the addon's copy of vanilla's chest file, one `modifications` entry inserting the addon's root into the chest top half the chest root mounts on both UI profiles. Nothing is defined in it | -| `RP/ui/_ui_defs.json` | the three above registered, or the game never loads them — written from scratch when the pack had none | -| `RP/texts/.lang` | the character table `` decodes through; only written when a screen has live text | -| `BP/entities/.json` | the entity each screen names: `minecraft:inventory` sized to the layout, and a `core:ui_layout` property carrying the screen's key — see [Entities](#entities) | - -No `tsconfig` alias is needed: a screen is imported by its path like any other module, and `@bedrock-core/ui/container` is where `createContainerScreen` lives. - -## The router - -One router covers every screen. A marker item in the container's slot 0 carries a protocol key (is this chest a compiled screen at all?) and a layout key (which one?), and the router shows the layout whose key matches. A vanilla chest has no marker, fails the first check and renders untouched — so a world with the render pack and an ordinary chest looks exactly as it did. - -Every edit to vanilla is made in a copy of vanilla's own `chest_screen.json`, at vanilla's own path: that is the one file the engine stacks across packs, in whatever order they sit. Nothing of vanilla's is removed or re-emitted. - -- **The render pack's copy**, static, does two things. It re-declares the chest screen with a different `$screen_content` — the way vanilla's own shulker-box and barrel screens point theirs elsewhere — namely the **chest root**, `core_ui_router.chest_root` / `chest_root_pocket` in the static `RP/ui/core-ui/container/router.json`. The root holds vanilla's chest panel, referenced by name and untouched, behind a gate that opens only when no compiled layout claims the chest; behind the opposite gate sit the library's chrome (key routes, touch take-progress, the held-item icon, the controller pointer) and a second reference to vanilla's chest top half, the panel every addon's root is inserted into. And it gives that top half's two children — the title label and the 9 × 3 grid, both chest-only definitions — a visibility binding on the protocol key, so in that second reference nothing but the roots shows. A `modifications` entry cannot switch the content: `variables` is not an array modifications reach, and a `controls` insert on the screen creates an array that shadows the one the screen inherits from `common.base_screen`, emptying every chest. -- **The addon's copy**, generated, inserts the addon's root into `chest.small_chest_panel_top_half` — one `modifications` entry, defining nothing. That definition declares its own `controls`, so the inserts from packs built apart all land; the chest root mounts it on both UI profiles, so one hook covers desktop and pocket. -- **The addon's router**, `RP/ui/core-ui/screens/_router.json` (namespace `core_ui_router`, every definition prefixed with the addon's namespace), holds that root: one gated host per screen. Its path and its names carry the addon's namespace, so no addon's file overwrites another's. - -Everything a compiled screen draws — item cells, slot buttons, the scrolling region, the transport-hiding renderer — is the library's own, in the static `core_ui_container` files the render pack ships. A compiled screen and a router reference no vanilla definition; the chest root references exactly three, the two chest panels it shows for an ordinary chest and the top half it mounts the roots in. - -## Entities - -A screen names the entity it opens from. The filter finds that entity's definition under `BP/entities` by its `identifier` — a screen naming an entity that is not there fails the build — and edits the workspace copy: - -```jsonc -"description": { - "properties": { - // The runtime reads this when a player opens the entity, to pick the screen. - "core:ui_layout": { "type": "int", "range": [0, 3969], "default": 1094 } - } -}, -"components": { - "minecraft:inventory": { - "container_type": "container", // the only type that routes to the chest screen - "inventory_size": 75, // drawn slots + live channels; a hand-written value is overwritten - "private": false // `true` stops the player opening it at all - } -} -``` - -Nobody keeps `inventory_size` in step with a layout by hand — the failure mode of that is a screen that silently draws cells the container does not have. Everything else on the entity is yours: its geometry, its behavior, whether it can be pushed or hurt. The demo entity in the reference pack is an invulnerable, gravity-less body with vanilla armor-stand art. - -One entity opens one screen: two screens naming the same entity is a build error. - -## Settings - -| Setting | Type | Default | Description | -| --- | --- | --- | --- | -| `namespace` | `string` | scanned | The addon's namespace, prefixing every screen's JSON UI namespace as `_`. Left unset, it is read from the `creator_pack` in your `core.register()`, the way the other filters resolve it; set it to override | - -`namespace` is the only setting. Everything else the filter needs is a fixed addon path Minecraft requires — screens under `BP/scripts`, entities under `BP/entities`, the router at vanilla's `RP/ui/chest_screen.json`, texts under `RP/texts` — none of which is optional, so none is a setting. - -## What the build checks - -No `*.screen.tsx` under `BP/scripts` is an info-level no-op. Everything else stops the build with a message naming the fix — the compiler's own message, relayed unchanged: - -| Check | What fails | -| --- | --- | -| **Root** | A screen without exactly one `` at its root, or one without an `entity` | -| **Backend** | ``, any `Form.*` field, ``, or a nested `` — a container has no native form and cannot scroll | -| **Canvas** | Content laid out past 320 × 210 — the message gives the size it found | -| **Live text** | `` inside a ` + + + ); +} +``` + +The build runs the component once to decide the **shape**; the runtime runs it again per viewer to decide the **values**, and the two walks line up position for position because a compiled screen's shape is fixed. Nothing about a screen is declared twice. + +A container screen is the same file with `` at its root and an entity to open from: + +```tsx title="packs/BP/scripts/screens/crafting_table.screen.tsx" +/** @jsxImportSource @bedrock-core/ui */ +import { Container, Panel, Slot, Text, useState, type JSX } from '@bedrock-core/ui'; + +export default function CraftingTable(): JSX.Element { + const [planks, setPlanks] = useState(0); + + return ( + + {`planks ${planks}`} + + setPlanks(value => value + stack.amount)} + onRemove={({ stack }) => setPlanks(value => value - stack.amount)} + /> + + + ); +} +``` + +### Names and keys + +A screen's **name** is its file name without the suffix: `counter.screen.tsx` is `counter`. With the addon's namespace it becomes the JSON UI namespace `_counter`, the output file, and the key `:counter` that `` and `navigate()` take. The name has to be unique across the addon whatever directory the screen sits in. + +### Live values are reserved, not discovered + +A compiled screen is baked, so a string that changes has to say how much room to reserve for it: + +```tsx +{`count ${count}`} +``` + +The build renders the component with each state slot perturbed and fails on anything that moved without a reservation, naming the strings it saw and the `maxLength` each needs. The same probe fails a screen whose **shape** moved — a cell added, dropped or reordered — because the cells are numbered once, at build time. + +### Conditionals become carried visibility + +`{cond && }` has already collapsed to `false` by the time any renderer sees it, and nothing can tell which element went missing. So the build rewrites the source text of every `.screen.tsx` before executing it, and ships the same rewrite to the runtime: + +| Written | Compiled as | +| --- | --- | +| `{cond && }` | `` | +| `{cond ?
    : }` | `` | +| `{cond ? : null}` | `` | + +An element that already carries `visible` keeps it, joined with `&&`. Only branches that are single elements are rewritten; a string, fragment or call in a branch is left alone — wrap it in an element to make it compilable. A form carries visibility on an entry; a chest screen bakes it, so a chest screen whose `visible` moves is a build error. + +### Static screens + +A screen is **static** when every string it shows is baked and every press is a `` or the way out. Nothing about it can differ between one present and the next, so the build already knows everything showing it takes — the title, the value each entry carries, the key each press leads to — and the addon ships that table instead of the component that would recompute it. + +`` is the assertion, not the mechanism: a qualifying screen is detected either way, and declaring it makes the build fail the moment the screen stops qualifying. + +```tsx title="packs/BP/scripts/screens/menu.screen.tsx" +/** @jsxImportSource @bedrock-core/ui */ +import { Link, Panel, Screen, Text, type JSX } from '@bedrock-core/ui'; + +export default function Menu(): JSX.Element { + return ( + + + {'Menu'} + {'Shop'} + {'Balance'} + + + ); +} +``` + +A key with no `:` in front of it is one of this bundle's own, named as its file is; a key that names another addon resolves through the reference that addon published. + +A modal never qualifies — its fields are built per present — and neither does anything with a live value or a handler of its own. + +### The one rule + +:::caution A screen module, and everything it imports, must not touch the world at import time +The filter evaluates the module once, on the build machine, with `@minecraft/server` and `@minecraft/server-ui` replaced by stubs that answer every name the packages declare and do nothing. Hooks are fine: the compiler renders the component with its initial state. What breaks is module-scope code that reaches for the game — `world.afterEvents.*.subscribe(...)`, `system.run(...)`, a dynamic property read next to an `import`. Keep that in the module that opens the screen; a screen's handlers and effects only ever run in game. +::: + +### Library screens + +A screen can also come from a module whose default export is a record of components, named by its keys. The `screens` setting lists such modules: + +```jsonc title="config.json" +{ "filter": "ui-compiler", "settings": { "screens": ["@bedrock-core/config/compiled"] } } +``` + +An addon that calls `core.register()` gets [`@bedrock-core/config`](/docs/config)'s screens without asking: declaring is what asks for them. The filter reads the register call in `BP/scripts/main.ts` or `BP/scripts/index.ts`, and compiles a config screen per section of the declared schema plus the addon's page in the shared addon list, both shaped for what the declaration says. An addon that names its own `page` keeps that one. + +## What it generates + +Everything lands in Regolith's temp workspace except the one declaration file, which is written back into the project for the editor's sake. The screen module is the only file you own. + +| Output | Where | Commit it? | +| --- | --- | --- | +| `RP/ui/core-ui/screens//.json` | workspace | ❌ | +| `RP/ui/core-ui/screens//faces.json` | workspace | ❌ | +| `RP/ui/core-ui/screens/_forms.json` | workspace | ❌ | +| `RP/ui/server_form.json` | workspace | ❌ | +| `RP/ui/core-ui/screens/_router.json` | workspace | ❌ | +| `RP/ui/chest_screen.json` | workspace | ❌ | +| `RP/ui/_ui_defs.json` | workspace, edited or created | ❌ | +| `RP/texts/.lang` | workspace, appended | ❌ | +| `BP/entities/.json` | workspace, edited | ❌ | +| `data/ui/ui.generated.ts` | workspace | ❌ | +| `data/ui/declared.screens.ts` | workspace | ❌ | +| `/ui/screens.generated.d.ts` | the project | ✅ | +| `RP/ui/core-ui/screens//.preview.json` | workspace, `gallery` only | ❌ | +| `RP/ui/core-ui/screens//gallery.json` | workspace, `gallery` only | ❌ | +| `RP/ui/core-ui/screens//core_build.json` and `RP/ui/hud_screen.json` | workspace, `stamp` only | ❌ | + +The screens sit under a folder named for the addon because a resource pack file is replaced, not merged, by a higher pack's file at the same path: two addons that both compiled a `guide_home` would otherwise shadow each other's namespace. Every UI file is registered in `_ui_defs.json`, or the game never loads it. + +### faces.json + +A **face** is one look with its static props — a button's four textures, a label's font and scale, a cell frame — carrying no bindings at all. Faces are deduplicated by a signature over the props that reach JSON UI, so a look is one definition however many screens draw it, and they live in the addon's own file rather than in the render pack: a styled layer other than [`ore-styled`](/docs/ore-styled) ships its own with nothing added to the pack. + +### The generated module + +`data/ui/ui.generated.ts` is reached from scripts as `@bedrock-core/generated/ui`, the way the [i18n](./i18n.md) and [guides](./guides.md) bundles are. Importing it is what associates a component with the layout compiled from it — the build knows a screen by its file, the runtime by the component it is handed — so the filter adds the import to the workspace copy of the script entry. Without it `render()` refuses every screen. + +| Export | Kind | Description | +| --- | --- | --- | +| `SCREEN_KEYS` | `readonly string[]` | Every screen this addon compiled, by the key it is navigated with | +| `ScreenKey` | type | One of `SCREEN_KEYS` | +| `UI_NAMESPACE` | `string` | The namespace the build wrote into every key and title | +| `UI_REFERENCE` | table | The static screens as rows: key, title, entry values, press targets | +| `uiReference()` | function | The same table as the `AddonReference` an addon publishes | +| `openGallery(player, options?)` | function | Opens the gallery; warns and returns `false` in a build without one | + +The module also augments `ScreenKeys`, so `navigate()` and `` autocomplete this addon's keys while still accepting another addon's — resolving one of those is the point. `/ui/screens.generated.d.ts` is the same declaration written back into the project, because the generated module only ever exists inside a Regolith run and the editor never sees one. + +Publishing the reference once at startup is what lets a realm running none of this addon's script show its static screens: + +```ts title="packs/BP/scripts/main.ts" +import { core } from '@bedrock-core/server'; +import { uiReference } from '@bedrock-core/generated/ui'; + +core.register({ manifest, screens: uiReference() }); +``` + +## How a screen reaches the screen it is drawn on + +Both hosts are reached the same way: one gated definition per screen under a root named for the addon, and one insert putting that root where the screen can see it. A gate compares the whole of what identifies the screen, so two screens can never both match. + +- **Form screens** gate on the form's title, which carries the protocol header and the screen's namespaced name. The library's own container is already gated on that header, so a compiled form needs no vanilla edit: the addon's root is inserted into the mount. The pack that *defines* the mount lists its root in the definition directly; every other pack inserts through `RP/ui/server_form.json`. +- **Container screens** gate on a layout key. A marker item in the container's first two slots carries a protocol key — is this chest a compiled screen at all? — and the layout key as two stack sizes, and the router shows the layout whose key matches. A vanilla chest has no marker, fails the first check and renders untouched. + +A screen's layout key is a hash of `_` folded into 1..3969. It depends on nothing but the screen's own name, so a rebuild never moves a key and an entity placed in a world keeps opening the screen it was stamped with; two addons built apart never claim the same key for their first screens. Two screens of one addon hashing alike is a build failure naming both. + +Every edit to a vanilla file is one `modifications` entry defining nothing, at vanilla's own path. That is the one kind of edit the engine stacks across packs in whatever order they sit — a definition in a vanilla file would replace vanilla's and every other pack's instead of joining them. The insert target declares its own `controls`, because an insert on a definition that merely inherits the array creates one that shadows it. + +## Entities + +A container screen names the entity it opens from. The filter finds that entity's definition under `BP/entities` by its `identifier` — a screen naming an entity that is not there fails the build — and stamps the workspace copy: + +```jsonc +"description": { + "properties": { + // The runtime reads this when a player opens the entity, to pick the screen. + "core:ui_layout": { "type": "int", "range": [0, 3969], "default": 1094 } + } +}, +"components": { + "minecraft:inventory": { + "container_type": "container", // the only type that routes to the chest screen + "inventory_size": 75, // drawn slots + live channels; a hand-written value is overwritten + "private": false // `true` stops the player opening it at all + } +} +``` + +Nobody keeps `inventory_size` in step with a layout by hand — the failure mode of that is a screen that silently draws cells the container does not have. Everything else on the entity is yours: its geometry, its behavior, whether it can be pushed or hurt. + +One entity opens one screen: two screens naming the same entity is a build error. + +## The character table + +A container slot publishes no text, so a live string crosses one character per slot: each cell reads its slot's stack size and localizes a key built from it. The table that turns those codes back into glyphs is appended to every `RP/texts/.lang`, in a marked block, and only when a container screen actually has live text. It comes from the runtime the project ships rather than from the filter, because it is the contract between the compiler and the runtime — they encode against the same list or nothing renders. + +## The gallery + +With `gallery: true` the build writes each screen twice: the served screen, and the same screen as **faces alone** under its own namespace, gated on its own title. A `gallery` screen lists every preview, and a press opens one. That is where a screen is looked at before any host attaches a channel to it — a preview has no entity, no entry and no channel, and shows reference strings, reference visibility and fields as static twins. + +```ts +import type { Player } from '@minecraft/server'; +import { openGallery } from '@bedrock-core/generated/ui'; + +export const showGallery = (player: Player): void => { + openGallery(player); +}; +``` + +For a development profile only, the way a component storybook is. A build without it exports an `openGallery` that warns and shows nothing. + +## Settings + +| Setting | Type | Default | Description | +| --- | --- | --- | --- | +| `namespace` | `string` | declared | The addon's namespace, lowercase `a-z`, `0-9` and `_`; it prefixes every screen's JSON UI namespace and names the router file and the output folder. Left unset, it is the `creator` and `pack` of the manifest the addon declared | +| `stamp` | `boolean` | `false` | Draw a build stamp at the HUD's top left — a short hash over everything under `RP/ui` plus the build clock — so what a running client is rendering is never in question | +| `gallery` | `boolean` | `false` | Write every screen's preview and the gallery screen that opens them, and export a working `openGallery` | +| `screens` | `string[]` | `[]` | Modules whose default export is a record of screens to compile besides the addon's own, each export key naming one | + +Every path is what the game needs, so none of them is a setting: screens under `BP/scripts`, entities under `BP/entities`, output under `RP/ui/core-ui/screens`, texts under `RP/texts`, and the hooks at vanilla's own paths. + +## Checks + +No screen to compile and no `screens` setting is an info-level no-op. Everything else stops the build with the compiler's own message, relayed unchanged, because those messages already name the fix. + +| Check | What fails | +| --- | --- | +| Root | A tree that starts with something other than ``, `` or ``; more than one element at a form's root; a `` with no `entity` | +| Shape | A screen that adds, drops or reorders a cell when its state changes | +| Live text | A `` whose string changes with no `maxLength`; the message names each string it saw and the length it needs | +| Carried visibility | A `visible` that moves on a container screen, which bakes it | +| Static | `` on a screen that carries a live value or runs a handler of its own, naming which | +| Canvas | Content laid out past 320 × 210, with the size it measured | +| Mechanism | A component the screen's host has no mechanism for — a slider or a dropdown outside a modal, a slot outside a container screen | +| Unsupported | A control with no compiled form at all, listing what is supported | +| Face rules | A face carrying a binding that reads a host, an image without `keep_ratio: false`, a label that does not say whether it localizes, two siblings of one name, a reference or `source_control_name` that resolves to nothing | +| Placement | A host that moved a control while standing its mechanism in, with the face's rect and the host's | +| Shared faces | A control that changes at runtime, or one needing a definition of its own, baked inside a button's face | +| Names | Two screens with the same name; a name or namespace outside letters, digits, `_` and `-` | +| Face collision | Two screens of one addon sharing a face name with different contents | +| Entity | An `entity` with no definition under `BP/entities`; two screens naming the same entity | +| Namespace | No `namespace` setting and no `manifest: { creator, pack }` in the register call | +| Import time | A module that reaches for the game while being evaluated | + +An entry that throws on the way to its `core.register()` call is a warning, not a failure: the addon gets none of the screens that follow from declaring, and the reason is printed rather than leaving a pack that builds clean with no config screen in it. + +## Notes + +The pipeline runs inside the bundle the filter builds, so `@bedrock-core/ui-runtime` and `@bedrock-core/ui-compiler` resolve from the **project's** `node_modules`. A screen is always compiled against the library version the addon actually ships, and the filter cannot drift from it. Every value the emitted JSON UI shares with the runtime — the character table, the layout property, the highest layout key — is read off that bundle for the same reason. + +The compiler itself and its layers are in [Faces and hosts](/docs/ui/compiler/passes), its programmatic entry points in [`@bedrock-core/ui-compiler`](/docs/ui/compiler/api), and what serves a compiled screen in game is [`@bedrock-core/ui`](/docs/ui). diff --git a/docs/ui/api/api.md b/docs/ui/api/api.md index 137de43..5b9279b 100644 --- a/docs/ui/api/api.md +++ b/docs/ui/api/api.md @@ -1,25 +1,55 @@ --- sidebar_position: 1 -description: "Core functions and utilities for building and displaying UI." +description: "render(), the contexts, the compiled-screen registry and the error classes." --- # API -Core functions and utilities for building and displaying UI. +The top-level surface: showing a screen, the contexts around it, and the records the build leaves behind. -## Functions +## Showing a screen -- [`render(root, player)`](./render.md) — Entry point for all UI. Displays a component tree to a player. -- [`createContext(defaultValue)`](./createContext.md) — Create a context object for passing values down the component tree without prop drilling. +- [`render(root, player, options?)`](./render.md) — show a compiled screen to one player and keep it shown across its state changes +- [`navigate(key, player, options?)`](../guides/navigation.md) — open a screen by key, including one another addon built +- `back(player)` — return to the screen the player came from +- `closeUi(player)` — close what a player is looking at, from outside the screen +- `createContainerScreen(Screen)` — serve a [container screen](../guides/container-screens.md), from `@bedrock-core/ui/container` ## Contexts -- [`TranslationContext`](./TranslationContext.md) — The context carrying how localized text resolves for a component subtree. `render()` provides it at every root, so you rarely provide it yourself. +- [`createContext(defaultValue)`](./createContext.md) — pass a value down the tree without prop drilling +- [`TranslationContext`](./TranslationContext.md) — how localized text resolves for a subtree; `render()` provides it at every root, so you rarely provide it yourself +- `ModalContext` — marks that a subtree is inside a ``; read by the build's restriction pass + +## Build records + +- [Compiled screens](./compiled-screens.md) — the component-to-title registry, the snapshot a `debug` render is diffed against, and the reference table a static screen publishes + +## Errors + +- [Errors](./errors.md) — every error class the library throws and the fix each one names + +## Types + +```ts +import type { + ControlProps, LayoutProps, + FunctionComponent, JSX, + NavigateOptions, RenderOptions, ScreenKey, ScreenKeys, + PressEvent, SlotEvent, SubmitEvent, UiEvent, ContainerEvent, + CompiledScreen, CompiledSnapshot, + AddonReference, ScreenReference, ReferenceTarget, WalkResult, +} from '@bedrock-core/ui'; +``` + +Every component's props type is exported beside it — `ButtonProps`, `TextProps`, `ListProps`, `TabsProps` and the rest — and every flex primitive through [`@bedrock-core/ui/flexbox`](/docs/flexbox). ## Advanced -- [Custom Native Components](../guides/custom-native-components.md) — register your own native component `type` that the runtime serializes and your resource pack's JSON UI decodes. Requires JSON UI **and** serialization knowledge. +- [Custom native components](../guides/custom-native-components.md) — register your own native component `type` that the runtime serializes and your resource pack's JSON UI decodes +- [`@bedrock-core/ui-compiler`](../compiler/api.md) — the build-time library, for tooling rather than for addons ## Next steps -- [Components](../components/components.md) — Built-in components that you can use in your JSX -- [Hooks](../hooks/hooks.md) — Add state and effects to your components +- [Components](../components/components.md) — every built-in component +- [Hooks](../hooks/hooks.md) — state and effects +- [Hosts](../guides/hosts.md) — what each screen can carry diff --git a/docs/ui/api/compiled-screens.md b/docs/ui/api/compiled-screens.md new file mode 100644 index 0000000..9a0e733 --- /dev/null +++ b/docs/ui/api/compiled-screens.md @@ -0,0 +1,79 @@ +--- +sidebar_position: 6 +description: "The registry that maps a screen component to the title and key the build gave it, and the table a static screen ships as." +--- +# Compiled screens + +The registry the build writes into and `render()` reads out of. + +## Import + +```ts +import { + addonReference, + compiledKeyOf, + compiledScreens, + compiledSnapshotOf, + compiledTitleOf, + presentReference, + registerCompiledScreen, + registerStaticScreens, + screenForKey, +} from '@bedrock-core/ui'; +``` + +Most of this is called by the module the build generates, not by hand. It is documented because a host that shows screens it did not build reads the same records. + +## Why the component is the key + +The build knows a screen by its file; the runtime knows it by the function `render()` was handed. Nothing carries a name between the two on its own, and the alternatives are all worse: a function's `.name` does not survive a bundler faithfully, a string the author repeats at the call site is a second place for the truth to live, and stamping a name into the author's module is a build editing source it does not own. + +So the build generates one module that imports each screen and registers it — the same shape as the i18n and guides bundles — and the addon imports that module once. The association is by component identity, which is what `render()` already has in hand. + +## Registration + +| Export | Kind | Description | +| --- | --- | --- | +| `registerCompiledScreen` | function | Records that a screen was compiled, with the key it is navigated by and the title it is drawn by | +| `registerStaticScreens` | function | Records the screens the build described in full, which ship as data rather than as components | + +Registering one component twice with different titles throws: one component is one compiled screen, so render it twice rather than compiling it twice. + +## Reading it back + +| Export | Kind | Description | +| --- | --- | --- | +| `compiledTitleOf` | function | The title a screen's layout is picked by, or `undefined` when it was not compiled | +| `compiledKeyOf` | function | The `:` key a screen is navigated by | +| `compiledSnapshotOf` | function | What the build baked: the shape fingerprint, the baked strings, and the carried-visible ordinals | +| `screenForKey` | function | The component a key names in this bundle, or `undefined` | +| `compiledScreens` | function | Every compiled screen this bundle registered, in registration order | + +Both `compiledTitleOf` and `compiledKeyOf` accept a component or an element rendering one, because a compiled screen takes props that way — a generic screen filled per present, whose shape does not depend on them. + +## The snapshot + +```ts +interface CompiledSnapshot { + readonly shape: string; + readonly baked: readonly string[]; + readonly vis: readonly number[]; +} +``` + +`vis` is load-bearing: it is how the runtime marks the same elements the build compiled bool carriers for, by position in the shared visible walk — stable because the shape is frozen. `shape` and `baked` serve [`render`'s `debug`](./render.md#debug): a present that disagrees with either is a liveness miss the build could not see. + +## References + +| Export | Kind | Description | +| --- | --- | --- | +| `addonReference` | function | Every static screen this bundle carries, as the record an addon publishes | +| `presentReference` | function | Shows a foreign screen and follows its links until a press leads nowhere | +| `isAddonReference` | function | Narrows a reference that arrived over the wire: the envelope | +| `isScreenReference` | function | Narrows one screen's reference | + +A reference is the title, the value each entry is shown with, and where each press leads. That is all a realm needs to show a screen it did not build, because the prose, the textures and the layout are already in the pack every client holds. + +Only a [static](../guides/navigation.md#static-screens) screen has one. A press running the owner's own handler cannot be described, so its target is `null` and it does nothing in a foreign realm — the screen still shows, and the presses that are links still work. + +`presentReference` returns `'back'` when the player pressed back out of the first screen of the walk, and `'done'` when the walk simply ended. That is how whoever opened it knows whether to show what the player came from. diff --git a/docs/ui/api/errors.md b/docs/ui/api/errors.md new file mode 100644 index 0000000..bf94038 --- /dev/null +++ b/docs/ui/api/errors.md @@ -0,0 +1,59 @@ +--- +sidebar_position: 5 +description: "The error classes the UI throws, what each one means, and the fix it names." +--- +# Errors + +Every error the library throws is a class you can catch with `instanceof`. Each one names the fix rather than only the symptom. + +## Import + +```ts +import { + ContainerScreenError, + ModalFormError, + ScreenRootError, + SerializationError, + UncompiledScreenError, +} from '@bedrock-core/ui'; +``` + +## UncompiledScreenError + +`render()` was handed a screen the build never compiled, so nothing in the pack answers to its title. + +Two things produce a registration: the [`ui-compiler` filter](/docs/filters/ui-compiler) seeing the screen, and `@bedrock-core/generated/ui` being imported once so the registrations run. Check both. + +## ScreenRootError + +The tree has no host root, or a root below its root. + +A screen's root names its [host](../guides/hosts.md) — [``](../components/Screen.md), [``](../components/Form/Form.md) or [``](../components/Container.md) — and there is no default, so a tree that starts with a `Panel`, a themed card, or two elements side by side has no screen to be. Providers and fragments above the root are looked through. + +It is also what a component throws when it asks [`useMechanism`](../hooks/useMechanism.md) and nothing above it names a host at all. + +## ContainerScreenError + +The tree breaks the container-screen rules. The cases: + +- a `` handed to `render()`, or a form handed to `createContainerScreen` +- a container-only control — [``](../components/Slot.md), [``](../components/SlotGrid.md) — outside a `` +- a `` with no `entity` +- content that does not fit the 320 × 210 canvas, which a container screen cannot scroll past +- a hook that needs a player where one compiled layout serves every player + +## ModalFormError + +The tree breaks the modal rules: a regular ` - ); -} +## debug + +Probing at build cannot see a threshold no probe crossed. `debug` is where such a miss becomes loud instead of silent: every present is diffed against what the build recorded, and a baked prop that changed, a shape that does not match, or a live string past its reservation is warned about. + +```ts +render(Screen, player, { debug: true }); ``` -When the handoff goes through an async opener (a prefetch, an RPC), **return the promise from `onPress`** so the swap lands inside the press's transaction — deterministic and flash-free. Fired-and-forgotten it still converges; worst case the screen re-locks for a frame. +Leave it off in a shipped build — the diff runs on every present. ## Usage -```tsx -import { render, Panel, Screen, Text } from '@bedrock-core/ui'; -import { world } from '@minecraft/server'; - -function WelcomeScreen() { - return ( - - - {'Hello, Minecraft!'} - - - ); +```ts +import { render } from '@bedrock-core/ui'; +import '@bedrock-core/generated/ui'; +import Welcome from './welcome.screen'; + +export function openWelcome(player: Player): void { + render(Welcome, player); } +``` -const isPlayer = (source: Entity): source is Player => source.typeId === MinecraftEntityTypes.Player; +## Scrolls -// Render it to a player -world.afterEvents.buttonPush.subscribe(({ source }: ButtonPushAfterEvent): void => { - if (isPlayer(source)) { - render(WelcomeScreen, source); - } -}); -``` +Content renders into a single full-screen **root scroll** by default, which scrolls when it overflows. For independent scroll regions compose [``](../components/Scroll.md); a form supports two of them beside the root. + +## Notes + +Each player has one live UI session, and a second `render()` swaps the new tree into it rather than stacking a second one. [State](../guides/state.md#one-ui-slot-per-player) covers what that does to the old tree's hooks and effects, and how to make an async handoff flash-free. + +To open a screen by key rather than by component — including another addon's — use [`navigate()`](../guides/navigation.md) instead. diff --git a/docs/ui/compiler/_category_.json b/docs/ui/compiler/_category_.json new file mode 100644 index 0000000..10e4737 --- /dev/null +++ b/docs/ui/compiler/_category_.json @@ -0,0 +1,10 @@ +{ + "position": 7, + "label": "Compiler", + "collapsible": true, + "collapsed": true, + "link": { + "type": "doc", + "id": "compiler/index" + } +} diff --git a/docs/ui/compiler/api.md b/docs/ui/compiler/api.md new file mode 100644 index 0000000..7ef1411 --- /dev/null +++ b/docs/ui/compiler/api.md @@ -0,0 +1,71 @@ +--- +sidebar_position: 3 +description: "@bedrock-core/ui-compiler: the entry points the ui-compiler filter calls, and the limits the compiled model imposes." +--- +# @bedrock-core/ui-compiler + +The build-time library the [`ui-compiler` filter](/docs/filters/ui-compiler) runs: a screen component goes in, the JSON UI document a host serves comes out. + +This page is for tooling. An addon never imports it — the filter does, and it bundles the compiler out of the **project's** `node_modules` rather than its own, so a screen is compiled by the version of the library the addon actually ships. An addon that compiles screens therefore depends on the compiler even though none of it reaches `main.js`. + +## Import + +```ts +import { compileFormScreen, compileScreen } from '@bedrock-core/ui-compiler'; +``` + +The build half of the runtime is a subpath of its own, and supplies everything the compiler takes as input: + +```ts +import { buildScreenOnce, hostFor, probeLiveness } from '@bedrock-core/ui-runtime/compile'; +``` + +## Compiling one screen + +```ts +compileScreen(Screen, { name, namespace? }): CompiledScreen +compileFormScreen(Screen, { name, namespace }): CompiledFormScreen +``` + +Both take the **component**, not the result of calling it: the compiler renders it under its own owner, which is what makes the hooks inside it resolve. `compileScreen` serves the chest; `compileFormScreen` serves the action form and the modal, deciding which from the root. Each probes for liveness before anything is baked, and each returns the served document, the face document, the preview, and the counts the filter reports. + +## Compiling an addon + +```ts +buildRouter(screens): ChestRouting +formRouter(screens, addon): FormRouting +``` + +The addon-level documents: the hooks into vanilla files, and the router holding one gated definition per screen. One addon per call — a router covers one addon, and mixing two is an error. + +## Exports + +| Export | Kind | Description | +| --- | --- | --- | +| `compileScreen` | function | Compiles one container screen | +| `compileFormScreen` | function | Compiles one form screen, action or modal | +| `buildRouter` | function | The chest hooks and one addon's chest router | +| `formRouter` | function | The mount insert and one addon's form router | +| `toIr` | function | A built root plus a host's addressing, lowered to IR | +| `faceOf` | function | IR to a face document and the faces it shares | +| `fill` | function | A face document plus a host, to the served document | +| `emit` | function | `faceOf` then `fill`, for a caller that wants only the result | +| `facesNamespaceOf` | function | `_faces`, the namespace an addon's shared faces live in | +| `previewNamespaceOf` | function | `__preview`, a preview's own namespace | +| `formRouterFileOf` | function | Pack path of an addon's form router | +| `CHEST_HOST` | const | The chest host: its hooks, canvas, collection and container type | +| `MOUNT_ANCHOR` | const | Where a compiled chest layout sits: centered both ways | +| `MOUNT_FILE` | const | Pack path of the form mount an addon inserts into | +| `SCREEN_DEFINITION` | const | Name of the definition the router mounts | +| `BACKDROP_DEFINITION` | const | Name of the full-screen image mounted behind it | +| `UnsupportedNodeError` | class | Thrown for a control with no compiled form | + +The IR node types, the JSON UI control types, and the result shapes (`CompiledScreen`, `CompiledFormScreen`, `FaceDocument`, `Preview`, `ScreenSpec`, `FormScreenSpec`, `ChestRouting`, `FormRouting`, `RoutedScreen`, `RoutedFormScreen`, `ToIrOptions`, `Allocation`) are exported as types beside them. + +## Limits + +Percentages, `%c` and anchors are not exposed to authors. The layout solver is the one source of geometry and it produces pixel rects against a canvas the host names; JSON UI's relative sizes appear only where the engine has to decide at draw time — a stack sized so hidden rows collapse, a fill inside a box the layout already sized. A screen-relative canvas is a host property, never a prop. + +Sharing one parameterized frame between a look's states does not work. A frame resolves `caption@$core_content` in its own scope, where the variable was never set, so the reference names nothing and the control has no type: the client refuses every caption in the world. Sharing has to happen at the mount, with each consumer carrying the caption name along with the frame. + +A config screen shaped for a schema is compiled into the **owning** addon's pack, and the host draws every addon's config — so a host has shaped screens for its own sections and none for anybody else's. The list item is answered by generic fallbacks that ship in the library set, `list_item_text` and `list_item_choice`, which the host falls back to whenever the owner's shaped screen is not in its bundle. Other shaped screens have no fallback. diff --git a/docs/ui/compiler/index.md b/docs/ui/compiler/index.md new file mode 100644 index 0000000..e5c0a0c --- /dev/null +++ b/docs/ui/compiler/index.md @@ -0,0 +1,42 @@ +--- +sidebar_position: 1 +sidebar_label: Overview +description: "How a screen's JSX becomes the static JSON UI a host serves, and what the build guarantees about it." +--- +# Compiler + +Every screen is compiled. `@bedrock-core/ui-compiler` turns a screen component into the static JSON UI that ships in the resource pack, and the [`ui-compiler` filter](/docs/filters/ui-compiler) is what runs it over a project. + +Nothing in the compiler reaches the game. It has no `@minecraft/server` calls and no components of its own: it renders a screen once on the build machine and writes a document the client already holds by the time anybody opens it. What crosses at runtime is the screen's title and the values that changed. + +## How a screen is compiled + +Four steps, each a pure function of the last. + +| Step | Takes | Gives | +| --- | --- | --- | +| Build | the screen component | one built element tree, rendered under the build's own owner so its hooks resolve | +| Lower | that tree, laid out against the host's canvas | the IR: one node per control, each with its rect, its static props and the mechanism it needs | +| Face | the IR | the face document — every control as its look alone, with no bindings at all | +| Fill | the face document plus a host | the screen document the host serves | + +Layout is solved once, at build, by [`@bedrock-core/flexbox`](/docs/flexbox) against a fixed 320 × 210 canvas. No geometry is measured in game and no layout is sent to the client. + +Which host a screen compiles for is decided by its root element, and there is no default — `` is an action form, `` a native modal, `` a chest screen. What differs between them is in [Hosts](../guides/hosts.md). + +## What you get + +**One geometry** — the layout pass owns every `size`, `offset`, `anchor_from` and `anchor_to`, and the host pass is diffed against it after it emits. A host can replace what a control is; it can never move it, so a mechanism cannot quietly break a layout that was signed off. + +**A capability model with names** — each host declares what every kind of component becomes on it. A `` outside a ``, a `` outside a container screen: refused at build, by name, in that host's own words, instead of drawn inert. + +**A drawable document with no host behind it** — the face pass produces a complete screen on its own. That is what the static rules run over, what the [gallery](/docs/filters/ui-compiler#the-gallery) shows, and why nothing hidden can evaluate a binding that is not there. + +**A frozen shape** — a compiled screen cannot add or drop a control at runtime. Everything that varies says so in the source: [``](../components/List.md) for a count, [`maxLength`](../components/Text.md) for a string, `visible` for a branch. A render that drifts from what the build measured is reported by `render(screen, player, { debug: true })` rather than silently drawn wrong. + +## Next steps + +- [Faces and hosts](./passes.md) — the two passes, the three layers, and the behaviors a primitive carries +- [`@bedrock-core/ui-compiler`](./api.md) — the programmatic entry points, for tooling rather than for addons +- [Hosts](../guides/hosts.md) — the three screens the library draws on, and what each can carry +- [`ui-compiler` filter](/docs/filters/ui-compiler) — running the compiler over a project diff --git a/docs/ui/compiler/passes.md b/docs/ui/compiler/passes.md new file mode 100644 index 0000000..b80d96b --- /dev/null +++ b/docs/ui/compiler/passes.md @@ -0,0 +1,98 @@ +--- +sidebar_position: 2 +description: "The face pass and the host pass, the three layers between the IR and the JSON UI, and the behaviors a primitive carries." +--- +# Faces and hosts + +Every screen is compiled twice over, and one invariant separates the halves: the **face pass** owns the layout, the **host pass** owns the mechanism. A host may replace what a control *is*; it may never move it. + +| Pass | Takes | Gives | Bindings | +| --- | --- | --- | --- | +| Face | the solved IR | the addon's shared faces, and one face document per screen | never | +| Host | a face document and a placement | the screen document the host serves | only here | + +## Faces and sockets + +A **face** is a node's look with its static props. A **socket** is a node with at least one carried prop or one input: a button with a press, a label whose text is live, a slot, a native field, a subtree whose `visible` is carried. + +The face document draws every socket as its inert face — the button with no mappings, the label with its reference string, the slot as an empty cell frame, the field as its payload-free twin — so the document is complete and drawable with no host behind it at all. That is what the gallery shows, and what the static validator checks. + +The host then takes each socket, in document order, and either **wraps** its face (a gate reading a carried `visible`; a one-child `stack_panel` carrying an entry index) or **replaces** it (a cell over a container slot, a text carrier in place of a static label, a native field placed by its row). Nothing outside the sockets is touched. + +Two reasons the split is not cosmetic: + +- The rules that only hold for static trees run once, over the face document, with no host in the loop. A face carrying a binding that reads a host is itself a failure. +- An engine component behind a gate that reads a collection row which is not there is a client assertion. A slider or a toggle lives in a face, and a face has no bindings, so nothing built hidden can evaluate a row. + +A face document cannot leave a named hole for another file to fill: a `$variable` used as an `@` base mounts nothing. So the face pass hands the host a complete document and the host splices into it. + +## The rect guard + +After the host emits, every control's `size`, `offset`, `anchor_from` and `anchor_to` are diffed against the face document. Any difference is a build error naming the control and the host: the placement is the layout's, signed off before any host touched the screen. The guard runs inside every compile, so the tests and a project build both hit it. + +## The three layers + +The stretch between the IR and the JSON UI is three directories, each a pure step and each testable without the other two. + +| Layer | Takes | Gives | Knows | +| --- | --- | --- | --- | +| `faces/` | plain data: a rect, textures, a style, children already drawn | one control entry — the look, written as JSON UI | nothing else; no host, no context, no address | +| `connectors/` | that face, plus the address the host allocated | the control that stands in the face's place | one host each | +| `nodes/` | a JSX element | an IR node, and the mechanism that node needs | the IR, and what each kind is | + +A face is `(data) => ControlEntry`; a connector is its mirror, `(data, face, ctx) => ControlEntry`. Children reach a face already drawn, so no recursion crosses two layers, and a connector never sees an IR node — everything it needs is in its own payload. + +`connectors/chest` and `connectors/form` are separate entry points rather than one barrel, because the two hosts share names and nothing else: a form's `press` is an entry the engine reports back, a chest's is an item taken and put straight back. + +Faces come in three families. **Primitives** are one look with nothing composed. **Compositions** have no look of their own and add the native plumbing that mixes drawn parts, which on a compiled screen is always a toggle. **Utils** are the vocabulary the two share. + +`nodes/` holds `primitives/` and `utils/` and nothing else. Every kind is one JSON UI control type with its static props; the utilities are what more than one lowering reads off an element. There is no composition layer — a composition is a component, built out of primitives. + +## The seam + +Nothing above a host dispatches on a host, and nothing below a host dispatches on a component. Both directions are registries, not switches. + +| Registry | Holds | Adding to it | +| --- | --- | --- | +| Node definitions | one entry per IR kind: which JSX types it lowers from, its children, the mechanism it needs, its face | a module under `nodes/primitives/` plus a list entry | +| Hosts | one entry per screen the library draws on | a folder under `hosts/` plus a list entry | +| Host mechanisms | one function per socket kind the host can serve | a key in that host's `fill` table | + +A node kind is one vertical slice: its IR shape, how a built element lowers into it, and how that shape draws. The walks stay dumb — the lowering walk owns order, geometry and naming; the face walk owns document assembly; the host walk owns socket order — and each dispatches through the definitions. + +A socket kind absent from a host's table is refused at build, by name, in that host's own words. That is the whole of the capability model: `press`, `text`, `texture`, `slot`, `grid`, `field`, `list` and `visible` are the kinds, and a host serving none of them draws faces alone, which is exactly what a preview is. + +## Behaviors + +A behavior is client-only logic a primitive carries: still static, still in the face document, never a mechanism. Between them they are every switch the library has. + +| Behavior | What it is | +| --- | --- | +| `route` | a button's mappings: close, submit, form click | +| `group` | swaps that move together, one forced index each | +| `states` | which children a control draws per state | +| `follows` | a sibling drawn while a swap beside it is on | + +A swap is the one mechanism a compiled screen owns outright: a toggle changes its own content with nothing reaching script. So everything built on it — a tab change, a fold, a choice between options — costs no press, no re-present and no payload. [``](../components/Tabs.md) is a group of swaps whose panes are drawn; [``](../components/Disclosure.md) is one swap with a panel that follows it. + +Content a swap shows lives inside the look, which is what keeps a look that is not showing from being built. Two things follow. A look may **draw** a sibling of its swap, which the compile moves inside it and re-bases from the swap's own corner — for content too big to solve inside the control that switches to it, such as a tab's whole pane. And `follows` is the one read in the other direction, for the one case that cannot nest: a fold's rows have to reflow what is under them, and a stack gives a hidden child no space, which is the reflow. + +Everything crossing siblings is resolved in the one walk that has the sibling list, because nothing inside a node can see what sits beside it. + +## Adding a host + +A host is one Minecraft screen the library draws on, and the transport that screen offers. Every screen-specific fact lives in one: the routing, the carriers, the inputs, the vanilla file that is hooked, the chrome, the runtime loop. + +1. Measure the screen — which vanilla file, which collection or string it publishes, what a control can read there, what an input looks like from script, how it is opened and closed. +2. Fill in the capability row: root element, owner, update model, routing key, carriers, inputs, native controls, cost unit. A column with nothing in it means the host offers nothing there, and components needing it are refused. That is correct, not a gap to paper over. +3. Write the contract shared with the runtime — carriers, inputs, routing, `allocate` — then the build half and the runtime half. No component changes. No IR changes unless the screen has a primitive nothing else has, and then as a host-agnostic node kind the host serves. +4. Add the vocabulary it needs to the render pack under `core_ui_`. +5. Add a screen to the reference addon. + +`allocate` is the one walk that runs at build and at runtime both, and it must produce the same placement position for position. Everything else in the build half runs only at build. + +## Next steps + +- [`@bedrock-core/ui-compiler`](./api.md) — the entry points the filter calls +- [Hosts](../guides/hosts.md) — what each of the three screens can carry +- [Custom native components](../guides/custom-native-components.md) — adding a component the render pack draws diff --git a/docs/ui/components/Background.md b/docs/ui/components/Background.md index 66e3a46..87cc03d 100644 --- a/docs/ui/components/Background.md +++ b/docs/ui/components/Background.md @@ -1,5 +1,5 @@ --- -sidebar_position: 7 +sidebar_position: 9 description: "Draw a full-screen texture behind everything in a form." --- # Background @@ -31,8 +31,6 @@ If a tree contains more than one ``, only the first is rendered; the ## Props -### Component-Specific props - | Prop | Type | Default | Description | | --- | --- | --- | --- | | `texture` | `string` | — | Resource-pack texture path drawn as the full-screen backdrop, e.g. `'textures/ui/my_background'` | diff --git a/docs/ui/components/Button.md b/docs/ui/components/Button.md index e1ed118..e7de184 100644 --- a/docs/ui/components/Button.md +++ b/docs/ui/components/Button.md @@ -1,10 +1,10 @@ --- -sidebar_position: 5 -description: "Interactive button component that responds to player interactions." +sidebar_position: 6 +description: "A press, textured per state, with an onPress handler." --- # Button -Interactive button component that responds to player interactions. +A press. ## Import @@ -15,45 +15,41 @@ import { Button } from '@bedrock-core/ui'; ## Usage ```tsx - ``` -Buttons are sized intrinsically from their content plus the button's built-in padding. Drop them inside a `Panel` and use flex props (`flex`, `flexDirection`, `gap`, …) to lay them out. +Buttons are sized intrinsically from their content plus the button's built-in padding. Drop them inside a `Panel` and use flex props to lay them out. ## Props -### Component-Specific props +| Prop | Type | Default | Description | +| --- | --- | --- | --- | +| `onPress` | `(event: PressEvent) => unknown \| Promise` | — | Runs when the player presses the button | +| `children` | `JSX.Node` | — | What the button shows, typically a `Text` or an `Image` | +| `backgroundHover` | `string` | `background` | Texture drawn while the player hovers | +| `backgroundPressed` | `string` | `background` | Texture drawn while the button is being pressed | +| `backgroundLocked` | `string` | `background` | Texture drawn while the button is disabled | -| Prop | Type | Description | -| --- | --- | --- | -| `onPress` | `(event: PressEvent) => unknown \| Promise` | Runs when the player presses the button. `event.player` is who pressed; on a [container screen](../guides/container-screens.md) `event.host` is the entity that owns the screen, and on a form there is none. Every handler in the library takes one event object — see [Handler events](../guides/handler-events.md) | -| `children` | `JSX.Node` | Child components — typically a `Text` (label) or `Image` (icon) | -| `backgroundHover` | `string` | Texture path used while the player hovers over the button | -| `backgroundPressed` | `string` | Texture path used while the button is being pressed | -| `backgroundLocked` | `string` | Texture path used when the button is disabled (`enabled={false}`) | +Inherits [control props](./control-props.md). Every state texture falls back to `background`, and `background` falls back to the blank-canvas placeholder, so one texture styles all four states. -Combine these with `background` (from control props) to fully texture the button across every state. This is the foundation that [`@bedrock-core/ore-styled`'s `Button`](/docs/ore-styled/Button) builds on top of. +This is the primitive [`@bedrock-core/ore-styled`'s `Button`](/docs/ore-styled/Button) is built on. -### Control props +## What a press is -Button inherits all standard [control props](./control-props.md). +`event.player` is who pressed. On a [container screen](../guides/container-screens.md) `event.host` is the entity that owns the screen; on a form there is none. Every handler in the library takes one event object — see [Handler events](../guides/handler-events.md). -## Examples +What the press *costs* depends on the [host](../guides/hosts.md): a form entry the engine reports back by index on an action form, an item taken and put straight back on a container screen. A native modal has no generic button at all — use [``](./Form/FormButton.md) there. -### Basic button +When the destination is another screen rather than a handler, reach for [``](./Link.md): its target is data the build can read, which is what makes the screen describable to other addons. -```tsx - -``` +## Examples -### Button with state +### With state ```tsx -function ToggleButton() { +function ToggleButton(): JSX.Element { const [isActive, setIsActive] = useState(false); return ( @@ -64,7 +60,7 @@ function ToggleButton() { } ``` -### Disabled button +### Disabled ```tsx ``` -### Row of buttons +### A row sharing the width ```tsx - - ``` -### Icon button +### An icon ```tsx - ``` -### Fully themed button +### Fully themed ```tsx @@ -109,7 +105,8 @@ function ToggleButton() { ## Notes -- Don't hardcode `width`/`height` — let buttons size to their content unless you need a specific footprint. -- Inside a row, use `flex={1}` on each button to distribute the space evenly. -- Use descriptive labels that clearly indicate the action. -- Disable buttons when an action is unavailable rather than hiding them. +Let buttons size to their content rather than hardcoding `width` and `height`, unless the layout needs a specific footprint. Inside a row, `flex={1}` on each button distributes the space evenly. + +Disable a button when its action is unavailable rather than hiding it: a hidden control leaves its box behind on a compiled screen unless the row is a [``](./Panel.md#stack). + +An `onPress` that returns a promise keeps the press's transaction open until it settles, which is what makes an async handoff flash-free. See [State](../guides/state.md#one-ui-slot-per-player). diff --git a/docs/ui/components/Container.md b/docs/ui/components/Container.md index bccfc0a..8ec2e2e 100644 --- a/docs/ui/components/Container.md +++ b/docs/ui/components/Container.md @@ -1,5 +1,5 @@ --- -sidebar_position: 10 +sidebar_position: 3 description: "The root of a container screen: names the entity the screen opens from, and is the screen's own panel." --- # Container @@ -27,12 +27,10 @@ export default function Furnace() { } ``` -Its presence decides the backend, the way [``](./Form/Form.md) makes a screen a native modal: a tree rooted in a `Container` is laid out once at build time by the [ui-compile filter](/docs/filters/ui-compile), baked into JSON UI, and served by `createContainerScreen` to every player who opens the entity it names. `render()` rejects it — a container screen is compiled ahead of time, not serialized per player. +Its presence decides the backend, the way [``](./Form/Form.md) makes a screen a native modal: a tree rooted in a `Container` is laid out once at build time by the [ui-compiler filter](/docs/filters/ui-compiler), baked into JSON UI, and served by `createContainerScreen` to every player who opens the entity it names. `render()` rejects it — a container screen is compiled ahead of time, not serialized per player. ## Props -### Component-Specific props - | Prop | Type | Default | Description | | --- | --- | --- | --- | | `entity` | `string` | — | Type of the entity the screen opens from, e.g. `'core:furnace'`. The build sizes that entity's `minecraft:inventory` and stamps it with the screen's layout key; the runtime serves the screen when a player interacts with it. The entity must exist in the behavior pack, or the build fails | @@ -40,9 +38,7 @@ Its presence decides the backend, the way [``](./Form/Form.md) makes a scr | `onClose` | `(event: ContainerEvent) => void` | `undefined` | Ran when a player closes the screen, or leaves the world with it open. `event.player` is who left, `event.host` the entity it belonged to | | `children` | `JSX.Node` | — | The screen. Anything a form can hold except the [form-only components](../guides/container-screens.md#not-supported), plus [`Slot`](./Slot.md), [`PlayerInventory`](./PlayerInventory.md) and [`Hotbar`](./Hotbar.md) | -### Control props - -Container inherits all standard [control props](./control-props.md). It is the screen's root panel, so `background` draws the frame and `padding` / `gap` / `flexDirection` lay the children out — the same way they would on a `Panel`. +Inherits [control props](./control-props.md). It is the screen's root panel, so `background` draws the frame and `padding` / `gap` / `flexDirection` lay the children out — the same way they would on a `Panel`. ## Rules diff --git a/docs/ui/components/Disclosure.md b/docs/ui/components/Disclosure.md new file mode 100644 index 0000000..dd6685b --- /dev/null +++ b/docs/ui/components/Disclosure.md @@ -0,0 +1,53 @@ +--- +sidebar_position: 14 +description: "A header that folds the rows under it entirely on the client, reflowing what is below." +--- +# Disclosure + +A header that folds the rows under it, entirely on the client. + +## Import + +```tsx +import { Disclosure } from '@bedrock-core/ui'; +``` + +## Usage + +```tsx +{'Getting started'}} + headerClosed={{'Getting started…'}} + gap={2} +> + {'Intro'} + {'First steps'} + +``` + +## Props + +| Prop | Type | Default | Description | +| --- | --- | --- | --- | +| `header` | `JSX.Element` | — | What the header draws while the rows show | +| `headerClosed` | `JSX.Element` | `header` | What it draws while they hide | +| `headerHeight` | `number` | `20` | Height of the header box in texels | +| `defaultOpen` | `boolean` | `true` | Whether the rows show when the screen opens | + +Inherits [control props](./control-props.md). The flow props — `flexDirection`, `gap`, `justifyContent`, `alignItems`, `alignContent`, `wrap` — apply to the **rows**, since that is what an author writing `gap` on a disclosure means; everything else sizes and places the fold itself. + +## What folding costs + +The header is a client-side toggle and the rows are a panel that *follows* it, which is vanilla's own idiom for a section that opens and closes. So a fold costs no press, no re-present and no payload. + +The rows sit in a stack, and a stack gives a hidden child no space, so everything below moves up when they fold. That is the one native reflow a frozen screen has — the same one [``](./List.md) is built on. + +## Notes + +Two headers, because a fold is the only thing that can tell them apart. Each is drawn inside its own state, so either may hold anything. + +Rows *follow* the header rather than nesting inside it because content inside a state has no say over its siblings, and rows that have to push what is under them need exactly that. + +## Limits + +Compiled-only. On a serialized screen a fold would be a re-render, which `useState` already does for nothing. diff --git a/docs/ui/components/Embed.md b/docs/ui/components/Embed.md new file mode 100644 index 0000000..4611fca --- /dev/null +++ b/docs/ui/components/Embed.md @@ -0,0 +1,73 @@ +--- +sidebar_position: 20 +description: "A screen one pack draws into another pack's screen, over an area the host reserves." +--- +# Embed + +A screen another pack draws into this one. + +## Import + +```tsx +import { Embed, EmbedSlots, embedMarker } from '@bedrock-core/ui'; +``` + +## Why it exists + +A compiled screen's layout lives in the pack of the addon that built it, and a host realm shows it by title. Some of what a host draws is not the host's to bake: the page for one addon in the addon list — its thumbnail, its description, its authors — belongs to that addon, baked in that addon's pack, and the host has nothing to say about it but where it goes. + +Neither side renders the other. The one contract is the host's frame, the area's place in it, and the slot count. + +## The embedded side + +`` is the root of the embedded component: a panel the size of the area the host leaves for it. That area is its canvas — the tree fills it, and nothing inside knows where the host put it. + +```tsx + + + {description} + +``` + +### Props + +| Prop | Type | Default | Description | +| --- | --- | --- | --- | +| `frame` | `{ width: number; height: number }` | — | The canvas the host bakes its own screen against | +| `area` | `{ x: number; y: number; width: number; height: number }` | — | The area of that frame this component fills | + +Inherits [control props](./control-props.md) except `width` and `height`, which come from `area`. + +## The host side + +`` is the run of entries a host reserves before its own. Slot 0 carries a **marker** naming the embedded screen; the pack holding that screen gates it on the marker instead of on the title, and draws it over the host's canvas. The slots after it are the embedded screen's own entries, which the host writes from the values the screen's owner published and reads back as presses by slot. + +```tsx + console.warn(`embedded entry ${String(index)}`)} +/> +``` + +### Props + +| Prop | Type | Default | Description | +| --- | --- | --- | --- | +| `count` | `number` | — | How many entries are reserved; a constant of the embedding screen | +| `values` | `readonly string[]` | — | What each slot carries this present — the marker first, then the embedded screen's values | +| `onPress` | `(index: number, event: PressEvent) => unknown` | — | A press on slot `index`, never 0 | + +## embedMarker + +```ts +embedMarker(namespace: string): string +``` + +The value slot 0 carries for one addon's screen: `core_addon:`, which is also the namespace that addon's compiled screens are emitted under. + +## Notes + +An embedded screen's own entries are numbered from **1**, because slot 0 is the marker. Both sides walk the tree through the same helper, so the numbering cannot drift. + +`count` is a constant of the embedding screen: the embedded one is baked against it, so changing it means rebuilding both packs. diff --git a/docs/ui/components/Expect.md b/docs/ui/components/Expect.md new file mode 100644 index 0000000..805af0b --- /dev/null +++ b/docs/ui/components/Expect.md @@ -0,0 +1,42 @@ +--- +sidebar_position: 19 +description: "States which screen a fragment is written for, and fails the build by name when it is drawn on another." +--- +# Expect + +States which screen a fragment is written for, and fails the build by name when it is drawn on another. + +## Import + +```tsx +import { Expect } from '@bedrock-core/ui'; +``` + +## Usage + +```tsx +export const AccountFields = (): JSX.Element => ( + + + + +); +``` + +## Props + +| Prop | Type | Default | Description | +| --- | --- | --- | --- | +| `host` | `'form-action' \| 'form-modal' \| 'chest'` | — | The screen this fragment is written for | + +Draws nothing and takes no layout space: its children are laid out as though it were not there. + +## When to reach for it + +A root names the host, so anything under a ``, `` or `` already knows what it becomes. This is for the other case: a component library that renders **into** a screen it does not own — a set of fields meant for a modal, exported as a fragment for an addon to place. + +Written at the top of that fragment, it says what the library assumed. An addon that drops it on the wrong screen is told where, once, instead of being told about each field in turn. + +## Notes + +The host ids are the same three [Hosts](../guides/hosts.md) names a root resolves to. diff --git a/docs/ui/components/Form/Form.md b/docs/ui/components/Form/Form.md index 12048f8..2e6751b 100644 --- a/docs/ui/components/Form/Form.md +++ b/docs/ui/components/Form/Form.md @@ -6,7 +6,7 @@ description: "Atomic modal form." Atomic modal form. Renders one native `ModalFormData` — every field is shown at once, and nothing comes back until the player presses submit, at which point every value arrives together, keyed by each field's `name`, in `onSubmit`. -This replaces the older one-modal-per-field pattern ([`Input`](../deprecated/Input.md), [`Dropdown`](../deprecated/Dropdown.md), [`Slider`](../deprecated/Slider.md)), which opens a separate single-control modal per field. Those components are now deprecated — for new screens with more than one field, use `Form`. +The [deprecated](../deprecated/Input.md) `Input`, `Dropdown` and `Slider` components open a separate single-control modal per field. Use `Form` for any screen with more than one field. ## Import @@ -47,11 +47,11 @@ Values only arrive once, in `onSubmit`, keyed by each field's `name`: ## Props -| Prop | Type | Description | -| --- | --- | --- | -| `onSubmit` | `(event: SubmitEvent) => void` | Called once when the player presses the submit button. `event.values` holds every field's value keyed by its `name` (`FormValues = Record`, where `ModalValue = string \| number \| boolean \| undefined`), and `event.player` is who submitted. Destructure it: `onSubmit={({ values }) => …}` | -| `onCancel` | `(event: UiEvent) => void` | Called when the player dismisses the modal — the X button, Esc, or a `Form.Button type="exit"`. `event.player` is who dismissed it | -| `children` | `JSX.Node` | Field declarations, decorative content, and the form's action buttons, in any order | +| Prop | Type | Default | Description | +| --- | --- | --- | --- | +| `onSubmit` | `(event: SubmitEvent) => void` | — | Called once when the player presses the submit button. `event.values` holds every field's value keyed by its `name` (`FormValues = Record`, where `ModalValue = string \| number \| boolean \| undefined`), and `event.player` is who submitted. Destructure it: `onSubmit={({ values }) => …}` | +| `onCancel` | `(event: UiEvent) => void` | — | Called when the player dismisses the modal — the X button, Esc, or a `Form.Button type="exit"`. `event.player` is who dismissed it | +| `children` | `JSX.Node` | — | Field declarations, decorative content, and the form's action buttons, in any order | ## Rules diff --git a/docs/ui/components/Form/FormButton.md b/docs/ui/components/Form/FormButton.md index 54ff852..cd7ded1 100644 --- a/docs/ui/components/Form/FormButton.md +++ b/docs/ui/components/Form/FormButton.md @@ -29,16 +29,12 @@ A `Form` enforces the cardinality of these buttons at build time (see [`Form`'s ## Props -### Component-Specific props - | Prop | Type | Default | Description | | --- | --- | --- | --- | | `type` | `'submit' \| 'exit'` | — | `'submit'` presses the native submit — field values return via the form's `onSubmit`. `'exit'` closes the form like Esc — no values, the form's `onCancel` fires instead | | `label` | `string` | `'Submit'` for `type="submit"`, `'Close'` for `type="exit"` | Button text | -### Control props - -`Form.Button` inherits all standard [control props](../control-props.md), plus `background`/`backgroundHover`/`backgroundPressed`/`backgroundLocked` for per-state texturing — the same shape as [`Button`](../Button.md). Defaults to `width: '100%'` when no explicit sizing is given. +Inherits [control props](../control-props.md), plus `background`/`backgroundHover`/`backgroundPressed`/`backgroundLocked` for per-state texturing — the same shape as [`Button`](../Button.md). Defaults to `width: '100%'` when no explicit sizing is given. ## Examples diff --git a/docs/ui/components/Form/FormDropdown.md b/docs/ui/components/Form/FormDropdown.md index 42c84fa..2e97b65 100644 --- a/docs/ui/components/Form/FormDropdown.md +++ b/docs/ui/components/Form/FormDropdown.md @@ -15,7 +15,7 @@ import { Form } from '@bedrock-core/ui'; ## Usage ```tsx - console.log(v.mode)}> + console.warn(v.mode)}> @@ -31,8 +31,6 @@ import { Form } from '@bedrock-core/ui'; ## Props -### Component-Specific props - | Prop | Type | Default | Description | | --- | --- | --- | --- | | `name` | `string` | — | Result key — the selected index appears at `values[name]` in the form's `onSubmit` | @@ -40,16 +38,14 @@ import { Form } from '@bedrock-core/ui'; | `children` | `JSX.Node` | — | The selectable options, authored as [`Form.Option`](./FormOption.md) elements. Popup rows flow at a fixed row height, so an option's own layout props are ignored here — only its `value`/`label`/style are read | | `popupBackground` | `string` | the unstyled placeholder texture | Background texture for the popup surface behind the option list | | `optionBackground` / `optionHover` / `optionSelected` | `string` | — | Group-level default row textures for idle/hover/selected states. Any `Form.Option` can override its own | -| `optionFont` | `LabelFont` / `number` / `'left' \| 'center' \| 'right'` | `'mojangles'` / `1.0` / `'left'` | Group-level default label styling for option rows. Any `Form.Option` can override its own | +| `optionFont` / `optionScale` / `optionAlign` | `LabelFont` / `number` / `'left' \| 'center' \| 'right'` | `'mojangles'` / `1.0` / `'left'` | Group-level default label styling for option rows. Any `Form.Option` can override its own | | `currentColor` | `string` | `''` | Color code prefix (e.g. `'§0'`) applied to the closed-box current-value text | | `currentFont` / `currentScale` | `LabelFont` / `number` | `'mojangles'` / `1.0` | Font and scale for the closed-box current-value label | | `currentInsetX` / `currentInsetY` | `number` | `8` / vertically centered | Position offset (px) of the current-value label from the closed box's left-middle frame | The closed box uses `background`/`backgroundHover`/`backgroundPressed`/`backgroundLocked` for per-state texturing — the same shape as [`Button`](../Button.md). -### Control props - -`Form.Dropdown` inherits all standard [control props](../control-props.md). +Inherits [control props](../control-props.md). ## Examples @@ -82,7 +78,7 @@ const options = ['Easy', 'Normal', 'Hard']; { const selected = options[v.mode as number]; - console.log(selected); + console.warn(selected); }}> {options.map(o => )} diff --git a/docs/ui/components/Form/FormInlineSelect.md b/docs/ui/components/Form/FormInlineSelect.md index 518c45a..178c6f9 100644 --- a/docs/ui/components/Form/FormInlineSelect.md +++ b/docs/ui/components/Form/FormInlineSelect.md @@ -15,7 +15,7 @@ import { Form } from '@bedrock-core/ui'; ## Usage ```tsx - console.log(v.team)}> + console.warn(v.team)}> @@ -30,8 +30,6 @@ Just like [`Form.Dropdown`](./FormDropdown.md), `Form.InlineSelect` reports the ## Props -### Component-Specific props - | Prop | Type | Default | Description | | --- | --- | --- | --- | | `name` | `string` | — | Result key — the selected index appears at `values[name]` in the form's `onSubmit` | @@ -41,11 +39,9 @@ Just like [`Form.Dropdown`](./FormDropdown.md), `Form.InlineSelect` reports the | `bullet` / `bulletSelected` | `string` | — | Unselected/selected bullet glyph texture (e.g. a radio dot). Leave both empty for a segmented, bullet-less look | | `bulletHover` / `bulletSelectedHover` | `string` | falls back to `bullet` / `bulletSelected` | Bullet glyph shown on hover | | `bulletWidth` / `bulletHeight` | `number` | `12` | Bullet glyph size (px) | -| `optionFont` | `LabelFont` / `number` / `'left' \| 'center' \| 'right'` | — | Group-level default label styling for option rows. Any `Form.Option` can override its own | - -### Control props +| `optionFont` / `optionScale` / `optionAlign` | `LabelFont` / `number` / `'left' \| 'center' \| 'right'` | — | Group-level default label styling for option rows. Any `Form.Option` can override its own | -`Form.InlineSelect` inherits all standard [control props](../control-props.md). +Inherits [control props](../control-props.md). ## Examples diff --git a/docs/ui/components/Form/FormInput.md b/docs/ui/components/Form/FormInput.md index 91e2fd9..2abfc71 100644 --- a/docs/ui/components/Form/FormInput.md +++ b/docs/ui/components/Form/FormInput.md @@ -15,7 +15,7 @@ import { Form } from '@bedrock-core/ui'; ## Usage ```tsx - console.log(v.nickname)}> + console.warn(v.nickname)}> @@ -27,8 +27,6 @@ import { Form } from '@bedrock-core/ui'; ## Props -### Component-Specific props - | Prop | Type | Default | Description | | --- | --- | --- | --- | | `name` | `string` | — | Result key — the value appears at `values[name]` in the form's `onSubmit` | @@ -41,9 +39,7 @@ import { Form } from '@bedrock-core/ui'; The box uses `background`/`backgroundHover`/`backgroundPressed`/`backgroundLocked` for per-state texturing — the same shape as [`Button`](../Button.md); `backgroundPressed` doubles as the focused-field state. -### Control props - -`Form.Input` inherits all standard [control props](../control-props.md). +Inherits [control props](../control-props.md). ## Examples diff --git a/docs/ui/components/Form/FormOption.md b/docs/ui/components/Form/FormOption.md index 52903d1..6ff2c5f 100644 --- a/docs/ui/components/Form/FormOption.md +++ b/docs/ui/components/Form/FormOption.md @@ -28,8 +28,6 @@ import { Form } from '@bedrock-core/ui'; ## Props -### Component-Specific props - | Prop | Type | Default | Description | | --- | --- | --- | --- | | `value` | `string` | — | The option's stable identifier — what a parent's `defaultValue` is matched against. The parent reports the SELECTED option's index on submit, not this value | @@ -39,9 +37,7 @@ import { Form } from '@bedrock-core/ui'; | `bullet` / `bulletSelected` / `bulletHover` / `bulletSelectedHover` | `string` | falls back to the parent's matching group prop | Per-option bullet glyph override (only meaningful under `Form.InlineSelect`) | | `bulletWidth` / `bulletHeight` | `number` | falls back to the parent's `bulletWidth` / `bulletHeight` | Per-option bullet size override | -### Control props - -Under `Form.InlineSelect`, `Form.Option` inherits all standard [control props](../control-props.md) for real flex layout. Under `Form.Dropdown`, layout props are accepted but ignored — popup rows flow at a fixed height. +Inherits [control props](../control-props.md), which lay out real flex rows under `Form.InlineSelect`. Under `Form.Dropdown`, layout props are accepted but ignored — popup rows flow at a fixed height. ## Examples diff --git a/docs/ui/components/Form/FormSlider.md b/docs/ui/components/Form/FormSlider.md index 3191d83..5b6f641 100644 --- a/docs/ui/components/Form/FormSlider.md +++ b/docs/ui/components/Form/FormSlider.md @@ -15,7 +15,7 @@ import { Form } from '@bedrock-core/ui'; ## Usage ```tsx -
    console.log(v.volume)}> + console.warn(v.volume)}> @@ -27,8 +27,6 @@ import { Form } from '@bedrock-core/ui'; ## Props -### Component-Specific props - | Prop | Type | Default | Description | | --- | --- | --- | --- | | `min` | `number` | — | Minimum selectable value | @@ -44,9 +42,7 @@ import { Form } from '@bedrock-core/ui'; The track uses `background`/`backgroundHover`/`backgroundPressed`/`backgroundLocked` for per-state texturing — the same shape as [`Button`](../Button.md). -### Control props - -`Form.Slider` inherits all standard [control props](../control-props.md). Defaults to `width: '100%'` when no explicit sizing is given. +Inherits [control props](../control-props.md). Defaults to `width: '100%'` when no explicit sizing is given. ## Examples diff --git a/docs/ui/components/Form/FormToggle.md b/docs/ui/components/Form/FormToggle.md index 520651e..6e1a6e5 100644 --- a/docs/ui/components/Form/FormToggle.md +++ b/docs/ui/components/Form/FormToggle.md @@ -15,7 +15,7 @@ import { Form } from '@bedrock-core/ui'; ## Usage ```tsx -
    console.log(v.sound)}> + console.warn(v.sound)}> @@ -27,8 +27,6 @@ import { Form } from '@bedrock-core/ui'; ## Props -### Component-Specific props - | Prop | Type | Default | Description | | --- | --- | --- | --- | | `name` | `string` | — | Result key — the value appears at `values[name]` in the form's `onSubmit` | @@ -39,9 +37,7 @@ import { Form } from '@bedrock-core/ui'; The unchecked (off) side uses `background`/`backgroundHover`/`backgroundPressed`/`backgroundLocked` for per-state texturing — the same shape as [`Button`](../Button.md) (the toggle RP has no pressed state to show `backgroundPressed`, but the prop is still accepted). -### Control props - -`Form.Toggle` inherits all standard [control props](../control-props.md) for layout and visibility — geometry is computed by the layout phase like any other component. +Inherits [control props](../control-props.md) for layout and visibility — geometry is computed by the layout phase like any other component. ## Examples diff --git a/docs/ui/components/Form/_category_.json b/docs/ui/components/Form/_category_.json index d006049..c75fae0 100644 --- a/docs/ui/components/Form/_category_.json +++ b/docs/ui/components/Form/_category_.json @@ -1,5 +1,5 @@ { - "position": 9, + "position": 22, "label": "Form", "collapsible": true, "collapsed": true, diff --git a/docs/ui/components/Fragment.md b/docs/ui/components/Fragment.md index a6c6f7c..0847e49 100644 --- a/docs/ui/components/Fragment.md +++ b/docs/ui/components/Fragment.md @@ -1,5 +1,5 @@ --- -sidebar_position: 8 +sidebar_position: 10 description: "A logical grouping component that doesn't render any visual container." --- # Fragment @@ -33,11 +33,11 @@ import { Fragment } from '@bedrock-core/ui'; ``` -### Component-Specific props +## Props -| Prop | Type | Description | -| --- | --- | --- | -| `children` | `JSX.Node` | The children components inside the fragment | +| Prop | Type | Default | Description | +| --- | --- | --- | --- | +| `children` | `JSX.Node` | — | What the fragment groups | ## Examples @@ -71,7 +71,7 @@ function StatusDisplay({ isOnline }: { isOnline: boolean }) { - Don't use Fragment when you need a visual container or its own flex layout (use `Panel` instead). - Fragment participates in the parent's flex flow — its children are lifted into the parent's layout. -## Fragment vs Panel +## Fragment vs panel | Aspect | Fragment | Panel | |--------|----------|-------| diff --git a/docs/ui/components/Hotbar.md b/docs/ui/components/Hotbar.md index ede7f69..97b63dc 100644 --- a/docs/ui/components/Hotbar.md +++ b/docs/ui/components/Hotbar.md @@ -1,5 +1,5 @@ --- -sidebar_position: 14 +sidebar_position: 18 description: "The player's hotbar — the 9 × 1 grid — inside a container screen." --- # Hotbar @@ -27,9 +27,7 @@ The same redrawn grid as [`PlayerInventory`](./PlayerInventory.md), one row tall ## Props -### Control props - -Hotbar inherits all standard [control props](./control-props.md). Its size is fixed by the engine's cell; use `alignSelf`, margins and the surrounding panel to place it. +Inherits [control props](./control-props.md). Its size is fixed by the engine's cell; use `alignSelf`, margins and the surrounding panel to place it. ## Notes diff --git a/docs/ui/components/Image.md b/docs/ui/components/Image.md index 8caddda..749e31b 100644 --- a/docs/ui/components/Image.md +++ b/docs/ui/components/Image.md @@ -1,10 +1,10 @@ --- -sidebar_position: 6 -description: "Display images and textures in your UI." +sidebar_position: 8 +description: "A texture from a resource pack, baked into the screen or carried at runtime." --- # Image -Display images and textures in your UI. +A texture from a resource pack. ## Import @@ -18,77 +18,32 @@ import { Image } from '@bedrock-core/ui'; ``` -Unlike `Text` and `Button`, `Image` is **not** intrinsically sized — you must provide `width` and `height` (or flex props) to give it a footprint. +Unlike `Text` and `Button`, `Image` is **not** intrinsically sized — give it `width` and `height`, or flex props, or it has no footprint. ## Props -### Component-Specific props - | Prop | Type | Default | Description | | --- | --- | --- | --- | -| `texture` | `string` | `'textures/ui/unstyled'` — the blank-canvas placeholder | Path to the texture in your Resource Pack (without file extension). Optional, but an `Image` without one just draws the placeholder. Any length — since protocol v0008 the texture rides the payload's variable-length tail, so paths are never padded, truncated or capped | - -### Control props +| `texture` | `string` | `'textures/ui/unstyled'` | Path to the texture in the resource pack, without the file extension | +| `live` | `boolean` | `false` | Carry the texture path at runtime rather than baking it | -Image inherits all standard [control props](./control-props.md). +Inherits [control props](./control-props.md). The default is the blank-canvas placeholder, so an `Image` with no `texture` draws a plain box. -## Examples +## live -### Basic image +A compiled image is **baked**: the path is written into the pack, and a later render showing another texture is silently wrong. `live` is how an image whose texture changes says so. ```tsx - -``` - -### Image gallery - -```tsx -function ImageGallery() { - const images = [ - 'textures/items/diamond', - 'textures/items/gold_ingot', - 'textures/items/iron_ingot', - 'textures/items/emerald', - ]; - - return ( - - {images.map((texture, index) => ( - - ))} - - ); -} -``` - -### Clickable image button - -```tsx -function ImageButton() { - return ( - - ); -} + ``` -## Texture path format +It costs one entry on a form. Leave it off for a texture that never changes, which is every decorative image. -Texture paths should: -- Be relative to your Resource Pack root. -- Omit file extensions (`.png`, `.jpg`). -- Use forward slashes (`/`) as path separators. -- Match exactly the path structure in your Resource Pack. +## Texture paths -Example Resource Pack structure: +A path is relative to the resource pack root, omits the file extension, and uses forward slashes. -``` +```txt packs/RP/ └── textures/ └── ui/ @@ -99,20 +54,43 @@ packs/RP/ └── panel_bg.png ``` -Usage: - ```tsx ``` +Paths are any length: the texture rides the payload's variable-length tail, so it is never padded, truncated or capped. + +## Examples + +### A row of icons + +```tsx +function Icons(): JSX.Element { + const items = ['diamond', 'gold_ingot', 'iron_ingot', 'emerald']; + + return ( + + {items.map(item => ( + + ))} + + ); +} +``` + +### An icon that presses + +```tsx + +``` + ## Notes -- Prefer nine-sliced textures for scaling backgrounds. -- Keep texture file sizes small to reduce pack size. -- Organize textures in logical folders within `textures/ui/`. -- Match texture dimensions to your UI footprint for crisp rendering. +Prefer nine-sliced textures for backgrounds that scale, keep file sizes small, and match texture dimensions to the UI footprint for crisp rendering. ## Limits -- Animated textures (flipbook) not yet supported. +Animated (flipbook) textures are not supported. diff --git a/docs/ui/components/Link.md b/docs/ui/components/Link.md new file mode 100644 index 0000000..3b22140 --- /dev/null +++ b/docs/ui/components/Link.md @@ -0,0 +1,68 @@ +--- +sidebar_position: 7 +description: "A button whose destination is data, so the build can read where it leads." +--- +# Link + +A button that goes somewhere. + +## Import + +```tsx +import { Link } from '@bedrock-core/ui'; +``` + +## Usage + +```tsx + + {'Catalog'} + +``` + +## Props + +| Prop | Type | Default | Description | +| --- | --- | --- | --- | +| `to` | `ScreenKey` | — | The screen to open, `:` as the build wrote it | +| `back` | `boolean` | `false` | Go back to the screen the player came from, whatever it was; set instead of `to` | +| `params` | `Record` | — | Props the target screen is rendered with; they fill what the layout already reserved | +| `replace` | `boolean` | `false` | Take the place of this screen rather than stacking over it | + +Inherits every prop of [` @@ -29,32 +29,46 @@ export default function Players() { } ``` -A screen's root names its host, and there is no default. `` makes it an action form the way [`
    `](./Form/Form.md) makes it a native modal and [``](./Container.md) a compiled container screen. It has no box of its own: its children are laid out against the form canvas exactly as they would be at the top of the tree. +A screen's root names its [host](../guides/hosts.md), and there is no default. `` makes it an action form the way [``](./Form/Form.md) makes it a native modal and [``](./Container.md) a container screen. It has no box of its own: its children are laid out against the form canvas exactly as they would be at the top of the tree. ## Props | Prop | Type | Default | Description | | --- | --- | --- | --- | +| `static` | `boolean` | `false` | Declare that the screen carries no live value and no press of its own | | `children` | `JSX.Node` | — | The screen's content | `Screen` takes no [control props](./control-props.md): it is a marker, not a panel. Put a `Panel` inside it for a background, padding or a direction. +## static + +A screen is static when every string it shows is baked and every press is a [``](./Link.md) or the way out. Such a screen needs nothing at runtime — the build already knows its title, the value each entry is shown with, and where each press leads — so the addon ships that table instead of the component, and any realm can show it. See [static screens](../guides/navigation.md#static-screens). + +Setting `static` both asks for that and **proves** it. A qualifying screen is detected either way; declaring it fails the build the moment the screen starts carrying live text, a carried `visible`, or a handler the build cannot read. + +```tsx + + {'Intro'} + {'Back'} + +``` + ## Rules -The build and `render()` enforce these, with a message naming the fix: +The build and `render()` enforce these, with a message naming the fix. - **One root, at the top.** Providers and fragments above it are looked through. A tree that starts with anything else — a `Panel`, a `Card`, two elements side by side — is refused with the list of roots. - **No root below the root.** A `` or a `` inside a `` is refused: compose the inner part as a component, or give it a screen of its own. -- **A component library never renders one.** The root is the one element an author writes at the top of a `*.screen.tsx`; a component that is used inside screens returns what goes under the root. +- **A component library never renders one.** The root is the one element an author writes at the top of a `*.screen.tsx`; a component used inside screens returns what goes under the root. ## Examples ### An embedded page -A page drawn into an area another screen leaves is still a screen of its own, so it starts with ``; the `Embed` inside it is what fills the area. +A page drawn into an area another screen leaves is still a screen of its own, so it starts with ``; the [``](./Embed.md) inside it is what fills the area. ```tsx -export default function FrameworkPage() { +export default function FrameworkPage(): JSX.Element { return ( @@ -62,3 +76,7 @@ export default function FrameworkPage() { ); } ``` + +## Notes + +A screen file is a `*.screen.tsx` under `BP/scripts` with a default export. That is what the [`ui-compiler` filter](/docs/filters/ui-compiler) compiles, and the filename without the suffix is the screen's [key](../guides/navigation.md#screen-keys). diff --git a/docs/ui/components/Scroll.md b/docs/ui/components/Scroll.md index 66addd9..af6e17a 100644 --- a/docs/ui/components/Scroll.md +++ b/docs/ui/components/Scroll.md @@ -1,6 +1,6 @@ --- -sidebar_position: 9 -description: " declares an independent scroll region." +sidebar_position: 11 +description: "One independent vertical scroll region, laid out in the parent flow like a panel." --- # Scroll @@ -20,29 +20,27 @@ scroll, so simple UIs need none. ## Props -| Prop | Type | Description | -| --- | --- | --- | -| `children` | `JSX.Node` | The content laid out inside this scroll's viewport | +| Prop | Type | Default | Description | +| --- | --- | --- | --- | +| `children` | `JSX.Node` | — | The content laid out inside this scroll's viewport | -### Control props - -`` inherits all standard [control props](./control-props.md) and they size and +Inherits [control props](./control-props.md) and they size and position its **viewport** in the parent's flex flow, exactly like a ``. An un-sized, non-absolute scroll defaults to `flexGrow: 1` so bare ``s share the parent's space; -`width`/`height` override that, and `position="absolute"` + `top`/`left` take it out of the flow. +`width`/`height` override that, and `position={'absolute'}` + `top`/`left` take it out of the flow. `visible`, `enabled`, and `background` are accepted (they come with `ControlProps`) but are **not** applied to the scroll viewport. ```tsx // Two side-by-side scroll columns — arrangement comes from the parent Panel. - - {left} + + {left} {right} // A fixed header above a scrolling body (stacked column). - + {header} {body} @@ -59,9 +57,5 @@ non-absolute scroll defaults to `flexGrow: 1` so bare ``s share the pare whole tree lives in the root scroll, which grows and scrolls when content overflows. As soon as you add a ``, the screen itself becomes a fixed-size canvas: content outside a scroll must fit within it, and only the content *inside* each `` scrolls. Size the - outer layout to the screen (e.g. `height="100%"`) and let each `` absorb overflow. -- Scrolls are vertical. Horizontal scrolling isn't exposed yet. - -## See also - -- [`render`](../api/render.md) — display a component tree to a player + outer layout to the screen (e.g. `height={'100%'}`) and let each `` absorb overflow. +- Scrolls are vertical. Horizontal scrolling is not exposed. diff --git a/docs/ui/components/Slot.md b/docs/ui/components/Slot.md index c4eb957..ff95831 100644 --- a/docs/ui/components/Slot.md +++ b/docs/ui/components/Slot.md @@ -1,5 +1,5 @@ --- -sidebar_position: 11 +sidebar_position: 15 description: "A real container cell inside a container screen: the player moves items through it, and the screen sees what arrives." --- # Slot @@ -27,27 +27,29 @@ Handlers are props, like everywhere else in this library. They are matched to th ## Props -### Component-Specific props - | Prop | Type | Default | Description | | --- | --- | --- | --- | -| `role` | `'both' \| 'input' \| 'output'` | `'both'` | What an interactive slot lets the player do | - - `both` — ordinary storage. Anything in, anything out. - - `input` — items go in and do not come back out. A furnace's fuel slot. - - `output` — items may be taken and nothing put in. A furnace's result. - - A role is enforced **server-side, by the runtime**, never by the engine: a container gives no way to veto a move, so a forbidden one is undone a tick later rather than prevented. An **output** slot with no result holds the runtime's marker item, so it is never empty — a shift-click can only auto-place into an empty (or matching) slot, so bulk-dumping into an output slot is blocked outright, with no flicker. Its compiled cell swaps to an empty fake while the marker sits there, so the marker is never rendered, hovered or takeable; a real result swaps the interactive cell back in. - - A role is ignored on a foreign or locked slot. (Q **drops nothing** from any container slot — dropping happens outside a container — so an input slot needs no special handling for the one take the undo could not reach.) - -| Prop | Type | Default | Description | -| --- | --- | --- | --- | -| `interactive` | `boolean` | `true` | Whether the player can move items through the slot at all. `false` draws an inert cell — the item shows, but no take, place or drop reaches it, and `role` does not apply. Use it for a slot the player must never touch; use `role` for one that moves in a single direction | +| `role` | `'both' \| 'input' \| 'output'` | `'both'` | What an interactive slot lets the player do; see [Roles](#roles) | +| `interactive` | `boolean` | `true` | Whether the player can move items through the slot at all. `false` draws an inert cell — the item shows, but no take, place or drop reaches it, and `role` does not apply | | `onInsert` | `(event: SlotEvent) => void` | — | Runs after an item arrives. `event.stack` is what landed, `event.player` who put it there, `event.host` the entity that owns the screen | | `onRemove` | `(event: SlotEvent) => void` | — | Runs after the slot empties. `event.stack` is what left, `event.player` who took it, `event.host` the entity that owns the screen | -| `collection` | `string` | — | A JSON UI collection to read instead of the screen's own — `inventory_items`, `hotbar_items`, or any collection the engine exposes. Given one, the slot is **foreign**: it draws `collection[index]`, takes no slot of the screen's own container, and the runtime never polls it. See [Own versus foreign](#own-versus-foreign) below | +| `collection` | `string` | — | A JSON UI collection to read instead of the screen's own — `inventory_items`, `hotbar_items`, or any collection the engine exposes. Given one, the slot is **foreign**: it draws `collection[index]`, takes no slot of the screen's own container, and the runtime never polls it | | `index` | `number` | — | The cell within `collection` to draw. Required, and only legal, alongside `collection`; an integer `>= 0` | +Inherits [control props](./control-props.md). Leave `width` and `height` alone — the cell is 18 × 18 whatever the layout asks for — and use margins and `alignSelf` to place it. + +### Roles + +- `both` — ordinary storage. Anything in, anything out. +- `input` — items go in and do not come back out. A furnace's fuel slot. +- `output` — items may be taken and nothing put in. A furnace's result. + +A role is enforced **server-side, by the runtime**, never by the engine: a container gives no way to veto a move, so a forbidden one is undone a tick later rather than prevented. + +An `output` slot with no result holds the runtime's marker item, so it is never empty — a shift-click can only auto-place into an empty or matching slot, so bulk-dumping into an output slot is blocked outright, with no flicker. Its compiled cell swaps to an empty fake while the marker sits there, so the marker is never rendered, hovered or takeable; a real result swaps the interactive cell back in. + +A role is ignored on a foreign or locked slot. Q drops nothing from any container slot — dropping happens outside a container — so an input slot needs no special handling for the one take the undo could not reach. + ### Own versus foreign An **own** slot (no `collection`) is a cell of the screen's own container: it is allocated a container index, the runtime polls it, and `role` enforces `input` / `output` a tick later by undoing a forbidden move. A **foreign** slot (`collection` + `index`) reads some other collection at an author-given index; it is never allocated and never polled, so `role` has no meaning there and combining the two throws. @@ -56,10 +58,6 @@ An **own** slot (no `collection`) is a cell of the screen's own container: it is For a whole collection at once — the player's inventory, a sub-range, another container — use [`SlotGrid`](./SlotGrid.md). -### Control props - -Slot inherits all standard [control props](./control-props.md). Leave `width` and `height` alone — the cell is 18 × 18 whatever the layout asks for — and use margins and `alignSelf` to place it. - ## Examples ### A furnace diff --git a/docs/ui/components/SlotGrid.md b/docs/ui/components/SlotGrid.md index b5bcef1..55612ce 100644 --- a/docs/ui/components/SlotGrid.md +++ b/docs/ui/components/SlotGrid.md @@ -1,5 +1,5 @@ --- -sidebar_position: 12 +sidebar_position: 16 description: "A grid of cells over a JSON UI collection the screen does not own, inside a container screen: the player's own inventory, another container's items, or any…" --- # SlotGrid @@ -25,24 +25,17 @@ Its size is fixed by the cell: `columns × rows` cells of 18 texels each. Lay it ## Props -### Component-Specific props - | Prop | Type | Default | Description | | --- | --- | --- | --- | | `collection` | `string` | — | The JSON UI collection every cell reads, e.g. `inventory_items`, `hotbar_items`, or a custom one | | `columns` | `number` | — | Columns of cells. At least one | | `rows` | `number` | — | Rows of cells. At least one | | `interactive` | `boolean` | `true` | Whether the player can move items through the cells. `false` makes the grid inert — no take, no place, no drop | - - A container slot's take and place are one combined engine action, so there is no take-only or place-only grid; interactivity is all-or-nothing, and `false` is the way to make a grid purely a display. - -| Prop | Type | Default | Description | -| --- | --- | --- | --- | | `hideOwned` | `boolean` | `false` | Draw the cell that hides the runtime's transport item. Only relevant for the player's own inventory and hotbar, where a button's transport is auto-placed for the tick it takes the runtime to reclaim it — otherwise it would flash there | -### Control props +Inherits [control props](./control-props.md). Its size is fixed by the cell; use `alignSelf`, margins and the surrounding panel to place it. -SlotGrid inherits all standard [control props](./control-props.md). Its size is fixed by the cell; use `alignSelf`, margins and the surrounding panel to place it. +A container slot's take and place are one combined engine action, so there is no take-only or place-only grid: interactivity is all-or-nothing, and `false` is the way to make a grid purely a display. ## PlayerInventory and Hotbar diff --git a/docs/ui/components/Tabs.md b/docs/ui/components/Tabs.md new file mode 100644 index 0000000..09a7438 --- /dev/null +++ b/docs/ui/components/Tabs.md @@ -0,0 +1,65 @@ +--- +sidebar_position: 13 +description: "Several panes on one screen, switched on the client with nothing reaching script." +--- +# Tabs + +Several panes on one screen, switched without the server hearing about it. + +## Import + +```tsx +import { Tabs } from '@bedrock-core/ui'; +``` + +## Usage + +```tsx + + {'Items'}} headerSelected={{'Items'}}> + + + {'Log'}}> + + + +``` + +## Props + +### Tabs + +| Prop | Type | Default | Description | +| --- | --- | --- | --- | +| `tabHeight` | `number` | `20` | Height of the header row in texels; the panes take what is left | + +### Tabs.Tab + +| Prop | Type | Default | Description | +| --- | --- | --- | --- | +| `header` | `JSX.Element` | — | The header while this tab is not the chosen one | +| `headerSelected` | `JSX.Element` | `header` | The header while it is | + +Both inherit [control props](./control-props.md). + +## What it costs + +A tab change costs no press, no re-present and no payload: each header is a client-side toggle and its pane is drawn **inside** the chosen state. Nothing outside the toggle observes which tab is open, so nothing has to be told when it changes. + +What you pay instead is pack size. Every tab's content is in the tree at once, so N tabs draw N times the controls — paid once at build and nothing at runtime, which is what makes tabs essentially free however many there are. + +## When it is a screen instead + +What you give up is exactly what "the server never hears it" means: no handler runs on a switch, and nothing outside the group can know which tab is open. A tab whose content depends on the switch is a screen change, not a tab — use [``](./Link.md) or `navigate()`. + +## Notes + +A pane that is not showing is never built, which is what keeps a native field inside a tab off a collection row that is not there. + +The panes are laid out beside the headers, filling the box below them; the compile re-bases each into its header's toggle. + +A `` written outside a `` is refused by its type. + +## Limits + +Compiled-only. On a serialized screen every switch would be N times the payload on every present, so the build says so rather than drawing it. diff --git a/docs/ui/components/Text.md b/docs/ui/components/Text.md index ed729d5..310f849 100644 --- a/docs/ui/components/Text.md +++ b/docs/ui/components/Text.md @@ -1,5 +1,5 @@ --- -sidebar_position: 4 +sidebar_position: 5 description: "Display text content in your UI." --- # Text @@ -22,8 +22,6 @@ import { Text } from '@bedrock-core/ui'; ## Props -### Component-Specific props - | Prop | Type | Default | Description | | --- | --- | --- | --- | | `children` | [`DisplayText`](/docs/i18n#displaytext) (`string \| RawMessage`) | — | The text to display. A single child only — arrays throw. Strings are auto-detected as keys or literals; `RawMessage` values are always localized. See [One text channel](#one-text-channel) | @@ -34,13 +32,12 @@ import { Text } from '@bedrock-core/ui'; | `maxLines` | `number` | — | Limit rendered text to N lines. The last line is always ellipsized when content overflows | | `maxLength` | `number` | — | The most characters the text will ever need. In a [container screen](../guides/container-screens.md) this is what makes the text **live**: a compiled layout cannot grow, so a string that changes at runtime reserves its cells before the build knows what it will say — one container slot per character, decoded through a 64-glyph table (space, `A–Z`, `a–z`, `0–9`, `.`; anything else, formatting codes included, draws as a blank). Leave it off for text that never changes, which is baked and may use any character at all. In a server form the text is live anyway; a literal string is cut to this length so the two backends agree on what fits, while keys and `RawMessage`s the client resolves are left whole | | `shadow` | `boolean` | `false` | Draw a drop shadow behind the glyphs. Purely visual — it does not affect layout or text metrics | -| `color` | `[number, number, number]` | — | Glyph colour as RGB in `0..1`. For text a `§` code cannot colour: a localization key, whose value the client resolves. Compiled screens only | +| `color` | `[number, number, number]` | — | Glyph color as RGB in `0..1`. For text a `§` code cannot color: a localization key, whose value the client resolves. Compiled screens only | | `textAlign` | `'left' \| 'center' \| 'right'` | `'left'` | Where the glyphs sit in the label's box. Only shows when the box is wider than the text: give the text a `width`, or let it grow. Compiled screens only | | `offsetX` / `offsetY` | `number` | `0` | Fine-tune the pixel nudge of the rendered label inside its layout box. The box itself does not move | +| `hug` | `boolean` | `false` | Draw the label at the width of its glyphs rather than in the box the layout solved, and let the engine place what follows. Only inside a [``](./Panel.md#stack) | -### Control props - -Text inherits all standard [control props](./control-props.md). +Inherits [control props](./control-props.md). ## Examples diff --git a/docs/ui/components/components.md b/docs/ui/components/components.md index f106be6..89dbb91 100644 --- a/docs/ui/components/components.md +++ b/docs/ui/components/components.md @@ -1,64 +1,88 @@ --- sidebar_position: 1 -description: "Built-in JSX components for layout, text, and interactivity." +description: "Every built-in component, grouped by what it is for." --- # Components -Built-in JSX components for layout, text, and interactivity. +Built-in JSX components for layout, text, interaction and the two switches a compiled screen owns. ## Roots -A screen's root names its host, and there is no default: a tree that starts with anything else is refused with the list of roots. +A screen's root names its [host](../guides/hosts.md), and there is no default: a tree that starts with anything else is refused with the list of roots. -- [**``**](./Screen.md) — an action form: buttons, decoration, lists and scrolls, shown with `render()`. -- [**``**](./Form/Form.md) — a native modal form, shown with `render()`. -- [**``**](./Container.md) — a compiled container screen, served with `createContainerScreen()`. +- [``](./Screen.md) — an action form: buttons, decoration, lists and scrolls, shown with `render()` +- [``](./Form/Form.md) — a native modal form, shown with `render()` +- [``](./Container.md) — a container screen an entity owns, served with `createContainerScreen()` -## Components +## Layout and decoration -- [**``**](./Panel.md) — basic container with optional background and flexbox layout. -- [**``**](./Text.md) — display text with Minecraft formatting codes, font, and scale. -- [**`} +``` + +becomes ` + ); +} +``` + +When the handoff goes through an async opener, **return the promise from `onPress`** so the swap lands inside the press's transaction. Fired and forgotten it still converges; worst case the screen re-locks for a frame. + +## A form change is a new present + +`@minecraft/server-ui` forms cannot be mutated while open, so a state change never repaints a form on its own. The component logic keeps running in the background; the player sees a new snapshot **when they press**. + +A container screen has no such limit: a handler renders and the slots settle in the same tick. + +## A container screen's state belongs to its entity + +One layout serves every viewer of a container screen. Its state is written to the entity after each render and read back at the next open, so it outlives every viewer — and effects run exactly while somebody is looking, because the fibers exist exactly then. + +That is also why a container screen has no `usePlayer()`: one compiled layout serves everyone, and the screen learns who is looking from `onOpen` instead. + +## Reacting to something outside the screen + +[`useObservable`](../hooks/useObservable.md) re-renders the component when an observable changes, which covers a config leaf, a db document, a query and anything else shaped like `@bedrock-core/observable`'s `ReadonlyObservable`. + +```tsx +const count = useObservable(playersObs, p => p.size); +``` + +With a `select` the component only re-renders when the selected slice changes, so a screen showing a count is not woken by every mutation of the collection behind it. + +## What a value costs + +A compiled screen's shape is frozen, so anything that varies has to reserve room for itself before the build knows what it will hold. + +| Varies | Declared as | Reserves | +| --- | --- | --- | +| A string | [`maxLength`](../components/Text.md) on a `` | its width, and on the chest one slot per character | +| A row count | [`max`](../components/List.md) on a `` | `max` copies of the row, plus one int | +| A branch | `visible` on the control | a carried bool | +| A texture | [`live`](../components/Image.md) on an `` | one entry on a form | + +Everything else is baked. A baked string fed from data that changes is silently wrong, which is what `render(screen, player, { debug: true })` reports. + +## Next steps + +- [Hooks](../hooks/hooks.md) — the reference for each hook +- [Hosts](./hosts.md) — what each screen can carry a live value on +- [Handler events](./handler-events.md) — the event object every handler takes diff --git a/docs/ui/hooks/hooks.md b/docs/ui/hooks/hooks.md index f71e448..69c44ef 100644 --- a/docs/ui/hooks/hooks.md +++ b/docs/ui/hooks/hooks.md @@ -1,39 +1,49 @@ --- sidebar_position: 1 -description: "State and effects management for your components." +description: "State, effects, and the hooks that reach the player, the host and the world." --- # Hooks -State and effects management for your components. +State and effects for your components, plus the few that reach outside them. -## Built-in hooks +## State -### State management +- [`useState`](./useState.md) — component state +- [`useReducer`](./useReducer.md) — state through a reducer +- [`useContext`](./useContext.md) — read a context value +- [`useObservable`](./useObservable.md) — re-render when an observable changes, optionally on a selected slice -- [`useState`](./useState.md) — Manage component state. -- [`useReducer`](./useReducer.md) — Manage complex state logic with a reducer function. -- [`useContext`](./useContext.md) — Access context values from Context. +## Effects and lifecycle -### Effects & lifecycle +- [`useEffect`](./useEffect.md) — side effects with cleanup +- [`useExit`](./useExit.md) — close the screen from inside it -- [`useEffect`](./useEffect.md) — Perform side effects in function components with cleanup support. -- [`useExit`](./useExit.md) — Request the UI to be closed. +## References -### References +- [`useRef`](./useRef.md) — a mutable value that survives re-renders -- [`useRef`](./useRef.md) — Create a mutable reference that is persisted across executions. +## Minecraft -### Minecraft specific +- [`usePlayer`](./usePlayer.md) — the player looking at this screen +- [`useEvent`](./useEvent.md) — subscribe to a Minecraft event signal for as long as the screen is mounted -- [`usePlayer`](./usePlayer.md) — Access the current player who is viewing the UI. -- [`useEvent`](./useEvent.md) — Subscribe to global Minecraft events within your UI components. +## Hosts -### Localization +- [`useMechanism`](./useMechanism.md) — what this kind of component becomes on the screen it is drawn on -- [`useTranslation`](./useTranslation.md) — Bind an addon's typed translation verbs to the viewing player. -- [`useTranslationResolver`](./useTranslationResolver.md) — Read the translation resolver active for this part of the tree. +## Localization + +- [`useTranslation`](./useTranslation.md) — bind an addon's typed translation verbs to the viewing player +- [`useTranslationResolver`](./useTranslationResolver.md) — read the resolver active for this part of the tree + +## Where the state lives + +A form cannot be mutated while open, so a state change never repaints what the player is looking at — they see a new snapshot when they press. A container screen's state belongs to its entity and outlives every viewer. Both are covered in [State](../guides/state.md). + +`usePlayer()` has no answer on a container screen: one compiled layout serves everyone, so the screen learns who is looking from `` instead. ## Next steps -- [Components](../components/components.md) — Built-in components that you can use in your JSX -- [API](../api/api.md) — APIs that are useful for defining components +- [State](../guides/state.md) — the model behind all of these +- [Components](../components/components.md) — what the hooks drive +- [API](../api/api.md) — `render()`, contexts and the compiled-screen registry diff --git a/docs/ui/hooks/useEffect.md b/docs/ui/hooks/useEffect.md index ed7362e..7150a35 100644 --- a/docs/ui/hooks/useEffect.md +++ b/docs/ui/hooks/useEffect.md @@ -1,5 +1,5 @@ --- -sidebar_position: 5 +sidebar_position: 6 description: "Perform side effects in function components." --- # useEffect @@ -73,7 +73,7 @@ function SearchResults() { useEffect(() => { if (query.length > 0) { - console.log(`Searching for: ${query}`); + console.warn(`Searching for: ${query}`); setResults([`Result for ${query}`]); } }, [query]); // Runs when query changes @@ -98,17 +98,17 @@ function MultiEffect() { // Effect 1: Log count changes useEffect(() => { - console.log(`Count changed to: ${count}`); + console.warn(`Count changed to: ${count}`); }, [count]); // Effect 2: Log name changes useEffect(() => { - console.log(`Name changed to: ${name}`); + console.warn(`Name changed to: ${name}`); }, [name]); // Effect 3: Run on every execution useEffect(() => { - console.log('Component executed'); + console.warn('Component executed'); }); return ( @@ -174,12 +174,12 @@ Include all values used inside the effect: ```tsx // ✅ Good - all dependencies listed useEffect(() => { - console.log(count, name); + console.warn(count, name); }, [count, name]); // ❌ Bad - missing dependencies useEffect(() => { - console.log(count, name); + console.warn(count, name); }, []); // count and name should be in deps! ``` diff --git a/docs/ui/hooks/useEvent.md b/docs/ui/hooks/useEvent.md index 442ef6f..3fc2968 100644 --- a/docs/ui/hooks/useEvent.md +++ b/docs/ui/hooks/useEvent.md @@ -1,5 +1,5 @@ --- -sidebar_position: 9 +sidebar_position: 10 description: "Subscribe to global Minecraft events within your UI components." --- # useEvent @@ -154,7 +154,7 @@ function EventHandler() { world.afterEvents.playerJoin, (event) => { // No external dependencies used - console.log(`${event.playerName} joined`); + console.warn(`${event.playerName} joined`); } // deps not needed ); diff --git a/docs/ui/hooks/useExit.md b/docs/ui/hooks/useExit.md index 3b26bc2..c5f35be 100644 --- a/docs/ui/hooks/useExit.md +++ b/docs/ui/hooks/useExit.md @@ -1,5 +1,5 @@ --- -sidebar_position: 6 +sidebar_position: 7 description: "Request the UI to be closed." --- # useExit @@ -7,7 +7,7 @@ description: "Request the UI to be closed." Request the UI to be closed. :::note Closing, not switching -`exit()` closes the UI back to the game. You do **not** need it to hand off to another screen or app — calling [`render()`](../api/render.md#one-ui-slot-per-player) (or an opener like `openUi`) while a UI is up swaps the new app into the running session by itself. +`exit()` closes the UI back to the game. You do **not** need it to hand off to another screen or app — calling [`render()`](../guides/state.md#one-ui-slot-per-player) (or an opener like `openUi`) while a UI is up swaps the new app into the running session by itself. ::: ## Import diff --git a/docs/ui/hooks/useMechanism.md b/docs/ui/hooks/useMechanism.md new file mode 100644 index 0000000..61430ff --- /dev/null +++ b/docs/ui/hooks/useMechanism.md @@ -0,0 +1,61 @@ +--- +sidebar_position: 11 +description: "What this kind of component becomes on the screen it is being drawn on." +--- +# useMechanism + +What this kind of component becomes on the screen it is being drawn on. + +## Import + +```tsx +import { useMechanism } from '@bedrock-core/ui'; +``` + +## Signature + +```ts +function useMechanism(kind: ComponentKind): Mechanism +``` + +## Parameters + +| Parameter | Type | Default | Description | +| --- | --- | --- | --- | +| `kind` | `ComponentKind` | — | What the author wrote, as the host's table names it | + +`ComponentKind` is the library's own vocabulary, not the styled layer's: `'Button'`, `'Toggle'`, `'Select'`, `'Option'`, `'Slider'`, `'Dropdown'`, `'Input'`, `'Form'`, `'Submit'`, `'Slot'`, `'SlotGrid'`. + +## Returns + +`Mechanism` — one of `'press'`, `'slot'`, `'field'`, `'submit'`, `'cancel'`, `'exit'`, `'collection'` or `'local'`. + +`'local'` is the one that costs the host nothing: the client draws it and handles it, and script never hears about it. The rest are the host's own transport, so each is a capability the screen spends. + +## Throws + +The [host](../guides/hosts.md)'s own refusal when it has no mechanism for the kind. The wording belongs to the screen, because the fix does — the same `Slider` is "put it inside a ``" on an action form and "a container has no native form" on a container screen. + +`ScreenRootError` when nothing above the component names a host at all. + +## When to reach for it + +This is the seam that lets one component serve every host. You need it when writing a component that *is* one of those kinds and has to draw differently per screen — which is how a `Toggle` is a native field on a modal and a pressed button on a screen of buttons. + +```tsx +function Checkbox({ name, label }: CheckboxProps): JSX.Element { + const mechanism = useMechanism('Toggle'); + + return mechanism === 'field' + ? + : ; +} +``` + +A component that only lays out or decorates — a card, a header, a row — asks for nothing and needs none of this. + +## Notes + +A host with no mechanism for the kind throws rather than returning nothing: a component that got an answer it could not use would only draw something inert, which is exactly what the capability model exists to prevent. + +[`@bedrock-core/ore-styled`](/docs/ore-styled) is built on this hook, which is why its `Checkbox` works on a modal and on a screen of buttons without the author choosing. diff --git a/docs/ui/hooks/useObservable.md b/docs/ui/hooks/useObservable.md new file mode 100644 index 0000000..7cc1829 --- /dev/null +++ b/docs/ui/hooks/useObservable.md @@ -0,0 +1,82 @@ +--- +sidebar_position: 5 +description: "Re-render the component when an observable changes, optionally only on a selected slice." +--- +# useObservable + +Re-renders the component when an observable changes. + +## Import + +```tsx +import { useObservable } from '@bedrock-core/ui'; +``` + +## Signature + +```ts +function useObservable(source: ObservableLike): T; +function useObservable(source: ObservableLike, select: (value: T) => S): S; +``` + +## Parameters + +| Parameter | Type | Default | Description | +| --- | --- | --- | --- | +| `source` | `ObservableLike` | — | Anything with `get()` and `subscribe(listener)` | +| `select` | `(value: T) => S` | — | Narrows what the component depends on, so it only re-renders when the slice changes | + +## Returns + +The current value, or the selected slice of it. + +## What counts as an observable + +`ObservableLike` is structural: `get()` for the current value, `subscribe(listener)` for the next ones, returning an unsubscribe. + +```ts +interface ObservableLike { + get(): T; + subscribe(listener: (next: T, prev: T) => void): () => void; +} +``` + +[`@bedrock-core/observable`](/docs/observable)'s `ReadonlyObservable`, a [config](/docs/config) leaf, a [db](/docs/db) document and a query all have that shape. Matching on shape rather than on an import is what keeps the UI free of a dependency on the server framework. + +## Usage + +```tsx +const phase = useObservable(phaseObs); +``` + +## Examples + +### Only re-render when the slice changes + +```tsx +function PlayerCount(): JSX.Element { + const count = useObservable(playersObs, players => players.size); + + return {String(count)}; +} +``` + +A screen showing a count is not woken by every mutation of the collection behind it. Equality is `Object.is`, applied by the state slot, so a slice that reads equal schedules nothing. + +### A config value + +```tsx +function Currency(): JSX.Element { + const symbol = useObservable(core.config.server.economy.currency); + + return {symbol}; +} +``` + +## Notes + +`select` is read through a ref rather than a dependency, so passing an inline arrow — the usual way to write one — does not resubscribe on every render. The subscription is keyed on the observable alone. + +The value can move between a render and the subscription landing, so the hook reads once more before listening. An unchanged value costs nothing. + +On a form, a change still does not repaint what the player is looking at: a form cannot be mutated while open, so the new value shows on their next press. See [State](../guides/state.md#a-form-change-is-a-new-present). diff --git a/docs/ui/hooks/usePlayer.md b/docs/ui/hooks/usePlayer.md index 8173b17..8a08a00 100644 --- a/docs/ui/hooks/usePlayer.md +++ b/docs/ui/hooks/usePlayer.md @@ -1,5 +1,5 @@ --- -sidebar_position: 8 +sidebar_position: 9 description: "Access the current player who is viewing the UI." --- # usePlayer diff --git a/docs/ui/hooks/useRef.md b/docs/ui/hooks/useRef.md index 4be4d5d..d484d69 100644 --- a/docs/ui/hooks/useRef.md +++ b/docs/ui/hooks/useRef.md @@ -1,5 +1,5 @@ --- -sidebar_position: 7 +sidebar_position: 8 description: "Create a mutable reference that persists across executions" --- # useRef @@ -122,10 +122,10 @@ function FirstExecutionDetector() { useEffect(() => { if (isFirstExecution.current) { - console.log('First execution!'); + console.warn('First execution!'); isFirstExecution.current = false; } else { - console.log('Subsequent execution'); + console.warn('Subsequent execution'); } }); diff --git a/docs/ui/hooks/useTranslation.md b/docs/ui/hooks/useTranslation.md index e123b7d..778b97f 100644 --- a/docs/ui/hooks/useTranslation.md +++ b/docs/ui/hooks/useTranslation.md @@ -1,5 +1,5 @@ --- -sidebar_position: 10 +sidebar_position: 12 description: "Bind an addon's typed translation verbs to the player viewing the UI." --- # useTranslation diff --git a/docs/ui/hooks/useTranslationResolver.md b/docs/ui/hooks/useTranslationResolver.md index 94495e4..b574529 100644 --- a/docs/ui/hooks/useTranslationResolver.md +++ b/docs/ui/hooks/useTranslationResolver.md @@ -1,5 +1,5 @@ --- -sidebar_position: 11 +sidebar_position: 13 description: "Read the translation resolver that is active for this part of the tree." --- # useTranslationResolver diff --git a/docs/ui/index.md b/docs/ui/index.md index d76bd7f..a1fa84a 100644 --- a/docs/ui/index.md +++ b/docs/ui/index.md @@ -2,13 +2,13 @@ slug: / sidebar_position: 1 sidebar_label: Overview -description: "Get up and running with @bedrock-core/ui in minutes." +description: "@bedrock-core/ui writes Minecraft Bedrock screens in JSX and compiles them into the resource pack." --- # ui ![The shared addon list, with a row per registered addon](/img/ui/addon-list.png) -Get up and running with `@bedrock-core/ui` in minutes. +`@bedrock-core/ui` writes Minecraft Bedrock screens in JSX and compiles them into the resource pack. :::caution Pre-1.0 `@bedrock-core/ui` is under active development. Breaking changes can still land until `1.0.0` — pin exact versions and read the release notes before upgrading. @@ -16,70 +16,85 @@ Get up and running with `@bedrock-core/ui` in minutes. ## What is @bedrock-core/ui? -`@bedrock-core/ui` is a React-like UI framework for Minecraft Bedrock Edition that enables you to create rich, interactive user interfaces using JSX syntax. It serializes your UI components into a protocol and renders them using JSON UI with the render pack. +A screen is a component. You write it with JSX, flexbox props and hooks, and the build [compiles](./compiler/index.md) it once into the JSON UI that ships in the pack. At runtime nothing sends a layout: showing a screen sends its title and the values that changed, and the client draws it from the pack it already holds. -For a pre-themed component set that matches vanilla Minecraft's look (buttons, cards, checkboxes, toggles, …), see the [`@bedrock-core/ore-styled`](/docs/ore-styled) layer. It's optional — pick it up when you want batteries-included visuals, skip it when you'd rather style every primitive yourself. +Three screens can be drawn on, and the root element picks one — [``](./components/Screen.md) is an action form, [``](./components/Form/Form.md) a native modal, [``](./components/Container.md) a custom entity's chest screen. One component set serves all three: a toggle is a native field on a modal and a pressed button on a screen of buttons, and it does not know which screen it is on. See [Hosts](./guides/hosts.md). -Localization is built in rather than bolted on: `` takes literal and localized children on the same channel, so one screen serves every language at once. See [i18n](/docs/i18n) for the translation verbs and how player locale is resolved. +For a pre-themed component set matching vanilla Minecraft's look, see [`@bedrock-core/ore-styled`](/docs/ore-styled). It is optional — pick it up for batteries-included visuals, skip it to style every primitive yourself. -## Learn React first +Localization is built in rather than bolted on: `` takes literal and localized children on the same channel, so one screen serves every language at once. See [i18n](/docs/i18n). -If you're new to React, start with the official React tutorial: +## Install -- React Learn: https://react.dev/learn + -### Differences with React +A world also needs the render pack, which must come from the same release as the library. [Installation](./installation.md) covers both, and the [CLI](/docs/cli) scaffolds them wired together. -`@minecraft/server-ui` forms cannot be mutated while open — updating one means closing it and presenting a new form, which loses cursor/controller focus. +## Your first screen -So your component logic keeps running in the background, but the player only sees a new snapshot of the UI **when they press a button**. A state change on its own does not repaint their screen. +A screen lives in a `*.screen.tsx` file under `BP/scripts` and default-exports its component. That is what the [`ui-compiler` filter](/docs/filters/ui-compiler) looks for. -## Your first UI +```tsx title="packs/BP/scripts/welcome.screen.tsx" +import { Button, Panel, Screen, Text } from '@bedrock-core/ui'; -Here's a simple example to get you started: - -```tsx -import { render, Panel, Screen, Text, Button } from '@bedrock-core/ui'; -import { world, Player, Entity, ButtonPushAfterEvent } from '@minecraft/server'; -import { MinecraftEntityTypes } from '@minecraft/vanilla-data'; - -// Create a simple UI component. at the root makes it an action form. -function WelcomeScreen() { +export default function Welcome(): JSX.Element { return ( - {'Welcome to Bedrock UI!'} + {'Welcome to Bedrock UI'} - ); } +``` + +Show it to a player with [`render()`](./api/render.md): + +```ts title="packs/BP/scripts/main.ts" +import { render } from '@bedrock-core/ui'; +import '@bedrock-core/generated/ui'; +import Welcome from './welcome.screen'; +import { world, type Entity, type Player, type ButtonPushAfterEvent } from '@minecraft/server'; +import { MinecraftEntityTypes } from '@minecraft/vanilla-data'; const isPlayer = (source: Entity): source is Player => source.typeId === MinecraftEntityTypes.Player; -// Render it to a player world.afterEvents.buttonPush.subscribe(({ source }: ButtonPushAfterEvent): void => { if (isPlayer(source)) { - render(WelcomeScreen, source); + render(Welcome, source); } }); ``` -## How it works +The `@bedrock-core/generated/ui` import is what runs the build's registrations. Without it `render()` throws `UncompiledScreenError`, because nothing in the pack answers to the screen's title. + +## What you get + +**A layout solved once** — [`@bedrock-core/flexbox`](/docs/flexbox) solves every rect at build time against a fixed 320 × 210 canvas. No geometry is measured in game, and a host that serves the screen cannot move a control the layout placed. + +**Refusals with names** — each host declares what every kind of component becomes on it. A `` outside a `` or a `` outside a container screen fails the build, in that host's own words, instead of drawing something inert. + +**Screens other addons can show** — a [static](./guides/navigation.md#static-screens) screen is described by its title, its entry values and one target per press. Publish that table and a realm running none of your script still shows your screens, because the layout is in the pack every client holds. + +**Switches that cost nothing** — [``](./components/Tabs.md) and [``](./components/Disclosure.md) change what is drawn entirely on the client. No press, no re-present, no payload. + +## Differences from React + +A `@minecraft/server-ui` form cannot be mutated while open, so a state change never repaints it: the player sees a new snapshot when they press. A container screen has no such limit. + +A compiled screen's **shape** is also frozen. Anything that varies declares itself — `maxLength` for a string, `` for a row count, `visible` for a branch — and everything else is baked. [State](./guides/state.md) covers what that costs. -1. **Write JSX Components**: Use familiar React-like syntax to define your UI -2. **Serialization**: The framework converts your component tree into a serialized protocol and injects it into @minecraft/server-ui form components -3. **JSON UI Decoding**: The render pack's JSON UI files decode the serialized data -4. **Rendering**: Players see rich, interactive UIs in Minecraft +If you are new to React, [react.dev/learn](https://react.dev/learn) is the place to start. ## Next steps -- [Installation](./installation.md) — Set up the framework in your project -- [Components](/docs/ui/components) — Built-in components that you can use in your JSX -- [ore-styled](/docs/ore-styled) — Themed component layer with vanilla Minecraft textures (optional) -- [Hooks](/docs/ui/hooks) — Add state and effects to your components -- [API](/docs/ui/api) — APIs that are useful for defining components -- [i18n](/docs/i18n) — Localize your UI so each player reads it in their own language +- [Installation](./installation.md) — the package, the render pack and the `tsconfig.json` entries +- [Hosts](./guides/hosts.md) — the three screens and what each can carry +- [Components](./components/components.md) — every built-in component +- [Hooks](./hooks/hooks.md) — state, effects and the Minecraft-specific hooks +- [Compiler](./compiler/index.md) — how a screen becomes JSON UI +- [API](./api/api.md) — `render()`, contexts and the compiled-screen registry diff --git a/docs/ui/installation.md b/docs/ui/installation.md index a9009f9..5fa8c67 100644 --- a/docs/ui/installation.md +++ b/docs/ui/installation.md @@ -1,38 +1,67 @@ --- sidebar_position: 2 -description: "Learn how to install @bedrock-core/ui for your Minecraft Bedrock addon project." +description: "Install @bedrock-core/ui, the render pack and the filter that compiles your screens." --- # Installation -Learn how to install `@bedrock-core/ui` for your Minecraft Bedrock addon project. +Three things have to be in place: the package, the render pack in the world, and the filter that compiles your screens into the pack. ## Prerequisites -- Node.js 20+ and Yarn (or npm) https://nodejs.org/ -- Regolith (recommended) https://regolith-docs.readthedocs.io/en/stable +- Node.js 20+ and Yarn or npm — https://nodejs.org +- Regolith — https://regolith-docs.readthedocs.io/en/stable + +Regolith is not optional here. A screen is drawn from JSON UI the build writes, so a project with no build has no screens. ## Quick start with the CLI -The [CLI](/docs/cli) scaffolds an addon with `@bedrock-core/ui` configured, TypeScript and ESLint, the Regolith build, the render pack and a working example screen. +The [CLI](/docs/cli) scaffolds an addon with `@bedrock-core/ui` configured, TypeScript and ESLint, the Regolith filter stack, the render pack and a working example screen. -The render pack decodes the runtime's wire format, so it must come from the **same release** as the library. See [Render pack](./guides/render-pack.md) for how to check which version a world is running. - ## Manual installation -If you're adding to an existing project, install the package: +### 1. The package -Download the render pack from the [releases page](https://github.com/bedrock-core/ui/releases) — take it from the same release as the library, as [Render pack](./guides/render-pack.md#getting-the-matching-pack) explains — and add it as a dependency in your behavior pack's `manifest.json`: +Everything an addon writes comes from the one entry point. Two subpaths carry the parts a screen file does not need: + +| Import | What it is | +| --- | --- | +| `@bedrock-core/ui` | components, hooks, `render()`, navigation | +| `@bedrock-core/ui/container` | `createContainerScreen()`, for serving a [container screen](./guides/container-screens.md) | +| `@bedrock-core/ui-runtime/compile` | the build half the [compiler](./compiler/index.md) reads; no addon reaches for it | + +### 2. The filter + +Add the [`ui-compiler` filter](/docs/filters/ui-compiler) to the Regolith stack. It has to run **after** `i18n` and **before** `bundler`. -```json +```json title="config.json" +{ + "filter": "ui-compiler", + "settings": { "namespace": "my_addon" } +} +``` + +The [`core` filter](/docs/filters/core) runs the whole stack in the right order with the namespace declared once, which is what the CLI scaffolds. + +The filter writes `@bedrock-core/generated/ui`. Import it once from your entry module so the registrations run: + +```ts title="packs/BP/scripts/main.ts" +import '@bedrock-core/generated/ui'; +``` + +### 3. The render pack + +The render pack decodes what the build wrote, so it must come from the **same release** as the library. Download it from the [releases page](https://github.com/bedrock-core/ui/releases) and add it as a dependency in your behavior pack's `manifest.json`: + +```json title="packs/BP/manifest.json" { "dependencies": [ { - "uuid": "761ecd37-ad1c-4a64-862a-d6cc38767426", - "version": [1, 10, 0] + "uuid": "761ecd37-ad1c-4a64-862a-d6cc38767426", + "version": [1, 11, 0] } ] } @@ -47,24 +76,10 @@ pack.mcaddon └── core-ui-vx.y.z.mcpack (render pack from releases) ``` -### Optional: ore-styled - -[`@bedrock-core/ore-styled`](/docs/ore-styled) is a themed component layer that pairs with `@bedrock-core/ui` to give you vanilla-Minecraft-styled buttons, cards, checkboxes, and more. It's entirely optional — skip this section if you'd rather hand-style each primitive yourself. - -If you installed `@bedrock-core/ui`, `ore-styled` is already included — no separate install needed. If you're on a minimal install (`@bedrock-core/ui-runtime` only), add it explicitly: - - - -Then import from `@bedrock-core/ore-styled` whenever you want a themed variant: - -```tsx -import { Button, Card } from '@bedrock-core/ore-styled'; -``` +[Render pack](./guides/render-pack.md#getting-the-matching-pack) explains how to check which version a world is running. ## TypeScript configuration -Add JSX support to your `tsconfig.json`: - ```jsonc title="tsconfig.json" { "compilerOptions": { @@ -74,36 +89,43 @@ Add JSX support to your `tsconfig.json`: } ``` -If you also run the i18n Regolith filter, it needs one more `paths` alias and an `include` entry so the generated bundle typechecks — see [tsconfig](/docs/filters/i18n#tsconfig). +If you also run the i18n filter, it needs one more `paths` alias and an `include` entry so the generated bundle typechecks — see [tsconfig](/docs/filters/i18n#tsconfig). + +## Optional: ore-styled -## Quick test +[`@bedrock-core/ore-styled`](/docs/ore-styled) is a themed component layer giving you vanilla-styled buttons, cards, checkboxes and more. Installing `@bedrock-core/ui` already includes it; on a minimal install add it explicitly: -Test your installation with a simple render: + ```tsx -import { render, Panel, Screen, Text } from '@bedrock-core/ui'; -import { world, Player, Entity, ButtonPushAfterEvent } from '@minecraft/server'; -import { MinecraftEntityTypes } from '@minecraft/vanilla-data'; - -const HelloWorld = ( - - - {'Hello from @bedrock-core/ui!'} - - -); - -const isPlayer = (source: Entity): source is Player => source.typeId === MinecraftEntityTypes.Player; - -world.afterEvents.buttonPush.subscribe(({ source }: ButtonPushAfterEvent): void => { - if (isPlayer(source)) { - render(HelloWorld, source); - } -}); +import { Button, Card } from '@bedrock-core/ore-styled'; ``` +## Check it works + +Write a screen, build, then show it. + +```tsx title="packs/BP/scripts/hello.screen.tsx" +import { Panel, Screen, Text } from '@bedrock-core/ui'; + +export default function Hello(): JSX.Element { + return ( + + + {'Hello from @bedrock-core/ui'} + + + ); +} +``` + + + +The filter logs one line per screen it compiled. If `render()` throws `UncompiledScreenError` instead, the build did not see the file or `@bedrock-core/generated/ui` was never imported. + ## Next steps -- [Components](./components/components.md) — Built-in components that you can use in your JSX -- [ore-styled](/docs/ore-styled) — Themed component layer with vanilla Minecraft textures (optional) -- [Hooks](./hooks/hooks.md) — Add state and effects to your components -- [API](./api/api.md) — APIs that are useful for defining components + +- [Hosts](./guides/hosts.md) — which root to write, and what each screen can carry +- [Components](./components/components.md) — every built-in component +- [Hooks](./hooks/hooks.md) — state and effects +- [`ui-compiler` filter](/docs/filters/ui-compiler) — every setting the build takes diff --git a/src/data/redirects.ts b/src/data/redirects.ts index 2ef05c4..32aee5b 100644 --- a/src/data/redirects.ts +++ b/src/data/redirects.ts @@ -21,7 +21,7 @@ export const redirects: { from: string; to: string }[] = [ { from: '/docs/ui/config', to: '/docs/config' }, { from: '/docs/ui/container-screens', to: '/docs/ui/guides/container-screens' }, { from: '/docs/ui/container-screens/findings', to: '/docs/ui/guides/container-screens' }, - { from: '/docs/ui/container-screens/regolith-filter', to: '/docs/filters/ui-compile' }, + { from: '/docs/ui/container-screens/regolith-filter', to: '/docs/filters/ui-compiler' }, { from: '/docs/ui/flexbox', to: '/docs/flexbox' }, { from: '/docs/ui/flexbox/computeLayout', to: '/docs/flexbox/computeLayout' }, { from: '/docs/ui/flexbox/createNode', to: '/docs/flexbox/createNode' }, @@ -102,4 +102,7 @@ export const redirects: { from: string; to: string }[] = [ { from: '/docs/ui/ui-runtime/hooks/useTranslation', to: '/docs/ui/hooks/useTranslation' }, { from: '/docs/ui/ui-runtime/hooks/useTranslationResolver', to: '/docs/ui/hooks/useTranslationResolver' }, { from: '/docs/ui/ui-runtime/render-pack', to: '/docs/ui/guides/render-pack' }, + { from: '/docs/filters/ui-compile', to: '/docs/filters/ui-compiler' }, + { from: '/docs/ui-compile', to: '/docs/ui/compiler' }, + { from: '/docs/ui-compiler', to: '/docs/ui/compiler' }, ]; diff --git a/src/data/sections.ts b/src/data/sections.ts index 8378c5a..285e071 100644 --- a/src/data/sections.ts +++ b/src/data/sections.ts @@ -127,7 +127,6 @@ export const sections: Section[] = [ icon: 'layout-grid', repo: `${GH}/ui`, }, - // Content { id: 'config', @@ -167,7 +166,7 @@ export const sections: Section[] = [ pkg: 'bedrock-core/regolith-filters', category: 'tooling', status: 'beta', - description: 'Regolith filters: manifest, generator, guides, i18n, ui-compile, bundler.', + description: 'Regolith filters: manifest, generator, guides, i18n, ui-compiler, bundler.', icon: 'funnel', repo: `${GH}/regolith-filters`, }, From eead4891c637bd50ec13b9ea6896788c5560b8d6 Mon Sep 17 00:00:00 2001 From: DrAv0011 Date: Sat, 12 Sep 2026 12:01:26 +0200 Subject: [PATCH 26/48] fix(sections): i18n ships from the server repository Co-Authored-By: Claude Opus 5 (1M context) --- src/data/sections.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/data/sections.ts b/src/data/sections.ts index 285e071..236c059 100644 --- a/src/data/sections.ts +++ b/src/data/sections.ts @@ -127,6 +127,7 @@ export const sections: Section[] = [ icon: 'layout-grid', repo: `${GH}/ui`, }, + // Content { id: 'config', @@ -156,7 +157,7 @@ export const sections: Section[] = [ status: 'beta', description: 'Typed keys, interpolation and plurals, resolved per player.', icon: 'languages', - repo: `${GH}/ui`, + repo: `${GH}/server`, }, // Tooling From 083883c24b1973e6834d3b2c51c50a1880925599 Mon Sep 17 00:00:00 2001 From: DrAv0011 Date: Sat, 12 Sep 2026 12:13:09 +0200 Subject: [PATCH 27/48] fix(sections): config and guides ship from the apps repository Co-Authored-By: Claude Opus 5 (1M context) --- src/data/sections.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/data/sections.ts b/src/data/sections.ts index 236c059..44ed3ed 100644 --- a/src/data/sections.ts +++ b/src/data/sections.ts @@ -137,7 +137,7 @@ export const sections: Section[] = [ status: 'beta', description: 'The shared addon list, settings screens and guide viewer.', icon: 'sliders-horizontal', - repo: `${GH}/ui`, + repo: `${GH}/apps`, }, { id: 'guides', @@ -147,7 +147,7 @@ export const sections: Section[] = [ status: 'beta', description: 'In-game guides authored in MDX.', icon: 'book-open', - repo: `${GH}/ui`, + repo: `${GH}/apps`, }, { id: 'i18n', From ad5b5207b0749be6d5e74c29c6ba5b2ac87aa4f2 Mon Sep 17 00:00:00 2001 From: DrAv0011 Date: Sun, 13 Sep 2026 01:04:58 +0200 Subject: [PATCH 28/48] docs(navigation): navigation is a stack of keys `createStackNavigator` and `useRoute` describe an API that no longer exists: a compiled screen is drawn from the pack by its title and cannot be swapped into a root, so the stack holds keys. New pages for `navigate`/`back`/`replace`/ `reset`, the real `useNavigation`, and the screen and page reference feeds. Co-Authored-By: Claude Opus 5 (1M context) --- docs/guides/index.md | 12 +- docs/navigation/createStackNavigator.md | 208 ------------------------ docs/navigation/index.md | 128 ++++++--------- docs/navigation/navigate.md | 95 +++++++++++ docs/navigation/references.md | 80 +++++++++ docs/navigation/useNavigation.md | 132 +++++---------- docs/navigation/useRoute.md | 90 ---------- docs/ore-styled/Header.md | 24 ++- docs/ore-styled/MenuRow.md | 22 ++- src/data/redirects.ts | 10 +- 10 files changed, 308 insertions(+), 493 deletions(-) delete mode 100644 docs/navigation/createStackNavigator.md create mode 100644 docs/navigation/navigate.md create mode 100644 docs/navigation/references.md delete mode 100644 docs/navigation/useRoute.md diff --git a/docs/guides/index.md b/docs/guides/index.md index f18c80b..fcde4e8 100644 --- a/docs/guides/index.md +++ b/docs/guides/index.md @@ -17,8 +17,10 @@ import { createGuide } from '@bedrock-core/guides'; // state, so recreating it each render resets the guide to its home. const Guide = createGuide(guides, { title: 'My Addon' }); -function GuideScreen({ navigation }: ScreenProps) { - return navigation.goBack()} />; +export default function GuideScreen(): JSX.Element { + const { back } = useNavigation(); + + return back()} />; } ``` @@ -36,7 +38,7 @@ Or, if you already depend on `@bedrock-core/ui`: import { createGuide } from '@bedrock-core/ui/guides'; ``` -Peer dependencies: `@bedrock-core/ui-runtime`, `@bedrock-core/navigation`, `@bedrock-core/ore-styled`. +Peer dependencies: `@bedrock-core/ui-runtime`, `@bedrock-core/ore-styled`, `@bedrock-core/i18n`. ## `createGuide(manifest, options?)` @@ -190,7 +192,7 @@ import { GuideBlockList } from '@bedrock-core/guides'; navigation.navigate('GuidePage', { pageId })} + onNavigate={(pageId) => navigate(`guide:${pageId}`, { replace: true })} /> ``` @@ -250,7 +252,7 @@ type GuideTreeNode ## Publishing a guide -Pass the manifest to the server runtime's [registration](/docs/server/api/registry) and every realm in the world can render it — the [`GuidesRegistry`](/docs/server/api/guides) replicates it, which is how your guide reaches the [shared addon list](/docs/config): +Publish your compiled screens once and every realm in the world can render the guide — [`screens(core)`](/docs/navigation/references) replicates the references, which is how your guide reaches the [shared addon list](/docs/config): ```ts import guides from '@bedrock-core/generated/guides'; diff --git a/docs/navigation/createStackNavigator.md b/docs/navigation/createStackNavigator.md deleted file mode 100644 index c6fe206..0000000 --- a/docs/navigation/createStackNavigator.md +++ /dev/null @@ -1,208 +0,0 @@ ---- -sidebar_position: 2 -description: "Create a typed stack navigator." ---- - -# createStackNavigator - -Create a typed stack navigator. This is the main setup step — call it once at module level, declare every screen in the `screens` map, and render the returned `Navigator`. - -## Import - -```ts -import { createStackNavigator } from '@bedrock-core/navigation'; -``` - -## Signature - -```ts -function createStackNavigator( - options: StackNavigatorOptions, -): { - Navigator: (props: { initialRouteName?: Extract }) => JSX.Element; - routeNames: Extract[]; - initialRouteName: Extract; -} -``` - -## TRoutes — typing your routes - -The generic `TRoutes` parameter is the single source of truth for every route name and its expected params. Define it as a plain object type before calling `createStackNavigator`. - -```ts -type Routes = { - Home: undefined; // no params - Profile: { userId: string }; // required params - Modal: { message?: string }; // optional params -}; - -const Stack = createStackNavigator({ ... }); -``` - -TypeScript uses this map to: -- Enforce that `navigate('Profile', { userId: '…' })` includes the right shape -- Make params optional when the type is `T | undefined` -- Forbid params entirely when the type is `undefined` - -## StackNavigatorOptions - -| Option | Type | Default | Description | -| --- | --- | --- | --- | -| `screens` | `ScreensMap` | — | Maps each route name to a screen component, optionally with `initialParams` | -| `initialRouteName` | `keyof TRoutes` | first key in `screens` | The route shown first when the navigator mounts | - -### `screens` - -Each entry can be either a bare component or an object: - -```ts -const Stack = createStackNavigator({ - screens: { - // Bare component — no default params - Home: HomeScreen, - - // Object form — provides initial/default params - Profile: { - screen: ProfileScreen, - initialParams: { userId: 'guest' }, - }, - }, -}); -``` - -`initialParams` are shallow-merged as defaults — params passed via `navigate` or `push` take precedence. - -### `initialRouteName` - -```ts -const Stack = createStackNavigator({ - screens: { Home: HomeScreen, Profile: ProfileScreen }, - initialRouteName: 'Profile', // start on Profile -}); -``` - -## NavigationContainer - -Every navigator must be wrapped in a `NavigationContainer`. It provides the navigation context consumed by [`useNavigation`](./useNavigation.md) and [`useRoute`](./useRoute.md). - -```ts -import { NavigationContainer } from '@bedrock-core/navigation'; -``` - -```tsx -function App() { - return ( - - - - ); -} -``` - -`NavigationContainer` accepts an optional `initialState` prop for restoring a previously serialized navigation state (e.g. from persistent storage). - -## Navigator component - -`Stack.Navigator` owns the stack state and renders the active screen. It re-renders the active screen whenever the stack changes. - -```tsx - - -// Override the initial screen at render time - -``` - -## ScreenProps — typing screen components - -Use `ScreenProps` to type the props of a screen component. It injects `navigation` (NavigationHelpers) and `route` (RouteObject) with the correct param types for that specific route. - -```ts -import type { ScreenProps } from '@bedrock-core/navigation'; - -function ProfileScreen({ navigation, route }: ScreenProps) { - // route.params is typed as { userId: string } - // navigation.navigate is typed for all routes in Routes - return {`User: ${route.params.userId}`}; -} -``` - -## Full example - -```tsx -import { render, Panel, Text, Button } from '@bedrock-core/ui'; -import { - NavigationContainer, - createStackNavigator, -} from '@bedrock-core/navigation'; -import type { ScreenProps } from '@bedrock-core/navigation'; - -type Routes = { - Menu: undefined; - Game: { difficulty: 'easy' | 'hard' }; - Result: { score: number }; -}; - -const Stack = createStackNavigator({ - screens: { - Menu: MenuScreen, - Game: { screen: GameScreen, initialParams: { difficulty: 'easy' } }, - Result: ResultScreen, - }, - initialRouteName: 'Menu', -}); - -function MenuScreen({ navigation }: ScreenProps) { - return ( - - {'Main Menu'} - - - ); -} - -function GameScreen({ navigation, route }: ScreenProps) { - return ( - - {`Difficulty: ${route.params.difficulty}`} - - - ); -} - -function ResultScreen({ navigation, route }: ScreenProps) { - return ( - - {`Score: ${route.params.score}`} - - - ); -} - -function App() { - return ( - - - - ); -} -``` - -## Advanced — stackReducer - -`stackReducer` is the underlying pure reducer that powers `Navigator`. It is exported for advanced use cases such as testing navigation logic in isolation or building a custom navigator. - -```ts -import { stackReducer } from '@bedrock-core/navigation'; -import type { StackAction } from '@bedrock-core/navigation'; - -const nextState = stackReducer(currentState, action, { - routeNames: ['Home', 'Profile'], - initialRouteName: 'Home', -}); -``` diff --git a/docs/navigation/index.md b/docs/navigation/index.md index 7961c9e..3dd617e 100644 --- a/docs/navigation/index.md +++ b/docs/navigation/index.md @@ -2,109 +2,77 @@ slug: / sidebar_position: 1 sidebar_label: Overview -description: "@bedrock-core/navigation is a stack-based navigation system for Minecraft Bedrock UI, inspired by React Navigation and adapted for @bedrock-core/ui's…" +description: "@bedrock-core/navigation moves a player from one compiled screen to another by key, across addons." --- - # navigation -`@bedrock-core/navigation` is a stack-based navigation system for Minecraft Bedrock UI, inspired by React Navigation and adapted for `@bedrock-core/ui`'s single-render-per-player model. +`@bedrock-core/navigation` moves a player from one screen to another by **key**, and keeps a stack of where they have been. -:::caution MVP scope -This package covers stack navigation only. There is no support for animations, tab navigators, nested navigators, or deep linking in the current release. +:::caution Pre-1.0 +`@bedrock-core/navigation` is under active development. Breaking changes can still land until `1.0.0` — pin exact versions and read the release notes before upgrading. ::: +## What is @bedrock-core/navigation? + +A [compiled screen](/docs/ui/compiler) is drawn from the resource pack by its title, and its shape is frozen at build. That rules out the navigator every React app has — a stack of components swapped inside one root — because there is no root to swap into. + +What fits is a stack of **keys**. `navigate('shop:catalog', player)` shows that screen and puts the one the player was on behind them; `back(player)` returns to it. + +The key is `:`, and that is what makes this work across addons: a key for a screen nobody in this realm compiled still resolves, through the reference its owner replicated. + ## Install +Peer dependency: `@bedrock-core/ui-runtime`, which an addon already has through [`@bedrock-core/ui`](/docs/ui). + ## Quick start -The example below wires up a two-screen stack: a `Home` screen that navigates to a `Details` screen and back. +```ts title="packs/BP/scripts/main.ts" +import { core } from '@bedrock-core/server'; +import { navigate, provideReferences, screens } from '@bedrock-core/navigation'; +import { uiReference } from '@bedrock-core/generated/ui'; +import '@bedrock-core/generated/ui'; -```tsx -import { render, Panel, Screen, Text, Button } from '@bedrock-core/ui'; -import { - NavigationContainer, - createStackNavigator, - type ScreenProps, -} from '@bedrock-core/navigation'; -import { world } from '@minecraft/server'; - -// 1. Define your route map — key = route name, value = params type -type Routes = { - Home: undefined; - Details: { id: number; title: string }; -}; - -// 2. Create the navigator once, outside any component -const Stack = createStackNavigator({ - screens: { - Home: { screen: HomeScreen }, - Details: { screen: DetailsScreen }, - }, - initialRouteName: 'Home', -}); - -// 3. Screen components receive navigation + route as props. Each is a whole -// screen, so each starts with a root: here, for a modal. -function HomeScreen({ navigation }: ScreenProps) { - return ( - - - {'Home Screen'} - - - - ); -} +core.register({ manifest }); -function DetailsScreen({ navigation, route }: ScreenProps) { - return ( - - - {`Details — ${route.params.title}`} - - - - ); +// Publish this addon's screens so other realms can show them. +screens(core).provide(uiReference()); + +// Resolve a key this bundle did not compile, from whoever owns it. +provideReferences(key => screens(core).find(key)); + +export function openCatalog(player: Player): void { + navigate('shop:catalog', player); } +``` + +Inside a screen, reach for the hook instead — the player is already in hand: + +```tsx +function Row(): JSX.Element { + const { navigate, back, canGoBack } = useNavigation(); -// 4. Wrap Navigator in NavigationContainer and render to a player -function App() { return ( - - - + + + + ); } - -world.afterEvents.playerSpawn.subscribe(({ player }) => { - render(App, player); -}); ``` -## How it works +## What you get -Navigation state is a plain stack — an array of `{ name, params }` route entries plus an `index` pointing to the active screen. All transitions (navigate, push, goBack, reset) dispatch an action to a pure reducer that produces a new state, which triggers `ui-runtime`'s re-render cycle and presents the updated UI to the player. +**A stack that survives a frozen layout** — it holds keys, not trees. Going back means showing that screen again, drawn from its own initial state; the state of the screen being returned to went with its fibers. -``` -NavigationContainer — provides the navigation context - └─ Stack.Navigator — owns the stack state, renders the active screen - └─ ActiveScreen({ navigation, route }) -``` +**Screens other addons can open** — publish your static screens once and `navigate(':')` works in any realm in the world, whether or not your script runs there. The client draws it from the pack it already holds. -## In this section +**A press that is data** — [``](/docs/ui/components/Link) puts the destination on the element rather than in a closure, so the build can read where it leads and describe the screen to other addons. -:::caution Pre-1.0 -`@bedrock-core/navigation` is under active development. Breaking changes can still land until `1.0.0` — pin exact versions and read the release notes before upgrading. -::: +## Next steps -| Page | Description | -|---|---| -| [createStackNavigator](./createStackNavigator.md) | Set up a typed stack navigator with screens, params, and initial routes | -| [useNavigation](./useNavigation.md) | Access navigation helpers (`navigate`, `push`, `goBack`, …) from any screen | -| [useRoute](./useRoute.md) | Read the current route name and params inside a screen | +- [Moving between screens](./navigate.md) — `navigate`, `back`, `replace`, `reset` and what each does to the stack +- [`useNavigation`](./useNavigation.md) — the same calls inside a screen, bound to its player +- [References](./references.md) — publishing your screens and resolving another addon's +- [Navigation in the ui docs](/docs/ui/guides/navigation) — screen keys, `` and static screens diff --git a/docs/navigation/navigate.md b/docs/navigation/navigate.md new file mode 100644 index 0000000..7f0b4c1 --- /dev/null +++ b/docs/navigation/navigate.md @@ -0,0 +1,95 @@ +--- +sidebar_position: 2 +description: "navigate, back, replace and reset: the four ways to move a player, and what each does to the stack." +--- +# Moving between screens + +Four calls, distinguished by what they leave behind the player. + +## Import + +```ts +import { back, canGoBack, currentKey, historyOf, navigate, replace, reset } from '@bedrock-core/navigation'; +``` + +## Signatures + +```ts +navigate(key: ScreenKey, player: Player, options?: NavigateOptions): boolean +replace(key: ScreenKey, player: Player, options?: Omit): boolean +reset(key: ScreenKey, player: Player, options?: Omit): boolean +back(player: Player, options?: Omit): boolean +``` + +| Call | The stack afterwards | +| --- | --- | +| `navigate` | one deeper — the screen they were on is behind them | +| `replace` | exactly as deep as it was — a back from the target returns past this screen | +| `reset` | empty — a back from the target has nowhere to go | +| `back` | one shallower — the screen behind becomes the current one | + +Each returns whether a screen was shown. A `false` is a key nothing resolved: a screen that did not compile, an addon nobody in this realm is running, or a typo. It is warned about where it is decided, never thrown. + +## Options + +| Option | Type | Default | Description | +| --- | --- | --- | --- | +| `params` | `Record` | — | Props the target screen is rendered with | +| `replace` | `boolean` | `false` | Show the screen in place of the current one; `replace()` is this with the flag already set | +| `debug` | `boolean` | `false` | Diff every present against the snapshot the build recorded and warn on drift | + +`params` fill what the layout already reserved. A compiled screen's shape is frozen, so they can never add or drop a cell — a generic screen's labels and values, not its structure. + +## Which one to reach for + +**`navigate`** is the default: the player is going somewhere they will come back from. + +**`replace`** is for screens that are peers, where none is the way back to another — the pages of a guide, the tabs of a set. A redirect is the other case. + +**`reset`** is what a menu's root wants. Going back out of the first screen of a flow should end the flow, not walk into whatever the player was looking at before it. + +**`back`** needs no key: the player's own stack decides. + +## Reading the stack + +```ts +historyOf(player: Player): readonly string[] +currentKey(player: Player): ScreenKey | undefined +canGoBack(player: Player): boolean +``` + +`historyOf` is the keys behind the player, oldest first. `currentKey` is the screen they are looking at. `canGoBack` is whether there is anything behind it — what a back control's `visible` wants. + +## Examples + +### A flow whose first screen ends it + +```ts +export function openShop(player: Player): void { + reset('shop:home', player); +} +``` + +A `back` from `shop:home` now returns `false`, so the control that calls it can be hidden with `canGoBack(player)`. + +### Pages that move sideways + +```ts +export function openPage(player: Player, pageId: string): void { + replace(`guide:${pageId}`, player); +} +``` + +The guide's index stays the thing a back returns to, however many pages deep the player reads. + +### Filling a generic screen + +```ts +navigate('shop:item', player, { params: { itemId: 'diamond', price: 64 } }); +``` + +## Notes + +Closing what a player is looking at from outside a screen is [`closeUi(player)`](/docs/ui/guides/navigation), from `@bedrock-core/ui` — it clears the stack as well. A screen closing itself is [`useExit()`](/docs/ui/hooks/useExit). + +A container screen has no key, so none of these can open one. A chest is entered by walking up to an entity. diff --git a/docs/navigation/references.md b/docs/navigation/references.md new file mode 100644 index 0000000..234e5ea --- /dev/null +++ b/docs/navigation/references.md @@ -0,0 +1,80 @@ +--- +sidebar_position: 4 +description: "Publishing this addon's screens and resolving a key it never compiled." +--- +# References + +A key for a screen nobody in this realm compiled still resolves, because every client already holds the pack that draws it. What has to travel is small: per screen the compiled title, the value each entry carries and where each press leads. + +## Import + +```ts +import { pages, provideReferences, screens } from '@bedrock-core/navigation'; +``` + +## provideReferences + +```ts +provideReferences(lookup: (key: string) => ScreenReference | undefined): void +``` + +Installs what resolves a key this bundle did not compile. Called once: + +```ts +provideReferences(key => screens(core).find(key)); +``` + +Until it is called, a foreign key warns and shows nothing. A key this bundle **did** compile never reaches the lookup — its own component is rendered. + +A screen shown from a reference is **shown, not rendered**: there is no component in this realm, so the walk drives the client directly — title, values, and the key each press leads to — for as long as the presses are links. A press that ran the owner's own handler cannot be described, so it does nothing there, and the walk ends. + +## screens + +```ts +screens(core: Runtime): ScreensRegistry +``` + +One registry per runtime, created on the first call and kept, so every caller in a realm reads and writes the same feed. It announces under `ui/reference`. + +| Member | Description | +| --- | --- | +| `provide(reference)` | Publish this addon's screens, from `uiReference()` in `@bedrock-core/generated/ui` | +| `find(key)` | The reference for one key, from whichever addon published it | +| `of(namespace)` | Everything one addon published | +| `namespaces()` | Every addon that has published screens | + +```ts +import { screens } from '@bedrock-core/navigation'; +import { uiReference } from '@bedrock-core/generated/ui'; + +screens(core).provide(uiReference()); +``` + +`find` searches rather than parsing the key. A key's first half is the owner's UI namespace, which an addon may set apart from the namespace it syncs under, so the published records are the only reliable answer. + +## pages + +```ts +pages(core: Runtime): PagesRegistry +``` + +The same shape for an addon's page in the shared addon list, announced under `addon/page`. The page follows from the manifest, so the build compiles one and [`ui(core)`](/docs/config) announces it — an addon that mounts the config UI needs none of this by hand. + +| Member | Description | +| --- | --- | +| `provide(reference)` | Publish this addon's page | +| `of(addonId)` | What another addon published | + +## Types + +```ts +import type { AddonPageReference, AddonScreens } from '@bedrock-core/navigation'; +``` + +Both are envelopes: the version, the owner, and the payload as `unknown`. The renderer owns the real shape and narrows it at the point of use, which is what keeps this package free of the screen format. `isAddonScreens` and `isAddonPageReference` are the envelope checks. + +## Notes + +Both registries extend `Announcement` from `@bedrock-core/server-runtime`, so they behave like every other cross-addon feed: published once at startup, readable by every realm, and re-read when an addon joins. + +An addon that calls `ui(core)` gets both the publishing and the lookup done for it. Write these yourself for a bundle that wants its screens navigable without mounting the config UI. diff --git a/docs/navigation/useNavigation.md b/docs/navigation/useNavigation.md index 9977eb3..dbe53f4 100644 --- a/docs/navigation/useNavigation.md +++ b/docs/navigation/useNavigation.md @@ -1,132 +1,84 @@ --- sidebar_position: 3 -description: "Access the navigation helpers for the current stack from any component inside a NavigationContainer." +description: "Navigation bound to the player the screen is being shown to." --- - # useNavigation -Access the navigation helpers for the current stack from any component inside a `NavigationContainer`. +Navigation bound to the player the screen is being shown to. ## Import -```ts +```tsx import { useNavigation } from '@bedrock-core/navigation'; ``` ## Signature ```ts -function useNavigation(): NavigationHelpers +function useNavigation(): Navigation ``` -Throws if called outside a `NavigationContainer`. +## Returns + +| Member | Type | Description | +| --- | --- | --- | +| `navigate` | `(key: ScreenKey, options?: NavigateOptions) => boolean` | Show that screen, putting this one behind the player | +| `replace` | `(key: ScreenKey, options?) => boolean` | Show that screen in this one's place, leaving the stack as deep as it is | +| `reset` | `(key: ScreenKey, options?) => boolean` | Show that screen as the only one the player has been on | +| `back` | `(options?) => boolean` | Go back to the screen navigated from; `false` when there is none | +| `canGoBack` | `boolean` | Whether there is a screen behind this one | +| `key` | `ScreenKey \| undefined` | The key of the screen this is | +| `history` | `readonly string[]` | The keys behind it, oldest first | + +The same calls as the [free functions](./navigate.md), with the player already in hand — which inside a screen is the only player there is. ## Usage ```tsx -import { useNavigation } from '@bedrock-core/navigation'; - -function BackButton() { - const navigation = useNavigation(); +function Footer(): JSX.Element { + const { back, canGoBack } = useNavigation(); return ( - ); } ``` -:::tip Prefer ScreenProps for screen components -Screen components already receive `navigation` as a prop via [`ScreenProps`](./createStackNavigator.md#screenprops--typing-screen-components). Use `useNavigation` in nested components that are not directly passed props by the navigator. -::: - -## NavigationHelpers API - -### `navigate` - -```ts -navigation.navigate('Home') -navigation.navigate('Profile', { userId: '123' }) -``` - -Navigate to a route by name. If the route is already present in the stack, pops back to it and merges the new params. If it is not in the stack, pushes a new entry. - -| Behavior | When | -|---|---| -| Push new entry | Route not in stack | -| Pop-to + merge params | Route already in stack | - -Use [`push`](#push) if you always want a new entry regardless of duplicates. - -### `push` - -```ts -navigation.push('Profile', { userId: '456' }) -``` - -Always push a new stack entry, even if a screen with the same name is already in the stack. Useful for flows where visiting the same screen multiple times is intentional (e.g. drill-down item detail). - -### `goBack` - -```ts -navigation.goBack() -``` +## Examples -Pop the current screen and return to the previous one. No-op if the stack has only one entry. Check [`canGoBack`](#cangoback) first when in doubt. +### A row of destinations -### `canGoBack` +```tsx +function Menu(): JSX.Element { + const { navigate } = useNavigation(); -```ts -if (navigation.canGoBack()) { - navigation.goBack(); + return ( + + + + + ); } ``` -Returns `true` when there is at least one screen below the current one in the stack (`index > 0`). - -### `reset` - -```ts -navigation.reset({ - routes: [{ name: 'Home' }, { name: 'Profile', params: { userId: '1' } }], - index: 1, -}) -``` - -Replace the entire navigation stack with a new one. The `index` must point to the active screen in the new `routes` array. Invalid route names are silently filtered out; `index` is clamped to the resulting array length. +### Knowing which screen this is -Useful for flows that should not allow the player to go back (e.g. after completing an action, reset to a fresh state): - -```ts -// After a game ends, clear the history and go back to the main menu -navigation.reset({ routes: [{ name: 'Menu' }], index: 0 }); -``` - -### `setParams` +```tsx +function Breadcrumb(): JSX.Element { + const { key, history } = useNavigation(); -```ts -navigation.setParams('Profile', { userId: '789' }) + return {[...history, key ?? ''].join(' > ')}; +} ``` -Merge partial params into the first matching screen in the stack without navigating. Only the provided keys are updated — other existing params are preserved. +`key` is the screen's own key, so a component shared by several screens can tell which one it is drawing in without being told. -```ts -// Only update the title; other params stay the same -navigation.setParams('Details', { title: 'Updated Title' }); -``` +## Notes -### `getState` +Prefer [``](/docs/ui/components/Link) over a `navigate()` in an `onPress` when the destination is fixed. A link's target is data the build reads off the tree, which is what lets the screen be described to another addon; a closure is script only this realm can run. -```ts -const state = navigation.getState(); -// { -// type: 'stack', -// routes: [{ key, name, params }, ...], -// index: 1, -// routeNames: ['Home', 'Profile'], -// stale: false, -// } -``` +`canGoBack` and `history` are read at render time. A form cannot change while it is open, so they are a snapshot of the moment the screen was presented — which is the same moment everything else on it was decided. -Returns a snapshot of the current `NavigationState`. Useful for debugging or persisting navigation state. +There is no `useRoute()`. Params arrive as the screen component's own **props**, because `navigate(key, player, { params })` renders it with them, so there is no route object to read them out of. The route's name is `key` above. diff --git a/docs/navigation/useRoute.md b/docs/navigation/useRoute.md deleted file mode 100644 index 7a43283..0000000 --- a/docs/navigation/useRoute.md +++ /dev/null @@ -1,90 +0,0 @@ ---- -sidebar_position: 4 -description: "Read the name and params of the currently active route from any component inside a NavigationContainer." ---- - -# useRoute - -Read the name and params of the currently active route from any component inside a `NavigationContainer`. - -## Import - -```ts -import { useRoute } from '@bedrock-core/navigation'; -``` - -## Signature - -```ts -function useRoute(): RouteObject -``` - -Throws if called outside a `NavigationContainer` or when there is no active route. - -## RouteObject - -```ts -interface RouteObject { - key: string; // unique identifier for this stack entry - name: string; // route name (e.g. 'Profile') - params: TParams extends undefined ? undefined : TParams; // typed params — `undefined` for parameterless routes -} -``` - -## Usage - -```tsx -import { useRoute } from '@bedrock-core/navigation'; - -function ProfileHeader() { - const route = useRoute(); - // route.params is typed as { userId: string } - - return {`Viewing user: ${route.params.userId}`}; -} -``` - -:::tip Prefer ScreenProps for screen components -Screen components already receive `route` as a prop via [`ScreenProps`](./createStackNavigator.md#screenprops--typing-screen-components). Use `useRoute` in nested components that need param access but are not directly wired by the navigator. -::: - -## Examples - -### Accessing required params - -```tsx -type Routes = { - Details: { id: number; title: string }; -}; - -function DetailsTitle() { - const route = useRoute(); - - return {route.params.title}; -} -``` - -### Accessing optional params with a fallback - -```tsx -type Routes = { - Modal: { message?: string }; -}; - -function ModalBody() { - const route = useRoute(); - const message = route.params.message ?? 'No message provided.'; - - return {message}; -} -``` - -### Reading the route name - -```tsx -function ActiveScreenLabel() { - const route = useRoute(); - - return {`Current screen: ${route.name}`}; -} -``` diff --git a/docs/ore-styled/Header.md b/docs/ore-styled/Header.md index 797df07..ad13602 100644 --- a/docs/ore-styled/Header.md +++ b/docs/ore-styled/Header.md @@ -17,12 +17,18 @@ import { Header } from '@bedrock-core/ore-styled'; ## Usage ```tsx -
    navigation.goBack()} - onClose={() => close()} -/> +function Settings(): JSX.Element { + const { back } = useNavigation(); + + return ( +
    back()} + onClose={() => closeUi(player)} + /> + ); +} ``` Renders as `Settings > Server > Pricing`, centered between the two icon buttons. @@ -57,7 +63,7 @@ const { key, raw } = useTranslation(i18n);
    $.settings.title)} breadcrumbs={[raw($ => $.settings.forPlayer, { name: player.name })]} - onBack={() => navigation.goBack()} + onBack={() => back()} /> ``` @@ -79,7 +85,7 @@ Omit `onBack` on the first screen of a stack. The slot still reserves its width,
    navigation.goBack()} + onBack={() => back()} onClose={() => close()} /> ``` @@ -90,7 +96,7 @@ Pair it with a [`Scroll`](/docs/ui/components/Scroll) so the header stays put wh ```tsx -
    navigation.goBack()} /> +
    back()} /> {items.map(item => ( buy(item)} /> diff --git a/docs/ore-styled/MenuRow.md b/docs/ore-styled/MenuRow.md index 12cd643..db878b2 100644 --- a/docs/ore-styled/MenuRow.md +++ b/docs/ore-styled/MenuRow.md @@ -17,12 +17,18 @@ import { MenuRow } from '@bedrock-core/ore-styled'; ## Usage ```tsx - navigation.navigate('Details', { id: 'diamond' })} -/> +function Row(): JSX.Element { + const { navigate } = useNavigation(); + + return ( + navigate('shop:details', { params: { id: 'diamond' } })} + /> + ); +} ``` ## Props @@ -59,7 +65,7 @@ const { key, raw } = useTranslation(i18n); $.shop.title)} subtitle={raw($ => $.shop.stock, { count })} - onPress={() => navigation.navigate('Shop')} + onPress={() => navigate('shop:home')} /> ``` @@ -116,7 +122,7 @@ Drop the chevron for rows that pick a value rather than navigating deeper. title={'Server settings'} subtitle={'Operators only'} enabled={isOperator} - onPress={() => navigation.navigate('ServerConfig')} + onPress={() => navigate('shop:server_config')} /> ``` diff --git a/src/data/redirects.ts b/src/data/redirects.ts index 32aee5b..4d28a1c 100644 --- a/src/data/redirects.ts +++ b/src/data/redirects.ts @@ -6,7 +6,7 @@ export const redirects: { from: string; to: string }[] = [ { from: '/docs/server/server-runtime', to: '/docs/server/api/runtime' }, { from: '/docs/server/server-runtime/config', to: '/docs/server/api/config' }, { from: '/docs/server/server-runtime/features', to: '/docs/server/api/features' }, - { from: '/docs/server/server-runtime/guides', to: '/docs/server/api/guides' }, + { from: '/docs/server/server-runtime/guides', to: '/docs/guides' }, { from: '/docs/server/server-runtime/host', to: '/docs/server/api/host' }, { from: '/docs/server/server-runtime/registry', to: '/docs/server/api/registry' }, { from: '/docs/server/server-runtime/shared', to: '/docs/server/api/shared' }, @@ -32,9 +32,9 @@ export const redirects: { from: string; to: string }[] = [ { from: '/docs/ui/i18n', to: '/docs/i18n' }, { from: '/docs/ui/i18n/regolith-filter', to: '/docs/filters/i18n' }, { from: '/docs/ui/navigation', to: '/docs/navigation' }, - { from: '/docs/ui/navigation/createStackNavigator', to: '/docs/navigation/createStackNavigator' }, + { from: '/docs/ui/navigation/createStackNavigator', to: '/docs/navigation' }, { from: '/docs/ui/navigation/useNavigation', to: '/docs/navigation/useNavigation' }, - { from: '/docs/ui/navigation/useRoute', to: '/docs/navigation/useRoute' }, + { from: '/docs/ui/navigation/useRoute', to: '/docs/navigation/useNavigation' }, { from: '/docs/ui/ore-styled', to: '/docs/ore-styled' }, { from: '/docs/ui/ore-styled/Button', to: '/docs/ore-styled/Button' }, { from: '/docs/ui/ore-styled/Card', to: '/docs/ore-styled/Card' }, @@ -105,4 +105,8 @@ export const redirects: { from: string; to: string }[] = [ { from: '/docs/filters/ui-compile', to: '/docs/filters/ui-compiler' }, { from: '/docs/ui-compile', to: '/docs/ui/compiler' }, { from: '/docs/ui-compiler', to: '/docs/ui/compiler' }, + { from: '/docs/navigation/createStackNavigator', to: '/docs/navigation' }, + { from: '/docs/navigation/useRoute', to: '/docs/navigation/useNavigation' }, + { from: '/docs/server/api/guides', to: '/docs/guides' }, + { from: '/docs/server/api/pages', to: '/docs/navigation/references' }, ]; From 847b3f44cc24baea871e1a3abbb9dfefaefed91c Mon Sep 17 00:00:00 2001 From: DrAv0011 Date: Sun, 13 Sep 2026 01:05:06 +0200 Subject: [PATCH 29/48] docs(server): register declares four things, and the UI feeds moved out `screens`, `page`, `guide`, `guideReference` and `translations` are no longer register fields: a bundle is published with `core.translations.provide()`, and screens and list pages ride the registries `@bedrock-core/navigation` builds. `core.guides` and `core.pages` are gone with them. Co-Authored-By: Claude Opus 5 (1M context) --- docs/i18n/index.md | 3 +- docs/server/api/announcement.md | 14 ++--- docs/server/api/authorize.md | 2 +- docs/server/api/guides.md | 82 ---------------------------- docs/server/api/pages.md | 49 ----------------- docs/server/api/runtime.md | 16 ++---- docs/server/api/shared.md | 4 +- docs/server/api/translations.md | 2 +- docs/server/guides/ui-integration.md | 27 ++++----- docs/server/index.md | 2 +- 10 files changed, 32 insertions(+), 169 deletions(-) delete mode 100644 docs/server/api/guides.md delete mode 100644 docs/server/api/pages.md diff --git a/docs/i18n/index.md b/docs/i18n/index.md index 26a0bf0..49b3841 100644 --- a/docs/i18n/index.md +++ b/docs/i18n/index.md @@ -337,7 +337,8 @@ A library creating its own instance must pass `{ asDefault: false }` so it never Publish the bundle itself through the server runtime's registration: ```ts -core.register({ manifest, translations: bundle }); +core.register({ manifest }); +core.translations.provide(bundle); ``` The runtime replicates the bundle — objects, templates and recorded argument order intact — and serves two lazy views: `core.translations.of(addonId)` gives verbs over a peer's strings, and `core.translations.forPlayer(player)` gives one resolver chaining every published bundle, later registrations winning collisions. Registry display fields (`packName`, `description`, `creatorName`) are translation keys so that this works. diff --git a/docs/server/api/announcement.md b/docs/server/api/announcement.md index 78ab9cb..27e1bcc 100644 --- a/docs/server/api/announcement.md +++ b/docs/server/api/announcement.md @@ -1,5 +1,5 @@ --- -sidebar_position: 12 +sidebar_position: 10 description: "Announcement is the shape of every cross-addon feed: one owner-written value under a framework key, read from every realm's mirror." --- @@ -7,7 +7,7 @@ description: "Announcement is the shape of every cross-addon feed: one owner-wri `Announcement` is the shape of every cross-addon feed the runtime publishes: one small, owner-written value under a framework key on the [mirror](/docs/sync/state), read from every realm's local copy. -`core.pages` is one. `core.guides` and `core.translations` extend one. `core.features.flags`, `core.config.schema`, `core.config.groups` and `core.shared.shape` are fields of one. Wherever you meet the five members below, they mean the same thing. +`core.translations` extends one, and so do the registries `@bedrock-core/navigation` builds over the same mirror — [`screens(core)` and `pages(core)`](/docs/navigation/references). `core.features.flags`, `core.config.schema`, `core.config.groups` and `core.shared.shape` are fields of one. Wherever you meet the five members below, they mean the same thing. ## Import @@ -35,13 +35,13 @@ type AnnouncementListener = (namespace: string) => void; ## Usage ```ts -core.pages.provide(addonPageReference(AddonPage)); // this addon's +core.translations.provide(bundle); // this addon's -core.pages.of('drav0011_shop'); // a peer's, or undefined -core.pages.namespaces(); // who published one +core.translations.of('drav0011_shop'); // a peer's, or undefined +core.translations.namespaces(); // who published one -const release = core.pages.subscribe((namespace) => { - redrawRowFor(namespace); +const release = core.translations.subscribe((namespace) => { + remeasureLabelsFor(namespace); }); ``` diff --git a/docs/server/api/authorize.md b/docs/server/api/authorize.md index 7eda3a2..9c0d746 100644 --- a/docs/server/api/authorize.md +++ b/docs/server/api/authorize.md @@ -1,5 +1,5 @@ --- -sidebar_position: 13 +sidebar_position: 11 description: "authorize is the one rule an RPC handler applies before it does anything on behalf of a player." --- diff --git a/docs/server/api/guides.md b/docs/server/api/guides.md deleted file mode 100644 index 12b5714..0000000 --- a/docs/server/api/guides.md +++ /dev/null @@ -1,82 +0,0 @@ ---- -sidebar_position: 10 -description: "core.guides announces each addon's compiled guide as a reference, so the elected host can present every addon's guide without any addon importing another." ---- - -# core.guides - -`core.guides` announces each addon's **compiled guide** across the world, so the [elected host](./host.md) can present every addon's guide — one in-game documentation browser for everything installed, without any addon importing another. - -A guide is authored as MDX and compiled by the [`guides` filter](/docs/filters/guides) into screens baked into the addon's own pack, so every client already holds what the guide *says*. What the host needs to present it is small — per screen a compiled title, the entry values and where each press leads — and that is the **reference** an addon announces. `core.guides` is an [`Announcement`](./announcement.md). - -## Import - -```ts -import { core } from '@bedrock-core/server'; -import type { GuideReference, GuideManifest } from '@bedrock-core/server'; -``` - -## Usage - -```ts -import { guideReference } from '@bedrock-core/guides'; - -core.register({ manifest, guideReference: guideReference(core.id) }); // publish up front -core.guides.provide(guideReference(core.id)); // or publish/replace later - -core.guides.own(); // this addon's reference -core.guides.of('drav0011_shop'); // another addon's, or undefined -core.guides.namespaces(); // every addon that published one -core.guides.subscribe((namespace) => { … }); -``` - -## What travels - -To the runtime a reference is an opaque payload with two known fields: - -```ts -interface GuideReference { - v: 1; - ns: string; // the owning addon's namespace - pages: unknown; // page id → screen reference, to the renderer -} -``` - -``` - → core-guide/reference → GuideReference -``` - -The runtime never looks inside one. Reads verify only that the value is an object carrying `ns` and `pages`; narrow it with `isGuideReference` from `@bedrock-core/guides` before presenting. - -## API - -`provide`, `own`, `of`, `namespaces` and `subscribe` are the [`Announcement`](./announcement.md#members) members over the reference. - -### `manifest` - -```ts -core.guides.manifest: Announcement - -interface GuideManifest { - tree: unknown; // sidebar entries in display order - pages: unknown; // page id → page data -} -``` - -The whole compiled manifest, announced under `core-guide/manifest`, for an addon that presents from one rather than from a reference. Declared with `register({ guide })`; read with `core.guides.manifest.of(addonId)`. A host that finds a reference presents from it and renders nothing of the manifest. - -## Guides and the host election - -Presenting is a job for exactly one realm, so the pattern is: - -```ts -if (core.host.isHost) { - for (const id of core.guides.namespaces()) { - listGuide(id, core.guides.of(id)); - } -} else { - void core.rpc.request(core.host.hostId, 'core:ui.open', { playerId: player.id, command: 'guide', args: [] }); -} -``` - -Because the reference is announced rather than fetched, the host already has every guide's index in memory — there is nothing to await. See [HostElection](./host.md). diff --git a/docs/server/api/pages.md b/docs/server/api/pages.md deleted file mode 100644 index f8fc79c..0000000 --- a/docs/server/api/pages.md +++ /dev/null @@ -1,49 +0,0 @@ ---- -sidebar_position: 11 -description: "core.pages announces an addon's page in the shared addon list, as a reference the elected host draws from." ---- - -# core.pages - -`core.pages` announces an addon's page in the shared addon list — the screen a player reaches by pressing the addon's row — as a reference the [elected host](./host.md) draws from. - -The page is a compiled screen baked into the addon's own pack, so every client already holds it. What the host needs to draw it into the list is small: per reserved entry, the value it is shown with and where a press leads. `core.pages` is an [`Announcement`](./announcement.md) over exactly that. - -## Import - -```ts -import { core } from '@bedrock-core/server'; -import type { AddonPageReference } from '@bedrock-core/server'; -``` - -## Usage - -```ts -import { addonPageReference } from '@bedrock-core/config/compiled'; -import AddonPage from './screens/addon.screen'; - -core.register({ manifest, page: addonPageReference(AddonPage) }); // publish up front -core.pages.provide(addonPageReference(AddonPage)); // or publish/replace later - -core.pages.of('drav0011_shop'); // a peer's, or undefined -``` - -## What travels - -```ts -interface AddonPageReference { - v: 1; - values: unknown; // per reserved entry, the value it is shown with; string[] to the renderer - targets: unknown; // per reserved entry, where a press leads -} -``` - -``` - → core-addon/page → AddonPageReference -``` - -The runtime never looks inside a reference; [`@bedrock-core/config`](/docs/config) owns the shape and narrows it at the point of use. Reads verify only that the value is an object carrying `values` and `targets`. - -## API - -`provide`, `own`, `of`, `namespaces` and `subscribe` — the [`Announcement`](./announcement.md#members) members. diff --git a/docs/server/api/runtime.md b/docs/server/api/runtime.md index 627cea5..677ae4d 100644 --- a/docs/server/api/runtime.md +++ b/docs/server/api/runtime.md @@ -44,8 +44,6 @@ Every accessor below throws `runtime. is unavailable: call register() firs | `core.db` | [`Db`](./db.md) | This addon's persisted documents, keyed by target. | | `core.config` | [`ConfigRegistry`](./config.md) | Schema, scopes and cross-addon config access. | | `core.translations` | [`TranslationsRegistry`](./translations.md) | Cross-addon i18n bundles, with resolvers over all of them. | -| `core.guides` | [`GuidesRegistry`](./guides.md) | Cross-addon guide references. | -| `core.pages` | [`Announcement`](./pages.md) | This addon's page in the shared addon list. | | `core.rpc` | `Rpc` | [RPC](/docs/sync/rpc), passed through from the sync node. | | `core.node` | `SyncNode` | The raw [sync node](/docs/sync) — bus, discovery, the mirror, events. | @@ -61,10 +59,6 @@ Declare the addon and bring it online. **Call exactly once — there is no separ | Field | Type | Equivalent to | |---|---|---| -| `translations` | `I18nBundle` | [`core.translations.provide()`](./translations.md#provide) | -| `guideReference` | `GuideReference` | [`core.guides.provide()`](./guides.md) | -| `guide` | `GuideManifest` | [`core.guides.manifest.provide()`](./guides.md#manifest) | -| `page` | `AddonPageReference` | [`core.pages.provide()`](./pages.md) | | `config` | `ConfigDefinition` | [`core.config.define()`](./config.md#define) | | `shared` | `SharedDef` | [`core.shared.define()`](./shared.md) | | `events` | `EventsDef` | [`core.events.define()`](./events.md) | @@ -73,7 +67,6 @@ Declare the addon and bring it online. **Call exactly once — there is no separ ```ts import { core } from '@bedrock-core/server'; -import { guideReference } from '@bedrock-core/guides'; import bundle from '@bedrock-core/generated/i18n'; import { configDef, sharedDef, eventsDef } from './example'; @@ -90,13 +83,13 @@ const { config, shared, events } = core.register({ icon: 'textures/ui/economy/icon', thumbnail: 'textures/ui/economy/thumbnail', }, - translations: bundle, - guideReference: guideReference('drav0011_economy'), config: configDef, shared: sharedDef, events: eventsDef, }); +core.translations.provide(bundle); + config.server.get(); // fully typed shared.currency.set('gold'); events.purchase.emit({ playerId: player.id, gold: 5 }); @@ -151,8 +144,9 @@ core.register({ description: i18n.key($ => $.meta.description), version: '1.0.0', }, - translations: bundle, }); + +core.translations.provide(bundle); ``` ### Validation @@ -234,7 +228,5 @@ The version of `@bedrock-core/server-runtime` this build was compiled against. I | [`core.db`](./db.md) | Persisted documents keyed by target | | [`core.config`](./config.md) | Schema, three scopes, persistence, cross-addon access, authorization | | [`core.translations`](./translations.md) | Announce and resolve i18n bundles across addons | -| [`core.guides`](./guides.md) | Announce and read guide references across addons | -| [`core.pages`](./pages.md) | An addon's page in the shared addon list | | [`Announcement`](./announcement.md) | The shape every cross-addon feed shares | | [`authorize`](./authorize.md) | The one rule a handler applies on behalf of a player | diff --git a/docs/server/api/shared.md b/docs/server/api/shared.md index 467c835..938bf15 100644 --- a/docs/server/api/shared.md +++ b/docs/server/api/shared.md @@ -112,8 +112,8 @@ Your namespace carries more than you put there. The framework replicates its own |---|---| | `core-config/schema`, `core-config/groups` | [`core.config`](./config.md) — the announced config schema | | `core-i18n/bundle` | [`core.translations`](./translations.md) — this addon's i18n bundle | -| `core-guide/reference`, `core-guide/manifest` | [`core.guides`](./guides.md) — the guide | -| `core-addon/page` | [`core.pages`](./pages.md) — the addon's page in the shared list | +| `core-ui/reference` | [`screens(core)`](/docs/navigation/references) — this addon's compiled screens, as references | +| `core-addon/page` | [`pages(core)`](/docs/navigation/references) — the addon's page in the shared list | | `core-feature/flags` | [`core.features`](./features.md) — every declared feature's flag, one record | | `core-shared/shape` | the shared registry — the owner's key names | diff --git a/docs/server/api/translations.md b/docs/server/api/translations.md index 1fdd16c..e4fc24e 100644 --- a/docs/server/api/translations.md +++ b/docs/server/api/translations.md @@ -25,7 +25,7 @@ import type { I18nBundle, TranslationResolver } from '@bedrock-core/server'; ```ts import bundle from '@bedrock-core/generated/i18n'; -core.register({ manifest, translations: bundle }); // publish up front +core.translations.provide(bundle); // publish up front core.translations.provide(bundle); // or publish/replace later core.translations.of('drav0011_shop'); // another addon's bundle diff --git a/docs/server/guides/ui-integration.md b/docs/server/guides/ui-integration.md index a18932e..bc3f4d0 100644 --- a/docs/server/guides/ui-integration.md +++ b/docs/server/guides/ui-integration.md @@ -13,7 +13,7 @@ This page is the seam between the two: what `server-runtime` publishes, which UI ``` ┌──────────────────────────── your addon ────────────────────────────┐ - │ core.register({ config, translations, guide }) │ + │ core.register({ config }) · core.translations.provide(bundle) │ └───────────────┬────────────────────────────────────────────────────┘ │ declares once ▼ @@ -43,22 +43,21 @@ One call, after `core.register()`: import { core } from '@bedrock-core/server'; import { ui } from '@bedrock-core/config'; import bundle from '@bedrock-core/generated/i18n'; -import guides from '@bedrock-core/generated/guides'; import { configDef } from './example'; core.register({ manifest: { creator: 'drav0011', pack: 'economy', packName: 'Economy', version: '1.0.0' }, - translations: bundle, - guide: guides, config: configDef, }); +core.translations.provide(bundle); + ui(core); ``` `ui` comes from [`@bedrock-core/config`](/docs/config) — the shared addon list, settings screens and guide viewer. `ui(core)` registers this addon's commands and serves the open RPC, so this realm can render on behalf of another whenever it wins the [host election](../api/host.md). -Pass the `Runtime` itself, not the typed config accessors — everything `ui` needs it reaches generically, through [`core.config.local`](../api/config.md#coreconfiglocal), `core.config.of()`, `core.registry`, `core.guides`, `core.translations` and `core.host`. +Pass the `Runtime` itself, not the typed config accessors — everything `ui` needs it reaches generically, through [`core.config.local`](../api/config.md#coreconfiglocal), `core.config.of()`, `core.registry`, `core.translations` and `core.host`. ## The three feeds @@ -105,15 +104,17 @@ for (const addon of core.registry.all()) { ### Guides -[`core.guides`](../api/guides.md) announces each addon's compiled guide as a reference — `guideReference(ns)` from `@bedrock-core/guides`, per screen the compiled title, the entry values and where a press leads. +A guide's pages are compiled screens like any other, so they ride the screen references [`screens(core)`](/docs/navigation/references) announces rather than a feed of their own. `ui(core)` publishes them for you. -The runtime treats it as opaque. [`@bedrock-core/guides`](/docs/guides) owns the real shape and narrows the payload with `isGuideReference` at the point of presenting. +The runtime treats the payload as opaque: [`@bedrock-core/guides`](/docs/guides) owns the real shape and narrows it at the point of presenting. -Because references are announced rather than fetched, the elected host already has every guide's index in memory: +Because references are announced rather than fetched, the realm drawing the list already has every addon's screens in memory: ```ts -for (const id of core.guides.namespaces()) { - const reference = core.guides.of(id); // synchronous, no RPC +import { screens } from '@bedrock-core/navigation'; + +for (const id of screens(core).namespaces()) { + const published = screens(core).of(id); // synchronous, no RPC } ``` @@ -145,11 +146,11 @@ import guides from '@bedrock-core/generated/guides'; // the guides filter's out The specifiers are `tsconfig.json` aliases the [`bundler`](/docs/filters/bundler) inlines at build time; the [`i18n`](/docs/filters/i18n) and [`guides`](/docs/filters/guides) filter pages cover the aliases, the outputs and the `namespace` they derive from `register()`. -An addon with no guide omits the `guide` field and the filter; the registries handle absence everywhere (`core.guides.of()` returns `undefined`, `core.config.of()` returns `undefined`, resolvers fall through). +An addon with no guide omits the filter; the registries handle absence everywhere (`core.config.of()` returns `undefined`, a key nothing published resolves to `undefined`, resolvers fall through). ## Next steps - [`core.config`](../api/config.md) — schema types, scopes and authorization - [`core.translations`](../api/translations.md) — what the bundle publishes -- [`core.guides`](../api/guides.md) — the manifest the runtime replicates -- [config](/docs/config) — the shared UI that reads all three +- [References](/docs/navigation/references) — the screen and page feeds the UI reads +- [config](/docs/config) — the shared UI that reads all of them diff --git a/docs/server/index.md b/docs/server/index.md index 4058f13..b607216 100644 --- a/docs/server/index.md +++ b/docs/server/index.md @@ -45,7 +45,7 @@ The packages underneath are strictly layered and installable on their own if you - **[Db](./api/db.md)** — persisted documents keyed by target, on whatever dynamic properties the target itself can hold, with versions and lazy migrations. Local: a peer reaches one only through a method you wrote. - **[Config](./api/config.md)** — a declarative schema in three scopes (server, dimension, player), stored as documents and editable in game. - **[Features](./api/features.md)** — behavior that auto-enables when a condition over the registry becomes true, and auto-disables when it stops being true. -- **[Translations](./api/translations.md)**, **[guides](./api/guides.md)** and **[pages](./api/pages.md)** — announce your i18n bundle, guide and list page so any addon's UI can render your content. +- **[Translations](./api/translations.md)** — announce your i18n bundle so any addon's UI can resolve and measure your strings. Your screens and your list page are announced by [`@bedrock-core/navigation`](/docs/navigation/references). - **[Host election](./api/host.md)** — a deterministic rule for "which realm does the work only one realm may do". ## Next steps From e3261010d3350e958ad5fd869a3d1981b8943912 Mon Sep 17 00:00:00 2001 From: DrAv0011 Date: Sun, 13 Sep 2026 02:46:11 +0200 Subject: [PATCH 30/48] docs: drop the removed ui field primitives, and ore-styled fields are declarations `Input`, `Dropdown` and `Slider` no longer exist in `@bedrock-core/ui`; the four deprecated pages are gone, redirected to their `Form.*` equivalents. The ore-styled components of the same names are `Form.Input` / `Form.Dropdown` / `Form.Slider` under the theme, so they take a `name` and report on submit rather than holding a value and calling `onChange`. `Checkbox` and `Toggle` ask what a boolean becomes on the screen they are drawn on, and the page says which props each host uses. Co-Authored-By: Claude Opus 5 (1M context) --- docs/ore-styled/Checkbox.md | 65 ++++++++----- docs/ore-styled/Dropdown.md | 97 ++++++++----------- docs/ore-styled/Input.md | 83 ++++++---------- docs/ore-styled/Slider.md | 84 ++++++---------- docs/ore-styled/Toggle.md | 60 +++++++----- docs/ore-styled/index.md | 12 +-- docs/ui/components/Form/Form.md | 2 - docs/ui/components/Form/FormDropdown.md | 2 +- docs/ui/components/components.md | 4 - docs/ui/components/deprecated/Dropdown.md | 90 ----------------- docs/ui/components/deprecated/Input.md | 92 ------------------ docs/ui/components/deprecated/Slider.md | 90 ----------------- docs/ui/components/deprecated/_category_.json | 11 --- .../deprecated/modal-field-props.md | 48 --------- src/data/redirects.ts | 12 ++- 15 files changed, 191 insertions(+), 561 deletions(-) delete mode 100644 docs/ui/components/deprecated/Dropdown.md delete mode 100644 docs/ui/components/deprecated/Input.md delete mode 100644 docs/ui/components/deprecated/Slider.md delete mode 100644 docs/ui/components/deprecated/_category_.json delete mode 100644 docs/ui/components/deprecated/modal-field-props.md diff --git a/docs/ore-styled/Checkbox.md b/docs/ore-styled/Checkbox.md index d8e8803..5ecd4ae 100644 --- a/docs/ore-styled/Checkbox.md +++ b/docs/ore-styled/Checkbox.md @@ -1,10 +1,10 @@ --- sidebar_position: 6 -description: "Labeled boolean control." +description: "A themed boolean that draws as a native field on a modal and a press everywhere else." --- # Checkbox -Labeled boolean control. Supports controlled and uncontrolled usage. +A labeled boolean: the box, then the caption. ![Checkbox](/img/ore-styled/Checkbox.png) @@ -17,52 +17,65 @@ import { Checkbox } from '@bedrock-core/ore-styled'; ## Usage ```tsx - console.log(v)} /> + ``` -## Props +## It depends on the screen + +`Checkbox` asks [`useMechanism('Toggle')`](/docs/ui/hooks/useMechanism) what a boolean becomes on the screen it is being drawn on, and draws that. Which props matter follows from the answer: -### Component-Specific props +| Screen | What it becomes | What reaches script | +| --- | --- | --- | +| [``](/docs/ui/components/Form) | a native [`Form.Toggle`](/docs/ui/components/Form/FormToggle) the engine owns | nothing until submit — the value arrives at `values[name]` | +| [``](/docs/ui/components/Screen) | a press that holds its own state | `onChange`, on every press | +| [``](/docs/ui/components/Container) | an item taken and put straight back | `onChange`, on every press | + +So `name` is the modal's prop and required there — a native field with no name has nothing to report under — while `on` and `onChange` only do anything where a press reaches script. You can write all of them and move the control between screens; each host uses the ones it can. + +## Props | Prop | Type | Default | Description | | --- | --- | --- | --- | -| `checked` | `boolean` | — | Controlled value. When provided, the component renders this state and `onChange` is your only way to update it. Omit to use the uncontrolled `defaultChecked` form | -| `defaultChecked` | `boolean` | `false` | Initial state when running uncontrolled | -| `onChange` | `(checked: boolean) => void` | — | Called with the next state every time the player toggles the checkbox | -| `label` | `string` | — | Text rendered next to the checkbox. Omit for a plain box with no label | -| `disabled` | `boolean` | `false` | When `true`, the checkbox renders the disabled texture and ignores presses | - -### Control props +| `name` | `string` | — | Result key on a modal, where it is required; ignored where the press itself is the answer | +| `label` | `string` | — | The caption beside it. Without one, the control is drawn bare | +| `defaultValue` | `boolean` | `false` | Which way it starts | +| `on` | `boolean` | — | Held by the caller instead of by the control. Only where a press reaches script | +| `onChange` | `(on: boolean) => void` | — | Called with the new state, on the hosts where a press reaches script | +| `enabled` | `boolean` | `true` | `false` draws the disabled texture and ignores presses | -Checkbox inherits all standard [control props](/docs/ui/components/control-props). +The theme's textures are defaults, not a lock: `background`, `backgroundHover`, `backgroundPressed`, `backgroundLocked`, `checkedBackground`, `checkedHover` and `checkedLocked` are all accepted and yours wins. Inherits [control props](/docs/ui/components/control-props). ## Examples -### Controlled +### In a modal ```tsx -function NotifySetting() { - const [enabled, setEnabled] = useState(false); - - return ( - - ); -} + apply(values.notify === true)}> + + + ``` -### Uncontrolled +### On a screen of buttons ```tsx - console.log('auto-save', v)} /> +function NotifySetting(): JSX.Element { + const [enabled, setEnabled] = useState(false); + + return ; +} ``` +A press re-presents the screen, so the new state is what the player sees next — the same rule as every other state change on a form. + ### Disabled ```tsx - + ``` ## Notes -- Reach for the uncontrolled form (`defaultChecked` + `onChange`) when the parent doesn't need to read the value every render. -- Pair related checkboxes in a [`Card`](./Card.md) or a `Panel` with `gap` to keep their hitboxes legible. +Pair related checkboxes in a [`Card`](./Card.md), or a `Panel` with `gap`, to keep their hitboxes legible. + +[`Toggle`](./Toggle.md) is the same control with the theme's switch faces and the caption on the left. diff --git a/docs/ore-styled/Dropdown.md b/docs/ore-styled/Dropdown.md index 8fe4c94..afa7fe7 100644 --- a/docs/ore-styled/Dropdown.md +++ b/docs/ore-styled/Dropdown.md @@ -1,14 +1,10 @@ --- -sidebar_position: 12 -description: "Select field with a chevron." +sidebar_position: 10 +description: "A themed dropdown for a modal form, with the options given as a string array." --- # Dropdown -Select field with a chevron. Pressing it opens a modal to choose one of a fixed set of options. Supports controlled and uncontrolled usage. - -:::caution Deprecated -This is the legacy one-modal-per-field pattern. For new screens, use [`Form.Dropdown`](./Form/FormDropdown.md) inside a [`Form`](./Form/Form.md). Still fully supported for existing screens. -::: +A themed dropdown: the current selection with a chevron, and a popup listing the options. ![Dropdown](/img/ore-styled/Dropdown.png) @@ -20,73 +16,64 @@ import { Dropdown } from '@bedrock-core/ore-styled'; ## Usage +Render it inside a [`
    `](/docs/ui/components/Form). The selection arrives in the form's `onSubmit`, keyed by `name`. + ```tsx - console.log(value)} -/> + console.warn(values.difficulty)}> + + + ``` -Built on top of the [`Dropdown`](/docs/ui/components/deprecated/Dropdown) primitive and the [theme](./theme.md) token map. The current selection sits on the left with a chevron on the right, inside the Ore-UI field frame; pressing it opens a single-dropdown modal — confirm commits the choice, cancel keeps the current one. +It is [`Form.Dropdown`](/docs/ui/components/Form/FormDropdown) with the [theme](./theme.md)'s closed-box, popup and option-row textures applied, plus a caption above the box. The ore layer owns the option children: it maps each entry of `options` to a `Form.Option` whose value and label are both that string, which is why `children` is not accepted here. -## Props +:::caution The result is an index +Like the primitive, the submitted value is the selected option's **index** (a `number`), not the string — that is the native modal dropdown's behavior. Read it back as `options[values[name]]`. +::: -### Component-Specific props +## Props | Prop | Type | Default | Description | | --- | --- | --- | --- | -| `options` | `string[]` | — | The selectable options. The face shows the current one; the modal lists them all | -| `value` | `string` | — | Controlled selection — should match one of `options`. When provided, the face reflects it on every render and `onChange` is your only way to update it | -| `defaultValue` | `string` | the first option | Initial selection when running uncontrolled | -| `onChange` | `(value: string, index: number) => void` | — | Called with the chosen option and its index in `options` when the player confirms the modal | -| `onCancel` | `() => void` | — | Called when the player cancels (X / Esc) the modal. The selection is left unchanged | - -### Modal field props +| `name` | `string` | — | Result key — the selected index appears at `values[name]` in the form's `onSubmit` | +| `options` | `string[]` | — | The selectable options; each becomes a `Form.Option` with its value and label set to the string | +| `label` | `string` | — | Caption rendered above the closed box | +| `defaultValue` | `string` | the first option | Initial selection, matched against one of `options` | -Dropdown inherits all [modal field props](/docs/ui/components/deprecated/modal-field-props) (`label`, `title`, `body`, `submitLabel`, `tooltip`) for configuring the modal. - -### Control props - -Dropdown inherits all standard [control props](/docs/ui/components/control-props). Use `enabled={false}` to render the disabled texture (including a dimmed chevron) and make the field inert (no modal opens). +Inherits every prop of [`Form.Dropdown`](/docs/ui/components/Form/FormDropdown) except `children` — the popup background, the option row faces, the option and current-value text styles — with the theme's values as defaults rather than a lock. Through it, [control props](/docs/ui/components/control-props) as well. ## Examples -### Controlled +### Reading the selection back ```tsx -function DifficultySetting() { - const [difficulty, setDifficulty] = useState('Normal'); - - return ( - - - {`Selected: ${difficulty}`} - - ); -} +const MODES = ['Peaceful', 'Easy', 'Normal', 'Hard']; + +
    console.warn(MODES[Number(values.difficulty)])}> + + + ``` -### Uncontrolled +### Disabled ```tsx - console.log(index, value)} -/> + ``` +`enabled={false}` draws the disabled texture, dims the chevron and makes the box inert. + ## Notes -- Keep `options` stable across renders; deriving it inline from changing data can shift indices unexpectedly. -- A controlled `value` should always be one of `options` — an unknown value falls back to the first option on the face. -- For two-state choices use a [`Toggle`](./Toggle.md) instead of a two-item dropdown. +There is no `onChange`: a native modal is atomic, so nothing reaches script while the form is open. + +For the same selection model drawn inline, with no popup, use [`Form.InlineSelect`](/docs/ui/components/Form/FormInlineSelect) — or [`Radio`](./Radio.md) and [`ToggleButtonGroup`](./ToggleButton.md) for its themed forms. + +## Limits + +Modal-only. The engine draws no dropdown on an action form or a container screen, so [`useMechanism('Dropdown')`](/docs/ui/hooks/useMechanism) refuses it there at build, naming the fix. diff --git a/docs/ore-styled/Input.md b/docs/ore-styled/Input.md index 439a5db..626f7c1 100644 --- a/docs/ore-styled/Input.md +++ b/docs/ore-styled/Input.md @@ -1,14 +1,10 @@ --- sidebar_position: 11 -description: "Single-line text field." +description: "A themed single-line text field for a modal form." --- # Input -Single-line text field. Pressing it opens a modal to edit the value. Supports controlled and uncontrolled usage. - -:::caution Deprecated -This is the legacy one-modal-per-field pattern. For new screens, use [`Form.Input`](./Form/FormInput.md) inside a [`Form`](./Form/Form.md). Still fully supported for existing screens. -::: +A themed single-line text field. ![Input](/img/ore-styled/Input.png) @@ -20,75 +16,52 @@ import { Input } from '@bedrock-core/ore-styled'; ## Usage +Render it inside a [`
    `](/docs/ui/components/Form). The value arrives in the form's `onSubmit`, keyed by `name`. + ```tsx - console.log(value)} -/> + console.warn(values.nickname)}> + + + ``` -Built on top of the [`Input`](/docs/ui/components/deprecated/Input) primitive and the [theme](./theme.md) token map. The current value (or the `placeholder`, shown muted) is rendered inside the Ore-UI field frame; pressing it opens a single-field modal — confirm commits the typed value, cancel keeps the current one. +It is [`Form.Input`](/docs/ui/components/Form/FormInput) with the [theme](./theme.md)'s field textures and font applied, plus a caption above the box. The widget itself is the engine's — it is owned by the client while the form is open, and every field's value comes back at once on submit. ## Props -### Component-Specific props - | Prop | Type | Default | Description | | --- | --- | --- | --- | -| `value` | `string` | — | Controlled value. When provided, the face reflects this on every render and `onChange` is your only way to update it | -| `defaultValue` | `string` | `''` | Initial value when running uncontrolled | -| `onChange` | `(value: string) => void` | — | Called with the new text when the player confirms the modal | -| `onCancel` | `() => void` | — | Called when the player cancels (X / Esc) the modal. The value is left unchanged | -| `placeholder` | `string` | — | Shown (muted) on the field face when the value is empty, and inside the modal text field | - -### Modal field props +| `name` | `string` | — | Result key — the value appears at `values[name]` in the form's `onSubmit` | +| `label` | `string` | — | Caption rendered above the field | +| `placeholder` | `string` | — | Text shown inside the field when it is empty | +| `defaultValue` | `string` | `''` | Initial text | -Input inherits all [modal field props](/docs/ui/components/deprecated/modal-field-props) (`label`, `title`, `body`, `submitLabel`, `tooltip`) for configuring the modal. - -### Control props - -Input inherits all standard [control props](/docs/ui/components/control-props). Use `enabled={false}` to render the disabled texture and make the field inert (no modal opens). +Inherits every prop of [`Form.Input`](/docs/ui/components/Form/FormInput) — the font, the scale, the text offsets and the per-state box textures — with the theme's values as defaults rather than a lock: pass one and yours wins. Through it, [control props](/docs/ui/components/control-props) as well. ## Examples -### Controlled +### Two fields in one form ```tsx -function NameField() { - const [name, setName] = useState(''); - - return ( - - - {`Hello, ${name !== '' ? name : 'stranger'}`} - - ); -} -``` - -### Uncontrolled - -```tsx - console.log(v)} /> +
    save(values.nickname, values.motto)}> + + + + ``` ### Disabled ```tsx - + ``` ## Notes -- Give the field a `width` (or let it stretch in a column) so the framed box reads as a field even when empty. -- Provide a `placeholder` so an empty field still reads as editable. -- Set `title` (or rely on `label`) so the modal has a clear heading. +Give the field a `width`, or let it stretch in a column, so the framed box reads as a field even when empty. A `placeholder` keeps an empty one reading as editable. + +There is no `onChange`: a native modal is atomic, so nothing reaches script while the form is open. For a value the screen reacts to immediately, use a press — [`Checkbox`](./Checkbox.md) and [`Toggle`](./Toggle.md) do that on the hosts where a press reaches script. + +## Limits + +Modal-only. The engine draws no text field on an action form or a container screen, so [`useMechanism('Input')`](/docs/ui/hooks/useMechanism) refuses it there at build, naming the fix. diff --git a/docs/ore-styled/Slider.md b/docs/ore-styled/Slider.md index fd6be7e..2f029f3 100644 --- a/docs/ore-styled/Slider.md +++ b/docs/ore-styled/Slider.md @@ -1,14 +1,10 @@ --- -sidebar_position: 13 -description: "Numeric field drawn as a track with a thumb." +sidebar_position: 12 +description: "A themed numeric slider for a modal form." --- # Slider -Numeric field drawn as a track with a thumb. The thumb shows the value's position along the track; pressing it opens a modal to pick a value within the range. Supports controlled and uncontrolled usage. - -:::caution Deprecated -This is the legacy one-modal-per-field pattern. For new screens, use [`Form.Slider`](./Form/FormSlider.md) inside a [`Form`](./Form/Form.md). Still fully supported for existing screens. -::: +A themed numeric slider. ![Slider](/img/ore-styled/Slider.png) @@ -20,74 +16,54 @@ import { Slider } from '@bedrock-core/ore-styled'; ## Usage +Render it inside a [`
    `](/docs/ui/components/Form). The value arrives in the form's `onSubmit`, keyed by `name`. + ```tsx - console.log(value)} -/> + console.warn(values.volume)}> + + + ``` -Built on top of the [`Slider`](/docs/ui/components/deprecated/Slider) primitive and the [theme](./theme.md) token map. The thumb only displays the current value; pressing the field opens a single-slider modal where the value is actually chosen — confirm commits, cancel keeps the current one. +It is [`Form.Slider`](/docs/ui/components/Form/FormSlider) with the [theme](./theme.md)'s track, progress fill and thumb textures applied, plus a caption above it. The widget is the engine's: the player drags it while the form is open, and the value comes back with every other field on submit. ## Props -### Component-Specific props - | Prop | Type | Default | Description | | --- | --- | --- | --- | +| `name` | `string` | — | Result key — the value appears at `values[name]` in the form's `onSubmit` | +| `label` | `string` | — | Caption rendered above the slider | | `min` | `number` | — | Minimum selectable value; the left end of the track | | `max` | `number` | — | Maximum selectable value; the right end of the track | -| `step` | `number` | `1` | Increment between selectable values in the modal | -| `value` | `number` | — | Controlled value. When provided, the thumb reflects it on every render and `onChange` is your only way to update it | -| `defaultValue` | `number` | `min` | Initial value when running uncontrolled | -| `onChange` | `(value: number) => void` | — | Called with the new value when the player confirms the modal | -| `onCancel` | `() => void` | — | Called when the player cancels (X / Esc) the modal. The value is left unchanged | - -### Modal field props - -Slider inherits all [modal field props](/docs/ui/components/deprecated/modal-field-props) (`label`, `title`, `body`, `submitLabel`, `tooltip`) for configuring the modal. +| `step` | `number` | `1` | Increment between selectable values | +| `defaultValue` | `number` | `min` | Initial value | -### Control props - -Slider inherits all standard [control props](/docs/ui/components/control-props). Use `enabled={false}` to render the disabled track/thumb textures and make the field inert (no modal opens). +Inherits every prop of [`Form.Slider`](/docs/ui/components/Form/FormSlider) — the track, progress and thumb textures, `trackHeight`, `thumbWidth` / `thumbHeight` — with the theme's values as defaults rather than a lock. Through it, [control props](/docs/ui/components/control-props) as well. ## Examples -### Controlled +### A settings form ```tsx -function VolumeSetting() { - const [volume, setVolume] = useState(50); - - return ( - - - {`${volume}`} - - ); -} +
    apply(values)}> + + + + ``` -### Uncontrolled +### Disabled ```tsx - console.log(v)} /> + ``` ## Notes -- The thumb only *shows* the value — pair the slider with a `Text` echo if you want the exact number visible without opening the modal. -- Choose a `step` that matches the precision you actually need — players can only land on `min + n * step`. -- Make sure `defaultValue` (or a controlled `value`) sits within `[min, max]` so the thumb stays on the track. +The interactive hitbox of the thumb is a fixed 16 × 16, so keep the visual thumb at its default size unless a mismatch is acceptable — a larger one looks draggable in places it is not. + +There is no `onChange`: a native modal is atomic, so nothing reaches script while the form is open. + +## Limits + +Modal-only. The engine draws no slider on an action form or a container screen, so [`useMechanism('Slider')`](/docs/ui/hooks/useMechanism) refuses it there at build, naming the fix. diff --git a/docs/ore-styled/Toggle.md b/docs/ore-styled/Toggle.md index 88bb200..7b3a654 100644 --- a/docs/ore-styled/Toggle.md +++ b/docs/ore-styled/Toggle.md @@ -1,10 +1,10 @@ --- sidebar_position: 7 -description: "On/off switch." +description: "A themed on/off switch that draws as a native field on a modal and a press everywhere else." --- # Toggle -On/off switch. Supports controlled and uncontrolled usage. +An on/off switch: the caption on the left, the switch pinned to the right — the settings-row reading order. ![Toggle](/img/ore-styled/Toggle.png) @@ -17,48 +17,62 @@ import { Toggle } from '@bedrock-core/ore-styled'; ## Usage ```tsx - console.log(on)} /> + ``` -## Props +## It depends on the screen + +`Toggle` is the same control as [`Checkbox`](./Checkbox.md) with the theme's switch faces: it asks [`useMechanism('Toggle')`](/docs/ui/hooks/useMechanism) what a boolean becomes on the screen it is being drawn on, and draws that. + +| Screen | What it becomes | What reaches script | +| --- | --- | --- | +| [`
    `](/docs/ui/components/Form) | a native [`Form.Toggle`](/docs/ui/components/Form/FormToggle) the engine owns | nothing until submit — the value arrives at `values[name]` | +| [``](/docs/ui/components/Screen) | a press that holds its own state | `onChange`, on every press | +| [``](/docs/ui/components/Container) | an item taken and put straight back | `onChange`, on every press | -### Component-Specific props +`name` is the modal's prop and required there; `on` and `onChange` only do anything where a press reaches script. + +## Props | Prop | Type | Default | Description | | --- | --- | --- | --- | -| `on` | `boolean` | — | Controlled value. When provided, the component renders this state and `onChange` is your only way to update it | -| `defaultOn` | `boolean` | `false` | Initial state when running uncontrolled | -| `onChange` | `(on: boolean) => void` | — | Called with the next state every time the player flips the toggle | -| `disabled` | `boolean` | `false` | When `true`, the toggle renders the disabled texture and ignores presses | +| `name` | `string` | — | Result key on a modal, where it is required; ignored where the press itself is the answer | +| `label` | `string` | — | The caption beside it. Without one, the switch is drawn bare | +| `defaultValue` | `boolean` | `false` | Which way it starts | +| `on` | `boolean` | — | Held by the caller instead of by the control. Only where a press reaches script | +| `onChange` | `(on: boolean) => void` | — | Called with the new state, on the hosts where a press reaches script | +| `enabled` | `boolean` | `true` | `false` draws the disabled texture and ignores presses | -### Control props - -Toggle inherits all standard [control props](/docs/ui/components/control-props). +The theme's switch textures are defaults, not a lock: `background`, `backgroundHover`, `backgroundPressed`, `backgroundLocked`, `checkedBackground`, `checkedHover` and `checkedLocked` are all accepted and yours wins. Inherits [control props](/docs/ui/components/control-props). ## Examples -### Controlled +### A settings form + +```tsx + apply(values)}> + + + + +``` + +### On a screen of buttons ```tsx -function MusicSetting() { +function SoundRow(): JSX.Element { const [on, setOn] = useState(true); - return ( - - {'Music'} - - - ); + return ; } ``` ### Disabled ```tsx - + ``` ## Notes -- Pair `Toggle` with a left-aligned label inside a `Panel` row so the player knows what they're flipping. -- For more than two states, use [`ToggleButtonGroup`](./ToggleButton.md) or [`RadioGroup`](./Radio.md) instead. +Reach for `Toggle` in a settings list, where the caption leads and the switches line up on the right, and for [`Checkbox`](./Checkbox.md) where the box should lead. diff --git a/docs/ore-styled/index.md b/docs/ore-styled/index.md index f488250..2754419 100644 --- a/docs/ore-styled/index.md +++ b/docs/ore-styled/index.md @@ -26,20 +26,20 @@ import { Button, Card, Header, MenuRow, Checkbox, Toggle, RadioGroup, Radio, Tog - [**``**](./Card.md) — container with the standard panel background, padding, and gap, in six variants. - [**`
    `**](./Header.md) — screen header bar: back button, breadcrumb trail, and close button. - [**``**](./MenuRow.md) — browse-list row: thumbnail, title, subtitle, and trailing chevron. -- [**``**](./Checkbox.md) — labeled checkbox, controlled or uncontrolled. -- [**``**](./Toggle.md) — on/off switch. +- [**``**](./Checkbox.md) — labeled boolean: a native field on a modal, a press everywhere else. +- [**``**](./Toggle.md) — the same boolean with the switch faces and the caption on the left. - [**`` / ``**](./Radio.md) — single-choice radio set. - [**`` / ``**](./ToggleButton.md) — segmented button group with single selection. - [**``**](./Divider.md) — horizontal or vertical divider line in three variants. -- [**``**](./Input.md) — single-line text field; pressing it opens the native modal text field. **Deprecated**, see [`Form.Input`](./Form/FormInput.md). -- [**``**](./Dropdown.md) — select field with a chevron; pressing it opens the native modal dropdown. **Deprecated**, see [`Form.Dropdown`](./Form/FormDropdown.md). -- [**``**](./Slider.md) — field drawn as a track + thumb; pressing it opens the native modal slider. **Deprecated**, see [`Form.Slider`](./Form/FormSlider.md). +- [**``**](./Input.md) — themed single-line text field, for use inside a `
    `. +- [**``**](./Dropdown.md) — themed select field with a chevron and a popup, for use inside a ``. +- [**``**](./Slider.md) — themed numeric slider, for use inside a ``. ## Form Atomic modal form — one native `ModalFormData` for the whole screen, all values arriving together on submit. See the [`Form`](./Form/Form.md) page for the full namespace. -- [**``**](./Form/Form.md) — the root component, plus its themed field members: `Form.Toggle`, `Form.Checkbox`, `Form.Radio`, `Form.ToggleButton`, `Form.Slider`, `Form.Dropdown`, `Form.Input`, `Form.Button`. +- [**``**](./Form/Form.md) — the themed root, plus [**`Form.Button`**](./Form/FormButton.md) for its submit and exit actions. The fields themselves are the components above: each asks what it becomes on the screen it is drawn on, so there is no separate themed modal variant. ## Theme diff --git a/docs/ui/components/Form/Form.md b/docs/ui/components/Form/Form.md index 2e6751b..bed5a7a 100644 --- a/docs/ui/components/Form/Form.md +++ b/docs/ui/components/Form/Form.md @@ -6,8 +6,6 @@ description: "Atomic modal form." Atomic modal form. Renders one native `ModalFormData` — every field is shown at once, and nothing comes back until the player presses submit, at which point every value arrives together, keyed by each field's `name`, in `onSubmit`. -The [deprecated](../deprecated/Input.md) `Input`, `Dropdown` and `Slider` components open a separate single-control modal per field. Use `Form` for any screen with more than one field. - ## Import ```tsx diff --git a/docs/ui/components/Form/FormDropdown.md b/docs/ui/components/Form/FormDropdown.md index 2e97b65..a5984a4 100644 --- a/docs/ui/components/Form/FormDropdown.md +++ b/docs/ui/components/Form/FormDropdown.md @@ -26,7 +26,7 @@ import { Form } from '@bedrock-core/ui'; ``` :::caution Result is an index, not a value -`Form.Dropdown` reports the selected option's **index** (a `number`) at `values[name]`, not its `value` string — this is the native modal dropdown's behavior. If you need the string back, map the index into your own options array yourself. This is different from the legacy [`Dropdown`](../deprecated/Dropdown.md), which resolves the index back to a value string for you. +`Form.Dropdown` reports the selected option's **index** (a `number`) at `values[name]`, not its `value` string — this is the native modal dropdown's behavior. If you need the string back, map the index into your own options array yourself. ::: ## Props diff --git a/docs/ui/components/components.md b/docs/ui/components/components.md index 89dbb91..7656e04 100644 --- a/docs/ui/components/components.md +++ b/docs/ui/components/components.md @@ -72,10 +72,6 @@ Only on a container screen. See [Container screens](../guides/container-screens. - [``](./Expect.md) — states which screen a fragment is written for, and fails the build when it lands elsewhere - [``](./Embed.md) — a screen one pack draws into an area another pack's screen reserves -## Deprecated - -[`Input`](./deprecated/Input.md), [`Dropdown`](./deprecated/Dropdown.md) and [`Slider`](./deprecated/Slider.md) are one-modal-per-field components kept until the code removes them; new screens use [``](./Form/Form.md). - ## Shared props - [Control props](./control-props.md) — the flexbox properties, `position={'absolute'}` placement, `visible`, `enabled` and `background`, on every component diff --git a/docs/ui/components/deprecated/Dropdown.md b/docs/ui/components/deprecated/Dropdown.md deleted file mode 100644 index afe7958..0000000 --- a/docs/ui/components/deprecated/Dropdown.md +++ /dev/null @@ -1,90 +0,0 @@ ---- -sidebar_position: 2 -description: "A select field backed by a modal dropdown." ---- -# Dropdown - -A select field backed by a modal dropdown. Pressing it opens a modal to choose one of a fixed set of options. Supports controlled and uncontrolled usage. - -:::caution Deprecated -This is the legacy one-modal-per-field pattern. For new screens, use [`Form.Dropdown`](../Form/FormDropdown.md) inside a [`Form`](../Form/Form.md). Still fully supported for existing screens. -::: - -## Import - -```tsx -import { Dropdown } from '@bedrock-core/ui'; -``` - -## Usage - -```tsx - console.warn(value)} -/> -``` - -## How it works - -`Dropdown` renders as a [`Button`](../Button.md) whose face shows the current selection. Pressing it opens a single-dropdown `ModalFormData`; on confirm the chosen option is committed (internal state + `onChange`), on cancel nothing changes (`onCancel`). Either way the root form re-presents with the current selection. - -The native modal works on item *indices*; `Dropdown` maps the selected index back to the matching `options` entry, so its public API stays value-based like [`Input`](./Input.md). - -## Props - -| Prop | Type | Default | Description | -| --- | --- | --- | --- | -| `options` | `string[]` | — | The selectable options. The face shows the current one; the modal lists them all | -| `value` | `string` | — | Controlled selection — should match one of `options`. When provided, the face reflects it on every render and `onChange` is your only way to update it | -| `defaultValue` | `string` | the first option | Initial selection when running uncontrolled | -| `onChange` | `(value: string, index: number) => void` | — | Called with the chosen option and its index in `options` when the player confirms the modal | -| `onCancel` | `() => void` | — | Called when the player cancels (X / Esc) the modal. The selection is left unchanged | -| `face` | `JSX.Node` | a `Text` showing the current selection | Overrides the content drawn on the button face. Lets a styled wrapper render its own face (e.g. the value plus a chevron) while reusing this component's modal + state logic. This is how [`@bedrock-core/ore-styled`](/docs/ore-styled/Dropdown) builds its themed `Dropdown` | - -### Modal field props - -Dropdown inherits all [modal field props](./modal-field-props.md) (`label`, `title`, `body`, `submitLabel`, `tooltip`) for configuring the modal. - -Inherits [control props](../control-props.md). Use `enabled={false}` to make the field inert (no modal opens). - -## Examples - -### Controlled - -```tsx -function DifficultySetting() { - const [difficulty, setDifficulty] = useState('Normal'); - - return ( - - - {`Selected: ${difficulty}`} - - ); -} -``` - -### Uncontrolled - -```tsx - console.warn(index, value)} -/> -``` - -## Notes - -- Keep `options` stable across renders; deriving it inline from changing data can shift indices unexpectedly. -- A controlled `value` should always be one of `options` — an unknown value falls back to the first option on the face. -- For two-state choices use a [`Toggle`](/docs/ore-styled/Toggle) instead of a two-item dropdown. diff --git a/docs/ui/components/deprecated/Input.md b/docs/ui/components/deprecated/Input.md deleted file mode 100644 index 8c3982a..0000000 --- a/docs/ui/components/deprecated/Input.md +++ /dev/null @@ -1,92 +0,0 @@ ---- -sidebar_position: 1 -description: "A single-line text field." ---- -# Input - -A single-line text field. Pressing it opens a modal to edit the value. Supports controlled and uncontrolled usage. - -:::caution Deprecated -This is the legacy one-modal-per-field pattern. For new screens, use [`Form.Input`](../Form/FormInput.md) inside a [`Form`](../Form/Form.md). Still fully supported for existing screens. -::: - -## Import - -```tsx -import { Input } from '@bedrock-core/ui'; -``` - -## Usage - -```tsx - console.warn(value)} -/> -``` - -## How it works - -Native `ActionFormData` can't take typed input, so `Input` renders as a [`Button`](../Button.md) whose face shows the current value (or the `placeholder` when empty). Pressing it opens a single-field `ModalFormData`; on confirm the typed text is committed (internal state + `onChange`), on cancel nothing changes (`onCancel`). Either way the root form re-presents with the current value. - -This is the unstyled runtime primitive — supply a `background` or compose a styled wrapper for a field-like appearance. - -## Props - -| Prop | Type | Default | Description | -| --- | --- | --- | --- | -| `value` | `string` | — | Controlled value. When provided, the face reflects this on every render and `onChange` is your only way to update it | -| `defaultValue` | `string` | `''` | Initial value when running uncontrolled | -| `onChange` | `(value: string) => void` | — | Called with the new text when the player confirms the modal | -| `onCancel` | `() => void` | — | Called when the player cancels (X / Esc) the modal. The value is left unchanged | -| `placeholder` | `string` | — | Shown on the button face when the value is empty, and inside the modal text field | -| `face` | `JSX.Node` | a `Text` showing the value (or `placeholder` when empty) | Overrides the content drawn on the button face. Lets a styled wrapper render its own face (e.g. colored value text) while reusing this component's modal + state logic. This is how [`@bedrock-core/ore-styled`](/docs/ore-styled/Input) builds its themed `Input` | - -### Modal field props - -Input inherits all [modal field props](./modal-field-props.md) (`label`, `title`, `body`, `submitLabel`, `tooltip`) for configuring the modal. - -Inherits [control props](../control-props.md). Use `enabled={false}` to make the field inert (no modal opens). - -## Examples - -### Controlled - -```tsx -function NameField() { - const [name, setName] = useState(''); - - return ( - - - {`Hello, ${name !== '' ? name : 'stranger'}`} - - ); -} -``` - -### Uncontrolled - -```tsx - console.warn(v)} /> -``` - -### Disabled - -```tsx - -``` - -## Notes - -- Provide a `placeholder` so an empty field still reads as editable. -- Set `title` (or rely on `label`) so the modal has a clear heading. -- Use `value` + `onChange` (controlled) when the value is part of your screen state; reach for `defaultValue` when the field can manage itself. diff --git a/docs/ui/components/deprecated/Slider.md b/docs/ui/components/deprecated/Slider.md deleted file mode 100644 index 8e4e59c..0000000 --- a/docs/ui/components/deprecated/Slider.md +++ /dev/null @@ -1,90 +0,0 @@ ---- -sidebar_position: 3 -description: "A numeric field backed by a modal slider." ---- -# Slider - -A numeric field backed by a modal slider. Pressing it opens a modal to pick a value within a range. Supports controlled and uncontrolled usage. - -:::caution Deprecated -This is the legacy one-modal-per-field pattern. For new screens, use [`Form.Slider`](../Form/FormSlider.md) inside a [`Form`](../Form/Form.md). Still fully supported for existing screens. -::: - -## Import - -```tsx -import { Slider } from '@bedrock-core/ui'; -``` - -## Usage - -```tsx - console.warn(value)} -/> -``` - -## How it works - -`Slider` renders as a [`Button`](../Button.md) whose face shows the current value. Pressing it opens a single-slider `ModalFormData`; on confirm the chosen value is committed (internal state + `onChange`), on cancel nothing changes (`onCancel`). Either way the root form re-presents with the current value. - -## Props - -| Prop | Type | Default | Description | -| --- | --- | --- | --- | -| `min` | `number` | — | Minimum selectable value | -| `max` | `number` | — | Maximum selectable value | -| `step` | `number` | `1` | Increment between selectable values | -| `value` | `number` | — | Controlled value. When provided, the face reflects it on every render and `onChange` is your only way to update it | -| `defaultValue` | `number` | `min` | Initial value when running uncontrolled | -| `onChange` | `(value: number) => void` | — | Called with the new value when the player confirms the modal | -| `onCancel` | `() => void` | — | Called when the player cancels (X / Esc) the modal. The value is left unchanged | -| `face` | `JSX.Node` | a `Text` showing the current value | Overrides the content drawn on the button face. Lets a styled wrapper render its own face (e.g. a track and thumb positioned by the value) while reusing this component's modal + state logic. This is how [`@bedrock-core/ore-styled`](/docs/ore-styled/Slider) builds its themed `Slider` | - -### Modal field props - -Slider inherits all [modal field props](./modal-field-props.md) (`label`, `title`, `body`, `submitLabel`, `tooltip`) for configuring the modal. - -Inherits [control props](../control-props.md). Use `enabled={false}` to make the field inert (no modal opens). - -## Examples - -### Controlled - -```tsx -function VolumeSetting() { - const [volume, setVolume] = useState(50); - - return ( - - - {`Volume: ${volume}%`} - - ); -} -``` - -### Uncontrolled - -```tsx - console.warn(v)} /> -``` - -## Notes - -- Choose a `step` that matches the precision you actually need — players can only land on `min + n * step`. -- Make sure `defaultValue` (or a controlled `value`) sits within `[min, max]`. -- Pair the slider with a `Text` that echoes the value so the current setting stays visible without opening the modal. diff --git a/docs/ui/components/deprecated/_category_.json b/docs/ui/components/deprecated/_category_.json deleted file mode 100644 index 74fd3a2..0000000 --- a/docs/ui/components/deprecated/_category_.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "position": 23, - "label": "Deprecated", - "collapsible": true, - "collapsed": true, - "link": { - "type": "generated-index", - "title": "Deprecated", - "description": "One-modal-per-field components, kept until the code removes them. Use Form.* instead." - } -} diff --git a/docs/ui/components/deprecated/modal-field-props.md b/docs/ui/components/deprecated/modal-field-props.md deleted file mode 100644 index 9472531..0000000 --- a/docs/ui/components/deprecated/modal-field-props.md +++ /dev/null @@ -1,48 +0,0 @@ ---- -sidebar_position: 4 -description: "These props belong to the legacy one-modal-per-field components." ---- -# Modal field props - -:::caution Deprecated -These props belong to the legacy one-modal-per-field components. New [`Form`](../Form/Form.md) fields configure modal chrome differently — there's no per-field `label`/`title`/`body`/`submitLabel`/`tooltip`, since a `Form` has one shared modal and headings are authored as a `Text` node. -::: - -Shared props for the **modal-backed field** components — [`Input`](./Input.md), [`Dropdown`](./Dropdown.md), and [`Slider`](./Slider.md). - -Native `ActionFormData` (what this runtime renders to) can't take typed input, so each of these components is really a [`Button`](../Button.md) that *looks like* a form field. Pressing it opens a single-control `ModalFormData`; when the player confirms, the value is committed and the root form re-presents. These props configure that modal — they do **not** appear on the button face, which always shows the current value (or placeholder). - -`ModalFieldProps` extends [control props](../control-props.md), so every field also supports the full set of layout / visibility / background props. - -## Props - -| Prop | Type | Default | Description | -| --- | --- | --- | --- | -| `label` | `string` | — | Label for the control *inside* the modal. Not shown on the button face | -| `title` | `string` | the `label` | Title of the modal window | -| `body` | `string` | — | Descriptive text shown above the control. `ModalFormData` has no body, so this renders as a leading label line | -| `submitLabel` | `string` | — | Text on the modal's confirm/submit button | -| `tooltip` | `string` | — | Hover tooltip on the modal control | - -## Customizing the face - -Each field also accepts a component-specific `face` prop (`JSX.Node`) that overrides what's drawn on the button face — while the component keeps owning the modal flow and value state. This is the seam styled wrappers build on: run the field controlled (`value` + `onChange`) so you know the current value, then pass a `face` node that renders it however you like. - -```tsx -{`§f${name === '' ? '§7type a name' : name}`}} -/> -``` - -The themed [`@bedrock-core/ore-styled`](/docs/ore-styled) `Input`, `Dropdown`, and `Slider` are exactly this pattern: the chevron and the slider track/thumb are custom `face` nodes. - -## TypeScript - -```tsx -import type { ModalFieldProps } from '@bedrock-core/ui'; -``` - -Handy when building your own styled wrapper around `Input` / `Dropdown` / `Slider`. diff --git a/src/data/redirects.ts b/src/data/redirects.ts index 4d28a1c..245a8e7 100644 --- a/src/data/redirects.ts +++ b/src/data/redirects.ts @@ -68,7 +68,7 @@ export const redirects: { from: string; to: string }[] = [ { from: '/docs/ui/ui-runtime/components/Background', to: '/docs/ui/components/Background' }, { from: '/docs/ui/ui-runtime/components/Button', to: '/docs/ui/components/Button' }, { from: '/docs/ui/ui-runtime/components/Container', to: '/docs/ui/components/Container' }, - { from: '/docs/ui/ui-runtime/components/Dropdown', to: '/docs/ui/components/deprecated/Dropdown' }, + { from: '/docs/ui/ui-runtime/components/Dropdown', to: '/docs/ui/components/Form/FormDropdown' }, { from: '/docs/ui/ui-runtime/components/Form', to: '/docs/ui/components/Form' }, { from: '/docs/ui/ui-runtime/components/Form/FormButton', to: '/docs/ui/components/Form/FormButton' }, { from: '/docs/ui/ui-runtime/components/Form/FormDropdown', to: '/docs/ui/components/Form/FormDropdown' }, @@ -80,16 +80,16 @@ export const redirects: { from: string; to: string }[] = [ { from: '/docs/ui/ui-runtime/components/Fragment', to: '/docs/ui/components/Fragment' }, { from: '/docs/ui/ui-runtime/components/Hotbar', to: '/docs/ui/components/Hotbar' }, { from: '/docs/ui/ui-runtime/components/Image', to: '/docs/ui/components/Image' }, - { from: '/docs/ui/ui-runtime/components/Input', to: '/docs/ui/components/deprecated/Input' }, + { from: '/docs/ui/ui-runtime/components/Input', to: '/docs/ui/components/Form/FormInput' }, { from: '/docs/ui/ui-runtime/components/Panel', to: '/docs/ui/components/Panel' }, { from: '/docs/ui/ui-runtime/components/PlayerInventory', to: '/docs/ui/components/PlayerInventory' }, { from: '/docs/ui/ui-runtime/components/Scroll', to: '/docs/ui/components/Scroll' }, - { from: '/docs/ui/ui-runtime/components/Slider', to: '/docs/ui/components/deprecated/Slider' }, + { from: '/docs/ui/ui-runtime/components/Slider', to: '/docs/ui/components/Form/FormSlider' }, { from: '/docs/ui/ui-runtime/components/Slot', to: '/docs/ui/components/Slot' }, { from: '/docs/ui/ui-runtime/components/SlotGrid', to: '/docs/ui/components/SlotGrid' }, { from: '/docs/ui/ui-runtime/components/Text', to: '/docs/ui/components/Text' }, { from: '/docs/ui/ui-runtime/components/control-props', to: '/docs/ui/components/control-props' }, - { from: '/docs/ui/ui-runtime/components/modal-field-props', to: '/docs/ui/components/deprecated/modal-field-props' }, + { from: '/docs/ui/ui-runtime/components/modal-field-props', to: '/docs/ui/components/Form' }, { from: '/docs/ui/ui-runtime/hooks', to: '/docs/ui/hooks' }, { from: '/docs/ui/ui-runtime/hooks/useContext', to: '/docs/ui/hooks/useContext' }, { from: '/docs/ui/ui-runtime/hooks/useEffect', to: '/docs/ui/hooks/useEffect' }, @@ -109,4 +109,8 @@ export const redirects: { from: string; to: string }[] = [ { from: '/docs/navigation/useRoute', to: '/docs/navigation/useNavigation' }, { from: '/docs/server/api/guides', to: '/docs/guides' }, { from: '/docs/server/api/pages', to: '/docs/navigation/references' }, + { from: '/docs/ui/components/deprecated/Input', to: '/docs/ui/components/Form/FormInput' }, + { from: '/docs/ui/components/deprecated/Dropdown', to: '/docs/ui/components/Form/FormDropdown' }, + { from: '/docs/ui/components/deprecated/Slider', to: '/docs/ui/components/Form/FormSlider' }, + { from: '/docs/ui/components/deprecated/modal-field-props', to: '/docs/ui/components/Form' }, ]; From 990508a636ff2cd56e0cc6b49dca88da8e1ea913 Mon Sep 17 00:00:00 2001 From: DrAv0011 Date: Sun, 13 Sep 2026 03:00:29 +0200 Subject: [PATCH 31/48] docs(ore-styled): one component per host, and the themed Form has one member The themed fields are no longer members of `Form`: `Checkbox`, `Toggle`, `Radio`, `ToggleButtonGroup`, `Slider`, `Dropdown` and `Input` each serve every host they can be drawn on, so the seven `Form.*` pages are gone and each page says which props its host uses. `Radio` and `ToggleButtonGroup` take an options array rather than owning children through context. Adds a page for `Trail` and documents `fieldLabel`, the `to` / `back` links on `Button`, `MenuRow` and `Header`, and the live-text reservations on all three. Co-Authored-By: Claude Opus 5 (1M context) --- docs/ore-styled/Button.md | 28 ++++-- docs/ore-styled/Card.md | 6 +- docs/ore-styled/Checkbox.md | 2 +- docs/ore-styled/Divider.md | 8 +- docs/ore-styled/Dropdown.md | 2 +- docs/ore-styled/Form/Form.md | 104 ++++++++++---------- docs/ore-styled/Form/FormButton.md | 6 +- docs/ore-styled/Form/FormCheckbox.md | 46 --------- docs/ore-styled/Form/FormDropdown.md | 73 -------------- docs/ore-styled/Form/FormInput.md | 55 ----------- docs/ore-styled/Form/FormRadio.md | 83 ---------------- docs/ore-styled/Form/FormSlider.md | 46 --------- docs/ore-styled/Form/FormToggle.md | 56 ----------- docs/ore-styled/Form/FormToggleButton.md | 60 ------------ docs/ore-styled/Form/_category_.json | 2 +- docs/ore-styled/Header.md | 43 ++++++--- docs/ore-styled/Input.md | 2 +- docs/ore-styled/MenuRow.md | 44 +++++---- docs/ore-styled/Radio.md | 112 +++++++++++++--------- docs/ore-styled/Slider.md | 2 +- docs/ore-styled/Toggle.md | 2 +- docs/ore-styled/ToggleButton.md | 116 ++++++++++++++--------- docs/ore-styled/Trail.md | 65 +++++++++++++ docs/ore-styled/index.md | 74 ++++++++++----- docs/ore-styled/theme.md | 12 +-- docs/ui/components/Form/FormDropdown.md | 2 +- docs/ui/components/Form/FormInput.md | 2 +- docs/ui/components/Form/FormSlider.md | 2 +- docs/ui/components/Form/FormToggle.md | 2 +- src/data/redirects.ts | 21 ++-- 30 files changed, 415 insertions(+), 663 deletions(-) delete mode 100644 docs/ore-styled/Form/FormCheckbox.md delete mode 100644 docs/ore-styled/Form/FormDropdown.md delete mode 100644 docs/ore-styled/Form/FormInput.md delete mode 100644 docs/ore-styled/Form/FormRadio.md delete mode 100644 docs/ore-styled/Form/FormSlider.md delete mode 100644 docs/ore-styled/Form/FormToggle.md delete mode 100644 docs/ore-styled/Form/FormToggleButton.md create mode 100644 docs/ore-styled/Trail.md diff --git a/docs/ore-styled/Button.md b/docs/ore-styled/Button.md index 1e785c6..3e39cd7 100644 --- a/docs/ore-styled/Button.md +++ b/docs/ore-styled/Button.md @@ -17,7 +17,7 @@ import { Button } from '@bedrock-core/ore-styled'; ## Usage ```tsx - ``` @@ -26,18 +26,28 @@ When `children` is a string the button automatically wraps it in a `Text` styled ## Props -### Component-Specific props - | Prop | Type | Default | Description | | --- | --- | --- | --- | -| `variant` | `'hero' \| 'primary' \| 'secondary' \| 'contrast' \| 'danger' \| 'realm' \| 'transparent'` | `'primary'` | Selects the texture set and text style applied to the button. `hero` uses the same primary texture but with the `minecraftTen` heading font. `transparent` has no visible shell — useful for icon-only or inline actions that should blend into the background | -| `enabled` | `boolean` | `true` | When `false`, the button renders with the disabled texture and ignores `onPress`. The disabled `textStyle` color is automatically applied to string children | -| `onPress` | `() => void \| Promise` | — | Callback invoked when the player presses the button | -| `children` | `string \| JSX.Node` | — | A string is auto-wrapped in a themed `Text`. Any other node is rendered as-is | +| `variant` | `'hero' \| 'primary' \| 'secondary' \| 'contrast' \| 'danger' \| 'realm' \| 'transparent'` | `'primary'` | The texture set and text style. `hero` is the primary texture with the `minecraftTen` heading font; `transparent` has no shell, for icon-only or inline actions | +| `children` | `string \| JSX.Node` | — | A string is auto-wrapped in a themed `Text`; any other node is rendered as-is | +| `onPress` | `(event: PressEvent) => unknown \| Promise` | — | Runs on a press. Use `to` instead when the press opens another screen | +| `to` | `ScreenKey` | — | The screen this button opens, `:`. A button with one is a [``](/docs/ui/components/Link) | +| `replace` | `boolean` | `false` | With `to`: take the place of the screen this button is on rather than stacking over it | +| `back` | `boolean` | `false` | The way back, in place of `to` — the player's own stack decides where | +| `enabled` | `boolean` | `true` | `false` draws the disabled texture, ignores the press, and applies the disabled text color to string children | + +Inherits [control props](/docs/ui/components/control-props). + +## A press or a destination -### Control props +`onPress` is script: only this realm can run it. `to` and `back` are **data** the build reads off the element, which is what lets a screen of buttons be [described to another addon](/docs/ui/guides/navigation#static-screens) and shown by a realm running none of your script. -Button inherits all standard [control props](/docs/ui/components/control-props). +Reach for `to` whenever the press simply opens a screen, and keep `onPress` for the presses that do something. + +```tsx + + +``` ## Examples diff --git a/docs/ore-styled/Card.md b/docs/ore-styled/Card.md index 3a33ec0..c955416 100644 --- a/docs/ore-styled/Card.md +++ b/docs/ore-styled/Card.md @@ -27,16 +27,12 @@ Cards lay their children out as a column with the theme's standard `gap`. Overri ## Props -### Component-Specific props - | Prop | Type | Default | Description | | --- | --- | --- | --- | | `variant` | `'default' \| 'light' \| 'dark' \| 'raised' \| 'raised-light' \| 'raised-dark'` | `'raised'` | Selects the background texture. The `raised` prefix lifts the card visually above the screen surface. The suffix sets the tint: `light` for a lighter fill, `dark` for a darker fill, or none for the neutral base. `default` is the flat neutral card | | `children` | `JSX.Node` | — | Content rendered inside the card | -### Control props - -Card inherits all standard [control props](/docs/ui/components/control-props). Use them to size the card, override the default padding, or change the flex direction. +Inherits [control props](/docs/ui/components/control-props). Use them to size the card, override the default padding, or change the flex direction. ## Examples diff --git a/docs/ore-styled/Checkbox.md b/docs/ore-styled/Checkbox.md index 5ecd4ae..e0de48e 100644 --- a/docs/ore-styled/Checkbox.md +++ b/docs/ore-styled/Checkbox.md @@ -1,5 +1,5 @@ --- -sidebar_position: 6 +sidebar_position: 8 description: "A themed boolean that draws as a native field on a modal and a press everywhere else." --- # Checkbox diff --git a/docs/ore-styled/Divider.md b/docs/ore-styled/Divider.md index af52031..df21e4b 100644 --- a/docs/ore-styled/Divider.md +++ b/docs/ore-styled/Divider.md @@ -1,5 +1,5 @@ --- -sidebar_position: 10 +sidebar_position: 4 description: "Thin horizontal or vertical separator." --- # Divider @@ -28,16 +28,12 @@ The divider stretches along the cross-axis of its parent. Inside a column `Panel ## Props -### Component-Specific props - | Prop | Type | Default | Description | | --- | --- | --- | --- | | `orientation` | `'horizontal' \| 'vertical'` | `'horizontal'` | Direction of the divider. Horizontal dividers take their width from the container; vertical dividers take their height from the container | | `variant` | `'default' \| 'light' \| 'dark'` | `'default'` | Visual weight. `default` is 2px thick; `light` and `dark` are 1px each | -### Control props - -Divider inherits all standard [control props](/docs/ui/components/control-props). +Inherits [control props](/docs/ui/components/control-props). ## Examples diff --git a/docs/ore-styled/Dropdown.md b/docs/ore-styled/Dropdown.md index afa7fe7..01db639 100644 --- a/docs/ore-styled/Dropdown.md +++ b/docs/ore-styled/Dropdown.md @@ -1,5 +1,5 @@ --- -sidebar_position: 10 +sidebar_position: 13 description: "A themed dropdown for a modal form, with the options given as a string array." --- # Dropdown diff --git a/docs/ore-styled/Form/Form.md b/docs/ore-styled/Form/Form.md index 88e37dd..7dcb647 100644 --- a/docs/ore-styled/Form/Form.md +++ b/docs/ore-styled/Form/Form.md @@ -1,10 +1,10 @@ --- sidebar_position: 1 -description: "Themed modal form." +description: "The themed native modal root, plus the submit and exit buttons this layer styles." --- # Form -Themed modal form. Wraps the [`Form`](/docs/ui/components/Form) primitive with authentic Minecraft textures from the [theme](../theme.md) — same config (`onSubmit`/`onCancel`), a themed field for each runtime field, and a couple of ore-styled-only conveniences. +The themed modal root: the runtime [``](/docs/ui/components/Form) unchanged — the same config, the same `onSubmit` and `onCancel` — with the action buttons this layer styles. ## Import @@ -12,67 +12,69 @@ Themed modal form. Wraps the [`Form`](/docs/ui/components/Form) primitive with a import { Form } from '@bedrock-core/ore-styled'; ``` -`Form` is a namespace object, mirroring the runtime's shape so a screen switches styled ↔ unstyled by changing only the import: +## The fields are not members of it -- [**`Form`**](/docs/ui/components/Form#props) — the root component; unchanged from the primitive. -- [**`Form.Toggle`**](./FormToggle.md) — themed on/off switch, settings-row style. -- [**`Form.Checkbox`**](./FormCheckbox.md) — themed checkbox, same underlying control as `Form.Toggle`. -- [**`Form.Radio`**](./FormRadio.md) — themed single-select radio group. -- [**`Form.ToggleButton`**](./FormToggleButton.md) — themed single-select segmented group. -- [**`Form.Slider`**](./FormSlider.md) — themed numeric slider. -- [**`Form.Dropdown`**](./FormDropdown.md) — themed select-with-popup field. -- [**`Form.Input`**](./FormInput.md) — themed text field. -- [**`Form.Button`**](./FormButton.md) — themed submit/exit action button. +`Form` has exactly one member, [`Form.Button`](./FormButton.md). The fields are separate components, imported by their own names: -:::note -ore-styled's `Form` does **not** re-export `InlineSelect`/`Option`. Use `Form.Radio` and `Form.ToggleButton` instead. -::: +```tsx +import { Checkbox, Dropdown, Form, Input, Radio, Slider, Toggle, ToggleButtonGroup } from '@bedrock-core/ore-styled'; +``` + +Each of them serves every host it can be drawn on. Inside a `` they become the engine's own fields; outside one they become whatever that screen offers, or say so at build. That is why there is no themed modal variant of each — one component covers both, and a field written for a settings modal moves to a screen of buttons without being rewritten. + +## Usage + +```tsx + apply(values)} onCancel={() => back(player)}> + + + + + + + + + + + + +``` + +## Props -Every field here accepts a `label?: string` that the runtime primitives don't have. The caption is composed for you: above the control for `Input`/`Dropdown`/`Slider`/`Radio`/`ToggleButton`, beside it as a settings row for `Toggle`/`Checkbox`. +| Prop | Type | Default | Description | +| --- | --- | --- | --- | +| `onSubmit` | `(event: SubmitEvent) => void` | — | Called once when the player submits, with every field's value keyed by its `name` | +| `onCancel` | `(event: UiEvent) => void` | — | Called when the player dismisses the modal | +| `children` | `JSX.Node` | — | The fields, the decoration and the action buttons, in any order | + +Unchanged from the primitive — see the runtime [`
    `](/docs/ui/components/Form) for the full contract. ## Rules -Unchanged from the primitive — see the runtime [`Form`'s Rules & Restrictions](/docs/ui/components/Form#rules): exactly one `Form.Button type="submit"` required, at most one `type="exit"`, no nesting, no plain `Button` inside. +The same ones the primitive enforces, as a build error rather than a warning: exactly one `Form.Button type="submit"` is required, at most one `type="exit"`, no nested ``, and no plain `
    + ); diff --git a/docs/navigation/index.md b/docs/navigation/index.md index eb5178e..97078f3 100644 --- a/docs/navigation/index.md +++ b/docs/navigation/index.md @@ -55,8 +55,8 @@ function Row(): JSX.Element { return ( - - + + ); } diff --git a/docs/navigation/useNavigation.md b/docs/navigation/useNavigation.md index 47b9e4c..74fce18 100644 --- a/docs/navigation/useNavigation.md +++ b/docs/navigation/useNavigation.md @@ -39,7 +39,7 @@ function Footer(): JSX.Element { const { back, canGoBack } = useNavigation(); return ( - ); @@ -56,8 +56,8 @@ function Menu(): JSX.Element { return ( - - + + ); } @@ -77,7 +77,7 @@ function Breadcrumb(): JSX.Element { ## Notes -Prefer [``](/docs/ui/components/controls/Link) over a `navigate()` in an `onPress` when the destination is fixed. A link's target is data the build reads off the tree, which is what lets the screen be described to another addon; a closure is script only this realm can run. +Prefer [``](/docs/ui/components/controls/Link) over a `navigate()` in a button's `action` when the destination is fixed. A link's target is data the build reads off the tree, which is what lets the screen be described to another addon; a closure is script only this realm can run. `canGoBack` and `history` are read at render time. A form cannot change while it is open, so they are a snapshot of the moment the screen was presented — which is the same moment everything else on it was decided. diff --git a/docs/ore-styled/Button.md b/docs/ore-styled/Button.md index 4907a00..10abc33 100644 --- a/docs/ore-styled/Button.md +++ b/docs/ore-styled/Button.md @@ -17,7 +17,7 @@ import { Button } from '@bedrock-core/ore-styled'; ## Usage ```tsx - ``` @@ -28,9 +28,9 @@ When `children` is a string the button automatically wraps it in a `Text` styled | Prop | Type | Default | Description | | --- | --- | --- | --- | -| `variant` | `'hero' \| 'primary' \| 'secondary' \| 'contrast' \| 'danger' \| 'realm' \| 'transparent'` | `'primary'` | The texture set and text style. `hero` is the primary texture with the `minecraftTen` heading font; `transparent` has no shell, for icon-only or inline actions | +| `variant` | `'hero' \| 'primary' \| 'secondary' \| 'contrast' \| 'danger' \| 'realm' \| 'transparent'` | `'primary'`, or `'secondary'` for `action={'exit'}` | The texture set and text style. `hero` is the primary texture with the `minecraftTen` heading font; `transparent` has no shell, for icon-only or inline actions | | `children` | `string \| JSX.Node` | — | A string is auto-wrapped in a themed `Text`; any other node is rendered as-is | -| `onPress` | `(event: PressEvent) => unknown \| Promise` | — | Runs on a press. Use `to` instead when the press opens another screen | +| `action` | `(event: PressEvent) => unknown \| Promise` \| `'submit'` \| `'exit'` | — | What the press does: a handler, or a form's own two actions. Use `to` instead when the press opens another screen | | `to` | `ScreenKey` | — | The screen this button opens, `:`. A button with one is a [``](/docs/ui/components/controls/Link) | | `replace` | `boolean` | `false` | With `to`: take the place of the screen this button is on rather than stacking over it | | `back` | `boolean` | `false` | The way back, in place of `to` — the player's own stack decides where | @@ -38,11 +38,24 @@ When `children` is a string the button automatically wraps it in a `Text` styled Inherits [control props](/docs/ui/components/control-props). +## A form's two actions + +Inside a [``](/docs/ui/components/roots/Form) a button is the form's own control rather than a handler: `action={'submit'}` submits and `action={'exit'}` dismisses. Exactly one submit is required, at most one exit beside it. + +```tsx + + + + +``` + +Keep the default variants — primary for the submit, secondary for the exit — unless there is a reason to deviate, such as a `danger` exit when cancelling discards real progress. And give the submit an actionable caption: "Save", not "Submit". + ## A press or a destination -`onPress` is script: only this realm can run it. `to` and `back` are **data** the build reads off the element, which is what lets a screen of buttons be [described to another addon](/docs/ui/guides/navigation#static-screens) and shown by a realm running none of your script. +`action` as a handler is script: only this realm can run it. `to` and `back` are **data** the build reads off the element, which is what lets a screen of buttons be [described to another addon](/docs/ui/guides/navigation#static-screens) and shown by a realm running none of your script. -Reach for `to` whenever the press simply opens a screen, and keep `onPress` for the presses that do something. +Reach for `to` whenever the press simply opens a screen, and keep a handler for the presses that do something. ```tsx @@ -55,13 +68,13 @@ Reach for `to` whenever the press simply opens a screen, and keep `onPress` for ```tsx - - - - - - - + + + + + + + ``` @@ -76,7 +89,7 @@ Reach for `to` whenever the press simply opens a screen, and keep `onPress` for ### Custom children ```tsx - ``` diff --git a/docs/ore-styled/Card.md b/docs/ore-styled/Card.md index b1a516b..448e3ec 100644 --- a/docs/ore-styled/Card.md +++ b/docs/ore-styled/Card.md @@ -80,8 +80,8 @@ Inherits [control props](/docs/ui/components/control-props). Use them to size th {'§lConfirm purchase'} {'Spend 32 emeralds?'} - - + + ``` diff --git a/docs/ore-styled/Checkbox.md b/docs/ore-styled/Checkbox.md index 07c5b9d..349c94c 100644 --- a/docs/ore-styled/Checkbox.md +++ b/docs/ore-styled/Checkbox.md @@ -26,7 +26,7 @@ import { Checkbox } from '@bedrock-core/ore-styled'; | Screen | What it becomes | What reaches script | | --- | --- | --- | -| [``](/docs/ui/components/Form) | a native [`Form.Toggle`](/docs/ui/components/Form/FormToggle) the engine owns | nothing until submit — the value arrives at `values[name]` | +| [``](/docs/ui/components/roots/Form) | a native [`Toggle`](/docs/ui/components/controls/Toggle) the engine owns | nothing until submit — the value arrives at `values[name]` | | [``](/docs/ui/components/roots/Screen) | a press that holds its own state | `onChange`, on every press | | [``](/docs/ui/components/roots/Container) | an item taken and put straight back | `onChange`, on every press | @@ -52,7 +52,7 @@ The theme's textures are defaults, not a lock: `background`, `backgroundHover`, ```tsx apply(values.notify === true)}> - + ``` diff --git a/docs/ore-styled/Dropdown.md b/docs/ore-styled/Dropdown.md index 01db639..f1f6cd1 100644 --- a/docs/ore-styled/Dropdown.md +++ b/docs/ore-styled/Dropdown.md @@ -16,7 +16,7 @@ import { Dropdown } from '@bedrock-core/ore-styled'; ## Usage -Render it inside a [`
    `](/docs/ui/components/Form). The selection arrives in the form's `onSubmit`, keyed by `name`. +Render it inside a [``](/docs/ui/components/roots/Form). The selection arrives in the form's `onSubmit`, keyed by `name`. ```tsx console.warn(values.difficulty)}> @@ -26,11 +26,11 @@ Render it inside a [``](/docs/ui/components/Form). The selection arrives i options={['Peaceful', 'Easy', 'Normal', 'Hard']} defaultValue={'Normal'} /> - + ``` -It is [`Form.Dropdown`](/docs/ui/components/Form/FormDropdown) with the [theme](./theme.md)'s closed-box, popup and option-row textures applied, plus a caption above the box. The ore layer owns the option children: it maps each entry of `options` to a `Form.Option` whose value and label are both that string, which is why `children` is not accepted here. +It is [`Dropdown`](/docs/ui/components/fields/Dropdown) with the [theme](./theme.md)'s closed-box, popup and option-row textures applied, plus a caption above the box. The ore layer owns the option children: it maps each entry of `options` to a `Option` whose value and label are both that string, which is why `children` is not accepted here. :::caution The result is an index Like the primitive, the submitted value is the selected option's **index** (a `number`), not the string — that is the native modal dropdown's behavior. Read it back as `options[values[name]]`. @@ -41,11 +41,11 @@ Like the primitive, the submitted value is the selected option's **index** (a `n | Prop | Type | Default | Description | | --- | --- | --- | --- | | `name` | `string` | — | Result key — the selected index appears at `values[name]` in the form's `onSubmit` | -| `options` | `string[]` | — | The selectable options; each becomes a `Form.Option` with its value and label set to the string | +| `options` | `string[]` | — | The selectable options; each becomes a `Option` with its value and label set to the string | | `label` | `string` | — | Caption rendered above the closed box | | `defaultValue` | `string` | the first option | Initial selection, matched against one of `options` | -Inherits every prop of [`Form.Dropdown`](/docs/ui/components/Form/FormDropdown) except `children` — the popup background, the option row faces, the option and current-value text styles — with the theme's values as defaults rather than a lock. Through it, [control props](/docs/ui/components/control-props) as well. +Inherits every prop of [`Dropdown`](/docs/ui/components/fields/Dropdown) except `children` — the popup background, the option row faces, the option and current-value text styles — with the theme's values as defaults rather than a lock. Through it, [control props](/docs/ui/components/control-props) as well. ## Examples @@ -56,7 +56,7 @@ const MODES = ['Peaceful', 'Easy', 'Normal', 'Hard'];
    console.warn(MODES[Number(values.difficulty)])}> - + ``` @@ -72,7 +72,7 @@ const MODES = ['Peaceful', 'Easy', 'Normal', 'Hard']; There is no `onChange`: a native modal is atomic, so nothing reaches script while the form is open. -For the same selection model drawn inline, with no popup, use [`Form.InlineSelect`](/docs/ui/components/Form/FormInlineSelect) — or [`Radio`](./Radio.md) and [`ToggleButtonGroup`](./ToggleButton.md) for its themed forms. +For the same selection model drawn inline, with no popup, use [`Select`](/docs/ui/components/controls/Select) — or [`Radio`](./Radio.md) and [`ToggleButtonGroup`](./ToggleButton.md) for its themed forms. ## Limits diff --git a/docs/ore-styled/Form/Form.md b/docs/ore-styled/Form/Form.md deleted file mode 100644 index 7dcb647..0000000 --- a/docs/ore-styled/Form/Form.md +++ /dev/null @@ -1,80 +0,0 @@ ---- -sidebar_position: 1 -description: "The themed native modal root, plus the submit and exit buttons this layer styles." ---- -# Form - -The themed modal root: the runtime [`
    `](/docs/ui/components/Form) unchanged — the same config, the same `onSubmit` and `onCancel` — with the action buttons this layer styles. - -## Import - -```tsx -import { Form } from '@bedrock-core/ore-styled'; -``` - -## The fields are not members of it - -`Form` has exactly one member, [`Form.Button`](./FormButton.md). The fields are separate components, imported by their own names: - -```tsx -import { Checkbox, Dropdown, Form, Input, Radio, Slider, Toggle, ToggleButtonGroup } from '@bedrock-core/ore-styled'; -``` - -Each of them serves every host it can be drawn on. Inside a `` they become the engine's own fields; outside one they become whatever that screen offers, or say so at build. That is why there is no themed modal variant of each — one component covers both, and a field written for a settings modal moves to a screen of buttons without being rewritten. - -## Usage - -```tsx - apply(values)} onCancel={() => back(player)}> - - - - - - - - - - - - -``` - -## Props - -| Prop | Type | Default | Description | -| --- | --- | --- | --- | -| `onSubmit` | `(event: SubmitEvent) => void` | — | Called once when the player submits, with every field's value keyed by its `name` | -| `onCancel` | `(event: UiEvent) => void` | — | Called when the player dismisses the modal | -| `children` | `JSX.Node` | — | The fields, the decoration and the action buttons, in any order | - -Unchanged from the primitive — see the runtime [`
    `](/docs/ui/components/Form) for the full contract. - -## Rules - -The same ones the primitive enforces, as a build error rather than a warning: exactly one `Form.Button type="submit"` is required, at most one `type="exit"`, no nested ``, and no plain `
    ``` -It is [`Form.Input`](/docs/ui/components/Form/FormInput) with the [theme](./theme.md)'s field textures and font applied, plus a caption above the box. The widget itself is the engine's — it is owned by the client while the form is open, and every field's value comes back at once on submit. +It is [`Input`](/docs/ui/components/fields/Input) with the [theme](./theme.md)'s field textures and font applied, plus a caption above the box. The widget itself is the engine's — it is owned by the client while the form is open, and every field's value comes back at once on submit. ## Props @@ -36,7 +36,7 @@ It is [`Form.Input`](/docs/ui/components/Form/FormInput) with the [theme](./them | `placeholder` | `string` | — | Text shown inside the field when it is empty | | `defaultValue` | `string` | `''` | Initial text | -Inherits every prop of [`Form.Input`](/docs/ui/components/Form/FormInput) — the font, the scale, the text offsets and the per-state box textures — with the theme's values as defaults rather than a lock: pass one and yours wins. Through it, [control props](/docs/ui/components/control-props) as well. +Inherits every prop of [`Input`](/docs/ui/components/fields/Input) — the font, the scale, the text offsets and the per-state box textures — with the theme's values as defaults rather than a lock: pass one and yours wins. Through it, [control props](/docs/ui/components/control-props) as well. ## Examples @@ -46,7 +46,7 @@ Inherits every prop of [`Form.Input`](/docs/ui/components/Form/FormInput) — th
    save(values.nickname, values.motto)}> - + ``` diff --git a/docs/ore-styled/Radio.md b/docs/ore-styled/Radio.md index 23a124e..5346b56 100644 --- a/docs/ore-styled/Radio.md +++ b/docs/ore-styled/Radio.md @@ -28,7 +28,7 @@ import { Radio } from '@bedrock-core/ore-styled'; /> ``` -The options are an array, not children — this layer owns them and maps each entry to a `Form.Option`, so a caller-supplied child could only fight the array. +The options are an array, not children — this layer owns them and maps each entry to a `Option`, so a caller-supplied child could only fight the array. ## It depends on the screen @@ -36,7 +36,7 @@ The options are an array, not children — this layer owns them and maps each en | Screen | What it becomes | What reaches script | | --- | --- | --- | -| [`
    `](/docs/ui/components/Form) | the engine's own [inline select](/docs/ui/components/Form/FormInlineSelect) | nothing until submit — the chosen option's **index** arrives at `values[name]` | +| [``](/docs/ui/components/roots/Form) | the engine's own [inline select](/docs/ui/components/controls/Select) | nothing until submit — the chosen option's **index** arrives at `values[name]` | | [``](/docs/ui/components/roots/Screen) | a button per row | `onChange`, with the chosen **value** | | [``](/docs/ui/components/roots/Container) | a row whose press is an item taken and put back | `onChange`, with the chosen **value** | @@ -65,7 +65,7 @@ interface RadioOption { } ``` -Inherits every prop of [`Form.InlineSelect`](/docs/ui/components/Form/FormInlineSelect) except `children` — the bullet glyphs per state, their size, the option row faces and the label style — with the theme's values as defaults. Row surfaces default to nothing: the bullet carries the look. Through it, [control props](/docs/ui/components/control-props) as well. +Inherits every prop of [`Select`](/docs/ui/components/controls/Select) except `children` — the bullet glyphs per state, their size, the option row faces and the label style — with the theme's values as defaults. Row surfaces default to nothing: the bullet carries the look. Through it, [control props](/docs/ui/components/control-props) as well. ## Examples @@ -76,7 +76,7 @@ const TEAMS = [{ value: 'red', label: 'Red' }, { value: 'blue', label: 'Blue' }] join(TEAMS[Number(values.team)].value)}> - + ``` diff --git a/docs/ore-styled/Slider.md b/docs/ore-styled/Slider.md index 03b5dc8..de594fe 100644 --- a/docs/ore-styled/Slider.md +++ b/docs/ore-styled/Slider.md @@ -16,16 +16,16 @@ import { Slider } from '@bedrock-core/ore-styled'; ## Usage -Render it inside a [`
    `](/docs/ui/components/Form). The value arrives in the form's `onSubmit`, keyed by `name`. +Render it inside a [``](/docs/ui/components/roots/Form). The value arrives in the form's `onSubmit`, keyed by `name`. ```tsx console.warn(values.volume)}> - + ``` -It is [`Form.Slider`](/docs/ui/components/Form/FormSlider) with the [theme](./theme.md)'s track, progress fill and thumb textures applied, plus a caption above it. The widget is the engine's: the player drags it while the form is open, and the value comes back with every other field on submit. +It is [`Slider`](/docs/ui/components/fields/Slider) with the [theme](./theme.md)'s track, progress fill and thumb textures applied, plus a caption above it. The widget is the engine's: the player drags it while the form is open, and the value comes back with every other field on submit. ## Props @@ -38,7 +38,7 @@ It is [`Form.Slider`](/docs/ui/components/Form/FormSlider) with the [theme](./th | `step` | `number` | `1` | Increment between selectable values | | `defaultValue` | `number` | `min` | Initial value | -Inherits every prop of [`Form.Slider`](/docs/ui/components/Form/FormSlider) — the track, progress and thumb textures, `trackHeight`, `thumbWidth` / `thumbHeight` — with the theme's values as defaults rather than a lock. Through it, [control props](/docs/ui/components/control-props) as well. +Inherits every prop of [`Slider`](/docs/ui/components/fields/Slider) — the track, progress and thumb textures, `trackHeight`, `thumbWidth` / `thumbHeight` — with the theme's values as defaults rather than a lock. Through it, [control props](/docs/ui/components/control-props) as well. ## Examples @@ -48,7 +48,7 @@ Inherits every prop of [`Form.Slider`](/docs/ui/components/Form/FormSlider) —
    apply(values)}> - + ``` diff --git a/docs/ore-styled/Toggle.md b/docs/ore-styled/Toggle.md index d37041c..4d94992 100644 --- a/docs/ore-styled/Toggle.md +++ b/docs/ore-styled/Toggle.md @@ -26,7 +26,7 @@ import { Toggle } from '@bedrock-core/ore-styled'; | Screen | What it becomes | What reaches script | | --- | --- | --- | -| [`
    `](/docs/ui/components/Form) | a native [`Form.Toggle`](/docs/ui/components/Form/FormToggle) the engine owns | nothing until submit — the value arrives at `values[name]` | +| [``](/docs/ui/components/roots/Form) | a native [`Toggle`](/docs/ui/components/controls/Toggle) the engine owns | nothing until submit — the value arrives at `values[name]` | | [``](/docs/ui/components/roots/Screen) | a press that holds its own state | `onChange`, on every press | | [``](/docs/ui/components/roots/Container) | an item taken and put straight back | `onChange`, on every press | @@ -53,7 +53,7 @@ The theme's switch textures are defaults, not a lock: `background`, `backgroundH apply(values)}> - + ``` diff --git a/docs/ore-styled/ToggleButton.md b/docs/ore-styled/ToggleButton.md index 7aaaf98..691c88a 100644 --- a/docs/ore-styled/ToggleButton.md +++ b/docs/ore-styled/ToggleButton.md @@ -37,7 +37,7 @@ The same choice a [`Radio`](./Radio.md) makes, in the shape a segmented control | Screen | What it becomes | What reaches script | | --- | --- | --- | -| [`
    `](/docs/ui/components/Form) | the engine's own [inline select](/docs/ui/components/Form/FormInlineSelect) | nothing until submit — the chosen option's **index** arrives at `values[name]` | +| [``](/docs/ui/components/roots/Form) | the engine's own [inline select](/docs/ui/components/controls/Select) | nothing until submit — the chosen option's **index** arrives at `values[name]` | | [``](/docs/ui/components/roots/Screen) | a button per segment | `onChange`, with the chosen **value** | | [``](/docs/ui/components/roots/Container) | a segment whose press is an item taken and put back | `onChange`, with the chosen **value** | @@ -64,7 +64,7 @@ interface ToggleButtonOption { } ``` -Inherits every prop of [`Form.InlineSelect`](/docs/ui/components/Form/FormInlineSelect) except `children`, with the theme's segment faces and text styles as defaults. Segments are glyph-less by default; pass a `bullet` to opt into one and the primitive's per-state fallbacks apply. Through it, [control props](/docs/ui/components/control-props) as well. +Inherits every prop of [`Select`](/docs/ui/components/controls/Select) except `children`, with the theme's segment faces and text styles as defaults. Segments are glyph-less by default; pass a `bullet` to opt into one and the primitive's per-state fallbacks apply. Through it, [control props](/docs/ui/components/control-props) as well. ## Examples @@ -79,7 +79,7 @@ const MODES = [ setMode(MODES[Number(values.difficulty)].value)}> - + ``` diff --git a/docs/ore-styled/index.md b/docs/ore-styled/index.md index 7d918ce..5f44dc5 100644 --- a/docs/ore-styled/index.md +++ b/docs/ore-styled/index.md @@ -27,14 +27,14 @@ No extra resource pack: the theme's textures live in the same [render pack](/doc ## Import ```tsx -import { Button, Card, Checkbox, Divider, Dropdown, Form, Header, Input, MenuRow, Radio, Slider, Toggle, ToggleButtonGroup, Trail } from '@bedrock-core/ore-styled'; +import { Button, Card, Checkbox, Divider, Dropdown, Header, Input, MenuRow, Radio, Slider, Toggle, ToggleButtonGroup, Trail } from '@bedrock-core/ore-styled'; ``` ## One component per host -A field here is written once and serves every screen it can be drawn on. [`Checkbox`](./Checkbox.md), [`Toggle`](./Toggle.md), [`Radio`](./Radio.md) and [`ToggleButtonGroup`](./ToggleButton.md) ask [`useMechanism`](/docs/ui/hooks/useMechanism) what they become: the engine's own field inside a [`
    `](./Form/Form.md), a press on a screen of buttons or a container screen. A screen that can draw neither refuses them at build, in that host's own words. +A field here is written once and serves every screen it can be drawn on. [`Checkbox`](./Checkbox.md), [`Toggle`](./Toggle.md), [`Radio`](./Radio.md) and [`ToggleButtonGroup`](./ToggleButton.md) ask [`useMechanism`](/docs/ui/hooks/useMechanism) what they become: the engine's own field inside a [``](/docs/ui/components/roots/Form), a press on a screen of buttons or a container screen. A screen that can draw neither refuses them at build, in that host's own words. -So there is no themed modal variant of each field, and `Form` has one member — its [action button](./Form/FormButton.md). [Input](./Input.md), [Dropdown](./Dropdown.md) and [Slider](./Slider.md) are the exception: the engine draws no text field, popup or slider outside a modal, so those three are modal-only. +So there is no themed modal variant of each field, and no themed modal root: a submit is ` diff --git a/docs/ui/api/errors.md b/docs/ui/api/errors.md index 4b8b8fe..5c4184d 100644 --- a/docs/ui/api/errors.md +++ b/docs/ui/api/errors.md @@ -28,7 +28,7 @@ Two things produce a registration: the [`ui-compiler` filter](/docs/filters/ui-c The tree has no host root, or a root below its root. -A screen's root names its [host](../guides/hosts.md) — [``](../components/roots/Screen.md), [``](../components/Form/Form.md) or [``](../components/roots/Container.md) — and there is no default, so a tree that starts with a `Panel`, a themed card, or two elements side by side has no screen to be. Providers and fragments above the root are looked through. +A screen's root names its [host](../guides/hosts.md) — [``](../components/roots/Screen.md), [``](../components/roots/Form.md) or [``](../components/roots/Container.md) — and there is no default, so a tree that starts with a `Panel`, a themed card, or two elements side by side has no screen to be. Providers and fragments above the root are looked through. It is also what a component throws when it asks [`useMechanism`](../hooks/useMechanism.md) and nothing above it names a host at all. diff --git a/docs/ui/api/render.md b/docs/ui/api/render.md index 9bfb711..0db6092 100644 --- a/docs/ui/api/render.md +++ b/docs/ui/api/render.md @@ -22,7 +22,7 @@ function render(root: JSX.Element | FunctionComponent, player: Player, options?: | Parameter | Type | Default | Description | | --- | --- | --- | --- | -| `root` | `FunctionComponent \| JSX.Element` | — | The screen: a component or element whose root is [``](../components/roots/Screen.md) or [``](../components/Form/Form.md) | +| `root` | `FunctionComponent \| JSX.Element` | — | The screen: a component or element whose root is [``](../components/roots/Screen.md) or [``](../components/roots/Form.md) | | `player` | `Player` | — | Who sees it | | `options` | `RenderOptions` | `{}` | See below | diff --git a/docs/ui/compiler/index.md b/docs/ui/compiler/index.md index bf5efa6..c968686 100644 --- a/docs/ui/compiler/index.md +++ b/docs/ui/compiler/index.md @@ -28,7 +28,7 @@ Which host a screen compiles for is decided by its root element, and there is no **One geometry** — the layout pass owns every `size`, `offset`, `anchor_from` and `anchor_to`, and the host pass is diffed against it after it emits. A host can replace what a control is; it can never move it, so a mechanism cannot quietly break a layout that was signed off. -**A capability model with names** — each host declares what every kind of component becomes on it. A `` outside a ``, a `` outside a container screen: refused at build, by name, in that host's own words, instead of drawn inert. +**A capability model with names** — each host declares what every kind of component becomes on it. A `` outside a ``, a `` outside a container screen: refused at build, by name, in that host's own words, instead of drawn inert. **A drawable document with no host behind it** — the face pass produces a complete screen on its own. That is what the static rules run over, what the [gallery](/docs/filters/ui-compiler#the-gallery) shows, and why nothing hidden can evaluate a binding that is not there. diff --git a/docs/ui/components/Form/Form.md b/docs/ui/components/Form/Form.md deleted file mode 100644 index 2160333..0000000 --- a/docs/ui/components/Form/Form.md +++ /dev/null @@ -1,68 +0,0 @@ ---- -sidebar_position: 1 -description: "Atomic modal form." ---- -# Form - -Atomic modal form. Renders one native `ModalFormData` — every field is shown at once, and nothing comes back until the player presses submit, at which point every value arrives together, keyed by each field's `name`, in `onSubmit`. - -## Import - -```tsx -import { Form } from '@bedrock-core/ui'; -``` - -`Form` is a namespace object: the root `` component plus its field members. - -- [**`Form`**](#props) — the root component; wraps the whole modal. -- [**`Form.Toggle`**](./FormToggle.md) — boolean on/off field. -- [**`Form.Slider`**](./FormSlider.md) — numeric field within a range. -- [**`Form.Dropdown`**](./FormDropdown.md) — select one of a fixed set of options from a popup. -- [**`Form.InlineSelect`**](./FormInlineSelect.md) — same selection model as `Form.Dropdown`, rendered inline with no popup. -- [**`Form.Option`**](./FormOption.md) — one selectable entry, used as a child of `Form.Dropdown` or `Form.InlineSelect`. -- [**`Form.Input`**](./FormInput.md) — single-line text field. -- [**`Form.Button`**](./FormButton.md) — the form's submit/exit action buttons. - -## How it works - -Decorative nodes — `Text`, `Image`, `Panel`, `Card`, and so on — render fine inside a `Form`. There is no `title`/`body` prop on the modal itself — author a heading as a `Text` node instead. - -Values only arrive once, in `onSubmit`, keyed by each field's `name`: - -```tsx - { v.sound; v.volume; }}> - {'Settings'} - - - - - - - - - -``` - -## Props - -| Prop | Type | Default | Description | -| --- | --- | --- | --- | -| `onSubmit` | `(event: SubmitEvent) => void` | — | Called once when the player presses the submit button. `event.values` holds every field's value keyed by its `name` (`FormValues = Record`, where `ModalValue = string \| number \| boolean \| undefined`), and `event.player` is who submitted. Destructure it: `onSubmit={({ values }) => …}` | -| `onCancel` | `(event: UiEvent) => void` | — | Called when the player dismisses the modal — the X button, Esc, or a `Form.Button type="exit"`. `event.player` is who dismissed it | -| `children` | `JSX.Node` | — | Field declarations, decorative content, and the form's action buttons, in any order | - -## Rules - -These are enforced at build time — violating them throws a `ModalFormError`, not just a lint warning: - -- Exactly **one** `Form.Button type="submit"` is required. The native modal has no built-in submit control. -- At most **one** `Form.Button type="exit"` is allowed. -- A `Form` is a root, the way [`Screen`](../roots/Screen.md) and [`Container`](../roots/Container.md) are: it sits at the top of the tree, and no root sits inside another. A `Form` inside a `Form` or a `Screen` is refused as a root. -- A plain `Button` cannot appear inside a `Form` — only `Form.*` field members and decorative nodes are allowed. If you need a `Screen` with regular buttons, use a separate screen (switch via navigation) instead of nesting form kinds. - -## Notes - -- Give every field a unique, stable `name` — it's the only handle you get back on submit. -- Keep exactly one `Form.Button type="submit"`; add a `type="exit"` only when you want an explicit cancel action distinct from the OS-level Esc/X (which already calls `onCancel`). -- Decorative content (headings, help text, images) is fine anywhere in the flow — it doesn't need to be a field. -- Prefer switching between an `ActionFormData` screen and a `Form` screen via navigation rather than trying to mix both kinds in one tree. diff --git a/docs/ui/components/Form/FormButton.md b/docs/ui/components/Form/FormButton.md deleted file mode 100644 index 60fb8b9..0000000 --- a/docs/ui/components/Form/FormButton.md +++ /dev/null @@ -1,55 +0,0 @@ ---- -sidebar_position: 8 -description: "The submit/exit action button of a Form." ---- -# Form.Button - -The submit/exit action button of a [`Form`](./Form.md). - -## Import - -```tsx -import { Form } from '@bedrock-core/ui'; -``` - -## Usage - -```tsx - - - - -``` - -## How it works - -`Form.Button` is **not** a native modal control and consumes no `formValues` slot, so you can position it anywhere in the form's layout flow like any other row. - -A `Form` enforces the cardinality of these buttons at build time (see [`Form`'s Rules & Restrictions](./Form.md#rules)): exactly one `type="submit"` is required, and at most one `type="exit"` is allowed. - -## Props - -| Prop | Type | Default | Description | -| --- | --- | --- | --- | -| `type` | `'submit' \| 'exit'` | — | `'submit'` presses the native submit — field values return via the form's `onSubmit`. `'exit'` closes the form like Esc — no values, the form's `onCancel` fires instead | -| `label` | `string` | `'Submit'` for `type="submit"`, `'Close'` for `type="exit"` | Button text | - -Inherits [control props](../control-props.md), plus `background`/`backgroundHover`/`backgroundPressed`/`backgroundLocked` for per-state texturing — the same shape as [`Button`](../controls/Button.md). Defaults to `width: '100%'` when no explicit sizing is given. - -## Examples - -### Submit + exit pair - -```tsx - - - - -``` - -## Notes - -- Give the submit button an actionable label ("Save", not the generic default "Submit") — it's user-facing. -- Only add a `type="exit"` button when you want an explicit, visible cancel action — Esc/X already calls `onCancel` without one. -- Position these anywhere in the form's flow; they don't need to be the last elements. -- For themed screens, prefer [`@bedrock-core/ore-styled`](/docs/ore-styled/Form/FormButton)'s `Form.Button`, which adds a `variant` prop. diff --git a/docs/ui/components/Form/FormInlineSelect.md b/docs/ui/components/Form/FormInlineSelect.md deleted file mode 100644 index 178c6f9..0000000 --- a/docs/ui/components/Form/FormInlineSelect.md +++ /dev/null @@ -1,62 +0,0 @@ ---- -sidebar_position: 6 -description: "Select field with every option visible inline (no popup), for use inside a Form." ---- -# Form.InlineSelect - -Select field with every option visible inline (no popup), for use inside a [`Form`](./Form.md). Same selection model as [`Form.Dropdown`](./FormDropdown.md) — same underlying native `ModalFormData.dropdown` control — only the rendering differs: options render in-flow instead of behind a popup. - -## Import - -```tsx -import { Form } from '@bedrock-core/ui'; -``` - -## Usage - -```tsx -
    console.warn(v.team)}> - - - - - - -``` - -:::caution Result is an index, not a value -Just like [`Form.Dropdown`](./FormDropdown.md), `Form.InlineSelect` reports the selected option's **index** (a `number`) at `values[name]`, not its `value` string. Map the index back to your own options array if you need the string. -::: - -## Props - -| Prop | Type | Default | Description | -| --- | --- | --- | --- | -| `name` | `string` | — | Result key — the selected index appears at `values[name]` in the form's `onSubmit` | -| `defaultValue` | `string` | the first option | Initial selection, matched against a [`Form.Option`](./FormOption.md)'s `value` | -| `children` | `JSX.Node` | — | The selectable options, authored as [`Form.Option`](./FormOption.md) elements. Unlike `Form.Dropdown`'s popup rows, each option here is laid out by the normal flex engine — position it with ordinary layout props (`flex`, `gap`, `width`, …) | -| `optionBackground` / `optionHover` / `optionSelected` | `string` | — | Group-level default row textures for idle/hover/selected states. Any `Form.Option` can override its own | -| `bullet` / `bulletSelected` | `string` | — | Unselected/selected bullet glyph texture (e.g. a radio dot). Leave both empty for a segmented, bullet-less look | -| `bulletHover` / `bulletSelectedHover` | `string` | falls back to `bullet` / `bulletSelected` | Bullet glyph shown on hover | -| `bulletWidth` / `bulletHeight` | `number` | `12` | Bullet glyph size (px) | -| `optionFont` / `optionScale` / `optionAlign` | `LabelFont` / `number` / `'left' \| 'center' \| 'right'` | — | Group-level default label styling for option rows. Any `Form.Option` can override its own | - -Inherits [control props](../control-props.md). - -## Examples - -### Radio-style inline select - -```tsx - - - - - -``` - -## Notes - -- Prefer `Form.InlineSelect` over `Form.Dropdown` when the option count is small and you want everything visible without an extra tap. -- Keep `Form.Option` children order stable across renders — the result is an index-based, like `Form.Dropdown`. -- This is the primitive that [`@bedrock-core/ore-styled`](/docs/ore-styled/Form)'s `Form.Radio` and `Form.ToggleButton` are built on — for themed screens, reach for those instead of styling this primitive by hand. diff --git a/docs/ui/components/Form/FormOption.md b/docs/ui/components/Form/FormOption.md deleted file mode 100644 index 6ff2c5f..0000000 --- a/docs/ui/components/Form/FormOption.md +++ /dev/null @@ -1,59 +0,0 @@ ---- -sidebar_position: 7 -description: "One selectable entry, used as a child of Form.Dropdown or Form.InlineSelect." ---- -# Form.Option - -One selectable entry, used as a child of [`Form.Dropdown`](./FormDropdown.md) or [`Form.InlineSelect`](./FormInlineSelect.md). - -## Import - -```tsx -import { Form } from '@bedrock-core/ui'; -``` - -## Usage - -```tsx - - - - - -``` - -## How it works - -`Form.Option` is layout-only — it is not itself a native control, and the whole group submits as its parent's single value. Under `Form.InlineSelect` each option is genuinely flex-laid-out like any other component; under `Form.Dropdown` the popup rows flow at a fixed height, so an option's own layout props are ignored there. - -## Props - -| Prop | Type | Default | Description | -| --- | --- | --- | --- | -| `value` | `string` | — | The option's stable identifier — what a parent's `defaultValue` is matched against. The parent reports the SELECTED option's index on submit, not this value | -| `label` | `string` | — | Option text rendered in the row | -| `font` / `scale` / `align` | `LabelFont` / `number` / `'left' \| 'center' \| 'right'` | falls back to the parent's `optionFont` / `optionScale` / `optionAlign` | Per-option label style override | -| `background` / `backgroundHover` / `backgroundSelected` | `string` | falls back to the parent's `optionBackground` / `optionHover` / `optionSelected` | Per-option row background override | -| `bullet` / `bulletSelected` / `bulletHover` / `bulletSelectedHover` | `string` | falls back to the parent's matching group prop | Per-option bullet glyph override (only meaningful under `Form.InlineSelect`) | -| `bulletWidth` / `bulletHeight` | `number` | falls back to the parent's `bulletWidth` / `bulletHeight` | Per-option bullet size override | - -Inherits [control props](../control-props.md), which lay out real flex rows under `Form.InlineSelect`. Under `Form.Dropdown`, layout props are accepted but ignored — popup rows flow at a fixed height. - -## Examples - -### Per-option override - -```tsx - - - - {/* Overrides the group's center alignment for just this row. */} - - -``` - -## Notes - -- Keep `value` unique within a group — it's what `defaultValue` matches against. -- A per-option override always wins over the group-level style prop of the same name. -- Generate options from a data array (`options.map(o => )`) rather than hand-writing each one, so the list stays easy to keep in sync with your options data. diff --git a/docs/ui/components/Form/FormToggle.md b/docs/ui/components/Form/FormToggle.md deleted file mode 100644 index 0be308a..0000000 --- a/docs/ui/components/Form/FormToggle.md +++ /dev/null @@ -1,65 +0,0 @@ ---- -sidebar_position: 2 -description: "Boolean on/off field for use inside a Form." ---- -# Form.Toggle - -Boolean on/off field for use inside a [`Form`](./Form.md). - -## Import - -```tsx -import { Form } from '@bedrock-core/ui'; -``` - -## Usage - -```tsx -
    console.warn(v.sound)}> - - - -``` - -## How it works - -`Form.Toggle` is a pure field declaration — no `onChange` / controlled value. It renders to the native `ModalFormData.toggle` control; the result (`boolean`) arrives at `values[name]` in the form's `onSubmit`, once, on submit. - -## Props - -| Prop | Type | Default | Description | -| --- | --- | --- | --- | -| `name` | `string` | — | Result key — the value appears at `values[name]` in the form's `onSubmit` | -| `defaultValue` | `boolean` | `false` | Initial on/off state | -| `checkedBackground` | `string` | the resolved unchecked base texture | Checked (on) base texture | -| `checkedHover` | `string` | the resolved checked base texture | Checked hover texture | -| `checkedLocked` | `string` | the resolved checked base texture | Checked texture when `enabled={false}` | - -The unchecked (off) side uses `background`/`backgroundHover`/`backgroundPressed`/`backgroundLocked` for per-state texturing — the same shape as [`Button`](../controls/Button.md) (the toggle RP has no pressed state to show `backgroundPressed`, but the prop is still accepted). - -Inherits [control props](../control-props.md) for layout and visibility — geometry is computed by the layout phase like any other component. - -## Examples - -### Basic toggle - -```tsx - -``` - -### Custom checked textures - -```tsx - -``` - -## Notes - -- Pick clear, unambiguous boolean `name`s (`sound`, not `s`) — it's the only thing you get back on submit. -- Only override `checkedBackground`/`checkedHover`/`checkedLocked` when the default on/off face doesn't match your theme; otherwise a single `background` styles both states. -- For themed screens, prefer [`@bedrock-core/ore-styled`](/docs/ore-styled/Toggle)'s `Form.Toggle` (or `Form.Checkbox` for checkbox-style rows) over styling this primitive by hand. diff --git a/docs/ui/components/Form/_category_.json b/docs/ui/components/Form/_category_.json deleted file mode 100644 index 6c9420d..0000000 --- a/docs/ui/components/Form/_category_.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "position": 8, - "label": "Form", - "collapsible": true, - "collapsed": true, - "link": { - "type": "doc", - "id": "components/Form/Form" - } -} diff --git a/docs/ui/components/cells/_category_.json b/docs/ui/components/cells/_category_.json index e103d13..35284ee 100644 --- a/docs/ui/components/cells/_category_.json +++ b/docs/ui/components/cells/_category_.json @@ -1,5 +1,5 @@ { - "position": 7, + "position": 8, "label": "Container cells", "collapsible": true, "collapsed": true, diff --git a/docs/ui/components/compiled/_category_.json b/docs/ui/components/compiled/_category_.json index d2503df..a1029e0 100644 --- a/docs/ui/components/compiled/_category_.json +++ b/docs/ui/components/compiled/_category_.json @@ -1,5 +1,5 @@ { - "position": 6, + "position": 7, "label": "Compiled", "collapsible": true, "collapsed": true, diff --git a/docs/ui/components/components.md b/docs/ui/components/components.md index 317e2b9..54a0115 100644 --- a/docs/ui/components/components.md +++ b/docs/ui/components/components.md @@ -10,10 +10,12 @@ Built-in JSX components, in the groups the sidebar uses. A screen's root names its [host](../guides/hosts.md), and there is no default: a tree that starts with anything else is refused with the list of roots. -- [``](./roots/Screen.md) — an action form: buttons, decoration, lists and scrolls, shown with `render()` -- [`
    `](./Form/Form.md) — a native modal form, shown with `render()`; it heads the Form group +- [``](./roots/Screen.md) — an action form: presses, decoration, lists and scrolls, shown with `render()` +- [``](./roots/Form.md) — a native modal form, shown with `render()` - [``](./roots/Container.md) — a container screen an entity owns, served with `createContainerScreen()` +A root is **only** a host. None of them has members: every control below is a top-level component, and which hosts it works on is its own capability. + ## Layout Boxes and flow. Each draws on all three hosts and asks for nothing. @@ -32,8 +34,13 @@ What a screen shows. Also free on every host. ## Controls -- [` ); } @@ -70,7 +70,7 @@ function Menu() { {'§lMain Menu'} - diff --git a/docs/ui/components/content/Image.md b/docs/ui/components/content/Image.md index 4e4947b..5487b8f 100644 --- a/docs/ui/components/content/Image.md +++ b/docs/ui/components/content/Image.md @@ -82,7 +82,7 @@ function Icons(): JSX.Element { ### An icon that presses ```tsx - ``` diff --git a/docs/ui/components/content/Text.md b/docs/ui/components/content/Text.md index 7e900d4..b1ad7dd 100644 --- a/docs/ui/components/content/Text.md +++ b/docs/ui/components/content/Text.md @@ -60,7 +60,7 @@ function Counter() { return ( {`Count: ${count}`} - diff --git a/docs/ui/components/control-props.md b/docs/ui/components/control-props.md index 747440b..3f66bab 100644 --- a/docs/ui/components/control-props.md +++ b/docs/ui/components/control-props.md @@ -83,7 +83,7 @@ Interactive primitives (`Button`, the `Form.*` fields) extend `background` with A compiled screen's shape is frozen, so a branch that adds or drops an element cannot be a runtime decision. The build rewrites the two React idioms into a carried `visible` instead, at source level, so what you write stays idiomatic: ```tsx -{isAdmin && } +{isAdmin && } ``` becomes ` ``` @@ -26,56 +26,63 @@ Buttons are sized intrinsically from their content plus the button's built-in pa | Prop | Type | Default | Description | | --- | --- | --- | --- | -| `onPress` | `(event: PressEvent) => unknown \| Promise` | — | Runs when the player presses the button | -| `children` | `JSX.Node` | — | What the button shows, typically a `Text` or an `Image` | +| `action` | `(event: PressEvent) => unknown \| Promise` \| `'submit'` \| `'exit'` | — | What the press does; see below | +| `children` | `JSX.Node` | — | What the button shows — a `Text`, an `Image`, or a row of both | | `backgroundHover` | `string` | `background` | Texture drawn while the player hovers | | `backgroundPressed` | `string` | `background` | Texture drawn while the button is being pressed | | `backgroundLocked` | `string` | `background` | Texture drawn while the button is disabled | Inherits [control props](../control-props.md). Every state texture falls back to `background`, and `background` falls back to the blank-canvas placeholder, so one texture styles all four states. -This is the primitive [`@bedrock-core/ore-styled`'s `Button`](/docs/ore-styled/Button) is built on. +## What the action is -## What a press is +`action` is the one prop a press is given, and it takes three kinds of thing. -`event.player` is who pressed. On a [container screen](../../guides/container-screens.md) `event.host` is the entity that owns the screen; on a form there is none. Every handler in the library takes one event object — see [Handler events](../../guides/handler-events.md). +| `action` | What happens | Where | +| --- | --- | --- | +| a handler | your function runs, with the player who pressed | [``](../roots/Screen.md) and [``](../roots/Container.md) | +| `'submit'` | the native modal submits, and [`
    `](../roots/Form.md) receives every value | [``](../roots/Form.md) | +| `'exit'` | the screen is left — the modal's dismiss, or the way out of a container screen | `` and `` | -What the press *costs* depends on the [host](../../guides/hosts.md): a form entry the engine reports back by index on an action form, an item taken and put straight back on a container screen. A native modal has no generic button at all — use [``](../Form/FormButton.md) there. +A handler is **script**: only this realm can run it, so the build cannot describe where the press leads. `'submit'` and `'exit'` are routed by the engine itself, so nothing reaches script for them at all. -When the destination is another screen rather than a handler, reach for [``](./Link.md): its target is data the build can read, which is what makes the screen describable to other addons. +When the press simply opens another screen, reach for [``](./Link.md) instead — its destination is data the build reads off the tree, which is what lets a screen of presses be [described to another addon](../../guides/navigation.md#static-screens). -## Examples +## What a press costs -### With state +What the press *is* depends on the [host](../../guides/hosts.md): -```tsx -function ToggleButton(): JSX.Element { - const [isActive, setIsActive] = useState(false); - - return ( - - ); -} -``` +- On `` it is a form entry the engine reports back by index. +- On `` it is an item taken and put straight back — which is also why `event.host` is the entity that owns the screen there, and why there is none on a form. +- On `` there is no generic press at all: a modal has its own two actions and nothing else, so a handler is refused there by name. -### Disabled +Every handler in the library takes one event object — see [Handler events](../../guides/handler-events.md). + +## Examples + +### A form's two actions + +Exactly one `'submit'` is required, and at most one `'exit'` beside it. ```tsx - + apply(values)} onCancel={() => back(player)}> + + + + + + + ``` ### A row sharing the width ```tsx - - @@ -84,11 +91,19 @@ function ToggleButton(): JSX.Element { ### An icon ```tsx - ``` +### Disabled + +```tsx + +``` + ### Fully themed ```tsx @@ -97,7 +112,7 @@ function ToggleButton(): JSX.Element { backgroundHover={'textures/ui/button_hover'} backgroundPressed={'textures/ui/button_pressed'} backgroundLocked={'textures/ui/button_locked'} - onPress={() => console.warn('pressed')} + action={() => console.warn('pressed')} > {'Themed'} @@ -105,8 +120,10 @@ function ToggleButton(): JSX.Element { ## Notes -Let buttons size to their content rather than hardcoding `width` and `height`, unless the layout needs a specific footprint. Inside a row, `flex={1}` on each button distributes the space evenly. +Let buttons size to their content rather than hardcoding `width` and `height`, unless the layout needs a specific footprint. Inside a row, `flex={1}` on each distributes the space evenly. Disable a button when its action is unavailable rather than hiding it: a hidden control leaves its box behind on a compiled screen unless the row is a [``](../layout/Panel.md#stack). -An `onPress` that returns a promise keeps the press's transaction open until it settles, which is what makes an async handoff flash-free. See [State](../../guides/state.md#one-ui-slot-per-player). +A handler that returns a promise keeps the press's transaction open until it settles, which is what makes an async handoff flash-free. See [State](../../guides/state.md#one-ui-slot-per-player). + +This is the primitive [`@bedrock-core/ore-styled`'s `Button`](/docs/ore-styled/Button) is built on. diff --git a/docs/ui/components/controls/Link.md b/docs/ui/components/controls/Link.md index 50039ff..005d67c 100644 --- a/docs/ui/components/controls/Link.md +++ b/docs/ui/components/controls/Link.md @@ -29,11 +29,11 @@ import { Link } from '@bedrock-core/ui'; | `params` | `Record` | — | Props the target screen is rendered with; they fill what the layout already reserved | | `replace` | `boolean` | `false` | Take the place of this screen rather than stacking over it | -Inherits every prop of [` + +``` + +:::caution Result is an index, not a value +Just like [`Dropdown`](../fields/Dropdown.md), `Select` reports the selected option's **index** (a `number`) at `values[name]`, not its `value` string. Map the index back to your own options array if you need the string. +::: + +## Props + +| Prop | Type | Default | Description | +| --- | --- | --- | --- | +| `name` | `string` | — | Result key — the selected index appears at `values[name]` in the form's `onSubmit` | +| `defaultValue` | `string` | the first option | Initial selection, matched against a [`Option`](./Option.md)'s `value` | +| `children` | `JSX.Node` | — | The selectable options, authored as [`Option`](./Option.md) elements. Unlike `Dropdown`'s popup rows, each option here is laid out by the normal flex engine — position it with ordinary layout props (`flex`, `gap`, `width`, …) | +| `optionBackground` / `optionHover` / `optionSelected` | `string` | — | Group-level default row textures for idle/hover/selected states. Any `Option` can override its own | +| `bullet` / `bulletSelected` | `string` | — | Unselected/selected bullet glyph texture (e.g. a radio dot). Leave both empty for a segmented, bullet-less look | +| `bulletHover` / `bulletSelectedHover` | `string` | falls back to `bullet` / `bulletSelected` | Bullet glyph shown on hover | +| `bulletWidth` / `bulletHeight` | `number` | `12` | Bullet glyph size (px) | +| `optionFont` / `optionScale` / `optionAlign` | `LabelFont` / `number` / `'left' \| 'center' \| 'right'` | — | Group-level default label styling for option rows. Any `Option` can override its own | + +Inherits [control props](../control-props.md). + +## Examples + +### Radio-style inline select + +```tsx + +``` + +## Notes + +- Prefer `Select` over `Dropdown` when the option count is small and you want everything visible without an extra tap. +- Keep `Option` children order stable across renders — the result is an index-based, like `Dropdown`. +- This is the primitive [`@bedrock-core/ore-styled`](/docs/ore-styled)'s [`Radio`](/docs/ore-styled/Radio) and [`ToggleButtonGroup`](/docs/ore-styled/ToggleButton) are built on — reach for those on a themed screen rather than styling this by hand. + +## Limits + +On a modal the answer is the chosen option's **index**, not its value — the native dropdown's behavior. Where a press reaches script instead, the value is what comes back. See the [capability table](../../guides/hosts.md#what-each-host-can-carry). diff --git a/docs/ui/components/controls/Toggle.md b/docs/ui/components/controls/Toggle.md new file mode 100644 index 0000000..5e60587 --- /dev/null +++ b/docs/ui/components/controls/Toggle.md @@ -0,0 +1,85 @@ +--- +sidebar_position: 3 +description: "A boolean. A native field on a modal, a press that flips on a screen, a slot on a container." +--- +# Toggle + +A boolean, on any of the three screens. + +## Import + +```tsx +import { Toggle } from '@bedrock-core/ui'; +``` + +## Usage + +```tsx + +``` + +## One component, three mechanisms + +`Toggle` asks [`useMechanism('Toggle')`](../../hooks/useMechanism.md) what a boolean becomes on the screen it is being drawn on, and draws that. The component is written once; what differs is the host. + +| Screen | What it is | How the value moves | +| --- | --- | --- | +| [`
    `](../roots/Form.md) | a native field the engine owns | nothing until submit, then `values[name]` | +| [``](../roots/Screen.md) | a button that flips its state and renders the screen again | `onChange` on the press; the player sees the new state on the next present | +| [``](../roots/Container.md) | a cell of the entity's container — the press is an item taken and put straight back | `onChange` on the press; the slots settle in the same tick | + +So `name` is what the modal reports under, and `on` / `onChange` are what the two press hosts give you. Write all of them and the control moves between screens unchanged: each host uses the ones it can. + +## Props + +| Prop | Type | Default | Description | +| --- | --- | --- | --- | +| `name` | `string` | — | Result key on a modal, where it is required; ignored where the press is the answer | +| `defaultValue` | `boolean` | `false` | Which way it starts | +| `on` | `boolean` | — | Held by the caller instead of by the control. Only where a press reaches script | +| `onChange` | `(on: boolean) => void` | — | Called with the new state, on the hosts where a press reaches script | +| `background` | `string` | the blank-canvas placeholder | The unchecked face | +| `backgroundHover` / `backgroundPressed` / `backgroundLocked` | `string` | `background` | The unchecked face per state | +| `checkedBackground` | `string` | the resolved `background` | The checked face | +| `checkedHover` / `checkedLocked` | `string` | `checkedBackground` | The checked face per state | + +Inherits [control props](../control-props.md). Geometry is solved by the layout like any other component and encoded for the render pack, so a native widget is positioned by the same flexbox as everything else. + +## Examples + +### In a modal + +```tsx + setMusic(values.music === true)}> + + + +``` + +### On a screen of buttons + +```tsx +function MusicRow(): JSX.Element { + const [on, setOn] = useState(true); + + return ; +} +``` + +The press re-presents the screen, which is how the player sees the flip — a form cannot change while it is open, and an action form is a form. + +### On a container screen + +```tsx + + + +``` + +The cell takes one index in the entity's container. A press is an item taken and put straight back, so the handler runs and the slots settle in the same tick. + +## Notes + +The faces resolve by one rule — `state ?? base ?? unstyled` — so a single `background` styles every state, and a `checkedBackground` styles the whole checked side. + +[`@bedrock-core/ore-styled`](/docs/ore-styled/Toggle)'s `Toggle` and `Checkbox` are this component with the theme's faces and a caption. diff --git a/docs/ui/components/controls/_category_.json b/docs/ui/components/controls/_category_.json index fdbfc3b..54573f2 100644 --- a/docs/ui/components/controls/_category_.json +++ b/docs/ui/components/controls/_category_.json @@ -6,6 +6,6 @@ "link": { "type": "generated-index", "title": "Controls", - "description": "A press, and a press whose destination the build can read." + "description": "A press, a destination, and the choices every host serves in its own way." } } diff --git a/docs/ui/components/cross-pack/Expect.md b/docs/ui/components/cross-pack/Expect.md index 873e779..6d34dc6 100644 --- a/docs/ui/components/cross-pack/Expect.md +++ b/docs/ui/components/cross-pack/Expect.md @@ -17,8 +17,8 @@ import { Expect } from '@bedrock-core/ui'; ```tsx export const AccountFields = (): JSX.Element => ( - - + + ); ``` diff --git a/docs/ui/components/Form/FormDropdown.md b/docs/ui/components/fields/Dropdown.md similarity index 50% rename from docs/ui/components/Form/FormDropdown.md rename to docs/ui/components/fields/Dropdown.md index a4720a5..d6dd094 100644 --- a/docs/ui/components/Form/FormDropdown.md +++ b/docs/ui/components/fields/Dropdown.md @@ -1,10 +1,10 @@ --- -sidebar_position: 5 +sidebar_position: 3 description: "Select field with a popup, for use inside a Form." --- -# Form.Dropdown +# Dropdown -Select field with a popup, for use inside a [`Form`](./Form.md). Pressing it opens a scrollable list of [`Form.Option`](./FormOption.md) children to choose from. +Select field with a popup, for use inside a [`Form`](../roots/Form.md). Pressing it opens a scrollable list of [`Option`](../controls/Option.md) children to choose from. ## Import @@ -16,17 +16,17 @@ import { Form } from '@bedrock-core/ui'; ```tsx
    console.warn(v.mode)}> - - - - - - + + + ``` :::caution Result is an index, not a value -`Form.Dropdown` reports the selected option's **index** (a `number`) at `values[name]`, not its `value` string — this is the native modal dropdown's behavior. If you need the string back, map the index into your own options array yourself. +`Dropdown` reports the selected option's **index** (a `number`) at `values[name]`, not its `value` string — this is the native modal dropdown's behavior. If you need the string back, map the index into your own options array yourself. ::: ## Props @@ -34,11 +34,11 @@ import { Form } from '@bedrock-core/ui'; | Prop | Type | Default | Description | | --- | --- | --- | --- | | `name` | `string` | — | Result key — the selected index appears at `values[name]` in the form's `onSubmit` | -| `defaultValue` | `string` | the first option | Initial selection, matched against a [`Form.Option`](./FormOption.md)'s `value` | -| `children` | `JSX.Node` | — | The selectable options, authored as [`Form.Option`](./FormOption.md) elements. Popup rows flow at a fixed row height, so an option's own layout props are ignored here — only its `value`/`label`/style are read | +| `defaultValue` | `string` | the first option | Initial selection, matched against a [`Option`](../controls/Option.md)'s `value` | +| `children` | `JSX.Node` | — | The selectable options, authored as [`Option`](../controls/Option.md) elements. Popup rows flow at a fixed row height, so an option's own layout props are ignored here — only its `value`/`label`/style are read | | `popupBackground` | `string` | the unstyled placeholder texture | Background texture for the popup surface behind the option list | -| `optionBackground` / `optionHover` / `optionSelected` | `string` | — | Group-level default row textures for idle/hover/selected states. Any `Form.Option` can override its own | -| `optionFont` / `optionScale` / `optionAlign` | `LabelFont` / `number` / `'left' \| 'center' \| 'right'` | `'mojangles'` / `1.0` / `'left'` | Group-level default label styling for option rows. Any `Form.Option` can override its own | +| `optionBackground` / `optionHover` / `optionSelected` | `string` | — | Group-level default row textures for idle/hover/selected states. Any `Option` can override its own | +| `optionFont` / `optionScale` / `optionAlign` | `LabelFont` / `number` / `'left' \| 'center' \| 'right'` | `'mojangles'` / `1.0` / `'left'` | Group-level default label styling for option rows. Any `Option` can override its own | | `currentColor` | `string` | `''` | Color code prefix (e.g. `'§0'`) applied to the closed-box current-value text | | `currentFont` / `currentScale` | `LabelFont` / `number` | `'mojangles'` / `1.0` | Font and scale for the closed-box current-value label | | `currentInsetX` / `currentInsetY` | `number` | `8` / vertically centered | Position offset (px) of the current-value label from the closed box's left-middle frame | @@ -52,11 +52,11 @@ Inherits [control props](../control-props.md). ### Basic dropdown ```tsx - - - - - + + ``` ### Per-option alignment override @@ -64,11 +64,11 @@ Inherits [control props](../control-props.md). The group sets a default alignment for all options; any option can override its own. ```tsx - - - - - + + ``` ### Reading the result @@ -80,16 +80,20 @@ const options = ['Easy', 'Normal', 'Hard']; const selected = options[v.mode as number]; console.warn(selected); }}> - - {options.map(o => )} - - + + {options.map(o => + ``` ## Notes -- Keep `Form.Option` children order stable across renders — the result is an index, so reordering shifts what a saved index means. +- Keep `Option` children order stable across renders — the result is an index, so reordering shifts what a saved index means. - Read `values[name]` as an index and map it back to your own array if you need the string; don't assume it's the `value` you passed in. -- Prefer [`Form.InlineSelect`](./FormInlineSelect.md) instead when you want every option visible without an extra tap (e.g. a short radio-style choice). -- For themed screens, prefer [`@bedrock-core/ore-styled`](/docs/ore-styled/Dropdown)'s `Form.Dropdown` over styling this primitive by hand. +- Prefer [`Select`](../controls/Select.md) instead when you want every option visible without an extra tap (e.g. a short radio-style choice). +- For themed screens, prefer [`@bedrock-core/ore-styled`](/docs/ore-styled/Dropdown)'s `Dropdown` over styling this primitive by hand. + +## Limits + +Modal-only. The engine draws no popup on an action form or a container screen, so writing one there is a build error naming the fix rather than a control drawn inert. [``](../controls/Toggle.md) and [` + ``` ## How it works -`Form.Input` is a pure field declaration — no `onChange` / controlled value. It renders to the native `ModalFormData.textField` control; the result (`string`) arrives at `values[name]` in the form's `onSubmit`, once, on submit. +`Input` is a pure field declaration — no `onChange` / controlled value. It renders to the native `ModalFormData.textField` control; the result (`string`) arrives at `values[name]` in the form's `onSubmit`, once, on submit. ## Props @@ -46,15 +46,15 @@ Inherits [control props](../control-props.md). ### Basic input ```tsx - + ``` ### Two inputs side by side ```tsx - - + + ``` @@ -62,4 +62,8 @@ Inherits [control props](../control-props.md). - Always provide a `placeholder` — it's the only hint the player gets about what to type. - Keep `name` stable across renders; it's the only key you get back on submit. -- For themed screens, prefer [`@bedrock-core/ore-styled`](/docs/ore-styled/Input)'s `Form.Input` over styling this primitive by hand. +- For themed screens, prefer [`@bedrock-core/ore-styled`](/docs/ore-styled/Input)'s `Input` over styling this primitive by hand. + +## Limits + +Modal-only. The engine draws no text field on an action form or a container screen, so writing one there is a build error naming the fix rather than a control drawn inert. [``](../controls/Toggle.md) and [``](../controls/Select.md) are the controls that serve all three hosts. diff --git a/docs/ui/components/fields/_category_.json b/docs/ui/components/fields/_category_.json new file mode 100644 index 0000000..0e245b2 --- /dev/null +++ b/docs/ui/components/fields/_category_.json @@ -0,0 +1,11 @@ +{ + "position": 6, + "label": "Modal fields", + "collapsible": true, + "collapsed": true, + "link": { + "type": "generated-index", + "title": "Modal fields", + "description": "The three the engine only draws inside a `
    `: a text field, a slider and a popup. Anywhere else they are refused at build." + } +} diff --git a/docs/ui/components/roots/Container.md b/docs/ui/components/roots/Container.md index 487c1c4..d78c6d1 100644 --- a/docs/ui/components/roots/Container.md +++ b/docs/ui/components/roots/Container.md @@ -1,5 +1,5 @@ --- -sidebar_position: 2 +sidebar_position: 3 description: "The root of a container screen: names the entity the screen opens from, and is the screen's own panel." --- # Container @@ -27,7 +27,7 @@ export default function Furnace() { } ``` -Its presence decides the backend, the way [``](../Form/Form.md) makes a screen a native modal: a tree rooted in a `Container` is laid out once at build time by the [ui-compiler filter](/docs/filters/ui-compiler), baked into JSON UI, and served by `createContainerScreen` to every player who opens the entity it names. `render()` rejects it — a container screen is compiled ahead of time, not serialized per player. +Its presence decides the backend, the way [``](./Form.md) makes a screen a native modal: a tree rooted in a `Container` is laid out once at build time by the [ui-compiler filter](/docs/filters/ui-compiler), baked into JSON UI, and served by `createContainerScreen` to every player who opens the entity it names. `render()` rejects it — a container screen is compiled ahead of time, not serialized per player. ## Props diff --git a/docs/ui/components/roots/Form.md b/docs/ui/components/roots/Form.md new file mode 100644 index 0000000..ffb23cd --- /dev/null +++ b/docs/ui/components/roots/Form.md @@ -0,0 +1,86 @@ +--- +sidebar_position: 2 +description: "The root that makes a screen a native modal form: one atomic ModalFormData, every value arriving together on submit." +--- +# Form + +The root that makes a screen a native modal form. + +## Import + +```tsx +import { Form } from '@bedrock-core/ui'; +``` + +## Usage + +```tsx title="packs/BP/scripts/settings.screen.tsx" +export default function Settings(): JSX.Element { + return ( + apply(values)}> + {'Settings'} + + + + + + ); +} +``` + +`Form` is a **host**, the way [``](./Screen.md) and [``](./Container.md) are. Its presence makes the renderer build one atomic `ModalFormData` instead of a screen of buttons. + +## Form has no members + +There is no `Form.Toggle`, no `Form.Input`, no `Form.Button`. Every control is a top-level component imported by its own name, and **which hosts it works on is its own capability**, not something a namespace decides: + +```tsx +import { Button, Dropdown, Form, Input, Option, Select, Slider, Text, Toggle } from '@bedrock-core/ui'; +``` + +[``](../controls/Toggle.md), [``](../fields/Input.md), [``](../fields/Slider.md) and [``](../fields/Dropdown.md) only work here, because the engine draws no text field, slider or popup anywhere else. See [Hosts](../../guides/hosts.md) for the whole table. + +## Props + +| Prop | Type | Default | Description | +| --- | --- | --- | --- | +| `onSubmit` | `(event: SubmitEvent) => void` | — | Called once when the player submits. `event.values` holds every control's value keyed by its `name` | +| `onCancel` | `(event: UiEvent) => void` | — | Called when the player dismisses the modal — the X, Esc, or an exit button | +| `children` | `JSX.Node` | — | The controls, the decoration and the action buttons, in any order | + +`Form` takes no [control props](../control-props.md): it is a marker, not a panel. Put a `Panel` inside it for a background, padding or a direction. + +## Values arrive once + +The native modal is atomic: nothing reaches script while it is open, and every value comes back together on submit. + +```tsx +
    { + values.music; // boolean + values.volume; // number + values.nickname; // string +}}> +``` + +`FormValues` is `Record`, where `ModalValue` is `string | number | boolean | undefined`. That is why a control here has a `name` and no `onChange` — there is nothing to call one from. + +A heading is a ``: the modal has no `title` or `body` prop of its own. + +## Rules + +The build enforces these, with a message naming the fix. + +- **Exactly one submit.** A modal has no built-in submit control, so the screen declares one: ` @@ -29,7 +29,7 @@ export default function Players(): JSX.Element { } ``` -A screen's root names its [host](../../guides/hosts.md), and there is no default. `` makes it an action form the way [``](../Form/Form.md) makes it a native modal and [``](./Container.md) a container screen. It has no box of its own: its children are laid out against the form canvas exactly as they would be at the top of the tree. +A screen's root names its [host](../../guides/hosts.md), and there is no default. `` makes it an action form the way [``](./Form.md) makes it a native modal and [``](./Container.md) a container screen. It has no box of its own: its children are laid out against the form canvas exactly as they would be at the top of the tree. ## Props diff --git a/docs/ui/components/roots/_category_.json b/docs/ui/components/roots/_category_.json index 0543826..575877a 100644 --- a/docs/ui/components/roots/_category_.json +++ b/docs/ui/components/roots/_category_.json @@ -6,6 +6,6 @@ "link": { "type": "generated-index", "title": "Roots", - "description": "The three roots. A screen's root names its host, and there is no default. The third, ``, heads the Form group." + "description": "The three roots. A screen's root names its host, and there is no default." } } diff --git a/docs/ui/guides/container-screens.md b/docs/ui/guides/container-screens.md index f3afef7..dfc679a 100644 --- a/docs/ui/guides/container-screens.md +++ b/docs/ui/guides/container-screens.md @@ -31,8 +31,8 @@ export default function Furnace() { {`holding ${held}`} - - + + setHeld(stack.typeId)} /> setHeld(`took ${stack.typeId}`)} /> @@ -134,7 +134,7 @@ What *is* baked into the JSON UI is inertness. A container slot's take and place State is **entity-owned**. Hook state lives on the entity the screen is attached to, in a dynamic property, and persists on its own: close the screen and reopen it, leave and come back, restart the world — the furnace is still at the charge it was left at. Nothing has to be saved or restored, but it does mean state must be JSON-serializable: numbers, strings, booleans, plain objects and arrays. -There is no single viewer, so **the player reaches a screen through its handlers** rather than a hook: `Slot` and `Button` handlers receive an event carrying the player who moved the item, and the `Container` itself has `onOpen` / `onClose` carrying the player who came or went — keep what the screen needs (a name, a count of viewers) in state. [`usePlayer`](../hooks/usePlayer.md) is unavailable, because a container screen has no player of its own. [`useExit`](../hooks/useExit.md) hands back a press rather than a closer: nothing closes a container from script, but a ` ); } ``` -When the handoff goes through an async opener, **return the promise from `onPress`** so the swap lands inside the press's transaction. Fired and forgotten it still converges; worst case the screen re-locks for a frame. +When the handoff goes through an async opener, **return the promise from `action`** so the swap lands inside the press's transaction. Fired and forgotten it still converges; worst case the screen re-locks for a frame. ## A form change is a new present diff --git a/docs/ui/hooks/useExit.md b/docs/ui/hooks/useExit.md index c5f35be..933c2cc 100644 --- a/docs/ui/hooks/useExit.md +++ b/docs/ui/hooks/useExit.md @@ -37,7 +37,7 @@ function CloseButton() { const exit = useExit(); return ( - ); @@ -57,12 +57,12 @@ function ConditionalClose() { {`Saved: ${isSaved ? 'Yes' : 'No'}`} - diff --git a/docs/ui/hooks/useMechanism.md b/docs/ui/hooks/useMechanism.md index 61430ff..bb44abe 100644 --- a/docs/ui/hooks/useMechanism.md +++ b/docs/ui/hooks/useMechanism.md @@ -47,8 +47,8 @@ function Checkbox({ name, label }: CheckboxProps): JSX.Element { const mechanism = useMechanism('Toggle'); return mechanism === 'field' - ? - : ; + ? + : ; } ``` diff --git a/docs/ui/hooks/useReducer.md b/docs/ui/hooks/useReducer.md index c200883..8eac239 100644 --- a/docs/ui/hooks/useReducer.md +++ b/docs/ui/hooks/useReducer.md @@ -64,13 +64,13 @@ function Counter() { {`Count: ${state.count}`} - - - @@ -133,13 +133,13 @@ function TodoApp() { return ( - {state.todos.map(todo => ( {`${todo.completed ? '✓' : '○'} ${todo.text}`} ))} - diff --git a/docs/ui/hooks/useRef.md b/docs/ui/hooks/useRef.md index d484d69..44f1619 100644 --- a/docs/ui/hooks/useRef.md +++ b/docs/ui/hooks/useRef.md @@ -55,10 +55,10 @@ function Timer() { {`Count: ${count}`} - - @@ -84,7 +84,7 @@ function PreviousValue() { {`Current: ${count}`} {`Previous: ${prevCountRef.current}`} - @@ -106,7 +106,7 @@ function ExecutionCounter() { {`State: ${state}`} {`Executions: ${executionCount.current}`} - diff --git a/docs/ui/hooks/useState.md b/docs/ui/hooks/useState.md index ec7e1eb..073ef5f 100644 --- a/docs/ui/hooks/useState.md +++ b/docs/ui/hooks/useState.md @@ -40,7 +40,7 @@ function Counter() { return ( {`Count: ${count}`} - @@ -57,7 +57,7 @@ function Toggle() { const [isOn, setIsOn] = useState(false); return ( - ); @@ -94,10 +94,10 @@ function StatsDisplay() { {`Mana: ${stats.mana}`} {`Level: ${stats.level}`} - - @@ -126,10 +126,10 @@ function TodoList() { {`${index + 1}. ${todo}`} ))} - - diff --git a/docs/ui/hooks/useTranslation.md b/docs/ui/hooks/useTranslation.md index 778b97f..0f96e2c 100644 --- a/docs/ui/hooks/useTranslation.md +++ b/docs/ui/hooks/useTranslation.md @@ -98,10 +98,10 @@ function LanguagePicker() { return ( - - @@ -119,7 +119,7 @@ function BuyButton({ item }: { item: Item }) { const { display, key, raw } = useTranslation(i18n); return ( - @@ -76,7 +76,7 @@ The `@bedrock-core/generated/ui` import is what runs the build's registrations. **A layout solved once** — [`@bedrock-core/flexbox`](/docs/flexbox) solves every rect at build time against a fixed 320 × 210 canvas. No geometry is measured in game, and a host that serves the screen cannot move a control the layout placed. -**Refusals with names** — each host declares what every kind of component becomes on it. A `` outside a `` or a `` outside a container screen fails the build, in that host's own words, instead of drawing something inert. +**Refusals with names** — each host declares what every kind of component becomes on it. A `` outside a `` or a `` outside a container screen fails the build, in that host's own words, instead of drawing something inert. **Screens other addons can show** — a [static](./guides/navigation.md#static-screens) screen is described by its title, its entry values and one target per press. Publish that table and a realm running none of your script still shows your screens, because the layout is in the pack every client holds. diff --git a/src/data/redirects.ts b/src/data/redirects.ts index 7fe54e3..7f17c3d 100644 --- a/src/data/redirects.ts +++ b/src/data/redirects.ts @@ -41,8 +41,8 @@ export const redirects: { from: string; to: string }[] = [ { from: '/docs/ui/ore-styled/Checkbox', to: '/docs/ore-styled/Checkbox' }, { from: '/docs/ui/ore-styled/Divider', to: '/docs/ore-styled/Divider' }, { from: '/docs/ui/ore-styled/Dropdown', to: '/docs/ore-styled/Dropdown' }, - { from: '/docs/ui/ore-styled/Form', to: '/docs/ore-styled/Form' }, - { from: '/docs/ui/ore-styled/Form/FormButton', to: '/docs/ore-styled/Form/FormButton' }, + { from: '/docs/ui/ore-styled/Form', to: '/docs/ui/components/roots/Form' }, + { from: '/docs/ui/ore-styled/Form/FormButton', to: '/docs/ore-styled/Button' }, { from: '/docs/ui/ore-styled/Form/FormCheckbox', to: '/docs/ore-styled/Checkbox' }, { from: '/docs/ui/ore-styled/Form/FormDropdown', to: '/docs/ore-styled/Dropdown' }, { from: '/docs/ui/ore-styled/Form/FormInput', to: '/docs/ore-styled/Input' }, @@ -68,28 +68,28 @@ export const redirects: { from: string; to: string }[] = [ { from: '/docs/ui/ui-runtime/components/Background', to: '/docs/ui/components/content/Background' }, { from: '/docs/ui/ui-runtime/components/Button', to: '/docs/ui/components/controls/Button' }, { from: '/docs/ui/ui-runtime/components/Container', to: '/docs/ui/components/roots/Container' }, - { from: '/docs/ui/ui-runtime/components/Dropdown', to: '/docs/ui/components/Form/FormDropdown' }, - { from: '/docs/ui/ui-runtime/components/Form', to: '/docs/ui/components/Form' }, - { from: '/docs/ui/ui-runtime/components/Form/FormButton', to: '/docs/ui/components/Form/FormButton' }, - { from: '/docs/ui/ui-runtime/components/Form/FormDropdown', to: '/docs/ui/components/Form/FormDropdown' }, - { from: '/docs/ui/ui-runtime/components/Form/FormInlineSelect', to: '/docs/ui/components/Form/FormInlineSelect' }, - { from: '/docs/ui/ui-runtime/components/Form/FormInput', to: '/docs/ui/components/Form/FormInput' }, - { from: '/docs/ui/ui-runtime/components/Form/FormOption', to: '/docs/ui/components/Form/FormOption' }, - { from: '/docs/ui/ui-runtime/components/Form/FormSlider', to: '/docs/ui/components/Form/FormSlider' }, - { from: '/docs/ui/ui-runtime/components/Form/FormToggle', to: '/docs/ui/components/Form/FormToggle' }, + { from: '/docs/ui/ui-runtime/components/Dropdown', to: '/docs/ui/components/fields/Dropdown' }, + { from: '/docs/ui/ui-runtime/components/Form', to: '/docs/ui/components/roots/Form' }, + { from: '/docs/ui/ui-runtime/components/Form/FormButton', to: '/docs/ui/components/controls/Button' }, + { from: '/docs/ui/ui-runtime/components/Form/FormDropdown', to: '/docs/ui/components/fields/Dropdown' }, + { from: '/docs/ui/ui-runtime/components/Form/FormInlineSelect', to: '/docs/ui/components/controls/Select' }, + { from: '/docs/ui/ui-runtime/components/Form/FormInput', to: '/docs/ui/components/fields/Input' }, + { from: '/docs/ui/ui-runtime/components/Form/FormOption', to: '/docs/ui/components/controls/Option' }, + { from: '/docs/ui/ui-runtime/components/Form/FormSlider', to: '/docs/ui/components/fields/Slider' }, + { from: '/docs/ui/ui-runtime/components/Form/FormToggle', to: '/docs/ui/components/controls/Toggle' }, { from: '/docs/ui/ui-runtime/components/Fragment', to: '/docs/ui/components/layout/Fragment' }, { from: '/docs/ui/ui-runtime/components/Hotbar', to: '/docs/ui/components/cells/Hotbar' }, { from: '/docs/ui/ui-runtime/components/Image', to: '/docs/ui/components/content/Image' }, - { from: '/docs/ui/ui-runtime/components/Input', to: '/docs/ui/components/Form/FormInput' }, + { from: '/docs/ui/ui-runtime/components/Input', to: '/docs/ui/components/fields/Input' }, { from: '/docs/ui/ui-runtime/components/Panel', to: '/docs/ui/components/layout/Panel' }, { from: '/docs/ui/ui-runtime/components/PlayerInventory', to: '/docs/ui/components/cells/PlayerInventory' }, { from: '/docs/ui/ui-runtime/components/Scroll', to: '/docs/ui/components/layout/Scroll' }, - { from: '/docs/ui/ui-runtime/components/Slider', to: '/docs/ui/components/Form/FormSlider' }, + { from: '/docs/ui/ui-runtime/components/Slider', to: '/docs/ui/components/fields/Slider' }, { from: '/docs/ui/ui-runtime/components/Slot', to: '/docs/ui/components/cells/Slot' }, { from: '/docs/ui/ui-runtime/components/SlotGrid', to: '/docs/ui/components/cells/SlotGrid' }, { from: '/docs/ui/ui-runtime/components/Text', to: '/docs/ui/components/content/Text' }, { from: '/docs/ui/ui-runtime/components/control-props', to: '/docs/ui/components/control-props' }, - { from: '/docs/ui/ui-runtime/components/modal-field-props', to: '/docs/ui/components/Form' }, + { from: '/docs/ui/ui-runtime/components/modal-field-props', to: '/docs/ui/components/roots/Form' }, { from: '/docs/ui/ui-runtime/hooks', to: '/docs/ui/hooks' }, { from: '/docs/ui/ui-runtime/hooks/useContext', to: '/docs/ui/hooks/useContext' }, { from: '/docs/ui/ui-runtime/hooks/useEffect', to: '/docs/ui/hooks/useEffect' }, @@ -109,10 +109,10 @@ export const redirects: { from: string; to: string }[] = [ { from: '/docs/navigation/useRoute', to: '/docs/navigation/useNavigation' }, { from: '/docs/server/api/guides', to: '/docs/guides' }, { from: '/docs/server/api/pages', to: '/docs/navigation/references' }, - { from: '/docs/ui/components/deprecated/Input', to: '/docs/ui/components/Form/FormInput' }, - { from: '/docs/ui/components/deprecated/Dropdown', to: '/docs/ui/components/Form/FormDropdown' }, - { from: '/docs/ui/components/deprecated/Slider', to: '/docs/ui/components/Form/FormSlider' }, - { from: '/docs/ui/components/deprecated/modal-field-props', to: '/docs/ui/components/Form' }, + { from: '/docs/ui/components/deprecated/Input', to: '/docs/ui/components/fields/Input' }, + { from: '/docs/ui/components/deprecated/Dropdown', to: '/docs/ui/components/fields/Dropdown' }, + { from: '/docs/ui/components/deprecated/Slider', to: '/docs/ui/components/fields/Slider' }, + { from: '/docs/ui/components/deprecated/modal-field-props', to: '/docs/ui/components/roots/Form' }, { from: '/docs/ore-styled/Form/FormCheckbox', to: '/docs/ore-styled/Checkbox' }, { from: '/docs/ore-styled/Form/FormToggle', to: '/docs/ore-styled/Toggle' }, { from: '/docs/ore-styled/Form/FormRadio', to: '/docs/ore-styled/Radio' }, @@ -139,4 +139,15 @@ export const redirects: { from: string; to: string }[] = [ { from: '/docs/ui/components/Hotbar', to: '/docs/ui/components/cells/Hotbar' }, { from: '/docs/ui/components/Expect', to: '/docs/ui/components/cross-pack/Expect' }, { from: '/docs/ui/components/Embed', to: '/docs/ui/components/cross-pack/Embed' }, + { from: '/docs/ui/components/Form/FormToggle', to: '/docs/ui/components/controls/Toggle' }, + { from: '/docs/ui/components/Form/FormInlineSelect', to: '/docs/ui/components/controls/Select' }, + { from: '/docs/ui/components/Form/FormOption', to: '/docs/ui/components/controls/Option' }, + { from: '/docs/ui/components/Form/FormInput', to: '/docs/ui/components/fields/Input' }, + { from: '/docs/ui/components/Form/FormSlider', to: '/docs/ui/components/fields/Slider' }, + { from: '/docs/ui/components/Form/FormDropdown', to: '/docs/ui/components/fields/Dropdown' }, + { from: '/docs/ui/components/Form/FormButton', to: '/docs/ui/components/controls/Button' }, + { from: '/docs/ui/components/Form', to: '/docs/ui/components/roots/Form' }, + { from: '/docs/ore-styled/Form', to: '/docs/ui/components/roots/Form' }, + { from: '/docs/ore-styled/Form/Form', to: '/docs/ui/components/roots/Form' }, + { from: '/docs/ore-styled/Form/FormButton', to: '/docs/ore-styled/Button' }, ]; From 94698e447ab5d137a965d57e8daefd2104a4af0a Mon Sep 17 00:00:00 2001 From: DrAv0011 Date: Mon, 14 Sep 2026 02:50:33 +0200 Subject: [PATCH 34/48] docs(server,sync): presence is an observable list discovery.peers, discovery.incompatiblePeers and core.registry.addons read with get() and watch with subscribe(). lastSeen is no longer a field on PeerInfo or IncompatiblePeer, and core.host.hostId is now core.host.id. Co-Authored-By: Claude Opus 5 (1M context) --- docs/server/api/host.md | 27 +++++++++++++++--------- docs/server/api/registry.md | 41 +++++++++++++++++++++++++++++-------- docs/sync/discovery.md | 31 ++++++++++++++++++++-------- 3 files changed, 72 insertions(+), 27 deletions(-) diff --git a/docs/server/api/host.md b/docs/server/api/host.md index 6a94253..a9f1853 100644 --- a/docs/server/api/host.md +++ b/docs/server/api/host.md @@ -9,6 +9,8 @@ description: "core.host answers one question: should this realm do the work that Some jobs cannot be done by every addon at once — rendering a shared config or guide UI is the motivating one. Host election picks a single realm for those, deterministically, with no negotiation messages at all. +The winner is a pure function of the [registry](./registry.md), so it is expressed as one: `core.host.id` is `computed` over `core.registry.addons` and re-derives itself whenever an addon appears or disappears. + ## Import ```ts @@ -23,15 +25,15 @@ import type { HostListener } from '@bedrock-core/server'; if (core.host.isHost) { renderLocally(player); } else { - void core.rpc.request(core.host.hostId, 'core:ui.open', { playerId: player.id }); + void core.rpc.request(core.host.id.get(), 'core:ui.open', { playerId: player.id }); } -core.host.subscribe(hostId => console.warn('UI host is now', hostId)); +core.host.id.subscribe(hostId => console.warn('UI host is now', hostId)); ``` ## Why it exists -Bedrock's custom-command registry is **world-global** and has no unregister API, so whichever realm loads first *owns* a given command name for the life of the world. That ownership is immovable — who does the **rendering** is not. The election picks the realm running the newest `@bedrock-core/server-runtime`, and the command owner becomes a router: it forwards the request to `core.host.hostId` instead of rendering locally. +Bedrock's custom-command registry is **world-global** and has no unregister API, so whichever realm loads first *owns* a given command name for the life of the world. That ownership is immovable — who does the **rendering** is not. The election picks the realm running the newest `@bedrock-core/server-runtime`, and the command owner becomes a router: it forwards the request to `core.host.id.get()` instead of rendering locally. The practical consequence: **installing one up-to-date bedrock-core addon upgrades the shared UI for every addon in the world**, including ones whose authors never shipped again. @@ -58,13 +60,18 @@ core.host.isHost: boolean Whether this realm is the current host and should do the work itself. -### `hostId` +### `id` ```ts -core.host.hostId: string +core.host.id: ReadonlyObservable ``` -Namespace of the realm running the newest runtime. Falls back to this addon's own id when the registry is somehow empty, so callers always have a target to address. +Namespace of the realm running the newest runtime, as an observable. Falls back to this addon's own id when the registry is somehow empty, so callers always have a target to address. + +```ts +core.host.id.get(); // who hosts right now +effect(() => refreshBanner(core.host.id.get()), [core.host.id]); +``` ### `host` @@ -79,15 +86,15 @@ The elected host's [registry entry](./registry.md#registeredaddon), when it is s ```ts core.host.subscribe(listener: HostListener): Unsubscribe -type HostListener = (hostId: string, previousHostId: string | undefined) => void; +type HostListener = (hostId: string, previousHostId: string) => void; ``` -Notified when hosting **moves**. Fires only on an actual change — including the initial election, if you subscribe before peers appear. Returns an unsubscribe function. +Notified when hosting **moves** — shorthand for `core.host.id.subscribe(...)`. Fires only on an actual change; subscribing does not deliver the current host, which `core.host.id` already has. Returns an unsubscribe function. ```ts core.host.subscribe((hostId, previousHostId) => { if (hostId === core.id) { - console.warn(`[economy] took over hosting from ${String(previousHostId)}`); + console.warn(`[economy] took over hosting from ${previousHostId}`); } }); ``` @@ -105,7 +112,7 @@ function dispatch(player: Player, command: string, args: (string | undefined)[]) return; } - void core.rpc.request(core.host.hostId, 'core:ui.open', { + void core.rpc.request(core.host.id.get(), 'core:ui.open', { playerId: player.id, command, args, diff --git a/docs/server/api/registry.md b/docs/server/api/registry.md index 480e64a..cadf13d 100644 --- a/docs/server/api/registry.md +++ b/docs/server/api/registry.md @@ -7,6 +7,8 @@ description: "core.registry is a live directory of every bedrock-core addon pres `core.registry` is a live directory of every bedrock-core addon present in the world — the local addon plus every peer [discovery](/docs/sync/discovery) can currently see. Each peer's announce `meta` blob is interpreted as an [`AddonManifest`](./runtime.md#manifest-fields), keyed by its namespace. +The directory itself is [`addons`](#addons), a [`ReadonlyObservable`](/docs/observable) list derived from discovery. `all()`, `get()` and `has()` all read that one list, so there is never a cached answer to "who is here" that can disagree with the live one. + ## Import ```ts @@ -17,7 +19,9 @@ import type { RegisteredAddon, AddonListener, CollisionListener, IncompatibleLis ## Usage ```ts -core.registry.all(); // RegisteredAddon[] — self + all live peers +core.registry.addons.subscribe(addons => redraw(addons)); // who is here, as a value + +core.registry.all(); // readonly RegisteredAddon[] — self + all live peers core.registry.get('drav0011_economy'); // by namespace, or undefined core.registry.has('drav0011_economy'); // boolean @@ -50,13 +54,27 @@ A peer's manifest is reconstructed from its discovery `meta`. A node that publis ## API +### `addons` + +```ts +core.registry.addons: ReadonlyObservable +``` + +Every registered addon as an observable list, the local one first. Subscribe to it to track **who is present**; `computed()` over it to derive something from the set. + +```ts +const addonCount = computed(() => core.registry.addons.get().length, [core.registry.addons]); +``` + +It republishes when an addon appears or disappears, and when a peer re-announces something new — never on the heartbeats that repeat what a peer already said. + ### `all` ```ts -core.registry.all(): RegisteredAddon[] +core.registry.all(): readonly RegisteredAddon[] ``` -Every registered addon: the local one first, then every live peer. +A snapshot of [`addons`](#addons): the local addon first, then every live peer. ```ts for (const addon of core.registry.all()) { @@ -86,7 +104,7 @@ Whether an addon with that namespace is present. This is the predicate feature c core.registry.onRegister(listener: AddonListener): Unsubscribe ``` -Fires when a **peer** becomes visible. Returns an unsubscribe function. +Fires when a **peer** becomes visible. Returns an unsubscribe function. This is a delta: to react to who is present rather than to each arrival, subscribe to [`addons`](#addons). ```ts const off = core.registry.onRegister((addon) => { @@ -137,13 +155,12 @@ core.registry.onNamespaceCollision((info) => { ### `incompatible` ```ts -core.registry.incompatible(): IncompatiblePeer[] +core.registry.incompatible(): readonly IncompatiblePeer[] interface IncompatiblePeer { id: string; pmin: number; pmax: number; - lastSeen: number; } ``` @@ -181,13 +198,21 @@ core.register({ }); ``` +### `missing` + +```ts +core.registry.missing: ReadonlyObservable +``` + +The declared dependencies that are not currently present, as an observable list. Empty means satisfied. + ### `missingDependencies` ```ts -core.registry.missingDependencies(): string[] +core.registry.missingDependencies(): readonly string[] ``` -The declared dependencies that are not currently present. +A snapshot of [`missing`](#missing). ```ts core.registry.missingDependencies(); // ['drav0011_economy'] until it registers diff --git a/docs/sync/discovery.md b/docs/sync/discovery.md index 9350d42..c7fd28a 100644 --- a/docs/sync/discovery.md +++ b/docs/sync/discovery.md @@ -9,6 +9,8 @@ description: "sync.discovery finds the other bedrock-core nodes in the world and Script events are ephemeral: a pack that loads after another has already announced never hears that announce. Discovery solves that two ways — every node re-announces on a heartbeat, and a freshly started node broadcasts a `whois` that prompts existing peers to announce straight back. A TTL sweep drops peers that go quiet. +Who is present is a **value**, not a stream: `peers` is a [`ReadonlyObservable`](/docs/observable) list you read with `.get()`, watch with `.subscribe()`, or derive from with `computed()`. It republishes only when the world actually changes — a heartbeat repeating what a peer already said notifies nobody, so a listener can sit on the list without waking every five seconds per peer. + ## Import ```ts @@ -18,13 +20,17 @@ import type { PeerInfo, CollisionInfo, IncompatiblePeer, PeerListener, Collision ## Usage ```ts +sync.discovery.peers.subscribe(peers => console.warn(`${peers.length} peers`)); + sync.discovery.onPeerUp(peer => console.warn(`${peer.id} v${peer.version} joined`)); sync.discovery.onPeerDown(peer => console.warn(`${peer.id} left`)); -const peers = sync.discovery.peers; +const peers = sync.discovery.peers.get(); const economy = sync.discovery.getPeer('drav0011_economy'); ``` +Subscribe to `peers` to react to **who is here**; use `onPeerUp` / `onPeerDown` to react to a single arrival or departure. + From a runtime, the same information arrives pre-interpreted through [`core.registry`](/docs/server/api/registry), which turns each peer's `meta` into an addon manifest. Reach for `core.node.discovery` only when you want the raw peer records. ## `PeerInfo` @@ -37,7 +43,6 @@ interface PeerInfo { protocol: number; caps: readonly string[]; meta?: Record; - lastSeen: number; } ``` @@ -49,7 +54,8 @@ interface PeerInfo { | `protocol` | The wire version this node and that peer [settled on](#protocol-negotiation). | | `caps` | Optional behaviors the peer can read, narrowed to what `protocol` allows. | | `meta` | The opaque blob it attached to its announce. `server-runtime` puts the addon manifest plus `runtimeVersion` here. | -| `lastSeen` | The tick this peer was last heard from. | + +Liveness is deliberately **not** a field here. A tick that moves on every heartbeat inside an observable value would make the list republish every five seconds per peer; ask for it by id with [`lastSeen`](#lastseen) instead. ## Protocol negotiation @@ -78,10 +84,18 @@ A capability is always narrowed by the negotiated version: one advertised by a n ### `peers` ```ts -sync.discovery.peers: PeerInfo[] +sync.discovery.peers: ReadonlyObservable +``` + +Known live peers, as an observable list. **Excludes self.** Each notification carries a fresh array; the `PeerInfo` objects inside it are never mutated. + +### `lastSeen` + +```ts +sync.discovery.lastSeen(id: string): number | undefined ``` -Known live peers. **Excludes self.** +The tick a node was last heard from, or `undefined` if it has never been heard. Covers unreachable nodes as well as peers. ### `getPeer` @@ -95,7 +109,7 @@ sync.discovery.getPeer(id: string): PeerInfo | undefined sync.discovery.onPeerUp(listener: PeerListener): Unsubscribe ``` -Fires when a peer is seen for the **first** time. Subsequent heartbeats from the same peer refresh `lastSeen` without re-firing. +Fires when a peer is seen for the **first** time. Subsequent heartbeats from the same peer refresh its liveness without re-firing, and without republishing `peers` unless the peer said something new (a version bump, a changed `meta`). ### `onPeerDown` @@ -103,7 +117,7 @@ Fires when a peer is seen for the **first** time. Subsequent heartbeats from the sync.discovery.onPeerDown(listener: PeerListener): Unsubscribe ``` -Fires when a peer expires — its `lastSeen` fell outside the TTL window during a sweep. Note that this is a **timeout**, not a graceful goodbye: there is no "leaving" message, so a peer that stops answering takes up to the TTL to disappear. +Fires when a peer expires — it was last heard outside the TTL window when a sweep ran. `peers` is republished once for the whole sweep, before any listener runs, so a handler reading the list never sees a half-swept world. Note that this is a **timeout**, not a graceful goodbye: there is no "leaving" message, so a peer that stops answering takes up to the TTL to disappear. ### `onCollision` @@ -123,13 +137,12 @@ At the runtime layer this is [`core.registry.onNamespaceCollision`](/docs/server ### `incompatiblePeers` ```ts -sync.discovery.incompatiblePeers: IncompatiblePeer[] +sync.discovery.incompatiblePeers: ReadonlyObservable interface IncompatiblePeer { id: string; pmin: number; pmax: number; - lastSeen: number; } ``` From c9ab065fe146ea337c25f22496929970b89e641f Mon Sep 17 00:00:00 2001 From: DrAv0011 Date: Thu, 17 Sep 2026 17:35:16 +0200 Subject: [PATCH 35/48] docs(site): local search, a catalog section, beta labels - Search is built into the site at build time with docusaurus-search-local; the Algolia block and its environment variables are removed. - catalog is a section of its own, and config's description covers settings only. - Every package is labelled beta. - The section switcher opens with the active section in view, a table's name column wraps only at spaces, and redirects point at the current page locations. - The addon list, config screen and guide page screenshots are retaken. Co-Authored-By: Claude Opus 5 (1M context) --- .env.example | 8 +- .github/workflows/deploy.yml | 5 - README.md | 35 +-- STYLE.md | 2 +- design/COMPONENT-REFERENCE.md | 14 +- design/DESIGN-GUIDE.md | 2 +- docusaurus.config.ts | 50 ++-- package.json | 1 + sidebars.ts | 3 + src/components/Home/index.tsx | 2 +- src/components/nav/SectionSwitcher.tsx | 14 +- src/css/bedrock/infima-bridge.css | 76 ++--- src/data/redirects.ts | 109 +++---- src/data/sections.ts | 12 +- src/pages/index.tsx | 4 +- static/img/ui/addon-list.png | Bin 35771 -> 30368 bytes static/img/ui/config-screen.png | Bin 32618 -> 45113 bytes static/img/ui/guide-page.png | Bin 33411 -> 79681 bytes tsconfig.json | 4 + yarn.lock | 400 ++++++++++++++++++++++++- 20 files changed, 532 insertions(+), 209 deletions(-) diff --git a/.env.example b/.env.example index 638a231..563b11d 100644 --- a/.env.example +++ b/.env.example @@ -1,7 +1 @@ -# DocSearch. Apply at https://docsearch.algolia.com/apply/ and copy the values -# from the Algolia dashboard. The key is the search-only one, which ships in the -# client bundle and is safe to expose; never use an admin or write key here. -# Leave these unset to build the site without a search box. -ALGOLIA_APP_ID= -ALGOLIA_SEARCH_API_KEY= -ALGOLIA_INDEX_NAME= +# No environment variables are required to run or build this site. diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index b5f6bfb..fadf2f2 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -26,11 +26,6 @@ jobs: run: yarn install --frozen-lockfile - name: Build website run: yarn build - env: - # DocSearch. Unset means the site builds without a search box. - ALGOLIA_APP_ID: ${{ vars.ALGOLIA_APP_ID }} - ALGOLIA_SEARCH_API_KEY: ${{ secrets.ALGOLIA_SEARCH_API_KEY }} - ALGOLIA_INDEX_NAME: ${{ vars.ALGOLIA_INDEX_NAME }} # From v4 this action excludes dotfiles, so Docusaurus's `.nojekyll` is not in the artifact. # Harmless here: artifact deployments are served as-is and never run Jekyll, and the build diff --git a/README.md b/README.md index 8d39b9c..37e9ca5 100644 --- a/README.md +++ b/README.md @@ -1,29 +1,22 @@ # @bedrock-core/docs -Documentation for @bedrock-core, built using [Docusaurus](https://docusaurus.io/). +Documentation for @bedrock-core, built with [Docusaurus](https://docusaurus.io/). -Available in +Available at -## Installation +## Install ```bash yarn ``` -## Local Development +## Develop ```bash yarn start ``` -This command starts a local development server and opens up a browser window. Most changes are reflected live without having to restart the server. - -## Search - -DocSearch is configured from the environment. Copy `.env.example` to `.env` and -fill in the three values from the Algolia dashboard; without them the site builds -with no search box. The deploy workflow reads the same names from repository -variables and secrets. +Starts a local dev server and opens a browser window. Most changes are reflected live without a restart. ## Build @@ -31,20 +24,12 @@ variables and secrets. yarn build ``` -This command generates static content into the `build` directory and can be served using any static contents hosting service. - -## Deployment - -Using SSH: +Generates static content into the `build` directory, servable by any static hosting service. -```bash -USE_SSH=true yarn deploy -``` +## Writing a page -Not using SSH: +Every page under `docs/` follows [`STYLE.md`](./STYLE.md). -```bash -GIT_USER= yarn deploy -``` +## Sections -If you are using GitHub pages for hosting, this command is a convenient way to build the website and push to the `gh-pages` branch. +`src/data/sections.ts` is the registry of sections: id, category, status, description, icon and source repository. `docusaurus.config.ts` creates one docs-plugin instance per section that has a matching `docs/` folder, and the navbar, sidebar switcher and home page all read the same registry. diff --git a/STYLE.md b/STYLE.md index a4a8c51..2ae3e69 100644 --- a/STYLE.md +++ b/STYLE.md @@ -28,7 +28,7 @@ Links: relative `.md` inside a section, absolute `/docs/
    /...` across se # ore-styled ← package name, lowercase One sentence. -:::caution Pre-1.0 … ::: ← until this package ships 1.0 +:::caution Beta … ::: ← until this package ships 1.0 ## What is @bedrock-core/ore-styled? ## Install diff --git a/design/COMPONENT-REFERENCE.md b/design/COMPONENT-REFERENCE.md index 36b591c..ce12faf 100644 --- a/design/COMPONENT-REFERENCE.md +++ b/design/COMPONENT-REFERENCE.md @@ -13,7 +13,7 @@ markup and class-free inline styling the design system expects. Mono-type status pill for release state and stability markers. ```jsx -pre-1.0 +beta v0.9.2 ``` @@ -349,7 +349,7 @@ export declare function PaginationNav(props: PaginationNavProps): JSX.Element; Sidebar header that names the current docs section and drops down to switch. Pair it with `SidebarNav`'s `header` slot — it is the flat, searchable counterpart to `DocsMenu`. ```jsx -} … /> +} … /> ```
    Props contract @@ -370,7 +370,7 @@ export interface SectionSwitcherProps { value?: string; onChange?: (id: string) => void; scope?: string; - /** Release badge shown on the closed trigger, e.g. "pre-1.0". */ + /** Release badge shown on the closed trigger, e.g. "beta". */ status?: string; style?: React.CSSProperties; } @@ -462,10 +462,10 @@ export declare function TableOfContents(props: TableOfContentsProps): JSX.Elemen ### Callout -Admonition block for the docs body — the "Pre-1.0" banner on every package overview is `kind="warning"`. +Admonition block for the docs body — the "Beta" banner on every package overview is `kind="warning"`. ```jsx -Breaking changes can still land until 1.0.0. +The API can change between releases. ```
    Props contract @@ -589,7 +589,7 @@ export declare function NextStepsList(props: NextStepsListProps): JSX.Element; Tile for one package in the homepage grid or a docs index. ```jsx - ``` @@ -608,7 +608,7 @@ export interface PackageCardProps { icon?: string; /** Package identity colour — pass a --pkg-* token. */ accent?: string; - /** Short release-state label, e.g. "pre-1.0". */ + /** Short release-state label, e.g. "beta". */ status?: string; href?: string; style?: React.CSSProperties; diff --git a/design/DESIGN-GUIDE.md b/design/DESIGN-GUIDE.md index 6b0f8bd..339df37 100644 --- a/design/DESIGN-GUIDE.md +++ b/design/DESIGN-GUIDE.md @@ -43,7 +43,7 @@ The existing docs voice is unusually good and this system preserves it verbatim **Feature bullets** follow a strict shape: **bold noun** — em dash — one sentence that says what it does *and* what it protects you from. *"**RPC** — typed request/response calls to another addon, with a timeout so an absent peer can never hang your code."* -**Honesty about maturity.** Every package overview opens with the same Pre-1.0 admonition. Limitations are stated as facts, not hidden: *"A state change on its own does not repaint their screen."* Optional layers are explicitly optional: *"It's optional — pick it up when you want batteries-included visuals, skip it when you'd rather style every primitive yourself."* +**Honesty about maturity.** Every package overview opens with the same Beta admonition. Limitations are stated as facts, not hidden: *"A state change on its own does not repaint their screen."* Optional layers are explicitly optional: *"It's optional — pick it up when you want batteries-included visuals, skip it when you'd rather style every primitive yourself."* **Page rhythm.** Every docs page ends with a **Next Steps** list of `link — short description` pairs. Keep it. diff --git a/docusaurus.config.ts b/docusaurus.config.ts index 8b2aa6c..feff7f9 100644 --- a/docusaurus.config.ts +++ b/docusaurus.config.ts @@ -1,6 +1,6 @@ import type { Config } from '@docusaurus/types'; import type * as Preset from '@docusaurus/preset-classic'; -import { existsSync, readFileSync } from 'node:fs'; +import { existsSync } from 'node:fs'; import { categories, publishedSections, sectionsOf } from './src/data/sections'; import { redirects } from './src/data/redirects'; import { bedrockPrism } from './src/prism/bedrock'; @@ -10,35 +10,6 @@ import { bedrockPrism } from './src/prism/bedrock'; const liveSections = publishedSections.filter((section) => existsSync(`docs/${section.id}`)); const isLive = (id: string): boolean => liveSections.some((section) => section.id === id); -// Search credentials come from the environment; a local .env fills them in for -// development. Without them the algolia block is omitted, the search theme is -// never loaded and the search box disappears instead of rendering inert. -function envFile(): Record { - if (!existsSync('.env')) return {}; - return Object.fromEntries( - readFileSync('.env', 'utf8') - .split(/\r?\n/) - .map((line) => line.trim()) - .filter((line) => line && !line.startsWith('#')) - .map((line) => { - const at = line.indexOf('='); - return [line.slice(0, at).trim(), line.slice(at + 1).trim().replace(/^["']|["']$/g, '')]; - }) - .filter(([key]) => key), - ); -} - -const env = { ...envFile(), ...process.env } as Record; -const algolia = - env.ALGOLIA_APP_ID && env.ALGOLIA_SEARCH_API_KEY && env.ALGOLIA_INDEX_NAME - ? { - appId: env.ALGOLIA_APP_ID, - apiKey: env.ALGOLIA_SEARCH_API_KEY, - indexName: env.ALGOLIA_INDEX_NAME, - contextualSearch: false, - } - : undefined; - // This runs in Node.js - Don't use client-side code here (browser APIs, JSX...) const config: Config = { @@ -116,6 +87,22 @@ const config: Config = { ], }, ], + // Builds a search index at build time, so search works offline and on the + // deployed site with no external service or credentials. + [ + '@easyops-cn/docusaurus-search-local', + { + hashed: true, + language: ['en'], + indexBlog: false, + indexPages: true, + docsRouteBasePath: liveSections.map((section) => `docs/${section.id}`), + // None of these sections are versioned; this only has to name a real + // plugin id so the search bar's version lookup has one to fall back + // on outside a docs route (the home page, the 404 page, /search). + docsPluginIdForPreferredVersion: 'server', + }, + ], ], themeConfig: { @@ -136,9 +123,6 @@ const config: Config = { { type: 'custom-iconLink', position: 'right', href: 'https://github.com/bedrock-core/', icon: 'github', label: 'GitHub' }, ], }, - // DocSearch: apply at https://docsearch.algolia.com/apply/, then set the - // three ALGOLIA_ variables. See .env.example. - ...(algolia ? { algolia } : {}), // Code blocks stay dark in both themes; one palette serves both. prism: { theme: bedrockPrism, diff --git a/package.json b/package.json index 3815cc4..99f7495 100644 --- a/package.json +++ b/package.json @@ -20,6 +20,7 @@ "@docusaurus/faster": "^3.10.2", "@docusaurus/plugin-client-redirects": "^3.10.2", "@docusaurus/preset-classic": "^3.10.2", + "@easyops-cn/docusaurus-search-local": "^0.55.3", "@mdx-js/react": "^3.1.1", "clsx": "^2.1.1", "lucide-react": "^1.42.0", diff --git a/sidebars.ts b/sidebars.ts index e0dac8d..13d2bca 100644 --- a/sidebars.ts +++ b/sidebars.ts @@ -2,6 +2,9 @@ import type { SidebarsConfig } from '@docusaurus/plugin-content-docs'; // Every docs instance reads this file and builds its `docs` sidebar from its // own folder: `_category_.json` files group pages, `sidebar_position` orders them. +// A page without a position sorts after the positioned ones, by file name, with +// uppercase before lowercase: ore-styled positions only its overview, so its +// components list alphabetically and its helpers (`fieldLabel`, `theme`) last. const sidebars: SidebarsConfig = { docs: [ { diff --git a/src/components/Home/index.tsx b/src/components/Home/index.tsx index f474e52..d9bd99f 100644 --- a/src/components/Home/index.tsx +++ b/src/components/Home/index.tsx @@ -225,7 +225,7 @@ export function Cta(): ReactNode {

    Start with one package.

    -

    Pin an exact version while a package is in beta, and read the release notes before you upgrade.

    +

    Pin an exact version, and read the changelog before you upgrade.

    {open ? ( -
    +
    {categories.map((category) => sections .filter((s) => s.category === category.id) diff --git a/src/css/bedrock/infima-bridge.css b/src/css/bedrock/infima-bridge.css index 8a7372f..3380fd8 100644 --- a/src/css/bedrock/infima-bridge.css +++ b/src/css/bedrock/infima-bridge.css @@ -274,7 +274,8 @@ table td:first-child code { color: var(--text-strong); font-weight: var(--weight .required { color: var(--status-danger); font-weight: var(--weight-bold); margin-left: 2px; } table td a code { color: var(--ifm-link-color); font-weight: var(--weight-semibold); } table td a:hover code { color: var(--ifm-link-hover-color); text-decoration: underline; } -table td:first-child { white-space: nowrap; } +/* the name column wraps only at spaces: a single identifier never breaks, a call signature does */ +table td:first-child { white-space: normal; overflow-wrap: normal; word-break: normal; } /* Next steps closes a page: one card per link, mono title, description alongside */ .markdown h2#next-steps ~ ul { @@ -330,72 +331,47 @@ table td:first-child { white-space: nowrap; } /* focus ring */ :focus-visible { outline: 2px solid var(--focus-ring); outline-offset: 2px; } -/* navbar right cluster: room before the theme toggle; DocSearch button as the kit's SearchInput */ +/* navbar right cluster: room before the theme toggle; the local search input as the kit's SearchInput */ .navbar__items--right { gap: var(--space-2); } .navbar__items--right > * { margin: 0; } -.DocSearch-Button { +:root { --ifm-navbar-search-input-color: var(--text-faint); } +.navbar__search-input { height: 32px; width: 220px; - margin: 0; - padding: 0 8px 0 10px; + padding: 0 8px 0 30px; border-radius: var(--radius-sm); background: var(--bg-surface); border: 1px solid var(--border-default); - color: var(--text-faint); + color: var(--text-body); font-family: var(--font-sans); font-size: var(--text-body-sm); box-shadow: none; transition: var(--transition-control); } -.DocSearch-Button:hover, .DocSearch-Button:focus-visible { +.navbar__search-input::placeholder { color: var(--text-faint); } +.navbar__search-input:hover, .navbar__search-input:focus { background: var(--bg-surface); border-color: var(--border-accent); box-shadow: var(--shadow-focus); - color: var(--text-faint); } -.DocSearch-Button .DocSearch-Search-Icon { width: 14px; height: 14px; color: var(--text-faint); } -.DocSearch-Button-Placeholder { flex: 1; text-align: left; padding: 0 0 0 var(--space-2); font-size: var(--text-body-sm); } -.DocSearch-Button-Keys { min-width: 0; gap: 3px; } -.DocSearch-Button-Key { - width: auto; - min-width: 22px; - height: 22px; - padding: 0 6px; - margin: 0; - top: 0; - border-radius: var(--radius-xs); - border: 1px solid var(--border-default); - border-bottom-width: 2px; - background: var(--bg-surface); - box-shadow: none; - color: var(--text-muted); - font-family: var(--font-mono); - font-size: var(--text-micro); +@media (max-width: 768px) { .navbar__search-input { width: 32px; } } +/* Local search results dropdown, on the same tokens: no card shadow on a hit + row, --shadow-md (the kit's popover level) on the dropdown itself. */ +:root { + --search-local-modal-background: var(--bg-raised); + --search-local-modal-shadow: var(--shadow-md); + --search-local-modal-width: 480px; + --search-local-spacing: var(--space-3); + --search-local-hit-height: 48px; + --search-local-hit-background: transparent; + --search-local-hit-shadow: none; + --search-local-hit-color: var(--text-body); + --search-local-hit-active-color: var(--accent-on-solid); + --search-local-highlight-color: var(--accent-solid); + --search-local-muted-color: var(--text-faint); + --search-local-input-active-border-color: var(--border-accent); + --search-local-icon-stroke-width: 1.6; } -@media (max-width: 768px) { .DocSearch-Button { width: 32px; padding: 0; justify-content: center; } .DocSearch-Button-Placeholder, .DocSearch-Button-Keys { display: none; } } -/* DocSearch modal on the same tokens */ -.DocSearch { - --docsearch-primary-color: var(--accent-solid); - --docsearch-text-color: var(--text-body); - --docsearch-muted-color: var(--text-muted); - --docsearch-container-background: var(--overlay-scrim); - --docsearch-modal-background: var(--bg-raised); - --docsearch-modal-shadow: var(--shadow-lg); - --docsearch-searchbox-background: var(--bg-surface); - --docsearch-searchbox-focus-background: var(--bg-surface); - --docsearch-searchbox-shadow: 0 0 0 1px var(--border-accent); - --docsearch-hit-color: var(--text-body); - --docsearch-hit-background: var(--bg-surface); - --docsearch-hit-active-color: var(--accent-on-solid); - --docsearch-hit-shadow: none; - --docsearch-key-gradient: var(--bg-surface); - --docsearch-key-shadow: 0 0 0 1px var(--border-default); - --docsearch-footer-background: var(--bg-sunken); - --docsearch-footer-shadow: 0 -1px 0 var(--border-subtle); - --docsearch-logo-color: var(--text-faint); -} -.DocSearch-Modal { border: 1px solid var(--border-default); border-radius: var(--radius-lg); } -.DocSearch-Hit a { border-radius: var(--radius-sm); } /* the navbar never uses the Docusaurus drawer: below 996px it keeps the desktop layout, the right cluster collapses to icons at 768px and the left one at 600px */ diff --git a/src/data/redirects.ts b/src/data/redirects.ts index 7f17c3d..c22c7b9 100644 --- a/src/data/redirects.ts +++ b/src/data/redirects.ts @@ -4,7 +4,8 @@ export const redirects: { from: string; to: string }[] = [ { from: '/docs/server/get-started/installation', to: '/docs/server/installation' }, { from: '/docs/server/get-started/overview', to: '/docs/server' }, { from: '/docs/server/server-runtime', to: '/docs/server/api/runtime' }, - { from: '/docs/server/server-runtime/config', to: '/docs/server/api/config' }, + { from: '/docs/server/server-runtime/config', to: '/docs/config/settings' }, + { from: '/docs/server/api/config', to: '/docs/config/settings' }, { from: '/docs/server/server-runtime/features', to: '/docs/server/api/features' }, { from: '/docs/server/server-runtime/guides', to: '/docs/guides' }, { from: '/docs/server/server-runtime/host', to: '/docs/server/api/host' }, @@ -16,7 +17,8 @@ export const redirects: { from: string; to: string }[] = [ { from: '/docs/server/sync/protocol', to: '/docs/sync/protocol' }, { from: '/docs/server/sync/rpc', to: '/docs/sync/rpc' }, { from: '/docs/server/sync/state', to: '/docs/sync/state' }, - { from: '/docs/server/ui-integration', to: '/docs/server/guides/ui-integration' }, + { from: '/docs/server/ui-integration', to: '/docs/navigation/realm' }, + { from: '/docs/server/guides/ui-integration', to: '/docs/navigation/realm' }, { from: '/docs/ui/cli', to: '/docs/cli' }, { from: '/docs/ui/config', to: '/docs/config' }, { from: '/docs/ui/container-screens', to: '/docs/ui/guides/container-screens' }, @@ -41,7 +43,7 @@ export const redirects: { from: string; to: string }[] = [ { from: '/docs/ui/ore-styled/Checkbox', to: '/docs/ore-styled/Checkbox' }, { from: '/docs/ui/ore-styled/Divider', to: '/docs/ore-styled/Divider' }, { from: '/docs/ui/ore-styled/Dropdown', to: '/docs/ore-styled/Dropdown' }, - { from: '/docs/ui/ore-styled/Form', to: '/docs/ui/components/roots/Form' }, + { from: '/docs/ui/ore-styled/Form', to: '/docs/ui/components/Form' }, { from: '/docs/ui/ore-styled/Form/FormButton', to: '/docs/ore-styled/Button' }, { from: '/docs/ui/ore-styled/Form/FormCheckbox', to: '/docs/ore-styled/Checkbox' }, { from: '/docs/ui/ore-styled/Form/FormDropdown', to: '/docs/ore-styled/Dropdown' }, @@ -49,14 +51,14 @@ export const redirects: { from: string; to: string }[] = [ { from: '/docs/ui/ore-styled/Form/FormRadio', to: '/docs/ore-styled/Radio' }, { from: '/docs/ui/ore-styled/Form/FormSlider', to: '/docs/ore-styled/Slider' }, { from: '/docs/ui/ore-styled/Form/FormToggle', to: '/docs/ore-styled/Toggle' }, - { from: '/docs/ui/ore-styled/Form/FormToggleButton', to: '/docs/ore-styled/ToggleButton' }, + { from: '/docs/ui/ore-styled/Form/FormToggleButton', to: '/docs/ore-styled/ToggleButtons' }, { from: '/docs/ui/ore-styled/Header', to: '/docs/ore-styled/Header' }, { from: '/docs/ui/ore-styled/Input', to: '/docs/ore-styled/Input' }, { from: '/docs/ui/ore-styled/MenuRow', to: '/docs/ore-styled/MenuRow' }, { from: '/docs/ui/ore-styled/Radio', to: '/docs/ore-styled/Radio' }, { from: '/docs/ui/ore-styled/Slider', to: '/docs/ore-styled/Slider' }, { from: '/docs/ui/ore-styled/Toggle', to: '/docs/ore-styled/Toggle' }, - { from: '/docs/ui/ore-styled/ToggleButton', to: '/docs/ore-styled/ToggleButton' }, + { from: '/docs/ui/ore-styled/ToggleButton', to: '/docs/ore-styled/ToggleButtons' }, { from: '/docs/ui/ore-styled/theme', to: '/docs/ore-styled/theme' }, { from: '/docs/ui/ui-runtime', to: '/docs/ui' }, { from: '/docs/ui/ui-runtime/api', to: '/docs/ui/api' }, @@ -65,31 +67,31 @@ export const redirects: { from: string; to: string }[] = [ { from: '/docs/ui/ui-runtime/api/custom-native-components', to: '/docs/ui/guides/custom-native-components' }, { from: '/docs/ui/ui-runtime/api/render', to: '/docs/ui/api/render' }, { from: '/docs/ui/ui-runtime/components', to: '/docs/ui/components' }, - { from: '/docs/ui/ui-runtime/components/Background', to: '/docs/ui/components/content/Background' }, - { from: '/docs/ui/ui-runtime/components/Button', to: '/docs/ui/components/controls/Button' }, - { from: '/docs/ui/ui-runtime/components/Container', to: '/docs/ui/components/roots/Container' }, - { from: '/docs/ui/ui-runtime/components/Dropdown', to: '/docs/ui/components/fields/Dropdown' }, - { from: '/docs/ui/ui-runtime/components/Form', to: '/docs/ui/components/roots/Form' }, - { from: '/docs/ui/ui-runtime/components/Form/FormButton', to: '/docs/ui/components/controls/Button' }, - { from: '/docs/ui/ui-runtime/components/Form/FormDropdown', to: '/docs/ui/components/fields/Dropdown' }, - { from: '/docs/ui/ui-runtime/components/Form/FormInlineSelect', to: '/docs/ui/components/controls/Select' }, - { from: '/docs/ui/ui-runtime/components/Form/FormInput', to: '/docs/ui/components/fields/Input' }, - { from: '/docs/ui/ui-runtime/components/Form/FormOption', to: '/docs/ui/components/controls/Option' }, - { from: '/docs/ui/ui-runtime/components/Form/FormSlider', to: '/docs/ui/components/fields/Slider' }, - { from: '/docs/ui/ui-runtime/components/Form/FormToggle', to: '/docs/ui/components/controls/Toggle' }, - { from: '/docs/ui/ui-runtime/components/Fragment', to: '/docs/ui/components/layout/Fragment' }, - { from: '/docs/ui/ui-runtime/components/Hotbar', to: '/docs/ui/components/cells/Hotbar' }, - { from: '/docs/ui/ui-runtime/components/Image', to: '/docs/ui/components/content/Image' }, - { from: '/docs/ui/ui-runtime/components/Input', to: '/docs/ui/components/fields/Input' }, - { from: '/docs/ui/ui-runtime/components/Panel', to: '/docs/ui/components/layout/Panel' }, - { from: '/docs/ui/ui-runtime/components/PlayerInventory', to: '/docs/ui/components/cells/PlayerInventory' }, - { from: '/docs/ui/ui-runtime/components/Scroll', to: '/docs/ui/components/layout/Scroll' }, - { from: '/docs/ui/ui-runtime/components/Slider', to: '/docs/ui/components/fields/Slider' }, - { from: '/docs/ui/ui-runtime/components/Slot', to: '/docs/ui/components/cells/Slot' }, - { from: '/docs/ui/ui-runtime/components/SlotGrid', to: '/docs/ui/components/cells/SlotGrid' }, - { from: '/docs/ui/ui-runtime/components/Text', to: '/docs/ui/components/content/Text' }, + { from: '/docs/ui/ui-runtime/components/Background', to: '/docs/ui/components/Background' }, + { from: '/docs/ui/ui-runtime/components/Button', to: '/docs/ui/components/Button' }, + { from: '/docs/ui/ui-runtime/components/Container', to: '/docs/ui/components/Container' }, + { from: '/docs/ui/ui-runtime/components/Dropdown', to: '/docs/ui/components/Dropdown' }, + { from: '/docs/ui/ui-runtime/components/Form', to: '/docs/ui/components/Form' }, + { from: '/docs/ui/ui-runtime/components/Form/FormButton', to: '/docs/ui/components/Button' }, + { from: '/docs/ui/ui-runtime/components/Form/FormDropdown', to: '/docs/ui/components/Dropdown' }, + { from: '/docs/ui/ui-runtime/components/Form/FormInlineSelect', to: '/docs/ui/components/Select' }, + { from: '/docs/ui/ui-runtime/components/Form/FormInput', to: '/docs/ui/components/Input' }, + { from: '/docs/ui/ui-runtime/components/Form/FormOption', to: '/docs/ui/components/Option' }, + { from: '/docs/ui/ui-runtime/components/Form/FormSlider', to: '/docs/ui/components/Slider' }, + { from: '/docs/ui/ui-runtime/components/Form/FormToggle', to: '/docs/ui/components/Toggle' }, + { from: '/docs/ui/ui-runtime/components/Fragment', to: '/docs/ui/components/Fragment' }, + { from: '/docs/ui/ui-runtime/components/Hotbar', to: '/docs/ui/components/Hotbar' }, + { from: '/docs/ui/ui-runtime/components/Image', to: '/docs/ui/components/Image' }, + { from: '/docs/ui/ui-runtime/components/Input', to: '/docs/ui/components/Input' }, + { from: '/docs/ui/ui-runtime/components/Panel', to: '/docs/ui/components/Panel' }, + { from: '/docs/ui/ui-runtime/components/PlayerInventory', to: '/docs/ui/components/PlayerInventory' }, + { from: '/docs/ui/ui-runtime/components/Scroll', to: '/docs/ui/components/Scroll' }, + { from: '/docs/ui/ui-runtime/components/Slider', to: '/docs/ui/components/Slider' }, + { from: '/docs/ui/ui-runtime/components/Slot', to: '/docs/ui/components/Slot' }, + { from: '/docs/ui/ui-runtime/components/SlotGrid', to: '/docs/ui/components/SlotGrid' }, + { from: '/docs/ui/ui-runtime/components/Text', to: '/docs/ui/components/Text' }, { from: '/docs/ui/ui-runtime/components/control-props', to: '/docs/ui/components/control-props' }, - { from: '/docs/ui/ui-runtime/components/modal-field-props', to: '/docs/ui/components/roots/Form' }, + { from: '/docs/ui/ui-runtime/components/modal-field-props', to: '/docs/ui/components/Form' }, { from: '/docs/ui/ui-runtime/hooks', to: '/docs/ui/hooks' }, { from: '/docs/ui/ui-runtime/hooks/useContext', to: '/docs/ui/hooks/useContext' }, { from: '/docs/ui/ui-runtime/hooks/useEffect', to: '/docs/ui/hooks/useEffect' }, @@ -109,45 +111,26 @@ export const redirects: { from: string; to: string }[] = [ { from: '/docs/navigation/useRoute', to: '/docs/navigation/useNavigation' }, { from: '/docs/server/api/guides', to: '/docs/guides' }, { from: '/docs/server/api/pages', to: '/docs/navigation/references' }, - { from: '/docs/ui/components/deprecated/Input', to: '/docs/ui/components/fields/Input' }, - { from: '/docs/ui/components/deprecated/Dropdown', to: '/docs/ui/components/fields/Dropdown' }, - { from: '/docs/ui/components/deprecated/Slider', to: '/docs/ui/components/fields/Slider' }, - { from: '/docs/ui/components/deprecated/modal-field-props', to: '/docs/ui/components/roots/Form' }, + { from: '/docs/ui/components/deprecated/Input', to: '/docs/ui/components/Input' }, + { from: '/docs/ui/components/deprecated/Dropdown', to: '/docs/ui/components/Dropdown' }, + { from: '/docs/ui/components/deprecated/Slider', to: '/docs/ui/components/Slider' }, + { from: '/docs/ui/components/deprecated/modal-field-props', to: '/docs/ui/components/Form' }, { from: '/docs/ore-styled/Form/FormCheckbox', to: '/docs/ore-styled/Checkbox' }, { from: '/docs/ore-styled/Form/FormToggle', to: '/docs/ore-styled/Toggle' }, { from: '/docs/ore-styled/Form/FormRadio', to: '/docs/ore-styled/Radio' }, - { from: '/docs/ore-styled/Form/FormToggleButton', to: '/docs/ore-styled/ToggleButton' }, + { from: '/docs/ore-styled/Form/FormToggleButton', to: '/docs/ore-styled/ToggleButtons' }, + { from: '/docs/ore-styled/ToggleButton', to: '/docs/ore-styled/ToggleButtons' }, { from: '/docs/ore-styled/Form/FormSlider', to: '/docs/ore-styled/Slider' }, { from: '/docs/ore-styled/Form/FormDropdown', to: '/docs/ore-styled/Dropdown' }, { from: '/docs/ore-styled/Form/FormInput', to: '/docs/ore-styled/Input' }, - { from: '/docs/ui/components/Screen', to: '/docs/ui/components/roots/Screen' }, - { from: '/docs/ui/components/Container', to: '/docs/ui/components/roots/Container' }, - { from: '/docs/ui/components/Panel', to: '/docs/ui/components/layout/Panel' }, - { from: '/docs/ui/components/Scroll', to: '/docs/ui/components/layout/Scroll' }, - { from: '/docs/ui/components/Fragment', to: '/docs/ui/components/layout/Fragment' }, - { from: '/docs/ui/components/Text', to: '/docs/ui/components/content/Text' }, - { from: '/docs/ui/components/Image', to: '/docs/ui/components/content/Image' }, - { from: '/docs/ui/components/Background', to: '/docs/ui/components/content/Background' }, - { from: '/docs/ui/components/Button', to: '/docs/ui/components/controls/Button' }, - { from: '/docs/ui/components/Link', to: '/docs/ui/components/controls/Link' }, - { from: '/docs/ui/components/Tabs', to: '/docs/ui/components/compiled/Tabs' }, - { from: '/docs/ui/components/Disclosure', to: '/docs/ui/components/compiled/Disclosure' }, - { from: '/docs/ui/components/List', to: '/docs/ui/components/compiled/List' }, - { from: '/docs/ui/components/Slot', to: '/docs/ui/components/cells/Slot' }, - { from: '/docs/ui/components/SlotGrid', to: '/docs/ui/components/cells/SlotGrid' }, - { from: '/docs/ui/components/PlayerInventory', to: '/docs/ui/components/cells/PlayerInventory' }, - { from: '/docs/ui/components/Hotbar', to: '/docs/ui/components/cells/Hotbar' }, - { from: '/docs/ui/components/Expect', to: '/docs/ui/components/cross-pack/Expect' }, - { from: '/docs/ui/components/Embed', to: '/docs/ui/components/cross-pack/Embed' }, - { from: '/docs/ui/components/Form/FormToggle', to: '/docs/ui/components/controls/Toggle' }, - { from: '/docs/ui/components/Form/FormInlineSelect', to: '/docs/ui/components/controls/Select' }, - { from: '/docs/ui/components/Form/FormOption', to: '/docs/ui/components/controls/Option' }, - { from: '/docs/ui/components/Form/FormInput', to: '/docs/ui/components/fields/Input' }, - { from: '/docs/ui/components/Form/FormSlider', to: '/docs/ui/components/fields/Slider' }, - { from: '/docs/ui/components/Form/FormDropdown', to: '/docs/ui/components/fields/Dropdown' }, - { from: '/docs/ui/components/Form/FormButton', to: '/docs/ui/components/controls/Button' }, - { from: '/docs/ui/components/Form', to: '/docs/ui/components/roots/Form' }, - { from: '/docs/ore-styled/Form', to: '/docs/ui/components/roots/Form' }, - { from: '/docs/ore-styled/Form/Form', to: '/docs/ui/components/roots/Form' }, + { from: '/docs/ui/components/Form/FormToggle', to: '/docs/ui/components/Toggle' }, + { from: '/docs/ui/components/Form/FormInlineSelect', to: '/docs/ui/components/Select' }, + { from: '/docs/ui/components/Form/FormOption', to: '/docs/ui/components/Option' }, + { from: '/docs/ui/components/Form/FormInput', to: '/docs/ui/components/Input' }, + { from: '/docs/ui/components/Form/FormSlider', to: '/docs/ui/components/Slider' }, + { from: '/docs/ui/components/Form/FormDropdown', to: '/docs/ui/components/Dropdown' }, + { from: '/docs/ui/components/Form/FormButton', to: '/docs/ui/components/Button' }, + { from: '/docs/ore-styled/Form', to: '/docs/ui/components/Form' }, + { from: '/docs/ore-styled/Form/Form', to: '/docs/ui/components/Form' }, { from: '/docs/ore-styled/Form/FormButton', to: '/docs/ore-styled/Button' }, ]; diff --git a/src/data/sections.ts b/src/data/sections.ts index 44ed3ed..b03e06a 100644 --- a/src/data/sections.ts +++ b/src/data/sections.ts @@ -129,13 +129,23 @@ export const sections: Section[] = [ }, // Content + { + id: 'catalog', + label: 'catalog', + pkg: '@bedrock-core/catalog', + category: 'content', + status: 'beta', + description: 'Every addon in the world, each with the page it published.', + icon: 'layout-list', + repo: `${GH}/apps`, + }, { id: 'config', label: 'config', pkg: '@bedrock-core/config', category: 'content', status: 'beta', - description: 'The shared addon list, settings screens and guide viewer.', + description: 'Settings in three scopes, and the screens that edit them.', icon: 'sliders-horizontal', repo: `${GH}/apps`, }, diff --git a/src/pages/index.tsx b/src/pages/index.tsx index 53b770c..17de5a3 100644 --- a/src/pages/index.tsx +++ b/src/pages/index.tsx @@ -1,8 +1,8 @@ import type { ReactNode } from 'react'; import useDocusaurusContext from '@docusaurus/useDocusaurusContext'; import Layout from '@theme/Layout'; -import PackageGrid from '@site/src/components/PackageGrid'; -import { CodeTour, Cta, Features, Hero } from '@site/src/components/Home'; +import PackageGrid from '../components/PackageGrid'; +import { CodeTour, Cta, Features, Hero } from '../components/Home'; export default function Home(): ReactNode { const { siteConfig } = useDocusaurusContext(); diff --git a/static/img/ui/addon-list.png b/static/img/ui/addon-list.png index d004e5f6c3b05b2846ad008f07d562741f5781ae..3bd38f4e3f03d1286cba8f8e6b95cd0a58c99e3d 100644 GIT binary patch literal 30368 zcmeFZXIN9));1hFZa`2_L=Z$oigc7-wkV>46d@oTgwUi&my+NXL`8v(ln|vfFTt~z3+!b*taVcrG zeVX3jq)OPmTlTkZi9i^@i$jnz`wl_&foHeDFW0Z1Y9z3TX z`@xm>@11#9K^{E&^(iSyN&35CHIhc9z59wF5FhPZ*RL8rvLsUcYXw>?PA?dzc_9Zc z^G7UvIQ778;^Y@4S$S4&yH`g~#~k8j?IdH=M&%AlUN~5L^&ZpdmHmU~TyCBF^WdvS z^6NMjt>+;n5Qz`_Y|Z!&b4d&#qu;w;o>v&bs_l$o;Pc65UR}vvZYh)gs%NWe(0SF> zq_~9b>^ZYf%M)^k>7&{(5)`LDTJIc$(I2H*W9hf{`FB0~+vh^g-(Dk=Nwkm+0s6aa z%X3`_7`aEA6TEoL^j|-6;OhT-^IXXI)-o5qA4{XEIa=+91Wv5Y;?k&VITJn0?+XgJ zRfB$fZwMha29oM>2oiV!93OsmGCSi9MP%8$zUzI)nph@CJx}1e1GX40EOY=O zGiF8I#ctIQmWdv-k0N=o%lYoXXLMK>8vhF1E6-8nEE^GGYITm|Jb3yrYuF}{JHm^)fUUaZ;t zE)1z}uU<^dsfemnoGs>B`4bz&dzybtB5L&orR2l%&gSNVO`8yd6Li-F$_$pDB7<7LKKvq(c0zqC z5=*w|FhEeJ5gRRtHQp9K7rCuieYK%3+He;Y7}Gm2HcP#1+^jNX)+~5|Y{k2kSyooI z6BKY2wQ*!P;^Q+G623x0{Ltg7*OA@r*6bHg9D<2j?SEX=JBCltEeGjG4e z>e|$E=ZSckTYsONz(ql93yK96e`G;U=+f5gR&A>vjok;|#G<_PJ9%^Lb?T$t$;=Zdc%~8_y83$47>szT zxjR!+ZDU#YN(5t^toML@b)Tg zoP=npXvxA`z}NeD6+DWof;J+$l!K|eAv4kl1p~V)&uHX&$ZH6)bu0X_UYz+xB&&Er86x8AyqC423 zX=Y|d_DUoBuWyg|5qzd|RO1jSU_`H|@})^R*VPgU+iA2+g2eo)JLMaeQcu}*A5pZ1 z!6pj=$GI@nd1|3xYLK*uc4aLK17zWYaqz|^JklOa1l}Ahqb)CaCYa_<%8T-5u;nJ^ zm`lHTI4Evj`4!Q+W|>3m3Z_1wHgW`Ag)b1WY6YWD3FJD0Ygk>9Z2&JTB!TDG4E-b4 zh_}dLCX=Y$YSa%qkNPgDDHWvt+4ZQ?YXkTZhzZ@_ASdGc5o5-Loh$3h?;Z9|u+>#7 zKcc%2@>%_F| zWxM~QVgKKIQ;%B>VN2d&QQK-E?s@Zz<0Y2V;*BiS|9M;ee%K>}z)O3P<_rQK08Ph( z=aUFMn9Bxxfa1S8kiXEz|M=#wkV>C-@(FO^$1f@;nqK@bLped&U(_4PqcVh1_Fu6h zuMB*!rQgWuXVkx{clTl)nj)nf;gY#hN*%pyzZ}CT=zH*(Ix~E z$Yvhh1!q+PO5y%1KfY{Cez0vBLW22>RMJUyv`Q5IA1*EV={h!e>5t6{iG9|0Ew|BK zZdSL~7$NoM&reW(YlTP#gUysp9Io=>3vJ;Ie2+#~MlQ2!bQ68AG3W;F;3gEUy9a?A z0{Bl&1_nt`16x@e&mX0HLcManQx_#H&ey3S8^fyvC5WwUu_1TiZOwU`jv&Zjv)W zOX7}yNjIu`0Yj(&w~Q;yq*^>I2F9Z-To*V~G%;u|d=|HG@-yT!o<9j-5HGNp^O zp+&{4_Fvek)0Rn^*(}G8vT;}xn7PBf%nwR(UD!F4P_7%igX0U;MT}2$pGfM-NV33J zxLd(Jm&ZRwZJ;h^v>-r1C^f{rDq{nT#aDvx(hHzk8jVccZ^XC(lU@Y+< zaMYKotbG0mE(KqS(PzlU6MdCZSfA9lF9K6yzKZ$+{QKvddWWrtcvO8vLLW}2q&Yv4 z&e2Uf#ur2(>{iRwj%k5ePE|dtE;R0IHfN7_7gA?{=FT;W6htr&>-E;jP9BhJ68FE> zc4IoiW`dAkO}t$ZNZs9LZS;fpZ-%n+1kE(`^_6Y7%3)_dkvB>1NC;zB{J@?$qlCRs z?O*_(_ojMl%z!UcNv-UP!PK%~DidE&i_+*upA`iPmObs!eX|fP9jmGz%(!w~FETr* zN6uSmzaGWcw_*-WxY z(#bIhuEVb86Hcjb4YW{Q2pHF^sA=r?r^e@sA+Jx2 z)EkD9dHW`!<;g($1v+`up%h|GwH02Aap_FVHPVtVsyh;F+?-$`X%g2 z;jtv)Ywu^+M|9*um%dfhiG@BKZ#sL&ln{{JzM4wg{rD`ZspIie`)mLg9-@qls$tML zDD+TERwR1PJ6tE{o`r>(g~dx*4i>&OG9~xmJ=tG~0?dL`NmY=rYceG+d-KiF4duJW z(cWFr(LAw>3M0^7*=ql{sW>^!W+z6R_4bMSQf4!Zw_@m0q+jiN8(|C9;e7E#ct&o8 z*-i~%TZJ!_wocvTRet#9-EVx#^Mh#~0L{112eu7--NU2n`;#j#hw6PWgPEMt5DG6U zudXhyK4aR349^e>&p7&MpO)4?!rD2bY4k`oLplTWB--=y@x!+-J_^-ZPb;`X(DOrl z;X2$V;U6j;ie^K1&g~u68CGB}lNDfxWj-@yM-9RbqZ)$5ucd4)cuoIRTYnGBmNoS30zQv;m9!_CcfQz z7HS=9V=#qCPz8w8qHoq)ouOZCHOxVIg409BI$c8nb`W--@zgK-bLuzuvM}#`O?|L^ zfMvKJ^Qx8vCq1x=WH(8$?&60>LFpS9|R@F4Gq8=31EDk-ODEt=xk{&kd1(>wf z%tH0vzxQrKi{u6P@QSMP8O@*aIM%WY<uM@x}RyIun?B7N&4Dg zbW_m(Cc1OP?T^}#tUimhidH$wmNlg!IxF|+zlz_-Q zyQmzr70%k&wcCzm;M*M!bjy=Sx{ftgBRa{AZoRK$F8T`GHw1FSsL=8^=)k=WwzIAw zW$VoAw@P>%du<)NqP>aVnO{u2zH>fA&V?uMK_2)C(dPnTi;f%58MSbZ_pr9=xxpU2 zh>Va$D*AeL<+kX+%MF^DzAaAOl&kH%)Ng|d*uJZD(V*fInPS9Q^y(i_6C$1u_Lorg zh+CZ$Zb~%T)!@d(2RAEVCUG!*c5*qM*TVfwS?T{lPk+!@CH zAd}qpA93hRKFU`+an`+Nk`Z$*bg9=sw{MbYUJ=uGVS3~)aNjx=H5kmOIFF|T15%$y zee3HpRqjc|i$xb_zt&ZJr)JRidMaxpi84xh#){ZBMoiXIDL(%C?0liujLnyyaMV6r zwX_xn!ERGrsHBaxeUg)@fhhvJF!dtDBc?&JW0C(#jnr0?N8{yL>{8S!a@r%{RIF2y zb=MPVQL(EajN^rcRy+ML6h_O{M0=U+hMU*f(T=4gZc*-9>{&%8#RXqQzEE6FS~WSf zM(!fXWg{9f{C!I6h38dH>wtqWaU03&=Y}wKUj$8R5n36wOcE|j%^A>!eAm>%AmYM)d z#9)(!cOA{+*`OXc;#NJoLZcpP=LgIHJ(LL2p;%KZS~Snb$+1FkwC=~o*B45e7aBq) zLsX2RCQulIjZcBMVv0_Vj0^l5xAyA3?ADd6f$#S-sw^>=BORml?cN^Iu+Vtv)@))F zv*`bJQaO6UsZWQ z*jMY1>G_9qy399*Q4Q3NSSPFOtUw+IM9a+*ohgs@<1(-Wi9L`8V&F-2`Sq{YK;-O9 zW#+40CAyPqyC}o<L-o>sr@F>Ey7fKic_V z3kW6Uf&-@#f1)v$w;oQy>O$%>-il`LtjalW9%Gw~8bo|>I_ISAGQ;e}`JA(~y!;f$ zKCQnPf;Qy+5aws)iG!0`(QApZ(QlEtuh!mp8%H1ANVb%Xlf8={$Rr3qpH~j@Ke{r49UG2V|)q}!P0_9xPWKXOdi>+`!Em~`b&qf#I zql?k4893qa`#K!rW%&S0Yw7+9w=WR3dv}YxjxCCbEvvf8x@$jxI!krWQ9OkHyQZ+{5*h>LE~(s9gJVUKuYH>C0K?-L!X6A$HW!* zh`c|Zo)XwO8T*1+mV4;7UYNh2&_{E&*nP!;GwDaJF+{2CI0nnuf4CXm!Kz)@pQnXJ zS3evB>>Qr3ykT6s3+u4g4s?+bTK(b&rv)8>ecL25^3~30NJP#*)^OOQ6S|Lg>Aud| zPS;hjt@SB$ssvIDAd(1 z7B!tLO%Iw+q<^Ikr+$7sLb+6I{Yj!_q2J=}w%0Vr*QbmebXr0<9C(T1SJR~~Q_~S` zejets*cZA{*@+^p`ekf41(KytS# zP~OTTwy`$SlZcGh7K+Pbx|#xN+wQy(x5Ip?@qTb+@iUSG4;}N|cf#{BUME?3UKSb5 zYM=&oJ+d{F7OoiCNZpvsub`)dSGz-cF3P_$?>e+GaLHMD1QM(ciquko^;*+G;jyBM52q zyl}*0{5tur-bGn3`b$?)rRELM^r0oZVfu3+iug=n>ulr>zJ#6P)z(K`PcJR^*r=VpyWZ;RA-p(OaTk~Ghj{vE-GGP>j`Tk zu;h~!s7vdC%!>~VjbO@IS*UjDN5weiJN`;5B`>+=-n74a#yiT?nw-?~Mw?+wK*HaN z!NwJ?QUEz+!5)jkenHUlDaO4j$c=J?3_@RDU-1GGhJBA46aV@l+O1+(yB(kVAS`vk z`q#A zM65L0R;nWS2goIX-Ca&c?Rg2zq&qF&7_$O0rxJ(GX0hqk?<-jy9QlX)FB4I5adE7T znSdf)^rHcM{Z7VV>cRG1$}HH~f!!}Hx%>CEHLU#H*HfO^?QcffQwAs5j!fq>fh5Yo zvi(hiV4^S%quthb>T{bm=ef)Pvn-b2nW$?F6a+R^|1Pu-Y=LVGgpGW{%4=k;eCWf) zg(Z|Ul;Kl(PpUn!qs9AwZIe?pHY9b@IjM6IS}l=Xy1C7cNI|3kEo26 zr;QJ^HPFjSl|e9*V zxkT12A$O>%YsV8`RB>X4iPPcAk42;HH|c)I#N4Y#L?!ajqTv}cAdz!;VCV(&aTOEa zA0PKG2+p|p&5SUtIzFfERzp-F@)x8g0%L}px}{>1X%$Z?cIoN`aW6&3A*<$Y*OkHK z;qFw^6FtZSP_CBmungy2B{>N>H|L0wf+6`Ak=b85<(P!seJq3j*viHFdIx{_@KV3@ ziSx1EkCrk9hX*du5eWYP6I<_CXnv!cYnEA|yR+Ma%Tg~>#Mz*M{tne+I*Eb4)&7qD zHLF^qUopcQ{3zaav-gGhEhp=X0X_m2`I9NTQRI4FyKQPEYw~cN?n@?@6)56 zr>0iAbUup|GlW6o!G4Qx@;eq^%1jI@x=>6B+nL}<$w-awrBX`@x1UDOa5yfE#1DjA zth}{xQeuls{|kwRRXY*4P^#-|_wc|%+bAUf$>pO9o@ynIUi`|xp4>V8+KubWy7@T? z0IE1sl>Ed)ACfgyhs8zPJYg__(517aN93}8OE&e&hs*b$`zE^Gmp7|X*6sZkkIUD* zuB&VAMtD&jdCq0hRk-~AZ}^QSH|!_tTlnvOm3A?IaLxVRjw*4Wjcoi&qtcEcTMRy}!+a!9oZQ**+EqgSk#28! z-^0(hE>x$F+?o%wCueOrNUqM=6n6G4@K~e&kwZK_-aGG4Qu&khuOWL@U zW6t3DSv2R2*Bk4al)12YtBk_2a8^Z)90PB3)eu*WP&jZo;5gZae0*mwU_D81L!!~< zCbI?ay=zhyZ}gyuocGjECPJEi_lys?qm%arI&^usdYB1TO6GPe!OW^S4=j3_)pR_S zH516U$-Zctggc7L{=ji1#S=b3ozXk+Z`S&wc>UFvLC zv&MmV|IMtMJ69)OiS&E@QM-USXt&lh5%r8!b>l;BztclT)jken&sEZz8GP|VwbuabazeGE?X#?@LrFsFP-wbP zSly>%h0(GaRMhnE2Jtc`V+5(r0E(xVE&-^1L%-BB=dDF^%K8^KQ{qbb zM!>s`Zp-~w?$spORxr!qSV{J!C7)IV&Yc(f=r-bu4;<1ouN&C|2u*#NpV!SHkZfnk z0ckzyT?P#y#gq&g2ebRe&@v4D;4y}1iB2zSg&f|rJyR`!`(AJ(#JB22kK2NM7YOVf z5`*QzAa0A1b{-iPBe}$wuXG}=&6dv&m3renoN<7_`T^S%IG1^ZH%Kz{AxXure;YQ} z=r!G?Myu*#<_nr9Y{vsAHd^7R)3>U3n2uhD7nU9Y(*)pJa+F)_oCJlY2-yA1FecX{n=UgNP{F<9kX*1S3zt7g<(M1fm%~V zh;$u-hQ0)lbL}`xLM%_7d1==vLpo9ac)4(Uw@WQ(>n1}wf#f=Z^>{GyUf~6k zn7jKk_!llfOEdGu!f3p-fhZQ{*7lXe>V?AYy8L{F^&@wG1`X7d|cnoNgAUV5Bmv)%J~>XH!K zp)<`=I$O4HZC>^E-IUA8s@ZRk0+>p_?%_Mjrru+%fSYA)EJ=gcQZH?eAA-$UAg8&%gcF9=k25 zwoYfDNwt>}*$rquQ}us@5Y-jShVNUqT6&5xGWP=-FeJIlw`Vdi>$ zPt7KYVK%G93Qoe|8TeUWrICw5MlNVBNIT=NilC@fwYE%6&{1nnka^pAkI^Y|dd)t! zHkIFt;?r;G(-+q<*$BvFN|pp|9e=?ntpMHe@J|4 zKqx>0gd)q2hJ|Y3@fVq6UD%mo-A^0wphaRsE+L)y0FF?+X~?yE71Dm_A0p{{8t|&JQy*R-7J45#+T_a0kjtO-C%fQJFj|*) zT-8C14BQz-eR(Z$_#D3i?C}CnEd(-*4Of-iVR)l+-U}ENw`E1%hf4d1wU^pFK?Dz7f?4f^ zDcWkKzE#jTu71zVf-;y!23C=ltX$Y$B`|wky#9pApMWeWBorO zgT9PiI`)h;Am*4d5#g1+URIVyHl~4^(RifVV6t$D&EkpHUKw;MVqrig&HoyGgn-rr zBUB<{4C7%~5d9|iJ0y$cp@);JdM*%LxlA8@S!sBkviRPX(?_2Fgj@pK@&kyL?dRan zAk{Ao*vtZ(4UG<{vn=etq<*jH&vyHSchC8MGjT~Xk|8Y@9}-_%^`n2za0~>l>kRNxzw-7o>L!++qabM2^94uwxB+jYVH$roesXBY zlwnK@vn9c!{OH`avl49Ktf{Kqku2h*e$4sMB6q?LcIPRmfT?b!vk(b@m~QU#e>gPw zaPIkNoUz4v^0cxaKEM9S>lqFRq!}uhm@juBd`)~K04Sw|Axx46haXotWHbHQrm41* zqpP}n{j$LnI`+z{NQ}grluBtttKX&nN4@_L#>daLl+?0fY2e`WW^|rTfuV@AlBN-<3-Pb7o|h? zE|Attr2=m%?l-#qPLl^wc}vP5&D>)~k6|o~tH2%ERRcl@2bTJhWl`<4`V4aYME=IY zYe(l>F~=_I^K{(e6pflnbuo{J1%F>HS8|#zyrm4EDat%5agFPkDlBIuznsj%y;WvK zi(qY}?WPb^9$M3G_~?hS9<%WH#AvzH*m1G`{7d^*ZE3KmUYdG`Pq$Du34S#Arp8qi z&^Q3Mu8g=Aw5bfX5ge`(y7Z|q7@lHQftVD!sQ-XN_C%R}JHH68X`dJ%b@kZ$Hd<2> z&5MI1O=a#`at&S3A2lSZJzVM!o{&>#AW;gj@bC41M4&Sm__*aCEy)1(fEe-klO4T~ z1$a$5lzoT-lbeTjF5dmd#=8S@Pl7~Sv1r@HwE1zNJoI~XF}wZty0lj{)hp855_It13|vRtV|Ql_xGX&EDal30+DbKRmWiU_T9 z%fS=9Cv?xKJ5qkzr=>v$cjCCAp#XDsb*zDp#z!G;hqgu?aHT%ayko1$8a zlOwF_gR*PX8wQWQ=o9U7$j?;eq&kPJW6)@IlY;m3BlHhFi{||Ik8A%4>e@=HtIx!N z>UUT4JL5{x(UmM>jN0jr*4uutETt_aeN)WAw%b1k(b@{ICDFT@_+5+APg0!z^4$tM zZB^#sVl~8u?pR5OUVCsv%h%vaX}Rz%L*|W`g0t_3W{)e4VCw+jiF5PI!k;zAupfk3 zoBVUPBH!VO1qB5_Us%dGkCNsHtb18E`lrHiuRH^9kXJCI04kKT>kuj~lL!BG%(dNk z@KZO&%hC7+dA`jC3WNF>8`WIO3&FBcsQafv5BpyGNpb#Dcj0-VFmPmk;yfe)LuaAJ zGc1$>)*Q(|pAbWAvu%kilh}6{zNQOUsMMg9FU~SzH|y$_fmW@QwNWNg1uo^QB;Mvp z!@&7M`$t!X0{EAT-xD6#itC+3pLfyT_fGBl2miYdbXlC-o{O7p8uNwvKIjrL5kC_&8^xF7Cfz=2e3(#xx+M!c@>x+CPi~dlB4PMiwFOpcoOsrVE5#5h zbU3Y8U-jO-&?1ju-0~EXK||j~%y!6^CU64)f1qOvIv=`}il=q}b1U(Er@H;#7~@>R zS@bz$5}|*WwB3OpnX(Xt{oP9Z1D_6S$ zO&du*!01AHBK3p-Y$A_7W6l0y7BdzetM+Z_l@=^B!zFP_sz zIXFP2fkRAPh)gLa6t=Fs))Z=!)EkIpF=7_0{XwY_1xGg zLgQgJjRRWesa?PW7X|v{-lv{uF)#1v2yHBjCcZfmsuOJJD)Z|IN=NZ`rfu!Kvt9mloKG<_Y;*X z!4L-7SLg_>%DO^^J9%t(W@wnW-G+3J7vAn(GN4#5-bInc1D{sz{vQ3v(%1y(;f>Hf}qY% zM|+R8F69B7y=qyF3csV*vR-3fy6tggem0Y)oG1H}A(BOb`KIkUib_lo6EKg0`*^o1{Q~ zV0K7_Y|=76g8UK739Z0W)^d26`G);y2RblXS8600R{o^R1#w;<`fCQ}KV_Xa zFKRkvm)#EQdg=e2!u$NT?`#waaY1Cee^Z4!j%g^QN(QWBTRo8c%vL>GzRxiBk$1;d z26izIPgLFd`i`~nodJuc4D2vXm#Zju50m&BcE!G9!!`T7%JBo=Qt6tlO(~m~=O_x@ z^*aS_@7#ell$mf(JZ zvO%ThRujrWZGLNR4n3)bOvlX*`}eExh32FNpixf^b4YYyd-qGL6LOGK(ezZb zKJvm&%IjiLGQ|>0;M%Qy@L*p5Xwij#L{&(+%f%g{uOi-$0S(GcMq(CWJ2Bwf01%yD z#{+Xj!^!Qje+XPbD!_bWuG&k&+rKhN2d_6}>VFZZ)Fc&#-xil>YcFN%c#F%v-eY12 z(ir<^$v^>O@XSJWC7R_KtGHz)tAy%PS3O^d zol1O=DPqmHr#(5PEX3yj{SWeZM!ZmwvXNE{~qR>03n^SctP4b<4BFi@_h;Mq0(x40k+NN*a?cIr758y8FP*K z;tr*rj1U&_?-R3Pi(|U8rsODomsTE8ioI*dRRwBrK)SWY?Q@bd2Z(oUb)tStklm|V z{zw}>uKsB5T~4BqHr#V!nd=z$fJ8UxCcV5qHcDO$Uh8hzi~1l4mW9R+yRN|>_eywIaCX*C|3ofL;peZH$jMeT z$r{+(?aj{orx%Eq83Pp;pa=l1Qys1qbvf{+J_E0gEB$3rl>xG~62d#)6{9;- z8^<>fL5jZmnqr!6&aL0}(aQ!}<+crGdMfusx~R$i!DiNoOX=lKORXBIN?x3stm#lz z10^BM?aSrPMJ@ev_HP~41F-39IyYv2Z-2F>{CWnbvQ!Tzwyotpb}AtQ^%i`$iz*tr zG+-MgYhXJ^jE^KNwO@O7YzXdzoMY9-5?J_xRt)_5Vql4t+BrD?<}3Z7tOZyq%0tWg z>YkReGE^sL#yiX|Egy|$u(^5YW3Pd2Kpmp6pR`Ht)<&Vx01^XV{f7XklLDo}+)~5$ zg5ROJPjcIz@8w-wiWQD_LPi)RD*2vT;^}zBqC<+7y5Zvt1T$nl~mJ@Gk{v;pVmg1Byh+; zLsst}7W~8n%ho1KyCzFTU7$Rv=K+-u>!C#qxd6DKXFSe;U^B2y^{12>Tl&8p)PG(Y z;M{&Khvyid^4iyTfH`YzZPl{eDGuPu_EjjV-*Z;t=>Wcd`V%YavJllF6u=>|A#Uk{ z?7bChY;3HQ68W4-R0e1nfZ^F$Z}+fwG_GXbEUgw4tFsoI6M=i#y)B=3<^L9DP|y7V zP(?$FSQ3V{5u`u;rkGw9K65~jX%<%ZtYlfB9U6vxHi5em)K%*nNoF@7T|xZ#9M=UO zT^*OLSO29d2!P)K0L9>w+urU4tGB*GEHvpa$S*8weGJ>H@%++gv(9@fr7VJR$1a#c zq4b=4ew_?*9X0t?M*@Zd9G%OCcuu>UG+lBRebv6W`AgRcPGJe{y&;?EaNaZYr0Z_q z8RV!l09C$2j6wD{z;ibVmD>!Zh=hKf|FrEl2k8L1{aU~$azgjL6l>j!t6s-rO+5Jz zg*-L^wj}BLM4Iiq&;b|zZV9@QFePJ#T?6{*0}_D^9vlC}$T65T`sroe3|AQI+`)RV zV*pugNB6*w2Xqu**{L;5@H0dqAU9!o6<2gV=U7oF`Vc!RAMR zcu@=e77{dN*kiY|uW^PU z9vDk$Ri|)F=LhMAw;~gEd8n51-z~xDAd*pZ-VBfc?j-wGrlF2uR65QfThY({p=G<< z#ZT>@YZI>8w_bSllWK-QrlNl;>;D#}mwb1l51PNA^9Rs1<3O?U9Vo$pOP>CxvHjiY z@?-c!;MeaL2d`~@Nd*s#<@+`S?zpqfL~zxea0{@j$igHv9u89XZo8&Ts3&Z%B7G-}t*m1gTdp-V^Bm z%=Q0U^G%Hp-j(FU>#^?p(|a37o$vPo(`1dFvfj+Pimc$pomecp?3hdm`wu#P5uk>4 z{+gfi;JrZecSnS0YtxiUPP>4?*y5=CpxKQx%{MI~yuD1TFImR}RVo-4pcCn4g{?{! zmT`Qz*e>2d2J_E<=j1KmrV>o(a9A?x7i;s^67M0Q6ZO(XKvneE|DPW4OP}TW;=bO!5YS#7hg35NnK?E5Rdy#?`${ zLeq0?rh8-ZON<~M*%Ep7fmP>o!q&Rg%av+kezEq`6s8M4k0kwA%siTe0$;z z&u}oL0j?*~fwsxm{aG!_I$iDi)vU4`NGFT_{I6|$|7c-|(FT14UYZ$%5iY@e`+)X| zwRX{^RoIzb%YBTu=ve2Mr05^kqr(Y_A99(B03=Y5|6`sV&>vk*mX{ z-dz)?9Soh?WT)10d$7i{$#iCtGf+>Kxs%|6ar5J2!s*+UyM(UGMnaNwOGf<(Fs0*0qr99 zFP_xUkDrX@H*P)&VcH6F-_72bq_?aP+oHMuqh%#xR&iU+Z@D=+eo=vP1IOi6?HXX{1j7BkVY*7mGuolG*CtZo1h)P{(1I;*-2(sO zgPLeJOGw)WW@0HH+^(-}bcpmSptk){y>tli%H8CNG|Xhf0V;EI&t~rNyi7Kj0^OQG zXOxeg14*Xe13kv$40?Y#qB0Op~QC_K?R#6joei5KUsD;E6;VolkACCNpeeu$?XTB8I zJnNqfR=8|(_6l)!Iy+E@#tz(I=Ix{oxc@&hS$j1ft>=B8?zE9 zwHM6@s=<{Z_%Q#KZ_%o!k6M z;=C*)Ue>L0Bk|j|Y(9^yg%=TMI1G?3S6;YR`etq>d z8_Y0EKA_s-N~N&MDgUvj}`Y>2H?Wt z&bLU8k}ALfjL5nYs0V;qDxnytlXLF37-b<$#(kb zXpu%=BNpXJNs9`|HDq!NXcTWwo+lKSdWud09e6Ml}?)l@W}y6_EXUanLHC>quy^?^;sDDN&92T=g=kGJ34O zC;gH;b})O$+`urc)NB455bx&G<%ylk$d)b73!T4@Za9YO9DM~T;c4(o92!1}wSIEh&ptX46 z+4=V*Gb=&`#vNX#`l3rtcStkn+I+D>qDP_(-95C~Mzc{;0W$#nCCnrh@I@)4ATmeo z)D>Nob;G*c+&ax3ooQl3e056aEKYX>-ZcWG7;97Z#acLj+ZpB#*CWRkXz}iW_&+G* z`S0Dpf4Y^`iq3N9&1&n+CgIAW*9vs`vp(JNJBhOHn&mJrFFei(Ixc{llcU&ZzUHwD zI32xqX~Co`dM)I}9B4DTFtWM^dJH(qw3n=sqhHCO!LoQaV*Pht13#!RB1;j#WpAe7 zTyf3*nI3m-v;TdqVrDADC<4>VIcjxM(>oQSuE}y|rj@2&Q;jBqA~-+9zCg@RY8}ve zj{cUBHC1agJ>e=2l2ovg%^%-N`Jc%4vgWk!uWjIGYZ7K}a-R<5;VUaJU{j1rZ~Av6UBx zdEb@!8gRY9LVy@Q;mJ42tX+_9JcfPvtN=9aDqf&x55%ri6*7?&)RLz*?bVq)hStrM9YbmhrhmI{i0#6oh+j31uTk?}Pp< ziAonMe(Aeibg${Q^D***%I7u7^RvbSC8_+gMS|S8h8I>p!hDx;$qb+=aa8ur6a?-LO6>TO`8bLQ0>H_oiywBmnFtyxQrP#E#LpfYuH zM`9Pmj?4r6gC+gE@1{KvcEDzOYX6*!>69WdT3gedGVuRkAlBa&ob;yN<>;tw|6mLB zrB_u&+alg*=Ww~^Ufwy5?QHU?83Bk7cm}<|GqLadq=#gPeZNCbwt7SsiztrhI8>*# z+0oJCJ)XeCna$-E-nQ4WlORfg|9fF(MJ-0AjkLPSi>8pm_@IDp1QXe{38&TM$We82 zO3KU2-3ipn``2f$r|b80c=TjvdqrlK1ZE#W0cbaynghaVm(yNIt~l$^KHCv+BVaMr z^&8tQ7SDh}HDE@%a(C$`MA|0nXWgRj%eQRbZ>{0ufqS>@ge6OLP5ALRv`?I#h64mC z-_^06g0oGvME8Rzo>udydHeP17A|cx0oQeh_6^9PewtO)j~yen(zk#S)9ZcVJ)a4; zeCnDPTMl*YGXgifBLmCEtARU~R9d;dFFZru4?&{On*lr2#I4x^eI0>H0a5gom2C!) zUwhL9EMPN53kt1*wj#<(AY$2ScQshHZ^D5#sFtsbp#RGduhdmehg3y_IC?iEc357R zUXMl0D=W&ni<2pxv0kmQut8!$Qx^Ez`X{ZRjdx+Ngf^vuUFt>6ia#g>g54C*As25u z`2-YjRMtO#4Bk}22Hxhn&^G}ZzCLeNA#hcEKR_SL;$Q**eOYNB_Ko-g(kRAILkG11 zy8vGBnwaiX?LlwGG=qy`b^C(?dgf_3d$0CcCZ$>Ee986=r>f>;YGJFgz0J*}Q9m8p zn#1a*f3lP=$&a6cnU#`A1-MyrM=LvcXJYpt0L%$Fn_Nk4YZx!notz>F*m{8+vG34x zF9dlCL!<%3BR>tMtU7chyAmWl?&xKAvdiey+JgUc(A~mA-XLvt&K?4>Lmp_&%%#d_ zNT&R^Xs-TGR5U-N&$xTA1?kx(r*1B|w?#)cE7y^dL61;j^s$EvsG}If&LLcnO4OQ7 zi&Renf8YiiJHUDyP4dAv69J~9JxZbSuef0JO$)#ak?}&Q8YB>4PLaTdOdTcN0I=8A zQkkBZ0N_hoYuP>u>z&1s8CtkoH6s=7X2Xw+cZoqa{}7$6cCCEHvgz zmS~<{{G|P@0Z|vUufM}txNw_@A!xHMGP&#OeK*Z;vV7ImH7_DHuUJ$`BZrgLbW(#a z9Te~&qH!wBt-Zj`d~0APvN3lvoWx?pUO6Ap8bXGgE!P^CLnVVQl@TU2MsV^uWF6zd z(u&wcZ^itlSMd|PH6O(87H@Zbo9fdyp8V#Sbw__#Kq^cR(B$zjsYwd@<$V%@UZ42g zHxM~f(LbM}O0lD>{t62VX_;6WKSv-35TG1aS2>cU>LmWamL1fNyu){je}f(m&&Lnl z$yn_`$YwVi^0BAmiK!}ni)Tr@k#TWOV$zDhD0$w-aXQpwd7tT?UFSxPhFl!*Qe2%s z7;$+jI!vk|RdeSI|A?{*TM*^*!NAcH_bXr}aa?iNu^!#2rv;ZsL2i~(ES2KxAxjVv z>rcSVie)tq*RAOW%Lb=`&Ax_^>meoatd8FT`QBTs-A;~Lr|v_LFZu^yKU8Uxlyb6y ze`B;hb%GLBR#t`>lxU0KmNXM2wsn+BnbBT}`vp%ocTg((tXHSPgpPYaPv$4f$3WRN za&Uto&*@Vysk9-@T6DZS7wrklGK+`h($%$Sn%`=0B5mZJG5cJwo9Klz_nwvx+T&Av z*4_$*cht<4n^BGx+;zUL>vZOh@Oc9+hZ;9l9jNSq9LSXvGz}=mnxONFDWEfX z2nY=)!i5to-JbuoAgeAH$)}x8vn_zFCDqe`lWFLW(k_}-Asg{WC`i}oi}~xIO4q_S zXE_~Ic9kO)TzLqNvMtFx&}yQ~ZEUxE_U0A3`_S*O?^+e2Txpi7lTb(k)eq<7RIgju z?zQ%bity_Sunln`FVJxhI%GmwJ5$tXyVI(hpe@5ab?(U<`|Z2%QPO6Mzj+Q$xNQXh zofe>5GM6jQ5ZWNANk*jZI~DgvyHT0S=fu;JEF0y1nf?VLBfhe9b^%8|Q=$NP1pAU{ z|5)moiG)#PGCixiqSICNmf#pLwQQzQe25NnK+8WU(-so2bFG)GHhMTJ9tai=-WCS` ztKfkuZIy*rwTHARtA*c}*l;Id{IyPwSv;kpZUUe5^~=GMdUg#DpuvfY`_k30@1Efk z>7%P#&))iTdkraLx_@#A_`z62CZI1K>`@Pi9jVj$I}cvj23UF0=c`YCFVCJuwYZ=B z!V6raGjM`i%>7X^J}^V~oz}vjAzbRW`M#^DXg~z8e=;LbJ1+`(eXnoW%9a8G6dlRd z14T;*VJD`RS#GV$PnG%yW&R{p%1eX+=aDelpRjk^Nh)2L|Kv720_eFcP9};V^4e8v z0o0s#fT1D^K_LiJZVXB!H5&h4d)FP;!2v342fYy5J5nOvSbBt1&9$LAdny^NZ2z8fdt68--xaCYkPXm`JLbS z{m%FO<;Zy7Jn!>7_jTX*bzP5Aj1}(iY*=(+IREM-q?@r*(%s)gLiI4nKHp~#(Yrml z{qb(~!eJX5w?usb3Y*Y^Di9vC8ea14DP@?TRX5@3(mS{%;qK?Mk{)b1Y+ph2zMJ`V z9W6@zaB~qmoBE0-LvT-rw~7&5%rB|?%l_;Hd;}{1B7w)aNFd~wx9b#<2=TqiC-gi8 z$bt!?B9|_jJakLG$}3PEv}hLIqYmO-O=H@qkw^w{-5I`dn5gbA$7nqo z>p5*;;dnDrRM)zBxq`V|`|{WmsR)AoF@rNn!t!27KPwi~Jj-6I3K~(z-JhR{26MX-eT+ngE&ECmS2B}EM-UkQp& zoL8s=qxAKN4EdcgWQ-|8y!b*Rt|#G%@8O4J^4u$*K!2&2#dHgCdqk*eZBheFP$)36 zlXx?eJsgv<5({gmZXIPrf^`sSgg?Kntel@tB{0~hfYMO#xy*uVDPJbr2JVbK;$~TZ z$`3|{rhIazvSpLB&)zTBarhN#J$=uD!Z>Q{4m0afQM7%%Ot)ppXAjMqwb%1NTis4x_*5L8q!D#@#5`d&;p)(|c;{E%1l^eloGL^3P92 zqDhU5xknv*jMeq@y4TCMZ!RtXCF`vG!hh5~I1ctkT`lREAtePSP~ZjGf}shD1g_I8ZOu!w&!Rl7is{*!xmT~+ z#9c8kZE`&OZqvXd5TYyRWGcrygnXv>GFcEh()-~#zopf=-`TsEeq9d6ynCT1>;ASp zDA*zco)8kq^ta;y8%8BPai@gJ(B=RtO9 zCXQU;o698DEn>njRXu0WZ$Y2!fK*J$h5J5lA3fETsEdh@d%mM#`Xx28PDWezR30fz zR&#a^3DDrkQP}C-D3#uwKzG<oa+o@L+c+1#n4ilU-iT}Ul7gx8oor%s#5G4kzT zCv_rS6yh5XrPgK+QW?Z5xPJ>5Thcm+jEr+dKnA#~O~308me&FSN`%SSg|X^j&G29| zUFcGZD`;`6E=eZ(O}(Yz2m}3_xi1XjrH*8VHSddG7a7LR8%HNI9y;bb=cl>0jARm5 zNogiMusC$Jv^%@dB%1|;13^{!T8P0JxMUEquw@U?VF8E|Kzcg%G9%brcc$iWxTPf8 zbKtFII+(}|yfu)Y_O!b3v?yk~%y_i()=icqw{56QP1mg`DwQ7_W_JL$HZ!e!q{OS^ zhmsYUehboR6SQbf~f4Lao{z`W(qj6%?5zyCnzKPw}+F!&kpRM=y zZBuPIa)c?kf;=b*H$c!&<(<(!9&!z#^80;U(v~QOs1NB=I8h5n+b+Rdjvki&{4>zu zjxWEx`R7xz?o|%4m%ly&#DetGNh0hRv1AVsCzw>wxzGoTF3nF?=fYjzQx+>$Z@1O) zfpEy~txwc0c0WWy5gMkaCw-x?T3)hFFIP1_D$$ks3Y*(G>Z$!+0C{xnA8B(%)%f!f z(1uka0XgoVRdd}yU4D4y%X2e3T>x_cp?joM05*SPZxzQ)r6%r2;0kahjuO~3Ui;nN znq86ypr7)CT|nnpSZ5PCVALO<1)fc}4I+wEKhog>`PiKjA~j51qG3PztSCX<3f8s8 zV-fAce+CAk>Xc0@s4A`W=BB!V(&bt#7;=;&wGD^C)|`%>?ZffVFVC5JLGu}IBFbeE zWg$tsI;Zg&@lw9yrOS5;$29E8f--VGZhAyvs(R9%u?tHGbNhC43HjYZl8o04%@>!} zmn2Dix1FkPnf78>hCs^%DATOuvC{#rZYL`t8?)Fn^mb-uTY{ox7OctKmdmG~h{~kW zDi;nqY=`7-lov-mtKo*cf8DmBPT}>G!T_ft$2y?1+2&#*ij=Qu^oYnv)Vw2PYg^BcB`4 zxA0q|sO$67iTzNi!?73ox&kdCwWuF+!_!90fxdhrADa!HCRQ|uwAd77{%qK6-rg^{ z@+Qa~KeBoE^>-F4O!MF&sYP25wUp_{f!gbug_P4)HLVx7f8?+RNE!PoHKcE}Go zK?cX}x?D_~dYMz84a3qO{v+sVQB6o7tQpwlrxBLboEPXpxD8nhi7O5iQo_vH!~@_T z32vktau(SI?W_JB3ld`G*}DqGo?qE` z0F-ycf%^pvHssb19ea1nVvX=w$#OYxsS_%}14*RnJr!U* z_J>kzsphuVnkTe%yLEiV8Sf=-Vh&FZZR8^v_)Uv>O5sO7snBq(elMFiI<>Dda`7fX zXzAM8g>*ui>5so4)rCeieT3Yy0r^_^&1h`uj?p#`N+k5bEFnMY&k?&R@i80gwRZM-&DfB8Kt2)${TT!)6OO<@Va86dJeES{awmICQLhVz8!P6ykmU+)&c ztjsl6ffhc{A`c=qaAjVgI9;aOB>=|D$L3ig67B-HQOix(^cx3S&>l>Zf?WsgycuzH zDnoeRixRXzaCHX%AZfStv;Eul#_I(7DJsw|)(c1Y?`EPUQH6<2;W69C5d{@3Dgu#M&zM|--VVwx7uYE>O(0pOr^DWrk ze+kdIIBDPAlY7C+BkATh`Mj)zxkf_ey6ucMP!LtFTD`4+LkS`4d$J$lvyR!4IU^)N zV%pdnzO#p|fJ)MmxdCMG$N7_#{o63Y*s$U<_DHssS><$=jBrQ5&`R`iQUaQ*#H~$6 z3y7?u(K)m*0H+?-V?5lV(7Z4>a@ErFKh-DN)|Y?~axb_}!Rr0xg8?p#VO~?Lmz zW}ZB~&aHjfW1KtFskurES1l2EU$10#GW!d4L116-Ks0{ZT4;o81Tm&iLf*|)5GjuO zs&XV4U#3TVvqc7SLjrh*t)>#}l&MJnR%`;OHbHkl@N{^%+Jxx7$upGhyPq9~fuT8k+QcJL3lwb+|d%r+wlqo~{%-zUmYH2kg~%igZE(J9$ju9h`5^ z4W|74=)@yiPUy33Yz6z71Dnp&pKnX!MTe&b?*Lmr-9g_}N$u)hmincTKs;Ar<_7VUU^F`5e1%^B z%wYCRwJGz*k;Aiue!RH3l6eT`72b8>Vr+I^xSJcglJanifVI~CebpunzyM)1h) zs1aws4g4#~fOCTEJ*h60cYy{QpVGd=B8zplQ_82|LA=uEVu&#p4A=YZ+s-@j;f4FV z<@KyzQIsap6?%+9(`a`3T&kXYd3uYi65a!YYxngzrofcX&v0VK9G{u0ppB1}*y7H) zEU4=FU^W4ao><1j27Xw;ScKl!tFNftZ1YJ!t~Ojy9gL;)i`^opI`B%iAIk zG4+2Xhv_%g`ce9KtD7<1VfWf=1W}FJ1@?pI!X@V##G#8jn0A7-po6CC)t9~-81uX& z?QWaT#9|{5v1Z}Zq|Nkj957J#G6%eWl=iS$zAmY#@3gJ(ITrtU$vJww_YO1Q+yI`4 zWQ2Q)qAtkPnf=6SqB@%WqUDuRi_WZ}n=WX-|*DRS= zHq1AmqY*d54wcS&p=X%f+FkVR&xqBLuJJjh#>Ie!PXTLod2H~f?7szK5`(w5xxY?w zk#tz~Y=H)Nq$^}Zh@0tl$dYE>r4MwE1e-Tg4D{R`J!XP=fe-cKqF8eX<}y{H6}>W5 z8a_QXC-kBy(i%dy$Zx+b=$3rl0m*MFp@Or&4BhptN=0O``m5i+h+K8^1e%?tAgvSF zM-skxGj3BURN{`4&4tDMsced{l7F^%HWhLU6jf_WG&IgC#=geaZid}OJUHNU|ZmX;x);fLmBw16_-z5?-D%*cza$dvSTL0 z%pMv-&!uBr6dDL73htPyzLX8sigNCl?~Z%~l&XgK{*tR{<1B$c*Ztkg131~K6nvv> zI!WNg9S?QPX`;+6kTIZ-(RjS1z%vzkIc0u$T=|%4l1sP@#-mg(j!Vb1qnJw3C;8s_`s2Ru>cFlE3BEl& zA*{?)$A>$;`JWRSX84Y-0!2zpXpF%m@|&(-_tvaVx}DRAGSGL{Zlpy5=gbshPPJr_>S#$XdD8x!y(-SaV@_i<0E;{S+NFcBq9ahCAN$Iu zlPhdis@LYNXJ-yr`m+a|aT7kvxP#HE)2s&>*tnSi z4Iz*Ju8T5?br!y8GjCBsk9i1h>k;j`S|d;i5w>x(kV=<1|C4gmQzR+0}-*3vjKUauh z%8G)8BH6!;DWql%cE3Oe?8mkHbQ6)uQ))ovx4ybSS0%qO9_%iQ5SFl}sJZ?|xFcQyInYhY>B#=V*cRvjaPTHNnLzUGWAq=z>?B~g4n8$UDOpm02Rm`Y0?rkOfd+5=+ z%c|vX0WRFYu%)=QN%mp(BOkUGB*Ka|j~?P?sgO-CcBV|LD9qfJEKrp}_Qg1MV(HqU zuq!9iOdh2=)XlsHL30YzuhYgVkMk~oc`%8$kqf-jO$pk~?cOwKKxdzGfcmAEfu(>Y zK(QX}^gk`^b?dyT?oqq#zMH?d1*v=-D_uurD zYD+dL;in2^jAOt5(y{(rf>7V*c5k;&XH(PMn2ToPVjJ?4jessh2;(xcxc5f%6;Zrj zk{$D+6a5y5-4cnWMCu{2qt3=<0Zs((AL7oeS|Z`Fh@grcCVQS`uKk5^BN%l=ekr$A zDn5RDV&KjkX7b}bdzqRln64-l%umUp2DRA76l*(!OC|pHV_%5fT!HXxoq=bYPqcKf zt=at8>|M;oKf60p*3`sXkI5HTU)5lu18 z)ggfxk!AMhQao{m3wXi#pF#rBJP&j(Zn5zoFL2a{NkCxv|2S#-Urz}fG!SO!pYd}4 zoz{ufd`z`o81&Tp6F&6_QIv*(Aa5)Ede}bvbHJ_$BK<%?{v;O`p{3*CLe6(GcLAD( z+OY_onI8q`{qBE*NH_uef^QxC@we>m|Ku9~@1EL!x(Y^ixu@WKxzKMUw`<@z!T7IN z4-c&*aqAwQ{XXTS$=DwHAh9SiFmk=d#9rxMYx{&EszWMfCFXpFN>!zS#MoC7qmjW1 zt{5{_&E>N@-q#WTti}P4>8SJa*`l!Mt3Lt-m))v??GEULD$>hckJqFRKa%O~4yDJI z~(cmh3iqxUXLX)Yepj)#8(v>-TAd<`$k^%Kxh zaP|B)U{b#?TE)k{N2uV=6xQVJhcZAQcVr*Suyot8zj+HWkJO@m{Sr|vQ3Tr+3r*9B zp{ZqSDTb#ZV+iN`-K-Hv*w;eRM&Q z1(xUVE+Ay57SYRmH*|A!%xosFzOQx|@B72WD2gJR8r+z>oW3-0mU*ocRnq61ieSD* ztijqdXTaj=Ouhb%!98>r?P}E8{*sbV4q36{5qPQh8mA#wN3dbb&%kT&w02@okwJBP zX5HVJX%b>k!-YW+`;$BS z*LpZLt&Vd_u|a`7uN9ghJRUc`{OzMQMxmKe%41qoPV(wS5P84 zTgl{pRy>mcJ*Q7jbfF$c`e7PSZ7ajSfqJ5B3PP!Aq#19YrRF)3T=lPx%T&&}zsynCBvyj(h1flUzr;lOoN?U!QCz+E(+4eW=8#$!hTtH;g`*tOce( z^>(whV#C$|HVW?{n2>Hc&LqqBv+Olqs6I}@m7ZOrIJ-OzqlQgL&Fn6aqwK1eONTwh z*A>~AkdDxbN1zO#4}#$HFJ}qtw^fJY;Ru56pQBjeF&Dp$GON*Qyb0v))8V1)uMkPl z^jZ*g-)WNDe8UZtFhE1T)2Td5H?MqSm|+VACBa-maz>zTI=N4@m2)IUj@3Is zpK1eg18e@?4Ok4&3zWCHYB`M<8d=eAUt^@Xg@?w}q3S&2%}ykk?T`UoIb@OiJzyF- z_X0!@fs9>`4J#WAiJ=su%s5wVGqX0(Bl@hI4@fUgW1)vhPixW0Qxi4weh2^m386=X z1ky9i=~%}NAWRpf(iJ>YXu6@56Bk`bg&!R)Wsq{O3Y1l~h=L+D6A5+hq4W$bPMuezLS+=QTD>>748V#ZnC3Cm|jNlJ4K>?k8`wGjuVlGi>=1 zgOt^>{UtEmQZf-Rp`tR8ZJYu{BM5Sx2_V6kFB-*WVHq61MXTlm$ZsM~q=WwJ$xfo! z6}zp$P3!T9VWX}ANYo70B0^@xic!OUCwhJ2EzZ_d^pK&x->hLNmLII%NC=I}4BwD= z(aW#@2dINtGiwYC+EWNz`7>E2gbtO$HWQAFQLmAyOa|7I zExP#a1ESEM3Mq0Hhb9#hc!d)zXT%SK4k%OqJkAKDgnw_+Kqn13EduV~-!K>k;gf?l zKZzax_n~?omm?=}d^q|`1f&1*;Hke99sXBdL`rVYL~TeD;$QZ@g!mU1uljjSwME02 PiW%)U+n4jb-B14k9s6f8 literal 35771 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 x?q}~ diff --git a/static/img/ui/config-screen.png b/static/img/ui/config-screen.png index df719101f018c50365eeb04243732fd0c47da681..4f0bcbd8cab21a4e6745d50e41ed5f208a24a974 100644 GIT binary patch literal 45113 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
    `](/docs/ui/components/roots/Form). The selection arrives in the form's `onSubmit`, keyed by `name`. +Render it inside a [``](/docs/ui/components/Form). The selection arrives in the form's `onSubmit`, keyed by `name`. ```tsx console.warn(values.difficulty)}> @@ -26,11 +25,11 @@ Render it inside a [``](/docs/ui/components/roots/Form). The selection arr options={['Peaceful', 'Easy', 'Normal', 'Hard']} defaultValue={'Normal'} /> - + {'Save'} ``` -It is [`Dropdown`](/docs/ui/components/fields/Dropdown) with the [theme](./theme.md)'s closed-box, popup and option-row textures applied, plus a caption above the box. The ore layer owns the option children: it maps each entry of `options` to a `Option` whose value and label are both that string, which is why `children` is not accepted here. +It is [`Dropdown`](/docs/ui/components/Dropdown) with the [theme](./theme.md)'s closed-box, popup and option-row textures applied, plus a caption above the box. The ore layer owns the option children: it maps each entry of `options` to a `Option` whose value and label are both that string, which is why `children` is not accepted here. :::caution The result is an index Like the primitive, the submitted value is the selected option's **index** (a `number`), not the string — that is the native modal dropdown's behavior. Read it back as `options[values[name]]`. @@ -45,7 +44,7 @@ Like the primitive, the submitted value is the selected option's **index** (a `n | `label` | `string` | — | Caption rendered above the closed box | | `defaultValue` | `string` | the first option | Initial selection, matched against one of `options` | -Inherits every prop of [`Dropdown`](/docs/ui/components/fields/Dropdown) except `children` — the popup background, the option row faces, the option and current-value text styles — with the theme's values as defaults rather than a lock. Through it, [control props](/docs/ui/components/control-props) as well. +Inherits every prop of [`Dropdown`](/docs/ui/components/Dropdown) except `children` — the popup background, the option row faces, the option and current-value text styles — with the theme's values as defaults rather than a lock. Through it, [control props](/docs/ui/components/control-props) as well. ## Examples @@ -56,7 +55,7 @@ const MODES = ['Peaceful', 'Easy', 'Normal', 'Hard'];
    console.warn(MODES[Number(values.difficulty)])}> - + {'Save'} ``` @@ -72,7 +71,7 @@ const MODES = ['Peaceful', 'Easy', 'Normal', 'Hard']; There is no `onChange`: a native modal is atomic, so nothing reaches script while the form is open. -For the same selection model drawn inline, with no popup, use [`Select`](/docs/ui/components/controls/Select) — or [`Radio`](./Radio.md) and [`ToggleButtonGroup`](./ToggleButton.md) for its themed forms. +For the same selection model drawn inline, with no popup, use [`Select`](/docs/ui/components/Select) — or [`Radio`](./Radio.md) and [`ToggleButtons`](./ToggleButtons.md) for its themed forms. ## Limits diff --git a/docs/ore-styled/Header.md b/docs/ore-styled/Header.md index 381e215..a5b46a6 100644 --- a/docs/ore-styled/Header.md +++ b/docs/ore-styled/Header.md @@ -1,5 +1,4 @@ --- -sidebar_position: 5 description: "Ore-styled header bar: icon-only back button, a breadcrumb trail, and a close button." --- # Header @@ -37,15 +36,13 @@ Renders as `Settings > Server > Pricing`, centered between the two icon buttons. | Prop | Type | Default | Description | | --- | --- | --- | --- | -| `title` | [`DisplayText`](/docs/i18n#displaytext) | — | The screen's own name, first in the trail. Optional only with `segments` | -| `breadcrumbs` | `DisplayText[]` | `[]` | The trail after the title, joined as `title > … > …` | -| `segments` | `readonly TrailSegment[]` | — | The whole [trail](./Trail.md) as segments, live ones included, in place of `title` and `breadcrumbs` | -| `titleMaxLength` | `number` | — | Characters the title reserves, for a title only known when the screen is shown | +| `title` | [`DisplayText`](/docs/i18n/api#displaytext) | — | The screen's own name, first in the trail. Baked, with `breadcrumbs` | +| `breadcrumbs` | `DisplayText[]` | `[]` | The trail after the title, joined as `title > ... > ...`. Baked, with `title` | +| `trail` | [`DisplayText`](/docs/i18n/api#displaytext) | — | The whole [trail](./Trail.md) as one composed value, in place of `title` and `breadcrumbs`, for a trail only known when the screen is shown | | `onBack` | `(event: PressEvent) => unknown` | — | Press handler for the back control. Omit to hide it — the slot keeps its width, so the title stays centered | | `backTo` | `ScreenKey` | — | The screen the back control returns to, in place of `onBack`: a link rather than a handler | | `back` | `boolean` | `false` | A back control that returns wherever the player came from, without naming it | | `cancel` | `string` | — | The back control as a modal's labeled dismiss. Only inside a `
    ` | -| `cancelWidth` | `number` | — | Room the cancel control takes; wide enough for its word | | `onClose` | `(event: PressEvent) => unknown` | — | Press handler for the close control. Omit to hide it | Inherits [control props](/docs/ui/components/control-props). It already sets `marginTop`, `marginLeft` and `marginRight` to `1` and takes the theme's header background; your own layout props override them. @@ -67,9 +64,25 @@ Three ways out, and which one you can use depends on what the screen knows about A modal has two controls of its own, its submit and its dismiss, and the dismiss is the only one left to leave the screen with. `cancel` puts it in the back slot with a word on it, since leaving a form abandons what was typed into it: ```tsx -
    +
    ``` +The labeled dismiss is wider than the icon back, so a header wearing one leaves its [trail](./Trail.md) less room — which is what `trailText(segments, resolve, { back: 'cancel' })` is told. + +## A trail only known at show time + +`title` and `breadcrumbs` are composed by the build in every language, collapsed to the room the bar leaves. Where the trail is decided per player — the addon selected, the entity being edited — compose it instead and pass it as `trail`, which travels as one form entry: + +```tsx +
    back()} + onClose={() => close()} +/> +``` + +Pass `trail` on every render, empty included: the entry it reserves is part of the screen's shape, and a shape that comes and goes moves every entry after it. + ## Localized titles `title` and every breadcrumb segment are `DisplayText`, so each may be a literal string, a `.lang` key, or a `RawMessage`: @@ -109,7 +122,7 @@ Omit `onBack` on the first screen of a stack. The slot still reserves its width, ### As a fixed screen header -Pair it with a [`Scroll`](/docs/ui/components/layout/Scroll) so the header stays put while the content moves. +Pair it with a [`Scroll`](/docs/ui/components/Scroll) so the header stays put while the content moves. ```tsx @@ -139,7 +152,7 @@ Read from `theme.components.header`: ## Notes - Use the same `Header` on every screen of a stack so the chrome never jumps. -- Keep the title short and put context in `breadcrumbs` — the trail is what gets clipped first when the row runs out of room. +- Keep the title short and put context in `breadcrumbs` — a composed trail gives its middle up first when the row runs out of room. - Omit `onBack` rather than passing a no-op on a root screen; the layout already accounts for the missing control. - Prefer `key()` output over pre-resolved strings so each player reads the trail in their own language. - Pair with [`MenuRow`](./MenuRow.md) for the list below it — the two are designed as one browse screen. diff --git a/docs/ore-styled/Input.md b/docs/ore-styled/Input.md index 628eefd..ef704f5 100644 --- a/docs/ore-styled/Input.md +++ b/docs/ore-styled/Input.md @@ -1,5 +1,4 @@ --- -sidebar_position: 12 description: "A themed single-line text field for a modal form." --- # Input @@ -16,16 +15,16 @@ import { Input } from '@bedrock-core/ore-styled'; ## Usage -Render it inside a [``](/docs/ui/components/roots/Form). The value arrives in the form's `onSubmit`, keyed by `name`. +Render it inside a [``](/docs/ui/components/Form). The value arrives in the form's `onSubmit`, keyed by `name`. ```tsx console.warn(values.nickname)}> - + {'Save'} ``` -It is [`Input`](/docs/ui/components/fields/Input) with the [theme](./theme.md)'s field textures and font applied, plus a caption above the box. The widget itself is the engine's — it is owned by the client while the form is open, and every field's value comes back at once on submit. +It is [`Input`](/docs/ui/components/Input) with the [theme](./theme.md)'s field textures and font applied, plus a caption above the box. The widget itself is the engine's — it is owned by the client while the form is open, and every field's value comes back at once on submit. ## Props @@ -36,7 +35,7 @@ It is [`Input`](/docs/ui/components/fields/Input) with the [theme](./theme.md)'s | `placeholder` | `string` | — | Text shown inside the field when it is empty | | `defaultValue` | `string` | `''` | Initial text | -Inherits every prop of [`Input`](/docs/ui/components/fields/Input) — the font, the scale, the text offsets and the per-state box textures — with the theme's values as defaults rather than a lock: pass one and yours wins. Through it, [control props](/docs/ui/components/control-props) as well. +Inherits every prop of [`Input`](/docs/ui/components/Input) — the font, the scale, the text offsets and the per-state box textures — with the theme's values as defaults rather than a lock: pass one and yours wins. Through it, [control props](/docs/ui/components/control-props) as well. ## Examples @@ -46,7 +45,7 @@ Inherits every prop of [`Input`](/docs/ui/components/fields/Input) — the font,
    save(values.nickname, values.motto)}> - + {'Save'}
    ``` diff --git a/docs/ore-styled/MenuRow.md b/docs/ore-styled/MenuRow.md index 2218f01..167174e 100644 --- a/docs/ore-styled/MenuRow.md +++ b/docs/ore-styled/MenuRow.md @@ -1,5 +1,4 @@ --- -sidebar_position: 7 description: "The browse-screen row: leading thumbnail, title, one-line subtitle, and a trailing chevron, drawn on the dropdown-option face." --- # MenuRow @@ -35,7 +34,7 @@ function Row(): JSX.Element { | Prop | Type | Default | Description | | --- | --- | --- | --- | -| `title` | [`DisplayText`](/docs/i18n#displaytext) | — | First line — the row's name | +| `title` | [`DisplayText`](/docs/i18n/api#displaytext) | — | First line — the row's name | | `subtitle` | `DisplayText` | — | Second line, rendered muted. Omit for a single-line row | | `icon` | `string` | — | Leading thumbnail texture path. Omit for a text-only row | | `iconSize` | `number` | the theme's row icon size | Thumbnail edge in px | @@ -43,7 +42,7 @@ function Row(): JSX.Element { | `selected` | `boolean` | `false` | Whether this row is the list's current selection. For a selecting list, where one row stands after the press | | `depth` | `number` | `0` | Indent level for nested index rows. Each step insets the row's whole box, not its contents, so a child row is visibly narrower than its section header | | `onPress` | `(event: PressEvent) => unknown \| Promise` | — | Press handler. Use `to` instead when the press opens another screen | -| `to` | `ScreenKey` | — | The screen this row opens, `:`. A row with one is a [``](/docs/ui/components/controls/Link) | +| `to` | `ScreenKey` | — | The screen this row opens, `:`. A row with one is a [``](/docs/ui/components/Link) | | `replace` | `boolean` | `false` | With `to`: take the place of the screen this row is on rather than stacking over it | | `titleMaxLength` | `number` | — | Characters the title reserves, for a title only known when the screen is shown | | `subtitleMaxLength` | `number` | — | Characters the subtitle reserves. Setting it also keeps the subtitle line when the subtitle is empty, so the row has one shape | @@ -162,4 +161,4 @@ Read from `theme.components.menuRow`: - Keep subtitles to one short line; both lines are clipped with an ellipsis at one line each. - Use `depth` for hierarchy instead of nesting `Panel`s with padding — the inset box is what communicates the level. - Set `chevron={false}` whenever pressing the row does not open another screen. -- Pair with [`Header`](./Header.md) above and a [`Scroll`](/docs/ui/components/layout/Scroll) around the rows for a standard browse screen. +- Pair with [`Header`](./Header.md) above and a [`Scroll`](/docs/ui/components/Scroll) around the rows for a standard browse screen. diff --git a/docs/ore-styled/Radio.md b/docs/ore-styled/Radio.md index 5346b56..4184fee 100644 --- a/docs/ore-styled/Radio.md +++ b/docs/ore-styled/Radio.md @@ -1,5 +1,4 @@ --- -sidebar_position: 10 description: "One choice out of several with every option visible: a bullet and a label per row." --- # Radio @@ -36,9 +35,9 @@ The options are an array, not children — this layer owns them and maps each en | Screen | What it becomes | What reaches script | | --- | --- | --- | -| [`
    `](/docs/ui/components/roots/Form) | the engine's own [inline select](/docs/ui/components/controls/Select) | nothing until submit — the chosen option's **index** arrives at `values[name]` | -| [``](/docs/ui/components/roots/Screen) | a button per row | `onChange`, with the chosen **value** | -| [``](/docs/ui/components/roots/Container) | a row whose press is an item taken and put back | `onChange`, with the chosen **value** | +| [``](/docs/ui/components/Form) | the engine's own [inline select](/docs/ui/components/Select) | nothing until submit — the chosen option's **index** arrives at `values[name]` | +| [``](/docs/ui/components/Screen) | a button per row | `onChange`, with the chosen **value** | +| [``](/docs/ui/components/Container) | a row whose press is an item taken and put back | `onChange`, with the chosen **value** | So `name` is the modal's prop, and `value` / `onChange` only do anything where a press reaches script. Note the asymmetry: the modal answers with an index, a press answers with the value. @@ -65,7 +64,7 @@ interface RadioOption { } ``` -Inherits every prop of [`Select`](/docs/ui/components/controls/Select) except `children` — the bullet glyphs per state, their size, the option row faces and the label style — with the theme's values as defaults. Row surfaces default to nothing: the bullet carries the look. Through it, [control props](/docs/ui/components/control-props) as well. +Inherits every prop of [`Select`](/docs/ui/components/Select) except `children` — the bullet glyphs per state, their size, the option row faces and the label style — with the theme's values as defaults. Row surfaces default to nothing: the bullet carries the look. Through it, [control props](/docs/ui/components/control-props) as well. ## Examples @@ -76,7 +75,7 @@ const TEAMS = [{ value: 'red', label: 'Red' }, { value: 'blue', label: 'Blue' }] join(TEAMS[Number(values.team)].value)}> - + {'Join'} ``` @@ -98,7 +97,7 @@ function TeamPicker(): JSX.Element { ## Notes -Use `Radio` when the options read as a list and each needs its own line. [`ToggleButtonGroup`](./ToggleButton.md) is the same choice drawn as side-by-side segments, for when a button-sized hit target suits better. +Use `Radio` when the options read as a list and each needs its own line. [`ToggleButtons`](./ToggleButtons.md) is the same choice drawn as side-by-side segments, for when a button-sized hit target suits better. ## Limits diff --git a/docs/ore-styled/Slider.md b/docs/ore-styled/Slider.md index de594fe..e653795 100644 --- a/docs/ore-styled/Slider.md +++ b/docs/ore-styled/Slider.md @@ -1,5 +1,4 @@ --- -sidebar_position: 14 description: "A themed numeric slider for a modal form." --- # Slider @@ -16,16 +15,16 @@ import { Slider } from '@bedrock-core/ore-styled'; ## Usage -Render it inside a [`
    `](/docs/ui/components/roots/Form). The value arrives in the form's `onSubmit`, keyed by `name`. +Render it inside a [``](/docs/ui/components/Form). The value arrives in the form's `onSubmit`, keyed by `name`. ```tsx console.warn(values.volume)}> - + {'Save'} ``` -It is [`Slider`](/docs/ui/components/fields/Slider) with the [theme](./theme.md)'s track, progress fill and thumb textures applied, plus a caption above it. The widget is the engine's: the player drags it while the form is open, and the value comes back with every other field on submit. +It is [`Slider`](/docs/ui/components/Slider) with the [theme](./theme.md)'s track, progress fill and thumb textures applied, plus a caption above it. The widget is the engine's: the player drags it while the form is open, and the value comes back with every other field on submit. ## Props @@ -38,7 +37,7 @@ It is [`Slider`](/docs/ui/components/fields/Slider) with the [theme](./theme.md) | `step` | `number` | `1` | Increment between selectable values | | `defaultValue` | `number` | `min` | Initial value | -Inherits every prop of [`Slider`](/docs/ui/components/fields/Slider) — the track, progress and thumb textures, `trackHeight`, `thumbWidth` / `thumbHeight` — with the theme's values as defaults rather than a lock. Through it, [control props](/docs/ui/components/control-props) as well. +Inherits every prop of [`Slider`](/docs/ui/components/Slider) — the track, progress and thumb textures, `trackHeight`, `thumbWidth` / `thumbHeight` — with the theme's values as defaults rather than a lock. Through it, [control props](/docs/ui/components/control-props) as well. ## Examples @@ -48,7 +47,7 @@ Inherits every prop of [`Slider`](/docs/ui/components/fields/Slider) — the tra
    apply(values)}> - + {'Apply'} ``` diff --git a/docs/ore-styled/Tabs.md b/docs/ore-styled/Tabs.md new file mode 100644 index 0000000..da82ed0 --- /dev/null +++ b/docs/ore-styled/Tabs.md @@ -0,0 +1,69 @@ +--- +description: "Panes switched on the client, each header a label on the theme's faces." +--- +# Tabs + +Panes switched on the client, each header a label on the theme's faces. + +![Tabs](/img/ore-styled/Tabs.png) + +## Import + +```tsx +import { Tabs } from '@bedrock-core/ore-styled'; +``` + +## Usage + +```tsx + + + + + + + + +``` + +It is [`Tabs`](/docs/ui/components/Tabs) with the [theme](./theme.md)'s `tabs` faces applied and a label in place of a drawn header. A chosen tab wears the pressed face and its label drops a pixel; labels are white whichever tab is chosen. + +Switching tabs reaches no script and presents nothing again. A tab whose content depends on the switch is a screen change, not a tab. + +## Props + +### Tabs + +| Prop | Type | Default | Description | +| --- | --- | --- | --- | +| `tabHeight` | `number` | the theme's tab height | Height of the header row; the panes take what is left | +| `tabBackground` | `string` | the theme's normal face | The face a header is drawn on while its tab is not chosen | +| `tabHover` | `string` | the theme's hover face | The face while the pointer is over a tab that is not chosen | +| `tabSelected` | `string` | the theme's pressed face | The face while its tab is the chosen one | +| `gap` | `Spacing` | `-1` | Space between headers; `-1` is the overlap that fuses adjacent borders | + +Inherits [control props](/docs/ui/components/control-props). + +### Tabs.Tab + +| Prop | Type | Default | Description | +| --- | --- | --- | --- | +| `label` | [`DisplayText`](/docs/i18n/api#displaytext) | — | The tab's name on its header | +| `children` | `JSX.Node` | — | The pane shown while the tab is chosen | + +## Examples + +### A face of your own for the chosen tab + +```tsx + + {first} + {second} + +``` + +## Notes + +The headers share the row's width evenly, so keep each label short enough to fit its share. + +The theme's `tabs` section and its textures started as copies of the toggle buttons'. diff --git a/docs/ore-styled/Toggle.md b/docs/ore-styled/Toggle.md index 4d94992..005fe52 100644 --- a/docs/ore-styled/Toggle.md +++ b/docs/ore-styled/Toggle.md @@ -1,5 +1,4 @@ --- -sidebar_position: 9 description: "A themed on/off switch that draws as a native field on a modal and a press everywhere else." --- # Toggle @@ -26,9 +25,9 @@ import { Toggle } from '@bedrock-core/ore-styled'; | Screen | What it becomes | What reaches script | | --- | --- | --- | -| [`
    `](/docs/ui/components/roots/Form) | a native [`Toggle`](/docs/ui/components/controls/Toggle) the engine owns | nothing until submit — the value arrives at `values[name]` | -| [``](/docs/ui/components/roots/Screen) | a press that holds its own state | `onChange`, on every press | -| [``](/docs/ui/components/roots/Container) | an item taken and put straight back | `onChange`, on every press | +| [``](/docs/ui/components/Form) | a native [`Toggle`](/docs/ui/components/Toggle) the engine owns | nothing until submit — the value arrives at `values[name]` | +| [``](/docs/ui/components/Screen) | a press that holds its own state | `onChange`, on every press | +| [``](/docs/ui/components/Container) | an item taken and put straight back | `onChange`, on every press | `name` is the modal's prop and required there; `on` and `onChange` only do anything where a press reaches script. @@ -53,7 +52,7 @@ The theme's switch textures are defaults, not a lock: `background`, `backgroundH apply(values)}> - + {'Save'} ``` diff --git a/docs/ore-styled/ToggleButton.md b/docs/ore-styled/ToggleButton.md deleted file mode 100644 index 691c88a..0000000 --- a/docs/ore-styled/ToggleButton.md +++ /dev/null @@ -1,106 +0,0 @@ ---- -sidebar_position: 11 -description: "One choice out of several, drawn as side-by-side segments with fused borders." ---- -# ToggleButtonGroup - -One choice out of several, drawn as side-by-side segments. - -![ToggleButtonGroup](/img/ore-styled/FormToggleButton.png) - -## Import - -```tsx -import { ToggleButtonGroup } from '@bedrock-core/ore-styled'; -``` - -## Usage - -```tsx - -``` - -The same choice a [`Radio`](./Radio.md) makes, in the shape a segmented control wears. Use it when the options benefit from a button-sized hit target and should read as one connected control. - -## It depends on the screen - -`ToggleButtonGroup` asks [`useMechanism('Select')`](/docs/ui/hooks/useMechanism) what a single choice becomes on the screen it is being drawn on. - -| Screen | What it becomes | What reaches script | -| --- | --- | --- | -| [`
    `](/docs/ui/components/roots/Form) | the engine's own [inline select](/docs/ui/components/controls/Select) | nothing until submit — the chosen option's **index** arrives at `values[name]` | -| [``](/docs/ui/components/roots/Screen) | a button per segment | `onChange`, with the chosen **value** | -| [``](/docs/ui/components/roots/Container) | a segment whose press is an item taken and put back | `onChange`, with the chosen **value** | - -The segments are laid out by the library's own flex system either way — equal widths, and a one-pixel overlap so adjacent borders fuse — so the geometry belongs to this layer and no JSON UI edit follows a change here. - -## Props - -| Prop | Type | Default | Description | -| --- | --- | --- | --- | -| `options` | `ToggleButtonOption[]` | — | The segments, left to right | -| `name` | `string` | — | Result key on a modal, where it is required; ignored where the press is the answer | -| `label` | `string` | — | Caption rendered above the group | -| `defaultValue` | `string` | the first option | Initial selection, matched on `value` | -| `segmentHeight` | `number` | the theme's toggle-button height | Height of each segment | -| `gap` | `Spacing` | `-1` | Space between segments; `-1` is the overlap that fuses adjacent borders | -| `value` | `string` | — | Held by the caller instead of by the group. Only where a press reaches script | -| `onChange` | `(value: string) => void` | — | Called with the chosen value, on the hosts where a press reaches script | -| `enabled` | `boolean` | `true` | `false` draws the disabled faces and ignores presses | - -```ts -interface ToggleButtonOption { - value: string; - label: string; -} -``` - -Inherits every prop of [`Select`](/docs/ui/components/controls/Select) except `children`, with the theme's segment faces and text styles as defaults. Segments are glyph-less by default; pass a `bullet` to opt into one and the primitive's per-state fallbacks apply. Through it, [control props](/docs/ui/components/control-props) as well. - -## Examples - -### In a modal - -```tsx -const MODES = [ - { value: 'easy', label: 'Easy' }, - { value: 'normal', label: 'Normal' }, - { value: 'hard', label: 'Hard' }, -]; - - setMode(MODES[Number(values.difficulty)].value)}> - - - -``` - -### On a screen of buttons - -```tsx -function ModePicker(): JSX.Element { - const [mode, setMode] = useState('normal'); - - return ; -} -``` - -### Separated segments - -```tsx - -``` - -## Notes - -The chosen segment sits a pixel lower than the others, which is what reads as pressed. - -Segments share the width evenly, so a long label in one of them widens every segment. Keep them short, or reach for [`Radio`](./Radio.md) where each option gets its own line. diff --git a/docs/ore-styled/ToggleButtons.md b/docs/ore-styled/ToggleButtons.md new file mode 100644 index 0000000..b43084d --- /dev/null +++ b/docs/ore-styled/ToggleButtons.md @@ -0,0 +1,123 @@ +--- +description: "Choices drawn as side-by-side segments with fused borders: one, or any number with multiple." +--- +# ToggleButtons + +Choices drawn as side-by-side segments: one, or any number with `multiple`. + +![ToggleButtons](/img/ore-styled/FormToggleButton.png) + +## Import + +```tsx +import { ToggleButtons } from '@bedrock-core/ore-styled'; +``` + +## Usage + +```tsx + +``` + +The same choice a [`Radio`](./Radio.md) makes, in the shape a segmented control wears. Use it when the options benefit from a button-sized hit target and should read as one connected control. + +With `multiple`, every segment is on or off by itself and pressing one leaves the others alone. Nothing else changes: the segments, their textures and the way a chosen one reads are the same in both modes. + +## It depends on the screen + +`ToggleButtons` asks [`useMechanism('Select')`](/docs/ui/hooks/useMechanism) what a choice becomes on the screen it is being drawn on. + +| Screen | What it becomes | What reaches script | +| --- | --- | --- | +| [`
    `](/docs/ui/components/Form) | the engine's own [inline select](/docs/ui/components/Select), or a native toggle per segment with `multiple` | nothing until submit — the chosen **index** arrives at `values[name]`, or with `multiple` the **indices** that are on | +| [``](/docs/ui/components/Screen) | a button per segment | `onChange`, with the chosen **value**, or every chosen **value** with `multiple` | +| [``](/docs/ui/components/Container) | a segment whose press is an item taken and put back | `onChange`, as on a screen | + +The segments are laid out by the library's own flex system either way — equal widths, and a one-pixel overlap so adjacent borders fuse — so the geometry belongs to this layer and no JSON UI edit follows a change here. + +## Props + +| Prop | Type | Default | Description | +| --- | --- | --- | --- | +| `options` | `ToggleButtonsOption[]` | — | The segments, left to right | +| `multiple` | `boolean` | `false` | Any number of segments may be on at once | +| `name` | `string` | — | Result key on a modal, where it is required; ignored where the press is the answer | +| `label` | `string` | — | Caption rendered above the segments | +| `defaultValue` | `string`, or `string[]` with `multiple` | the first option, or none with `multiple` | Initial selection, matched on `value` | +| `value` | `string`, or `string[]` with `multiple` | — | Held by the caller instead of by the control. Only where a press reaches script | +| `onChange` | `(value: string) => void`, or `(values: string[]) => void` with `multiple` | — | Called with the chosen value, or every chosen value in segment order, on the hosts where a press reaches script | +| `segmentHeight` | `number` | the theme's toggle-button height | Height of each segment | +| `gap` | `Spacing` | `-1` | Space between segments; `-1` is the overlap that fuses adjacent borders | +| `enabled` | `boolean` | `true` | `false` draws the disabled faces and ignores presses | + +```ts +interface ToggleButtonsOption { + value: string; + label: string; +} +``` + +Inherits every prop of [`Select`](/docs/ui/components/Select) except `children`, with the theme's segment faces, label colours and drop as defaults. Segments are glyph-less by default; pass a `bullet` to opt into one and the primitive's per-state fallbacks apply. Through it, [control props](/docs/ui/components/control-props) as well. + +## Examples + +### In a modal + +```tsx +const MODES = [ + { value: 'easy', label: 'Easy' }, + { value: 'normal', label: 'Normal' }, + { value: 'hard', label: 'Hard' }, +]; + + setMode(MODES[Number(values.difficulty)].value)}> + + {'Start'} + +``` + +### Several at once in a modal + +```tsx +const NOTICES = [ + { value: 'join', label: 'Join' }, + { value: 'leave', label: 'Leave' }, + { value: 'buy', label: 'Buy' }, +]; + +
    setNotices((values.notices as number[]).map(index => NOTICES[index].value))}> + + {'Save'} + +``` + +### On a screen of buttons + +```tsx +function ModePicker(): JSX.Element { + const [mode, setMode] = useState('normal'); + + return ; +} +``` + +### Separated segments + +```tsx + +``` + +## Notes + +A chosen segment wears the pressed face, a white label and a one-pixel drop, which is what reads as pressed. On a modal the label is drawn inside each state of the engine's own control, so it changes with the segment rather than staying one colour. + +Segments share the width evenly, so a long label in one of them widens every segment. Keep them short, or reach for [`Radio`](./Radio.md) where each option gets its own line. diff --git a/docs/ore-styled/Trail.md b/docs/ore-styled/Trail.md index ac2da40..614a65d 100644 --- a/docs/ore-styled/Trail.md +++ b/docs/ore-styled/Trail.md @@ -1,15 +1,16 @@ --- -sidebar_position: 6 -description: "A breadcrumb trail as a row of its own: title > scope > entity, with live segments that take no room when empty." +description: "A breadcrumb trail as a row of its own: title > scope > entity, travelling as one value that collapses from the middle when it does not fit." --- # Trail The breadcrumb trail every [`Header`](./Header.md) wears, as a row of its own so any screen can show one. +![Trail](/img/ore-styled/Trail.png) + ## Import ```tsx -import { Trail } from '@bedrock-core/ore-styled'; +import { Trail, trailText } from '@bedrock-core/ore-styled'; ``` ## Usage @@ -24,42 +25,53 @@ Renders as `Economy > Server > Pricing`, the separators in the trail's lighter c | Prop | Type | Default | Description | | --- | --- | --- | --- | -| `segments` | `readonly TrailSegment[]` | — | The segments in order | - -```ts -type TrailSegment = DisplayText | { text: DisplayText; maxLength: number }; -``` +| `text` | [`DisplayText`](/docs/i18n/api#displaytext) | — | The whole trail as one value, drawn by one label. `trailText` composes one | +| `maxLength` | `number` | — | Characters `text` reserves, which is what makes the label live | +| `segments` | `readonly DisplayText[]` | — | A trail known at build time, in place of `text`: composed by the build in every language, collapsed to the room the row is laid out with | Inherits [control props](/docs/ui/components/control-props). -## Baked and live segments +## A live trail is one value -A bare segment is **baked**: the build writes the string into the pack. - -A segment given a `maxLength` is **live**: the compiled screen keeps a box that wide and shows whatever it is sent at show time — a key the client resolves, or a literal. Reach for it where the text is only known when the screen opens, such as an addon's name or the entity being edited. +A trail whose segments are only known when the screen opens — an addon's name, the entity being edited — is composed server-side and travels as a single `RawMessage`: ```tsx - +const trail = trailText( + [addonName, scopeLabel, entityName], + core.translations.forPlayer(player), + { back: 'icon' }, +); + + +``` + +A form entry's text is resolved by the **client** before the binding sees it, so every segment reaches the player in their own language off one entry. `maxLength` is what makes the label live: the compiled screen keeps one entry for the trail and shows whatever it is sent. + +## Collapsing from the middle + +`trailText` resolves every segment through the resolver it is given and drops what does not fit in the room the header's controls leave. The **last** segment always stays — it is where the player is — the **first** is kept while it fits, and the rest come back in from the end: + +```text +Economy > Server > Economy > Balances +Economy > ... > Economy > Balances +Economy > ... > Balances +... > Balances ``` -A live segment sent empty **hides with its separator**, so a two-deep trail and a three-deep one are the same compiled screen. +Everything dropped becomes one `...` in the trail's own color. `{ back: 'cancel' }` says the header wears a modal's labeled dismiss, which leaves the trail less room than the icon back. -## Why each segment is its own label +## Baked segments -One label cannot hold two localization keys, so every segment is a `` of its own. That keeps a key a key all the way to the client, where it resolves in that player's language. +`segments` is the build-time trail. The build composes it once for every language the pack ships: each segment resolved in that language, then collapsed from the middle to the width the row was laid out at, by the same rule `trailText` applies to a live trail. One label draws it, through a key the build writes into every language, so the player reads their own. -The coloring follows from the same rule: a literal takes the trail color as a `§` code, while a key or a live segment is colored through the label instead, because a `§` code in front of a key stops it resolving. +Every segment is already resolved, so the trail's colors ride along as `§` codes. ## Why it hugs -The row is a [``](/docs/ui/components/layout/Panel#stack) of hugging labels. A compiled screen solves a box for each segment as wide as the longest string it may ever hold, so a shorter one would leave the rest of that box as air and the trail would drift off-center. +The row is a [``](/docs/ui/components/Panel#stack) of hugging labels. A compiled screen solves a box as wide as the longest string it may ever hold, so a shorter one would leave the rest of that box as air and the trail would drift off-center. -Each label instead draws at the width of its own glyphs, the engine packs them, an empty segment takes no room at all, and the stack hangs from the middle — so the trail stays centered on what it actually says. +The label instead draws at the width of its own glyphs, the engine packs the row, and the stack hangs from the middle — so the trail stays centered on what it actually says. ## Notes -[`Header`](./Header.md) builds one from its `title` and `breadcrumbs`, or takes a whole `segments` array through to here. Use `Trail` directly for a trail somewhere other than a header bar. +[`Header`](./Header.md) builds a baked trail from its `title` and `breadcrumbs`, or takes a composed one through its `trail` prop. Use `Trail` directly for a trail somewhere other than a header bar. diff --git a/docs/ore-styled/fieldLabel.md b/docs/ore-styled/fieldLabel.md new file mode 100644 index 0000000..58d8d7d --- /dev/null +++ b/docs/ore-styled/fieldLabel.md @@ -0,0 +1,58 @@ +--- +description: "A form field's caption, colored by enabled state, for a control of your own." +--- +# fieldLabel + +A form field's caption, colored by enabled state. + +## Import + +```tsx +import { fieldLabel } from '@bedrock-core/ore-styled'; +``` + +## Signature + +```ts +function fieldLabel(label: string, enabled: boolean): JSX.Element +``` + +## Parameters + +| Parameter | Type | Default | Description | +| --- | --- | --- | --- | +| `label` | `string` | — | The caption text | +| `enabled` | `boolean` | — | Whether the control it labels accepts input | + +## Returns + +`JSX.Element` — a `Text` in the theme's field-label style, colored for the enabled state. + +## Usage + +```tsx +fieldLabel('Volume', true); +``` + +The runtime's own fields — `Toggle`, `Slider`, `Dropdown`, `Input` — are deliberately label-free. Every themed field in this package composes its caption with `fieldLabel` when given a `label` prop; reach for it directly only when styling a control of your own. + +## Examples + +### A custom labeled field + +```tsx +function RatingField({ label, enabled, stars }: { label: string; enabled: boolean; stars: number }): JSX.Element { + return ( + + {fieldLabel(label, enabled)} + + + ); +} +``` + +## Notes + +A literal `label` carries the theme's enabled or disabled color as a `§` prefix. A string the active [translation resolver](/docs/ui/hooks/useTranslationResolver) recognizes as a `.lang` key passes through untouched instead — a `§` prefix in front of a key would stop it resolving, the same rule [`MenuRow`](./MenuRow.md) follows for its own text. Bake the color codes into the translation itself when a localized caption needs them. + +Reads `theme.components.form.labelStyle` for its font, scale, color and boldness — see [theme](./theme.md). diff --git a/docs/ore-styled/index.md b/docs/ore-styled/index.md index 5f44dc5..42bb421 100644 --- a/docs/ore-styled/index.md +++ b/docs/ore-styled/index.md @@ -8,8 +8,8 @@ description: "@bedrock-core/ore-styled is a themed component layer over the @bed `@bedrock-core/ore-styled` is a themed component layer over the [`@bedrock-core/ui`](/docs/ui/components) primitives. -:::caution Pre-1.0 -`@bedrock-core/ore-styled` is under active development. Breaking changes can still land until `1.0.0` — pin exact versions and read the release notes before upgrading. +:::caution Beta +`@bedrock-core/ore-styled` is in beta: the API can change between releases. Pin exact versions and read the changelog before upgrading. ::: ## What is @bedrock-core/ore-styled? @@ -27,23 +27,19 @@ No extra resource pack: the theme's textures live in the same [render pack](/doc ## Import ```tsx -import { Button, Card, Checkbox, Divider, Dropdown, Header, Input, MenuRow, Radio, Slider, Toggle, ToggleButtonGroup, Trail } from '@bedrock-core/ore-styled'; +import { Button, Card, Checkbox, Divider, Dropdown, Header, Input, MenuRow, Radio, Slider, Tabs, Toggle, ToggleButtons, Trail } from '@bedrock-core/ore-styled'; ``` -## One component per host - -A field here is written once and serves every screen it can be drawn on. [`Checkbox`](./Checkbox.md), [`Toggle`](./Toggle.md), [`Radio`](./Radio.md) and [`ToggleButtonGroup`](./ToggleButton.md) ask [`useMechanism`](/docs/ui/hooks/useMechanism) what they become: the engine's own field inside a [`
    `](/docs/ui/components/roots/Form), a press on a screen of buttons or a container screen. A screen that can draw neither refuses them at build, in that host's own words. - -So there is no themed modal variant of each field, and no themed modal root: a submit is ` - - - ); -} -``` - -The build runs the component once to decide the **shape**; the runtime runs it again per viewer to decide the **values**, and the two walks line up position for position because a compiled screen's shape is fixed. Nothing about a screen is declared twice. - -A container screen is the same file with `` at its root and an entity to open from: - -```tsx title="packs/BP/scripts/screens/crafting_table.screen.tsx" -/** @jsxImportSource @bedrock-core/ui */ -import { Container, Panel, Slot, Text, useState, type JSX } from '@bedrock-core/ui'; - -export default function CraftingTable(): JSX.Element { - const [planks, setPlanks] = useState(0); - - return ( - - {`planks ${planks}`} - - setPlanks(value => value + stack.amount)} - onRemove={({ stack }) => setPlanks(value => value - stack.amount)} - /> - - - ); -} -``` - -### Names and keys - -A screen's **name** is its file name without the suffix: `counter.screen.tsx` is `counter`. With the addon's namespace it becomes the JSON UI namespace `_counter`, the output file, and the key `:counter` that `` and `navigate()` take. The name has to be unique across the addon whatever directory the screen sits in. - -### Live values are reserved, not discovered - -A compiled screen is baked, so a string that changes has to say how much room to reserve for it: - -```tsx -{`count ${count}`} -``` - -The build renders the component with each state slot perturbed and fails on anything that moved without a reservation, naming the strings it saw and the `maxLength` each needs. The same probe fails a screen whose **shape** moved — a cell added, dropped or reordered — because the cells are numbered once, at build time. - -### Conditionals become carried visibility - -`{cond && }` has already collapsed to `false` by the time any renderer sees it, and nothing can tell which element went missing. So the build rewrites the source text of every `.screen.tsx` before executing it, and ships the same rewrite to the runtime: - -| Written | Compiled as | -| --- | --- | -| `{cond && }` | `` | -| `{cond ? : }` | `` | -| `{cond ? : null}` | `` | - -An element that already carries `visible` keeps it, joined with `&&`. Only branches that are single elements are rewritten; a string, fragment or call in a branch is left alone — wrap it in an element to make it compilable. A form carries visibility on an entry; a chest screen bakes it, so a chest screen whose `visible` moves is a build error. - -### Static screens - -A screen is **static** when every string it shows is baked and every press is a `` or the way out. Nothing about it can differ between one present and the next, so the build already knows everything showing it takes — the title, the value each entry carries, the key each press leads to — and the addon ships that table instead of the component that would recompute it. - -`` is the assertion, not the mechanism: a qualifying screen is detected either way, and declaring it makes the build fail the moment the screen stops qualifying. - -```tsx title="packs/BP/scripts/screens/menu.screen.tsx" -/** @jsxImportSource @bedrock-core/ui */ -import { Link, Panel, Screen, Text, type JSX } from '@bedrock-core/ui'; - -export default function Menu(): JSX.Element { - return ( - - - {'Menu'} - {'Shop'} - {'Balance'} - - - ); -} -``` - -A key with no `:` in front of it is one of this bundle's own, named as its file is; a key that names another addon resolves through the reference that addon published. - -A modal never qualifies — its fields are built per present — and neither does anything with a live value or a handler of its own. - -### The one rule - -:::caution A screen module, and everything it imports, must not touch the world at import time -The filter evaluates the module once, on the build machine, with `@minecraft/server` and `@minecraft/server-ui` replaced by stubs that answer every name the packages declare and do nothing. Hooks are fine: the compiler renders the component with its initial state. What breaks is module-scope code that reaches for the game — `world.afterEvents.*.subscribe(...)`, `system.run(...)`, a dynamic property read next to an `import`. Keep that in the module that opens the screen; a screen's handlers and effects only ever run in game. -::: - -### Library screens - -A screen can also come from a module whose default export is a record of components, named by its keys. The `screens` setting lists such modules: - -```jsonc title="config.json" -{ "filter": "ui-compiler", "settings": { "screens": ["@bedrock-core/config/compiled"] } } -``` - -An addon that calls `core.register()` gets [`@bedrock-core/config`](/docs/config)'s screens without asking: declaring is what asks for them. The filter reads the register call in `BP/scripts/main.ts` or `BP/scripts/index.ts`, and compiles a config screen per section of the declared schema plus the addon's page in the shared addon list, both shaped for what the declaration says. An addon that names its own `page` keeps that one. - -## What it generates - -Everything lands in Regolith's temp workspace except the one declaration file, which is written back into the project for the editor's sake. The screen module is the only file you own. - -| Output | Where | Commit it? | -| --- | --- | --- | -| `RP/ui/core-ui/screens//.json` | workspace | ❌ | -| `RP/ui/core-ui/screens//faces.json` | workspace | ❌ | -| `RP/ui/core-ui/screens/_forms.json` | workspace | ❌ | -| `RP/ui/server_form.json` | workspace | ❌ | -| `RP/ui/core-ui/screens/_router.json` | workspace | ❌ | -| `RP/ui/chest_screen.json` | workspace | ❌ | -| `RP/ui/_ui_defs.json` | workspace, edited or created | ❌ | -| `RP/texts/.lang` | workspace, appended | ❌ | -| `BP/entities/.json` | workspace, edited | ❌ | -| `data/ui/ui.generated.ts` | workspace | ❌ | -| `data/ui/declared.screens.ts` | workspace | ❌ | -| `/ui/screens.generated.d.ts` | the project | ✅ | -| `RP/ui/core-ui/screens//.preview.json` | workspace, `gallery` only | ❌ | -| `RP/ui/core-ui/screens//gallery.json` | workspace, `gallery` only | ❌ | -| `RP/ui/core-ui/screens//core_build.json` and `RP/ui/hud_screen.json` | workspace, `stamp` only | ❌ | - -The screens sit under a folder named for the addon because a resource pack file is replaced, not merged, by a higher pack's file at the same path: two addons that both compiled a `guide_home` would otherwise shadow each other's namespace. Every UI file is registered in `_ui_defs.json`, or the game never loads it. - -### faces.json - -A **face** is one look with its static props — a button's four textures, a label's font and scale, a cell frame — carrying no bindings at all. Faces are deduplicated by a signature over the props that reach JSON UI, so a look is one definition however many screens draw it, and they live in the addon's own file rather than in the render pack: a styled layer other than [`ore-styled`](/docs/ore-styled) ships its own with nothing added to the pack. - -### The generated module - -`data/ui/ui.generated.ts` is reached from scripts as `@bedrock-core/generated/ui`, the way the [i18n](./i18n.md) and [guides](./guides.md) bundles are. Importing it is what associates a component with the layout compiled from it — the build knows a screen by its file, the runtime by the component it is handed — so the filter adds the import to the workspace copy of the script entry. Without it `render()` refuses every screen. - -| Export | Kind | Description | -| --- | --- | --- | -| `SCREEN_KEYS` | `readonly string[]` | Every screen this addon compiled, by the key it is navigated with | -| `ScreenKey` | type | One of `SCREEN_KEYS` | -| `UI_NAMESPACE` | `string` | The namespace the build wrote into every key and title | -| `UI_REFERENCE` | table | The static screens as rows: key, title, entry values, press targets | -| `uiReference()` | function | The same table as the `AddonReference` an addon publishes | -| `openGallery(player, options?)` | function | Opens the gallery; warns and returns `false` in a build without one | - -The module also augments `ScreenKeys`, so `navigate()` and `` autocomplete this addon's keys while still accepting another addon's — resolving one of those is the point. `/ui/screens.generated.d.ts` is the same declaration written back into the project, because the generated module only ever exists inside a Regolith run and the editor never sees one. - -Publishing the reference once at startup is what lets a realm running none of this addon's script show its static screens: - -```ts title="packs/BP/scripts/main.ts" -import { core } from '@bedrock-core/server'; -import { uiReference } from '@bedrock-core/generated/ui'; - -core.register({ manifest, screens: uiReference() }); -``` - -## How a screen reaches the screen it is drawn on - -Both hosts are reached the same way: one gated definition per screen under a root named for the addon, and one insert putting that root where the screen can see it. A gate compares the whole of what identifies the screen, so two screens can never both match. - -- **Form screens** gate on the form's title, which carries the protocol header and the screen's namespaced name. The library's own container is already gated on that header, so a compiled form needs no vanilla edit: the addon's root is inserted into the mount. The pack that *defines* the mount lists its root in the definition directly; every other pack inserts through `RP/ui/server_form.json`. -- **Container screens** gate on a layout key. A marker item in the container's first two slots carries a protocol key — is this chest a compiled screen at all? — and the layout key as two stack sizes, and the router shows the layout whose key matches. A vanilla chest has no marker, fails the first check and renders untouched. - -A screen's layout key is a hash of `_` folded into 1..3969. It depends on nothing but the screen's own name, so a rebuild never moves a key and an entity placed in a world keeps opening the screen it was stamped with; two addons built apart never claim the same key for their first screens. Two screens of one addon hashing alike is a build failure naming both. - -Every edit to a vanilla file is one `modifications` entry defining nothing, at vanilla's own path. That is the one kind of edit the engine stacks across packs in whatever order they sit — a definition in a vanilla file would replace vanilla's and every other pack's instead of joining them. The insert target declares its own `controls`, because an insert on a definition that merely inherits the array creates one that shadows it. - -## Entities - -A container screen names the entity it opens from. The filter finds that entity's definition under `BP/entities` by its `identifier` — a screen naming an entity that is not there fails the build — and stamps the workspace copy: - -```jsonc -"description": { - "properties": { - // The runtime reads this when a player opens the entity, to pick the screen. - "core:ui_layout": { "type": "int", "range": [0, 3969], "default": 1094 } - } -}, -"components": { - "minecraft:inventory": { - "container_type": "container", // the only type that routes to the chest screen - "inventory_size": 75, // drawn slots + live channels; a hand-written value is overwritten - "private": false // `true` stops the player opening it at all - } -} -``` - -Nobody keeps `inventory_size` in step with a layout by hand — the failure mode of that is a screen that silently draws cells the container does not have. Everything else on the entity is yours: its geometry, its behavior, whether it can be pushed or hurt. - -One entity opens one screen: two screens naming the same entity is a build error. - -## The character table - -A container slot publishes no text, so a live string crosses one character per slot: each cell reads its slot's stack size and localizes a key built from it. The table that turns those codes back into glyphs is appended to every `RP/texts/.lang`, in a marked block, and only when a container screen actually has live text. It comes from the runtime the project ships rather than from the filter, because it is the contract between the compiler and the runtime — they encode against the same list or nothing renders. - -## The gallery - -With `gallery: true` the build writes each screen twice: the served screen, and the same screen as **faces alone** under its own namespace, gated on its own title. A `gallery` screen lists every preview, and a press opens one. That is where a screen is looked at before any host attaches a channel to it — a preview has no entity, no entry and no channel, and shows reference strings, reference visibility and fields as static twins. - -```ts -import type { Player } from '@minecraft/server'; -import { openGallery } from '@bedrock-core/generated/ui'; - -export const showGallery = (player: Player): void => { - openGallery(player); -}; -``` - -For a development profile only, the way a component storybook is. A build without it exports an `openGallery` that warns and shows nothing. - ## Settings | Setting | Type | Default | Description | | --- | --- | --- | --- | | `namespace` | `string` | declared | The addon's namespace, lowercase `a-z`, `0-9` and `_`; it prefixes every screen's JSON UI namespace and names the router file and the output folder. Left unset, it is the `creator` and `pack` of the manifest the addon declared | | `stamp` | `boolean` | `false` | Draw a build stamp at the HUD's top left — a short hash over everything under `RP/ui` plus the build clock — so what a running client is rendering is never in question | -| `gallery` | `boolean` | `false` | Write every screen's preview and the gallery screen that opens them, and export a working `openGallery` | | `screens` | `string[]` | `[]` | Modules whose default export is a record of screens to compile besides the addon's own, each export key naming one | +| `pretty` | `false \| { indent?, size? }` | `false` | How generated JSON is laid out. Absent or `false` writes it minified. An object lays it out: `indent` is `"tab"` or `"space"`, `size` the characters per level (2 for spaces, 1 for tabs when omitted). Laid out, each file is headed with the comment saying it is generated; minified, it is headerless too | -Every path is what the game needs, so none of them is a setting: screens under `BP/scripts`, entities under `BP/entities`, output under `RP/ui/core-ui/screens`, texts under `RP/texts`, and the hooks at vanilla's own paths. - -## Checks - -No screen to compile and no `screens` setting is an info-level no-op. Everything else stops the build with the compiler's own message, relayed unchanged, because those messages already name the fix. - -| Check | What fails | -| --- | --- | -| Root | A tree that starts with something other than ``, `` or ``; more than one element at a form's root; a `` with no `entity` | -| Shape | A screen that adds, drops or reorders a cell when its state changes | -| Live text | A `` whose string changes with no `maxLength`; the message names each string it saw and the length it needs | -| Carried visibility | A `visible` that moves on a container screen, which bakes it | -| Static | `` on a screen that carries a live value or runs a handler of its own, naming which | -| Canvas | Content laid out past 320 × 210, with the size it measured | -| Mechanism | A component the screen's host has no mechanism for — a slider or a dropdown outside a modal, a slot outside a container screen | -| Unsupported | A control with no compiled form at all, listing what is supported | -| Face rules | A face carrying a binding that reads a host, an image without `keep_ratio: false`, a label that does not say whether it localizes, two siblings of one name, a reference or `source_control_name` that resolves to nothing | -| Placement | A host that moved a control while standing its mechanism in, with the face's rect and the host's | -| Shared faces | A control that changes at runtime, or one needing a definition of its own, baked inside a button's face | -| Names | Two screens with the same name; a name or namespace outside letters, digits, `_` and `-` | -| Face collision | Two screens of one addon sharing a face name with different contents | -| Entity | An `entity` with no definition under `BP/entities`; two screens naming the same entity | -| Namespace | No `namespace` setting and no `manifest: { creator, pack }` in the register call | -| Import time | A module that reaches for the game while being evaluated | - -An entry that throws on the way to its `core.register()` call is a warning, not a failure: the addon gets none of the screens that follow from declaring, and the reason is printed rather than leaving a pack that builds clean with no config screen in it. - -## Notes +Every path is what the game needs, so none of them is a setting: screens under `BP/scripts`, entities under `BP/entities`, blocks under `BP/blocks`, output under `RP/ui/core-ui/screens`, texts under `RP/texts`, and the hooks at vanilla's own paths. -The pipeline runs inside the bundle the filter builds, so `@bedrock-core/ui-runtime` and `@bedrock-core/ui-compiler` resolve from the **project's** `node_modules`. A screen is always compiled against the library version the addon actually ships, and the filter cannot drift from it. Every value the emitted JSON UI shares with the runtime — the character table, the layout property, the highest layout key — is read off that bundle for the same reason. +No screen to compile and no `screens` setting is an info-level no-op. Everything else stops the build with the compiler's own message; [Build checks](/docs/ui/compiler/checks) lists them. -The compiler itself and its layers are in [Faces and hosts](/docs/ui/compiler/passes), its programmatic entry points in [`@bedrock-core/ui-compiler`](/docs/ui/compiler/api), and what serves a compiled screen in game is [`@bedrock-core/ui`](/docs/ui). +See [Compiler](/docs/ui/compiler) for writing screens, what the build writes into the pack, and how the compiler works. diff --git a/docs/i18n/api.md b/docs/i18n/api.md new file mode 100644 index 0000000..3c62294 --- /dev/null +++ b/docs/i18n/api.md @@ -0,0 +1,307 @@ +--- +sidebar_position: 4 +description: "The three verbs, locale resolution, createI18n and every runtime export of @bedrock-core/i18n." +--- + +# API reference + +## The three verbs + +The core idea: prefer the client, fall back to the server. The client resolves `.lang` keys per player for free; the server only resolves when your code needs the string *now*. + +| Verb | Returns | Resolved by | Use for | +| --- | --- | --- | --- | +| `key()` | namespaced key string | client | `Text` children, registry display fields — no arguments | +| `raw()` | `RawMessage` (`translate` + `with`) | client | interpolated text the client should localize | +| `t()` | plain string | server | layout math, chat, composing strings | + +`key()` and `raw()` never spell the namespace — they prepend it at runtime from the bundle's metadata, so renaming your addon's namespace never touches a call site. + +### Every verb, and what it produces + +Given `shop.title = 'Shop'` and `shop.bought = 'You bought {{item}} for {{price}} emeralds.'` in an addon whose namespace is `drav0011_shop`: + +| Call | Produces | The player sees | Reach for it when | +| --- | --- | --- | --- | +| `key($ => $.shop.title)` | `'drav0011_shop.shop.title'` | `Shop` | passing text somewhere the **client** resolves it: a `Text` child, a `MenuRow` label, a registry display field. No arguments possible. | +| `raw($ => $.shop.bought, { item: 'Apple', price: 5 })` | `{ translate: 'drav0011_shop.shop.bought', with: ['Apple', '5'] }` | `You bought Apple for 5 emeralds.` | the same, but with **arguments**. Still client-resolved, so still per-player and uncapped. | +| `raw($ => $.shop.title)` | `{ translate: 'drav0011_shop.shop.title' }` | `Shop` | argless `raw()` collapses to the bare key — identical to `key()`, just typed as a `RawMessage`. | +| `raw($ => $.shop.bought, { item: raw($ => $.vanilla.item.apple.name), price: 5 })` | `{ translate: '…shop.bought', with: { rawtext: [{ translate: 'item.apple.name' }, { text: '5' }] } }` | `You bought Apple for 5 emeralds.` | an argument that is **itself** a translation — the client resolves both, so the item name follows the player's language too. | +| `t($ => $.shop.bought, { item: 'Apple', price: 5 })` | `'You bought Apple for 5 emeralds.'` | *(you decide)* | you need the **string right now**, server-side: `sendMessage`, string concatenation, comparisons, or anything that takes no `RawMessage`. | +| `display(key($ => $.shop.title))` | `'Shop'` | *(you decide)* | you hold a `DisplayText` of unknown shape — a literal, a key, or a `RawMessage` — and need a plain string. Accepts all three. | +| `resolve('drav0011_shop.shop.title')` | `'Shop'` \| `undefined` | *(you decide)* | you have a **real `.lang` key** already, not a path — measurement, or bridging another addon's key. | + +The split that matters: `key()` and `raw()` **defer** to the client, so each player sees their own language and nothing is capped; `t()`, `display()` and `resolve()` **resolve now**, on the server, and give you one string for whichever locale you bound to. + +:::tip A key nothing resolves comes back literally +`display()` and `resolve()` mirror Bedrock: an unknown key returns as itself rather than throwing or emptying. If you see a raw `drav0011_shop.shop.title` in game, the key exists at the call site but not in the built `.lang`. +::: + +### Two call shapes, one type + +Every verb takes a **selector** or the equivalent **dot string**. Both autocomplete, both are checked identically: + +```ts +t($ => $.shop.bought, { item: 'Apple', price: 5 }); +t('shop.bought', { item: 'Apple', price: 5 }); +``` + +An unknown path is a compile error in both forms. Prefer the selector form on projects with the vanilla branch enabled — the dot-string union over ~10k vanilla keys is only instantiated when you actually use a string. + +At a call site the tree is rooted at your own keys, with two branches grafted in by the filter: + +```ts +t($ => $.shop.bought, { item, price }); // yours — packs/data/i18n +t($ => $.core.addons.title); // a library's strings +t($ => $.vanilla.item.apple.name); // vanilla Minecraft +``` + +## Interpolation + +`{{var}}` placeholders in the authored template become **required, closed** properties on the argument object: + +```ts +// en_US.ts -> bought: 'You bought {{item}} for {{price}} emeralds.' + +t($ => $.shop.bought, { item: 'Apple', price: 5 }); // ✅ + +t($ => $.shop.bought); // ❌ arguments are required +t($ => $.shop.bought, { item: 'Apple' }); // ❌ missing variable: price +t($ => $.shop.bought, { item: 'Apple', price: 5, cost: 1 }); // ❌ unknown variable: cost +t($ => $.shop.title, { item: 'x' }); // ❌ template has no variables +``` + +Values are `string | number`. + +`raw()` widens what an argument accepts: any `RawMessage` part — a nested `raw()`, a `score`, a `selector` — is allowed, and the moment one appears the whole `with` array travels as rawtext parameters so the **client** resolves every part in its own language: + +```ts +raw($ => $.shop.bought, { item: raw($ => $.vanilla.item.apple.name), price: 5 }); +// { +// translate: 'drav0011_shop.shop.bought', +// with: { rawtext: [{ translate: 'item.apple.name' }, { text: '5' }] }, +// } +``` + +`raw()` orders its `with` array by the argument order the filter recorded at build time. See [Argument order](./authoring.md#argument-order) for how that order is chosen. + +### Vanilla keys take positional arguments + +Vanilla strings are not literal-typed (they come from Mojang's `.lang`, not your source), so their leaves accept an optional loose record **or** a positional array matching the client's `%1$s` slots: + +```ts +raw($ => $.vanilla.multiplayer.player.joined, [player.name]); +// { translate: 'multiplayer.player.joined', with: ['Steve'] } +``` + +## Plurals + +Author `_one` / `_other` variants (see [Plurals](./authoring.md#plurals) for authoring them). They **collapse into a single leaf** that takes `count`: + +```ts +// en_US.ts +// stock_one: '{{count}} left in stock', +// stock_other: '{{count}} left in stock', + +t($ => $.shop.stock, { count: 1 }); // '1 left in stock' +t($ => $.shop.stock, { count: 3 }); // '3 left in stock' + +t($ => $.shop.stock, {}); // ❌ count is required on a plural leaf +t($ => $.shop.stock_one, { count: 1 }); // ❌ suffixed variants are hidden +``` + +Bedrock `.lang` has no plural mechanism, so the suffix is **always** chosen server-side — even for `key()` and `raw()`, where the already-suffixed key is what travels to the client: + +```ts +key($ => $.shop.stock, { count: 1 }); // 'drav0011_shop.shop.stock_one' +key($ => $.shop.stock, { count: 9 }); // 'drav0011_shop.shop.stock_other' +``` + +:::caution Pluralized leaves need a bound verb set +Which suffix wins depends on the *target language's* plural rules, so a plural call only makes sense against a resolved locale. Use `i18n.forPlayer(player)` (or [`useTranslation`](/docs/ui/hooks/useTranslation) in a component) rather than the unbound top-level verbs, which are pinned to the default locale. +::: + +Categories come from a built-in CLDR rule table (`Intl.PluralRules` is not available in Bedrock's script engine) covering the locales the Bedrock client ships: + +| Language | Categories | +| --- | --- | +| `ja`, `ko`, `zh`, `id` | `other` only | +| `fr` | `one` (i = 0 or 1) / `other` | +| `cs`, `sk` | `one` / `few` (2–4) / `other` | +| `pl` | `one` / `few` / `many` | +| `ru`, `uk` | `one` / `few` / `many` | +| everything else (`en`, `de`, `es`, `it`, `pt`, `nl`, `sv`, `tr`, …) | `one` (n = 1) / `other` | + +Lookup falls back `_` → `_other`, so a category a locale never authored never strands a string. + +## DisplayText + +```ts +type DisplayText = string | RawMessage; +``` + +`DisplayText` is **the** player-facing text union — every channel that shows a player something shares it: [`Text`](/docs/ui/components/Text) children, [`Header`](/docs/ore-styled/Header) and [`MenuRow`](/docs/ore-styled/MenuRow) labels, registry display fields, `display()` input. + +Which shape a string is — a literal or a `.lang` key — is decided **lazily by the active resolver**, never declared: + +```tsx +{'Hello'} {/* nothing resolves it -> literal */} +{key($ => $.shop.title)} {/* the resolver knows it -> localized */} +{raw($ => $.shop.bought, { item, price })} {/* always localized */} +``` + +A key nothing resolves paints literally — which is exactly what Bedrock does with an unmatched `.lang` key, so a foreign addon's key still resolves on the *client* even when your server has never seen it. + +## Locale resolution + +`t()` needs a locale. The chain, first hit wins: + +1. **Per-player override** — `setLocale(player, 'es_ES')`, persisted in a dynamic property so it survives rejoin. `clearLocale(player)` removes it. +2. **The player's client language** — `player.clientSystemInfo.locale`. +3. **A sibling region of that language** — a player on unauthored `es_MX` gets the Spanish written for Spain rather than English. +4. The addon's `defaultLocale`, then any locale the bundle carries. + +```ts +t($ => $.shop.title); // defaultLocale — no player in sight + +const { t: tp } = i18n.forPlayer(player); // bound through the chain above +const { t: es } = i18n.forLocale('es_ES'); // pinned, e.g. for logs or broadcasts + +i18n.setLocale(player, 'es_ES'); // persisted override +i18n.clearLocale(player); // client language takes over again +``` + +`forPlayer` and `forLocale` return the **full bound verb set** (`locale`, `t`, `key`, `raw`, `resolve`, `display`) — binding matters for plurals even on the client-resolved verbs, as noted above. Bound sets are cached per locale, so calling `forPlayer` on every render is cheap. + +The override is stored under the dynamic property `bedrock_core:i18n_locale`, exported as `LOCALE_PROPERTY`. + +## resolve() and display() + +Two lookups sit alongside the verbs on every bound set. + +### `resolve(realKey)` + +```ts +type TranslationResolver = (key: string) => string | undefined; +``` + +Resolves a **real `.lang` key** — `key()` output, a registry display field, a vanilla key, a `.lang` passthrough entry — to its display string, or `undefined` when this bundle does not carry it. + +This is the measurement contract the UI runtime uses. You rarely call it directly; you pass it around ([`TranslationContext`](/docs/ui/api/TranslationContext) carries exactly this type). + +### `display(value)` + +```ts +display(value: DisplayText): string +``` + +Any `DisplayText` to a plain string, server-side, in this locale — for the places a key must **become** text: breadcrumb trails, native modal headings, chat prefixes. Literal strings pass through, key strings resolve, `RawMessage`s resolve and fill their `with` parameters (nested translates resolve one level; `score`/`selector` parts have no server value and fill as `''`). A key nothing resolves comes back literally. + +```ts +const { display } = i18n.forPlayer(player); + +display('Plain text'); // 'Plain text' +display(key($ => $.shop.title)); // 'Shop' +display(raw($ => $.shop.bought, { item: 'Apple', price: 5 })); +// 'You bought Apple for 5 emeralds.' +``` + +The free function `resolveDisplay(resolve, value)` is the same logic over any resolver you already hold — that is what `Header` and `MenuRow` use. + +## Cross-addon sharing + +Publish the bundle itself through the server runtime's registration: + +```ts +core.register({ manifest }); +core.translations.provide(bundle); +``` + +The runtime replicates the bundle — objects, templates and recorded argument order intact — and serves two lazy views: `core.translations.of(addonId)` gives verbs over a peer's strings, and `core.translations.forPlayer(player)` gives one resolver chaining every published bundle, later registrations winning collisions. Registry display fields (`packName`, `description`, `creatorName`) are translation keys so that this works. + +## Without the filter + +`createResourceBundle` builds the same bundle shape from nested resource modules at runtime — full typed verbs, no build step: + +```ts +import { createI18n, createResourceBundle } from '@bedrock-core/i18n'; +import en_US from './i18n/en_US'; +import es_ES from './i18n/es_ES'; + +const bundle = createResourceBundle('core', { en_US, es_ES }); + +export const i18n = createI18n(bundle, { asDefault: false }); +``` + +```ts +function createResourceBundle( + namespace: string, + locales: Readonly> & { readonly en_US: T }, + options?: ResourceBundleOptions, +): I18nBundle & { readonly resources?: T } +``` + +| Option | Type | Default | Description | +| --- | --- | --- | --- | +| `defaultLocale` | `string` | `'en_US'` | The locale defining the type and the recorded argument order | +| `extra` | `Record>` | — | `.lang`-passthrough entries (locale → REAL key → string) to carry for measurement | + +Two audiences: + +- **Libraries.** Their resources ship inside the package, and the consuming addon's filter folds them into its `.lang`; the library still wants typed verbs over its own strings. `@bedrock-core/config` does exactly this. +- **Addons not running the filter.** Everything works minus what only a build can do: `.lang` emission, the vanilla branch, cross-locale parity checks. + +:::caution `asDefault: false` for libraries +A library creating its own instance must pass `{ asDefault: false }` so it never shadows the host addon's bundle as the default translation source. An addon's own `createI18n` call *is* the registration and should keep the default (`true`). +::: + +## `createI18n(bundle, options?)` + +```ts +function createI18n(bundle: B, options?: CreateI18nOptions): I18n> +``` + +| Option | Type | Default | Description | +| --- | --- | --- | --- | +| `asDefault` | `boolean` | `true` | Register this instance as the addon's default translation source | + +Returns an `I18n`: the default-locale bound set plus `bundle`, `forLocale`, `forPlayer`, `setLocale`, `clearLocale`. + +### `BoundI18n` + +What `forPlayer` / `forLocale` return, and what `I18n` extends. + +| Member | Type | Description | +| --- | --- | --- | +| `locale` | `string` | The resolved locale this set is bound to | +| `t` | `TranslateFn` | Server-resolved, interpolated string | +| `key` | `TranslateFn` | The real `.lang` key (plural suffix applied) | +| `raw` | `TranslateFn` | `translate` + `with` for the client | +| `resolve` | `TranslationResolver` | Lazy real-key lookup over this bundle | +| `display` | `(value: DisplayText) => string` | Any `DisplayText` to a plain string | + +### Other exports + +| Export | Kind | Description | +| --- | --- | --- | +| `DisplayText` | type | `string \| RawMessage` — the shared text union | +| `resolveDisplay(resolve, value)` | function | The `display()` primitive over any resolver | +| `overlay(bound, published, bundle)` | function | A library's bound verbs with the world's published resolver laid over them: `t()` prefers a published value, `resolve()` and `display()` become the world's | +| `createResourceBundle(ns, locales, options?)` | function | Build a bundle from objects at runtime | +| `currentI18n()` | function | The addon's registered default instance, or `undefined` | +| `realKeyFor(bundle, path)` | function | Flat path → real `.lang` key | +| `pickLocale(available, candidates, default)` | function | The locale-chain policy, standalone | +| `pluralCategory(locale, count)` | function | The CLDR category for a locale + count | +| `interpolate(template, args?)` | function | Fill `{{var}}` (record) or `%N$s` (array) | +| `templateVars(template)` | function | `{{var}}` names, first-appearance order | +| `toPositional(template, order)` | function | `{{var}}` → `%N$s` against a recorded order | +| `LOCALE_PROPERTY` | const | `'bedrock_core:i18n_locale'` | +| `I18nBundle`, `LangEntries` | types | The bundle shape the filter generates | +| `TranslationResolver`, `TranslateFn`, `BoundI18n`, `I18n`, `CreateI18nOptions` | types | Engine types | +| `Leaf`, `AnyLeaf`, `ArgsOf`, `Interp`, `PathsOf`, `ResolvePath`, `SelectorTree`, `TemplateVars` | types | The compile-time machinery | + +## Limits + +- **Compile-time guarantees end where dynamic strings begin.** `t()` on a runtime-assembled key the type system never saw returns the key itself, mirroring how Bedrock renders an unknown `.lang` key literally. +- **`$t(other.key)` nesting is a build-time feature.** Bedrock `.lang` has no nesting, so the filter flattens references before emitting; nothing resolves them at runtime. +- **Vanilla `t()` values are partial by design.** Only the vanilla keys your compiled scripts reference as literals or `$.vanilla.` chains ride in the bundle — see [Vanilla strings](./libraries.md#vanilla-strings). diff --git a/docs/i18n/authoring.md b/docs/i18n/authoring.md new file mode 100644 index 0000000..344387c --- /dev/null +++ b/docs/i18n/authoring.md @@ -0,0 +1,135 @@ +--- +sidebar_position: 2 +description: "Locale files, namespacing, argument order, $t() nesting, plurals and the meta branch: authoring the resources the i18n filter compiles." +--- + +# Authoring resources + +Nested TypeScript objects under `packs/data/i18n/` are the source of truth for an addon's text. The [i18n Regolith filter](/docs/filters/i18n) reads them and generates the `.lang` files, the runtime bundle and the types. + +## Locale files + +One module per locale, each default-exporting a nested object: + +```ts +// packs/data/i18n/en_US.ts +export default { + shop: { + title: 'Shop', + bought: 'You bought {{item}} for {{price}} emeralds.', + stock_one: '{{count}} left in stock', + stock_other: '{{count}} left in stock', + }, +} as const; +``` + +:::caution `as const` is not optional +It is what lets the compiler infer the key space and the interpolation variables each template requires. Without it every template widens to `string` and you lose typed arguments entirely. +::: + +The default locale (`defaultLocale`, `en_US` unless configured) is the **shape**: every other locale file must carry exactly its key set, checked in both directions — a locale missing a key falls back to the default locale's value, and a key with no default-locale counterpart is dropped. + +Filenames must be `.ts` and must be a locale code the Bedrock client ships — a locale nobody can select is flagged. `.d.ts` and `.generated.json` files in the same folder are ignored. + +Keys are constrained by what has to survive as both a `.lang` key segment and a TypeScript property: + +| Rule | Why | +| --- | --- | +| Segments match `[A-Za-z0-9_]+` | must survive a `key=value` line and a TS property name | +| Values are single-line strings | a `.lang` entry is one line | +| Nesting depth ≤ 6 | past that, type-level path recursion degrades the whole key union to `string` | +| Leaves are strings, branches are objects | arrays and other types are rejected | + +## Namespacing + +Every key lands in the `.lang` files prefixed with the addon's namespace: `shop.bought` becomes `drav0011_shop.shop.bought`. The prefix is what keeps addons from colliding everywhere their text meets — Bedrock merges every installed pack's `.lang` into one world-wide table, and the server runtime merges every addon's published translation tables under the same namespace. + +The namespace is **derived, not configured**. The filter scans `BP/scripts` for the `core.register({ manifest: { creator: '…', pack: '…' } })` call and joins the two string literals: + +```ts +core.register({ manifest: { creator: 'drav0011', pack: 'shop', /* ... */ } }); +// -> namespace 'drav0011_shop' +``` + +Only files containing a `.register(` call are considered, so unrelated `creator:`/`pack:` properties elsewhere do not poison the scan. When the scan finds no call, or finds `creator`/`pack` composed at runtime instead of written as literals, the build fails and names the fix: make them literals, or set the filter's `namespace` setting — required only in that case. + +Call sites never spell the namespace. `key()` and `raw()` prepend it at runtime from the bundle's metadata, so renaming the addon's namespace never touches a call site. + +## Argument order + +`{{var}}` syntax is rewritten to Minecraft's positional form for the `.lang` files: + +```txt +'You bought {{item}} for {{price}}' -> 'You bought %1$s for %2$s' +``` + +The placeholders are numbered by first appearance in the **default locale**. Because every locale's `.lang` uses those same numbers, a translation may put the arguments in any order its sentence needs and each still lands in the right place — reordering the words never reorders the values. The runtime bundle keeps the original `{{var}}` template and substitutes by name, so script-side text (`t()`, `raw()`) is unaffected by argument order either way. + +### Nesting with `$t()` + +`$t(other.key)` references are inlined at build time, recursively — Bedrock `.lang` has no nesting: + +```ts +demo: { + title: 'i18n Demo', + intro: 'Every verb the library has, live: $t(demo.title).', +}, +``` + +Unknown references and cycles are reported and replaced with `''`. + +:::caution Format functions are not supported +`{{price, currency}}` does not work. A format function is JavaScript and cannot travel to the client. Format in code, pass the result as the argument. +::: + +## Tags for `` + +A string drawn with [``](/docs/ui/components/Trans) marks its links and styles with named tags, which the screen maps to components: + +```ts +help: { prices: 'See the shop for today\'s prices.' }, +``` + +The tags pass through this filter untouched. A translation may move them, reorder them and wrap them around other words. The string is composed at build, so it cannot also take `{{variables}}`. + +## Plurals + +Author `_one` / `_other` variants (plus `_zero`, `_two`, `_few`, `_many` where a language needs them). A plural group with no `_other` fails the build — it is the universal fallback category, and a group without it resolves to nothing for most counts. + +CLDR categories differ per language, so a locale may declare a category the default locale never has. Czech needs `_few`; English does not: + +```ts +// packs/data/i18n/en_US.ts // packs/data/i18n/cs_CZ.ts +stock_one: '{{count}} left', stock_one: 'Zbývá {{count}} kus', +stock_other: '{{count}} left', stock_few: 'Zbývají {{count}} kusy', + stock_other: 'Zbývá {{count}} kusů', +``` + +`cs_CZ.stock_few` is **not** flagged as an extra key: it rides into the bundle, checks its variables against the group's `_other`, and picks up its recorded argument order from the locale that defines it. What parity still requires is that the default locale declares the group (`stock_other`). See [Plurals](./api.md#plurals) for how a plural leaf resolves at runtime. + +## Meta branch + +A `meta` branch names the addon for the pack list: + +```ts +export default { + meta: { + name: 'Shop', + description: 'Sells items to players', + }, + shop: { title: 'Shop' }, +} as const; +``` + +`meta.name` and `meta.description` are copied onto the two literal keys Bedrock resolves a manifest header from — `pack.name` and `pack.description` — written into **both** packs' generated `.lang` sections, since each manifest resolves from its own pack's texts: + +```jsonc title="packs/BP/manifest.json and packs/RP/manifest.json" +{ + "header": { + "name": "pack.name", + "description": "pack.description" + } +} +``` + +The resource pack's `.lang` carries everything: the namespaced `.meta.name` / `.meta.description` keys (what `key()` resolves and what rides in the runtime bundle) plus the two `pack.name` / `pack.description` aliases. The behavior pack's `.lang` carries only the two aliases — nothing else, since a manifest looks up nothing but those literal keys. Other `meta.*` keys, such as `meta.creator`, are ordinary namespaced strings with no alias. diff --git a/docs/i18n/index.md b/docs/i18n/index.md index 1c6705d..9c48cd7 100644 --- a/docs/i18n/index.md +++ b/docs/i18n/index.md @@ -2,28 +2,32 @@ slug: / sidebar_position: 1 sidebar_label: Overview -description: "@bedrock-core/i18n is the localization layer for Minecraft Bedrock addons: typed keys, typed interpolation and plurals, resolved on the client in each…" +description: "@bedrock-core/i18n is the localization layer for Minecraft Bedrock addons: typed keys, interpolation and plurals, resolved per player." --- # i18n `@bedrock-core/i18n` is the localization layer for Minecraft Bedrock addons: typed keys, typed interpolation and plurals, resolved on the **client** in each player's own language wherever possible, and on the **server** whenever your code needs the actual string. -It is the runtime half of a two-part system. The build half is the [`i18n` Regolith filter](/docs/filters/i18n), which turns your `packs/data/i18n/.ts` modules into `.lang` files, a runtime bundle and the types this package's API infers from. - -:::tip Zero runtime dependencies -No i18next in your script bundle. The conventions are i18next's (`{{var}}` interpolation, `_one`/`_other` plural suffixes, the selector call shape), so existing knowledge transfers; every locale ships statically in one bundle. +:::caution Beta +`@bedrock-core/i18n` is in beta: the API can change between releases. Pin exact versions and read the changelog before upgrading. ::: +## What is @bedrock-core/i18n? + +It is the runtime half of a two-part system. The build half is the [`i18n` Regolith filter](/docs/filters/i18n), which turns `packs/data/i18n/.ts` modules into `.lang` files, a runtime bundle and the types this package's API infers from. + +The conventions are i18next's — `{{var}}` interpolation, `_one`/`_other` plural suffixes, the selector call shape — so existing knowledge transfers. Nothing from i18next ships in the script bundle: every locale rides statically in one generated bundle. + ## Install -The package is reachable two ways. If you already depend on `@bedrock-core/ui`, use the facade entry — nothing extra to install: +Every addon already depends on `@bedrock-core/server`, which carries it at its own subpath — nothing extra to install: ```tsx -import { createI18n } from '@bedrock-core/ui/i18n'; +import { createI18n } from '@bedrock-core/server/i18n'; ``` -Otherwise (a script-only addon, a library, or a minimal `@bedrock-core/ui-runtime` install) add the package directly: +A library that does not depend on the meta package adds it directly: @@ -31,7 +35,7 @@ Otherwise (a script-only addon, a library, or a minimal `@bedrock-core/ui-runtim import { createI18n } from '@bedrock-core/i18n'; ``` -Both entries export exactly the same surface — `@bedrock-core/ui/i18n` is a one-line re-export of `@bedrock-core/i18n`. The rest of this page writes `@bedrock-core/i18n`; substitute the facade path if you prefer. +Both entries export exactly the same surface — `@bedrock-core/server/i18n` is a one-line re-export of `@bedrock-core/i18n`. The rest of this section writes `@bedrock-core/i18n`; substitute the meta path if you prefer. ## Setup @@ -45,374 +49,23 @@ import { createI18n } from '@bedrock-core/i18n'; export const i18n = createI18n(bundle); ``` -That is the whole setup. Key paths, interpolation variables and plural forms are all inferred from the bundle's type — no module augmentation, no manual type imports. See [the filter page](/docs/filters/i18n#tsconfig) for the `@bedrock-core/generated/i18n` path alias this import needs. - -`createI18n` also **registers itself as the addon's default translation source**, which is what lets `Text` measure localized children with no wiring at all — see [In the UI](#in-the-ui). - -## The three verbs - -The core idea: prefer the client, fall back to the server. The client resolves `.lang` keys per player for free; the server only resolves when your code needs the string *now*. - -| Verb | Returns | Resolved by | Use for | -| --- | --- | --- | --- | -| `key()` | namespaced key string | client | `Text` children, registry display fields — no arguments | -| `raw()` | `RawMessage` (`translate` + `with`) | client | interpolated text the client should localize | -| `t()` | plain string | server | layout math, chat, composing strings | - -`key()` and `raw()` never spell the namespace — they prepend it at runtime from the bundle's metadata, so renaming your addon's namespace never touches a call site. - -### Every verb, and what it produces - -Given `shop.title = 'Shop'` and `shop.bought = 'You bought {{item}} for {{price}} emeralds.'` in an addon whose namespace is `drav0011_shop`: - -| Call | Produces | The player sees | Reach for it when | -| --- | --- | --- | --- | -| `key($ => $.shop.title)` | `'drav0011_shop.shop.title'` | `Shop` | passing text somewhere the **client** resolves it: a `Text` child, a `MenuRow` label, a registry display field. No arguments possible. | -| `raw($ => $.shop.bought, { item: 'Apple', price: 5 })` | `{ translate: 'drav0011_shop.shop.bought', with: ['Apple', '5'] }` | `You bought Apple for 5 emeralds.` | the same, but with **arguments**. Still client-resolved, so still per-player and uncapped. | -| `raw($ => $.shop.title)` | `{ translate: 'drav0011_shop.shop.title' }` | `Shop` | argless `raw()` collapses to the bare key — identical to `key()`, just typed as a `RawMessage`. | -| `raw($ => $.shop.bought, { item: raw($ => $.vanilla.item.apple.name), price: 5 })` | `{ translate: '…shop.bought', with: { rawtext: [{ translate: 'item.apple.name' }, { text: '5' }] } }` | `You bought Apple for 5 emeralds.` | an argument that is **itself** a translation — the client resolves both, so the item name follows the player's language too. | -| `t($ => $.shop.bought, { item: 'Apple', price: 5 })` | `'You bought Apple for 5 emeralds.'` | *(you decide)* | you need the **string right now**, server-side: `sendMessage`, string concatenation, comparisons, or anything that takes no `RawMessage`. | -| `display(key($ => $.shop.title))` | `'Shop'` | *(you decide)* | you hold a `DisplayText` of unknown shape — a literal, a key, or a `RawMessage` — and need a plain string. Accepts all three. | -| `resolve('drav0011_shop.shop.title')` | `'Shop'` \| `undefined` | *(you decide)* | you have a **real `.lang` key** already, not a path — measurement, or bridging another addon's key. | - -The split that matters: `key()` and `raw()` **defer** to the client, so each player sees their own language and nothing is capped; `t()`, `display()` and `resolve()` **resolve now**, on the server, and give you one string for whichever locale you bound to. - -:::tip A key nothing resolves comes back literally -`display()` and `resolve()` mirror Bedrock: an unknown key returns as itself rather than throwing or emptying. If you see a raw `drav0011_shop.shop.title` in game, the key exists at the call site but not in the built `.lang`. -::: - -### Two call shapes, one type - -Every verb takes a **selector** or the equivalent **dot string**. Both autocomplete, both are checked identically: - -```ts -t($ => $.shop.bought, { item: 'Apple', price: 5 }); -t('shop.bought', { item: 'Apple', price: 5 }); -``` - -An unknown path is a compile error in both forms. Prefer the selector form on projects with the vanilla branch enabled — the dot-string union over ~10k vanilla keys is only instantiated when you actually use a string. - -At a call site the tree is rooted at your own keys, with two branches grafted in by the filter: - -```ts -t($ => $.shop.bought, { item, price }); // yours — packs/data/i18n -t($ => $.core.addons.title); // a library's strings -t($ => $.vanilla.item.apple.name); // vanilla Minecraft -``` - -## Interpolation - -`{{var}}` placeholders in the authored template become **required, closed** properties on the argument object: - -```ts -// en_US.ts → bought: 'You bought {{item}} for {{price}} emeralds.' - -t($ => $.shop.bought, { item: 'Apple', price: 5 }); // ✅ - -t($ => $.shop.bought); // ❌ arguments are required -t($ => $.shop.bought, { item: 'Apple' }); // ❌ missing variable: price -t($ => $.shop.bought, { item: 'Apple', price: 5, cost: 1 }); // ❌ unknown variable: cost -t($ => $.shop.title, { item: 'x' }); // ❌ template has no variables -``` - -Values are `string | number`. - -`raw()` widens what an argument accepts: any `RawMessage` part — a nested `raw()`, a `score`, a `selector` — is allowed, and the moment one appears the whole `with` array travels as rawtext parameters so the **client** resolves every part in its own language: - -```ts -raw($ => $.shop.bought, { item: raw($ => $.vanilla.item.apple.name), price: 5 }); -// { -// translate: 'drav0011_shop.shop.bought', -// with: { rawtext: [{ translate: 'item.apple.name' }, { text: '5' }] }, -// } -``` - -`raw()` orders its `with` array by the argument order the filter recorded at build time (first-appearance order in the default locale), so a translation may reorder its sentence freely without reordering arguments. - -:::caution Format functions do not exist -`{{price, currency}}` is not supported. A format function is JavaScript and cannot travel to the client. Format in code and pass the result as the argument. -::: - -### Vanilla keys take positional arguments - -Vanilla strings are not literal-typed (they come from Mojang's `.lang`, not your source), so their leaves accept an optional loose record **or** a positional array matching the client's `%1$s` slots: - -```ts -raw($ => $.vanilla.multiplayer.player.joined, [player.name]); -// { translate: 'multiplayer.player.joined', with: ['Steve'] } -``` - -## Plurals - -Author `_one` / `_other` variants (plus `_zero`, `_two`, `_few`, `_many` where a language needs them). They **collapse into a single leaf** that takes `count`: - -```ts -// en_US.ts -// stock_one: '{{count}} left in stock', -// stock_other: '{{count}} left in stock', - -t($ => $.shop.stock, { count: 1 }); // '1 left in stock' -t($ => $.shop.stock, { count: 3 }); // '3 left in stock' - -t($ => $.shop.stock, {}); // ❌ count is required on a plural leaf -t($ => $.shop.stock_one, { count: 1 }); // ❌ suffixed variants are hidden -``` - -Bedrock `.lang` has no plural mechanism, so the suffix is **always** chosen server-side — even for `key()` and `raw()`, where the already-suffixed key is what travels to the client: - -```ts -key($ => $.shop.stock, { count: 1 }); // 'drav0011_shop.shop.stock_one' -key($ => $.shop.stock, { count: 9 }); // 'drav0011_shop.shop.stock_other' -``` - -:::caution Pluralized leaves need a bound verb set -Which suffix wins depends on the *target language's* plural rules, so a plural call only makes sense against a resolved locale. Use `i18n.forPlayer(player)` (or [`useTranslation`](/docs/ui/hooks/useTranslation) in a component) rather than the unbound top-level verbs, which are pinned to the default locale. -::: - -Categories come from a built-in CLDR rule table (`Intl.PluralRules` is not available in Bedrock's script engine) covering the locales the Bedrock client ships: - -| Language | Categories | -| --- | --- | -| `ja`, `ko`, `zh`, `id` | `other` only | -| `fr` | `one` (i = 0 or 1) / `other` | -| `cs`, `sk` | `one` / `few` (2–4) / `other` | -| `pl` | `one` / `few` / `many` | -| `ru`, `uk` | `one` / `few` / `many` | -| everything else (`en`, `de`, `es`, `it`, `pt`, `nl`, `sv`, `tr`, …) | `one` (n = 1) / `other` | - -Lookup falls back `_` → `_other`, so a category a locale never authored never strands a string. A locale may author *extra* variants the default locale does not have (Czech `_few`); the filter carries them. - -## DisplayText - -```ts -type DisplayText = string | RawMessage; -``` - -`DisplayText` is **the** player-facing text union — every channel that shows a player something shares it: [`Text`](/docs/ui/components/content/Text) children, [`Header`](/docs/ore-styled/Header) and [`MenuRow`](/docs/ore-styled/MenuRow) labels, registry display fields, `display()` input. - -Which shape a string is — a literal or a `.lang` key — is decided **lazily by the active resolver**, never declared: - -```tsx -{'Hello'} {/* nothing resolves it → literal */} -{key($ => $.shop.title)} {/* the resolver knows it → localized */} -{raw($ => $.shop.bought, { item, price })} {/* always localized */} -``` - -A key nothing resolves paints literally — which is exactly what Bedrock does with an unmatched `.lang` key, so a foreign addon's key still resolves on the *client* even when your server has never seen it. - -## Locale resolution - -`t()` needs a locale. The chain, first hit wins: - -1. **Per-player override** — `setLocale(player, 'es_ES')`, persisted in a dynamic property so it survives rejoin. `clearLocale(player)` removes it. -2. **The player's client language** — `player.clientSystemInfo.locale`. -3. **A sibling region of that language** — a player on unauthored `es_MX` gets the Spanish written for Spain rather than English. -4. The addon's `defaultLocale`, then any locale the bundle carries. - -```ts -t($ => $.shop.title); // defaultLocale — no player in sight - -const { t: tp } = i18n.forPlayer(player); // bound through the chain above -const { t: es } = i18n.forLocale('es_ES'); // pinned, e.g. for logs or broadcasts +That is the whole setup. Key paths, interpolation variables and plural forms are all inferred from the bundle's type — no module augmentation, no manual type imports. See [bundler](/docs/filters/bundler) for the `@bedrock-core/generated/i18n` path alias this import needs. -i18n.setLocale(player, 'es_ES'); // persisted override -i18n.clearLocale(player); // client language takes over again -``` - -`forPlayer` and `forLocale` return the **full bound verb set** (`locale`, `t`, `key`, `raw`, `resolve`, `display`) — binding matters for plurals even on the client-resolved verbs, as noted above. Bound sets are cached per locale, so calling `forPlayer` on every render is cheap. - -The override is stored under the dynamic property `bedrock_core:i18n_locale`, exported as `LOCALE_PROPERTY`. - -## resolve() and display() - -Two lookups sit alongside the verbs on every bound set. - -### `resolve(realKey)` - -```ts -type TranslationResolver = (key: string) => string | undefined; -``` - -Resolves a **real `.lang` key** — `key()` output, a registry display field, a vanilla key, a `.lang` passthrough entry — to its display string, or `undefined` when this bundle does not carry it. - -This is the measurement contract the UI runtime uses. You rarely call it directly; you pass it around ([`TranslationContext`](/docs/ui/api/TranslationContext) carries exactly this type). - -### `display(value)` - -```ts -display(value: DisplayText): string -``` - -Any `DisplayText` to a plain string, server-side, in this locale — for the places a key must **become** text: breadcrumb trails, native modal headings, chat prefixes. Literal strings pass through, key strings resolve, `RawMessage`s resolve and fill their `with` parameters (nested translates resolve one level; `score`/`selector` parts have no server value and fill as `''`). A key nothing resolves comes back literally. - -```ts -const { display } = i18n.forPlayer(player); - -display('Plain text'); // 'Plain text' -display(key($ => $.shop.title)); // 'Shop' -display(raw($ => $.shop.bought, { item: 'Apple', price: 5 })); -// 'You bought Apple for 5 emeralds.' -``` - -The free function `resolveDisplay(resolve, value)` is the same logic over any resolver you already hold — that is what `Header` and `MenuRow` use. - -## In the UI - -### Measurement needs no wiring - -`createI18n(bundle)` registers itself as the addon's default translation source, and `render()` wraps every root so the resolver, bound to the viewing player, is available to the whole tree. Localized `Text` children resolve through it per player. There is nothing to add at your App root. - -### Binding the verbs - -Inside a component, bind the addon's typed verbs to the viewing player with [`useTranslation`](/docs/ui/hooks/useTranslation): - -```tsx -import { Panel, Text, useTranslation } from '@bedrock-core/ui'; -import { i18n } from '../i18n'; - -function Shop() { - const { t, key, raw, locale } = useTranslation(i18n); - - return ( - - {key($ => $.shop.title)} - {raw($ => $.shop.bought, { item: 'Apple', price: 64 })} - {t($ => $.shop.locale, { locale })} - - ); -} -``` - -Outside a component (server-side code, event handlers) bind explicitly instead — `i18n.forPlayer(player)` is the same call `useTranslation` makes: - -```ts -world.afterEvents.playerSpawn.subscribe(({ player }) => { - const { raw } = i18n.forPlayer(player); - player.sendMessage(raw($ => $.shop.bought, { item: 'Apple', price: 5 })); -}); -``` - -### Overriding the resolver - -[`TranslationContext`](/docs/ui/api/TranslationContext) exists to **override** the default for a subtree — for hosts that resolve beyond their own bundle (`@bedrock-core/config` provides `core.translations.forPlayer(player)`, which chains every addon's published bundle) or subtrees pinned to custom data. [`useTranslationResolver`](/docs/ui/hooks/useTranslationResolver) reads whichever resolver is active. - -## Without the filter - -`createResourceBundle` builds the same bundle shape from nested resource modules at runtime — full typed verbs, no build step: - -```ts -import { createI18n, createResourceBundle } from '@bedrock-core/i18n'; -import en_US from './i18n/en_US'; -import es_ES from './i18n/es_ES'; - -const bundle = createResourceBundle('core', { en_US, es_ES }); - -export const i18n = createI18n(bundle, { asDefault: false }); -``` - -```ts -function createResourceBundle( - namespace: string, - locales: Readonly> & { readonly en_US: T }, - options?: ResourceBundleOptions, -): I18nBundle & { readonly resources?: T } -``` - -| Option | Type | Default | Description | -| --- | --- | --- | --- | -| `defaultLocale` | `string` | `'en_US'` | The locale defining the type and the recorded argument order | -| `extra` | `Record>` | — | `.lang`-passthrough entries (locale → REAL key → string) to carry for measurement | - -Two audiences: - -- **Libraries.** Their resources ship inside the package, and the consuming addon's filter folds them into its `.lang`; the library still wants typed verbs over its own strings. `@bedrock-core/config` does exactly this. -- **Addons not (yet) running the filter.** Everything works minus what only a build can do: `.lang` emission, the vanilla branch, cross-locale parity checks. - -:::caution `asDefault: false` for libraries -A library creating its own instance must pass `{ asDefault: false }` so it never shadows the host addon's bundle as the default translation source. An addon's own `createI18n` call *is* the registration and should keep the default (`true`). -::: - -## Cross-addon sharing - -Publish the bundle itself through the server runtime's registration: - -```ts -core.register({ manifest }); -core.translations.provide(bundle); -``` - -The runtime replicates the bundle — objects, templates and recorded argument order intact — and serves two lazy views: `core.translations.of(addonId)` gives verbs over a peer's strings, and `core.translations.forPlayer(player)` gives one resolver chaining every published bundle, later registrations winning collisions. Registry display fields (`packName`, `description`, `creatorName`) are translation keys so that this works. - -## API reference - -### `createI18n(bundle, options?)` - -```ts -function createI18n(bundle: B, options?: CreateI18nOptions): I18n> -``` - -| Option | Type | Default | Description | -| --- | --- | --- | --- | -| `asDefault` | `boolean` | `true` | Register this instance as the addon's default translation source | - -Returns an `I18n`: the default-locale bound set plus `bundle`, `forLocale`, `forPlayer`, `setLocale`, `clearLocale`. - -### `BoundI18n` - -What `forPlayer` / `forLocale` return, and what `I18n` extends. - -| Member | Type | Description | -| --- | --- | --- | -| `locale` | `string` | The resolved locale this set is bound to | -| `t` | `TranslateFn` | Server-resolved, interpolated string | -| `key` | `TranslateFn` | The real `.lang` key (plural suffix applied) | -| `raw` | `TranslateFn` | `translate` + `with` for the client | -| `resolve` | `TranslationResolver` | Lazy real-key lookup over this bundle | -| `display` | `(value: DisplayText) => string` | Any `DisplayText` to a plain string | - -### Other exports - -| Export | Kind | Description | -| --- | --- | --- | -| `DisplayText` | type | `string \| RawMessage` — the shared text union | -| `resolveDisplay(resolve, value)` | function | The `display()` primitive over any resolver | -| `createResourceBundle(ns, locales, options?)` | function | Build a bundle from objects at runtime | -| `currentI18n()` | function | The addon's registered default instance, or `undefined` | -| `realKeyFor(bundle, path)` | function | Flat path → real `.lang` key | -| `pickLocale(available, candidates, default)` | function | The locale-chain policy, standalone | -| `pluralCategory(locale, count)` | function | The CLDR category for a locale + count | -| `interpolate(template, args?)` | function | Fill `{{var}}` (record) or `%N$s` (array) | -| `templateVars(template)` | function | `{{var}}` names, first-appearance order | -| `toPositional(template, order)` | function | `{{var}}` → `%N$s` against a recorded order | -| `LOCALE_PROPERTY` | const | `'bedrock_core:i18n_locale'` | -| `I18nBundle`, `LangEntries` | types | The bundle shape the filter generates | -| `TranslationResolver`, `TranslateFn`, `BoundI18n`, `I18n`, `CreateI18nOptions` | types | Engine types | -| `Leaf`, `AnyLeaf`, `ArgsOf`, `Interp`, `PathsOf`, `ResolvePath`, `SelectorTree`, `TemplateVars` | types | The compile-time machinery | - -## Limits - -- **Compile-time guarantees end where dynamic strings begin.** `t()` on a runtime-assembled key the type system never saw returns the key itself, mirroring how Bedrock renders an unknown `.lang` key literally. -- **`$t(other.key)` nesting is a build-time feature.** Bedrock `.lang` has no nesting, so the filter flattens references before emitting; nothing resolves them at runtime. -- **Vanilla `t()` values are partial by design.** Only the vanilla keys your compiled scripts reference as literals or `$.vanilla.` chains ride in the bundle — see [the filter page](/docs/filters/i18n#vanilla-strings). - -## Using it from the UI - -The verbs above are bound to a player. Inside a component these hooks do that for you: - -:::caution Pre-1.0 -`@bedrock-core/i18n` is under active development. Breaking changes can still land until `1.0.0` — pin exact versions and read the release notes before upgrading. -::: +`createI18n` also registers this instance as the addon's default translation source, which is what lets [`Text`](/docs/ui/components/Text) measure localized children with no further wiring. -| API | What it gives you | -| --- | --- | -| [`useTranslation(i18n)`](/docs/ui/hooks/useTranslation) | Your addon's fully typed verbs (`t`, `key`, `raw`, `display`, `resolve`, `locale`) bound to the viewing player. The one you want almost always. | -| [`useTranslationResolver()`](/docs/ui/hooks/useTranslationResolver) | The active `TranslationResolver` on its own, for components that build display strings themselves rather than calling verbs. | -| [`TranslationContext`](/docs/ui/api/TranslationContext) | Overrides which resolver a subtree uses — for hosts resolving beyond their own bundle, or a subtree pinned to custom data. Seeded automatically at every root. | -| [``](/docs/ui/components/content/Text) | The consumer: its `children` accept `DisplayText`, so `key()` and `raw()` output goes straight in. | +## What you get -## In this section +- **Client-first resolution.** `key()` and `raw()` defer to the client, so each player sees their own language at no per-player cost on the server; `t()` resolves now, server-side, for whichever locale you're bound to. See [The three verbs](./api.md#the-three-verbs). +- **Typed everything.** Key paths, required interpolation variables and plural forms all come from the bundle's inferred type — an unknown path or a missing argument is a compile error, not a blank string in game. +- **Plurals without `Intl`.** A built-in CLDR rule table picks `_one` / `_few` / `_other` per locale, since Bedrock's script engine has no `Intl.PluralRules`. +- **One `DisplayText` channel.** [`Text`](/docs/ui/components/Text) children, [`Header`](/docs/ore-styled/Header) and [`MenuRow`](/docs/ore-styled/MenuRow) labels, and registry display fields all accept the same `string | RawMessage` union, resolved lazily by whichever resolver is active. +- **Cross-addon sharing.** `core.translations.provide(bundle)` publishes a bundle; `core.translations.of(addonId)` and `.forPlayer(player)` read across every published addon's strings — see [Cross-addon sharing](./api.md#cross-addon-sharing). -| Page | Description | -| --- | --- | -| [i18n Regolith filter](/docs/filters/i18n) | Authoring `packs/data/i18n/.ts`, generated outputs and parity checks | +## Next steps +- [Authoring resources](./authoring.md) — locale files, namespacing, interpolation, plurals and the meta branch +- [Libraries and overrides](./libraries.md) — folding a dependency's strings into your bundle, overriding library and vanilla strings +- [API reference](./api.md) — the three verbs, locale resolution, `createI18n` and every export +- [i18n Regolith filter](/docs/filters/i18n) — generating `.lang` files and the runtime bundle from your resources +- [useTranslation](/docs/ui/hooks/useTranslation) — binding the typed verbs to the viewing player inside a component +- [TranslationContext](/docs/ui/api/TranslationContext) — overriding which resolver a subtree sees diff --git a/docs/i18n/libraries.md b/docs/i18n/libraries.md new file mode 100644 index 0000000..e7c13b4 --- /dev/null +++ b/docs/i18n/libraries.md @@ -0,0 +1,71 @@ +--- +sidebar_position: 3 +description: "Folding a dependency's typed strings into your bundle, and overriding a library's or a vanilla string." +--- + +# Libraries and overrides + +A library ships its strings inside its own package and declares them in `package.json`, together with an export that makes them reachable for the generated types: + +```jsonc +"bedrockCore": { "i18n": { "dir": "./src/i18n", "namespace": "core" } }, +"exports": { "./i18n/*": { "types": "./src/i18n/*.ts", "import": "./src/i18n/*.ts" } } +``` + +## Libraries + +The [i18n filter](/docs/filters/i18n) walks the dependency graph for that field and folds each library's resources in under the declared namespace: its keys are emitted into your `.lang` files, its tree appears under `$.core.*`, and its strings ride in your runtime bundle. + +Discovery rules: + +- **The walk is transitive and sees through non-declaring packages** — a declarer may sit behind an umbrella that declares nothing itself, like `@bedrock-core/config` behind `@bedrock-core/ui`. +- **Resolution follows Node's rules**: nearest `node_modules` first, then ancestors. +- **`devDependencies` count only at the addon root** — transitive devDependencies are not installed. +- **Several packages may share one namespace** (the whole bedrock-core family publishes under `core`). Their trees are merged; a key two packages define with *different* values is a build error naming both. +- A library declaring `bedrockCore.i18n` whose directory has no `.ts` files is a warning, not an error. A library namespace of `vanilla` is rejected. + +## Overriding a library string + +Library branches are **override-only** from `data/i18n`. You may author `core.addons.title` to deliberately rename a library string ("Addons" → "Mods") and your value wins — but only for paths the library actually defines: + +```ts +// packs/data/i18n/en_US.ts +export default { + core: { addons: { title: 'Mods' } }, // override — 'core.addons.title' must exist + shop: { title: 'Shop' }, +} as const; +``` + +An unknown path under a library branch is a build error. Overrides are exempt from the parity check — override in one locale without the others and the library's own translation fills the gap — but an override must keep the library's interpolation variable set. + +## Vanilla strings + +Opt in with the filter's `vanilla` setting. Off by default, because it fetches and diffs the vanilla `.lang` files against Mojang's `bedrock-samples` on every build. Once on, `$.vanilla.*` autocompletes — the full vanilla tree (~10k keys) is generated into `vanilla.generated.d.ts`. Those strings are never emitted into the resource pack: the client already ships them, so re-adding them would only bloat the pack. + +Server-side values (what `t()` returns and what the layout engine measures) are included in the runtime bundle **only for the keys your compiled scripts actually reference**. The filter scans the compiled output — and every discovered library's `src` — for string literals and for `$.vanilla.` selector chains: + +```ts +t($ => $.vanilla.item.apple.name); // found -> bundled +t('vanilla.item.apple.name'); // found -> bundled +t(`item.${id}.name`); // NOT found — assembled at runtime +``` + +A key that is not found still resolves on the client through `key()` / `raw()`; what degrades is `t()` (falls back to the raw key) and layout measurement for that one string. + +Vanilla `.lang` content is fetched per locale from Mojang's `bedrock-samples` and cached under `.regolith/cache/i18n/` for `cacheMaxAgeHours`. A locale whose fetch fails warns and falls back to the default locale's strings. + +## Overriding a vanilla string + +A `vanilla` branch in the addon's own resources overrides a vanilla string, the same way an addon overrides a library's keys: + +```ts +// packs/data/i18n/en_US.ts +export default { + shop: { title: 'Shop' }, + vanilla: { item: { apple: { name: 'Golden Snack' } } }, +} as const; +``` + +The overridden key is written to the resource pack's `.lang` under its **vanilla** name, not the namespaced form — `item.apple.name=Golden Snack` — because Bedrock merges every installed pack's `.lang`, and that is the key the client already looks up for that string. The runtime bundle carries the replacement wherever it carries that vanilla string, which is only when `vanilla` is on and the key is one your compiled scripts reference. + +With the filter's `vanilla` setting on, a key no vanilla string has is reported. From e5c4cf17939c02cce31a5ba27706668cf614b0d8 Mon Sep 17 00:00:00 2001 From: DrAv0011 Date: Thu, 17 Sep 2026 17:35:17 +0200 Subject: [PATCH 39/48] docs(navigation): the realm page, params across realms - uiOf(core) has a page of its own: the show methods, the navigator and the way back. It replaces the server's UI integration guide. - references and navigate describe the params a link carries from a static screen and to another realm. Co-Authored-By: Claude Opus 5 (1M context) --- docs/navigation/index.md | 21 ++-- docs/navigation/navigate.md | 4 +- docs/navigation/realm.md | 121 +++++++++++++++++++++ docs/navigation/references.md | 30 ++++-- docs/navigation/useNavigation.md | 8 +- docs/server/guides/ui-integration.md | 156 --------------------------- 6 files changed, 161 insertions(+), 179 deletions(-) create mode 100644 docs/navigation/realm.md delete mode 100644 docs/server/guides/ui-integration.md diff --git a/docs/navigation/index.md b/docs/navigation/index.md index 97078f3..35b3aab 100644 --- a/docs/navigation/index.md +++ b/docs/navigation/index.md @@ -8,9 +8,13 @@ description: "@bedrock-core/navigation moves a player from one compiled screen t `@bedrock-core/navigation` moves a player from one screen to another by **key**, and keeps a stack of where they have been. -:::caution Pre-1.0 -`@bedrock-core/navigation` is under active development. Breaking changes can still land until `1.0.0` — pin exact versions and read the release notes before upgrading. +:::caution Beta +`@bedrock-core/navigation` is in beta: the API can change between releases. Pin exact versions and read the changelog before upgrading. ::: +:::caution Author note +The API for navigation *WILL* change, this a temp step while transitioning to hybrid screens from only runtime ones. +::: + ## What is @bedrock-core/navigation? @@ -36,10 +40,10 @@ import '@bedrock-core/generated/ui'; core.register({ manifest }); -// Publish this addon's screens so other realms can show them. +// Publish this addon's screens so other realms can show them, and resolve a key this +// bundle did not compile from whoever owns it. An addon that installs any of the apps +// gets both done by `uiOf(core)`; this is the bundle that mounts none. screens(core).provide(uiReference()); - -// Resolve a key this bundle did not compile, from whoever owns it. provideReferences(key => screens(core).find(key)); export function openCatalog(player: Player): void { @@ -55,8 +59,8 @@ function Row(): JSX.Element { return ( - - + + ); } @@ -68,11 +72,12 @@ function Row(): JSX.Element { **Screens other addons can open** — publish your static screens once and `navigate(':')` works in any realm in the world, whether or not your script runs there. The client draws it from the pack it already holds. -**A press that is data** — [``](/docs/ui/components/controls/Link) puts the destination on the element rather than in a closure, so the build can read where it leads and describe the screen to other addons. +**A press that is data** — [``](/docs/ui/components/Link) puts the destination on the element rather than in a closure, so the build can read where it leads and describe the screen to other addons. ## Next steps - [Moving between screens](./navigate.md) — `navigate`, `back`, `replace`, `reset` and what each does to the stack - [`useNavigation`](./useNavigation.md) — the same calls inside a screen, bound to its player - [References](./references.md) — publishing your screens and resolving another addon's +- [The realm](./realm.md) — `uiOf(core)`: the show methods, the way back, and where each player is - [Navigation in the ui docs](/docs/ui/guides/navigation) — screen keys, `` and static screens diff --git a/docs/navigation/navigate.md b/docs/navigation/navigate.md index 7f0b4c1..8f43855 100644 --- a/docs/navigation/navigate.md +++ b/docs/navigation/navigate.md @@ -38,7 +38,9 @@ Each returns whether a screen was shown. A `false` is a key nothing resolved: a | `replace` | `boolean` | `false` | Show the screen in place of the current one; `replace()` is this with the flag already set | | `debug` | `boolean` | `false` | Diff every present against the snapshot the build recorded and warn on drift | -`params` fill what the layout already reserved. A compiled screen's shape is frozen, so they can never add or drop a cell — a generic screen's labels and values, not its structure. +`params` fill what the layout already reserved. A compiled screen's shape is frozen, so they can never add or drop a cell — a generic screen's labels and values, not its structure. A static screen is shown from its table and takes none. + +Params that reach another realm, or a static screen's table, are written as JSON, so they must be plain data: strings, finite numbers, booleans, null, and arrays and objects of those. A realm drops params that are not, with a warning, and still opens the screen. ## Which one to reach for diff --git a/docs/navigation/realm.md b/docs/navigation/realm.md new file mode 100644 index 0000000..c173b55 --- /dev/null +++ b/docs/navigation/realm.md @@ -0,0 +1,121 @@ +--- +sidebar_position: 5 +description: "uiOf(core) is the UI a realm has once, whichever apps are installed: the show methods, the navigator, the way back, and where each player is." +--- + +# The realm + +A screen is drawn by the addon whose pack holds it. Most of the shared UI is in every pack, so whichever realm a command is typed into draws it; what one addon *declared* exists in exactly one bundle, and reaching it means asking that addon's realm. `uiOf(core)` is the part of that every app needs exactly once, however many apps an addon installs. + +## Import + +```ts +import { uiOf, methodFor, isUiTarget, isUiReturn, registerDeclared } from '@bedrock-core/navigation'; +import type { UiPresence, UiTarget, ScreenTarget, UiReturn, TargetOpener } from '@bedrock-core/navigation'; +``` + +## uiOf + +```ts +uiOf(core: Runtime): UiPresence +``` + +The realm's one UI presence, built on the first call and kept in the runtime's `core:ui` slot. Every app calls it and gets the same object, so the show methods, the navigator and the way back are installed once. An app registers what it draws and reads the rest back: + +```ts +const realm = uiOf(core); + +realm.serve('config', (player, target) => openConfig(core, player, target)); +realm.offers('config'); +``` + +## Targets + +A place in the UI, as data. What travels when one realm asks another to draw a screen, and what comes back the other way when the player leaves it: + +```ts +interface UiTarget { + readonly kind: string; + readonly addonId?: string; + readonly [field: string]: unknown; +} +``` + +The `kind` is open. This package serves one of them itself, `screen`, because a key and its params are the whole of what a cross-realm `navigate()` carries; every other kind belongs to the app that serves it, and an app narrows the fields of its own kind with its own guard. `addonId` is the one field the realm reads for itself: a kind nothing here serves is sent to that addon's realm, which may have installed the app this one did not. + +`isUiTarget` checks the envelope off the wire: a string `kind`, and for `screen` a string `key` and, when present, an object `params`. `isUiReturn` does the same for one hop of a way back, `{ realm, target }`. A realm running an older or newer copy of an app may have sent either, so a path with anything unreadable in it is dropped rather than half-walked. + +## One method per kind + +```ts +methodFor(kind: string): string // 'core:config.show', or 'core:ui.show' for a screen +``` + +The method a realm is asked on is derived from the kind, not registered, so a caller maps one to the other with nothing to probe. An addon that did not install an app does not serve its method, and the request is refused with `unknown method`: a visible failure the caller falls back from, instead of a target kind silently opening the wrong screen. + +## Serving a kind + +| Member | Description | +| --- | --- | +| `serve(kind, opener)` | Register what draws that kind here, and start answering its method. One opener per kind; a second throws | +| `serves(kind)` | Whether an app mounted in this realm draws that kind | +| `show(player, target)` | Draw a target: the local opener, or the owning realm when nothing here serves the kind, or the owner of a screen key this bundle did not compile | + +`show` is the funnel. A command, a press on a page, a request from another realm and an app's own `open` all end here, which is where a target is routed once. + +## Asking another realm + +| Member | Description | +| --- | --- | +| `ask(owner, player, target, from?)` | Ask `owner`'s realm to show a target, carrying the way back. Never rejects; resolves whether that realm took the player | +| `returnTo(player)` | The way back a request from here carries: the realms the player crossed, with this one appended when it has a place to name | +| `showing(player, target)` | Record what this realm is showing a player, as the target that put them there | + +When the other realm takes the player, this one drops its component tree and input lock but leaves the forms on screen: closing them would close the one that realm just opened. + +`showing` matters for one kind of screen. A screen drawn from a *model*, a catalog or a roster, cannot be returned to by its key, because rendering its component with no model draws the empty shape of it. The target that opened it is what can be sent back across a realm, so every such screen records it. + +## Resolving keys + +| Member | Description | +| --- | --- | +| `reference(key)` | The reference for one screen key: the sources this realm added first, then whatever an addon published. `undefined` is a key nothing in this world can draw | +| `resolve(source)` | Add a source of references tried before the published ones, for screens baked into a pack that no addon announces | +| `alias(addonId, ns)` | Say which UI namespace a row belongs to when that row is not an addon that publishes | +| `screenKey(addonId, name)` | The key of one of an addon's screens by the name its build gave it, read off what that addon published or off an alias | + +The framework is the one row that needs the last three: it has a page and a guide but no realm, so it announces nothing. The catalog hands the realm its table and its namespace. + +## The first tick + +```ts +realm.onReady(() => { /* publish something read off the build */ }); +``` + +Runs on the first tick, when every module the entry imports has been evaluated and the build's declarations are in hand; immediately if that tick has passed. Every publisher runs in a try/catch that warns rather than throws, so an addon shipping an older runtime than the UI it mounts loses one announcement rather than failing to start. + +The realm publishes two things itself: this addon's [screen references](./references.md), and its page in the catalog when the build declared one. + +## What an addon offers + +| Member | Description | +| --- | --- | +| `offers(app)` | Declare that this addon serves an app, by the name its target kind is known by | +| `offered(addonId)` | What an addon announced it serves. Empty for one that announced nothing | + +Announced as one list on the first tick, after every app has installed, so any realm can tell what a peer answers before asking it. A catalog uses it to draw an entry for an app an addon does not serve as unreachable, rather than leading a player at a request that would be refused. An app that only learns during its own tick whether it has anything to serve, a guide with no pages, still counts: the list goes out last. + +## What the build declared + +```ts +registerDeclared({ page }); +declaredParts(): DeclaredParts +``` + +The channel the build uses to hand the runtime something the addon author never wrote. The ui-compiler filter generates a module that asks each installed app for the screens its declaration implies; the catalog's builds the addon's page from the manifest and calls `registerDeclared` with it, and the realm reads it back on the first tick and publishes the reference. The generated module is imported for its side effect at the top of the entry, which is what makes it evaluate before anything reads it. + +## Notes + +`uiOf` serves `core:ui.show` for `screen` targets, installs [`provideReferences`](./references.md) with `ask` and `sendBack` wired to the transport, and forgets a player's place when they leave. An app never installs a navigator, serves that method or keeps its own return path. + +A realm running an older copy of an app understands as much of a target as it knows and falls back for the rest. Nothing about a target's fields reaches the runtime. diff --git a/docs/navigation/references.md b/docs/navigation/references.md index 234e5ea..8b6e696 100644 --- a/docs/navigation/references.md +++ b/docs/navigation/references.md @@ -1,21 +1,24 @@ --- sidebar_position: 4 -description: "Publishing this addon's screens and resolving a key it never compiled." +description: "Publishing this addon's screens and page, and resolving a key it never compiled." --- + # References A key for a screen nobody in this realm compiled still resolves, because every client already holds the pack that draws it. What has to travel is small: per screen the compiled title, the value each entry carries and where each press leads. +An addon that installs any app gets all of this done for it by [`uiOf(core)`](./realm.md). Reach for these directly in a bundle that wants its screens navigable without mounting an app. + ## Import ```ts -import { pages, provideReferences, screens } from '@bedrock-core/navigation'; +import { addonPageReference, pages, pageTargeted, provideReferences, screens } from '@bedrock-core/navigation'; ``` ## provideReferences ```ts -provideReferences(lookup: (key: string) => ScreenReference | undefined): void +provideReferences(lookup: (key: string) => ScreenReference | undefined, crossRealm?: CrossRealm): void ``` Installs what resolves a key this bundle did not compile. Called once: @@ -24,9 +27,9 @@ Installs what resolves a key this bundle did not compile. Called once: provideReferences(key => screens(core).find(key)); ``` -Until it is called, a foreign key warns and shows nothing. A key this bundle **did** compile never reaches the lookup — its own component is rendered. +Until it is called, a foreign key warns and shows nothing. A key this bundle **did** compile never reaches the lookup; its own component is rendered. -A screen shown from a reference is **shown, not rendered**: there is no component in this realm, so the walk drives the client directly — title, values, and the key each press leads to — for as long as the presses are links. A press that ran the owner's own handler cannot be described, so it does nothing there, and the walk ends. +A screen shown from a reference is **shown, not rendered**: there is no component in this realm, so the walk drives the client directly, title, values and the key and params each press leads to, for as long as the presses are links. A press that ran the owner's own handler cannot be described, so such a screen needs its owner's script. Pass `crossRealm` to reach it: `ask(owner, key, player, params)` sends the player there, and `sendBack(address, rest, player)` returns them. Without one, such a key warns exactly as an unknown key does. ## screens @@ -58,23 +61,30 @@ screens(core).provide(uiReference()); pages(core: Runtime): PagesRegistry ``` -The same shape for an addon's page in the shared addon list, announced under `addon/page`. The page follows from the manifest, so the build compiles one and [`ui(core)`](/docs/config) announces it — an addon that mounts the config UI needs none of this by hand. +The same shape for an addon's page in the [catalog](/docs/catalog/page), announced under `addon/page`. Every addon publishes one, whether or not it installed a catalog: the page follows from the manifest, the build compiles it, and the realm announces it on the first tick. | Member | Description | | --- | --- | | `provide(reference)` | Publish this addon's page | | `of(addonId)` | What another addon published | +Where a press on the page leads is the **name of an app**, `config` or `guide`, not a screen: the page is drawn in one realm and answered in another, and only the owning realm knows what its config screen looks like. + +```ts +addonPageReference(Page: FunctionComponent): AddonPageReference // the reference of a page screen +pageTargeted(app: string): TargetedPress // a press that names the app it opens +``` + +`addonPageReference` builds a page's reference the way the compile built the screen, reading each entry's value off the tree and each press's target off its handler. `pageTargeted` marks a press with the app it opens; its body is empty on purpose, because the page's own script never runs. + ## Types ```ts -import type { AddonPageReference, AddonScreens } from '@bedrock-core/navigation'; +import type { AddonPageReference, AddonScreens, PageTarget, TargetedPress } from '@bedrock-core/navigation'; ``` -Both are envelopes: the version, the owner, and the payload as `unknown`. The renderer owns the real shape and narrows it at the point of use, which is what keeps this package free of the screen format. `isAddonScreens` and `isAddonPageReference` are the envelope checks. +`AddonScreens` is an envelope: the version, the owner's UI namespace, and the screens as `unknown`. The renderer owns the real shape and narrows it at the point of use, which is what keeps this package free of the screen format. `AddonPageReference` is `{ v: 1, values: string[], targets: (PageTarget | null)[] }`. `isAddonScreens` and `isAddonPageReference` are the envelope checks. ## Notes Both registries extend `Announcement` from `@bedrock-core/server-runtime`, so they behave like every other cross-addon feed: published once at startup, readable by every realm, and re-read when an addon joins. - -An addon that calls `ui(core)` gets both the publishing and the lookup done for it. Write these yourself for a bundle that wants its screens navigable without mounting the config UI. diff --git a/docs/navigation/useNavigation.md b/docs/navigation/useNavigation.md index 74fce18..7bef288 100644 --- a/docs/navigation/useNavigation.md +++ b/docs/navigation/useNavigation.md @@ -39,7 +39,7 @@ function Footer(): JSX.Element { const { back, canGoBack } = useNavigation(); return ( - ); @@ -56,8 +56,8 @@ function Menu(): JSX.Element { return ( - - + + ); } @@ -77,7 +77,7 @@ function Breadcrumb(): JSX.Element { ## Notes -Prefer [``](/docs/ui/components/controls/Link) over a `navigate()` in a button's `action` when the destination is fixed. A link's target is data the build reads off the tree, which is what lets the screen be described to another addon; a closure is script only this realm can run. +Prefer [``](/docs/ui/components/Link) over a `navigate()` in a button's `action` when the destination is fixed. A link's target is data the build reads off the tree, which is what lets the screen be described to another addon; a closure is script only this realm can run. `canGoBack` and `history` are read at render time. A form cannot change while it is open, so they are a snapshot of the moment the screen was presented — which is the same moment everything else on it was decided. diff --git a/docs/server/guides/ui-integration.md b/docs/server/guides/ui-integration.md deleted file mode 100644 index bc3f4d0..0000000 --- a/docs/server/guides/ui-integration.md +++ /dev/null @@ -1,156 +0,0 @@ ---- -sidebar_position: 1 -description: "The server side stores, validates and replicates data." ---- - -# UI integration - -The server side stores, validates and replicates data. It draws nothing. Presentation lives in the `@bedrock-core` **ui** packages — start at the [ui overview](/docs/ui) for their full reference. - -This page is the seam between the two: what `server-runtime` publishes, which UI package consumes it, and what you have to do in your addon to light it up. - -## The split - -``` - ┌──────────────────────────── your addon ────────────────────────────┐ - │ core.register({ config }) · core.translations.provide(bundle) │ - └───────────────┬────────────────────────────────────────────────────┘ - │ declares once - ▼ - ┌──────────── @bedrock-core/server-runtime ──────────────────────────┐ - │ ConfigRegistry → core-config/schema (replicated) │ - │ TranslationsRegistry → core-i18n/bundle (replicated) │ - │ GuidesRegistry → core-guide/manifest (replicated) │ - │ HostElection → who renders │ - └───────────────┬────────────────────────────────────────────────────┘ - │ read by any realm, for any addon - ▼ - ┌──────────── @bedrock-core ui packages ─────────────────────────────┐ - │ @bedrock-core/config — the addon list, config screens, commands │ - │ @bedrock-core/guides — the guide renderer │ - │ @bedrock-core/i18n — resolution, interpolation, measurement │ - │ @bedrock-core/ui — the JSX runtime everything renders with │ - └────────────────────────────────────────────────────────────────────┘ -``` - -**The UI reads the registries, not your addon.** It never imports your code and never knows your schema type — everything it draws it discovered at runtime from replicated state. - -## Mounting the shared UI - -One call, after `core.register()`: - -```ts -import { core } from '@bedrock-core/server'; -import { ui } from '@bedrock-core/config'; -import bundle from '@bedrock-core/generated/i18n'; -import { configDef } from './example'; - -core.register({ - manifest: { creator: 'drav0011', pack: 'economy', packName: 'Economy', version: '1.0.0' }, - config: configDef, -}); - -core.translations.provide(bundle); - -ui(core); -``` - -`ui` comes from [`@bedrock-core/config`](/docs/config) — the shared addon list, settings screens and guide viewer. `ui(core)` registers this addon's commands and serves the open RPC, so this realm can render on behalf of another whenever it wins the [host election](../api/host.md). - -Pass the `Runtime` itself, not the typed config accessors — everything `ui` needs it reaches generically, through [`core.config.local`](../api/config.md#coreconfiglocal), `core.config.of()`, `core.registry`, `core.translations` and `core.host`. - -## The three feeds - -### Config - -[`ConfigRegistry`](../api/config.md) publishes a **flattened, scope-prefixed schema** to replicated state: - -``` - → core-config/schema → { - 'server.pricing.taxRate': { type: 'number', default: 0.05, min: 0, max: 1, step: 0.01, label: 'Tax Rate' }, - 'player.allowGifts': { type: 'boolean', default: true, label: 'Allow Gifts' }, -} -``` - -**Registering alone puts your addon in the UI's addon list** — `config`, like `guide`, is optional; without it the addon's row simply has no Config entry. Declaring it publishes the schema map above, which is everything a form needs — the UI builds the whole form without a round trip. Values are fetched separately, on demand, over the `core:config.*` RPCs. - -The schema describes **data only**; the UI picks the control: - -| Schema says | UI picks | -|---|---| -| `type: 'boolean'` | a toggle or checkbox | -| `type: 'number'` with `min`/`max`/`step` | a slider or a numeric input | -| `type: 'string'` with `maxLength` | a text input | -| `type: 'enum'` with `options` | a dropdown or a toggle-button row | -| `type: 'list'` with `itemType`/`maxItems` | *no control* — a modal form has nothing to draw for it. The screen shows the label, the current items against `maxItems`, and the command that changes it; editing goes through [`get`/`set`/`add`/`remove`](/docs/config#list-settings-from-a-command) | - -Authorization crosses the seam too. When the UI acts for a player it builds its accessor with `core.config.of(addonId, { actorId: player.id })`, and the owning addon applies [the operator rule](../api/config.md#authorization) on its side. The caller-side permission checks in the UI are a convenience — they keep unreachable settings out of a player's command list and screens — but the decision that counts is made by the addon that owns the data. - -### i18n - -[`TranslationsRegistry`](../api/translations.md) replicates each addon's `I18nBundle` — the artifact the `i18n` Regolith filter generates as `@bedrock-core/generated/i18n`. - -`packName`, `creatorName` and `description` are translation keys in *someone else's* resource pack. `core.translations.forPlayer(player)` resolves them against every published bundle, picking the player's locale through the [override → client locale → sibling region → default chain](/docs/i18n#locale-resolution). - -Declare `translations`, or the realm rendering your addon can neither resolve your labels nor **measure** them — and layout needs a string's width before it is sent to the client. - -```ts -const resolve = core.translations.forPlayer(player); - -for (const addon of core.registry.all()) { - const label = resolve(addon.packName) ?? addon.packName; // key → text, or the literal -} -``` - -### Guides - -A guide's pages are compiled screens like any other, so they ride the screen references [`screens(core)`](/docs/navigation/references) announces rather than a feed of their own. `ui(core)` publishes them for you. - -The runtime treats the payload as opaque: [`@bedrock-core/guides`](/docs/guides) owns the real shape and narrows it at the point of presenting. - -Because references are announced rather than fetched, the realm drawing the list already has every addon's screens in memory: - -```ts -import { screens } from '@bedrock-core/navigation'; - -for (const id of screens(core).namespaces()) { - const published = screens(core).of(id); // synchronous, no RPC -} -``` - -## Which realm renders - -The realm whose command was typed forwards the raw request to the realm running the newest `@bedrock-core/server-runtime`, and every decision happens there. See [HostElection](../api/host.md). - -## What you have to do - -| Step | Why | -|---|---| -| Declare `config` in `register()` (optional) | Publishes the schema — this is what gives your row a Config screen | -| Declare `translations` in `register()` | Makes your display keys resolvable and measurable by whoever renders | -| Declare `guide` in `register()` | Publishes your guide for the host to render | -| Set `icon` / `thumbnail` in the manifest | Resource-pack texture paths the addon list draws | -| Call `ui(core)` once, after `register()` | Registers your commands and serves the open RPC | -| Ship the generated artifacts | The `i18n` and `guides` Regolith filters produce `@bedrock-core/generated/*` | - -Everything else is the ui side's job: [screens and components](/docs/ui), [navigation](/docs/navigation), [theming](/docs/ore-styled), and [per-player locale](/docs/i18n). - -## The generated imports - -Two of the three feeds come from build-time filters rather than hand-written code: - -```ts -import bundle from '@bedrock-core/generated/i18n'; // the i18n filter's output -import guides from '@bedrock-core/generated/guides'; // the guides filter's output -``` - -The specifiers are `tsconfig.json` aliases the [`bundler`](/docs/filters/bundler) inlines at build time; the [`i18n`](/docs/filters/i18n) and [`guides`](/docs/filters/guides) filter pages cover the aliases, the outputs and the `namespace` they derive from `register()`. - -An addon with no guide omits the filter; the registries handle absence everywhere (`core.config.of()` returns `undefined`, a key nothing published resolves to `undefined`, resolvers fall through). - -## Next steps - -- [`core.config`](../api/config.md) — schema types, scopes and authorization -- [`core.translations`](../api/translations.md) — what the bundle publishes -- [References](/docs/navigation/references) — the screen and page feeds the UI reads -- [config](/docs/config) — the shared UI that reads all of them From 0abab84d6490d5bbf46794d7a4adf1f95d417354 Mon Sep 17 00:00:00 2001 From: DrAv0011 Date: Thu, 17 Sep 2026 17:35:17 +0200 Subject: [PATCH 40/48] docs(server, sync, db): declarations and slots, one writer per namespace - register() takes one declaration per field, each installed into a runtime slot, with a section on writing one; core.host is reserved for capabilities. - The mirror applies a namespace's entries only from its owner. - A block document needs a block entity with dynamic properties. - Announcement documents isRecord and which packages construct one. Co-Authored-By: Claude Opus 5 (1M context) --- docs/db/index.md | 4 +- docs/db/resolver.md | 6 +- docs/db/targets.md | 18 ++-- docs/flexbox/computeLayout.md | 2 +- docs/observable/index.md | 4 +- docs/observable/observable.md | 2 +- docs/server/api/announcement.md | 9 +- docs/server/api/authorize.md | 1 - docs/server/api/host.md | 124 +++------------------------ docs/server/api/registry.md | 6 +- docs/server/api/runtime.md | 144 ++++++++++++++++++++++++++------ docs/server/api/shared.md | 9 +- docs/server/api/translations.md | 9 +- docs/server/guides/channels.md | 10 +-- docs/server/index.md | 10 +-- docs/server/installation.md | 13 ++- docs/sync/discovery.md | 24 +++++- docs/sync/index.md | 12 +-- docs/sync/protocol.md | 14 ++-- docs/sync/rpc.md | 2 +- docs/sync/state.md | 68 ++++++--------- 21 files changed, 241 insertions(+), 250 deletions(-) diff --git a/docs/db/index.md b/docs/db/index.md index df61cc3..60404df 100644 --- a/docs/db/index.md +++ b/docs/db/index.md @@ -9,8 +9,8 @@ description: "@bedrock-core/db is persisted documents on dynamic properties: typ `@bedrock-core/db` is persisted documents on dynamic properties: typed collections keyed by target, stored on whatever dynamic properties the target itself can hold. -:::caution Pre-1.0 -`@bedrock-core/db` is under active development. Breaking changes can still land until `1.0.0` — pin exact versions and read the release notes before upgrading. +:::caution Beta +`@bedrock-core/db` is in beta: the API can change between releases. Pin exact versions and read the changelog before upgrading. ::: ## What is @bedrock-core/db? diff --git a/docs/db/resolver.md b/docs/db/resolver.md index ca01530..4f96e7d 100644 --- a/docs/db/resolver.md +++ b/docs/db/resolver.md @@ -7,7 +7,7 @@ description: "The resolver probes a target once per type for where its documents The resolver decides, per target, where a document can live: on the target's own dynamic properties through one of the engine's two ABIs, or on a world property keyed by the target's identity when it has none — or nowhere, with a reason. -Nothing is declared. A target is probed once **per type** — a block type either has a `minecraft:block_entity` or it does not, an item type is either stackable or not — and the decision is cached; a throw (a block in an unloaded chunk) is never cached. +Nothing is declared. A target is probed once **per type** — a block type either has the `minecraft:dynamic_properties` component or it does not, an item type is either stackable or not — and the decision is cached; a throw (a block in an unloaded chunk) is never cached. ## Import @@ -53,8 +53,8 @@ interface Refused { ok: false; kind: TargetKind; reason: string } |---|---|---| | `World`, `Entity`, `Player` | `own`, direct ABI | six methods, 32 767 characters per value | | `ContainerSlot` with a non-stackable item | `own`, direct ABI | the slot is the item's place; a stackable item refuses properties | -| block whose type declares `minecraft:block_entity` | `own`, component ABI | about 950 bytes per block, dies with the block | -| `Dimension`, vanilla block | `proxied` | a world property keyed by the target's identity | +| block whose type declares `minecraft:block_entity` with `dynamic_properties: true` | `own`, component ABI | about 950 bytes per block, dies with the block | +| `Dimension`, any other block | `proxied` | a world property keyed by the target's identity | | `ItemStack` | **refused** | a detached copy — the write never reaches the world | A host's `caps` say what a collection may [`require`](./targets.md#require): diff --git a/docs/db/targets.md b/docs/db/targets.md index 16ed032..404200f 100644 --- a/docs/db/targets.md +++ b/docs/db/targets.md @@ -27,14 +27,14 @@ type TargetKind = 'world' | 'dimension' | 'entity' | 'block' | 'slot' | 'itemSta |---|---|---| | `World` | the world | ✅ | | `Player`, `Entity` | the entity; dies with it | ✅ | -| `Block` whose type declares `minecraft:block_entity` | the block entity, about 950 bytes per pack; dies with the block | ✅ | +| `Block` whose type declares `minecraft:block_entity` with `dynamic_properties: true` | the block entity, about 950 bytes per pack; dies with the block | ✅ | | `ContainerSlot` holding a non-stackable item | the slot's item | ✅ | | `Dimension` | the world, keyed by the dimension id | ❌ | -| a vanilla block | the world, keyed by dimension and location | ❌ | +| any other block | the world, keyed by dimension and location | ❌ | | `ItemStack` | refused — a detached copy; the write never reaches the world | — | | `ContainerSlot` holding a stackable item | refused — a stackable item cannot hold properties | — | -See the [resolver](./resolver.md) for how the decision is made. +See [Blocks](#blocks) for what a block needs, and the [resolver](./resolver.md) for how the decision is made. ## Acceptors @@ -79,7 +79,7 @@ interface Requirements { } ``` -Only `true` is a demand; an omitted key is indifferent. A target whose host lacks a required capability is refused by `for()` with a reason — a vanilla block under `require: { own: true }` is refused instead of stored on the world. +Only `true` is a demand; an omitted key is indifferent. A target whose host lacks a required capability is refused by `for()` with a reason — a block without dynamic properties under `require: { own: true }` is refused instead of stored on the world. The check also runs in the IDE: a requirement the acceptor's target type can *never* satisfy is a compile error whose missing-property name is the reason. `own` on a `dimensions()` collection and `readableWhenUnloaded` on an `entityTypes()` collection are both type errors. @@ -93,7 +93,15 @@ db.collection('elevators', { ## Blocks -A block document lives on the block entity, so the block's type must declare `minecraft:block_entity` in its JSON. Two more things a block collection needs from the pack: +A block holds its own documents when its type turns dynamic properties on: + +```json +"minecraft:block_entity": { "dynamic_properties": true } +``` + +The resolver probes for the `minecraft:dynamic_properties` component this gives the block, not for the block entity: a block entity without it is stored on the world like any other block. + +Two things a block collection needs from the pack: - **`blockCleanup`** — a custom component to register and list on every accepted block type. Its `onBreak` fires for every removal, `/setblock` and script `setPermutation` included, and is what keeps the [index](./collection.md#all) honest: diff --git a/docs/flexbox/computeLayout.md b/docs/flexbox/computeLayout.md index ec45d23..88cb1e4 100644 --- a/docs/flexbox/computeLayout.md +++ b/docs/flexbox/computeLayout.md @@ -115,7 +115,7 @@ const root = createNode( computeLayout(root); // Absolute child is excluded from flex flow. -// top: 4, right: 4 → x = 320 - 4 - 20 = 296, y = 4 +// top: 4, right: 4 -> x = 320 - 4 - 20 = 296, y = 4 root.children[1].layout // { x: 296, y: 4, width: 20, height: 20 } ``` diff --git a/docs/observable/index.md b/docs/observable/index.md index 9e26d53..39b24b0 100644 --- a/docs/observable/index.md +++ b/docs/observable/index.md @@ -9,8 +9,8 @@ description: "@bedrock-core/observable is the reactive primitive the stack notif `@bedrock-core/observable` is the reactive primitive the stack notifies through: a value with three verbs — `get` / `set` / `subscribe` — the same three a config leaf has, a shared key has, a db document has, and Minecraft's own data-driven UI observables have. -:::caution Pre-1.0 -`@bedrock-core/observable` is under active development. Breaking changes can still land until `1.0.0` — pin exact versions and read the release notes before upgrading. +:::caution Beta +`@bedrock-core/observable` is in beta: the API can change between releases. Pin exact versions and read the changelog before upgrading. ::: ## What is @bedrock-core/observable? diff --git a/docs/observable/observable.md b/docs/observable/observable.md index 12c7c7a..3afc9b1 100644 --- a/docs/observable/observable.md +++ b/docs/observable/observable.md @@ -51,7 +51,7 @@ const phase = observable<'lobby' | 'fight' | 'end'>('lobby'); phase.get(); // 'lobby' const release = phase.subscribe((next, prev) => { - console.warn(`${prev} → ${next}`); + console.warn(`${prev} -> ${next}`); }); phase.set('fight'); // listener runs here, before set returns diff --git a/docs/server/api/announcement.md b/docs/server/api/announcement.md index 27e1bcc..ee885d8 100644 --- a/docs/server/api/announcement.md +++ b/docs/server/api/announcement.md @@ -7,15 +7,18 @@ description: "Announcement is the shape of every cross-addon feed: one owner-wri `Announcement` is the shape of every cross-addon feed the runtime publishes: one small, owner-written value under a framework key on the [mirror](/docs/sync/state), read from every realm's local copy. -`core.translations` extends one, and so do the registries `@bedrock-core/navigation` builds over the same mirror — [`screens(core)` and `pages(core)`](/docs/navigation/references). `core.features.flags`, `core.config.schema`, `core.config.groups` and `core.shared.shape` are fields of one. Wherever you meet the five members below, they mean the same thing. +`core.translations` extends one, and so do the registries `@bedrock-core/navigation` builds over the same mirror — [`screens(core)` and `pages(core)`](/docs/navigation/references). `core.features.flags` and `core.shared.shape` are fields of one. Wherever you meet the five members below, they mean the same thing. ## Import ```ts -import type { Announcement, AnnouncementListener } from '@bedrock-core/server'; +import { Announcement, isRecord } from '@bedrock-core/server'; +import type { AnnouncementListener } from '@bedrock-core/server'; ``` -The runtime constructs every announcement; an addon only reads and writes through them. +The runtime constructs its own — `core.features.flags`, `core.shared.shape` — and so does a package that extends it: `@bedrock-core/navigation` builds `screens(core)` and `pages(core)` the same way, `new Announcement(node.state, addonId, name, guard)`, over a subsystem's own value and a guard for it. An ordinary addon only reads and writes through the announcements it is handed; it does not mint its own. + +`isRecord(value)` is the guard every announcement's own guard starts from — a non-null, non-array object, the envelope shape before checking any field. A [declaration](./runtime.md#writing-one) publishing something of its own composes a stricter guard on top of it. ## Members diff --git a/docs/server/api/authorize.md b/docs/server/api/authorize.md index 9c0d746..a264977 100644 --- a/docs/server/api/authorize.md +++ b/docs/server/api/authorize.md @@ -88,5 +88,4 @@ Whether the player is a world operator. Reads `player.playerPermissionLevel`, wh ## Notes -- Config's own nine `core:config.*` methods call `authorize` with the world, the dimension or the player's entity as the target — see [config authorization](./config.md#authorization). - The rule keys off the **actor**, never the calling pack. Script events carry no sender identity a rule could rest on. diff --git a/docs/server/api/host.md b/docs/server/api/host.md index a9f1853..f57134d 100644 --- a/docs/server/api/host.md +++ b/docs/server/api/host.md @@ -1,139 +1,41 @@ --- sidebar_position: 4 -description: "core.host answers one question: should this realm do the work that exactly one realm may do?" +description: "core.host is an election over the registry that nothing uses today. It is reserved for capabilities: shared state that exactly one addon may run." --- # core.host -`core.host` answers one question: **should this realm do the work that exactly one realm may do?** - -Some jobs cannot be done by every addon at once — rendering a shared config or guide UI is the motivating one. Host election picks a single realm for those, deterministically, with no negotiation messages at all. - -The winner is a pure function of the [registry](./registry.md), so it is expressed as one: `core.host.id` is `computed` over `core.registry.addons` and re-derives itself whenever an addon appears or disappears. +`core.host` picks one realm out of the [registry](./registry.md), deterministically, with no negotiation messages at all. **Nothing in the stack calls it today.** Read it as a mechanism waiting for its first user, not as a description of how anything currently behaves. ## Import ```ts import { core } from '@bedrock-core/server'; -import { HostElection } from '@bedrock-core/server'; -import type { HostListener } from '@bedrock-core/server'; +import type { HostElection, HostListener } from '@bedrock-core/server'; ``` -## Usage - -```ts -if (core.host.isHost) { - renderLocally(player); -} else { - void core.rpc.request(core.host.id.get(), 'core:ui.open', { playerId: player.id }); -} - -core.host.id.subscribe(hostId => console.warn('UI host is now', hostId)); -``` +`HostElection` is the shape of `core.host` itself; `HostListener` is what `subscribe` takes. ## Why it exists -Bedrock's custom-command registry is **world-global** and has no unregister API, so whichever realm loads first *owns* a given command name for the life of the world. That ownership is immovable — who does the **rendering** is not. The election picks the realm running the newest `@bedrock-core/server-runtime`, and the command owner becomes a router: it forwards the request to `core.host.id.get()` instead of rendering locally. +Some state no addon can own alone: an energy grid, a fluid network, a physics world. Two addons that both ship the library must run **one** simulation, not two, and every addon has to see the same state through its own copy of the code. That needs exactly one owner, which is what an election over the registry gives. Until such a capability exists, the mechanism has no caller. -The practical consequence: **installing one up-to-date bedrock-core addon upgrades the shared UI for every addon in the world**, including ones whose authors never shipped again. +The UI does not need it. A screen is drawn by the addon whose pack holds it, and a request for it crosses to that realm over its own show method, so no realm has to be chosen for everyone. ## The rule -1. Highest `runtimeVersion` wins — that is [`RUNTIME_VERSION`](./runtime.md#runtime_version), the version of `@bedrock-core/server-runtime` each addon was built against, **not** the addon's own `version`. +1. Highest `runtimeVersion` wins, the version of `@bedrock-core/server-runtime` each addon was built against, which is [`RUNTIME_VERSION`](./runtime.md#runtime_version), **not** the addon's own `version`. 2. Ties are broken by the **lowest namespace**, compared as a plain string. -Every realm sees the same [registry](./registry.md) and applies the same rule, so they all agree on the same winner without exchanging a single message. - -The election re-runs whenever a peer appears or disappears. - -:::note Peers with no announced runtime version -A peer whose `meta` carries no usable `runtimeVersion` is treated as `0.0.0`. It loses the election instead of corrupting it. -::: +Every realm sees the same registry and applies the same rule, so they all agree on the same winner without exchanging a single message. The winner is `computed` over `core.registry.addons` and re-derives itself whenever an addon appears or disappears. A peer whose `meta` carries no usable `runtimeVersion` is treated as `0.0.0`, so it loses rather than corrupting the election. ## API -### `isHost` - -```ts -core.host.isHost: boolean -``` - -Whether this realm is the current host and should do the work itself. - -### `id` - -```ts -core.host.id: ReadonlyObservable -``` - -Namespace of the realm running the newest runtime, as an observable. Falls back to this addon's own id when the registry is somehow empty, so callers always have a target to address. - -```ts -core.host.id.get(); // who hosts right now -effect(() => refreshBanner(core.host.id.get()), [core.host.id]); -``` - -### `host` - ```ts -core.host.host: RegisteredAddon | undefined +core.host.isHost: boolean // whether this realm won +core.host.id: ReadonlyObservable // the winner's namespace, as an observable +core.host.host: RegisteredAddon | undefined // the winner's registry entry, while present +core.host.subscribe(listener): Unsubscribe // told when the winner moves ``` -The elected host's [registry entry](./registry.md#registeredaddon), when it is still present. - -### `subscribe` - -```ts -core.host.subscribe(listener: HostListener): Unsubscribe - -type HostListener = (hostId: string, previousHostId: string) => void; -``` - -Notified when hosting **moves** — shorthand for `core.host.id.subscribe(...)`. Fires only on an actual change; subscribing does not deliver the current host, which `core.host.id` already has. Returns an unsubscribe function. - -```ts -core.host.subscribe((hostId, previousHostId) => { - if (hostId === core.id) { - console.warn(`[economy] took over hosting from ${previousHostId}`); - } -}); -``` - -## The router pattern - -The shape this is built for: whichever realm receives a player-facing command does the smallest possible slice of work — identify the player, name the request, forward the raw arguments — and everything that involves a decision happens on the host. - -```ts -// In the realm whose command was typed: -function dispatch(player: Player, command: string, args: (string | undefined)[]): void { - if (core.host.isHost) { - open(player, command, args); - - return; - } - - void core.rpc.request(core.host.id.get(), 'core:ui.open', { - playerId: player.id, - command, - args, - }).catch((error: unknown) => console.warn(`[ui] host refused: ${String(error)}`)); -} - -// Every realm serves the handler, because any of them may win the election later: -core.rpc.onRequest('core:ui.open', (params) => { - const { playerId, command, args } = params as { playerId: string; command: string; args: (string | undefined)[] }; - const player = world.getAllPlayers().find(candidate => candidate.id === playerId); - - if (!player) { throw new Error(`core:ui.open: player '${playerId}' is not in the world`); } - - open(player, command, args); - - return true; -}); -``` - -:::tip Serve the handler everywhere, not just on the host -Hosting can move at any time — a newer addon loads, the current host's pack is removed. Every realm that participates should register the handler at startup so it is ready if it wins later. -::: - -This is exactly how [`@bedrock-core/config`](../guides/ui-integration.md) mounts the shared config and guide UI. +`id` falls back to this addon's own namespace when the registry is somehow empty, so a caller always has a target. `subscribe` fires only on an actual change and does not deliver the current winner, which `id` already has. diff --git a/docs/server/api/registry.md b/docs/server/api/registry.md index cadf13d..8e71eaa 100644 --- a/docs/server/api/registry.md +++ b/docs/server/api/registry.md @@ -46,10 +46,10 @@ Every entry carries the full manifest plus three fields the registry adds: |---|---| | `id` | The namespace, `creator_pack`. The key everything else uses. | | `self` | `true` for the local addon, `false` for a peer. | -| `runtimeVersion` | The `@bedrock-core/server-runtime` version that addon was built against — **not** its own `version`. This is what the [host election](./host.md) compares. | +| `runtimeVersion` | The `@bedrock-core/server-runtime` version that addon was built against — **not** its own `version`. This is what [`core.host`](./host.md) compares. | :::note Peers can be partially known -A peer's manifest is reconstructed from its discovery `meta`. A node that published no meta keeps its whole namespace as `pack` and an empty string as `creator` — the id is never split back into halves. `runtimeVersion` defaults to `0.0.0` when absent or malformed, so that peer loses the host election rather than corrupting it. +A peer's manifest is reconstructed from its discovery `meta`. A node that published no meta keeps its whole namespace as `pack` and an empty string as `creator` — the id is never split back into halves. `runtimeVersion` defaults to `0.0.0` when absent or malformed, so that peer loses an election rather than corrupting it. ::: ## API @@ -166,7 +166,7 @@ interface IncompatiblePeer { Addons heard on the bus that this build cannot talk to, because the [protocol ranges](/docs/sync/discovery#protocol-negotiation) the two were built with do not overlap. They are present in the world but absent from [`all()`](#all): without a conversation there is no manifest to read. -They are listed rather than ignored because the alternative is worse than an error. An addon that cannot be reached, silently left out, looks exactly like an addon that was never installed — the addon list is confidently wrong instead of visibly incomplete. +They are listed rather than ignored because the alternative is worse than an error. An addon that cannot be reached, silently left out, looks exactly like an addon that was never installed — the catalog is confidently wrong instead of visibly incomplete. ### `onIncompatible` diff --git a/docs/server/api/runtime.md b/docs/server/api/runtime.md index 677ae4d..9487b8d 100644 --- a/docs/server/api/runtime.md +++ b/docs/server/api/runtime.md @@ -5,7 +5,7 @@ description: "@bedrock-core/server-runtime is the framework layer addons build o # core -`@bedrock-core/server-runtime` is the framework layer addons build on. Where [`@bedrock-core/sync`](/docs/sync) is the low-level transport, the runtime is the thing you **register into**: an addon declares its identity and its data once, and that declaration flows into a cross-addon registry — a live directory of every bedrock-core addon present in the world. +`@bedrock-core/server-runtime` is the framework layer addons build on. Where [`@bedrock-core/sync`](/docs/sync) is the low-level transport, the runtime is the thing you **register into**: an addon declares its identity and everything it installs once, and that declaration flows into a cross-addon registry — a live directory of every bedrock-core addon present in the world. ## Install @@ -38,36 +38,42 @@ Every accessor below throws `runtime. is unavailable: call register() firs | `core.manifest` | `AddonManifest` | The validated manifest, identity fields only. | | `core.registry` | [`Registry`](./registry.md) | The cross-addon directory. | | `core.features` | [`FeatureManager`](./features.md) | Condition-driven togglable behavior. | -| `core.host` | [`HostElection`](./host.md) | Which realm does the work only one realm may do. | | `core.shared` | [`SharedRegistry`](./shared.md) | The replicated mirror as typed trees: `of(ns)` for a peer's, `own` for this addon's. | | `core.events` | [`EventsRegistry`](./events.md) | Broadcasts delivered and forgotten: `of(ns)` for a peer's, `own` for this addon's. | | `core.db` | [`Db`](./db.md) | This addon's persisted documents, keyed by target. | -| `core.config` | [`ConfigRegistry`](./config.md) | Schema, scopes and cross-addon config access. | | `core.translations` | [`TranslationsRegistry`](./translations.md) | Cross-addon i18n bundles, with resolvers over all of them. | +| `core.slot(key)`, `core.fill(key, value)` | [`RuntimeSlots`](#slots) | Where a package above the runtime parks its subsystem, keyed `namespace:name`. | +| `core.host` | [`HostElection`](./host.md) | Reserved for capabilities. Nothing elects today. | | `core.rpc` | `Rpc` | [RPC](/docs/sync/rpc), passed through from the sync node. | | `core.node` | `SyncNode` | The raw [sync node](/docs/sync) — bus, discovery, the mirror, events. | +Settings are not a member. They are a package above the runtime, reached through `configOf(core)` from `@bedrock-core/config/server`; see [the settings subsystem](/docs/config/settings). + ## `register()` ```ts -register(options: RegisterOptions): Registered // { config?, shared?, events? } — one key per declaration +register(options: O): Declared ``` -Declare the addon and bring it online. **Call exactly once — there is no separate `start()`.** It throws on an invalid manifest and on a second call. +Declare the addon and bring it online. **Call exactly once, at the top of the entry module, and nothing else runs after it.** It throws on an invalid manifest and on a second call. -`RegisterOptions` is a `manifest` (the [manifest fields](#manifest-fields)) plus the optional declarations beside it. Each declaration is exactly equivalent to the standalone call listed beside it, which stays available for publishing late or replacing data at runtime: +`RegisterOptions` is a `manifest` (the [manifest fields](#manifest-fields)) plus any number of **declarations** beside it. A declaration is a value with an `install(core)` method. `register()` installs each one in the order its key was written, on the already-live runtime, and hands what `install` returned back under the same key. The runtime never knows what a declaration builds, which is what lets a package above it add a field and have its own types come back typed. -| Field | Type | Equivalent to | +| Field | Declaration | From | |---|---|---| -| `config` | `ConfigDefinition` | [`core.config.define()`](./config.md#define) | -| `shared` | `SharedDef` | [`core.shared.define()`](./shared.md) | -| `events` | `EventsDef` | [`core.events.define()`](./events.md) | +| `shared` | [`registerShared(keys)`](./shared.md) | `@bedrock-core/server` | +| `events` | [`registerEvents(tree)`](./events.md) | `@bedrock-core/server` | +| `config` | [`registerConfig(definition)`](/docs/config) | `@bedrock-core/config` | +| `catalog` | [`registerCatalog()`](/docs/catalog) | `@bedrock-core/catalog` | +| `guides` | [`registerGuides()`](/docs/guides) | `@bedrock-core/guides` | -`register()` returns the typed accessors of what was declared, one key each: `config` (the scope accessors, the same value [`core.config.define()`](./config.md#define) returns), [`shared`](./shared.md) (the tree) and [`events`](./events.md) (the tree). Each key is present only when its declaration was given. +`Declared` is the result: one key per declaration in the bag, typed by what its `install` returns. Destructure it. ```ts -import { core } from '@bedrock-core/server'; -import bundle from '@bedrock-core/generated/i18n'; +import { core, registerEvents, registerShared } from '@bedrock-core/server'; +import { registerCatalog } from '@bedrock-core/catalog'; +import { registerConfig } from '@bedrock-core/config'; +import { registerGuides } from '@bedrock-core/guides'; import { configDef, sharedDef, eventsDef } from './example'; const { config, shared, events } = core.register({ @@ -83,18 +89,75 @@ const { config, shared, events } = core.register({ icon: 'textures/ui/economy/icon', thumbnail: 'textures/ui/economy/thumbnail', }, - config: configDef, - shared: sharedDef, - events: eventsDef, + catalog: registerCatalog(), + config: registerConfig(configDef), + guides: registerGuides(), + shared: registerShared(sharedDef), + events: registerEvents(eventsDef), }); -core.translations.provide(bundle); - config.server.get(); // fully typed shared.currency.set('gold'); events.purchase.emit({ playerId: player.id, gold: 5 }); ``` +A field takes arguments only for what the build cannot know. `registerGuides()` takes none, because the guides filter already compiled the pages. `registerConfig(definition)` takes the definition because the definition *is* the declaration, and the ui-compiler filter reads it out of this very call to shape one screen per section. + +### What a declaration may do + +`register()` runs at script load, so an `install` runs synchronously inside it, on a live runtime: the node, the registry, features and translations are started and the db is usable. Within that, an install may: + +1. Fill one [slot](#slots) and read any other. +2. Serve RPC methods, announce a value on the mirror, read the registry, and store through `core.db`. +3. Subscribe to `system.beforeEvents.startup`. Custom commands can only be registered there, and startup fires after every module has loaded, so a subscription made during `register()` is early enough. + +Two rules keep declarations independent of each other: + +- **Anything read off the build is published on the first tick, never synchronously.** Compiled screens, a page, a guide manifest: the generated modules that hold them are evaluated before `register()` runs today, and deferring to the first tick makes the import order irrelevant. +- **Knowledge of another field is read at use, through its slot, never at install.** An install cannot see a field written after it, and a slot read when a screen opens always can. There is no second install pass. + +`stop?()` runs in reverse install order when the runtime stops. There are no other hooks. + +### Writing one + +```ts +import type { Declaration, Runtime } from '@bedrock-core/server'; + +declare module '@bedrock-core/server-runtime' { + interface RuntimeSlots { 'acme:widgets': WidgetRegistry } +} + +export function registerWidgets(definition: WidgetDefinition): Declaration { + let registry: WidgetRegistry | undefined; + + return { + install(core: Runtime): Widgets { + registry = new WidgetRegistry(core.node, core.namespace); + core.fill('acme:widgets', registry); + + return registry.define(definition); + }, + stop(): void { + registry?.stop(); + }, + }; +} +``` + +The factory is named `registerWidgets` rather than `widgets` so the accessor can keep the plain name: `const { widgets } = core.register({ manifest, widgets: registerWidgets(definition) })`. + +## Slots + +The runtime cannot construct a subsystem that lives above it, so it offers a named slot instead: `core.fill(key, value)` parks one, `core.slot(key)` hands it back. `RuntimeSlots` is empty here and filled in by module augmentation from the package that owns each subsystem, so the runtime never imports what it holds. + +```ts +declare module '@bedrock-core/server-runtime' { + interface RuntimeSlots { 'core:config': ConfigRegistry } +} +``` + +A key is namespaced the way a feed or an RPC method is, so two packages never collide. `fill` throws on a second fill of one key. A declaration fills its slot from `install`, and the owning package exports one reader, `configOf(core)` for config, which decides for itself what an unfilled slot means: only that package knows whether absence is an error or the ordinary state of an addon that declared nothing. + ## Manifest fields ```ts @@ -122,12 +185,12 @@ interface AddonManifest { | `description` | — | Short description. | | `dependencies` | — | Namespaces (`creator_pack`) this addon needs. **Soft** — a missing one logs and fires an event, it never blocks. | | `optionalDependencies` | — | Namespaces that unlock optional [features](./features.md) when present. | -| `icon` | — | Resource-pack texture path for a registry UI icon, e.g. `textures/ui/my_addon_logo`. | -| `thumbnail` | — | Resource-pack texture path for a 16:9 banner. | +| `icon` | — | Resource-pack texture path for the catalog icon, e.g. `textures/ui/my_addon_logo`. | +| `thumbnail` | — | Resource-pack texture path for a 16:9 banner on the addon's page. | ### Display fields are translation keys -`packName`, `creatorName` and `description` are assumed to be Minecraft translation keys shipped in the addon's resource pack `.lang`, so a registry UI can render them in each player's language. Plain text still works — Bedrock falls back to the literal string when no `.lang` entry matches. +`packName`, `creatorName` and `description` are assumed to be Minecraft translation keys shipped in the addon's resource pack `.lang`, so a catalog can render them in each player's language. Plain text still works — Bedrock falls back to the literal string when no `.lang` entry matches. ```ts import { createI18n } from '@bedrock-core/i18n'; @@ -145,10 +208,10 @@ core.register({ version: '1.0.0', }, }); - -core.translations.provide(bundle); ``` +The bundle travels on its own. `register()` publishes the bundle the addon's default `createI18n` instance was created with on the first tick, through [`core.translations`](./translations.md), so an addon that draws nothing still has its name resolved by whatever realm lists it. + ### Validation `register()` validates the manifest and throws a descriptive error rather than letting a misconfigured addon misbehave silently: @@ -166,7 +229,7 @@ core.translations.provide(bundle); core.stop(); ``` -Take the addon offline and clear every accessor. Safe to call before registering (no-op). Mostly useful in GameTests — a shipped addon registers and stays up. +Take the addon offline and clear every accessor. Every declaration's `stop` runs first, in reverse install order. Safe to call before registering (no-op). Mostly useful in GameTests — a shipped addon registers and stays up. ## Several runtimes in one realm @@ -214,7 +277,35 @@ Use `core` — the singleton — in a real addon. One identity per pack. import { RUNTIME_VERSION } from '@bedrock-core/server'; ``` -The version of `@bedrock-core/server-runtime` this build was compiled against. It is stamped into the discovery `meta` blob automatically, surfaces on every registry entry as `runtimeVersion`, and is what the [host election](./host.md) compares. It is generated at release time; addons never set it. +The version of `@bedrock-core/server-runtime` this build was compiled against. It is stamped into the discovery `meta` blob automatically and surfaces on every registry entry as `runtimeVersion`. It is generated at release time; addons never set it. + +## `isUsable` + +```ts +import { isUsable, type EngineHandle } from '@bedrock-core/server'; + +function isUsable(handle: T | null | undefined): handle is T + +interface EngineHandle { readonly isValid?: boolean } +``` + +Whether an engine handle can still be touched — `Entity`, `Player`, `Block`, `Camera`, `Component`, `Container`, `ContainerSlot`, `Effect` and the rest of what exposes a readonly `isValid`. It goes false once the thing the handle points at is gone — despawned, disconnected, moved into an unloaded chunk — and every other member throws from then on. `isUsable` is `false` for `null`/`undefined` and for such a handle, `true` for everything else, including a plain object that carries no `isValid` at all. + +Reach for it on a handle that outlives the moment it was obtained: one kept in a map, or one an `afterEvents` subscriber receives, which by definition runs after the fact. A throw from inside a subscriber is never caught by the caller — the engine catches it and logs it against the *pack's* name — so a library depending on this runtime that let one through would have the error attributed to itself. + +```ts +const tracked = new Map(); + +world.afterEvents.playerSpawn.subscribe(({ player }) => { tracked.set(player.id, player); }); + +function messageIfPresent(playerId: string, text: string): void { + const player = tracked.get(playerId); + + if (isUsable(player)) { player.sendMessage(text); } +} +``` + +`Entity.id` is the documented exception: it stays readable once `isValid` is false, so id-keyed bookkeeping still works for a handle that has gone stale — it is any other member that throws. ## In this section @@ -222,11 +313,10 @@ The version of `@bedrock-core/server-runtime` this build was compiled against. I |---|---| | [`core.registry`](./registry.md) | Enumerate peers, resolve dependencies, detect namespace collisions | | [`core.features`](./features.md) | Behavior that toggles on a condition over the registry and the mirror | -| [`core.host`](./host.md) | Deterministic "who does the shared work" | | [`core.shared`](./shared.md) | The replicated mirror as typed trees, one value per key, owner-only writes | | [`core.events`](./events.md) | Broadcasts delivered and forgotten | | [`core.db`](./db.md) | Persisted documents keyed by target | -| [`core.config`](./config.md) | Schema, three scopes, persistence, cross-addon access, authorization | | [`core.translations`](./translations.md) | Announce and resolve i18n bundles across addons | +| [`core.host`](./host.md) | Reserved for capabilities | | [`Announcement`](./announcement.md) | The shape every cross-addon feed shares | | [`authorize`](./authorize.md) | The one rule a handler applies on behalf of a player | diff --git a/docs/server/api/shared.md b/docs/server/api/shared.md index 938bf15..4311a74 100644 --- a/docs/server/api/shared.md +++ b/docs/server/api/shared.md @@ -41,7 +41,7 @@ const { shared } = core.register({ }); ``` -`register()` returns the typed accessors of what was declared, one key each: `config` (the scope accessors, the same value `core.config.define()` returns) and `shared` (the tree). +`register()` returns the typed accessors of what was declared, one key each: `config` (the scope accessors `registerConfig(definition)` installs) and `shared` (the tree). A key may not begin `core-`, which is the framework's own announcement prefix; `register()` throws if one does. @@ -79,10 +79,10 @@ import type { EconomyShared } from '@drav0011/economy-types'; const economy = core.shared.of('drav0011_economy'); // undefined until the peer has registered economy?.currency.get(); // string | undefined -economy?.event.subscribe(event => …); +economy?.event.subscribe(event => ...); ``` -`of()` materializes the tree from the key names the owner announced under `core-shared/shape` when it registered; the type argument is the compile-time view over it, the same arrangement as `core.config.of()`. A peer's key reads `undefined` while its value has not arrived — a peer never knows what the owner declared — and a peer's tree has no `set` at all, in the type and at runtime. +`of()` materializes the tree from the key names the owner announced under `core-shared/shape` when it registered; the type argument is the compile-time view over it. A peer's key reads `undefined` while its value has not arrived — a peer never knows what the owner declared — and a peer's tree has no `set` at all, in the type and at runtime. Peers that only have the namespace, not the type, still get an untyped tree from `core.shared.of(ns)`. @@ -110,7 +110,6 @@ Your namespace carries more than you put there. The framework replicates its own | Key | Written by | |---|---| -| `core-config/schema`, `core-config/groups` | [`core.config`](./config.md) — the announced config schema | | `core-i18n/bundle` | [`core.translations`](./translations.md) — this addon's i18n bundle | | `core-ui/reference` | [`screens(core)`](/docs/navigation/references) — this addon's compiled screens, as references | | `core-addon/page` | [`pages(core)`](/docs/navigation/references) — the addon's page in the shared list | @@ -120,5 +119,5 @@ Your namespace carries more than you put there. The framework replicates its own Each is an [`Announcement`](./announcement.md). The shared tree never sees them; to reach the raw namespace, framework keys included, use `core.node.state`: ```ts -core.node.state.get(core.id, 'core-config/schema'); +core.node.state.get(core.id, 'core-feature/flags'); ``` diff --git a/docs/server/api/translations.md b/docs/server/api/translations.md index e4fc24e..4155158 100644 --- a/docs/server/api/translations.md +++ b/docs/server/api/translations.md @@ -25,14 +25,13 @@ import type { I18nBundle, TranslationResolver } from '@bedrock-core/server'; ```ts import bundle from '@bedrock-core/generated/i18n'; -core.translations.provide(bundle); // publish up front -core.translations.provide(bundle); // or publish/replace later +core.translations.provide(bundle); // replace what register() published, or publish another core.translations.of('drav0011_shop'); // another addon's bundle core.translations.i18n('drav0011_shop'); // verbs over it: t(), key(), raw(), resolve() core.translations.forPlayer(player); // chained resolver for that player's locale core.translations.forLocale('en_US'); // chained resolver for one locale -core.translations.subscribe((namespace) => { … }); // an addon re-published +core.translations.subscribe((namespace) => { ... }); // an addon re-published ``` ## What travels @@ -40,7 +39,7 @@ core.translations.subscribe((namespace) => { … }); // an addon re-published The bundle itself — the module the [i18n filter](/docs/filters/i18n) generates (`@bedrock-core/generated/i18n`), or `createResourceBundle`'s runtime equivalent. Templates stay in `{{var}}` form with their recorded argument order. ``` - → core-i18n/bundle → I18nBundle + -> core-i18n/bundle -> I18nBundle ``` A payload that fails structural validation reads as no bundle rather than replacing a good one. @@ -53,7 +52,7 @@ A payload that fails structural validation reads as no bundle rather than replac core.translations.provide(bundle: I18nBundle): void ``` -Publish this addon's bundle. Usually declared up front through `register({ translations })`; call this directly to publish late or to replace the bundle at runtime. +Publish this addon's bundle. `register()` does this for you on the first tick, with the bundle your default `createI18n` instance was created with, so an addon that draws nothing still has its display keys resolved everywhere. Call it directly to publish a different bundle or to replace it at runtime. ### `of` diff --git a/docs/server/guides/channels.md b/docs/server/guides/channels.md index 79330ca..ad71f58 100644 --- a/docs/server/guides/channels.md +++ b/docs/server/guides/channels.md @@ -25,7 +25,7 @@ A value only some peers want, some of the time, is an RPC answer, not a shared k ## What stays local -[`core.db`](../api/db.md) is local. A collection is this addon's; nothing in it is served, announced or mirrored by default. The same holds for config values: the schema is announced so a UI can build a form, but the values are fetched over the nine `core:config.*` methods the runtime serves, with the acting player checked on each. +[`core.db`](../api/db.md) is local. A collection is this addon's; nothing in it is served, announced or mirrored by default. The same holds for [config](/docs/config/settings): its schema and values stay with the addon that declares them. That is deliberate. Storage and exposure are different decisions, and an addon that persists a document has not said anything about who may read it. @@ -60,7 +60,7 @@ core.rpc.serve({ }); ``` -Config peers are not told when a value changes. An owner that wants them told does the same: mirrors the value on a shared key, or emits an event. +A config setting is shared the same way: the owner mirrors it on a shared key, emits an event when it changes, or serves it. ## Reading from the other side @@ -79,11 +79,11 @@ Each read is typed by what the owner exports — `typeof sharedDef`, `typeof eve ## Where each value can be seen -| Place | Owner | Survives restart | Peers see it | Authoritative | +| Place | Owner | Survives restart | Peers see it by default | Authoritative | |---|---|---|---|---| | an observable | this addon | no | no | yes, for what it holds | -| a db document | this addon | yes | through an RPC method | yes | -| the config accessor tree | this addon | yes | through the config methods | yes | +| a db document | this addon | yes | no | yes | +| the config accessor tree | this addon | yes | no | yes | | a shared key, own namespace | this addon | no — map a document onto it | yes, from their mirror | yes | | a shared key, a peer's namespace | the peer | no | — | no: a copy; writes are dropped | | an event | the sender | no | once, if listening | — | diff --git a/docs/server/index.md b/docs/server/index.md index b607216..ac42355 100644 --- a/docs/server/index.md +++ b/docs/server/index.md @@ -9,8 +9,8 @@ description: "Get two Minecraft addons talking to each other." Get two Minecraft addons talking to each other. -:::caution Pre-1.0 -The `@bedrock-core` server packages are under active development. Breaking changes can still land until `1.0.0` — pin exact versions and read the release notes before upgrading. +:::caution Beta +`@bedrock-core/server` is in beta: the API can change between releases. Pin exact versions and read the changelog before upgrading. ::: ## What is @bedrock-core/server? @@ -34,7 +34,7 @@ None of them imported each other. They found each other at runtime. That is the answer for an addon. It is a meta package that pins a matching set of the stack and re-exports everything, so `import { core } from '@bedrock-core/server'` is all you need. Each package underneath stays reachable at its own subpath — `/sync`, `/db`, `/observable` — for when you reach past `core` to the thing itself. -The packages underneath are strictly layered and installable on their own if you are building a framework layer of your own: [`@bedrock-core/server-runtime`](./api/runtime.md) (registry, features, config, shared, events, guides, translations, host election), [`@bedrock-core/sync`](/docs/sync) (bus, discovery, RPC, the mirror, events), [`@bedrock-core/db`](/docs/db) (persisted documents) and [`@bedrock-core/observable`](/docs/observable) (the reactive primitive every accessor is). +The packages underneath are strictly layered and installable on their own if you are building a framework layer of your own: [`@bedrock-core/server-runtime`](./api/runtime.md) (registry, features, shared, events, db, translations, slots), [`@bedrock-core/sync`](/docs/sync) (bus, discovery, RPC, the mirror, events), [`@bedrock-core/db`](/docs/db) (persisted documents) and [`@bedrock-core/observable`](/docs/observable) (the reactive primitive every accessor is). ## What you get @@ -43,7 +43,6 @@ The packages underneath are strictly layered and installable on their own if you - **[Shared](./api/shared.md)** — a flat shape every realm mirrors locally, one observable per key. Reads are synchronous; writes broadcast a delta; only the owner writes. - **[Events](./api/events.md)** — a broadcast delivered and forgotten, typed by its payload, so a peer hears that something happened without polling for it. - **[Db](./api/db.md)** — persisted documents keyed by target, on whatever dynamic properties the target itself can hold, with versions and lazy migrations. Local: a peer reaches one only through a method you wrote. -- **[Config](./api/config.md)** — a declarative schema in three scopes (server, dimension, player), stored as documents and editable in game. - **[Features](./api/features.md)** — behavior that auto-enables when a condition over the registry becomes true, and auto-disables when it stops being true. - **[Translations](./api/translations.md)** — announce your i18n bundle so any addon's UI can resolve and measure your strings. Your screens and your list page are announced by [`@bedrock-core/navigation`](/docs/navigation/references). - **[Host election](./api/host.md)** — a deterministic rule for "which realm does the work only one realm may do". @@ -53,6 +52,5 @@ The packages underneath are strictly layered and installable on their own if you - [Installation](./installation.md) — scaffold with the CLI, or install and register by hand - [Sharing data between addons](./guides/channels.md) — which of shared, events and RPC carries what, and what stays local - [Trust model](./guides/trust-model.md) — what the framework defends against, and what it cannot -- [`core`](./api/runtime.md) — the runtime reference: registry, features, host, shared, events, db, config +- [`core`](./api/runtime.md) — the runtime reference: `register()`, declarations, slots, registry, features, shared, events, db - [sync](/docs/sync) — the transport reference: nodes, discovery, RPC, the mirror, events -- [UI integration](./guides/ui-integration.md) — how config, translations and guides feed the UI packages diff --git a/docs/server/installation.md b/docs/server/installation.md index d729ec4..d8da343 100644 --- a/docs/server/installation.md +++ b/docs/server/installation.md @@ -31,6 +31,7 @@ import { core } from '@bedrock-core/server'; // the runtime import { computed } from '@bedrock-core/server/observable'; // the reactive primitive import { createEngineDb } from '@bedrock-core/server/db'; // documents beyond core.db, rarely needed import { createSync } from '@bedrock-core/server/sync'; // the raw transport, rarely needed +import { createI18n } from '@bedrock-core/server/i18n'; // typed translations ``` :::info The packages ship TypeScript sources @@ -66,9 +67,9 @@ Calling `register()` a second time on the same runtime throws. So does an invali ``` `${creator}_${pack}` - creator: 'test', pack: 'demo_a' → test_demo_a - creator: 'drav0011', pack: 'economy' → drav0011_economy - creator: 'bt', pack: 'gc_graves' → bt_gc_graves + creator: 'test', pack: 'demo_a' -> test_demo_a + creator: 'drav0011', pack: 'economy' -> drav0011_economy + creator: 'bt', pack: 'gc_graves' -> bt_gc_graves ``` :::caution The id is `creator_pack`, never `creator:pack` @@ -108,7 +109,7 @@ const configDef = { server: { economy: { startingBalance: { type: 'number', default: 100, min: 0, max: 10000, step: 1, label: 'Starting Balance' }, - currency: { type: 'enum', default: 'emerald', options: ['emerald', 'gold', 'diamond'], label: 'Currency' }, + currency: { type: 'select', default: 'emerald', options: ['emerald', 'gold', 'diamond'], label: 'Currency' }, }, }, player: { @@ -145,7 +146,7 @@ core.rpc.serve({ // Every scope is a dotted tree mirroring the schema — walk to the node and subscribe. config.server.economy.currency.subscribe((next, prev) => { - console.warn(`currency: ${String(prev)} → ${next}`); + console.warn(`currency: ${String(prev)} -> ${next}`); }); world.afterEvents.playerSpawn.subscribe(({ player, initialSpawn }) => { @@ -214,7 +215,5 @@ Addons load in undefined order and messages flush over ticks, so you will never - [`core`](./api/runtime.md) — the full runtime reference - [Sharing data between addons](./guides/channels.md) — which of shared, events and RPC carries what -- [`core.config`](./api/config.md) — schema types, scopes, cross-addon access and authorization - [`core.registry`](./api/registry.md) — enumerating peers, dependencies and collisions - [sync](/docs/sync) — the transport underneath, when you need it directly -- [UI integration](./guides/ui-integration.md) — turning your schema and guides into player-facing screens diff --git a/docs/sync/discovery.md b/docs/sync/discovery.md index c7fd28a..5e2bc2a 100644 --- a/docs/sync/discovery.md +++ b/docs/sync/discovery.md @@ -17,6 +17,12 @@ Who is present is a **value**, not a stream: `peers` is a [`ReadonlyObservable`] import type { PeerInfo, CollisionInfo, IncompatiblePeer, PeerListener, CollisionListener, IncompatibleListener, DiscoveryOptions } from '@bedrock-core/sync'; ``` +`negotiateProtocol` and `capsFor` are the standalone functions behind [protocol negotiation](#protocol-negotiation) below; `SELF_CAPS` is what this build broadcasts: + +```ts +import { capsFor, negotiateProtocol, SELF_CAPS } from '@bedrock-core/sync'; +``` + ## Usage ```ts @@ -59,7 +65,13 @@ Liveness is deliberately **not** a field here. A tick that moves on every heartb ## Protocol negotiation -Discovery is also where two nodes agree on what to speak. Every announce carries the range its sender supports, and hearing one settles the pair on the newest version both know: +Discovery is also where two nodes agree on what to speak. Every announce carries the range its sender supports, and hearing one settles the pair on the newest version both know, through the standalone function the bus calls for every peer: + +```ts +function negotiateProtocol(theirMin: number | undefined, theirMax: number | undefined): number | undefined +``` + +`undefined` when the ranges do not overlap at all. Otherwise: ```ts agreed = min(PROTOCOL_MAX, theirMax) // valid while agreed >= max(PROTOCOL_MIN, theirMin) @@ -75,9 +87,17 @@ An announce with no range at all comes from a node built before the field existe ```ts Cap.Batch // 'batch' — reads several envelopes packed into one message + +SELF_CAPS: readonly Cap[] // everything this build can read; broadcast in every announce +``` + +A capability is always narrowed by the negotiated version, through `capsFor`: + +```ts +function capsFor(protocol: number, advertised: readonly string[] | undefined): readonly string[] ``` -A capability is always narrowed by the negotiated version: one advertised by a node that also speaks something newer is still out of reach at the version actually in use. +One advertised by a node that also speaks something newer is still out of reach at the version actually in use — `capsFor` is what applies that narrowing when a peer's announce carries no `caps` at all, on any protocol that implies `Cap.Batch` by version alone. ## API diff --git a/docs/sync/index.md b/docs/sync/index.md index e669fbb..5f71a2b 100644 --- a/docs/sync/index.md +++ b/docs/sync/index.md @@ -10,7 +10,7 @@ description: "@bedrock-core/sync is the low-level cross-addon transport for Mine `@bedrock-core/sync` is the low-level cross-addon transport for Minecraft Bedrock. It layers a message bus, peer discovery, RPC, a replicated state mirror and a broadcast channel on top of script events, so addons in separate script realms can talk. :::warning For framework and library developers -If you are building a Bedrock addon, you do not need this package directly — use [`@bedrock-core/server-runtime`](/docs/server/api/runtime) instead. The runtime creates and manages the one sync node for you, and raw transport access is available as `core.node` whenever you want it. +If you are building a Bedrock addon, you do not need this package directly — use [`@bedrock-core/server`](/docs/server/api/runtime) instead. The runtime creates and manages the one sync node for you, and raw transport access is available as `core.node` whenever you want it. ::: ## Install @@ -64,8 +64,6 @@ interface SyncNodeOptions { version?: string; schemaVersion?: number; meta?: Record; - ownedNamespaces?: string[]; - strictOwnership?: boolean; maxMessage?: number; instanceId?: string; } @@ -73,12 +71,10 @@ interface SyncNodeOptions { | Option | Default | What it does | |---|---|---| -| `id` | — | Unique addon id. Used as the envelope `src`, the RPC address, and the default owned namespace. | +| `id` | — | Unique addon id. Used as the envelope `src`, the RPC address, and the one namespace this node writes. | | `version` | `'0.0.0'` | Announced to peers as `PeerInfo.version`. | | `schemaVersion` | `0` | Announced alongside `version`, for higher layers that version their payloads. | | `meta` | — | Opaque metadata broadcast with every announce; surfaces on peers as `PeerInfo.meta`. `server-runtime` puts the addon manifest here. | -| `ownedNamespaces` | `[id]` | Namespaces this node is authoritative for — the ones it answers snapshot requests for. | -| `strictOwnership` | `false` | When `true`, `state.set()` / `state.delete()` throw for a namespace this node does not own. See [ownership](./state.md#ownership-and-strictownership). | | `maxMessage` | `2000` | Character budget for one script-event message — what the [chunker](./protocol.md#framing-and-chunking) splits against and what a batch is packed up to. Mainly for tests. | | `instanceId` | generated | Overrides the auto-generated instance id. Mainly for tests. | @@ -111,10 +107,6 @@ class SyncNode { ## In this section -:::caution Pre-1.0 -`@bedrock-core/sync` is under active development. Breaking changes can still land until `1.0.0` — pin exact versions and read the release notes before upgrading. -::: - | Page | Description | |---|---| | [Discovery](./discovery.md) | Finding peers: announce, whois, TTL eviction, namespace collisions | diff --git a/docs/sync/protocol.md b/docs/sync/protocol.md index c7baf94..15cb3e3 100644 --- a/docs/sync/protocol.md +++ b/docs/sync/protocol.md @@ -10,10 +10,12 @@ What actually goes over the wire: the bus, the envelope, framing and rate limiti ## Import ```ts -import { Bus, Cap, MAX_MESSAGE, MessageType, PROTOCOL_MAX, PROTOCOL_MIN } from '@bedrock-core/sync'; +import { Bus, Cap, MAX_MESSAGE, MessageType, PROTOCOL_MAX, PROTOCOL_MIN, SELF_CAPS } from '@bedrock-core/sync'; import type { Envelope, BusOptions, SendOptions, EnvelopeHandler, Unsubscribe } from '@bedrock-core/sync'; ``` +`SELF_CAPS` is what this build broadcasts as `caps` on every announce; how a receiver narrows a peer's `caps` against the negotiated version is [`capsFor`, next to negotiation](./discovery.md#capabilities). + ## One channel Every bedrock-core message in the world travels on a single script-event channel: @@ -67,7 +69,7 @@ Decoding accepts any `v` inside the window. Only a version below `PROTOCOL_MIN` The window is two versions wide: a version stays readable for two releases after it stops being the newest. Raising `PROTOCOL_MIN` drops everything below it and is a breaking change. -A node whose range does not overlap this build's at all cannot be addressed. It is reported through [`onIncompatible`](./discovery.md#onincompatible) and named in the addon list rather than quietly missing from it. +A node whose range does not overlap this build's at all cannot be addressed. It is reported through [`onIncompatible`](./discovery.md#onincompatible) and named in the catalog rather than quietly missing from it. ## Message types @@ -141,9 +143,9 @@ A message whose `dst` equals the sender's own id never goes over the wire — it One script-event message opens with a single tag character naming which of three shapes follows: ```text -0{"v":2,"src":"shop",…} one envelope, verbatim -2[{"v":2,…},{"v":2,…}] several envelopes packed into one message -1{"c":"…","s":0,"t":9,"p":"…"} one frame of an envelope too large to send whole +0{"v":2,"src":"shop",...} one envelope, verbatim +2[{"v":2,...},{"v":2,...}] several envelopes packed into one message +1{"c":"...","s":0,"t":9,"p":"..."} one frame of an envelope too large to send whole ``` The tag exists to keep the common case cheap. Nesting an envelope inside a frame's `p` field means JSON-escaping the whole thing to sit inside a JSON string — every quote costs a backslash — and a one-piece message would carry a `c`/`s`/`t` header describing a split that never happened. Most bus traffic is one-piece, so the tag keeps the common case cheap. @@ -217,7 +219,7 @@ To watch raw traffic from an addon: ```ts core.node.bus.on('state-delta', (envelope) => { - console.warn(`${envelope.src} → ${JSON.stringify(envelope.data)}`); + console.warn(`${envelope.src} -> ${JSON.stringify(envelope.data)}`); }); ``` diff --git a/docs/sync/rpc.md b/docs/sync/rpc.md index 4f7ecd6..0340f2e 100644 --- a/docs/sync/rpc.md +++ b/docs/sync/rpc.md @@ -156,7 +156,7 @@ Every `request` can reject — timeout, unknown method, or a handler that threw. ### Namespace your method names -The framework's own methods are namespaced (`core:config.server.get`, `core:ui.open`). Method names are per-node, so collisions are only possible within your own addon — but a prefix keeps framework methods and yours visibly apart. +The framework's own methods are namespaced (`core:config.show`, `core:catalog.show`). Method names are per-node, so collisions are only possible within your own addon — but a prefix keeps framework methods and yours visibly apart. ## Lifecycle diff --git a/docs/sync/state.md b/docs/sync/state.md index 7cb42de..88dfb29 100644 --- a/docs/sync/state.md +++ b/docs/sync/state.md @@ -7,7 +7,7 @@ description: "sync.state is a replicated key/value store." `sync.state` is a **replicated** key/value store. Every node keeps a full in-memory mirror, so reads are local and synchronous; writes broadcast a delta that every other node applies to its own mirror. -Any node may read any `namespace:key`. A mirror **applies** an entry for a namespace only when it came from the namespace's owner — the node whose id is the namespace — unless the owner wrote the key with `{ open: true }`, in which case any node's write is taken. Among accepted entries conflicts resolve last-write-wins on a logical clock (a higher version wins; on a tie, the lexicographically greater `src`), so every mirror converges regardless of delivery order. Refused entries are counted in `droppedForeign`. +Any node may read any `namespace:key`. A mirror **applies** an entry for a namespace only when it came from the namespace's owner — the node whose id is the namespace. Among accepted entries conflicts resolve last-write-wins on a logical clock (a higher version wins; on a tie, the lexicographically greater `src`), so every mirror converges regardless of delivery order. Refused entries are counted in `droppedForeign`. :::tip From an addon, prefer `core.shared` [Shared](/docs/server/api/shared) declares a shape and gives you a typed tree over this store, with the framework's reserved keys hidden. Drop to `core.node.state` — the object documented here — when you need a raw key or a framework key. @@ -17,18 +17,17 @@ Any node may read any `namespace:key`. A mirror **applies** an entry for a names ```ts import { State, stateKey } from '@bedrock-core/sync'; -import type { StateKey, StateChange, StateChangeListener, StateOptions, SnapshotEntry } from '@bedrock-core/sync'; +import type { StateKey, StateChange, StateChangeListener, SnapshotEntry } from '@bedrock-core/sync'; ``` ## Usage ```ts sync.state.set('mycoolitems', 'spawnRate', 5); -sync.state.set('mycoolitems', 'votes', 0, { open: true }); // any node may write this key from now on const rate = sync.state.get('mycoolitems', 'spawnRate'); // 5 -const all = sync.state.getNamespace('drav0011_economy'); // { currency: 'gold', … } +const all = sync.state.getNamespace('drav0011_economy'); // { currency: 'gold', ... } -sync.state.subscribe(({ ns, key, value, deleted }) => { /* … */ }); +sync.state.subscribe(({ ns, key, value, deleted }) => { /* ... */ }); sync.state.delete('mycoolitems', 'spawnRate'); ``` @@ -62,13 +61,11 @@ Every namespace currently present in the mirror, in insertion order. ### `set` ```ts -set(ns: string, key: StateKey, value: NoInfer, options?: SetOptions): void -set(ns: string, key: string, value: unknown, options?: SetOptions): void - -interface SetOptions { open?: boolean } +set(ns: string, key: StateKey, value: NoInfer): void +set(ns: string, key: string, value: unknown): void ``` -Write a key, apply it locally, and broadcast a `state-delta`. Throws when [`strictOwnership`](#ownership-and-strictownership) is on and `ns` is not owned. `open: true`, honoured only when this node owns `ns`, marks the key writable by any node; a write to a namespace this node does not own is applied by every mirror — this one included — only if the owner opened the key. +Write a key, apply it locally, and broadcast a `state-delta`. Only the namespace's owner writes it: a write to another node's namespace is dropped by every mirror, this one included, and counted in `droppedForeign`. See [ownership](#ownership). ### `delete` @@ -143,7 +140,7 @@ sync.state.requestSync(); // everything sync.state.requestSync('drav0011_economy'); // only that namespace ``` -Responders answer **only for namespaces they own** — `ownedNamespaces`, which defaults to `[id]`. A namespace with no live owner is not re-served by whoever happens to be mirroring it, so a stale mirror is never presented as authoritative. +Responders answer **only for their own namespace**, the one named by their id. A namespace with no live owner is not re-served by whoever happens to be mirroring it, so a stale mirror is never presented as authoritative. Empty namespaces are skipped rather than answered with an empty snapshot. @@ -180,58 +177,41 @@ Serialize a namespace, **including tombstones** — a snapshot that dropped them | Addressed | Broadcast | Broadcast at startup, direct reply to a request | | Applied | Last-write-wins per key | Last-write-wins per entry | -## Ownership and `strictOwnership` +## Ownership -```ts -const sync = createSync({ - id: 'mycoolitems', - ownedNamespaces: ['mycoolitems', 'mycoolitems_shared'], - strictOwnership: true, -}); -``` +A namespace has one writer: the node whose id is the namespace. Every mirror applies that rule, this node's own included, so a write to another node's namespace is dropped everywhere and counted in `droppedForeign`. -`ownedNamespaces` (default `[id]`) does two things: - -1. It is the set this node answers snapshot requests for. -2. With `strictOwnership: true`, it is the set this node is allowed to write. - -By default **writes are open** — any node may write any namespace. With `strictOwnership` enabled, a write outside the owned set throws: - -``` -[sync] cannot write to namespace 'drav0011_economy': not owned by this node (strictOwnership is enabled) -``` - -The runtime creates its node with `ownedNamespaces: [namespace]` and leaves `strictOwnership` at its default, so `core.node.state` can still write anywhere. [`core.shared`](/docs/server/api/shared) narrows that by construction — its trees only ever address your own namespace, and a peer's tree has no `set`. +[`core.shared`](/docs/server/api/shared) never reaches another namespace: its trees only ever address your own, and a peer's tree has no `set`. :::note Ownership is a convention, not a security boundary -`strictOwnership` guards *your* node against writing where it should not. It cannot stop another pack from writing your namespace — every addon in a world runs arbitrary script. Treat state as shared and cooperative; put anything that needs an authority check behind [RPC](./rpc.md), the way [config](/docs/server/api/config#authorization) does. +A mirror trusts a delta's sender id, and no message carries an identity worth trusting; a pack can also write the underlying dynamic properties directly. Every addon in a world runs arbitrary script. Treat state as shared and cooperative; put anything that needs an authority check behind [RPC](./rpc.md), with [`authorize`](/docs/server/api/authorize) in front of it. ::: ## Persistence is not sync's job sync is in-memory only, and it deliberately does **not** touch dynamic properties — those are pack-scoped, and each addon owns its own durability. -To persist: call `subscribe`, write your namespace to your own dynamic properties, and re-publish on load. Defer all of it with `system.run`, since dynamic properties cannot be touched during early execution. +To persist, keep the namespace in a [`@bedrock-core/db`](/docs/db) document: restore it on load, then save it on every change. Do both inside `system.run`, since dynamic properties cannot be read during early execution, and restore before subscribing, so the restore does not save straight back. ```ts +import { schema } from '@bedrock-core/db'; +import { createEngineDb } from '@bedrock-core/db/minecraft'; import { system, world } from '@minecraft/server'; -system.run(() => { - const NS = 'mycoolitems'; - const saved = world.getDynamicProperty(`${NS}:save`); +const NS = 'mycoolitems'; +const saved = createEngineDb(NS) + .collection('state', { schema: schema>() }) + .for(world); - if (typeof saved === 'string') { - for (const [k, v] of Object.entries(JSON.parse(saved) as Record)) { - sync.state.set(NS, k, v); - } +system.run(() => { + for (const [key, value] of Object.entries(saved.get() ?? {})) { + sync.state.set(NS, key, value); } sync.state.subscribe((change) => { - if (change.ns !== NS) { return; } - - world.setDynamicProperty(`${NS}:save`, JSON.stringify(sync.state.getNamespace(NS))); + if (change.ns === NS) { saved.set(sync.state.getNamespace(NS)); } }); }); ``` -From an addon, `@bedrock-core/db` does this per document, on whatever dynamic property the target itself can hold — which is what you want once a namespace can grow past one property's 32767-character ceiling. A [shared](/docs/server/api/shared) key that must survive a restart is one such document, mirrored across in a line. +A db document is one JSON string, chunked past a property's 32 767-character ceiling, versioned and migrated on read. From an addon, [`core.db`](/docs/server/api/db) is that instance already keyed under the addon's namespace, and a [shared](/docs/server/api/shared) key that must survive a restart is one such document, mirrored across in a line. From 72b5cd0eb5dbef7765f571471c34357dac28b0f2 Mon Sep 17 00:00:00 2001 From: DrAv0011 Date: Thu, 17 Sep 2026 17:35:17 +0200 Subject: [PATCH 41/48] docs(bds-runner, cli): pack optimizer, pin from manifests, the scaffold as generated - bds-runner documents optimize, the build pinned from the packs' min_engine_version on the first run, and the nethernet transport. - cli documents its three prompts, the test profiles and GameTests, and the apps the template installs. Co-Authored-By: Claude Opus 5 (1M context) --- docs/bds-runner/cli.md | 43 ++++++++++++++++ docs/bds-runner/config.md | 35 +++++++++++-- docs/bds-runner/index.md | 4 +- docs/cli/index.md | 106 ++++++++++++++++++++++++-------------- 4 files changed, 145 insertions(+), 43 deletions(-) diff --git a/docs/bds-runner/cli.md b/docs/bds-runner/cli.md index baf837a..3887bc9 100644 --- a/docs/bds-runner/cli.md +++ b/docs/bds-runner/cli.md @@ -6,6 +6,7 @@ description: "The bc-bds commands, every run option, what a run does, exit codes ```text bc-bds run --packs --tag [options] run a suite +bc-bds optimize --packs --out pack built packs into archives bc-bds fetch download and cache the server bc-bds where show which build will be used, and from where ``` @@ -47,6 +48,48 @@ Either a directory containing `BP/` and optionally `RP/`, which is what Regolith Passing `--packs` more than once installs several addons into the same world. That is how a test which asserts that *another* addon is present can pass. Each pack is copied into the world under a folder named after the addon it came from, so two addons that both export `BP/` do not collide. +## `optimize` options + +```text +bc-bds optimize --packs --out [--unpack] +``` + +Runs the server's own pack optimizer over built packs. It minifies their JSON, packs each folder into a `.brarchive` under `__brarchive/`, and stamps `pack_optimization_version` into the manifest so the engine knows to read from there. The server converts and exits; it never serves. + +`--packs` is a directory whose *subdirectories* are each one pack. Regolith's `build/` already has that shape — one folder per pack, each with its own manifest — so the export needs no rearranging. + +| Option | Effect | +| --- | --- | +| `--packs ` | Directory holding one subfolder per pack. Required | +| `--out ` | Where the converted packs are written. Has to sit outside `--packs`, which is read as a directory of packs. Required | +| `--unpack` | The other direction: expand a converted tree back into loose files | +| `--verbose` | Echo the converter's own per-file lines | +| `--offline` | Never download. Fail if the server is not already cached | + +The build the conversion runs on decides the archive format it writes, so pin one in `bds-runner.json` rather than taking `latest`. See [Choosing the server build](./config.md#choosing-the-server-build). + +### What converting costs + +A converted pack needs a **1.26.40 or newer client**; older clients fail to load it. The converter does not raise `min_engine_version` to match, so nothing in the pack tells such a player why it failed. Decide that before shipping one. + +### What gets archived + +| Input | Result | +| --- | --- | +| `manifest.json` | copied out, plus `pack_optimization_version` in the header | +| anything else at the pack root | copied out — only subdirectories are archived | +| `**/*.json` | archived and minified, `//` comments stripped | +| `**/*.png`, `**/*.js` | archived unchanged | +| `texts/*.lang` | listed in the archive, and copied out unchanged | + +An entry that carries no bytes is a listing rather than content: the engine learns a directory's contents from one read and still loads that file from disk. Nothing about those files gets smaller, so the summary counts them apart from the archived ones. + +The saving is whitespace, so it lands on JSON and nothing else. A pack of compiled screens roughly halves; a pack whose weight is textures or a sourcemap barely moves. + +### `--unpack` is not an inverse + +It restores the file tree, not the sources: JSON comes back minified and without the comments it was written with. The build output is the original, not the unpacked copy. + ## What a run does 1. Resolves the server build and downloads it into the cache if it is not there. See [Choosing the server build](./config.md#choosing-the-server-build). diff --git a/docs/bds-runner/config.md b/docs/bds-runner/config.md index a44f5c1..e0b9d85 100644 --- a/docs/bds-runner/config.md +++ b/docs/bds-runner/config.md @@ -32,13 +32,15 @@ The schema file the `$schema` line points at is generated from the selected serv | Key | Value | Why | | --- | --- | --- | +| `server-name` | `bc-bds-runner` | Identifies the server in its own properties file | +| `transport` | `nethernet` | The transport every client uses from 1.26.50 on; a server left on `raknet` refuses players | | `gamemode`, `force-gamemode` | `creative`, `true` | Nothing wanders into a plot; a joining player can edit it | | `difficulty` | `peaceful` | No mob AI competes for ticks | | `default-player-permission-level` | `operator` | A joining player can run commands | | `allow-list` | `false` | Anyone on the LAN can join a held-open server | | `view-distance`, `tick-distance`, `max-threads`, `max-players` | `5`, `4`, `4`, `1` | The tests run in one plot; the rest is wasted simulation | | `player-idle-timeout` | `0` | A kick mid-run would look like a hang | -| `content-log-file-enabled` | `true` | A second copy of the log on disk, next to the server | +| `content-log-file-enabled`, `content-log-file-max-size-bytes` | `true`, `33554432` | A second copy of the log on disk, next to the server | | `script-watchdog-hang-threshold` | `60000` | A long test is not killed by the 10 s default | | `script-watchdog-enable-shutdown` | `false` | A hung script fails the run instead of taking the server down before it can report | | `enable-lan-visibility` | `false`, `true` with `--keep-alive` | Advertised on the LAN only when someone is meant to join | @@ -47,7 +49,7 @@ Anything in `properties` is applied over those, so `"difficulty": "normal"` wins Five keys cannot be overridden because the runner depends on them: `level-name`, `server-port` and `server-portv6` (use `--port`), `allow-cheats`, and `online-mode`. Setting one is an error that names what controls it. -The runner also writes `config/default/permissions.json` so the world's scripts may import `@minecraft/server`, `@minecraft/server-gametest`, `@minecraft/server-ui` and `@minecraft/debug-utilities`, whatever the build's default list says. +The runner also writes `config/default/permissions.json`, listing `@minecraft/server`, `@minecraft/server-gametest`, `@minecraft/server-ui` and `@minecraft/debug-utilities` as modules the world's scripts may import — a fixed list, written explicitly so a run never depends on the build's own default `permissions.json`. ## World @@ -69,10 +71,37 @@ Precedence, highest first: 1. `--bds-version` / `--bds-channel` 2. `BC_BDS_VERSION` / `BC_BDS_CHANNEL` 3. The nearest `bds-runner.json`, or the file named by `--config` -4. Newest `stable` +4. The build your packs ask for — see below +5. Newest `stable` `bc-bds where` prints the selected build, the config file it came from, the schema path, and the current upstream builds. +### The first run writes the pin for you + +A project with no `bds-runner.json` does not silently get whatever is newest. Before the first +download the runner reads the `min_engine_version` of every pack manifest in the project, takes +the highest, and pins the newest build published in that line — `1.26.40` selects `1.26.40.8`. +It writes the result and says so: + +```text + no bds-runner.json: 2 manifest(s) declare min_engine_version 1.26.40 + pinned 1.26.40.8 (stable) in bds-runner.json +``` + +`min_engine_version` is the promise a pack makes to players: this is the oldest client that can +load me. Running the tests on exactly that build tests the promise rather than something newer, +and [converting packs](./cli.md#optimize-options) on it cannot emit an archive format older +clients in that range would choke on. + +The scan skips `node_modules`, `build`, `dist`, `.bds` and other generated trees, so a dependency +or a stale export cannot decide the project's build. A line that only ever shipped as preview +pins the preview build. Nothing is written when no manifest declares a version, when the index is +unreachable, or when a config file already exists — the newest stable build is used and the +project stays as it was. + +This happens once. Edit or delete the file to change the pin; `bc-bds where` reports what would be +detected without writing anything. + Build metadata comes from [Bedrock-OSS/BDS-Versions](https://github.com/Bedrock-OSS/BDS-Versions); the download itself comes from minecraft.net and is checked against the published SHA-1. If the index is unreachable the run fails rather than falling back to a build it already has. ## Working directory diff --git a/docs/bds-runner/index.md b/docs/bds-runner/index.md index 79a9465..8200dc7 100644 --- a/docs/bds-runner/index.md +++ b/docs/bds-runner/index.md @@ -8,8 +8,8 @@ description: "Run an addon's GameTests headlessly on a Bedrock Dedicated Server Runs a Minecraft Bedrock addon's GameTests on a real Bedrock Dedicated Server, headless, and exits with a CI status code. -:::caution Pre-1.0 -`@bedrock-core/bds-runner` is under active development. Breaking changes can still land until `1.0.0` — pin exact versions and read the release notes before upgrading. +:::caution Beta +`@bedrock-core/bds-runner` is in beta: the API can change between releases. Pin exact versions and read the changelog before upgrading. ::: ## What is @bedrock-core/bds-runner? diff --git a/docs/cli/index.md b/docs/cli/index.md index 7742a9c..c33c8d8 100644 --- a/docs/cli/index.md +++ b/docs/cli/index.md @@ -7,7 +7,12 @@ description: "@bedrock-core/cli scaffolds a complete Minecraft Bedrock addon pro # cli -`@bedrock-core/cli` scaffolds a complete Minecraft Bedrock addon project — Regolith build, TypeScript, ESLint, the full bedrock-core stack, and a working example screen — in one command. +`@bedrock-core/cli` scaffolds a complete Minecraft Bedrock addon project — Regolith build, TypeScript, ESLint, the full bedrock-core stack, and three working example screens — in one command. + + +:::caution Beta +`@bedrock-core/cli` is in beta: the API can change between releases. Pin exact versions and read the changelog before upgrading. +::: @@ -21,14 +26,16 @@ description: "@bedrock-core/cli scaffolds a complete Minecraft Bedrock addon pro | Flag | Description | | --- | --- | +| `-a, --author ` | Author name. Skips the author prompt | +| `-d, --description ` | Project description. Skips the description prompt | | `-V, --version` | Print the CLI version | | `-h, --help` | Print usage | -There are no other flags — no template switch, no `--yes`, no package-manager choice. +No template switch and no package-manager choice — the template ships a `yarn.lock`. ### Prompts -Three text prompts, all with defaults you can accept with Enter: +Three text prompts, all with defaults you can accept with Enter. `[project-name]` and `--author`/`--description` each skip their own prompt, so a fully-flagged invocation runs with no prompts at all: | Prompt | Default | Validation | | --- | --- | --- | @@ -40,27 +47,34 @@ Ctrl-C prints `✖ Operation cancelled` and exits cleanly. The CLI refuses to wr ## What gets scaffolded -The template scaffolds the **whole bedrock-core stack**, not just a UI: [server runtime](/docs/server/api/runtime) registration, the shared config UI, typed translations, MDX guides, JSON generation from TypeScript, and a themed example screen with navigation and a modal form. +The template scaffolds the **whole bedrock-core stack**, not just a UI: [server runtime](/docs/server/api/runtime) registration, the addon catalog, the shared config UI, typed translations, MDX guides, JSON generation from TypeScript, a GameTest suite, and three themed example screens covering navigation, a navigated param and a native modal form. ```txt my-addon/ -├── config.json Regolith: generator → guides → i18n → bundler -├── package.json scripts: regolith-install / build / watch / lint +├── config.json Regolith: one `core` filter, four profiles +├── package.json scripts: regolith-install / build / build:test / watch / watch:test / lint ├── tsconfig.json JSX + the two @bedrock-core/generated aliases +├── tsconfig.test.json extends tsconfig.json; entry is scripts/gametest.ts ├── eslint.config.mjs ├── .vscode/ launch.json wired to the Minecraft debugger (port 19144) ├── core-ui-v*.mcpack render pack, downloaded for you └── packs/ ├── BP/ │ ├── manifest.json + │ ├── manifest.test.json extends manifest.json, adds @minecraft/server-gametest │ ├── blocks/tutorial.block.ts generator sample — one file, many blocks │ ├── entities/training_dummy.entity.ts generator sample — single file │ ├── texts/{en_US.lang, languages.json} │ └── scripts/ - │ ├── main.ts core.register(...) + ui(core) + events + │ ├── main.ts core.register(...) + events + │ ├── gametest.ts the test-profile entry: imports ./main and ./tests │ ├── config.ts typed config schema + │ ├── tests/index.ts GameTest suite, tagged "example" │ └── UI/ - │ ├── Example.tsx ore-styled screens + stack navigation + Form + │ ├── screens/ + │ │ ├── home.screen.tsx ore-styled screen, navigation and local state + │ │ ├── plan.screen.tsx reads a navigated param, `back` button + │ │ └── profile_form.screen.tsx a native modal form │ └── i18n.ts createI18n(bundle) ├── RP/ │ ├── manifest.json @@ -77,19 +91,18 @@ my-addon/ ### The Regolith pipeline -`config.json` defines four filters, in this order, in both the `build` and `default` profiles: +`config.json` runs one [`core`](/docs/filters/core) filter in every profile, which chains the six stages in dependency order — manifest, generator, guides, i18n, ui-compiler, bundler — with the namespace declared once as `shared.namespace`: -| Order | Filter | What it does | +| Setting | Stage | What it does | | --- | --- | --- | -| 1 | [`generator`](/docs/filters/generator) | Transpiles `.ts` templates in `BP/`/`RP/` into JSON (blocks, entities), and generates Minecraft document types | -| 2 | [`guides`](/docs/filters/guides) | Compiles `data/guides//**.mdx` into a manifest + `.lang` | -| 3 | [`i18n`](/docs/filters/i18n) | Compiles `data/i18n/.ts` into `.lang`, the runtime bundle, and types | -| 4 | [`bundler`](/docs/filters/bundler) | Bundles `BP/scripts/` into one `main.js` with esbuild | - -The order matters: `guides` writes its `.lang` section before `i18n` picks it up as measurement passthrough, and `i18n` must write its bundle before the bundler inlines it. See [the i18n filter page](/docs/filters/i18n#coexisting-with-the-guides-filter). +| `generator.include` / `exclude` | generator | Widened to every `.ts` under the packs, excluding `BP/scripts` and `data` | +| `manifest.manifestPath` | manifest | `BP/manifest.test.json` in the `test` and `build-test` profiles only | +| `ui-compiler.stamp` | ui-compiler | `true` in `default`, drawing the build-stamp HUD hook | +| `bundler.debug` | bundler | `false` in `build`; `true` everywhere else | +| `bundler.tsConfigPath` | bundler | `tsconfig.test.json` in `test` and `build-test`, whose entry is `gametest.ts` | Templates are checked against Mojang's official JSON Schemas. The `generator` -filter writes document types into `packs/data/generated/mc/`, so a template is a +stage writes document types into `packs/data/generated/mc/`, so a template is a plain export with a `satisfies` on the end: ```ts @@ -104,7 +117,18 @@ global, so nothing is imported and nothing reaches the runtime — `satisfies` i erased at build time. The generated types are gitignored, so run the build once after scaffolding. -The two profiles differ only in build flags: `default` (used by `regolith watch`) exports to `development` with `pretty` JSON and a debug bundle; `build` (used by `yarn build`) exports read-only to `local` with neither. +### Profiles + +| Profile | Script | Export | Notes | +| --- | --- | --- | --- | +| `build` | `yarn build` | read-only, `local` | Minified, `bundler.debug: false` — the release build | +| `default` | `yarn watch` | writable, `development` | Laid-out JSON, debug bundle, build-stamp HUD, redeploys on change | +| `test` | `yarn watch:test` | writable, `development` | Same as `default`, resolving `manifest.test.json` and bundling `gametest.ts` | +| `build-test` | `yarn build:test` | read-only, `./build/test/BP` and `./build/test/RP` | The gametest manifest and entry, for [`bds-runner`](/docs/bds-runner) | + +### GameTests + +`packs/BP/scripts/tests/index.ts` registers one GameTest tagged `example` through `@minecraft/server-gametest`, a beta module only `manifest.test.json` declares. `gametest.ts` — the entry `tsconfig.test.json` names — imports `./main` then `./tests`, so a release build (`main.ts`) never pulls in the test suite or the beta module. `yarn build:test` produces the pack [`bds-runner`](/docs/bds-runner) runs the suite against. ### tsconfig @@ -119,7 +143,7 @@ The two profiles differ only in build flags: `default` (used by `regolith watch` "@bedrock-core/generated/guides": ["./packs/data/guides/guides.generated.json"] } }, - "include": ["packs/BP/scripts/**/*", "packs/data/**/*"] + "include": ["packs/BP/scripts/**/*", "packs/BP/blocks/**/*", "packs/BP/entities/**/*", "packs/data/**/*"] } ``` @@ -127,11 +151,13 @@ The two profiles differ only in build flags: `default` (used by `regolith watch` Both generated files are produced by the filters, so a freshly scaffolded project does not typecheck until `yarn build` has run at least once. This is expected — run the build before hunting for missing modules. ::: +A second tsconfig, `tsconfig.test.json`, extends this one and names `packs/BP/scripts/gametest.ts` as its sole entry — the `test` and `build-test` profiles point the bundler at it. See [GameTests](#gametests). + ### Manifests -Five UUIDs are generated per project (`crypto.randomUUID()`), one per manifest header and module. The BP and RP depend on each other by UUID, both use `pack_scope: "world"` and `min_engine_version: [1, 26, 30]`, and neither bakes its name and description into the manifest: both headers point at `pack.name` / `pack.description` — the only two keys Bedrock resolves for a manifest header — which you author once as `meta.*` in `packs/data/i18n/.ts`. The [i18n filter](/docs/filters/i18n#manifest-display-strings) emits those aliases into each pack's own `texts/.lang` — a manifest key resolves only from the pack it belongs to — so the pack list reads in the player's language, and the template's `texts/en_US.lang` files hold nothing but a comment pointing back at `packs/data/i18n/`. +Five UUIDs are generated per project (`crypto.randomUUID()`), one per manifest header and module, plus `BP/manifest.test.json`, which `extends` the BP manifest and adds a dependency on `@minecraft/server-gametest`. Every manifest is `format_version: 3`, so every version field is a SemVer string: both packs use `pack_scope: "world"` and `min_engine_version: "1.26.50"`. Neither bakes its name and description into the manifest: both headers point at `pack.name` / `pack.description` — the only two keys Bedrock resolves for a manifest header — which you author once as `meta.name` / `meta.description` in `packs/data/i18n/.ts`. The [i18n filter](/docs/i18n/authoring#meta-branch) emits those aliases into each pack's own `texts/.lang` — a manifest key resolves only from the pack it belongs to — so the pack list reads in the player's language, and the template's `texts/en_US.lang` files hold nothing but a comment pointing back at `packs/data/i18n/`. -The BP also declares a dependency on `@minecraft/server` and `@minecraft/server-ui`. Add the [render pack](/docs/ui/guides/render-pack) dependency when you ship. +The BP also declares a dependency on `@minecraft/server` and `@minecraft/server-ui`, and on the [render pack](/docs/ui/guides/render-pack) by its fixed UUID — already wired in, not something you add later. ### Identifiers @@ -142,7 +168,7 @@ Two of your answers become Minecraft-safe identifiers — lowercased, non-alphan | `CREATOR_ID` | Author name | `core.register({ manifest: { creator } })`, the addon namespace | | `PACK_ID` | Project name | `core.register({ manifest: { pack } })`, generated identifiers | -Together they form the addon namespace `_` that the [i18n filter derives](/docs/filters/i18n#namespacing) for `.lang` keys and that the `guides` filter takes as its `namespace` setting. +Together they form the addon namespace `_` that the [i18n filter derives](/docs/i18n/authoring#namespacing) for `.lang` keys and that the `guides` filter takes as its `namespace` setting. ### The generated `main.ts` @@ -156,17 +182,15 @@ const { config } = core.register({ version: '1.0.0', description: i18n.key($ => $.meta.description), }, - translations: bundle, - guide: guides, - config: configDef, + catalog: registerCatalog(), + config: registerConfig(configDef), + guides: registerGuides(), }); - -ui(core); ``` -Display fields are **i18n keys**, not literals — that is what lets the shared list render your addon's name in each player's own language. `core.register()` publishes them to the [server-side registry](/docs/server/api/registry); `ui(core)` mounts the [shared config UI](/docs/config) and registers the four `:…` commands. +Display fields are **i18n keys**, not literals — that is what lets a catalog render your addon's name in each player's own language. `core.register()` publishes them to the [registry](/docs/server/api/registry) and, on the first tick, the bundle they resolve from. The three app fields register `:catalog`, `:config` and `:guide` under your namespace and serve the show methods another realm asks on; nothing runs after the call. -A `playerSpawn` handler greets the player with an interpolated translation (gated on a config value), and a `buttonPush` handler renders the example screen — push a stone button in-game to see it. +A `playerSpawn` handler greets the player with an interpolated translation (gated on a config value), and a `buttonPush` handler renders the Home screen — push a stone button in-game to see it, then follow its navigation to the plan screen and the profile form. ## After scaffolding @@ -175,13 +199,17 @@ The CLI **does not** install anything. It copies the template, substitutes your It then prints: ```txt +✔ Project created successfully! + Next steps: cd my-addon yarn install (or npm install) yarn run regolith-install (or npm run regolith-install) yarn run build (or npm run build) - See packs/BP/scripts/UI/Example.tsx to explore the starter screens and navigation. + The first build writes the Minecraft document types, so the .ts templates in + packs/BP/blocks and packs/BP/entities autocomplete once it has run. + See packs/BP/scripts/UI/screens/ to explore the starter screens and navigation. Render pack: @@ -195,29 +223,31 @@ Development: Push a stone button in-game to see the example UI! ``` +When the render pack download fails, the last line under "Render pack:" is replaced with a link to the latest `.mcpack` on GitHub Releases instead of a filename — non-fatal, so scaffolding still finishes. + | Script | What it runs | | --- | --- | -| `regolith-install` | `regolith install-all` — fetches the four filters | +| `regolith-install` | `regolith install-all` — fetches every filter the `core` filter chains | | `build` | `regolith run build` — the read-only local export profile | +| `build:test` | `regolith run build-test` — the read-only gametest export, for `bds-runner` | | `watch` | `regolith watch` — the development profile, redeploying on change | +| `watch:test` | `regolith watch test` — the development profile, resolving the gametest manifest and entry | | `lint` | `eslint .` | | `loopback` / `loopback:preview` | Windows loopback exemption for the Minecraft debugger | No git repository is created and no package manager is detected — the template ships a `yarn.lock`, so `yarn install` is the smoothest path. :::tip Prerequisites -Node.js 20+, a package manager, and [Regolith](https://regolith-docs.readthedocs.io/en/stable) on your `PATH`. See [Installation](/docs/ui/installation). +Node.js 22.18+ (what the Regolith filters run on), a package manager, and [Regolith](https://regolith-docs.readthedocs.io/en/stable) on your `PATH`. See [Installation](/docs/ui/installation). ::: ## Next steps -:::caution Pre-1.0 -`@bedrock-core/cli` is under active development. Breaking changes can still land until `1.0.0` — pin exact versions and read the release notes before upgrading. -::: - [Render pack](/docs/ui/guides/render-pack) — what the `.mcpack` is and how versioning works - [i18n](/docs/i18n) — the translations the template already wires up -- [config](/docs/config) — the settings UI `ui(core)` mounts +- [catalog](/docs/catalog) — the addon browser the template installs +- [config](/docs/config) — the settings app the template installs - [guides](/docs/guides) — the in-game guide the template seeds -- [ore-styled](/docs/ore-styled) — the components `Example.tsx` uses -- [server-runtime](/docs/server/api/runtime) — the `core.register()` half of the generated `main.ts`, and [how the two sides meet](/docs/server/guides/ui-integration) +- [ore-styled](/docs/ore-styled) — the components the starter screens use +- [server-runtime](/docs/server/api/runtime) — the `core.register()` half of the generated `main.ts` From 0add77b30b2ade96d0cbca35571ff4d69f27e9be Mon Sep 17 00:00:00 2001 From: DrAv0011 Date: Thu, 17 Sep 2026 17:41:20 +0200 Subject: [PATCH 42/48] docs(ui): every component page in one folder, Trans, link params - Component pages sit directly under components/, listed alphabetically after the overview, which keeps the groups as prose. - Trans has a page, Button documents hug, and Link's params must be plain data on a static screen. Co-Authored-By: Claude Opus 5 (1M context) --- .../ui/components/{content => }/Background.md | 9 +- docs/ui/components/{controls => }/Button.md | 48 ++++---- docs/ui/components/Container.md | 103 ++++++++++++++++ .../components/{compiled => }/Disclosure.md | 5 +- docs/ui/components/{fields => }/Dropdown.md | 25 ++-- docs/ui/components/{cross-pack => }/Embed.md | 7 +- docs/ui/components/{cross-pack => }/Expect.md | 3 +- docs/ui/components/{roots => }/Form.md | 23 ++-- docs/ui/components/{layout => }/Fragment.md | 1 - docs/ui/components/{cells => }/Hotbar.md | 5 +- docs/ui/components/{content => }/Image.md | 5 +- docs/ui/components/{fields => }/Input.md | 15 ++- docs/ui/components/{controls => }/Link.md | 9 +- docs/ui/components/{compiled => }/List.md | 5 +- docs/ui/components/{controls => }/Option.md | 13 +- docs/ui/components/{layout => }/Panel.md | 5 +- .../components/{cells => }/PlayerInventory.md | 5 +- docs/ui/components/{roots => }/Screen.md | 15 ++- docs/ui/components/{layout => }/Scroll.md | 3 +- docs/ui/components/Select.md | 85 +++++++++++++ docs/ui/components/{fields => }/Slider.md | 13 +- docs/ui/components/{cells => }/Slot.md | 45 ++++++- docs/ui/components/{cells => }/SlotGrid.md | 5 +- docs/ui/components/{compiled => }/Tabs.md | 8 +- docs/ui/components/{content => }/Text.md | 41 +++++-- docs/ui/components/{controls => }/Toggle.md | 15 ++- docs/ui/components/Trans.md | 114 ++++++++++++++++++ docs/ui/components/cells/_category_.json | 11 -- docs/ui/components/compiled/_category_.json | 11 -- docs/ui/components/components.md | 57 ++++----- docs/ui/components/content/_category_.json | 11 -- docs/ui/components/control-props.md | 5 +- docs/ui/components/controls/Select.md | 68 ----------- docs/ui/components/controls/_category_.json | 11 -- docs/ui/components/cross-pack/_category_.json | 11 -- docs/ui/components/fields/_category_.json | 11 -- docs/ui/components/layout/_category_.json | 11 -- docs/ui/components/roots/Container.md | 69 ----------- docs/ui/components/roots/_category_.json | 11 -- 39 files changed, 516 insertions(+), 401 deletions(-) rename docs/ui/components/{content => }/Background.md (91%) rename docs/ui/components/{controls => }/Button.md (58%) create mode 100644 docs/ui/components/Container.md rename docs/ui/components/{compiled => }/Disclosure.md (83%) rename docs/ui/components/{fields => }/Dropdown.md (70%) rename docs/ui/components/{cross-pack => }/Embed.md (86%) rename docs/ui/components/{cross-pack => }/Expect.md (92%) rename docs/ui/components/{roots => }/Form.md (62%) rename docs/ui/components/{layout => }/Fragment.md (98%) rename docs/ui/components/{cells => }/Hotbar.md (83%) rename docs/ui/components/{content => }/Image.md (91%) rename docs/ui/components/{fields => }/Input.md (78%) rename docs/ui/components/{controls => }/Link.md (74%) rename docs/ui/components/{compiled => }/List.md (89%) rename docs/ui/components/{controls => }/Option.md (64%) rename docs/ui/components/{layout => }/Panel.md (87%) rename docs/ui/components/{cells => }/PlayerInventory.md (89%) rename docs/ui/components/{roots => }/Screen.md (68%) rename docs/ui/components/{layout => }/Scroll.md (96%) create mode 100644 docs/ui/components/Select.md rename docs/ui/components/{fields => }/Slider.md (85%) rename docs/ui/components/{cells => }/Slot.md (65%) rename docs/ui/components/{cells => }/SlotGrid.md (90%) rename docs/ui/components/{compiled => }/Tabs.md (75%) rename docs/ui/components/{content => }/Text.md (75%) rename docs/ui/components/{controls => }/Toggle.md (68%) create mode 100644 docs/ui/components/Trans.md delete mode 100644 docs/ui/components/cells/_category_.json delete mode 100644 docs/ui/components/compiled/_category_.json delete mode 100644 docs/ui/components/content/_category_.json delete mode 100644 docs/ui/components/controls/Select.md delete mode 100644 docs/ui/components/controls/_category_.json delete mode 100644 docs/ui/components/cross-pack/_category_.json delete mode 100644 docs/ui/components/fields/_category_.json delete mode 100644 docs/ui/components/layout/_category_.json delete mode 100644 docs/ui/components/roots/Container.md delete mode 100644 docs/ui/components/roots/_category_.json diff --git a/docs/ui/components/content/Background.md b/docs/ui/components/Background.md similarity index 91% rename from docs/ui/components/content/Background.md rename to docs/ui/components/Background.md index 470cef8..51e4c17 100644 --- a/docs/ui/components/content/Background.md +++ b/docs/ui/components/Background.md @@ -1,5 +1,4 @@ --- -sidebar_position: 3 description: "Draw a full-screen texture behind everything in a form." --- # Background @@ -23,7 +22,7 @@ import { Background } from '@bedrock-core/ui'; `Background` occupies no layout space — it takes no width/height, participates in no flexbox flow, and is invisible to its siblings. It simply renders the given texture across the whole screen, behind all other form content. -Place one anywhere in the tree (conventionally first, at the root). It works on both backends — a plain `ActionForm` tree and inside a [``](../roots/Form.md) modal. +Place one anywhere in the tree (conventionally first, at the root). It works on both backends — a plain `ActionForm` tree and inside a [``](./Form.md) modal. :::note Only the first `` wins If a tree contains more than one ``, only the first is rendered; the rest are ignored. @@ -52,7 +51,7 @@ function Settings({ onSubmit }) { {'Music'} - + {'Save'} ); } @@ -70,7 +69,7 @@ function Menu() { {'§lMain Menu'} - @@ -83,4 +82,4 @@ function Menu() { - The texture path is capped at 80 UTF-8 bytes and cannot contain `;`. - Only the first `` in a tree is drawn. -- The texture always covers the entire screen — there is no partial or positioned mode. For a bounded background, use a [``](../layout/Panel.md) or [``](./Image.md) instead. +- The texture always covers the entire screen — there is no partial or positioned mode. For a bounded background, use a [``](./Panel.md) or [``](./Image.md) instead. diff --git a/docs/ui/components/controls/Button.md b/docs/ui/components/Button.md similarity index 58% rename from docs/ui/components/controls/Button.md rename to docs/ui/components/Button.md index 6f24fd0..6dfe720 100644 --- a/docs/ui/components/controls/Button.md +++ b/docs/ui/components/Button.md @@ -1,6 +1,5 @@ --- -sidebar_position: 1 -description: "A press. Its action is a handler, the form's submit, or the way out." +description: "A press: a handler on a screen or a container screen. A form's own submit and exit are Form.Button." --- # Button @@ -15,7 +14,7 @@ import { Button } from '@bedrock-core/ui'; ## Usage ```tsx - ``` @@ -26,37 +25,38 @@ Buttons are sized intrinsically from their content plus the button's built-in pa | Prop | Type | Default | Description | | --- | --- | --- | --- | -| `action` | `(event: PressEvent) => unknown \| Promise` \| `'submit'` \| `'exit'` | — | What the press does; see below | +| `onPress` | `(event: PressEvent) => unknown \| Promise` | — | Runs on the press, with the player who pressed; see below | | `children` | `JSX.Node` | — | What the button shows — a `Text`, an `Image`, or a row of both | | `backgroundHover` | `string` | `background` | Texture drawn while the player hovers | | `backgroundPressed` | `string` | `background` | Texture drawn while the button is being pressed | | `backgroundLocked` | `string` | `background` | Texture drawn while the button is disabled | +| `hug` | `boolean` | `false` | Draw the press around what its children draw rather than in the box the layout solved, so it covers exactly the glyphs the client shows. For a press in a line of hugging text, which is what [``](./Trans.md) draws. Action forms only | -Inherits [control props](../control-props.md). Every state texture falls back to `background`, and `background` falls back to the blank-canvas placeholder, so one texture styles all four states. +Inherits [control props](./control-props.md). Every state texture falls back to `background`, and `background` falls back to the blank-canvas placeholder, so one texture styles all four states. -## What the action is +## What a press does -`action` is the one prop a press is given, and it takes three kinds of thing. +A press is one of three things, and each is its own component. -| `action` | What happens | Where | +| Component | What happens | Where | | --- | --- | --- | -| a handler | your function runs, with the player who pressed | [``](../roots/Screen.md) and [``](../roots/Container.md) | -| `'submit'` | the native modal submits, and [`
    `](../roots/Form.md) receives every value | [``](../roots/Form.md) | -| `'exit'` | the screen is left — the modal's dismiss, or the way out of a container screen | `` and `` | +| ` - + {'Save'} + {'Cancel'} ``` @@ -79,10 +79,10 @@ Exactly one `'submit'` is required, and at most one `'exit'` beside it. ```tsx - - @@ -91,7 +91,7 @@ Exactly one `'submit'` is required, and at most one `'exit'` beside it. ### An icon ```tsx - ``` @@ -112,7 +112,7 @@ Exactly one `'submit'` is required, and at most one `'exit'` beside it. backgroundHover={'textures/ui/button_hover'} backgroundPressed={'textures/ui/button_pressed'} backgroundLocked={'textures/ui/button_locked'} - action={() => console.warn('pressed')} + onPress={() => console.warn('pressed')} > {'Themed'} @@ -122,8 +122,8 @@ Exactly one `'submit'` is required, and at most one `'exit'` beside it. Let buttons size to their content rather than hardcoding `width` and `height`, unless the layout needs a specific footprint. Inside a row, `flex={1}` on each distributes the space evenly. -Disable a button when its action is unavailable rather than hiding it: a hidden control leaves its box behind on a compiled screen unless the row is a [``](../layout/Panel.md#stack). +Disable a button when its action is unavailable rather than hiding it: a hidden control leaves its box behind on a compiled screen unless the row is a [``](./Panel.md#stack). -A handler that returns a promise keeps the press's transaction open until it settles, which is what makes an async handoff flash-free. See [State](../../guides/state.md#one-ui-slot-per-player). +A handler that returns a promise keeps the press's transaction open until it settles, which is what makes an async handoff flash-free. See [State](../guides/state.md#one-ui-slot-per-player). This is the primitive [`@bedrock-core/ore-styled`'s `Button`](/docs/ore-styled/Button) is built on. diff --git a/docs/ui/components/Container.md b/docs/ui/components/Container.md new file mode 100644 index 0000000..40530b6 --- /dev/null +++ b/docs/ui/components/Container.md @@ -0,0 +1,103 @@ +--- +description: "The root of a container screen: names the entity or block the screen opens from, and is the screen's own panel." +--- +# Container + +The root of a [container screen](../guides/container-screens.md): names the entity or the block the screen opens from, and is the screen's own panel. + +## Import + +```tsx +import { Container } from '@bedrock-core/ui'; +``` + +## Usage + +```tsx +export default function Furnace() { + return ( + + {'§fFurnace'} + + + + + ); +} +``` + +Its presence decides the backend, the way [`
    `](./Form.md) makes a screen a native modal: a tree rooted in a `Container` is laid out once at build time by the [ui-compiler filter](/docs/filters/ui-compiler), baked into JSON UI, and served by `createContainerScreen` to every player who opens the host it names. `render()` rejects it — a container screen is compiled ahead of time, not serialized per player. + +:::caution Experimental: block containers +A block-hosted screen uses its block's `minecraft:block_entity` container, and block containers are an experimental game feature. Expect rough edges, and expect this to change when the game's feature does. Entity-hosted screens are not affected. +::: + +A screen names **exactly one** of `entity` and `block`. Naming both, or neither, fails the build: a screen opens from one host, and which one decides what the build stamps and which vanilla screen the layout is routed onto. Nothing else about the screen changes — the same components, the same cells, the same handlers. + +## Props + +| Prop | Type | Default | Description | +| --- | --- | --- | --- | +| `entity` | `string` | — | Type of the entity the screen opens from, e.g. `'core:furnace'`. The build sizes that entity's `minecraft:inventory` and stamps it with the screen's layout key; the runtime serves the screen when a player interacts with it. The entity must exist in the behavior pack, or the build fails. Exactly one of this and `block` | +| `block` | `string` | — | **Experimental.** Type of the block the screen opens from, e.g. `'core:workbench'`. The build gives that block a `minecraft:block_entity` container sized to the layout, turns its dynamic properties on and stamps the layout key as a block state; a player opens the screen by interacting with a placed one. The block must exist in the behavior pack, or the build fails | +| `onOpen` | `(event: ContainerEvent) => void` | `undefined` | Ran when a player opens the screen, and again for every further viewer. `event.player` is who opened it, `event.host` the entity or block it opened and `event.container` that host's own cells. One layout serves everyone looking, so this is where a screen learns who is there — keep what it needs in state | +| `onClose` | `(event: ContainerEvent) => void` | `undefined` | Ran when a player closes the screen, or leaves the world with it open. `event.player` is who left, `event.host` the entity or block it belonged to, `event.container` its own cells | +| `children` | `JSX.Node` | — | The screen. Anything a form can hold except the [form-only components](../guides/container-screens.md#not-supported), plus [`Slot`](./Slot.md), [`PlayerInventory`](./PlayerInventory.md) and [`Hotbar`](./Hotbar.md) | + +Inherits [control props](./control-props.md). It is the screen's root panel, so `background` draws the frame and `padding` / `gap` / `flexDirection` lay the children out — the same way they would on a `Panel`. + +`event.container` is the screen's own cells as the engine's own [`Container`](https://learn.microsoft.com/minecraft/creator/scriptapi/minecraft/server/container) — the drawn [``](./Slot.md)s in document order, by index or by the `name` each declared, with the routing key, the buttons and the live-value bank invisible. The same cells are reachable from outside the component through `screen.container(host)`; see [Reaching the cells](../guides/container-screens.md#reaching-the-cells). + +## Rules + +The build enforces these, with a message naming the fix: + +- **Exactly one, at the root.** Providers and fragments above it are looked through; anything else beside it is rejected, and a screen with no root at all is refused with the list of roots. +- **Exactly one host.** `entity` or `block`, never both and never neither. +- **No nesting.** One host opens one screen, and no root sits inside another — compose the inner part as a component instead. +- **The content fits the canvas.** A container screen is laid out on the same 320 × 210 canvas as a form, but it cannot scroll: content past the canvas fails the build rather than clipping. +- **A block holds 54 slots.** That is the whole allocation — the routing key, every cell and the live-value bank — so a block-hosted screen that needs more fails the build. An entity's inventory has no such cap. + +## Examples + +### A framed screen + +```tsx + + {'§lVault'} + + + + + + + + + +``` + +`PlayerInventory` and `Hotbar` are not free: a container screen owns the whole vanilla screen, so leave them out and the player's own grids are gone. + +### The same screen on either host + +Nothing above the root differs, so a screen written once serves both: + +```tsx +// crafting.tsx — the screen, named by neither host +export function Crafting({ entity, block }: { entity?: string; block?: string }) { + return ( + + {'§fCrafting'} + + + ); +} + +// crafting_table.screen.tsx +export default () => ; + +// crafting_block.screen.tsx +export default () => ; +``` + +Each screen file is compiled separately and gets its own layout key, so the two hosts open their own copies of the same layout. diff --git a/docs/ui/components/compiled/Disclosure.md b/docs/ui/components/Disclosure.md similarity index 83% rename from docs/ui/components/compiled/Disclosure.md rename to docs/ui/components/Disclosure.md index 0a4ee53..a7fc641 100644 --- a/docs/ui/components/compiled/Disclosure.md +++ b/docs/ui/components/Disclosure.md @@ -1,5 +1,4 @@ --- -sidebar_position: 2 description: "A header that folds the rows under it entirely on the client, reflowing what is below." --- # Disclosure @@ -17,7 +16,7 @@ import { Disclosure } from '@bedrock-core/ui'; ```tsx {'Getting started'}} - headerClosed={{'Getting started…'}} + headerClosed={{'Getting started...'}} gap={2} > {'Intro'} @@ -34,7 +33,7 @@ import { Disclosure } from '@bedrock-core/ui'; | `headerHeight` | `number` | `20` | Height of the header box in texels | | `defaultOpen` | `boolean` | `true` | Whether the rows show when the screen opens | -Inherits [control props](../control-props.md). The flow props — `flexDirection`, `gap`, `justifyContent`, `alignItems`, `alignContent`, `wrap` — apply to the **rows**, since that is what an author writing `gap` on a disclosure means; everything else sizes and places the fold itself. +Inherits [control props](./control-props.md). The flow props — `flexDirection`, `gap`, `justifyContent`, `alignItems`, `alignContent`, `wrap` — apply to the **rows**, since that is what an author writing `gap` on a disclosure means; everything else sizes and places the fold itself. ## What folding costs diff --git a/docs/ui/components/fields/Dropdown.md b/docs/ui/components/Dropdown.md similarity index 70% rename from docs/ui/components/fields/Dropdown.md rename to docs/ui/components/Dropdown.md index d6dd094..c37fb6c 100644 --- a/docs/ui/components/fields/Dropdown.md +++ b/docs/ui/components/Dropdown.md @@ -1,15 +1,14 @@ --- -sidebar_position: 3 description: "Select field with a popup, for use inside a Form." --- # Dropdown -Select field with a popup, for use inside a [`Form`](../roots/Form.md). Pressing it opens a scrollable list of [`Option`](../controls/Option.md) children to choose from. +Select field with a popup, for use inside a [`Form`](./Form.md). Pressing it opens a scrollable list of [`Option`](./Option.md) children to choose from. ## Import ```tsx -import { Form } from '@bedrock-core/ui'; +import { Dropdown, Form, Option } from '@bedrock-core/ui'; ``` ## Usage @@ -21,7 +20,7 @@ import { Form } from '@bedrock-core/ui'; ``` @@ -34,18 +33,18 @@ import { Form } from '@bedrock-core/ui'; | Prop | Type | Default | Description | | --- | --- | --- | --- | | `name` | `string` | — | Result key — the selected index appears at `values[name]` in the form's `onSubmit` | -| `defaultValue` | `string` | the first option | Initial selection, matched against a [`Option`](../controls/Option.md)'s `value` | -| `children` | `JSX.Node` | — | The selectable options, authored as [`Option`](../controls/Option.md) elements. Popup rows flow at a fixed row height, so an option's own layout props are ignored here — only its `value`/`label`/style are read | +| `defaultValue` | `string` | the first option | Initial selection, matched against a [`Option`](./Option.md)'s `value` | +| `children` | `JSX.Node` | — | The selectable options, authored as [`Option`](./Option.md) elements. Popup rows flow at a fixed row height, so an option's own layout props are ignored here — only its `value`/`label`/style are read | | `popupBackground` | `string` | the unstyled placeholder texture | Background texture for the popup surface behind the option list | | `optionBackground` / `optionHover` / `optionSelected` | `string` | — | Group-level default row textures for idle/hover/selected states. Any `Option` can override its own | -| `optionFont` / `optionScale` / `optionAlign` | `LabelFont` / `number` / `'left' \| 'center' \| 'right'` | `'mojangles'` / `1.0` / `'left'` | Group-level default label styling for option rows. Any `Option` can override its own | +| `optionFont` / `optionScale` / `optionAlign` | `TextFont` / `number` / `'left' \| 'center' \| 'right'` | `'mojangles'` / `1.0` / `'left'` | Group-level default label styling for option rows. Any `Option` can override its own | | `currentColor` | `string` | `''` | Color code prefix (e.g. `'§0'`) applied to the closed-box current-value text | -| `currentFont` / `currentScale` | `LabelFont` / `number` | `'mojangles'` / `1.0` | Font and scale for the closed-box current-value label | +| `currentFont` / `currentScale` | `TextFont` / `number` | `'mojangles'` / `1.0` | Font and scale for the closed-box current-value label | | `currentInsetX` / `currentInsetY` | `number` | `8` / vertically centered | Position offset (px) of the current-value label from the closed box's left-middle frame | -The closed box uses `background`/`backgroundHover`/`backgroundPressed`/`backgroundLocked` for per-state texturing — the same shape as [`Button`](../controls/Button.md). +The closed box uses `background`/`backgroundHover`/`backgroundPressed`/`backgroundLocked` for per-state texturing — the same shape as [`Button`](./Button.md). -Inherits [control props](../control-props.md). +Inherits [control props](./control-props.md). ## Examples @@ -83,7 +82,7 @@ const options = ['Easy', 'Normal', 'Hard']; {options.map(o => - + {'Save'} ``` @@ -91,9 +90,9 @@ const options = ['Easy', 'Normal', 'Hard']; - Keep `Option` children order stable across renders — the result is an index, so reordering shifts what a saved index means. - Read `values[name]` as an index and map it back to your own array if you need the string; don't assume it's the `value` you passed in. -- Prefer [`Select`](../controls/Select.md) instead when you want every option visible without an extra tap (e.g. a short radio-style choice). +- Prefer [`Select`](./Select.md) instead when you want every option visible without an extra tap (e.g. a short radio-style choice). - For themed screens, prefer [`@bedrock-core/ore-styled`](/docs/ore-styled/Dropdown)'s `Dropdown` over styling this primitive by hand. ## Limits -Modal-only. The engine draws no popup on an action form or a container screen, so writing one there is a build error naming the fix rather than a control drawn inert. [``](../controls/Toggle.md) and [``](./Select.md) are the controls that serve all three hosts. diff --git a/docs/ui/components/cross-pack/Embed.md b/docs/ui/components/Embed.md similarity index 86% rename from docs/ui/components/cross-pack/Embed.md rename to docs/ui/components/Embed.md index f806374..5871490 100644 --- a/docs/ui/components/cross-pack/Embed.md +++ b/docs/ui/components/Embed.md @@ -1,5 +1,4 @@ --- -sidebar_position: 2 description: "A screen one pack draws into another pack's screen, over an area the host reserves." --- # Embed @@ -14,7 +13,7 @@ import { Embed, EmbedSlots, embedMarker } from '@bedrock-core/ui'; ## Why it exists -A compiled screen's layout lives in the pack of the addon that built it, and a host realm shows it by title. Some of what a host draws is not the host's to bake: the page for one addon in the addon list — its thumbnail, its description, its authors — belongs to that addon, baked in that addon's pack, and the host has nothing to say about it but where it goes. +A compiled screen's layout lives in the pack of the addon that built it, and a host realm shows it by title. Some of what a host draws is not the host's to bake: the page for one addon in the catalog — its thumbnail, its description, its authors — belongs to that addon, baked in that addon's pack, and the host has nothing to say about it but where it goes. Neither side renders the other. The one contract is the host's frame, the area's place in it, and the slot count. @@ -36,7 +35,7 @@ Neither side renders the other. The one contract is the host's frame, the area's | `frame` | `{ width: number; height: number }` | — | The canvas the host bakes its own screen against | | `area` | `{ x: number; y: number; width: number; height: number }` | — | The area of that frame this component fills | -Inherits [control props](../control-props.md) except `width` and `height`, which come from `area`. +Inherits [control props](./control-props.md) except `width` and `height`, which come from `area`. ## The host side @@ -55,7 +54,7 @@ Inherits [control props](../control-props.md) except `width` and `height`, which | Prop | Type | Default | Description | | --- | --- | --- | --- | | `count` | `number` | — | How many entries are reserved; a constant of the embedding screen | -| `values` | `readonly string[]` | — | What each slot carries this present — the marker first, then the embedded screen's values | +| `values` | `readonly DisplayText[]` | — | What each slot carries this present — the marker first, then the embedded screen's values | | `onPress` | `(index: number, event: PressEvent) => unknown` | — | A press on slot `index`, never 0 | ## embedMarker diff --git a/docs/ui/components/cross-pack/Expect.md b/docs/ui/components/Expect.md similarity index 92% rename from docs/ui/components/cross-pack/Expect.md rename to docs/ui/components/Expect.md index 6d34dc6..e9c7731 100644 --- a/docs/ui/components/cross-pack/Expect.md +++ b/docs/ui/components/Expect.md @@ -1,5 +1,4 @@ --- -sidebar_position: 1 description: "States which screen a fragment is written for, and fails the build by name when it is drawn on another." --- # Expect @@ -39,4 +38,4 @@ Written at the top of that fragment, it says what the library assumed. An addon ## Notes -The host ids are the same three [Hosts](../../guides/hosts.md) names a root resolves to. +The host ids are the same three [Hosts](../guides/hosts.md) names a root resolves to. diff --git a/docs/ui/components/roots/Form.md b/docs/ui/components/Form.md similarity index 62% rename from docs/ui/components/roots/Form.md rename to docs/ui/components/Form.md index ffb23cd..8827f12 100644 --- a/docs/ui/components/roots/Form.md +++ b/docs/ui/components/Form.md @@ -1,5 +1,4 @@ --- -sidebar_position: 2 description: "The root that makes a screen a native modal form: one atomic ModalFormData, every value arriving together on submit." --- # Form @@ -22,7 +21,7 @@ export default function Settings(): JSX.Element { - + {'Save'} ); } @@ -30,15 +29,15 @@ export default function Settings(): JSX.Element { `Form` is a **host**, the way [``](./Screen.md) and [``](./Container.md) are. Its presence makes the renderer build one atomic `ModalFormData` instead of a screen of buttons. -## Form has no members +## One member: Form.Button -There is no `Form.Toggle`, no `Form.Input`, no `Form.Button`. Every control is a top-level component imported by its own name, and **which hosts it works on is its own capability**, not something a namespace decides: +`Form.Button`, with `type` `submit` or `exit`, is the modal's own submit and dismiss button, and the only member `Form` has. Every field is a top-level component imported by its own name, and **which hosts it works on is its own capability**, not something a namespace decides: ```tsx import { Button, Dropdown, Form, Input, Option, Select, Slider, Text, Toggle } from '@bedrock-core/ui'; ``` -[``](../controls/Toggle.md), [``](../fields/Input.md), [``](../fields/Slider.md) and [``](../fields/Dropdown.md) only work here, because the engine draws no text field, slider or popup anywhere else. See [Hosts](../../guides/hosts.md) for the whole table. +[``](./Toggle.md), [``](./Input.md), [``](./Slider.md) and [``](./Dropdown.md) only work here, because the engine draws no text field, slider or popup anywhere else. See [Hosts](../guides/hosts.md) for the whole table. ## Props @@ -48,7 +47,7 @@ import { Button, Dropdown, Form, Input, Option, Select, Slider, Text, Toggle } f | `onCancel` | `(event: UiEvent) => void` | — | Called when the player dismisses the modal — the X, Esc, or an exit button | | `children` | `JSX.Node` | — | The controls, the decoration and the action buttons, in any order | -`Form` takes no [control props](../control-props.md): it is a marker, not a panel. Put a `Panel` inside it for a background, padding or a direction. +`Form` takes no [control props](./control-props.md): it is a marker, not a panel. Put a `Panel` inside it for a background, padding or a direction. ## Values arrive once @@ -70,17 +69,17 @@ A heading is a ``: the modal has no `title` or `body` prop of its own. The build enforces these, with a message naming the fix. -- **Exactly one submit.** A modal has no built-in submit control, so the screen declares one: ` ``` diff --git a/docs/ui/components/fields/Input.md b/docs/ui/components/Input.md similarity index 78% rename from docs/ui/components/fields/Input.md rename to docs/ui/components/Input.md index 91ab275..5ed1675 100644 --- a/docs/ui/components/fields/Input.md +++ b/docs/ui/components/Input.md @@ -1,15 +1,14 @@ --- -sidebar_position: 1 description: "Single-line text field, for use inside a Form." --- # Input -Single-line text field, for use inside a [`Form`](../roots/Form.md). +Single-line text field, for use inside a [`Form`](./Form.md). ## Import ```tsx -import { Form } from '@bedrock-core/ui'; +import { Form, Input } from '@bedrock-core/ui'; ``` ## Usage @@ -17,7 +16,7 @@ import { Form } from '@bedrock-core/ui'; ```tsx console.warn(v.nickname)}> - + {'Save'} ``` @@ -32,14 +31,14 @@ import { Form } from '@bedrock-core/ui'; | `name` | `string` | — | Result key — the value appears at `values[name]` in the form's `onSubmit` | | `placeholder` | `string` | — | Text shown inside the native field when empty | | `defaultValue` | `string` | `''` | Initial text | -| `font` | `LabelFont` | `'mojangles'` | Font family for the typed value and placeholder | +| `font` | `TextFont` | `'mojangles'` | Font family for the typed value and placeholder | | `scale` | `number` | `1.0` | Scale multiplier relative to the standard glyph size | | `textOffsetX` / `textOffsetY` | `number` | `8` / vertically centered | Typed-value position offset (px) from the box's left-middle frame | | `placeholderOffsetX` / `placeholderOffsetY` | `number` | `8` / vertically centered | Placeholder position offset (px), same frame as the typed value | -The box uses `background`/`backgroundHover`/`backgroundPressed`/`backgroundLocked` for per-state texturing — the same shape as [`Button`](../controls/Button.md); `backgroundPressed` doubles as the focused-field state. +The box uses `background`/`backgroundHover`/`backgroundPressed`/`backgroundLocked` for per-state texturing — the same shape as [`Button`](./Button.md); `backgroundPressed` doubles as the focused-field state. -Inherits [control props](../control-props.md). +Inherits [control props](./control-props.md). ## Examples @@ -66,4 +65,4 @@ Inherits [control props](../control-props.md). ## Limits -Modal-only. The engine draws no text field on an action form or a container screen, so writing one there is a build error naming the fix rather than a control drawn inert. [``](../controls/Toggle.md) and [``](./Select.md) are the controls that serve all three hosts. diff --git a/docs/ui/components/controls/Link.md b/docs/ui/components/Link.md similarity index 74% rename from docs/ui/components/controls/Link.md rename to docs/ui/components/Link.md index 005d67c..8420a9f 100644 --- a/docs/ui/components/controls/Link.md +++ b/docs/ui/components/Link.md @@ -1,5 +1,4 @@ --- -sidebar_position: 2 description: "A button whose destination is data, so the build can read where it leads." --- # Link @@ -26,14 +25,14 @@ import { Link } from '@bedrock-core/ui'; | --- | --- | --- | --- | | `to` | `ScreenKey` | — | The screen to open, `:` as the build wrote it | | `back` | `boolean` | `false` | Go back to the screen the player came from, whatever it was; set instead of `to` | -| `params` | `Record` | — | Props the target screen is rendered with; they fill what the layout already reserved | +| `params` | `Record` | — | Props the target screen is rendered with; they fill what the layout already reserved. On a static screen, plain data only: strings, finite numbers, booleans, null, and arrays and objects of those | | `replace` | `boolean` | `false` | Take the place of this screen rather than stacking over it | -Inherits every prop of [`
    @@ -29,7 +28,7 @@ export default function Players(): JSX.Element { } ``` -A screen's root names its [host](../../guides/hosts.md), and there is no default. `` makes it an action form the way [`
    `](./Form.md) makes it a native modal and [``](./Container.md) a container screen. It has no box of its own: its children are laid out against the form canvas exactly as they would be at the top of the tree. +A screen's root names its [host](../guides/hosts.md), and there is no default. `` makes it an action form the way [``](./Form.md) makes it a native modal and [``](./Container.md) a container screen. It has no box of its own: its children are laid out against the form canvas exactly as they would be at the top of the tree. ## Props @@ -38,11 +37,11 @@ A screen's root names its [host](../../guides/hosts.md), and there is no default | `static` | `boolean` | `false` | Declare that the screen carries no live value and no press of its own | | `children` | `JSX.Node` | — | The screen's content | -`Screen` takes no [control props](../control-props.md): it is a marker, not a panel. Put a `Panel` inside it for a background, padding or a direction. +`Screen` takes no [control props](./control-props.md): it is a marker, not a panel. Put a `Panel` inside it for a background, padding or a direction. ## static -A screen is static when every string it shows is baked and every press is a [``](../controls/Link.md) or the way out. Such a screen needs nothing at runtime — the build already knows its title, the value each entry is shown with, and where each press leads — so the addon ships that table instead of the component, and any realm can show it. See [static screens](../../guides/navigation.md#static-screens). +A screen is static when every string it shows is baked and every press is a [``](./Link.md) or the way out. Such a screen needs nothing at runtime — the build already knows its title, the value each entry is shown with, and where each press leads — so the addon ships that table instead of the component, and any realm can show it. See [static screens](../guides/navigation.md#static-screens). Setting `static` both asks for that and **proves** it. A qualifying screen is detected either way; declaring it fails the build the moment the screen starts carrying live text, a carried `visible`, or a handler the build cannot read. @@ -65,7 +64,7 @@ The build and `render()` enforce these, with a message naming the fix. ### An embedded page -A page drawn into an area another screen leaves is still a screen of its own, so it starts with ``; the [``](../cross-pack/Embed.md) inside it is what fills the area. +A page drawn into an area another screen leaves is still a screen of its own, so it starts with ``; the [``](./Embed.md) inside it is what fills the area. ```tsx export default function FrameworkPage(): JSX.Element { @@ -79,4 +78,4 @@ export default function FrameworkPage(): JSX.Element { ## Notes -A screen file is a `*.screen.tsx` under `BP/scripts` with a default export. That is what the [`ui-compiler` filter](/docs/filters/ui-compiler) compiles, and the filename without the suffix is the screen's [key](../../guides/navigation.md#screen-keys). +A screen file is a `*.screen.tsx` under `BP/scripts` with a default export. That is what the [`ui-compiler` filter](/docs/filters/ui-compiler) compiles, and the filename without the suffix is the screen's [key](../guides/navigation.md#screen-keys). diff --git a/docs/ui/components/layout/Scroll.md b/docs/ui/components/Scroll.md similarity index 96% rename from docs/ui/components/layout/Scroll.md rename to docs/ui/components/Scroll.md index e268ad3..a620dc8 100644 --- a/docs/ui/components/layout/Scroll.md +++ b/docs/ui/components/Scroll.md @@ -1,5 +1,4 @@ --- -sidebar_position: 2 description: "One independent vertical scroll region, laid out in the parent flow like a panel." --- @@ -24,7 +23,7 @@ scroll, so simple UIs need none. | --- | --- | --- | --- | | `children` | `JSX.Node` | — | The content laid out inside this scroll's viewport | -Inherits [control props](../control-props.md) and they size and +Inherits [control props](./control-props.md) and they size and position its **viewport** in the parent's flex flow, exactly like a ``. An un-sized, non-absolute scroll defaults to `flexGrow: 1` so bare ``s share the parent's space; `width`/`height` override that, and `position={'absolute'}` + `top`/`left` take it out of the flow. diff --git a/docs/ui/components/Select.md b/docs/ui/components/Select.md new file mode 100644 index 0000000..89275b4 --- /dev/null +++ b/docs/ui/components/Select.md @@ -0,0 +1,85 @@ +--- +description: "Choices with every option visible inline (no popup): one, or any number with multiple." +--- +# Select + +Choices out of several, with every option visible: one, or any number with `multiple`. + +`Select` works on all three hosts and draws differently on each: a native field inside a [``](./Form.md), a press per option on a [``](./Screen.md), and a cell per option on a [``](./Container.md). [``](./Dropdown.md) is the same selection model behind a popup, and only a modal can draw one. + +## Import + +```tsx +import { Form, Option, Select } from '@bedrock-core/ui'; +``` + +## Usage + +```tsx + console.warn(v.team)}> + + {'Save'} + +``` + +:::caution Result is an index, not a value +Just like [`Dropdown`](./Dropdown.md), `Select` reports the selected option's **index** (a `number`) at `values[name]`, not its `value` string. With `multiple` it reports the **indices** that are on (a `number[]`, in option order, `[]` when none are). Map them back to your own options array if you need the strings. +::: + +## Props + +| Prop | Type | Default | Description | +| --- | --- | --- | --- | +| `name` | `string` | — | Result key — the selected index, or the indices with `multiple`, appear at `values[name]` in the form's `onSubmit` | +| `multiple` | `boolean` | `false` | Any number of options may be on at once. On a modal each option is a native toggle of its own, all answering under `name` | +| `value` | `string`, or `string[]` with `multiple` | — | The chosen options' values, held by the caller instead of by the control. Only where a press reaches script | +| `onChange` | `(value: string) => void`, or `(values: string[]) => void` with `multiple` | — | Called with the chosen option's `value`, or every chosen value in option order, on the hosts where a press reaches script | +| `defaultValue` | `string`, or `string[]` with `multiple` | the first option, or none with `multiple` | Initial selection, matched against an [`Option`](./Option.md)'s `value` | +| `children` | `JSX.Node` | — | The selectable options, authored as [`Option`](./Option.md) elements. Unlike `Dropdown`'s popup rows, each option here is laid out by the normal flex engine — position it with ordinary layout props (`flex`, `gap`, `width`, …) | +| `optionBackground` / `optionHover` / `optionSelected` | `string` | — | Group-level default row textures for idle/hover/selected states. Any `Option` can override its own | +| `bullet` / `bulletSelected` | `string` | — | Unselected/selected bullet glyph texture (e.g. a radio dot). Leave both empty for a segmented, bullet-less look | +| `bulletHover` / `bulletSelectedHover` | `string` | falls back to `bullet` / `bulletSelected` | Bullet glyph shown on hover | +| `bulletWidth` / `bulletHeight` | `number` | `12` | Bullet glyph size (px) | +| `optionFont` / `optionScale` / `optionAlign` | `TextFont` / `number` / `'left' \| 'center' \| 'right'` | — | Group-level default label styling for option rows. Any `Option` can override its own | +| `optionColor` / `optionColorSelected` | `[number, number, number]` | the label's own; `optionColorSelected` falls back to `optionColor` | Group-level default label colour at rest and while selected, RGB in 0..1. Any `Option` can override its own | +| `optionDropSelected` | `number` | `0` | How far an option's label sits lower while selected, in px | + +Inherits [control props](./control-props.md). + +## Examples + +### Radio-style inline select + +```tsx + +``` + +### Several at once + +```tsx +
    console.warn(values.notices)}> + + {'Save'} +
    +``` + +## Notes + +- Prefer `Select` over `Dropdown` when the option count is small and you want everything visible without an extra tap. +- Keep `Option` children order stable across renders — the result is an index-based, like `Dropdown`. +- This is the primitive [`@bedrock-core/ore-styled`](/docs/ore-styled)'s [`Radio`](/docs/ore-styled/Radio) and [`ToggleButtons`](/docs/ore-styled/ToggleButtons) are built on — reach for those on a themed screen rather than styling this by hand. + +## Limits + +On a modal the answer is the chosen option's **index**, not its value — the native dropdown's behavior — and with `multiple` the indices that are on. Where a press reaches script instead, the values are what come back. See the [capability table](../guides/hosts.md#what-each-host-can-carry). diff --git a/docs/ui/components/fields/Slider.md b/docs/ui/components/Slider.md similarity index 85% rename from docs/ui/components/fields/Slider.md rename to docs/ui/components/Slider.md index 9fcb61b..5150a46 100644 --- a/docs/ui/components/fields/Slider.md +++ b/docs/ui/components/Slider.md @@ -1,15 +1,14 @@ --- -sidebar_position: 2 description: "Numeric field drawn as a track + thumb, for use inside a Form." --- # Slider -Numeric field drawn as a track + thumb, for use inside a [`Form`](../roots/Form.md). +Numeric field drawn as a track + thumb, for use inside a [`Form`](./Form.md). ## Import ```tsx -import { Form } from '@bedrock-core/ui'; +import { Form, Slider } from '@bedrock-core/ui'; ``` ## Usage @@ -17,7 +16,7 @@ import { Form } from '@bedrock-core/ui'; ```tsx
    console.warn(v.volume)}> - + {'Save'} ``` @@ -40,9 +39,9 @@ import { Form } from '@bedrock-core/ui'; | `trackHeight` | `number` | `10` | Height (px) of the track + progress fill. The track always spans the full control width and is vertically centered | | `thumbWidth` / `thumbHeight` | `number` | `16` | Size (px) of the draggable thumb. The interactive hitbox is a fixed 16×16, so keep the visual thumb at the default size unless you've confirmed the mismatch is acceptable | -The track uses `background`/`backgroundHover`/`backgroundPressed`/`backgroundLocked` for per-state texturing — the same shape as [`Button`](../controls/Button.md). +The track uses `background`/`backgroundHover`/`backgroundPressed`/`backgroundLocked` for per-state texturing — the same shape as [`Button`](./Button.md). -Inherits [control props](../control-props.md). Defaults to `width: '100%'` when no explicit sizing is given. +Inherits [control props](./control-props.md). Defaults to `width: '100%'` when no explicit sizing is given. ## Examples @@ -66,4 +65,4 @@ Inherits [control props](../control-props.md). Defaults to `width: '100%'` when ## Limits -Modal-only. The engine draws no slider on an action form or a container screen, so writing one there is a build error naming the fix rather than a control drawn inert. [``](../controls/Toggle.md) and [``](./Select.md) are the controls that serve all three hosts. diff --git a/docs/ui/components/cells/Slot.md b/docs/ui/components/Slot.md similarity index 65% rename from docs/ui/components/cells/Slot.md rename to docs/ui/components/Slot.md index 896aa38..6674010 100644 --- a/docs/ui/components/cells/Slot.md +++ b/docs/ui/components/Slot.md @@ -1,10 +1,9 @@ --- -sidebar_position: 1 description: "A real container cell inside a container screen: the player moves items through it, and the screen sees what arrives." --- # Slot -A real container cell inside a [container screen](../../guides/container-screens.md): the player moves items through it, and the screen sees what arrives. +A real container cell inside a [container screen](../guides/container-screens.md): the player moves items through it, and the screen sees what arrives. ## Import @@ -29,14 +28,15 @@ Handlers are props, like everywhere else in this library. They are matched to th | Prop | Type | Default | Description | | --- | --- | --- | --- | +| `name` | `string` | — | What addon logic calls this cell: `container.getItem('output')` reaches it instead of a counted index. Own slots only, and unique within a screen — see [Naming a cell](#naming-a-cell) | | `role` | `'both' \| 'input' \| 'output'` | `'both'` | What an interactive slot lets the player do; see [Roles](#roles) | | `interactive` | `boolean` | `true` | Whether the player can move items through the slot at all. `false` draws an inert cell — the item shows, but no take, place or drop reaches it, and `role` does not apply | -| `onInsert` | `(event: SlotEvent) => void` | — | Runs after an item arrives. `event.stack` is what landed, `event.player` who put it there, `event.host` the entity that owns the screen | -| `onRemove` | `(event: SlotEvent) => void` | — | Runs after the slot empties. `event.stack` is what left, `event.player` who took it, `event.host` the entity that owns the screen | +| `onInsert` | `(event: SlotEvent) => void` | — | Runs after an item arrives. `event.stack` is what landed, `event.player` who put it there, `event.host` the entity or block that owns the screen, `event.container` its own cells | +| `onRemove` | `(event: SlotEvent) => void` | — | Runs after the slot empties. `event.stack` is what left, `event.player` who took it, `event.host` the entity or block that owns the screen, `event.container` its own cells | | `collection` | `string` | — | A JSON UI collection to read instead of the screen's own — `inventory_items`, `hotbar_items`, or any collection the engine exposes. Given one, the slot is **foreign**: it draws `collection[index]`, takes no slot of the screen's own container, and the runtime never polls it | | `index` | `number` | — | The cell within `collection` to draw. Required, and only legal, alongside `collection`; an integer `>= 0` | -Inherits [control props](../control-props.md). Leave `width` and `height` alone — the cell is 18 × 18 whatever the layout asks for — and use margins and `alignSelf` to place it. +Inherits [control props](./control-props.md). Leave `width` and `height` alone — the cell is 18 × 18 whatever the layout asks for — and use margins and `alignSelf` to place it. ### Roles @@ -50,6 +50,39 @@ An `output` slot with no result holds the runtime's marker item, so it is never A role is ignored on a foreign or locked slot. Q drops nothing from any container slot — dropping happens outside a container — so an input slot needs no special handling for the one take the undo could not reach. +### Naming a cell + +A screen's own cells are reached through `event.container` inside the component and through `screen.container(host)` outside it — the engine's own [`Container`](https://learn.microsoft.com/minecraft/creator/scriptapi/minecraft/server/container), addressed by index or by name; see [Reaching the cells](../guides/container-screens.md#reaching-the-cells). A `name` is how one particular cell is picked out of them: + +```tsx +{/* The nine inputs are interchangeable, so none of them is named. */} +{Array.from({ length: 9 }, (_, index) => )} + +{/* The result is the one cell the recipe addresses. */} + +``` + +```ts +for (let slot = 0; slot < container.size; slot += 1) { + if (container.getSlot(slot).name === undefined) { + // One of the nine inputs. + } +} + +if (container.getItem('output') === undefined) { + container.setItem('output', new ItemStack('minecraft:crafting_table', 1)); +} +``` + +Most cells want no name. An unnamed cell is found by walking the container's indices, which is what a grid of interchangeable inputs wants; a name is for the cell whose job is different from its neighbours'. Every name a screen declares is in `container.names`, mapped to its index. + +Two things are build errors, with a message naming the fix: + +- `name` on a **foreign** slot. A name reaches a cell of the container the screen owns, and a foreign slot draws someone else's collection. +- Two own slots sharing a name. A name reaches one cell, so it has to be unique within a screen — two screens may use the same name freely. + +Buttons are not nameable: a press is delivered to its own handler, so there is nothing to look up. + ### Own versus foreign An **own** slot (no `collection`) is a cell of the screen's own container: it is allocated a container index, the runtime polls it, and `role` enforces `input` / `output` a tick later by undoing a forbidden move. A **foreign** slot (`collection` + `index`) reads some other collection at an author-given index; it is never allocated and never polled, so `role` has no meaning there and combining the two throws. @@ -93,7 +126,7 @@ function Furnace() {
    ``` -Every slot costs one index in the entity's inventory; the build sizes the container to fit them all. +Every slot costs one index in the host's container; the build sizes it to fit them all. ### A peek at the player's hotbar diff --git a/docs/ui/components/cells/SlotGrid.md b/docs/ui/components/SlotGrid.md similarity index 90% rename from docs/ui/components/cells/SlotGrid.md rename to docs/ui/components/SlotGrid.md index 5fd32fa..cc56cac 100644 --- a/docs/ui/components/cells/SlotGrid.md +++ b/docs/ui/components/SlotGrid.md @@ -1,10 +1,9 @@ --- -sidebar_position: 2 description: "A grid of cells over a JSON UI collection the screen does not own, inside a container screen: the player's own inventory, another container's items, or any…" --- # SlotGrid -A grid of cells over a JSON UI collection the screen does not own, inside a [container screen](../../guides/container-screens.md): the player's own inventory, another container's items, or any collection the engine exposes. +A grid of cells over a JSON UI collection the screen does not own, inside a [container screen](../guides/container-screens.md): the player's own inventory, another container's items, or any collection the engine exposes. ## Import @@ -33,7 +32,7 @@ Its size is fixed by the cell: `columns × rows` cells of 18 texels each. Lay it | `interactive` | `boolean` | `true` | Whether the player can move items through the cells. `false` makes the grid inert — no take, no place, no drop | | `hideOwned` | `boolean` | `false` | Draw the cell that hides the runtime's transport item. Only relevant for the player's own inventory and hotbar, where a button's transport is auto-placed for the tick it takes the runtime to reclaim it — otherwise it would flash there | -Inherits [control props](../control-props.md). Its size is fixed by the cell; use `alignSelf`, margins and the surrounding panel to place it. +Inherits [control props](./control-props.md). Its size is fixed by the cell; use `alignSelf`, margins and the surrounding panel to place it. A container slot's take and place are one combined engine action, so there is no take-only or place-only grid: interactivity is all-or-nothing, and `false` is the way to make a grid purely a display. diff --git a/docs/ui/components/compiled/Tabs.md b/docs/ui/components/Tabs.md similarity index 75% rename from docs/ui/components/compiled/Tabs.md rename to docs/ui/components/Tabs.md index a4e05bc..816c3ff 100644 --- a/docs/ui/components/compiled/Tabs.md +++ b/docs/ui/components/Tabs.md @@ -1,5 +1,4 @@ --- -sidebar_position: 1 description: "Several panes on one screen, switched on the client with nothing reaching script." --- # Tabs @@ -32,6 +31,9 @@ import { Tabs } from '@bedrock-core/ui'; | Prop | Type | Default | Description | | --- | --- | --- | --- | | `tabHeight` | `number` | `20` | Height of the header row in texels; the panes take what is left | +| `tabBackground` | `string` | `'textures/ui/unstyled'` | The face every header is drawn on while its tab is not chosen | +| `tabHover` | `string` | `tabBackground` | The face while the pointer is over a tab that is not chosen | +| `tabSelected` | `string` | `tabBackground` | The face while its tab is the chosen one | ### Tabs.Tab @@ -40,7 +42,7 @@ import { Tabs } from '@bedrock-core/ui'; | `header` | `JSX.Element` | — | The header while this tab is not the chosen one | | `headerSelected` | `JSX.Element` | `header` | The header while it is | -Both inherit [control props](../control-props.md). +Both inherit [control props](./control-props.md). A header is drawn on its face: the face fills the tab, and `header` or `headerSelected` sits on it. [`@bedrock-core/ore-styled`](/docs/ore-styled/Tabs)'s `Tabs` sets all three faces from the theme and takes a label instead of a drawn header. ## What it costs @@ -50,7 +52,7 @@ What you pay instead is pack size. Every tab's content is in the tree at once, s ## When it is a screen instead -What you give up is exactly what "the server never hears it" means: no handler runs on a switch, and nothing outside the group can know which tab is open. A tab whose content depends on the switch is a screen change, not a tab — use [``](../controls/Link.md) or `navigate()`. +What you give up is exactly what "the server never hears it" means: no handler runs on a switch, and nothing outside the group can know which tab is open. A tab whose content depends on the switch is a screen change, not a tab — use [``](./Link.md) or `navigate()`. ## Notes diff --git a/docs/ui/components/content/Text.md b/docs/ui/components/Text.md similarity index 75% rename from docs/ui/components/content/Text.md rename to docs/ui/components/Text.md index b1ad7dd..a055e22 100644 --- a/docs/ui/components/content/Text.md +++ b/docs/ui/components/Text.md @@ -1,5 +1,4 @@ --- -sidebar_position: 1 description: "Display text content in your UI." --- # Text @@ -24,20 +23,20 @@ import { Text } from '@bedrock-core/ui'; | Prop | Type | Default | Description | | --- | --- | --- | --- | -| `children` | [`DisplayText`](/docs/i18n#displaytext) (`string \| RawMessage`) | — | The text to display. A single child only — arrays throw. Strings are auto-detected as keys or literals; `RawMessage` values are always localized. See [One text channel](#one-text-channel) | +| `children` | [`DisplayText`](/docs/i18n/api#displaytext) (`string \| RawMessage`) | — | The text to display. A single child only — arrays throw. Strings are auto-detected as keys or literals; `RawMessage` values are always localized. See [One text channel](#one-text-channel) | | `font` | `'mojangles' \| 'minecraftTen'` | `'mojangles'` | Font selection | | `scale` | `number` | `1.0` | Scale multiplier relative to the standard "normal" glyph size. Values below `1.0` produce smaller text; values above `1.0` produce larger text | | `wordBreak` | `'normal' \| 'break-word'` | — | When set to `'break-word'`, text automatically wraps at word boundaries (with hyphens for mid-word breaks). Width comes from the container — no explicit `maxWidth` needed | -| `overflow` | `'ellipsis'` | — | When set, text that overflows its container is truncated with `…` | +| `overflow` | `'ellipsis'` | — | When set, text that overflows its container is truncated with `...` | | `maxLines` | `number` | — | Limit rendered text to N lines. The last line is always ellipsized when content overflows | -| `maxLength` | `number` | — | The most characters the text will ever need. In a [container screen](../../guides/container-screens.md) this is what makes the text **live**: a compiled layout cannot grow, so a string that changes at runtime reserves its cells before the build knows what it will say — one container slot per character, decoded through a 64-glyph table (space, `A–Z`, `a–z`, `0–9`, `.`; anything else, formatting codes included, draws as a blank). Leave it off for text that never changes, which is baked and may use any character at all. In a server form the text is live anyway; a literal string is cut to this length so the two backends agree on what fits, while keys and `RawMessage`s the client resolves are left whole | +| `maxLength` | `number` | — | The most characters the text will ever need. In a [container screen](../guides/container-screens.md) this is what makes the text **live**: a compiled layout cannot grow, so a string that changes at runtime reserves its cells before the build knows what it will say — one container slot per character, decoded through a 64-glyph table (space, `A–Z`, `a–z`, `0–9`, `.`; anything else, formatting codes included, draws as a blank). Leave it off for text that never changes, which is baked and may use any character at all. In a server form the text is live anyway; a literal string is cut to this length so the two backends agree on what fits, while keys and `RawMessage`s the client resolves are left whole | | `shadow` | `boolean` | `false` | Draw a drop shadow behind the glyphs. Purely visual — it does not affect layout or text metrics | | `color` | `[number, number, number]` | — | Glyph color as RGB in `0..1`. For text a `§` code cannot color: a localization key, whose value the client resolves. Compiled screens only | | `textAlign` | `'left' \| 'center' \| 'right'` | `'left'` | Where the glyphs sit in the label's box. Only shows when the box is wider than the text: give the text a `width`, or let it grow. Compiled screens only | | `offsetX` / `offsetY` | `number` | `0` | Fine-tune the pixel nudge of the rendered label inside its layout box. The box itself does not move | -| `hug` | `boolean` | `false` | Draw the label at the width of its glyphs rather than in the box the layout solved, and let the engine place what follows. Only inside a [``](../layout/Panel.md#stack) | +| `hug` | `boolean` | `false` | Draw the label at the width of its glyphs rather than in the box the layout solved, and let the engine place what follows. Only inside a [``](./Panel.md#stack) | -Inherits [control props](../control-props.md). +Inherits [control props](./control-props.md). ## Examples @@ -60,7 +59,7 @@ function Counter() { return ( {`Count: ${count}`} - @@ -96,7 +95,7 @@ function Greeting() { ``` :::tip Which verb? -`key()` and `raw()` keep resolution on the client, so each player reads the text in their own language. `t()` resolves server-side in the player's currently resolved locale — reach for it when you need to compose the string yourself (concatenating formatting codes, building a template). Full write-up in [The three verbs](/docs/i18n#the-three-verbs). +`key()` and `raw()` keep resolution on the client, so each player reads the text in their own language. `t()` resolves server-side in the player's currently resolved locale — reach for it when you need to compose the string yourself (concatenating formatting codes, building a template). Full write-up in [The three verbs](/docs/i18n/api#the-three-verbs). ::: ### Wrapped & truncated text @@ -123,6 +122,28 @@ Wrapping works for localized children too — a localized child wraps against it {'§eBig Title'} ``` +### Text composed per language + +```tsx +function Title(): JSX.Element { + const composed = useComposed((resolve, width) => { + const long = resolve('drav0011_shop.title.long') ?? ''; + + return width === undefined || measureText({ text: long }).width <= width + ? long + : resolve('drav0011_shop.title.short') ?? ''; + }); + + return ( + + + + ); +} +``` + +The build composes the title once for every language the pack ships, at the width the panel is laid out at, and the player reads their own. See [`useComposed`](../hooks/useComposed.md). + ### Live text in a container screen ```tsx @@ -157,7 +178,7 @@ function Furnace() { ## One text channel -`Text` takes a **single** child of type [`DisplayText`](/docs/i18n#displaytext) — `string | RawMessage`. Literal text and localized text ride the same channel, and which one you get is detected rather than declared. +`Text` takes a **single** child of type [`DisplayText`](/docs/i18n/api#displaytext) — `string | RawMessage`. Literal text and localized text ride the same channel, and which one you get is detected rather than declared. - A **`string`** is auto-detected. If the active translation resolver knows it as a key (a `key()` result, a registry display field, any published `.lang` key), it is localized — the client resolves it in its own language. If nothing resolves it, it paints literally, which is exactly how Bedrock treats an unmatched key anyway. - A **`RawMessage`** (a `raw()` result) is always localized. The **client** resolves and fills it — its own language, no length cap, `score`/`selector` parts included. @@ -174,7 +195,7 @@ import { createI18n } from '@bedrock-core/i18n'; export const i18n = createI18n(bundle); ``` -Inside components, bind [the typed verbs](/docs/i18n#the-three-verbs) with [`useTranslation(i18n)`](../../hooks/useTranslation.md); outside them, use `i18n.forPlayer(player)` / `i18n.forLocale(locale)`. +Inside components, bind [the typed verbs](/docs/i18n/api#the-three-verbs) with [`useTranslation(i18n)`](../hooks/useTranslation.md); outside them, use `i18n.forPlayer(player)` / `i18n.forLocale(locale)`. The bundle comes from the [i18n filter](/docs/filters/i18n); a [CLI](/docs/cli) scaffold has both wired. ::: diff --git a/docs/ui/components/controls/Toggle.md b/docs/ui/components/Toggle.md similarity index 68% rename from docs/ui/components/controls/Toggle.md rename to docs/ui/components/Toggle.md index 5e60587..63be8b4 100644 --- a/docs/ui/components/controls/Toggle.md +++ b/docs/ui/components/Toggle.md @@ -1,5 +1,4 @@ --- -sidebar_position: 3 description: "A boolean. A native field on a modal, a press that flips on a screen, a slot on a container." --- # Toggle @@ -20,13 +19,13 @@ import { Toggle } from '@bedrock-core/ui'; ## One component, three mechanisms -`Toggle` asks [`useMechanism('Toggle')`](../../hooks/useMechanism.md) what a boolean becomes on the screen it is being drawn on, and draws that. The component is written once; what differs is the host. +`Toggle` asks [`useMechanism('Toggle')`](../hooks/useMechanism.md) what a boolean becomes on the screen it is being drawn on, and draws that. The component is written once; what differs is the host. | Screen | What it is | How the value moves | | --- | --- | --- | -| [`
    `](../roots/Form.md) | a native field the engine owns | nothing until submit, then `values[name]` | -| [``](../roots/Screen.md) | a button that flips its state and renders the screen again | `onChange` on the press; the player sees the new state on the next present | -| [``](../roots/Container.md) | a cell of the entity's container — the press is an item taken and put straight back | `onChange` on the press; the slots settle in the same tick | +| [``](./Form.md) | a native field the engine owns | nothing until submit, then `values[name]` | +| [``](./Screen.md) | a button that flips its state and renders the screen again | `onChange` on the press; the player sees the new state on the next present | +| [``](./Container.md) | a cell of the host's container — the press is an item taken and put straight back | `onChange` on the press; the slots settle in the same tick | So `name` is what the modal reports under, and `on` / `onChange` are what the two press hosts give you. Write all of them and the control moves between screens unchanged: each host uses the ones it can. @@ -43,7 +42,7 @@ So `name` is what the modal reports under, and `on` / `onChange` are what the tw | `checkedBackground` | `string` | the resolved `background` | The checked face | | `checkedHover` / `checkedLocked` | `string` | `checkedBackground` | The checked face per state | -Inherits [control props](../control-props.md). Geometry is solved by the layout like any other component and encoded for the render pack, so a native widget is positioned by the same flexbox as everything else. +Inherits [control props](./control-props.md). Geometry is solved by the layout like any other component and encoded for the render pack, so a native widget is positioned by the same flexbox as everything else. ## Examples @@ -52,7 +51,7 @@ Inherits [control props](../control-props.md). Geometry is solved by the layout ```tsx setMusic(values.music === true)}> - + {'Save'} ``` @@ -76,7 +75,7 @@ The press re-presents the screen, which is how the player sees the flip — a fo ``` -The cell takes one index in the entity's container. A press is an item taken and put straight back, so the handler runs and the slots settle in the same tick. +The cell takes one index in the host's container. A press is an item taken and put straight back, so the handler runs and the slots settle in the same tick. ## Notes diff --git a/docs/ui/components/Trans.md b/docs/ui/components/Trans.md new file mode 100644 index 0000000..81c8007 --- /dev/null +++ b/docs/ui/components/Trans.md @@ -0,0 +1,114 @@ +--- +description: "A translated text whose tags are components, presses and styles, drawn exactly where their text falls in whichever language the player reads it." +--- +# Trans + +A translated text whose tags are components, drawn exactly where their text falls in whichever language the player reads it. It follows react-i18next's `Trans`: the string carries named tags, and `components` says what each one is. + +## Import + +```tsx +import { Trans } from '@bedrock-core/ui'; +``` + +## Usage + +```ts +// packs/data/i18n/en_US.ts +help: { prices: 'See the shop for today\'s prices.' }, +// packs/data/i18n/es_ES.ts +help: { prices: 'Mira los precios de hoy en la tienda.' }, +``` + +```tsx + $.help.prices)} + components={{ + shop: , + gold: , + }} +/> +``` + +The Spanish string puts the two tags in the other order. Components are matched by name, so each language keeps its own. + +## Props + +| Prop | Type | Default | Description | +| --- | --- | --- | --- | +| `i18nKey` | `string` | — | The key the text is written under, as [`key()`](/docs/i18n/api#the-three-verbs) returns it. The build reads it in every language the pack ships | +| `translations` | `Record` | — | The text in every language, by locale, in place of `i18nKey`: for a tool that writes its own | +| `components` | `Record \| JSX.Element[]` | — | What each tag stands for, by name, or by index for `<0>`, `<1>` and so on | +| `font` | `'mojangles' \| 'minecraftTen'` | `'mojangles'` | Font of the whole text | +| `scale` | `number` | `1.0` | Scale of the whole text, as on [``](./Text.md) | +| `shadow` | `boolean` | `false` | Draw a drop shadow behind the whole text | +| `color` | `[number, number, number]` | — | Glyph color of the whole text as RGB in `0..1` | + +Inherits [control props](./control-props.md). + +## Tags + +| Tag | Draws its content | +| --- | --- | +| `…`, `name` a `` | in that text's `color` and `shadow` | +| `…`, `name` anything else | inside that component, as a press hugging the text: a ``, a `} +{isAdmin && } ``` becomes ` - -``` - -:::caution Result is an index, not a value -Just like [`Dropdown`](../fields/Dropdown.md), `Select` reports the selected option's **index** (a `number`) at `values[name]`, not its `value` string. Map the index back to your own options array if you need the string. -::: - -## Props - -| Prop | Type | Default | Description | -| --- | --- | --- | --- | -| `name` | `string` | — | Result key — the selected index appears at `values[name]` in the form's `onSubmit` | -| `defaultValue` | `string` | the first option | Initial selection, matched against a [`Option`](./Option.md)'s `value` | -| `children` | `JSX.Node` | — | The selectable options, authored as [`Option`](./Option.md) elements. Unlike `Dropdown`'s popup rows, each option here is laid out by the normal flex engine — position it with ordinary layout props (`flex`, `gap`, `width`, …) | -| `optionBackground` / `optionHover` / `optionSelected` | `string` | — | Group-level default row textures for idle/hover/selected states. Any `Option` can override its own | -| `bullet` / `bulletSelected` | `string` | — | Unselected/selected bullet glyph texture (e.g. a radio dot). Leave both empty for a segmented, bullet-less look | -| `bulletHover` / `bulletSelectedHover` | `string` | falls back to `bullet` / `bulletSelected` | Bullet glyph shown on hover | -| `bulletWidth` / `bulletHeight` | `number` | `12` | Bullet glyph size (px) | -| `optionFont` / `optionScale` / `optionAlign` | `LabelFont` / `number` / `'left' \| 'center' \| 'right'` | — | Group-level default label styling for option rows. Any `Option` can override its own | - -Inherits [control props](../control-props.md). - -## Examples - -### Radio-style inline select - -```tsx - -``` - -## Notes - -- Prefer `Select` over `Dropdown` when the option count is small and you want everything visible without an extra tap. -- Keep `Option` children order stable across renders — the result is an index-based, like `Dropdown`. -- This is the primitive [`@bedrock-core/ore-styled`](/docs/ore-styled)'s [`Radio`](/docs/ore-styled/Radio) and [`ToggleButtonGroup`](/docs/ore-styled/ToggleButton) are built on — reach for those on a themed screen rather than styling this by hand. - -## Limits - -On a modal the answer is the chosen option's **index**, not its value — the native dropdown's behavior. Where a press reaches script instead, the value is what comes back. See the [capability table](../../guides/hosts.md#what-each-host-can-carry). diff --git a/docs/ui/components/controls/_category_.json b/docs/ui/components/controls/_category_.json deleted file mode 100644 index 54573f2..0000000 --- a/docs/ui/components/controls/_category_.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "position": 5, - "label": "Controls", - "collapsible": true, - "collapsed": true, - "link": { - "type": "generated-index", - "title": "Controls", - "description": "A press, a destination, and the choices every host serves in its own way." - } -} diff --git a/docs/ui/components/cross-pack/_category_.json b/docs/ui/components/cross-pack/_category_.json deleted file mode 100644 index 14e64e8..0000000 --- a/docs/ui/components/cross-pack/_category_.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "position": 9, - "label": "Cross-pack", - "collapsible": true, - "collapsed": true, - "link": { - "type": "generated-index", - "title": "Cross-pack", - "description": "Drawing into, or being drawn into, another addon's screen." - } -} diff --git a/docs/ui/components/fields/_category_.json b/docs/ui/components/fields/_category_.json deleted file mode 100644 index 0e245b2..0000000 --- a/docs/ui/components/fields/_category_.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "position": 6, - "label": "Modal fields", - "collapsible": true, - "collapsed": true, - "link": { - "type": "generated-index", - "title": "Modal fields", - "description": "The three the engine only draws inside a `
    `: a text field, a slider and a popup. Anywhere else they are refused at build." - } -} diff --git a/docs/ui/components/layout/_category_.json b/docs/ui/components/layout/_category_.json deleted file mode 100644 index 5db7d0b..0000000 --- a/docs/ui/components/layout/_category_.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "position": 3, - "label": "Layout", - "collapsible": true, - "collapsed": true, - "link": { - "type": "generated-index", - "title": "Layout", - "description": "Boxes and flow: the panel, the scroll region and the wrapper that draws nothing." - } -} diff --git a/docs/ui/components/roots/Container.md b/docs/ui/components/roots/Container.md deleted file mode 100644 index d78c6d1..0000000 --- a/docs/ui/components/roots/Container.md +++ /dev/null @@ -1,69 +0,0 @@ ---- -sidebar_position: 3 -description: "The root of a container screen: names the entity the screen opens from, and is the screen's own panel." ---- -# Container - -The root of a [container screen](../../guides/container-screens.md): names the entity the screen opens from, and is the screen's own panel. - -## Import - -```tsx -import { Container } from '@bedrock-core/ui'; -``` - -## Usage - -```tsx -export default function Furnace() { - return ( - - {'§fFurnace'} - - - - - ); -} -``` - -Its presence decides the backend, the way [``](./Form.md) makes a screen a native modal: a tree rooted in a `Container` is laid out once at build time by the [ui-compiler filter](/docs/filters/ui-compiler), baked into JSON UI, and served by `createContainerScreen` to every player who opens the entity it names. `render()` rejects it — a container screen is compiled ahead of time, not serialized per player. - -## Props - -| Prop | Type | Default | Description | -| --- | --- | --- | --- | -| `entity` | `string` | — | Type of the entity the screen opens from, e.g. `'core:furnace'`. The build sizes that entity's `minecraft:inventory` and stamps it with the screen's layout key; the runtime serves the screen when a player interacts with it. The entity must exist in the behavior pack, or the build fails | -| `onOpen` | `(event: ContainerEvent) => void` | `undefined` | Ran when a player opens the screen, and again for every further viewer. `event.player` is who opened it and `event.host` the entity it opened. One layout serves everyone looking, so this is where a screen learns who is there — keep what it needs in state | -| `onClose` | `(event: ContainerEvent) => void` | `undefined` | Ran when a player closes the screen, or leaves the world with it open. `event.player` is who left, `event.host` the entity it belonged to | -| `children` | `JSX.Node` | — | The screen. Anything a form can hold except the [form-only components](../../guides/container-screens.md#not-supported), plus [`Slot`](../cells/Slot.md), [`PlayerInventory`](../cells/PlayerInventory.md) and [`Hotbar`](../cells/Hotbar.md) | - -Inherits [control props](../control-props.md). It is the screen's root panel, so `background` draws the frame and `padding` / `gap` / `flexDirection` lay the children out — the same way they would on a `Panel`. - -## Rules - -The build enforces these, with a message naming the fix: - -- **Exactly one, at the root.** Providers and fragments above it are looked through; anything else beside it is rejected, and a screen with no root at all is refused with the list of roots. -- **No nesting.** One entity opens one screen, and no root sits inside another — compose the inner part as a component instead. -- **The content fits the canvas.** A container screen is laid out on the same 320 × 210 canvas as a form, but it cannot scroll: content past the canvas fails the build rather than clipping. - -## Examples - -### A framed screen - -```tsx - - {'§lVault'} - - - - - - - - - -``` - -`PlayerInventory` and `Hotbar` are not free: a container screen owns the whole chest screen, so leave them out and the player's own grids are gone. diff --git a/docs/ui/components/roots/_category_.json b/docs/ui/components/roots/_category_.json deleted file mode 100644 index 575877a..0000000 --- a/docs/ui/components/roots/_category_.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "position": 2, - "label": "Roots", - "collapsible": true, - "collapsed": true, - "link": { - "type": "generated-index", - "title": "Roots", - "description": "The three roots. A screen's root names its host, and there is no default." - } -} From 1ec7f4f17461519592d8a1be057f94122f3e5c71 Mon Sep 17 00:00:00 2001 From: DrAv0011 Date: Thu, 17 Sep 2026 17:41:20 +0200 Subject: [PATCH 43/48] docs(ui): compiler pages for writing a screen, what the build writes, and its checks - Writing a screen: names and keys, reserved values, carried visibility, static screens and their link params, library and app screens, import time. - What the build writes: roots and mounts, entity and block hosts, text composed per language, the character table. - Build checks lists every check that stops a build, Trans included. Co-Authored-By: Claude Opus 5 (1M context) --- docs/ui/compiler/api.md | 6 +- docs/ui/compiler/checks.md | 31 ++++++++ docs/ui/compiler/index.md | 11 +-- docs/ui/compiler/output.md | 94 ++++++++++++++++++++++++ docs/ui/compiler/passes.md | 6 +- docs/ui/compiler/screens.md | 138 ++++++++++++++++++++++++++++++++++++ 6 files changed, 276 insertions(+), 10 deletions(-) create mode 100644 docs/ui/compiler/checks.md create mode 100644 docs/ui/compiler/output.md create mode 100644 docs/ui/compiler/screens.md diff --git a/docs/ui/compiler/api.md b/docs/ui/compiler/api.md index 7ef1411..a521ffc 100644 --- a/docs/ui/compiler/api.md +++ b/docs/ui/compiler/api.md @@ -1,5 +1,5 @@ --- -sidebar_position: 3 +sidebar_position: 6 description: "@bedrock-core/ui-compiler: the entry points the ui-compiler filter calls, and the limits the compiled model imposes." --- # @bedrock-core/ui-compiler @@ -8,6 +8,8 @@ The build-time library the [`ui-compiler` filter](/docs/filters/ui-compiler) run This page is for tooling. An addon never imports it — the filter does, and it bundles the compiler out of the **project's** `node_modules` rather than its own, so a screen is compiled by the version of the library the addon actually ships. An addon that compiles screens therefore depends on the compiler even though none of it reaches `main.js`. +The same holds for `@bedrock-core/ui-runtime`: the pipeline runs inside that bundle, so the filter cannot drift from the library. Every value the emitted JSON UI shares with the runtime — the character table, the layout property, the highest layout key — is read off it for the same reason. + ## Import ```ts @@ -67,5 +69,3 @@ The IR node types, the JSON UI control types, and the result shapes (`CompiledSc Percentages, `%c` and anchors are not exposed to authors. The layout solver is the one source of geometry and it produces pixel rects against a canvas the host names; JSON UI's relative sizes appear only where the engine has to decide at draw time — a stack sized so hidden rows collapse, a fill inside a box the layout already sized. A screen-relative canvas is a host property, never a prop. Sharing one parameterized frame between a look's states does not work. A frame resolves `caption@$core_content` in its own scope, where the variable was never set, so the reference names nothing and the control has no type: the client refuses every caption in the world. Sharing has to happen at the mount, with each consumer carrying the caption name along with the frame. - -A config screen shaped for a schema is compiled into the **owning** addon's pack, and the host draws every addon's config — so a host has shaped screens for its own sections and none for anybody else's. The list item is answered by generic fallbacks that ship in the library set, `list_item_text` and `list_item_choice`, which the host falls back to whenever the owner's shaped screen is not in its bundle. Other shaped screens have no fallback. diff --git a/docs/ui/compiler/checks.md b/docs/ui/compiler/checks.md new file mode 100644 index 0000000..6f9b6cd --- /dev/null +++ b/docs/ui/compiler/checks.md @@ -0,0 +1,31 @@ +--- +sidebar_position: 5 +description: "Every check that stops a compiled screen's build, and what fails it." +--- +# Build checks + +A failed check stops the build with the compiler's own message, which the [`ui-compiler` filter](/docs/filters/ui-compiler) relays unchanged, because those messages already name the fix. + +| Check | What fails | +| --- | --- | +| Root | A tree that starts with something other than ``, `` or ``; more than one element at a form's root; a `` naming neither `entity` nor `block`, or naming both | +| Shape | A screen that adds, drops or reorders a cell when its state changes | +| Live text | A `` whose string changes with no `maxLength`; the message names each string it saw and the length it needs | +| Carried visibility | A `visible` that moves on a container screen, which bakes it | +| Static | `` on a screen that carries a live value or runs a handler of its own, naming which | +| Trans | A tag left open or closed out of order, a placeholder in a `` string, a `` component setting more than `color` and `shadow`, a press inside a press, or a component that is neither | +| Canvas | Content laid out past 320 × 210, with the size it measured | +| Mechanism | A component the screen's host has no mechanism for — a slider or a dropdown outside a modal, a slot outside a container screen | +| Unsupported | A control with no compiled form at all, listing what is supported | +| Face rules | A face carrying a binding that reads a host, an image without `keep_ratio: false`, a label that does not say whether it localizes, two siblings of one name, a reference or `source_control_name` that resolves to nothing | +| Placement | A host that moved a control while standing its mechanism in, with the face's rect and the host's | +| Shared faces | A control that changes at runtime, or one needing a definition of its own, baked inside a button's face | +| Names | Two screens with the same name; a name or namespace outside letters, digits, `_` and `-` | +| Face collision | Two screens of one addon sharing a face name with different contents | +| Host | A screen naming an entity or block that has no definition under `BP/entities` or `BP/blocks`; two screens naming the same host | +| Block capacity | A block-hosted screen needing more than 54 container slots | +| Crafting table | A block-hosted screen naming a block that declares `minecraft:crafting_table` | +| Namespace | No `namespace` setting and no `manifest: { creator, pack }` in the register call | +| Import time | A module that reaches for the game while being evaluated | + +An entry that throws on the way to its `core.register()` call is a warning, not a failure: the addon gets none of the screens that follow from declaring, and the reason is printed rather than leaving a pack that builds clean with none of its app screens in it. diff --git a/docs/ui/compiler/index.md b/docs/ui/compiler/index.md index c968686..4211b4a 100644 --- a/docs/ui/compiler/index.md +++ b/docs/ui/compiler/index.md @@ -20,7 +20,7 @@ Four steps, each a pure function of the last. | Face | the IR | the face document — every control as its look alone, with no bindings at all | | Fill | the face document plus a host | the screen document the host serves | -Layout is solved once, at build, by [`@bedrock-core/flexbox`](/docs/flexbox) against a fixed 320 × 210 canvas. No geometry is measured in game and no layout is sent to the client. +Layout is solved at build, by [`@bedrock-core/flexbox`](/docs/flexbox) against a fixed 320 × 210 canvas. No geometry is measured in game and no layout is sent to the client. A screen with text composed per language — a [``](../components/Trans.md), a [`useComposed`](../hooks/useComposed.md) string — is laid out again at the widths the first layout gave that text. Which host a screen compiles for is decided by its root element, and there is no default — `` is an action form, `` a native modal, `` a chest screen. What differs between them is in [Hosts](../guides/hosts.md). @@ -30,13 +30,16 @@ Which host a screen compiles for is decided by its root element, and there is no **A capability model with names** — each host declares what every kind of component becomes on it. A `` outside a ``, a `` outside a container screen: refused at build, by name, in that host's own words, instead of drawn inert. -**A drawable document with no host behind it** — the face pass produces a complete screen on its own. That is what the static rules run over, what the [gallery](/docs/filters/ui-compiler#the-gallery) shows, and why nothing hidden can evaluate a binding that is not there. +**A drawable document with no host behind it** — the face pass produces a complete screen on its own. That is what the static rules run over, and why nothing hidden can evaluate a binding that is not there. -**A frozen shape** — a compiled screen cannot add or drop a control at runtime. Everything that varies says so in the source: [``](../components/compiled/List.md) for a count, [`maxLength`](../components/content/Text.md) for a string, `visible` for a branch. A render that drifts from what the build measured is reported by `render(screen, player, { debug: true })` rather than silently drawn wrong. +**A frozen shape** — a compiled screen cannot add or drop a control at runtime. Everything that varies says so in the source: [``](../components/List.md) for a count, [`maxLength`](../components/Text.md) for a string, `visible` for a branch. A render that drifts from what the build measured is reported by `render(screen, player, { debug: true })` rather than silently drawn wrong. ## Next steps +- [Writing a screen](./screens.md) — the `*.screen.tsx` file, reserved values, carried visibility and static screens +- [What the build writes](./output.md) — mounts, routing, host definitions and the text written per language - [Faces and hosts](./passes.md) — the two passes, the three layers, and the behaviors a primitive carries +- [Build checks](./checks.md) — everything that stops a build, and what fails it - [`@bedrock-core/ui-compiler`](./api.md) — the programmatic entry points, for tooling rather than for addons - [Hosts](../guides/hosts.md) — the three screens the library draws on, and what each can carry -- [`ui-compiler` filter](/docs/filters/ui-compiler) — running the compiler over a project +- [`ui-compiler` filter](/docs/filters/ui-compiler) — installing the filter and its settings diff --git a/docs/ui/compiler/output.md b/docs/ui/compiler/output.md new file mode 100644 index 0000000..46960b2 --- /dev/null +++ b/docs/ui/compiler/output.md @@ -0,0 +1,94 @@ +--- +sidebar_position: 3 +description: "Where a compiled screen is mounted, how the client picks its layout, what the build stamps onto an entity or block, and the text it writes per language." +--- +# What the build writes + +A compiled screen reaches the client as JSON UI in the addon's resource pack: one gated definition per screen, an insert that routes it onto the vanilla screen it is drawn on, and for a container screen, a stamp on the entity or block that opens it. + +## Roots and mounts + +The root the author writes names the host, and there is no default: `` for an action form, `` for a native modal, `` for a container screen — naming either `entity` or `block`. One file naming convention, one component set, three roots: + +| Root | Screen | Where the layout is mounted | Opened with | +| --- | --- | --- | --- | +| `` | an action form | the library's own container on the form screen | `render(Screen, player)` | +| `` | a native modal form | the same container, with the engine's fields in place | `render(Form, player)` | +| `` | a custom entity's container screen | the vanilla chest, through a hook and the addon's router | `createContainerScreen(Container)` | +| `` | a custom block's container screen | the vanilla data-driven container, through a second hook and the same router | `createContainerScreen(Container)` | + +A tree that starts with anything else — or a `` naming neither `entity` nor `block`, or both — is refused by the list of roots. [Hosts](../guides/hosts.md) covers what each screen can carry. + +## Routing + +Both hosts are reached the same way: one gated definition per screen under a root named for the addon, and one insert putting that root where the screen can see it. A gate compares the whole of what identifies the screen, so two screens can never both match. + +- **Form screens** gate on the form's title, which carries the protocol header and the screen's namespaced name. The library's own container is already gated on that header, so a compiled form needs no vanilla edit: the addon's root is inserted into the mount. The pack that *defines* the mount lists its root in the definition directly; every other pack inserts through `RP/ui/server_form.json`. +- **Container screens** gate on a layout key. A marker item in the container's first two slots carries a protocol key — is this container a compiled screen at all? — and the layout key as two stack sizes, and the router shows the layout whose key matches. An entity-hosted screen inserts the addon's root into `RP/ui/chest_screen.json`, at vanilla's `chest.small_chest_panel_top_half`; a block-hosted screen inserts the same root into `RP/ui/data_driven_container_screen.json`, at `data_driven_container.panel_top_half`. A vanilla chest or data-driven container has no marker, fails the first check and renders untouched. + +A screen's layout key is a hash of `_` folded into 1..3969. It depends on nothing but the screen's own name, so a rebuild never moves a key and an entity placed in a world keeps opening the screen it was stamped with; two addons built apart never claim the same key for their first screens. Two screens of one addon hashing alike is a build failure naming both. + +Every edit to a vanilla file is one `modifications` entry defining nothing, at vanilla's own path. That is the one kind of edit the engine stacks across packs in whatever order they sit — a definition in a vanilla file would replace vanilla's and every other pack's instead of joining them. The insert target declares its own `controls`, because an insert on a definition that merely inherits the array creates one that shadows it. + +## Host definitions + +A container screen names the entity or the block it opens from. The filter finds that host's definition under `BP/entities` or `BP/blocks` by its `identifier` — a screen naming a host that is not there fails the build — and stamps the workspace copy. + +### An entity (``) + +```jsonc +"description": { + "properties": { + // The runtime reads this when a player opens the entity, to pick the screen. + "core:ui_layout": { "type": "int", "range": [0, 3969], "default": 1094 } + } +}, +"components": { + "minecraft:inventory": { + "container_type": "container", // the only type that routes to the chest screen + "inventory_size": 75, // drawn slots + live channels; a hand-written value is overwritten + "private": false // `true` stops the player opening it at all + } +} +``` + +### A block (``) + +```jsonc +"description": { + "states": { + // One value, because a block type opens one screen. A string, not a number: the engine + // stores an integer state by its value in the block's state bits, and a layout key does + // not fit them, while a single string value costs none. + "core:ui_layout": ["1094"] + } +}, +"components": { + "minecraft:block_entity": { + "container": { "slot_count": 35 }, // drawn slots + live channels, 1..54 + "dynamic_properties": true // where the screen's state is kept + } +} +``` + +`minecraft:block_entity` cannot vary per permutation and cannot be combined with `minecraft:crafting_table` — the filter refuses a block that declares one, since a compiled screen needs the block entity for its own container. A block container holds 54 slots at most, the whole of a screen's allocation: the routing sentinel, every `` and `Button`, and one bank slot per character of every live ``. A screen that outgrows it either sheds cells or moves to an entity, whose inventory has no cap. + +Nobody keeps a container size or a layout key in step with a layout by hand — the failure mode of that is a screen that silently draws cells the container does not have, or a host that opens the wrong screen. Everything else on the entity or block is yours: its geometry, its behavior, whether it can be pushed or hurt. + +One host opens one screen: two screens naming the same entity, or the same block, is a build error. + +## Text composed per language + +Some text takes its shape from what it says: a baked breadcrumb trail collapses to its room, a [``](../components/Trans.md) breaks into lines. The filter builds every screen with the strings of each language `RP/texts/languages.json` lists, as the filters before it left them, so the build composes that text once per language. + +What the screens composed is written into each `RP/texts/.lang`, in a marked block, under keys named after what the text says in every language. Two screens composing the same text share one key. A screen that is not static also carries each `` as laid out, in the snapshot it is registered with, so a render at runtime draws the same pieces and emits a press among them in the same place. + +## The character table + +A container slot publishes no text, so a live string crosses one character per slot: each cell reads its slot's stack size and localizes a key built from it. The table that turns those codes back into glyphs is appended to every `RP/texts/.lang`, in a marked block, and only when a container screen actually has live text. It comes from the runtime the project ships rather than from the filter, because it is the contract between the compiler and the runtime — they encode against the same list or nothing renders. + +## Next steps + +- [Faces and hosts](./passes.md) — the passes that produce each screen document +- [Build checks](./checks.md) — everything that stops a build, and what fails it +- [Container screens](../guides/container-screens.md) — serving a screen an entity or a block owns diff --git a/docs/ui/compiler/passes.md b/docs/ui/compiler/passes.md index 11ef87d..1b8cca5 100644 --- a/docs/ui/compiler/passes.md +++ b/docs/ui/compiler/passes.md @@ -1,5 +1,5 @@ --- -sidebar_position: 2 +sidebar_position: 4 description: "The face pass and the host pass, the three layers between the IR and the JSON UI, and the behaviors a primitive carries." --- # Faces and hosts @@ -15,7 +15,7 @@ Every screen is compiled twice over, and one invariant separates the halves: the A **face** is a node's look with its static props. A **socket** is a node with at least one carried prop or one input: a button with a press, a label whose text is live, a slot, a native field, a subtree whose `visible` is carried. -The face document draws every socket as its inert face — the button with no mappings, the label with its reference string, the slot as an empty cell frame, the field as its payload-free twin — so the document is complete and drawable with no host behind it at all. That is what the gallery shows, and what the static validator checks. +The face document draws every socket as its inert face — the button with no mappings, the label with its reference string, the slot as an empty cell frame, the field as its payload-free twin — so the document is complete and drawable with no host behind it at all. That is what the static validator checks. The host then takes each socket, in document order, and either **wraps** its face (a gate reading a carried `visible`; a one-child `stack_panel` carrying an entry index) or **replaces** it (a cell over a container slot, a text carrier in place of a static label, a native field placed by its row). Nothing outside the sockets is touched. @@ -73,7 +73,7 @@ A behavior is client-only logic a primitive carries: still static, still in the | `states` | which children a control draws per state | | `follows` | a sibling drawn while a swap beside it is on | -A swap is the one mechanism a compiled screen owns outright: a toggle changes its own content with nothing reaching script. So everything built on it — a tab change, a fold, a choice between options — costs no press, no re-present and no payload. [``](../components/compiled/Tabs.md) is a group of swaps whose panes are drawn; [``](../components/compiled/Disclosure.md) is one swap with a panel that follows it. +A swap is the one mechanism a compiled screen owns outright: a toggle changes its own content with nothing reaching script. So everything built on it — a tab change, a fold, a choice between options — costs no press, no re-present and no payload. [``](../components/Tabs.md) is a group of swaps whose panes are drawn; [``](../components/Disclosure.md) is one swap with a panel that follows it. Content a swap shows lives inside the look, which is what keeps a look that is not showing from being built. Two things follow. A look may **draw** a sibling of its swap, which the compile moves inside it and re-bases from the swap's own corner — for content too big to solve inside the control that switches to it, such as a tab's whole pane. And `follows` is the one read in the other direction, for the one case that cannot nest: a fold's rows have to reflow what is under them, and a stack gives a hidden child no space, which is the reflow. diff --git a/docs/ui/compiler/screens.md b/docs/ui/compiler/screens.md new file mode 100644 index 0000000..81103d0 --- /dev/null +++ b/docs/ui/compiler/screens.md @@ -0,0 +1,138 @@ +--- +sidebar_position: 2 +description: "The *.screen.tsx file and what compiling it asks of the source: names and keys, reserved values, carried visibility, static screens, and screens from a module or an app." +--- +# Writing a screen + +A screen is a module ending in `.screen.tsx`, anywhere under `BP/scripts`, that default-exports a component. The [`ui-compiler` filter](/docs/filters/ui-compiler) compiles every one it finds. Ordinary `.tsx` helpers sit beside one untouched — only the suffix marks a screen. + +```tsx title="packs/BP/scripts/screens/counter.screen.tsx" +/** @jsxImportSource @bedrock-core/ui */ +import { Button, Panel, Screen, Text, useState, type JSX } from '@bedrock-core/ui'; + +export default function Counter(): JSX.Element { + const [count, setCount] = useState(0); + + return ( + + + {`count ${count}`} + + + + ); +} +``` + +The build runs the component once to decide the **shape**; the runtime runs it again per viewer to decide the **values**, and the two walks line up position for position because a compiled screen's shape is fixed. Nothing about a screen is declared twice. + +A container screen is the same file with `` at its root and a host — an entity or a block — to open from: + +```tsx title="packs/BP/scripts/screens/crafting_table.screen.tsx" +/** @jsxImportSource @bedrock-core/ui */ +import { Container, Panel, Slot, Text, useState, type JSX } from '@bedrock-core/ui'; + +export default function CraftingTable(): JSX.Element { + const [planks, setPlanks] = useState(0); + + return ( + + {`planks ${planks}`} + + setPlanks(value => value + stack.amount)} + onRemove={({ stack }) => setPlanks(value => value - stack.amount)} + /> + + + ); +} +``` + +A block-hosted screen is the same shape with `block` in place of `entity` — see [Host definitions](./output.md#host-definitions) for what each stamps onto its definition. + +## Names and keys + +A screen's **name** is its file name without the suffix: `counter.screen.tsx` is `counter`. With the addon's namespace it becomes the JSON UI namespace `_counter`, the output file, and the key `:counter` that `` and `navigate()` take. The name has to be unique across the addon whatever directory the screen sits in. + +## Live values are reserved, not discovered + +A compiled screen is baked, so a string that changes has to say how much room to reserve for it: + +```tsx +{`count ${count}`} +``` + +The build renders the component with each state slot perturbed and fails on anything that moved without a reservation, naming the strings it saw and the `maxLength` each needs. The same probe fails a screen whose **shape** moved — a cell added, dropped or reordered — because the cells are numbered once, at build time. + +## Conditionals become carried visibility + +`{cond && }` has already collapsed to `false` by the time any renderer sees it, and nothing can tell which element went missing. So the build rewrites the source text of every `.screen.tsx` before executing it, and ships the same rewrite to the runtime: + +| Written | Compiled as | +| --- | --- | +| `{cond && }` | `` | +| `{cond ? : }` | `` | +| `{cond ? : null}` | `` | + +An element that already carries `visible` keeps it, joined with `&&`. Only branches that are single elements are rewritten; a string, fragment or call in a branch is left alone — wrap it in an element to make it compilable. A form carries visibility on an entry; a container screen bakes it, so a container screen whose `visible` moves is a build error. [Conditional rendering](../components/control-props.md#conditional-rendering) shows the same rewrite from the component side. + +## Static screens + +A screen is **static** when every string it shows is baked and every press is a `` or the way out. Nothing about it can differ between one present and the next, so the build already knows everything showing it takes — the title, the value each entry carries, the key and params each press leads to — and the addon ships that table instead of the component that would recompute it. + +`` is the assertion, not the mechanism: a qualifying screen is detected either way, and declaring it makes the build fail the moment the screen stops qualifying. + +```tsx title="packs/BP/scripts/screens/menu.screen.tsx" +/** @jsxImportSource @bedrock-core/ui */ +import { Link, Panel, Screen, Text, type JSX } from '@bedrock-core/ui'; + +export default function Menu(): JSX.Element { + return ( + + + {'Menu'} + {'Shop'} + {'Balance'} + + + ); +} +``` + +A key with no `:` in front of it is one of this bundle's own, named as its file is; a key that names another addon resolves through the reference that addon published. + +A modal never qualifies — its fields are built per present — and neither does anything with a live value, a handler of its own, or a link whose params are not plain data. [Navigation](../guides/navigation.md#static-screens) covers publishing the table so other realms can show the screen. + +## Import time + +:::caution A screen module, and everything it imports, must not touch the world at import time +The filter evaluates the module once, on the build machine, with `@minecraft/server` and `@minecraft/server-ui` replaced by stubs that answer every name the packages declare and do nothing. Hooks are fine: the compiler renders the component with its initial state. What breaks is module-scope code that reaches for the game — `world.afterEvents.*.subscribe(...)`, `system.run(...)`, a dynamic property read next to an `import`. Keep that in the module that opens the screen; a screen's handlers and effects only ever run in game. +::: + +## Library screens + +A screen can also come from a module whose default export is a record of components, named by its keys. The filter's `screens` setting lists such modules: + +```jsonc title="config.json" +{ "filter": "ui-compiler", "settings": { "screens": ["./BP/scripts/screens/shared.ts"] } } +``` + +## App screens + +The bedrock-core apps need no entry in `screens`: declaring is what asks for their screens. The filter reads the register call in `BP/scripts/main.ts` or `BP/scripts/index.ts` and, for each app it finds there, bakes the module the app's declaration names and asks that module for the screens that follow from the declaration. The filter knows no app by name; an app describes itself. + +| On the declaration | What it is | +| --- | --- | +| `app` | The app's name, `'catalog'`, `'config'`, `'guide'` | +| `compiled` | The module to bake. Its default export is the app's own screens, like any `screens` module. Absent for an app whose screens another filter writes, as the guides filter does per page | + +A `compiled` module may also export `shape(declared, manifest)`: given the declaration as data, its installer dropped, and the manifest fields, it returns the screens the declaration implies, named. The [catalog](/docs/catalog/page)'s returns the page the manifest becomes; [config](/docs/config)'s returns one screen per section of the declared schema. The generated module calls it at build time to bake those screens and again at runtime, so an app registers there whatever it needs to find them later. + +## Next steps + +- [What the build writes](./output.md) — where a screen is mounted, how the client picks it, and what is stamped onto its host +- [Build checks](./checks.md) — everything that stops a build, and what fails it +- [Hosts](../guides/hosts.md) — which root to write, and what each screen can carry +- [Container screens](../guides/container-screens.md) — serving a screen an entity or a block owns From ee696931cb5025bde3647f4467837b42fd335eab Mon Sep 17 00:00:00 2001 From: DrAv0011 Date: Thu, 17 Sep 2026 17:41:20 +0200 Subject: [PATCH 44/48] docs(ui): useComposed, ModalContext and withControl, protocol v0009, block container screens - API gains ModalContext and withControl; compiled screens describe link params and whyNotPlainData. - Hooks gain useComposed, and useObservable says what a form and a container screen do with a change. - Handlers are onPress, the render pack is 1.12.x on protocol v0009, and a container screen is hosted by an entity or a block. Co-Authored-By: Claude Opus 5 (1M context) --- docs/ui/api/ModalContext.md | 49 ++++++ docs/ui/api/TranslationContext.md | 2 +- docs/ui/api/api.md | 3 +- docs/ui/api/compiled-screens.md | 33 +++- docs/ui/api/createContext.md | 4 +- docs/ui/api/errors.md | 7 +- docs/ui/api/render.md | 6 +- docs/ui/api/withControl.md | 60 ++++++++ docs/ui/guides/container-screens.md | 167 +++++++++++++++++---- docs/ui/guides/custom-native-components.md | 24 +-- docs/ui/guides/handler-events.md | 16 +- docs/ui/guides/hosts.md | 26 ++-- docs/ui/guides/navigation.md | 10 +- docs/ui/guides/render-pack.md | 26 ++-- docs/ui/guides/state.md | 21 +-- docs/ui/hooks/hooks.md | 5 +- docs/ui/hooks/useComposed.md | 66 ++++++++ docs/ui/hooks/useExit.md | 10 +- docs/ui/hooks/useMechanism.md | 2 +- docs/ui/hooks/useObservable.md | 27 ++-- docs/ui/hooks/useReducer.md | 10 +- docs/ui/hooks/useRef.md | 8 +- docs/ui/hooks/useState.md | 12 +- docs/ui/hooks/useTranslation.md | 12 +- docs/ui/hooks/useTranslationResolver.md | 6 +- docs/ui/index.md | 12 +- docs/ui/installation.md | 2 +- 27 files changed, 475 insertions(+), 151 deletions(-) create mode 100644 docs/ui/api/ModalContext.md create mode 100644 docs/ui/api/withControl.md create mode 100644 docs/ui/hooks/useComposed.md diff --git a/docs/ui/api/ModalContext.md b/docs/ui/api/ModalContext.md new file mode 100644 index 0000000..7e41a44 --- /dev/null +++ b/docs/ui/api/ModalContext.md @@ -0,0 +1,49 @@ +--- +sidebar_position: 7 +description: "The context marking that a subtree is inside a native modal form." +--- +# ModalContext + +The context marking that a subtree is inside a [``](../components/Form.md). + +## Import + +```tsx +import { ModalContext } from '@bedrock-core/ui'; +``` + +## Type + +```ts +const ModalContext: Context; + +interface FormConfig { + onSubmit?: (event: SubmitEvent) => void; + onCancel?: (event: UiEvent) => void; +} +``` + +`null` — the default — means the subtree is not inside a modal. + +## You do not provide this yourself + +[``](../components/Form.md) provides it once, at its own root, with the `onSubmit` / `onCancel` handlers it was given: + +```tsx + save(values)}> + + + +``` + +Nothing below that needs to read or provide it. It exists for the build's own restriction pass, which reads it to enforce that a field such as `Input` only appears inside a `
    `, and that no regular ` diff --git a/docs/ui/api/errors.md b/docs/ui/api/errors.md index 5c4184d..8815d67 100644 --- a/docs/ui/api/errors.md +++ b/docs/ui/api/errors.md @@ -28,7 +28,7 @@ Two things produce a registration: the [`ui-compiler` filter](/docs/filters/ui-c The tree has no host root, or a root below its root. -A screen's root names its [host](../guides/hosts.md) — [``](../components/roots/Screen.md), [``](../components/roots/Form.md) or [``](../components/roots/Container.md) — and there is no default, so a tree that starts with a `Panel`, a themed card, or two elements side by side has no screen to be. Providers and fragments above the root are looked through. +A screen's root names its [host](../guides/hosts.md) — [``](../components/Screen.md), [``](../components/Form.md) or [``](../components/Container.md) — and there is no default, so a tree that starts with a `Panel`, a themed card, or two elements side by side has no screen to be. Providers and fragments above the root are looked through. It is also what a component throws when it asks [`useMechanism`](../hooks/useMechanism.md) and nothing above it names a host at all. @@ -37,8 +37,9 @@ It is also what a component throws when it asks [`useMechanism`](../hooks/useMec The tree breaks the container-screen rules. The cases: - a `` handed to `render()`, or a form handed to `createContainerScreen` -- a container-only control — [``](../components/cells/Slot.md), [``](../components/cells/SlotGrid.md) — outside a `` -- a `` with no `entity` +- a container-only control — [``](../components/Slot.md), [``](../components/SlotGrid.md) — outside a `` +- a `` naming neither `entity` nor `block`, or both +- more container slots than a block-hosted screen's 54-slot cap - content that does not fit the 320 × 210 canvas, which a container screen cannot scroll past - a hook that needs a player where one compiled layout serves every player diff --git a/docs/ui/api/render.md b/docs/ui/api/render.md index 0db6092..61e5870 100644 --- a/docs/ui/api/render.md +++ b/docs/ui/api/render.md @@ -22,7 +22,7 @@ function render(root: JSX.Element | FunctionComponent, player: Player, options?: | Parameter | Type | Default | Description | | --- | --- | --- | --- | -| `root` | `FunctionComponent \| JSX.Element` | — | The screen: a component or element whose root is [``](../components/roots/Screen.md) or [``](../components/roots/Form.md) | +| `root` | `FunctionComponent \| JSX.Element` | — | The screen: a component or element whose root is [``](../components/Screen.md) or [``](../components/Form.md) | | `player` | `Player` | — | Who sees it | | `options` | `RenderOptions` | `{}` | See below | @@ -41,7 +41,7 @@ A screen is drawn from its layout in the pack, picked by the title the build reg - the [`ui-compiler` filter](/docs/filters/ui-compiler) seeing the screen — a `*.screen.tsx` under `BP/scripts`, or one of the screens a build compiles from what the addon declared - `@bedrock-core/generated/ui` being imported once so the build's registrations run -A [``](../components/roots/Container.md) is refused too, with `ContainerScreenError`: a container screen belongs to an entity and is served by `createContainerScreen` instead. +A [``](../components/Container.md) is refused too, with `ContainerScreenError`: a container screen belongs to an entity or a block and is served by `createContainerScreen` instead. ## debug @@ -67,7 +67,7 @@ export function openWelcome(player: Player): void { ## Scrolls -Content renders into a single full-screen **root scroll** by default, which scrolls when it overflows. For independent scroll regions compose [``](../components/layout/Scroll.md); a form supports two of them beside the root. +Content renders into a single full-screen **root scroll** by default, which scrolls when it overflows. For independent scroll regions compose [``](../components/Scroll.md); a form supports two of them beside the root. ## Notes diff --git a/docs/ui/api/withControl.md b/docs/ui/api/withControl.md new file mode 100644 index 0000000..e53b548 --- /dev/null +++ b/docs/ui/api/withControl.md @@ -0,0 +1,60 @@ +--- +sidebar_position: 8 +description: "Fill a native component's control props with their defaults and package its layout for the compiler." +--- +# withControl + +Fills a native component's control props with their defaults, and packages its layout for the compiler. + +## Import + +```tsx +import { withControl } from '@bedrock-core/ui'; +``` + +## Signature + +```ts +function withControl(props: JSX.Props): JSX.Props +``` + +## Parameters + +| Parameter | Type | Default | Description | +| --- | --- | --- | --- | +| `props` | `JSX.Props` | — | The author's props, read for [control props](../components/control-props.md) and every flex layout prop | + +## Returns + +`JSX.Props` — `visible`, `enabled` and `background` filled with their defaults, the element's font slot and scroll region, and a `__layout` block the layout phase reads and replaces with the computed geometry. + +## Usage + +Every built-in component calls it once, spreading the author's own props through first: + +```tsx +import { withControl, type ControlProps, type FunctionComponent, type JSX } from '@bedrock-core/ui'; + +interface RatingProps extends ControlProps { + stars: number; +} + +const Rating: FunctionComponent = ({ stars, ...rest }: RatingProps): JSX.Element => ({ + type: 'mypack:rating', + props: { + ...withControl(rest), + stars, + }, +}); +``` + +## Notes + +Only needed when writing a [custom native component](../guides/custom-native-components.md) — a function that returns a host element directly. A component composed from other components (one that returns JSX rather than a host element) never calls it itself. + +The geometry it writes is a placeholder for the layout phase to fill in. Set layout through the flex props (`flexGrow`, `width`, `padding`, …) that `withControl` reads, not the `jsonUIx` / `jsonUIWidth` fields it leaves behind — those are the layout phase's output, not an input. + +## Related + +- [Control props](../components/control-props.md) — the props every built-in component accepts +- [Custom native components](../guides/custom-native-components.md) — the one place authoring code calls this directly diff --git a/docs/ui/guides/container-screens.md b/docs/ui/guides/container-screens.md index dfc679a..6c1eb02 100644 --- a/docs/ui/guides/container-screens.md +++ b/docs/ui/guides/container-screens.md @@ -1,13 +1,30 @@ --- sidebar_position: 4 -description: "A container screen is a custom entity's chest screen, written in JSX with the same components as a form." +description: "A container screen is a custom entity's or custom block's container screen, written in JSX with the same components as a form." --- # Container screens -A **container screen** is a custom entity's chest screen, written in JSX with the same components as a form. The [ui-compiler Regolith filter](/docs/filters/ui-compiler) compiles it into static JSON UI at build time; at runtime `createContainerScreen` serves it to every player who opens the entity, and everything alive in it — text, buttons, entities, the items in its slots — travels through the container's own slots. +A **container screen** is the screen a custom entity or a custom block opens, written in JSX with the same components as a form. The [ui-compiler Regolith filter](/docs/filters/ui-compiler) compiles it into static JSON UI at build time; at runtime `createContainerScreen` serves it to every player who opens that host, and everything alive in it — text, buttons, entities, the items in its slots — travels through the container's own slots. -It is the second backend of `@bedrock-core/ui`. A form is serialized per player when it is shown. A container screen cannot be: the chest screen has no string channel wide enough to carry a layout, so the layout is baked once and only state moves at runtime. What you get in exchange is what a form cannot give — real item slots the player drags into, a screen that stays open while its values change, and state that belongs to a thing in the world. +It is the second backend of `@bedrock-core/ui`. A form is serialized per player when it is shown. A container screen cannot be: the vanilla container screen has no string channel wide enough to carry a layout, so the layout is baked once and only state moves at runtime. What you get in exchange is what a form cannot give — real item slots the player drags into, a screen that stays open while its values change, and state that belongs to a thing in the world. + +## The two hosts + +A screen names exactly one of them on its [``](../components/Container.md) root, and nothing above the root differs between the two: + +| Host | Written | Its container | Where its state lives | Vanilla screen it opens | +| --- | --- | --- | --- | --- | +| A custom entity | `` | `minecraft:inventory`, sized by the build | a dynamic property on the entity | the chest | +| A custom block | `` | `minecraft:block_entity.container`, sized by the build | the block entity's own dynamic properties | the data-driven container | + +:::caution Experimental: block containers +A block-hosted screen uses its block's `minecraft:block_entity` container, and block containers are an experimental game feature. Expect rough edges, and expect this to change when the game's feature does. Entity-hosted screens are not affected. +::: + +An entity goes where you put it and can be spawned, moved and removed from script; a block is placed, broken and mined like any other, and its screen goes with the block entity. The practical difference is capacity: a **block container holds 54 slots**, which is the whole allocation below, and an entity's inventory has no such cap. + +The build reads the root and stamps the host it names — the container's size and the screen's layout key — so nothing is kept in step by hand. A screen naming a host that is not in the behavior pack fails the build, and so does a block-hosted screen that needs more than 54 slots. ## A screen @@ -31,8 +48,8 @@ export default function Furnace() { {`holding ${held}`} - - + + setHeld(stack.typeId)} /> setHeld(`took ${stack.typeId}`)} /> @@ -46,12 +63,24 @@ export default function Furnace() { } ``` -Three things make it a container screen: the file name ends in `.screen.tsx` (that is how the filter finds it), the module default-exports the component, and the root is a [``](../components/roots/Container.md) naming the entity it opens from. Everything else is the component set you already know. +Three things make it a container screen: the file name ends in `.screen.tsx` (that is how the filter finds it), the module default-exports the component, and the root is a [``](../components/Container.md) naming the entity or block it opens from. Everything else is the component set you already know. + +A screen written once can serve both hosts: put everything above the root in a shared component, and let each `.screen.tsx` name nothing but its host. + +```tsx title="packs/BP/scripts/screens/crafting_block.screen.tsx" +import { Crafting } from './crafting'; + +export default function CraftingBlock() { + return ; +} +``` + +Each screen file is compiled separately and gets its own layout key, so the two hosts open their own copies of the same layout. The build runs the component once to decide the **shape**; the runtime runs it again, per viewer, to decide the **values**. The two walks line up position for position because a compiled screen cannot change shape — so nothing is named, nothing is registered, and there is no second file describing the same screen. :::caution A screen must not touch the world at import time -The build evaluates the module once, on the build machine, with `@minecraft/server` replaced by a stub. Hooks are fine; module-scope code that reaches for the game (`world.afterEvents.*.subscribe`, `system.run`, a dynamic property read next to an `import`) is not. Keep that in the module that calls `createContainerScreen` — see [the filter page](/docs/filters/ui-compiler#the-one-rule). +The build evaluates the module once, on the build machine, with `@minecraft/server` replaced by a stub. Hooks are fine; module-scope code that reaches for the game (`world.afterEvents.*.subscribe`, `system.run`, a dynamic property read next to an `import`) is not. Keep that in the module that calls `createContainerScreen` — see [Import time](../compiler/screens.md#import-time). ::: ## Serving it @@ -63,13 +92,19 @@ import Furnace from '../screens/furnace.screen'; const screen = createContainerScreen(Furnace); ``` -That is the whole behavior-pack side. `createContainerScreen` attaches the screen to every entity of the type the `` names; a player opens it by interacting with the entity, the way they open a chest, and the runtime drives the screen for as long as it is open. Nothing opens a container from script — a screen is bound to something in the world. +That is the whole behavior-pack side. `createContainerScreen` attaches the screen to every entity — or every placed block — of the type the `` names; a player opens it by interacting with that host, the way they open a chest, and the runtime drives the screen for as long as it is open. Nothing opens a container from script — a screen is bound to something in the world. + +A block-hosted screen needs nothing bound to it: a placed block is already in the world. An entity-hosted one usually does — something has to spawn the entity. ```ts -function createContainerScreen( +function createContainerScreen( Screen: FunctionComponent, options?: { pollInterval?: number; debug?: boolean }, -): { entity: string; detach(): void } +): { + host: { kind: 'entity' | 'block'; type: string }; + container(host: Entity | Block): NamedContainer; + detach(): void; +} ``` | Option | Type | Default | Description | @@ -79,24 +114,72 @@ function createContainerScreen( | Member | Description | | --- | --- | -| `entity` | The entity type the screen names, for spawning or finding hosts. | +| `host` | What the screen's `` names: `kind` is `'entity'` or `'block'`, `type` the identifier — for spawning entities or finding blocks. | +| `container(host)` | The screen's own cells on one entity or block — see [Reaching the cells](#reaching-the-cells). | | `detach()` | Stop serving the screen. | +### Reaching the cells + +The host's container is not the screen. Its first slots carry the routing key, every button rides a slot of its own, and the live values sit in a bank behind the drawn range — so a raw container index is a number only the allocator knows. + +`container(host)` hands back the container as you **wrote** it: index `i` is the `i`-th own `` in document order, `size` is how many of them there are, and a cell carries the [`name`](../components/Slot.md) its `` declared. Nothing the runtime placed shows through it, so an `output` cell with no result reads empty rather than holding the marker. + +It is the engine's own [`Container`](https://learn.microsoft.com/minecraft/creator/scriptapi/minecraft/server/container), member for member, with two additions: every slot parameter takes an index **or a name**, and `getSlot()` hands back the engine's [`ContainerSlot`](https://learn.microsoft.com/minecraft/creator/scriptapi/minecraft/server/containerslot) plus a `name`. There is nothing new to learn — `getItem`, `setItem`, `addItem`, `find`, `moveItem` and the rest mean what they mean everywhere else. (`weight` and `containerRules` are left off: a view over part of a container has no honest answer for either.) + +```ts +import { ItemStack, system, world } from '@minecraft/server'; + +const screen = createContainerScreen<'output'>(Furnace); + +// A machine ticking over its own entities. No session and no viewer: the cells +// are built from the layout the screen was constructed with, so a furnace +// smelts whether or not anyone is looking at it. +system.runInterval(() => { + for (const host of world.getDimension('overworld').getEntities({ type: screen.host.type })) { + const cells = screen.container(host); + const coal = cells.find(new ItemStack('minecraft:coal', 1)); + + if (coal !== undefined && cells.getItem('output') === undefined) { + const fuel = cells.getSlot(coal); + + if (fuel.amount > 1) { + fuel.amount -= 1; + } else { + fuel.setItem(); + } + + cells.setItem('output', new ItemStack('minecraft:iron_ingot', 1)); + } + } +}, 20); +``` + +The type argument only names the slots: `createContainerScreen<'output'>` makes `getItem('output')` typed and a misspelling a compile error, and `names` maps each one to its index. Leave it off and a name is an ordinary string. + +Four behaviors are the container screen's own: + +- Anything the runtime placed reads as an **empty slot** through every reader — `getItem`, `hasItem`, `typeId`, `amount`, `getTags`, the lore, the dynamic properties. A marker is never the author's item. +- Emptying an `output` cell restores its marker in the same call, so the cell is never empty and nothing can be shift-clicked over a result. +- `addItem()` fills the cells in view order but **skips `output` cells**: an output cell is the result the screen published for the player to take, not storage, so a bulk add must not write one. +- `clearAll()` empties the screen's own cells and nothing else — the routing key, the buttons and the bank are not reachable through the view at all. + +A host with no container — an entity that has died, a block that was broken or whose chunk is not loaded — reads as a container of size 0 whose writes do nothing; `isValid` is where that shows. Nothing throws, and nothing is remembered: a block whose chunk comes back serves its screen again. + ## The components The same set as a form, with four additions and a few container-specific behaviors: | Component | In a container screen | | --- | --- | -| [`Container`](../components/roots/Container.md) | The root. Names the entity, and is the screen's own panel: `padding`, `gap` and `background` apply. | -| [`Slot`](../components/cells/Slot.md) | A container cell of the screen's own container. `role` is `both` (storage), `input` (in only) or `output` (out only), enforced server-side; `interactive={false}` locks it inert. `onInsert(event)` and `onRemove(event)` fire after a move, with `event.stack`, `event.player` and `event.host`. Given a `collection`, it instead reads a foreign cell — see [Rendering other containers](#rendering-other-containers). | -| [`SlotGrid`](../components/cells/SlotGrid.md) | A grid of cells over a foreign collection — any collection the engine exposes. Not part of the screen's own container. | -| [`PlayerInventory`](../components/cells/PlayerInventory.md), [`Hotbar`](../components/cells/Hotbar.md) | The player's own grids — thin `SlotGrid` wrappers over `inventory_items` / `hotbar_items`. Placed by the layout engine. Not free: a screen owns the whole chest screen, so leave them out and they are gone. | -| [`Text`](../components/content/Text.md) | Baked, unless it has `maxLength` — see [Live text](#live-text). | -| [`Image`](../components/content/Image.md) | A texture, baked into the layout. | -| [`Scroll`](../components/layout/Scroll.md) | A region laid out at its own height that the client scrolls. Not inside another scroll. | -| [`Button`](../components/controls/Button.md) | A container slot with the item hidden: a press reaches script only as an item move, and the face is ordinary JSON UI. `enabled={false}` draws `backgroundLocked` and ignores presses. Its children are baked into the face, so they are static text or images — including their color, which is why an [ore-styled](/docs/ore-styled) button's caption keeps its enabled color while its background swaps to the disabled one. | -| [`Background`](../components/content/Background.md) | A full-screen texture behind everything, as in a form. | +| [`Container`](../components/Container.md) | The root. Names the entity or the block, and is the screen's own panel: `padding`, `gap` and `background` apply. | +| [`Slot`](../components/Slot.md) | A container cell of the screen's own container. `role` is `both` (storage), `input` (in only) or `output` (out only), enforced server-side; `interactive={false}` locks it inert. `name` is what addon logic calls the cell — see [Reaching the cells](#reaching-the-cells). `onInsert(event)` and `onRemove(event)` fire after a move, with `event.stack`, `event.player`, `event.host` and `event.container`. Given a `collection`, it instead reads a foreign cell — see [Rendering other containers](#rendering-other-containers). | +| [`SlotGrid`](../components/SlotGrid.md) | A grid of cells over a foreign collection — any collection the engine exposes. Not part of the screen's own container. | +| [`PlayerInventory`](../components/PlayerInventory.md), [`Hotbar`](../components/Hotbar.md) | The player's own grids — thin `SlotGrid` wrappers over `inventory_items` / `hotbar_items`. Placed by the layout engine. Not free: a screen owns the whole vanilla screen, so leave them out and they are gone. | +| [`Text`](../components/Text.md) | Baked, unless it has `maxLength` — see [Live text](#live-text). | +| [`Image`](../components/Image.md) | A texture, baked into the layout. | +| [`Scroll`](../components/Scroll.md) | A region laid out at its own height that the client scrolls. Not inside another scroll. | +| [`Button`](../components/Button.md) | A container slot with the item hidden: a press reaches script only as an item move, and the face is ordinary JSON UI. `enabled={false}` draws `backgroundLocked` and ignores presses. Its children are baked into the face, so they are static text or images — including their color, which is why an [ore-styled](/docs/ore-styled) button's caption keeps its enabled color while its background swaps to the disabled one. | +| [`Background`](../components/Background.md) | A full-screen texture behind everything, as in a form. | | `Panel`, `Fragment`, contexts | Exactly as in a form. | [ore-styled](/docs/ore-styled) components compose the same way: the `Button` above is ore-styled's, with `enabled` driving its disabled look. @@ -132,9 +215,28 @@ What *is* baked into the JSON UI is inertness. A container slot's take and place ## State and handlers -State is **entity-owned**. Hook state lives on the entity the screen is attached to, in a dynamic property, and persists on its own: close the screen and reopen it, leave and come back, restart the world — the furnace is still at the charge it was left at. Nothing has to be saved or restored, but it does mean state must be JSON-serializable: numbers, strings, booleans, plain objects and arrays. +State is **host-owned**. Hook state lives on the entity or the block the screen is attached to — a dynamic property on the entity, the block entity's own dynamic properties on the block — and persists on its own: close the screen and reopen it, leave and come back, restart the world, and the furnace is still at the charge it was left at. Nothing has to be saved or restored, but it does mean state must be JSON-serializable: numbers, strings, booleans, plain objects and arrays. + +A block's state goes where the block entity goes: break the block and it is gone with the container, which is what a player expects of a machine. + +There is no single viewer, so **the player reaches a screen through its handlers** rather than a hook: `Slot` and `Button` handlers receive an event carrying the player who moved the item, and the `Container` itself has `onOpen` / `onClose` carrying the player who came or went — keep what the screen needs (a name, a count of viewers) in state. `event.host` is the entity or the block the screen belongs to, whichever it was written for. + +Every one of those events also carries `event.container`: the screen's own cells, exactly as [`container(host)`](#reaching-the-cells) gives them. A handler is written inside the component and cannot reach the screen object, so the cells come to it instead: + +```tsx + + + +``` -There is no single viewer, so **the player reaches a screen through its handlers** rather than a hook: `Slot` and `Button` handlers receive an event carrying the player who moved the item, and the `Container` itself has `onOpen` / `onClose` carrying the player who came or went — keep what the screen needs (a name, a count of viewers) in state. [`usePlayer`](../hooks/usePlayer.md) is unavailable, because a container screen has no player of its own. [`useExit`](../hooks/useExit.md) hands back a press rather than a closer: nothing closes a container from script, but a ` ); } ``` -When the handoff goes through an async opener, **return the promise from `action`** so the swap lands inside the press's transaction. Fired and forgotten it still converges; worst case the screen re-locks for a frame. +When the handoff goes through an async opener, **return the promise from `onPress`** so the swap lands inside the press's transaction. Fired and forgotten it still converges; worst case the screen re-locks for a frame. ## A form change is a new present @@ -36,21 +35,23 @@ When the handoff goes through an async opener, **return the promise from `action A container screen has no such limit: a handler renders and the slots settle in the same tick. -## A container screen's state belongs to its entity +## A container screen's state belongs to its entity or block -One layout serves every viewer of a container screen. Its state is written to the entity after each render and read back at the next open, so it outlives every viewer — and effects run exactly while somebody is looking, because the fibers exist exactly then. +One layout serves every viewer of a container screen. Its state is written to the host after each render and read back at the next open, so it outlives every viewer — and effects run exactly while somebody is looking, because the fibers exist exactly then. That is also why a container screen has no `usePlayer()`: one compiled layout serves everyone, and the screen learns who is looking from `onOpen` instead. ## Reacting to something outside the screen -[`useObservable`](../hooks/useObservable.md) re-renders the component when an observable changes, which covers a config leaf, a db document, a query and anything else shaped like `@bedrock-core/observable`'s `ReadonlyObservable`. +[`useObservable`](../hooks/useObservable.md) reads an observable into a component: a config leaf, a db document, a query, or anything else shaped like `@bedrock-core/observable`'s `ReadonlyObservable`. + +A change lands the way a state change does. A form keeps it and shows it on the player's next press; a container screen updates its live values at once. ```tsx const count = useObservable(playersObs, p => p.size); ``` -With a `select` the component only re-renders when the selected slice changes, so a screen showing a count is not woken by every mutation of the collection behind it. +With a `select` only a change to the selected slice counts, so a screen showing a count is not woken by every mutation of the collection behind it. ## What a value costs @@ -58,10 +59,10 @@ A compiled screen's shape is frozen, so anything that varies has to reserve room | Varies | Declared as | Reserves | | --- | --- | --- | -| A string | [`maxLength`](../components/content/Text.md) on a `` | its width, and on the chest one slot per character | -| A row count | [`max`](../components/compiled/List.md) on a `` | `max` copies of the row, plus one int | +| A string | [`maxLength`](../components/Text.md) on a `` | its width, and on the chest one slot per character | +| A row count | [`max`](../components/List.md) on a `` | `max` copies of the row, plus one int | | A branch | `visible` on the control | a carried bool | -| A texture | [`live`](../components/content/Image.md) on an `` | one entry on a form | +| A texture | [`live`](../components/Image.md) on an `` | one entry on a form | Everything else is baked. A baked string fed from data that changes is silently wrong, which is what `render(screen, player, { debug: true })` reports. diff --git a/docs/ui/hooks/hooks.md b/docs/ui/hooks/hooks.md index 69c44ef..ba6c460 100644 --- a/docs/ui/hooks/hooks.md +++ b/docs/ui/hooks/hooks.md @@ -11,7 +11,7 @@ State and effects for your components, plus the few that reach outside them. - [`useState`](./useState.md) — component state - [`useReducer`](./useReducer.md) — state through a reducer - [`useContext`](./useContext.md) — read a context value -- [`useObservable`](./useObservable.md) — re-render when an observable changes, optionally on a selected slice +- [`useObservable`](./useObservable.md) — read an observable ## Effects and lifecycle @@ -35,10 +35,11 @@ State and effects for your components, plus the few that reach outside them. - [`useTranslation`](./useTranslation.md) — bind an addon's typed translation verbs to the viewing player - [`useTranslationResolver`](./useTranslationResolver.md) — read the resolver active for this part of the tree +- [`useComposed`](./useComposed.md) — compose a string in every language the pack ships, at the width the layout gives a box ## Where the state lives -A form cannot be mutated while open, so a state change never repaints what the player is looking at — they see a new snapshot when they press. A container screen's state belongs to its entity and outlives every viewer. Both are covered in [State](../guides/state.md). +A form cannot be mutated while open, so a state change never repaints what the player is looking at — they see a new snapshot when they press. A container screen's state belongs to its entity or block and outlives every viewer. Both are covered in [State](../guides/state.md). `usePlayer()` has no answer on a container screen: one compiled layout serves everyone, so the screen learns who is looking from `` instead. diff --git a/docs/ui/hooks/useComposed.md b/docs/ui/hooks/useComposed.md new file mode 100644 index 0000000..bbad87d --- /dev/null +++ b/docs/ui/hooks/useComposed.md @@ -0,0 +1,66 @@ +--- +sidebar_position: 14 +description: "Compose a string in every language the pack ships, at the width the layout gives a box." +--- +# useComposed + +Compose a string in every language the pack ships, at the width the layout gives a box. + +## Import + +```tsx +import { useComposed } from '@bedrock-core/ui'; +``` + +## Signature + +```ts +function useComposed(compose: (resolve: TranslationResolver, width: number | undefined) => string): Composed; +``` + +## Parameters + +| Parameter | Type | Default | Description | +| --- | --- | --- | --- | +| `compose` | `(resolve: TranslationResolver, width: number \| undefined) => string` | — | What the text says in one language: `resolve` reads that language's strings, `width` is the room it has | + +## Returns + +A `Composed`, whose two halves are spread on two elements: + +- `text` — on the `` that draws the composition, which the build draws through a key it writes into every language +- `box` — on the box whose width the composition has to fit, so the build lays it out at that width + +## Usage + +```tsx +function ShopTitle(): JSX.Element { + const composed = useComposed((resolve, width) => { + const long = resolve('drav0011_shop.title.long') ?? ''; + const short = resolve('drav0011_shop.title.short') ?? ''; + + return width === undefined || measureText({ text: long }).width <= width ? long : short; + }); + + return ( + + + + ); +} +``` + +Each language gets whichever title fits in it, and the player reads their own. + +## Examples + +### A breadcrumb trail + +[`Trail`](/docs/ore-styled/Trail)'s `segments` is built on this hook: every segment is resolved in each language and the trail collapses from the middle to the room its row was laid out with. + +## Notes + +- A compiled screen has one layout, but what fits in it depends on what the text says, which differs per language. The build calls `compose` once for every language `RP/texts/languages.json` lists, with the strings that language's `.lang` holds. A key a language lacks resolves through the default language. +- `width` is `undefined` the first time. The screen is laid out, then laid out again with the width `box` was given, so compose something reasonable without one. +- Each distinct composition is drawn through one key, named after what it says in every language, which the build writes into each `.lang`. +- Outside a build, `compose` runs once, through the render's own resolver, with no width. diff --git a/docs/ui/hooks/useExit.md b/docs/ui/hooks/useExit.md index 933c2cc..b558444 100644 --- a/docs/ui/hooks/useExit.md +++ b/docs/ui/hooks/useExit.md @@ -7,7 +7,7 @@ description: "Request the UI to be closed." Request the UI to be closed. :::note Closing, not switching -`exit()` closes the UI back to the game. You do **not** need it to hand off to another screen or app — calling [`render()`](../guides/state.md#one-ui-slot-per-player) (or an opener like `openUi`) while a UI is up swaps the new app into the running session by itself. +`exit()` closes the UI back to the game. You do **not** need it to hand off to another screen or app — calling [`render()`](../guides/state.md#one-ui-slot-per-player) (or an app's `open`) while a UI is up swaps the new app into the running session by itself. ::: ## Import @@ -37,7 +37,7 @@ function CloseButton() { const exit = useExit(); return ( - ); @@ -57,12 +57,12 @@ function ConditionalClose() { {`Saved: ${isSaved ? 'Yes' : 'No'}`} - diff --git a/docs/ui/hooks/useMechanism.md b/docs/ui/hooks/useMechanism.md index bb44abe..da8d250 100644 --- a/docs/ui/hooks/useMechanism.md +++ b/docs/ui/hooks/useMechanism.md @@ -48,7 +48,7 @@ function Checkbox({ name, label }: CheckboxProps): JSX.Element { return mechanism === 'field' ? - : ; + : ; } ``` diff --git a/docs/ui/hooks/useObservable.md b/docs/ui/hooks/useObservable.md index 7cc1829..0b0771b 100644 --- a/docs/ui/hooks/useObservable.md +++ b/docs/ui/hooks/useObservable.md @@ -1,10 +1,10 @@ --- sidebar_position: 5 -description: "Re-render the component when an observable changes, optionally only on a selected slice." +description: "Read an observable into a component and keep it current, the way a state change is kept." --- # useObservable -Re-renders the component when an observable changes. +Reads an observable, and keeps the component's copy of it current. A change lands the way a [`useState`](./useState.md) change does. ## Import @@ -24,7 +24,7 @@ function useObservable(source: ObservableLike, select: (value: T) => S) | Parameter | Type | Default | Description | | --- | --- | --- | --- | | `source` | `ObservableLike` | — | Anything with `get()` and `subscribe(listener)` | -| `select` | `(value: T) => S` | — | Narrows what the component depends on, so it only re-renders when the slice changes | +| `select` | `(value: T) => S` | — | Narrows what the component depends on, so only a change to the slice counts | ## Returns @@ -41,7 +41,7 @@ interface ObservableLike { } ``` -[`@bedrock-core/observable`](/docs/observable)'s `ReadonlyObservable`, a [config](/docs/config) leaf, a [db](/docs/db) document and a query all have that shape. Matching on shape rather than on an import is what keeps the UI free of a dependency on the server framework. +[`@bedrock-core/observable`](/docs/observable)'s `ReadonlyObservable`, a [config](/docs/config) leaf, a [db](/docs/db) document and a query all have that shape. ## Usage @@ -51,7 +51,7 @@ const phase = useObservable(phaseObs); ## Examples -### Only re-render when the slice changes +### Only react to a slice ```tsx function PlayerCount(): JSX.Element { @@ -61,13 +61,15 @@ function PlayerCount(): JSX.Element { } ``` -A screen showing a count is not woken by every mutation of the collection behind it. Equality is `Object.is`, applied by the state slot, so a slice that reads equal schedules nothing. +A change to the collection that leaves its size alone schedules nothing. Equality is `Object.is`, applied by the state slot. ### A config value +With `config` the accessor `register()` handed back: + ```tsx function Currency(): JSX.Element { - const symbol = useObservable(core.config.server.economy.currency); + const symbol = useObservable(config.server.economy.currency); return {symbol}; } @@ -75,8 +77,15 @@ function Currency(): JSX.Element { ## Notes +A change from the observable is a state change, so when the player sees it depends on the screen: + +| Screen | A change | +| --- | --- | +| Form | Is kept, and shows on the next screen the player's press brings up: an open form cannot change | +| Container screen | Updates the screen's live values at once: a `maxLength` text, a `` count, a carried `visible` | + +What the build baked stays as the build drew it on both. See [State](../guides/state.md#a-form-change-is-a-new-present). + `select` is read through a ref rather than a dependency, so passing an inline arrow — the usual way to write one — does not resubscribe on every render. The subscription is keyed on the observable alone. The value can move between a render and the subscription landing, so the hook reads once more before listening. An unchanged value costs nothing. - -On a form, a change still does not repaint what the player is looking at: a form cannot be mutated while open, so the new value shows on their next press. See [State](../guides/state.md#a-form-change-is-a-new-present). diff --git a/docs/ui/hooks/useReducer.md b/docs/ui/hooks/useReducer.md index 8eac239..c200883 100644 --- a/docs/ui/hooks/useReducer.md +++ b/docs/ui/hooks/useReducer.md @@ -64,13 +64,13 @@ function Counter() { {`Count: ${state.count}`} - - - @@ -133,13 +133,13 @@ function TodoApp() { return ( - {state.todos.map(todo => ( {`${todo.completed ? '✓' : '○'} ${todo.text}`} ))} - diff --git a/docs/ui/hooks/useRef.md b/docs/ui/hooks/useRef.md index 44f1619..d484d69 100644 --- a/docs/ui/hooks/useRef.md +++ b/docs/ui/hooks/useRef.md @@ -55,10 +55,10 @@ function Timer() { {`Count: ${count}`} - - @@ -84,7 +84,7 @@ function PreviousValue() { {`Current: ${count}`} {`Previous: ${prevCountRef.current}`} - @@ -106,7 +106,7 @@ function ExecutionCounter() { {`State: ${state}`} {`Executions: ${executionCount.current}`} - diff --git a/docs/ui/hooks/useState.md b/docs/ui/hooks/useState.md index 073ef5f..ec7e1eb 100644 --- a/docs/ui/hooks/useState.md +++ b/docs/ui/hooks/useState.md @@ -40,7 +40,7 @@ function Counter() { return ( {`Count: ${count}`} - @@ -57,7 +57,7 @@ function Toggle() { const [isOn, setIsOn] = useState(false); return ( - ); @@ -94,10 +94,10 @@ function StatsDisplay() { {`Mana: ${stats.mana}`} {`Level: ${stats.level}`} - - @@ -126,10 +126,10 @@ function TodoList() { {`${index + 1}. ${todo}`} ))} - - diff --git a/docs/ui/hooks/useTranslation.md b/docs/ui/hooks/useTranslation.md index 0f96e2c..4164efa 100644 --- a/docs/ui/hooks/useTranslation.md +++ b/docs/ui/hooks/useTranslation.md @@ -59,11 +59,11 @@ import { createI18n } from '@bedrock-core/i18n'; export const i18n = createI18n(bundle); ``` -See the [i18n guide](/docs/i18n) for what each verb does and when to prefer which. +See the [i18n API reference](/docs/i18n/api) for what each verb does and when to prefer which. ## The locale it binds to -The bound locale comes from the [locale resolution chain](/docs/i18n#locale-resolution): a persisted per-player override, then the client language, a sibling region, then the bundle's default. +The bound locale comes from the [locale resolution chain](/docs/i18n/api#locale-resolution): a persisted per-player override, then the client language, a sibling region, then the bundle's default. `locale` on the returned set is the one that won, which is handy to show back to the player: @@ -98,10 +98,10 @@ function LanguagePicker() { return ( - - @@ -119,7 +119,7 @@ function BuyButton({ item }: { item: Item }) { const { display, key, raw } = useTranslation(i18n); return ( - @@ -80,7 +80,7 @@ The `@bedrock-core/generated/ui` import is what runs the build's registrations. **Screens other addons can show** — a [static](./guides/navigation.md#static-screens) screen is described by its title, its entry values and one target per press. Publish that table and a realm running none of your script still shows your screens, because the layout is in the pack every client holds. -**Switches that cost nothing** — [``](./components/compiled/Tabs.md) and [``](./components/compiled/Disclosure.md) change what is drawn entirely on the client. No press, no re-present, no payload. +**Switches that cost nothing** — [``](./components/Tabs.md) and [``](./components/Disclosure.md) change what is drawn entirely on the client. No press, no re-present, no payload. ## Differences from React diff --git a/docs/ui/installation.md b/docs/ui/installation.md index 5fa8c67..9bb1eb2 100644 --- a/docs/ui/installation.md +++ b/docs/ui/installation.md @@ -89,7 +89,7 @@ pack.mcaddon } ``` -If you also run the i18n filter, it needs one more `paths` alias and an `include` entry so the generated bundle typechecks — see [tsconfig](/docs/filters/i18n#tsconfig). +If you also run the i18n filter, it needs one more `paths` alias and an `include` entry so the generated bundle typechecks — see [bundler](/docs/filters/bundler#authoring). ## Optional: ore-styled From 418da5e8102f787cbe6858e30a1f5bf415fcdcdb Mon Sep 17 00:00:00 2001 From: DrAv0011 Date: Fri, 18 Sep 2026 21:08:13 +0200 Subject: [PATCH 45/48] docs(ui): container presses as drops, SlotGrid without hideOwned Co-Authored-By: Claude Opus 5 (1M context) --- docs/ui/compiler/checks.md | 1 + docs/ui/compiler/output.md | 10 +++++----- docs/ui/compiler/passes.md | 2 +- docs/ui/compiler/screens.md | 6 ++++++ docs/ui/components/Hotbar.md | 3 +-- docs/ui/components/PlayerInventory.md | 4 ++-- docs/ui/components/SlotGrid.md | 9 ++++----- docs/ui/guides/container-screens.md | 6 +++--- 8 files changed, 23 insertions(+), 18 deletions(-) diff --git a/docs/ui/compiler/checks.md b/docs/ui/compiler/checks.md index 6f9b6cd..ae47dce 100644 --- a/docs/ui/compiler/checks.md +++ b/docs/ui/compiler/checks.md @@ -12,6 +12,7 @@ A failed check stops the build with the compiler's own message, which the [`ui-c | Shape | A screen that adds, drops or reorders a cell when its state changes | | Live text | A `` whose string changes with no `maxLength`; the message names each string it saw and the length it needs | | Carried visibility | A `visible` that moves on a container screen, which bakes it | +| Looks | A prop that changes with state on an element the host draws itself — a press, a slot, a live string, a live image or a list — naming each prop and the values it saw; or an element taking more than 63 looks on a container screen | | Static | `` on a screen that carries a live value or runs a handler of its own, naming which | | Trans | A tag left open or closed out of order, a placeholder in a `` string, a `` component setting more than `color` and `shadow`, a press inside a press, or a component that is neither | | Canvas | Content laid out past 320 × 210, with the size it measured | diff --git a/docs/ui/compiler/output.md b/docs/ui/compiler/output.md index 46960b2..f78fe87 100644 --- a/docs/ui/compiler/output.md +++ b/docs/ui/compiler/output.md @@ -24,7 +24,7 @@ A tree that starts with anything else — or a `` naming neither `ent Both hosts are reached the same way: one gated definition per screen under a root named for the addon, and one insert putting that root where the screen can see it. A gate compares the whole of what identifies the screen, so two screens can never both match. - **Form screens** gate on the form's title, which carries the protocol header and the screen's namespaced name. The library's own container is already gated on that header, so a compiled form needs no vanilla edit: the addon's root is inserted into the mount. The pack that *defines* the mount lists its root in the definition directly; every other pack inserts through `RP/ui/server_form.json`. -- **Container screens** gate on a layout key. A marker item in the container's first two slots carries a protocol key — is this container a compiled screen at all? — and the layout key as two stack sizes, and the router shows the layout whose key matches. An entity-hosted screen inserts the addon's root into `RP/ui/chest_screen.json`, at vanilla's `chest.small_chest_panel_top_half`; a block-hosted screen inserts the same root into `RP/ui/data_driven_container_screen.json`, at `data_driven_container.panel_top_half`. A vanilla chest or data-driven container has no marker, fails the first check and renders untouched. +- **Container screens** gate on a layout key. A marker item in the container's first slot carries a protocol key — is this container a compiled screen at all? — as its max durability, and the layout key as its current durability, and the router shows the layout whose key matches. An entity-hosted screen inserts the addon's root into `RP/ui/chest_screen.json`, at vanilla's `chest.small_chest_panel_top_half`; a block-hosted screen inserts the same root into `RP/ui/data_driven_container_screen.json`, at `data_driven_container.panel_top_half`. A vanilla chest or data-driven container has no marker, fails the first check and renders untouched. A screen's layout key is a hash of `_` folded into 1..3969. It depends on nothing but the screen's own name, so a rebuild never moves a key and an entity placed in a world keeps opening the screen it was stamped with; two addons built apart never claim the same key for their first screens. Two screens of one addon hashing alike is a build failure naming both. @@ -57,10 +57,10 @@ A container screen names the entity or the block it opens from. The filter finds ```jsonc "description": { "states": { - // One value, because a block type opens one screen. A string, not a number: the engine - // stores an integer state by its value in the block's state bits, and a layout key does - // not fit them, while a single string value costs none. - "core:ui_layout": ["1094"] + // A string, not a number: the engine stores an integer state by its value in the block's + // state bits, and a layout key does not fit them. The key is the default; `none` is there + // because a one-value state needs zero bits, which the engine logs as out of range. + "core:ui_layout": ["1094", "none"] } }, "components": { diff --git a/docs/ui/compiler/passes.md b/docs/ui/compiler/passes.md index 1b8cca5..9a1f5b2 100644 --- a/docs/ui/compiler/passes.md +++ b/docs/ui/compiler/passes.md @@ -60,7 +60,7 @@ Nothing above a host dispatches on a host, and nothing below a host dispatches o A node kind is one vertical slice: its IR shape, how a built element lowers into it, and how that shape draws. The walks stay dumb — the lowering walk owns order, geometry and naming; the face walk owns document assembly; the host walk owns socket order — and each dispatches through the definitions. -A socket kind absent from a host's table is refused at build, by name, in that host's own words. That is the whole of the capability model: `press`, `text`, `texture`, `slot`, `grid`, `field`, `list` and `visible` are the kinds, and a host serving none of them draws faces alone, which is exactly what a preview is. +A socket kind absent from a host's table is refused at build, by name, in that host's own words. That is the whole of the capability model: `press`, `text`, `texture`, `slot`, `grid`, `field`, `list`, `visible` and `look` are the kinds, and a host serving none of them draws faces alone, which is exactly what a preview is. ## Behaviors diff --git a/docs/ui/compiler/screens.md b/docs/ui/compiler/screens.md index 81103d0..a3094c1 100644 --- a/docs/ui/compiler/screens.md +++ b/docs/ui/compiler/screens.md @@ -66,6 +66,12 @@ A compiled screen is baked, so a string that changes has to say how much room to The build renders the component with each state slot perturbed and fails on anything that moved without a reservation, naming the strings it saw and the `maxLength` each needs. The same probe fails a screen whose **shape** moved — a cell added, dropped or reordered — because the cells are numbered once, at build time. +## Looks are discovered + +Everything else an element draws — a texture, a colour, an alignment, its size and its place — needs no marker. The probe perturbs each state slot and presses each button, and every element whose look moved is drawn once per look it can take, with the one worn chosen at runtime: by an entry on a form, by an item's durability on a container screen. Props moved by different causes are paired, so a word coloured by one control and moved by another has every combination drawn. A button draws its looks inside its face; any other element draws each version in place, with its children drawn once over them. + +An element the host draws itself — a press, a slot, a live string, a live image or a list — cannot be copied per look, so a prop that changes on one fails the build, naming the prop and the values it saw. Keep it the same for every state and put what changes on a plain element beside it. + ## Conditionals become carried visibility `{cond && }` has already collapsed to `false` by the time any renderer sees it, and nothing can tell which element went missing. So the build rewrites the source text of every `.screen.tsx` before executing it, and ships the same rewrite to the runtime: diff --git a/docs/ui/components/Hotbar.md b/docs/ui/components/Hotbar.md index 6bed605..cd2e6f0 100644 --- a/docs/ui/components/Hotbar.md +++ b/docs/ui/components/Hotbar.md @@ -22,7 +22,7 @@ import { Hotbar } from '@bedrock-core/ui'; ``` -The same redrawn grid as [`PlayerInventory`](./PlayerInventory.md), one row tall: 162 × 18 — a thin [`SlotGrid`](./SlotGrid.md) wrapper, ``. Placed by the layout engine at its natural size, and — like the inventory — not drawn unless asked for, because a container screen owns the whole chest screen. +The same redrawn grid as [`PlayerInventory`](./PlayerInventory.md), one row tall: 162 × 18 — a thin [`SlotGrid`](./SlotGrid.md) wrapper, ``. Placed by the layout engine at its natural size, and — like the inventory — not drawn unless asked for, because a container screen owns the whole chest screen. ## Props @@ -30,5 +30,4 @@ Inherits [control props](./control-props.md). Its size is fixed by the engine's ## Notes -- A button's transport item draws as nothing here too, for the tick it takes the runtime to reclaim it. - Vanilla stacks the hotbar four texels under the inventory; `marginTop={4}` reproduces that. diff --git a/docs/ui/components/PlayerInventory.md b/docs/ui/components/PlayerInventory.md index c266d51..c7092cb 100644 --- a/docs/ui/components/PlayerInventory.md +++ b/docs/ui/components/PlayerInventory.md @@ -22,7 +22,7 @@ import { PlayerInventory } from '@bedrock-core/ui'; ``` -`PlayerInventory` binds to the player's inventory rather than to the container, which is why it exists as a component of its own: nothing in a form has anything like it. It is a thin [`SlotGrid`](./SlotGrid.md) wrapper — `` — placed by the layout engine like any other node, at its natural size of 162 × 54 (nine 18-texel cells by three). Reach for `SlotGrid` directly for any other shape or collection. +`PlayerInventory` binds to the player's inventory rather than to the container, which is why it exists as a component of its own: nothing in a form has anything like it. It is a thin [`SlotGrid`](./SlotGrid.md) wrapper — `` — placed by the layout engine like any other node, at its natural size of 162 × 54 (nine 18-texel cells by three). Reach for `SlotGrid` directly for any other shape or collection. A container screen owns the whole chest screen, so the grid is **not free**: leave it out and the player has no inventory on screen. Pair it with [`Hotbar`](./Hotbar.md) for the full vanilla bottom half. @@ -32,5 +32,5 @@ Inherits [control props](./control-props.md). Its size is fixed by the engine's ## Notes -- Drawn the way vanilla draws it, with one difference: a button's transport item — auto-placed in the player's inventory for the tick it takes the runtime to reclaim it — draws as nothing, so a press never flashes a stray item. +- Drawn the way vanilla draws it. - Items in the grid are the player's own. Moves into the container's [`Slot`](./Slot.md)s are what the screen observes. diff --git a/docs/ui/components/SlotGrid.md b/docs/ui/components/SlotGrid.md index cc56cac..b55f8b7 100644 --- a/docs/ui/components/SlotGrid.md +++ b/docs/ui/components/SlotGrid.md @@ -14,8 +14,8 @@ import { SlotGrid } from '@bedrock-core/ui'; ## Usage ```tsx -{/* The player's inventory, read-only, transport items hidden. */} - +{/* The player's inventory, read-only. */} + ``` Where a [`Slot`](./Slot.md) is one cell, a `SlotGrid` is a whole collection at once. It reads the collection straight — it is **not** part of the screen's own container, so it takes no slot of it and the runtime never polls it. An interactive grid is driven by the engine's own take and place on that collection; a display-only one is inert. @@ -30,7 +30,6 @@ Its size is fixed by the cell: `columns × rows` cells of 18 texels each. Lay it | `columns` | `number` | — | Columns of cells. At least one | | `rows` | `number` | — | Rows of cells. At least one | | `interactive` | `boolean` | `true` | Whether the player can move items through the cells. `false` makes the grid inert — no take, no place, no drop | -| `hideOwned` | `boolean` | `false` | Draw the cell that hides the runtime's transport item. Only relevant for the player's own inventory and hotbar, where a button's transport is auto-placed for the tick it takes the runtime to reclaim it — otherwise it would flash there | Inherits [control props](./control-props.md). Its size is fixed by the cell; use `alignSelf`, margins and the surrounding panel to place it. @@ -41,8 +40,8 @@ A container slot's take and place are one combined engine action, so there is no [`PlayerInventory`](./PlayerInventory.md) and [`Hotbar`](./Hotbar.md) are thin `SlotGrid` wrappers: ```tsx -const PlayerInventory = props => ; -const Hotbar = props => ; +const PlayerInventory = props => ; +const Hotbar = props => ; ``` Reach for `SlotGrid` directly when you want a different shape — a read-only mirror, a sub-range, or another entity's collection. diff --git a/docs/ui/guides/container-screens.md b/docs/ui/guides/container-screens.md index 6c1eb02..00a1b44 100644 --- a/docs/ui/guides/container-screens.md +++ b/docs/ui/guides/container-screens.md @@ -178,7 +178,7 @@ The same set as a form, with four additions and a few container-specific behavio | [`Text`](../components/Text.md) | Baked, unless it has `maxLength` — see [Live text](#live-text). | | [`Image`](../components/Image.md) | A texture, baked into the layout. | | [`Scroll`](../components/Scroll.md) | A region laid out at its own height that the client scrolls. Not inside another scroll. | -| [`Button`](../components/Button.md) | A container slot with the item hidden: a press reaches script only as an item move, and the face is ordinary JSON UI. `enabled={false}` draws `backgroundLocked` and ignores presses. Its children are baked into the face, so they are static text or images — including their color, which is why an [ore-styled](/docs/ore-styled) button's caption keeps its enabled color while its background swaps to the disabled one. | +| [`Button`](../components/Button.md) | A container slot with the item hidden: a press drops that item, which is how it reaches script and names the player who pressed, and the face is ordinary JSON UI. `enabled={false}` draws `backgroundLocked` and ignores presses. Its children are baked into the face, so they are static text or images — including their color, which is why an [ore-styled](/docs/ore-styled) button's caption keeps its enabled color while its background swaps to the disabled one. | | [`Background`](../components/Background.md) | A full-screen texture behind everything, as in a form. | | `Panel`, `Fragment`, contexts | Exactly as in a form. | @@ -203,7 +203,7 @@ A `Slot` and a `SlotGrid` can read a collection the screen does **not** own — ```tsx {/* one foreign cell */} - {/* a whole collection */} + {/* a whole collection */} ``` The difference between an **own** slot and a **foreign** one is where the value lives and who drives it: @@ -211,7 +211,7 @@ The difference between an **own** slot and a **foreign** one is where the value - An **own** `Slot` (no `collection`) is a cell of the screen's own container. It is allocated a container index, the runtime polls it every sweep, and its `role` — `input` / `output` — is enforced a tick later by undoing a move the engine already made. A container reports no events and offers no veto, so a role is a server-side runtime thing, never a baked one. - A **foreign** `Slot collection` / `SlotGrid` reads another collection at an author-given index. It costs no index in the screen's own container and the runtime never touches it: the engine's own take and place drive it directly. `role` has no meaning here (nothing polls it) and is refused. -What *is* baked into the JSON UI is inertness. A container slot's take and place are a single combined engine action, so there is no take-only or place-only cell to express a one-directional `role` on the client — the runtime undoes the wrong direction a tick later. (Two things are baked: **no slot drops** — Q is not a route on any container cell, since dropping belongs outside a container and a dropped item lands out of the runtime's reach; and an output slot with no result holds the runtime's marker item while its compiled cell swaps to an empty fake — the slot is never empty, so shift-click auto-placement is blocked, and the marker is never rendered, hovered or takeable, because no real cell exists while it sits there.) A cell can also be made fully inert with `interactive={false}` — it withholds focus, so it can neither be taken from, placed into, nor dropped. A drawn-but-untouchable mirror of the player's inventory is exactly that. +What *is* baked into the JSON UI is inertness. A container slot's take and place are a single combined engine action, so there is no take-only or place-only cell to express a one-directional `role` on the client — the runtime undoes the wrong direction a tick later. (Two things are baked: **no slot drops** — Q is not a route on any `Slot` cell, since a dropped item lands out of the runtime's reach (a `Button` is the exception: dropping its hidden item is its press); and an output slot with no result holds the runtime's marker item while its compiled cell swaps to an empty fake — the slot is never empty, so shift-click auto-placement is blocked, and the marker is never rendered, hovered or takeable, because no real cell exists while it sits there.) A cell can also be made fully inert with `interactive={false}` — it withholds focus, so it can neither be taken from, placed into, nor dropped. A drawn-but-untouchable mirror of the player's inventory is exactly that. ## State and handlers From 2fb8534814c869434bb2208870d32a77b0af72e2 Mon Sep 17 00:00:00 2001 From: DrAv0011 Date: Sun, 20 Sep 2026 14:46:11 +0200 Subject: [PATCH 46/48] docs: update release and filter installation guidance --- docs/catalog/index.md | 2 +- docs/catalog/page.md | 4 ++-- docs/cli/index.md | 8 ++++++-- docs/config/index.md | 2 +- docs/config/schema-to-screens.md | 18 +++++++++++------- docs/config/settings.md | 14 ++++++++------ docs/filters/ci.md | 7 ++++++- docs/filters/core.md | 4 ++++ docs/filters/index.md | 6 +++++- docs/ore-styled/index.md | 9 ++++++--- docs/ui/compiler/api.md | 7 +++---- docs/ui/components/Scroll.md | 4 +--- docs/ui/installation.md | 2 +- 13 files changed, 55 insertions(+), 32 deletions(-) diff --git a/docs/catalog/index.md b/docs/catalog/index.md index 16ab08f..709b115 100644 --- a/docs/catalog/index.md +++ b/docs/catalog/index.md @@ -40,7 +40,7 @@ It runs beside `@bedrock-core/server` and `@bedrock-core/ui`. - **A command.** `:catalog` opens the list with this addon selected. `registerCatalog({ commands: false })` leaves the command out, so you can open it from an item or a block instead. - **Every addon in the world.** Each addon that called `core.register()`, in the same order everywhere, with the framework last. -- **Each addon's page, drawn from its own pack.** The [page](./page.md) is built from the addon's manifest, so an addon with no catalog of its own still has one. +- **Each catalog addon's page, drawn from its own pack.** The [page](./page.md) is built from the addon's manifest. Other registered addons remain visible in the list and use the fallback area until shared pages move below the catalog app. ## Next steps diff --git a/docs/catalog/page.md b/docs/catalog/page.md index d5235ae..9f4ac0c 100644 --- a/docs/catalog/page.md +++ b/docs/catalog/page.md @@ -18,7 +18,7 @@ Every string on it is a localization key the client resolves from the addon's ow | `packName` | the name, large | | `version` | under the name | | `icon` | the square icon above the name | -| `thumbnail` | the 16:9 banner, when set | +| `thumbnail` | the 16:6 banner, when set | | `description` | the card | | `creatorName`, or `creator` | after "Author(s):" | @@ -26,7 +26,7 @@ Every string on it is a localization key the client resolves from the addon's ow The ui-compiler filter reads the manifest out of `core.register()` and writes a module that asks this package's `shape` for the page; that builds it and registers it, beside the addon's other compiled screens. The realm reads it back on the first tick and publishes its **reference**: per reserved entry, the value it is shown with and where a press leads. That is all another realm needs to draw the page out of the pack every client already holds. -The page is generated for an addon that installed any of the three apps. An addon that installed none publishes no page, and its row shows the fallback area, the name and version alone. +The page is generated only when the addon installs the catalog. An addon that installs another app without the catalog publishes no page yet, and its row shows the fallback area, the name and version alone. ## Where a press goes diff --git a/docs/cli/index.md b/docs/cli/index.md index c33c8d8..c8dff38 100644 --- a/docs/cli/index.md +++ b/docs/cli/index.md @@ -51,7 +51,7 @@ The template scaffolds the **whole bedrock-core stack**, not just a UI: [server ```txt my-addon/ -├── config.json Regolith: one `core` filter, four profiles +├── config.json Regolith: `core` plus six declared stages, four profiles ├── package.json scripts: regolith-install / build / build:test / watch / watch:test / lint ├── tsconfig.json JSX + the two @bedrock-core/generated aliases ├── tsconfig.test.json extends tsconfig.json; entry is scripts/gametest.ts @@ -91,6 +91,10 @@ my-addon/ ### The Regolith pipeline +The template pins `core` and all six stages in `filterDefinitions`. Run `regolith install-all` +before its first build: Regolith installs only declared filters, and does not automatically +install the stages that `core` invokes. + `config.json` runs one [`core`](/docs/filters/core) filter in every profile, which chains the six stages in dependency order — manifest, generator, guides, i18n, ui-compiler, bundler — with the namespace declared once as `shared.namespace`: | Setting | Stage | What it does | @@ -227,7 +231,7 @@ When the render pack download fails, the last line under "Render pack:" is repla | Script | What it runs | | --- | --- | -| `regolith-install` | `regolith install-all` — fetches every filter the `core` filter chains | +| `regolith-install` | `regolith install-all` — fetches every filter declared in `config.json` | | `build` | `regolith run build` — the read-only local export profile | | `build:test` | `regolith run build-test` — the read-only gametest export, for `bds-runner` | | `watch` | `regolith watch` — the development profile, redeploying on change | diff --git a/docs/config/index.md b/docs/config/index.md index e601812..8e04ad3 100644 --- a/docs/config/index.md +++ b/docs/config/index.md @@ -47,7 +47,7 @@ It runs beside `@bedrock-core/server` and `@bedrock-core/ui`. ## What you get -- **Screens shaped for your schema.** One compiled screen per section, baked into your own pack at build. A level of only groups is a screen of buttons, a level with a field is a form, and a list gets an editor of its own. Nothing about a section travels at runtime; only the values do. +- **Screens shaped for your schema.** One compiled form per section with fields, baked into your own pack at build. A level is either a form or a screen of buttons, so every button names a real child section or list. Nothing about a section travels at runtime; only the values do. - **Two commands under your own namespace.** `:config` for a player's own settings and `:configat` for an operator reaching any scope, with generated autocomplete for every verb and every setting. Turn them off with `registerConfig(definition, { commands: false })`. - **Each addon draws its own settings.** A command or `config.open()` naming another addon hands the screens to that addon's realm, which draws them from its own pack and values, and the player comes back. - **Strings you can override.** Every label, hint and command reply is a `core.*` key folded into your bundle, so a rename or a locale you ship reaches every screen. diff --git a/docs/config/schema-to-screens.md b/docs/config/schema-to-screens.md index b679a67..22c24a1 100644 --- a/docs/config/schema-to-screens.md +++ b/docs/config/schema-to-screens.md @@ -13,8 +13,10 @@ The ui-compiler filter reads the definition out of `core.register()` and bakes o | The level holds | It renders as | | --- | --- | -| only sub-groups and/or lists | a **screen of buttons** — one row per sub-group, one per list | -| at least one form field | a **form**, with any sub-groups drawn inline beneath it and indented | +| only form fields | a **form** | +| one or more sub-groups and/or lists | a **screen of buttons**, one row per sub-group or list | + +A level cannot mix form fields with sub-groups or lists. `registerConfig()` and the ui-compiler reject that shape with the path that needs restructuring. Put the form fields in a named child group instead. This keeps every screen unambiguous: it is either a form or a menu. Walking a schema shaped like the reference addon: @@ -24,9 +26,11 @@ server: { balances: { /* fields */ }, // -> form currency: { /* fields */ }, // -> form }, - display: { // has fields -> form - prefix: { /* ... */ }, - advanced: { /* fields */ }, // -> drawn INLINE, indented, inside display's form + display: { // only destinations -> screen of buttons + general: { // -> form + prefix: { /* ... */ }, + }, + advanced: { /* fields */ }, // -> own form, reached from display }, moderation: { // only lists -> screen of buttons, one row per list blockedItems: { type: 'list', /* ... */ }, @@ -37,7 +41,7 @@ server: { Depth is unbounded, and each level answers only for itself: a tree can be pure structure for three levels and then hold settings. :::note A list is not a form field -Lists do not count toward "at least one form field". A list has no modal control either, so it never needed the form, which is why a level holding nothing but lists is a button screen and each list opens a real editor there. A list on a level that *does* have fields shows its items and the command that edits them, because there is genuinely no button to give it. +Lists have no native modal control, so every level that holds one opens a screen of buttons and each list gets a real editor there. Put any form fields in a child group beside the list. ::: ## What each entry becomes @@ -63,7 +67,7 @@ Groups are nested objects, and may name themselves with [`$label` and `$descript Reached from a button screen, a list opens its own editor: current items as rows, a press to remove one, and an **Add** button. Adding presents a native modal with a text field. `maxItems` disables Add and says why. -Edits stage locally and write on **Save**, the same as the settings form. Writing per press would be one write of the whole array per item touched, each replicated to everyone mid-edit. +Each list change writes immediately. The list editor does not have a Save button because every add, edit, or removal is already a complete list value. ## Next steps diff --git a/docs/config/settings.md b/docs/config/settings.md index f874a27..fde30d5 100644 --- a/docs/config/settings.md +++ b/docs/config/settings.md @@ -62,7 +62,9 @@ const configDef = { currency: { type: 'select', default: 'emerald', options: ['emerald', 'gold', 'diamond'], label: 'Currency' }, shopEnabled: { type: 'boolean', default: true, label: 'Shop Enabled' }, }, - bannedItems: { type: 'list', maxItems: 50, default: [], label: 'Banned Items', description: 'Item IDs that cannot be sold' }, + moderation: { + bannedItems: { type: 'list', maxItems: 50, default: [], label: 'Banned Items', description: 'Item IDs that cannot be sold' }, + }, }, dimension: { miningBonus: { type: 'number', default: 1, min: 0, max: 5, label: 'Mining Bonus' }, @@ -192,8 +194,8 @@ A **`list`** is open-ended — an addon can cap it with `maxItems` but cannot en A `list` entry is an ordered array of free strings, and the only array whose items are not drawn from `options`: ```ts -config.server.bannedItems.get(); // string[] -config.server.bannedItems.set(['minecraft:bedrock', 'minecraft:barrier']); +config.server.moderation.bannedItems.get(); // string[] +config.server.moderation.bannedItems.set(['minecraft:bedrock', 'minecraft:barrier']); ``` `maxItems` caps the length. A setting whose items come from a fixed set is a `multiselect`. @@ -220,7 +222,7 @@ A modal form has no control for a list, so whether the config screen can edit on config.server.get(); // { // pricing: { taxRate: number; currency: 'emerald' | 'gold' | 'diamond'; shopEnabled: boolean }; -// bannedItems: string[]; +// moderation: { bannedItems: string[] }; // } ``` @@ -229,7 +231,7 @@ The accessor tree is built from the same machinery, so a node's `get()` returns ```ts config.server.pricing.get(); // { taxRate: number; currency: 'emerald' | 'gold' | 'diamond'; shopEnabled: boolean } config.server.pricing.currency.get(); // 'emerald' | 'gold' | 'diamond' -config.server.bannedItems.get(); // string[] +config.server.moderation.bannedItems.get(); // string[] config.server.pricing.nope; // compile error — not a schema key ``` @@ -258,7 +260,7 @@ const cfg = config.server.get(); // the whole scope, a fully typed nested config.server.patch({ pricing: { taxRate: 0.1 } }); config.server.set({ pricing: { taxRate: 0.1, currency: 'gold', shopEnabled: true }, - bannedItems: [], + moderation: { bannedItems: [] }, }); ``` diff --git a/docs/filters/ci.md b/docs/filters/ci.md index a0753da..4dcdd8b 100644 --- a/docs/filters/ci.md +++ b/docs/filters/ci.md @@ -25,11 +25,16 @@ jobs: resolvers: | github.com/bedrock-core/regolith-filters + - name: Install declared filters + run: regolith install-all + - name: Run Regolith profile run: regolith run release ``` -After the step completes, `regolith` is on `PATH` for every later step in the same job. The action runs no profile itself. +After the step completes, `regolith` is on `PATH` for every later step in the same job. The action +only registers resolvers: `regolith install-all` installs the filters in the project's +`filterDefinitions`. A `core` profile must declare `core` and its six delegated stages. ## Inputs diff --git a/docs/filters/core.md b/docs/filters/core.md index 26efbb1..7541aec 100644 --- a/docs/filters/core.md +++ b/docs/filters/core.md @@ -26,6 +26,10 @@ regolith config resolvers --append github.com/bedrock-core/regolith-filters/reso regolith install core manifest generator guides i18n ui-compiler bundler ``` +Declare those same seven names in `regolith.filterDefinitions` with their released versions. +`regolith install-all` reads only that object; it does not follow `core`'s chain. The +[CLI template](/docs/cli) is a complete pinned example. + Then one entry per profile replaces the six: ```jsonc title="config.json" diff --git a/docs/filters/index.md b/docs/filters/index.md index b4f8820..4c1f65d 100644 --- a/docs/filters/index.md +++ b/docs/filters/index.md @@ -18,9 +18,13 @@ Register the repository as a Regolith resolver once per machine, then install fi ```bash regolith config resolvers --append github.com/bedrock-core/regolith-filters/resolver.json -regolith install i18n +regolith install core manifest generator guides i18n ui-compiler bundler ``` +For a `core` profile, declare those same seven names in `config.json` under +`regolith.filterDefinitions`. `regolith install-all` reads that object; it does not +install the filters that `core` invokes transitively. + The filters run on **Node.js 22.18 or newer**. They are TypeScript files Regolith runs directly; nothing is compiled or published to npm. ## The stack diff --git a/docs/ore-styled/index.md b/docs/ore-styled/index.md index 42bb421..6853a43 100644 --- a/docs/ore-styled/index.md +++ b/docs/ore-styled/index.md @@ -27,7 +27,7 @@ No extra resource pack: the theme's textures live in the same [render pack](/doc ## Import ```tsx -import { Button, Card, Checkbox, Divider, Dropdown, Header, Input, MenuRow, Radio, Slider, Tabs, Toggle, ToggleButtons, Trail } from '@bedrock-core/ore-styled'; +import { Button, Card, Checkbox, Divider, Dropdown, Form, Header, Input, MenuRow, Radio, Slider, Tabs, Toggle, ToggleButtons, Trail } from '@bedrock-core/ore-styled'; ``` ## Layout and chrome @@ -51,7 +51,10 @@ import { Button, Card, Checkbox, Divider, Dropdown, Header, Input, MenuRow, Radi - [**``**](./Radio.md) — a bullet and a label per row - [**``**](./ToggleButtons.md) — side-by-side segments with fused borders, one choice or several -## Modal fields +## Forms and modal fields + +- **``** — the native form root with the theme's button treatment +- **``** — a submit or exit action with `primary`, `secondary`, `danger`, or `transparent` styling - [**``**](./Input.md) — a single-line text field - [**``**](./Dropdown.md) — the current selection with a chevron, and a popup @@ -69,7 +72,7 @@ fieldLabel('Volume', true); // the caption, in the theme's field-label style It takes the label and whether the control is enabled. A literal string carries the state color as a `§` prefix; a string the active resolver knows as a `.lang` key passes through untouched, because a prefix in front of a key stops it resolving. -The modal root itself draws nothing, so it is not themed: import [``](/docs/ui/components/Form) from `@bedrock-core/ui` and put these components inside it. +Use the themed `` from this package when you want its action buttons to match the rest of the screen. Its props match the runtime form root, so the field components above sit inside it in the usual way. ## Theme diff --git a/docs/ui/compiler/api.md b/docs/ui/compiler/api.md index a521ffc..189e0ca 100644 --- a/docs/ui/compiler/api.md +++ b/docs/ui/compiler/api.md @@ -29,12 +29,12 @@ compileScreen(Screen, { name, namespace? }): CompiledScreen compileFormScreen(Screen, { name, namespace }): CompiledFormScreen ``` -Both take the **component**, not the result of calling it: the compiler renders it under its own owner, which is what makes the hooks inside it resolve. `compileScreen` serves the chest; `compileFormScreen` serves the action form and the modal, deciding which from the root. Each probes for liveness before anything is baked, and each returns the served document, the face document, the preview, and the counts the filter reports. +Both take the **component**, not the result of calling it: the compiler renders it under its own owner, which is what makes the hooks inside it resolve. `compileScreen` serves the chest; `compileFormScreen` serves the action form and the modal, deciding which from the root. Each probes for liveness before anything is baked and returns the served document, face document, compiled entries and allocation data the filter needs. ## Compiling an addon ```ts -buildRouter(screens): ChestRouting +buildRouter(screens) formRouter(screens, addon): FormRouting ``` @@ -53,7 +53,6 @@ The addon-level documents: the hooks into vanilla files, and the router holding | `fill` | function | A face document plus a host, to the served document | | `emit` | function | `faceOf` then `fill`, for a caller that wants only the result | | `facesNamespaceOf` | function | `_faces`, the namespace an addon's shared faces live in | -| `previewNamespaceOf` | function | `__preview`, a preview's own namespace | | `formRouterFileOf` | function | Pack path of an addon's form router | | `CHEST_HOST` | const | The chest host: its hooks, canvas, collection and container type | | `MOUNT_ANCHOR` | const | Where a compiled chest layout sits: centered both ways | @@ -62,7 +61,7 @@ The addon-level documents: the hooks into vanilla files, and the router holding | `BACKDROP_DEFINITION` | const | Name of the full-screen image mounted behind it | | `UnsupportedNodeError` | class | Thrown for a control with no compiled form | -The IR node types, the JSON UI control types, and the result shapes (`CompiledScreen`, `CompiledFormScreen`, `FaceDocument`, `Preview`, `ScreenSpec`, `FormScreenSpec`, `ChestRouting`, `FormRouting`, `RoutedScreen`, `RoutedFormScreen`, `ToIrOptions`, `Allocation`) are exported as types beside them. +The IR node types, the JSON UI control types, and the result shapes (`CompiledScreen`, `CompiledFormScreen`, `FaceDocument`, `ScreenSpec`, `FormScreenSpec`, `FormRouting`, `RoutedScreen`, `RoutedFormScreen`, `ToIrOptions`, `Allocation`) are exported as types beside them. ## Limits diff --git a/docs/ui/components/Scroll.md b/docs/ui/components/Scroll.md index a620dc8..0a83202 100644 --- a/docs/ui/components/Scroll.md +++ b/docs/ui/components/Scroll.md @@ -5,7 +5,7 @@ description: "One independent vertical scroll region, laid out in the parent flo # Scroll `` declares an independent scroll region. Arrange a group of scrolls with a -concrete `` wrapper. A form supports up to 2 of them. + concrete `` wrapper. ## Import @@ -47,8 +47,6 @@ non-absolute scroll defaults to `flexGrow: 1` so bare ``s share the pare ## Notes -- A form supports at most **2 custom ``s** (3 total with the root scroll). Rendering - more **throws a `ScrollLimitError`** during layout. - Scrolls cost engine time on big screens. Use one only where you genuinely need an independent scrolling region; reach for a plain `` when the single root scroll will do. diff --git a/docs/ui/installation.md b/docs/ui/installation.md index 9bb1eb2..cf34293 100644 --- a/docs/ui/installation.md +++ b/docs/ui/installation.md @@ -8,7 +8,7 @@ Three things have to be in place: the package, the render pack in the world, and ## Prerequisites -- Node.js 20+ and Yarn or npm — https://nodejs.org +- Node.js 22.18.0+ and Yarn or npm — https://nodejs.org - Regolith — https://regolith-docs.readthedocs.io/en/stable Regolith is not optional here. A screen is drawn from JSON UI the build writes, so a project with no build has no screens. From 4ed69ea9d63107b56f6a3be2ddc5da24e5a23238 Mon Sep 17 00:00:00 2001 From: DrAv0011 Date: Sun, 20 Sep 2026 17:14:34 +0200 Subject: [PATCH 47/48] style(home): remove pending label from marketplace readiness - Comment out the 'Marketplace ready' entry in the TRUST array - Remove the conditional rendering of the 'soon' badge in the Hero component --- src/components/Home/index.tsx | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/components/Home/index.tsx b/src/components/Home/index.tsx index d9bd99f..ba5df7b 100644 --- a/src/components/Home/index.tsx +++ b/src/components/Home/index.tsx @@ -12,7 +12,7 @@ const GITHUB = 'https://github.com/bedrock-core/'; const TRUST = [ { icon: 'shield-check', label: 'Type-safe by design' }, { icon: 'package', label: 'Zero dependencies at runtime' }, - { icon: 'store', label: 'Marketplace ready', pending: true }, + // { icon: 'store', label: 'Marketplace ready' }, ]; export function Hero(): ReactNode { @@ -48,7 +48,6 @@ export function Hero(): ReactNode {
  • {item.label} - {item.pending ? soon : null}
  • ))} From 992b44f7a4f51266a6cc5165a95329cc50aac703 Mon Sep 17 00:00:00 2001 From: DrAv0011 Date: Sun, 20 Sep 2026 21:04:35 +0200 Subject: [PATCH 48/48] docs: correct release-facing API guidance --- docs/server/api/runtime.md | 2 +- docs/server/installation.md | 7 +- docs/ui/api/api.md | 4 +- docs/ui/api/withControl.md | 16 +- docs/ui/compiler/passes.md | 2 +- docs/ui/guides/custom-native-components.md | 397 ++------------------- docs/ui/guides/render-pack.md | 4 +- 7 files changed, 43 insertions(+), 389 deletions(-) diff --git a/docs/server/api/runtime.md b/docs/server/api/runtime.md index 9487b8d..8037291 100644 --- a/docs/server/api/runtime.md +++ b/docs/server/api/runtime.md @@ -55,7 +55,7 @@ Settings are not a member. They are a package above the runtime, reached through register(options: O): Declared ``` -Declare the addon and bring it online. **Call exactly once, at the top of the entry module, and nothing else runs after it.** It throws on an invalid manifest and on a second call. +Declare the addon and bring it online. **Call exactly once, near the top of the entry module.** Registration and declaration installation complete synchronously before the next statement. It throws on an invalid manifest and on a second call. `RegisterOptions` is a `manifest` (the [manifest fields](#manifest-fields)) plus any number of **declarations** beside it. A declaration is a value with an `install(core)` method. `register()` installs each one in the order its key was written, on the already-live runtime, and hands what `install` returned back under the same key. The runtime never knows what a declaration builds, which is what lets a package above it add a field and have its own types come back typed. diff --git a/docs/server/installation.md b/docs/server/installation.md index d8da343..cf465fc 100644 --- a/docs/server/installation.md +++ b/docs/server/installation.md @@ -24,6 +24,10 @@ If you're adding to an existing project, install the package: +The settings example below also uses the config app: + + + That single dependency pins matching versions of the packages the runtime is built on and re-exports each at its own subpath: ```ts @@ -88,6 +92,7 @@ Everything an addon *declares* rides in the one `register()` call. Here is an ec ```ts title="packs/BP/scripts/main.ts" import { core, players, schema } from '@bedrock-core/server'; +import { registerConfig } from '@bedrock-core/config'; import { world, type Player } from '@minecraft/server'; // The RPC surface other addons call. Publish this interface from a types package so @@ -129,7 +134,7 @@ const { config } = core.register({ creatorName: 'DrAv0011', version: '1.0.0', }, - config: configDef, + config: registerConfig(configDef), }); // ─── Serve RPC ─────────────────────────────────────────────────────────────── diff --git a/docs/ui/api/api.md b/docs/ui/api/api.md index 16928b7..ac92b47 100644 --- a/docs/ui/api/api.md +++ b/docs/ui/api/api.md @@ -45,8 +45,8 @@ Every component's props type is exported beside it — `ButtonProps`, `TextProps ## Advanced -- [`withControl(props)`](./withControl.md) — fill a native component's control props with their defaults, for a component that returns a host element directly -- [Custom native components](../guides/custom-native-components.md) — register your own native component `type` that the runtime serializes and your resource pack's JSON UI decodes +- [`withControl(props)`](./withControl.md) — low-level control normalization used by framework component packages +- [Extending components](../guides/custom-native-components.md) — compose public controls and understand the native-control boundary - [`@bedrock-core/ui-compiler`](../compiler/api.md) — the build-time library, for tooling rather than for addons ## Next steps diff --git a/docs/ui/api/withControl.md b/docs/ui/api/withControl.md index e53b548..277482c 100644 --- a/docs/ui/api/withControl.md +++ b/docs/ui/api/withControl.md @@ -30,31 +30,31 @@ function withControl(props: JSX.Props): JSX.Props ## Usage -Every built-in component calls it once, spreading the author's own props through first: +Framework component packages call it once before adding the fields owned by a built-in control: ```tsx import { withControl, type ControlProps, type FunctionComponent, type JSX } from '@bedrock-core/ui'; -interface RatingProps extends ControlProps { - stars: number; +interface FrameProps extends ControlProps { + children?: JSX.Node; } -const Rating: FunctionComponent = ({ stars, ...rest }: RatingProps): JSX.Element => ({ - type: 'mypack:rating', +const Frame: FunctionComponent = ({ children, ...rest }: FrameProps): JSX.Element => ({ + type: 'panel', props: { ...withControl(rest), - stars, + children, }, }); ``` ## Notes -Only needed when writing a [custom native component](../guides/custom-native-components.md) — a function that returns a host element directly. A component composed from other components (one that returns JSX rather than a host element) never calls it itself. +Addon components composed from public controls do not call `withControl`. Returning an arbitrary host-element type does not add that type to the compiler or render pack; see [Extending components](../guides/custom-native-components.md). The geometry it writes is a placeholder for the layout phase to fill in. Set layout through the flex props (`flexGrow`, `width`, `padding`, …) that `withControl` reads, not the `jsonUIx` / `jsonUIWidth` fields it leaves behind — those are the layout phase's output, not an input. ## Related - [Control props](../components/control-props.md) — the props every built-in component accepts -- [Custom native components](../guides/custom-native-components.md) — the one place authoring code calls this directly +- [Extending components](../guides/custom-native-components.md) — the supported addon composition boundary diff --git a/docs/ui/compiler/passes.md b/docs/ui/compiler/passes.md index 9a1f5b2..e036894 100644 --- a/docs/ui/compiler/passes.md +++ b/docs/ui/compiler/passes.md @@ -95,4 +95,4 @@ A host is one Minecraft screen the library draws on, and the transport that scre - [`@bedrock-core/ui-compiler`](./api.md) — the entry points the filter calls - [Hosts](../guides/hosts.md) — what each of the three screens can carry -- [Custom native components](../guides/custom-native-components.md) — adding a component the render pack draws +- [Extending components](../guides/custom-native-components.md) — composing controls and adding framework-level native behavior diff --git a/docs/ui/guides/custom-native-components.md b/docs/ui/guides/custom-native-components.md index e947bfe..d840b88 100644 --- a/docs/ui/guides/custom-native-components.md +++ b/docs/ui/guides/custom-native-components.md @@ -1,394 +1,45 @@ --- -sidebar_position: 5 -description: "Register your own native component type that the runtime serializes and your" +sidebar_position: 8 +description: "Extend the UI with composed components and understand the boundary around native controls." --- -# Custom native components -Register your own native component `type` that the runtime serializes and your -**own resource pack's JSON UI decodes and renders** — extending the framework -beyond the built-in `Panel` / `Text` / `Button` / `Image` primitives. +# Extending components -:::danger Experimental — not covered by the 1.0 API promise -A registration is a pair of halves: a writer that packs props into the byte payload, and JSON UI in your own pack that decodes them at fixed offsets. It is therefore bound to the **wire format** rather than to the component API. That format is being replaced by compiled screens, which describe a component by the values it carries instead of by a byte layout, and this entry point changes with it. Everything else in `@bedrock-core/ui` is stable at 1.0; a custom native component is not — pin an exact version if you ship one. -::: +Build reusable addon components by composing the controls exported from `@bedrock-core/ui` and `@bedrock-core/ui/ore-styled`. -:::warning Advanced — you own both sides -This is a low-level extension point, not everyday API. To use it you need to -understand **two** things: +## Compose public components -1. **Bedrock JSON UI** — control trees, bindings, and `modifications` to splice - your control into an existing screen. -2. **This runtime's serialization protocol** — how a component's props become the - compact binary payload your JSON UI control has to decode field-by-field. - -Most UIs never need this: compose the built-in components instead. Reach for a -custom native component only when you need a JSON UI capability the built-ins -don't expose (a custom renderer, a special control, a binding the runtime doesn't -emit). The render pack's own components in `packs/RP/ui/core-ui/` are the reference implementation. -::: - -## The big picture - -A native component spans two packages you control: - -``` -TypeScript (this runtime) Resource pack (your JSON UI) -───────────────────────── ──────────────────────────── -1. component -> { type, props } -2. Writer -> form.button()/label()/header() -3. registerComponent(type, ...) - │ - ▼ serialized payload (fixed-width binary, one form entry) - 4. a JSON UI control decodes the - payload, gated on #type == 'type', - spliced into a router via modifications -``` - -The runtime renders **everything** through three ActionForm primitives, each routed -by the native form factory to its own RP router: - -- `form.button()` → `button_router` (interactive) -- `form.label()` → `label_router` (static; hosts the merged `label_cell` that renders - every built-in decorative type) -- `form.header()` → `header_router` (static; the built-in `Image` rides this slot so - label cells never pay for an image subtree) - -A custom component picks one of those slots in its writer, and the matching router on -the RP side decodes it. - -## TypeScript side - -### 1. Define the component - -A native component is a function component that returns a host element whose -`type` is your unique, **namespaced** string. Props must be serializable -primitives (`string` / `number` / `boolean`); use `withControl` to carry the -standard layout / visibility / `enabled` / `background` props. +A function component can own props, state and layout while returning supported controls. It remains compatible with every host that supports those controls and needs no resource-pack registration. ```tsx -import { withControl, type JSX } from '@bedrock-core/ui'; +import { Panel, Text, type FunctionComponent, type JSX } from '@bedrock-core/ui'; interface RatingProps { - stars: number; - background?: string; -} - -function Rating({ stars, ...rest }: RatingProps): JSX.Element { - return { - type: 'mypack:rating', - props: { - ...withControl(rest), - stars, // serialized and decoded by your RP control - }, - }; -} -``` - -### 2. Write the writer - -A `Writer` emits the serialized payload into one slot. Use the provided slot -helpers — they keep your component consistent with the presenter's selection -mapping: - -- `emitButton(payload, form, ctx, callbacks, icon?)` — interactive (button) slot. - Registers `callbacks.onPress` against the current button index and advances it. -- `emitLabel(payload, form, ctx?)` — static (label) slot. Pass `ctx` through so the - modal backend's control index stays in step with the entries it consumes. -- `emitHeader(payload, form, ctx?)` — static (header) slot: the native factory routes it - to `header_router` directly, so your control is the ONLY thing instantiated for the - entry (no sibling variants at all). Prefer this slot for a static custom component; - on the modal backend it transparently falls back to the label slot. - -```tsx -import { emitLabel, type Writer } from '@bedrock-core/ui'; - -const ratingWriter: Writer = (payload, form, ctx, callbacks, props) => { - emitLabel(payload, form, ctx); // static -> label_router -}; -``` - -For an interactive control, call `emitButton` instead and pass `ctx` / `callbacks` -straight through so `onPress` is wired up. The optional 5th `props` argument lets -the writer read serialized values (e.g. to pass an icon path to `form.button`). - -### 3. Register it - -Register the `type` → behavior mapping once, **before** `render()` runs your -component. The built-ins register themselves lazily inside `render()`; put your -own registration at module load (an import side-effect-free top-level call, or a -setup function you call before your first render). - -```tsx -import { registerComponent } from '@bedrock-core/ui'; - -registerComponent('mypack:rating', { writer: ratingWriter }); -``` - -`registerComponent` **throws on a duplicate type**, so clashes between addons -surface immediately instead of silently overriding — always namespace your type -(`mypack:rating`, not `rating`). A wrapper component that emits nothing itself and -just renders its children registers as `{ transparent: true }` instead of a -writer (this is how `fragment` works). - -## Resource pack side - -The serialized payload arrives as a single form `button` or `label` entry. On the -RP side you: - -1. **Build a JSON UI control** that decodes the payload. The runtime prefixes a - protocol header, then writes each prop as a fixed-width field (type-prefixed - `s:` / `n:` / `b:`, padded, with a per-field marker). Your control slices those - fields out with `%.Ns` view bindings — exactly like the built-in components do. -2. **Gate it on `#type`** so it only renders for your component: - `(#pre_visible and (#type = 'mypack:rating'))`. -3. **Splice it into the router** — every form entry passes through `button_router` - (interactive, `emitButton`) or `label_router` (static, `emitLabel`); each control - inside renders for every entry but stays hidden unless its `#type` gate matches. - Add your control to that router's `controls` array with a JSON UI `modifications` - block — the same `insert_back` pattern the runtime uses to inject controls into - the vanilla `server_form`: - -```json -// your_pack/ui/button_router_ext.json -{ - // Modify the runtime's router (same namespace + element name = merge). - // Your pack must sit ABOVE @bedrock-core's RP in the pack stack. - "namespace": "core_ui_common", - "button_router": { - "modifications": [ - { - "array_name": "controls", - "operation": "insert_back", - "value": [ - { "rating@mypack.rating": {} } - ] - } - ] - } + value: number; } -``` - -For a static component, modify `label_router` (or `header_router` for `emitHeader`) -the same way. The inserted control (`mypack.rating`) is the decode panel from steps -1–2 — its `#type` gate is what keeps it hidden for every form entry that isn't yours. -Note that in `label_router` your control sits as a **sibling of the merged -`label_cell`**, which renders for every label-slot entry and already draws the common -`background` field (`[440]`) via its `cell_bg` leaf — so a custom label-slot component -gets its `background` prop rendered for free and should NOT decode/draw it again. - -The built-in controls are the reference implementation for the decode bindings -and the router wiring — read them alongside the serializer: - -- Decode + `#type` gate pattern: `packages/resource-pack/packs/RP/ui/core-ui/components/text.json` - (the merged `label_cell` + `cell_type_frame` gate frames) and `components/image.json` -- Router shape: `core-ui/common/button_router.json`, `label_router.json`, `header_router.json` -- Field layout & protocol `VERSION`: `packages/ui-runtime/src/core/payload.ts` - -## Performance rules for custom components - -JSON UI cost is dominated by **control instantiation and creation-time binding -evaluation** — every form entry instantiates each router's whole subtree in every -mounted scroll-pool slot, and every binding evaluates at least once at screen -creation. Payload string length is irrelevant, and `visible: false` does NOT prevent -instantiation: - -1. **Prefer the header slot** (`emitHeader`) for static components: the engine routes - the entry straight to your control — zero cost added to every other cell. A control - spliced into `label_router`/`button_router` instead is instantiated for EVERY - entry of that slot, on every mounted pool slot, whether it matches or not. -2. **Keep the non-matching cost tiny.** Structure your control as a cheap gate plus - self-gating leaves: decode `#type` with `binding_condition: "once"` (~7 bindings), - bind `#visible` from it, and put every other decode binding behind - `binding_condition: "visible"` — a non-matching entry then pays only the gate. -3. **`once` and `visible` are safe for anything screen-constant.** The payload never - changes while a screen instance is open (each `show()` builds a fresh screen), so - decode chains never need default/`always` conditions. Reserve unconditioned - bindings for genuinely live engine channels (toggle state, dropdown open state, - typed text) — and never condition a binding that a hidden control needs in order - to compute its own visibility, or it can never become visible. -4. **Emit fewer entries.** One element = one engine cell. If a wrapper renders - nothing (like a background-less ``), don't emit it; if two elements always - render together (like a background panel + its text), fold them into one payload - and one control. The serializer already does both for the built-ins. -5. **Don't re-decode what the shared machinery already provides.** In the label slot, - the merged `label_cell` draws the common `background` field for every entry; - decode only your component-specific fields (at absolute offsets `[1024]+`). -:::caution Keep the protocol in sync -The payload format is versioned (`PROTOCOL_HEADER` / `VERSION` in `payload.ts`). -If the runtime's protocol version changes, your decode bindings must be updated to -match — a mismatched header means your control reads garbage. -::: - -## Modal form controls - -Everything above covers the `ActionFormData` backend (`button_router`/`label_router`). -[`Form`](../components/Form.md) renders through a **second** backend — native -`ModalFormData` — which has its own typed controls and its own set of writer -helpers. A decorative custom component (`emitLabel`) works unchanged on both -backends, since `form.label()` exists on `ActionFormData` and `ModalFormData` alike. -An *interactive* custom component for use inside a `Form`, though, must emit through -one of the four modal-only emitters instead of `emitButton` — `ModalFormData` has no -generic button slot, only four typed ones: - -```ts -import { emitToggle, emitSlider, emitDropdown, emitInput, type Writer } from '@bedrock-core/ui'; +const Rating: FunctionComponent = ({ value }): JSX.Element => ( + + {'Rating'} + {`${value}/5`} + +); ``` -#### `emitToggle(payload, form, ctx, name, defaultValue)` -Emits a `ModalFormData.toggle`. `defaultValue: boolean`. - -#### `emitSlider(payload, form, ctx, name, min, max, defaultValue, valueStep)` -Emits a `ModalFormData.slider`. `valueStep: number | undefined` — pass `undefined` -for the native default step (`1`). - -#### `emitDropdown(payload, form, ctx, name, options, defaultValueIndex)` -Emits a `ModalFormData.dropdown`. `options: string[]`, `defaultValueIndex: number`. -The native control returns the selected **index**, not a value — see -[`Dropdown`](../components/Dropdown.md)'s result gotcha. - -#### `emitInput(payload, form, ctx, name, placeholder, defaultValue)` -Emits a `ModalFormData.textField`. `placeholder: string`, `defaultValue: string`. - -Each takes the same leading `payload, form, ctx` triple as `emitButton`, then the -native control's own typed arguments directly — not as serialized payload fields. -Each also records `name` against the control's ordinal (so the presenter can re-key -`response.formValues[ordinal]` back into `{ name: value }` after submit) before -making the typed `ModalFormData` call. A modal control writer must still throw a -`ModalFormError` if `!isModalForm(form)` — see any built-in `Form.*` writer -(e.g. `Toggle.ts`) for the guard pattern. - -### The `nativeArgs` channel +Keep the returned tree within the rules of its host. A screen uses one [``](../components/Screen.md), a modal uses one [``](../components/Form.md), and a container layout uses one [``](../components/Container.md) at its root. -A modal control's non-primitive or purely-computed data (a dropdown's `options` -array, a slider's `min`/`max`/`defaultValue`) doesn't need to survive as a decoded -JSON UI binding — the RP never reads it, only the writer does. Passing it through -the normal serialized `payload` would cost payload bytes and could shift the -byte offsets every other field is decoded at. Components route this data instead -through the writer's 6th argument, `nativeArgs?: Record` — a -side channel that's never serialized: +## Embed another addon's area -```ts -export const MyToggle: FunctionComponent = ({ name, defaultValue, ...layout }) => ({ - type: MODAL_TOGGLE_SLOT_TYPE, - props: { ...withControl(layout) /* control-block payload, decoded by the RP */ }, - nativeArgs: { name, defaultValue: defaultValue ?? false }, // writer-only, never serialized -}); -``` - -The writer reads `nativeArgs` directly (`toggleWriter` in the example above -reads `nativeArgs.name`/`nativeArgs.defaultValue`) instead of decoding them from -`props`. Most components never need this — it exists specifically for the built-in -modal field controls, where a rich prop surface (state backgrounds, geometry, -per-option styling) would otherwise blow the ≤64-props/≤80-bytes-per-field budget -described in [Caveats](#notes). A custom modal control only needs `nativeArgs` if -it has similarly non-primitive or purely-internal data to pass its writer. - -### Dropdown popup architecture - -If your custom modal control needs a floating popup (like `Dropdown`'s option -list), note that the popup is **not** rendered inside the control's own subtree — -Bedrock's native dropdown popup box ignores its host's anchors, so the built-in -dropdown renders its popup through a separate overlay: - -- **`modal_container`**'s `inside_header_panel` is a real control at the modal's - content root, *outside* the scroll, holding a `collection_panel` (`popup_overlay`) - that generates one `dropdown_popup_router` per form row. -- **`dropdown_popup_router`** shows itself only when its own row is an open - dropdown (gated on the row's decoded `#type` plus the native open/close toggle - state) and, when visible, centers a `dropdown_popup_card` on the host's exact - center point — so the popup is always form-width and layered above every row, - regardless of which cell opened it. -- The dropdown's own closed-box control (`dropdown_content`) keeps only an - **invisible** `input_panel` shield: it owns the native open/close state and the - `dropdown_exit` button mappings, but draws nothing (no `"modal": true`, or the - shield would swallow all input to the popup rendered outside it). -- `inline_select.json` deliberately points its own `dropdown_area` at a - **nonexistent** control name (`inline_offscreen_area`) — since `inside_header_panel` - is now a real host, pointing an inline (non-popup) select there would incorrectly - re-host its rows into the popup overlay. -- The main modal scroll keeps `always_handle_scrolling: false` so mouse wheel input - routes by pointer position; the popup's own scroll claims the wheel globally - (`$always_handle_scrolling: true`) only while it exists (gated by the router). - -Read `packages/resource-pack/packs/RP/ui/core-ui/common/modal_container.json` and -`.../form_components/dropdown.json` together with `optionPayload.ts` before -building a custom control that needs similar popup/overlay behavior — the comments -in those files record several traps (e.g. an `input_panel` backdrop behind the -popup silently eats all option-row clicks) that are easy to reintroduce. - -## API reference - -```ts -import { - registerComponent, - getRegisteredTypes, - emitButton, - emitLabel, - emitHeader, - type ComponentDescriptor, - type Writer, -} from '@bedrock-core/ui'; -``` - -#### `registerComponent(type, descriptor)` -- `type: string` — unique, namespaced component type; must match the JSON UI - control's `#type` gate. -- `descriptor: ComponentDescriptor` — `{ writer }` for a renderable control, or - `{ transparent: true }` for a children-only wrapper. -- Throws `SerializationError` if `type` is already registered, or if the - descriptor is neither transparent nor has a writer. - -#### `getRegisteredTypes(): string[]` -All currently registered type strings, sorted. Handy for debugging "unknown -component type" errors. - -#### `ComponentDescriptor` -```ts -interface ComponentDescriptor { - writer?: Writer; // emits the payload via emitButton / emitLabel - transparent?: boolean; // emits nothing; the serializer walks to children -} -``` - -#### `Writer` -```ts -type Writer = ( - payload: string | RawMessage, // serialized props - form: FormTarget, // ActionFormData or ModalFormData - ctx: SerializationContext | undefined, // button/ordinal index + callback map - callbacks: Record void>, // function props (onPress, ...) - props?: SerializableProps, // serialized values, if needed - nativeArgs?: Record, // writer-only side channel, see below - children?: unknown, // built children, for writers that read post-layout geometry -) => void; -``` +Use [``](../components/Embed.md) when one addon owns a compiled area that another addon's screen reserves. The embedded component is still made from public controls; its owner compiles and publishes the screen reference. -`payload` is a plain `string` for the common case. It is a `RawMessage` only when the -element's last field is a variable-length **tail** carrying a client-resolved message -(this is how `Text` ships localized copy past the fixed-width field limit) — the emit -helpers accept both, so a writer that just forwards `payload` needs no special casing. +## Native control boundary -`form` is `FormTarget = ActionFormData | ModalFormData` — narrow it with -`isActionForm`/`isModalForm` before calling a backend-specific method. `nativeArgs` -and `children` are almost always `undefined` for an ActionForm-only component; they -exist for [modal form controls](#modal-form-controls) that need a side channel for -non-primitive data or post-layout child geometry (e.g. `Select` reading each -`Option`'s computed position). +Addon code cannot register a new host-element type for the compiled-screen pipeline. A native control needs matching behavior in the runtime tree, the UI compiler, each supported host and the shared render pack. Registering a serializer or adding JSON UI in one addon does not establish that contract for other addons. -#### `emitButton` / `emitLabel` / `emitHeader` -Slot helpers for ActionForm writers — see [step 2](#2-write-the-writer). For modal -form writers, see [`emitToggle`/`emitSlider`/`emitDropdown`/`emitInput`](#modal-form-controls). +The runtime exports a few low-level descriptor and writer types for framework packages. They are implementation interfaces rather than an addon extension point. Add a new native control to the framework packages and their tests together when composition cannot express the required behavior. -## Notes +## Next steps -- **Namespace your type.** Registration throws on duplicates; `mypack:rating` - avoids cross-addon clashes. -- **Register before serialization.** If a component serializes before its type is - registered, `render()` throws "Unknown native component type". -- **Props must be serializable primitives** (`string` / `number` / `boolean`). - Functions are collected as callbacks (e.g. `onPress`); everything else throws. -- **Field budget.** Each string/number field is fixed-width (≤ 80 bytes per value), - and an element can carry at most 64 props — keep payloads lean. -- **You maintain the RP side.** A runtime protocol bump requires updating your - decode bindings to match. +- [Components](../components/components.md) — controls available for composition +- [Hosts](./hosts.md) — rules and capabilities of each screen host +- [`Embed`](../components/Embed.md) — reserve and fill an area across addon packs diff --git a/docs/ui/guides/render-pack.md b/docs/ui/guides/render-pack.md index ca55cb7..678e7bd 100644 --- a/docs/ui/guides/render-pack.md +++ b/docs/ui/guides/render-pack.md @@ -98,7 +98,5 @@ See [`Text`](../components/Text.md) for the component and [i18n](/docs/i18n/api) For an `Image` cell the component-specific region is just the texture tail. For a `Text` cell it carries the label group: `labelFontType`, `fontScaleFactor`, `labelX` `[1190]`, `labelY` `[1273]`, and the text tail. `labelFontType` stays in the group even though the cell label sources `[606]`, so every sub-element group reads its own slot 1 at the same offset. -:::tip Custom native components are unaffected -Fields you define in a [custom native component](./custom-native-components.md) start at `[1024]`. Common fields such as `region` and `fontType` are carved from the reserved block so that offset never moves; a resource pack decoding a custom component at a fixed offset from 1024 keeps working across render-pack releases. -::: +The framework's component-specific fields begin at `[1024]`. They are part of the shared runtime/compiler/render-pack contract rather than an addon extension point. See [Extending components](./custom-native-components.md) for the supported composition boundary.

    fN{Lrb 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 I=6L?U0Calb-T(jq literal 32618 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 E0oUuvbN~PV diff --git a/static/img/ui/guide-page.png b/static/img/ui/guide-page.png index 1eee726bb070cdc691e86a550489fc677273a5f0..cd56a82d61645b2f0ab914a10c3dd7e9b8fb7a61 100644 GIT binary patch literal 79681 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%0D3s3QDhj)Y2Y>01l%{Fqcb`{EZ@(mc=IR91EPS@u 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%0A>;ky8@GAQK{x{I4LXi`{eTjy`s?{B&b1 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 bJwEe%9kXLRA~g>TBAAo}LOfSY@BRM)R;IQh diff --git a/tsconfig.json b/tsconfig.json index 3585c51..eb011c3 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,6 +1,10 @@ { // This file is not used in compilation. It is here just for a nice editor experience. "extends": "@docusaurus/tsconfig", + "compilerOptions": { + // @docusaurus/tsconfig sets the deprecated `baseUrl` for its `@site/*` path alias. + "ignoreDeprecations": "6.0" + }, "exclude": [ ".docusaurus", "build" diff --git a/yarn.lock b/yarn.lock index 25171c5..fc30de7 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1512,6 +1512,7 @@ __metadata: "@docusaurus/preset-classic": "npm:^3.10.2" "@docusaurus/tsconfig": "npm:^3.10.2" "@docusaurus/types": "npm:^3.10.2" + "@easyops-cn/docusaurus-search-local": "npm:^0.55.3" "@mdx-js/react": "npm:^3.1.1" clsx: "npm:^2.1.1" docusaurus-plugin-llms: "npm:^0.4.0" @@ -2414,7 +2415,7 @@ __metadata: languageName: node linkType: hard -"@docusaurus/plugin-content-docs@npm:3.10.2": +"@docusaurus/plugin-content-docs@npm:3.10.2, @docusaurus/plugin-content-docs@npm:^2 || ^3": version: 3.10.2 resolution: "@docusaurus/plugin-content-docs@npm:3.10.2" dependencies: @@ -2691,7 +2692,7 @@ __metadata: languageName: node linkType: hard -"@docusaurus/theme-translations@npm:3.10.2": +"@docusaurus/theme-translations@npm:3.10.2, @docusaurus/theme-translations@npm:^2 || ^3": version: 3.10.2 resolution: "@docusaurus/theme-translations@npm:3.10.2" dependencies: @@ -2729,7 +2730,7 @@ __metadata: languageName: node linkType: hard -"@docusaurus/utils-common@npm:3.10.2": +"@docusaurus/utils-common@npm:3.10.2, @docusaurus/utils-common@npm:^2 || ^3": version: 3.10.2 resolution: "@docusaurus/utils-common@npm:3.10.2" dependencies: @@ -2739,7 +2740,7 @@ __metadata: languageName: node linkType: hard -"@docusaurus/utils-validation@npm:3.10.2": +"@docusaurus/utils-validation@npm:3.10.2, @docusaurus/utils-validation@npm:^2 || ^3": version: 3.10.2 resolution: "@docusaurus/utils-validation@npm:3.10.2" dependencies: @@ -2755,7 +2756,7 @@ __metadata: languageName: node linkType: hard -"@docusaurus/utils@npm:3.10.2": +"@docusaurus/utils@npm:3.10.2, @docusaurus/utils@npm:^2 || ^3": version: 3.10.2 resolution: "@docusaurus/utils@npm:3.10.2" dependencies: @@ -2784,6 +2785,59 @@ __metadata: languageName: node linkType: hard +"@easyops-cn/autocomplete.js@npm:^0.38.1": + version: 0.38.1 + resolution: "@easyops-cn/autocomplete.js@npm:0.38.1" + dependencies: + cssesc: "npm:^3.0.0" + immediate: "npm:^3.2.3" + checksum: 10c0/114132fc71811cb319463ef9592179b99ab6265030e612c0c790839929764c6f632d7e155784fe89921365005ddf838cb83ed428799de67c581d25e1110bc84d + languageName: node + linkType: hard + +"@easyops-cn/docusaurus-search-local@npm:^0.55.3": + version: 0.55.3 + resolution: "@easyops-cn/docusaurus-search-local@npm:0.55.3" + dependencies: + "@docusaurus/plugin-content-docs": "npm:^2 || ^3" + "@docusaurus/theme-translations": "npm:^2 || ^3" + "@docusaurus/utils": "npm:^2 || ^3" + "@docusaurus/utils-common": "npm:^2 || ^3" + "@docusaurus/utils-validation": "npm:^2 || ^3" + "@easyops-cn/autocomplete.js": "npm:^0.38.1" + "@node-rs/jieba": "npm:^1.6.0" + cheerio: "npm:^1.0.0" + clsx: "npm:^2.1.1" + comlink: "npm:^4.4.2" + debug: "npm:^4.2.0" + fs-extra: "npm:^10.0.0" + klaw-sync: "npm:^6.0.0" + lunr: "npm:^2.3.9" + lunr-languages: "npm:^1.4.0" + mark.js: "npm:^8.11.1" + tslib: "npm:^2.4.0" + peerDependencies: + "@docusaurus/theme-common": ^2 || ^3 + open-ask-ai: ^0.7.3 + react: ^16.14.0 || ^17 || ^18 || ^19 + react-dom: ^16.14.0 || 17 || ^18 || ^19 + peerDependenciesMeta: + open-ask-ai: + optional: true + checksum: 10c0/1b12d64ad6b83dec0810518ef20d643af524bd17a23e83c55c33ae9837f4f30f474c49398b93522d063bd2039762ea76475aec81e81ab0a8254ae3fe65f16313 + languageName: node + linkType: hard + +"@emnapi/core@npm:^1.4.3": + version: 1.11.3 + resolution: "@emnapi/core@npm:1.11.3" + dependencies: + "@emnapi/wasi-threads": "npm:1.2.3" + tslib: "npm:^2.4.0" + checksum: 10c0/4ca08d349a82d5d2887ccc9e12df630877b0412ddcd59b9faee61e3c3947ccead27a18257a18bfe17abdf2b0709857808ad75d423ac49edd50c32fb140a7ed6e + languageName: node + linkType: hard + "@emnapi/core@npm:^1.5.0": version: 1.10.0 resolution: "@emnapi/core@npm:1.10.0" @@ -2794,6 +2848,15 @@ __metadata: languageName: node linkType: hard +"@emnapi/runtime@npm:^1.4.3": + version: 1.11.3 + resolution: "@emnapi/runtime@npm:1.11.3" + dependencies: + tslib: "npm:^2.4.0" + checksum: 10c0/a00f1020fefb9d4145c367f93a9fddb383a00da8ffd7871e20b19659890379b83aeecb9f84d7d0eda5456343f4a09eb05b0acb5153b0d3d889539dedb1ed87c3 + languageName: node + linkType: hard + "@emnapi/runtime@npm:^1.5.0": version: 1.10.0 resolution: "@emnapi/runtime@npm:1.10.0" @@ -2812,6 +2875,15 @@ __metadata: languageName: node linkType: hard +"@emnapi/wasi-threads@npm:1.2.3": + version: 1.2.3 + resolution: "@emnapi/wasi-threads@npm:1.2.3" + dependencies: + tslib: "npm:^2.4.0" + checksum: 10c0/5aed84bc5dbe867973b20406ca1ed95661a4892ecaef80378fdf2d37424b3f7b9c428df8a3e1d82b783a3345a530032bf049e699e1f113ea52203c3e9b4e6ce5 + languageName: node + linkType: hard + "@eslint-community/eslint-utils@npm:^4.2.0": version: 4.9.0 resolution: "@eslint-community/eslint-utils@npm:4.9.0" @@ -3126,6 +3198,168 @@ __metadata: languageName: node linkType: hard +"@napi-rs/wasm-runtime@npm:^0.2.3": + version: 0.2.12 + resolution: "@napi-rs/wasm-runtime@npm:0.2.12" + dependencies: + "@emnapi/core": "npm:^1.4.3" + "@emnapi/runtime": "npm:^1.4.3" + "@tybys/wasm-util": "npm:^0.10.0" + checksum: 10c0/6d07922c0613aab30c6a497f4df297ca7c54e5b480e00035e0209b872d5c6aab7162fc49477267556109c2c7ed1eb9c65a174e27e9b87568106a87b0a6e3ca7d + languageName: node + linkType: hard + +"@node-rs/jieba-android-arm-eabi@npm:1.10.4": + version: 1.10.4 + resolution: "@node-rs/jieba-android-arm-eabi@npm:1.10.4" + conditions: os=android & cpu=arm + languageName: node + linkType: hard + +"@node-rs/jieba-android-arm64@npm:1.10.4": + version: 1.10.4 + resolution: "@node-rs/jieba-android-arm64@npm:1.10.4" + conditions: os=android & cpu=arm64 + languageName: node + linkType: hard + +"@node-rs/jieba-darwin-arm64@npm:1.10.4": + version: 1.10.4 + resolution: "@node-rs/jieba-darwin-arm64@npm:1.10.4" + conditions: os=darwin & cpu=arm64 + languageName: node + linkType: hard + +"@node-rs/jieba-darwin-x64@npm:1.10.4": + version: 1.10.4 + resolution: "@node-rs/jieba-darwin-x64@npm:1.10.4" + conditions: os=darwin & cpu=x64 + languageName: node + linkType: hard + +"@node-rs/jieba-freebsd-x64@npm:1.10.4": + version: 1.10.4 + resolution: "@node-rs/jieba-freebsd-x64@npm:1.10.4" + conditions: os=freebsd & cpu=x64 + languageName: node + linkType: hard + +"@node-rs/jieba-linux-arm-gnueabihf@npm:1.10.4": + version: 1.10.4 + resolution: "@node-rs/jieba-linux-arm-gnueabihf@npm:1.10.4" + conditions: os=linux & cpu=arm + languageName: node + linkType: hard + +"@node-rs/jieba-linux-arm64-gnu@npm:1.10.4": + version: 1.10.4 + resolution: "@node-rs/jieba-linux-arm64-gnu@npm:1.10.4" + conditions: os=linux & cpu=arm64 & libc=glibc + languageName: node + linkType: hard + +"@node-rs/jieba-linux-arm64-musl@npm:1.10.4": + version: 1.10.4 + resolution: "@node-rs/jieba-linux-arm64-musl@npm:1.10.4" + conditions: os=linux & cpu=arm64 & libc=musl + languageName: node + linkType: hard + +"@node-rs/jieba-linux-x64-gnu@npm:1.10.4": + version: 1.10.4 + resolution: "@node-rs/jieba-linux-x64-gnu@npm:1.10.4" + conditions: os=linux & cpu=x64 & libc=glibc + languageName: node + linkType: hard + +"@node-rs/jieba-linux-x64-musl@npm:1.10.4": + version: 1.10.4 + resolution: "@node-rs/jieba-linux-x64-musl@npm:1.10.4" + conditions: os=linux & cpu=x64 & libc=musl + languageName: node + linkType: hard + +"@node-rs/jieba-wasm32-wasi@npm:1.10.4": + version: 1.10.4 + resolution: "@node-rs/jieba-wasm32-wasi@npm:1.10.4" + dependencies: + "@napi-rs/wasm-runtime": "npm:^0.2.3" + conditions: cpu=wasm32 + languageName: node + linkType: hard + +"@node-rs/jieba-win32-arm64-msvc@npm:1.10.4": + version: 1.10.4 + resolution: "@node-rs/jieba-win32-arm64-msvc@npm:1.10.4" + conditions: os=win32 & cpu=arm64 + languageName: node + linkType: hard + +"@node-rs/jieba-win32-ia32-msvc@npm:1.10.4": + version: 1.10.4 + resolution: "@node-rs/jieba-win32-ia32-msvc@npm:1.10.4" + conditions: os=win32 & cpu=ia32 + languageName: node + linkType: hard + +"@node-rs/jieba-win32-x64-msvc@npm:1.10.4": + version: 1.10.4 + resolution: "@node-rs/jieba-win32-x64-msvc@npm:1.10.4" + conditions: os=win32 & cpu=x64 + languageName: node + linkType: hard + +"@node-rs/jieba@npm:^1.6.0": + version: 1.10.4 + resolution: "@node-rs/jieba@npm:1.10.4" + dependencies: + "@node-rs/jieba-android-arm-eabi": "npm:1.10.4" + "@node-rs/jieba-android-arm64": "npm:1.10.4" + "@node-rs/jieba-darwin-arm64": "npm:1.10.4" + "@node-rs/jieba-darwin-x64": "npm:1.10.4" + "@node-rs/jieba-freebsd-x64": "npm:1.10.4" + "@node-rs/jieba-linux-arm-gnueabihf": "npm:1.10.4" + "@node-rs/jieba-linux-arm64-gnu": "npm:1.10.4" + "@node-rs/jieba-linux-arm64-musl": "npm:1.10.4" + "@node-rs/jieba-linux-x64-gnu": "npm:1.10.4" + "@node-rs/jieba-linux-x64-musl": "npm:1.10.4" + "@node-rs/jieba-wasm32-wasi": "npm:1.10.4" + "@node-rs/jieba-win32-arm64-msvc": "npm:1.10.4" + "@node-rs/jieba-win32-ia32-msvc": "npm:1.10.4" + "@node-rs/jieba-win32-x64-msvc": "npm:1.10.4" + dependenciesMeta: + "@node-rs/jieba-android-arm-eabi": + optional: true + "@node-rs/jieba-android-arm64": + optional: true + "@node-rs/jieba-darwin-arm64": + optional: true + "@node-rs/jieba-darwin-x64": + optional: true + "@node-rs/jieba-freebsd-x64": + optional: true + "@node-rs/jieba-linux-arm-gnueabihf": + optional: true + "@node-rs/jieba-linux-arm64-gnu": + optional: true + "@node-rs/jieba-linux-arm64-musl": + optional: true + "@node-rs/jieba-linux-x64-gnu": + optional: true + "@node-rs/jieba-linux-x64-musl": + optional: true + "@node-rs/jieba-wasm32-wasi": + optional: true + "@node-rs/jieba-win32-arm64-msvc": + optional: true + "@node-rs/jieba-win32-ia32-msvc": + optional: true + "@node-rs/jieba-win32-x64-msvc": + optional: true + checksum: 10c0/9c51e51e9c0319e1a9d658bf08adf7b2ace06e30fb248ef499fe0059fc582071e8e1d197783c1fcf084cf0d738c3828f7fd50f35735f2b1cf9d003171b8e43e2 + languageName: node + linkType: hard + "@nodelib/fs.scandir@npm:2.1.5": version: 2.1.5 resolution: "@nodelib/fs.scandir@npm:2.1.5" @@ -3859,6 +4093,15 @@ __metadata: languageName: node linkType: hard +"@tybys/wasm-util@npm:^0.10.0": + version: 0.10.4 + resolution: "@tybys/wasm-util@npm:0.10.4" + dependencies: + tslib: "npm:^2.4.0" + checksum: 10c0/27947f254efa3f2bc41f47040f57f41c246200c6439a9fd54c69f50940e320022c320275f138e30b543ee81ce69593905dfa7ba0831577ab636f829aafa70701 + languageName: node + linkType: hard + "@tybys/wasm-util@npm:^0.10.1": version: 0.10.2 resolution: "@tybys/wasm-util@npm:0.10.2" @@ -5345,6 +5588,25 @@ __metadata: languageName: node linkType: hard +"cheerio@npm:^1.0.0": + version: 1.2.0 + resolution: "cheerio@npm:1.2.0" + dependencies: + cheerio-select: "npm:^2.1.0" + dom-serializer: "npm:^2.0.0" + domhandler: "npm:^5.0.3" + domutils: "npm:^3.2.2" + encoding-sniffer: "npm:^0.2.1" + htmlparser2: "npm:^10.1.0" + parse5: "npm:^7.3.0" + parse5-htmlparser2-tree-adapter: "npm:^7.1.0" + parse5-parser-stream: "npm:^7.1.2" + undici: "npm:^7.19.0" + whatwg-mimetype: "npm:^4.0.0" + checksum: 10c0/91a566aabfa9962f28056045bb7d92d79c0f8f3abb1fb86a852a9d1760556adddeb01a36b6f08fa7c133282375d387ae450a181a659e76c6a64016c30cc3f611 + languageName: node + linkType: hard + "chokidar@npm:^3.5.3, chokidar@npm:^3.6.0": version: 3.6.0 resolution: "chokidar@npm:3.6.0" @@ -5483,6 +5745,13 @@ __metadata: languageName: node linkType: hard +"comlink@npm:^4.4.2": + version: 4.4.2 + resolution: "comlink@npm:4.4.2" + checksum: 10c0/38aa1f455cf08e94aaa8fc494fd203cc0ef02ece6c21404b7931ce17567e8a72deacddab98aa5650cfd78332ff24c34610586f6fb27fd19dc77e753ed1980deb + languageName: node + linkType: hard + "comma-separated-tokens@npm:^2.0.0": version: 2.0.3 resolution: "comma-separated-tokens@npm:2.0.3" @@ -6001,7 +6270,7 @@ __metadata: languageName: node linkType: hard -"debug@npm:4, debug@npm:^4.0.0, debug@npm:^4.1.0, debug@npm:^4.3.1, debug@npm:^4.3.4, debug@npm:^4.4.1": +"debug@npm:4, debug@npm:^4.0.0, debug@npm:^4.1.0, debug@npm:^4.2.0, debug@npm:^4.3.1, debug@npm:^4.3.4, debug@npm:^4.4.1": version: 4.4.3 resolution: "debug@npm:4.4.3" dependencies: @@ -6266,7 +6535,7 @@ __metadata: languageName: node linkType: hard -"domutils@npm:^3.0.1": +"domutils@npm:^3.0.1, domutils@npm:^3.2.2": version: 3.2.2 resolution: "domutils@npm:3.2.2" dependencies: @@ -6391,6 +6660,16 @@ __metadata: languageName: node linkType: hard +"encoding-sniffer@npm:^0.2.1": + version: 0.2.1 + resolution: "encoding-sniffer@npm:0.2.1" + dependencies: + iconv-lite: "npm:^0.6.3" + whatwg-encoding: "npm:^3.1.1" + checksum: 10c0/d6b591880788f3baf8dd1744636dd189d24a1ec93e6f9817267c60ac3458a5191ca70ab1a186fb67731beff1c3489c6527dfdc4718158ed8460ab2f400dd5e7d + languageName: node + linkType: hard + "encoding@npm:^0.1.13": version: 0.1.13 resolution: "encoding@npm:0.1.13" @@ -6431,6 +6710,13 @@ __metadata: languageName: node linkType: hard +"entities@npm:^7.0.1": + version: 7.0.1 + resolution: "entities@npm:7.0.1" + checksum: 10c0/b4fb9937bb47ecb00aaaceb9db9cdd1cc0b0fb649c0e843d05cf5dbbd2e9d2df8f98721d8b1b286445689c72af7b54a7242fc2d63ef7c9739037a8c73363e7ca + languageName: node + linkType: hard + "env-paths@npm:^2.2.0": version: 2.2.1 resolution: "env-paths@npm:2.2.1" @@ -6996,6 +7282,17 @@ __metadata: languageName: node linkType: hard +"fs-extra@npm:^10.0.0": + version: 10.1.0 + resolution: "fs-extra@npm:10.1.0" + dependencies: + graceful-fs: "npm:^4.2.0" + jsonfile: "npm:^6.0.1" + universalify: "npm:^2.0.0" + checksum: 10c0/5f579466e7109719d162a9249abbeffe7f426eb133ea486e020b89bc6d67a741134076bf439983f2eb79276ceaf6bd7b7c1e43c3fd67fe889863e69072fb0a5e + languageName: node + linkType: hard + "fs-extra@npm:^11.1.1, fs-extra@npm:^11.2.0": version: 11.3.2 resolution: "fs-extra@npm:11.3.2" @@ -7227,7 +7524,7 @@ __metadata: languageName: node linkType: hard -"graceful-fs@npm:^4.1.2, graceful-fs@npm:^4.1.6, graceful-fs@npm:^4.2.0, graceful-fs@npm:^4.2.11, graceful-fs@npm:^4.2.4, graceful-fs@npm:^4.2.6, graceful-fs@npm:^4.2.9": +"graceful-fs@npm:^4.1.11, graceful-fs@npm:^4.1.2, graceful-fs@npm:^4.1.6, graceful-fs@npm:^4.2.0, graceful-fs@npm:^4.2.11, graceful-fs@npm:^4.2.4, graceful-fs@npm:^4.2.6, graceful-fs@npm:^4.2.9": version: 4.2.11 resolution: "graceful-fs@npm:4.2.11" checksum: 10c0/386d011a553e02bc594ac2ca0bd6d9e4c22d7fa8cfbfc448a6d148c59ea881b092db9dbe3547ae4b88e55f1b01f7c4a2ecc53b310c042793e63aa44cf6c257f2 @@ -7551,6 +7848,18 @@ __metadata: languageName: node linkType: hard +"htmlparser2@npm:^10.1.0": + version: 10.1.0 + resolution: "htmlparser2@npm:10.1.0" + dependencies: + domelementtype: "npm:^2.3.0" + domhandler: "npm:^5.0.3" + domutils: "npm:^3.2.2" + entities: "npm:^7.0.1" + checksum: 10c0/36394e29b80cfcc5e78e0fa4d3aa21fdaac3e6778d23e5c933e625c290987cd9a724a2eb0753ab60ed0c69dfaba0ab115f0ee50fb112fd8f0c4d522e7e0089a2 + languageName: node + linkType: hard + "htmlparser2@npm:^6.1.0": version: 6.1.0 resolution: "htmlparser2@npm:6.1.0" @@ -7703,7 +8012,7 @@ __metadata: languageName: node linkType: hard -"iconv-lite@npm:^0.6.2": +"iconv-lite@npm:0.6.3, iconv-lite@npm:^0.6.2, iconv-lite@npm:^0.6.3": version: 0.6.3 resolution: "iconv-lite@npm:0.6.3" dependencies: @@ -7737,6 +8046,13 @@ __metadata: languageName: node linkType: hard +"immediate@npm:^3.2.3": + version: 3.3.0 + resolution: "immediate@npm:3.3.0" + checksum: 10c0/40eab095d5944ad79af054700beee97000271fde8743720932d8eb41ccbf2cb8c855ff95b128cf9a7fec523a4f11ee2e392b9f2fa6456b055b1160f1b4ad3e3b + languageName: node + linkType: hard + "import-fresh@npm:^3.3.0": version: 3.3.1 resolution: "import-fresh@npm:3.3.1" @@ -8299,6 +8615,15 @@ __metadata: languageName: node linkType: hard +"klaw-sync@npm:^6.0.0": + version: 6.0.0 + resolution: "klaw-sync@npm:6.0.0" + dependencies: + graceful-fs: "npm:^4.1.11" + checksum: 10c0/00d8e4c48d0d699b743b3b028e807295ea0b225caf6179f51029e19783a93ad8bb9bccde617d169659fbe99559d73fb35f796214de031d0023c26b906cecd70a + languageName: node + linkType: hard + "kleur@npm:^3.0.3": version: 3.0.3 resolution: "kleur@npm:3.0.3" @@ -8580,6 +8905,20 @@ __metadata: languageName: node linkType: hard +"lunr-languages@npm:^1.4.0": + version: 1.22.0 + resolution: "lunr-languages@npm:1.22.0" + checksum: 10c0/ba222d17cbef233bb44ac84c7937a9ce7b3162d42f9164d85057cd813e77146d4b21c4628b19577ec99d9819b5b8814e4bc57eb535021fa2669581bb98dc7f41 + languageName: node + linkType: hard + +"lunr@npm:^2.3.9": + version: 2.3.9 + resolution: "lunr@npm:2.3.9" + checksum: 10c0/77d7dbb4fbd602aac161e2b50887d8eda28c0fa3b799159cee380fbb311f1e614219126ecbbd2c3a9c685f1720a8109b3c1ca85cc893c39b6c9cc6a62a1d8a8b + languageName: node + linkType: hard + "make-fetch-happen@npm:^14.0.3": version: 14.0.3 resolution: "make-fetch-happen@npm:14.0.3" @@ -8599,6 +8938,13 @@ __metadata: languageName: node linkType: hard +"mark.js@npm:^8.11.1": + version: 8.11.1 + resolution: "mark.js@npm:8.11.1" + checksum: 10c0/5e69e776db61abdd857b5cbb7070c8a3b1b0e5c12bf077fcd5a8c6f17b1f85ed65275aba5662b57136d1b9f82b54bb34d4ef4220f7703c9a7ab806ae1e208cff + languageName: node + linkType: hard + "markdown-extensions@npm:^2.0.0": version: 2.0.0 resolution: "markdown-extensions@npm:2.0.0" @@ -10103,7 +10449,7 @@ __metadata: languageName: node linkType: hard -"parse5-htmlparser2-tree-adapter@npm:^7.0.0": +"parse5-htmlparser2-tree-adapter@npm:^7.0.0, parse5-htmlparser2-tree-adapter@npm:^7.1.0": version: 7.1.0 resolution: "parse5-htmlparser2-tree-adapter@npm:7.1.0" dependencies: @@ -10113,7 +10459,16 @@ __metadata: languageName: node linkType: hard -"parse5@npm:^7.0.0": +"parse5-parser-stream@npm:^7.1.2": + version: 7.1.2 + resolution: "parse5-parser-stream@npm:7.1.2" + dependencies: + parse5: "npm:^7.0.0" + checksum: 10c0/e236c61000d38ecad369e725a48506b051cebad8abb00e6d4e8bff7aa85c183820fcb45db1559cc90955bdbbdbd665ea94c41259594e74566fff411478dc7fcb + languageName: node + linkType: hard + +"parse5@npm:^7.0.0, parse5@npm:^7.3.0": version: 7.3.0 resolution: "parse5@npm:7.3.0" dependencies: @@ -12776,6 +13131,13 @@ __metadata: languageName: node linkType: hard +"undici@npm:^7.19.0": + version: 7.29.1 + resolution: "undici@npm:7.29.1" + checksum: 10c0/5a419b1364531071ebdfd93748f7f2392d4eb6d68dd99814e1020f8fc6a517e3298129004c871516ee204bac68aba93541f587200b04a7449b8d45683a7d86f6 + languageName: node + linkType: hard + "unicode-canonical-property-names-ecmascript@npm:^2.0.0": version: 2.0.1 resolution: "unicode-canonical-property-names-ecmascript@npm:2.0.1" @@ -13301,6 +13663,22 @@ __metadata: languageName: node linkType: hard +"whatwg-encoding@npm:^3.1.1": + version: 3.1.1 + resolution: "whatwg-encoding@npm:3.1.1" + dependencies: + iconv-lite: "npm:0.6.3" + checksum: 10c0/273b5f441c2f7fda3368a496c3009edbaa5e43b71b09728f90425e7f487e5cef9eb2b846a31bd760dd8077739c26faf6b5ca43a5f24033172b003b72cf61a93e + languageName: node + linkType: hard + +"whatwg-mimetype@npm:^4.0.0": + version: 4.0.0 + resolution: "whatwg-mimetype@npm:4.0.0" + checksum: 10c0/a773cdc8126b514d790bdae7052e8bf242970cebd84af62fb2f35a33411e78e981f6c0ab9ed1fe6ec5071b09d5340ac9178e05b52d35a9c4bcf558ba1b1551df + languageName: node + linkType: hard + "which@npm:^2.0.1": version: 2.0.2 resolution: "which@npm:2.0.2" From bc0f3fe59e059ad26eec0217ddc7ab056003919e Mon Sep 17 00:00:00 2001 From: DrAv0011 Date: Thu, 17 Sep 2026 17:35:16 +0200 Subject: [PATCH 36/48] docs(ore-styled): Tabs, ToggleButtons and fieldLabel pages, alphabetical sidebar - ToggleButtons replaces ToggleButton, and Tabs and fieldLabel have pages; Tabs and Trail show screenshots. - Header and Trail describe a baked trail as one label per language. - The sidebar lists the overview, the components alphabetically, then fieldLabel and theme. Co-Authored-By: Claude Opus 5 (1M context) --- docs/ore-styled/Button.md | 33 ++++----- docs/ore-styled/Card.md | 7 +- docs/ore-styled/Checkbox.md | 9 +-- docs/ore-styled/Divider.md | 1 - docs/ore-styled/Dropdown.md | 13 ++-- docs/ore-styled/Header.md | 31 +++++--- docs/ore-styled/Input.md | 11 ++- docs/ore-styled/MenuRow.md | 7 +- docs/ore-styled/Radio.md | 13 ++-- docs/ore-styled/Slider.md | 11 ++- docs/ore-styled/Tabs.md | 69 +++++++++++++++++ docs/ore-styled/Toggle.md | 9 +-- docs/ore-styled/ToggleButton.md | 106 -------------------------- docs/ore-styled/ToggleButtons.md | 123 +++++++++++++++++++++++++++++++ docs/ore-styled/Trail.md | 60 +++++++++------ docs/ore-styled/fieldLabel.md | 58 +++++++++++++++ docs/ore-styled/index.md | 22 +++--- docs/ore-styled/theme.md | 13 ++-- static/img/ore-styled/Tabs.png | Bin 0 -> 2218 bytes static/img/ore-styled/Trail.png | Bin 0 -> 2371 bytes 20 files changed, 375 insertions(+), 221 deletions(-) create mode 100644 docs/ore-styled/Tabs.md delete mode 100644 docs/ore-styled/ToggleButton.md create mode 100644 docs/ore-styled/ToggleButtons.md create mode 100644 docs/ore-styled/fieldLabel.md create mode 100644 static/img/ore-styled/Tabs.png create mode 100644 static/img/ore-styled/Trail.png diff --git a/docs/ore-styled/Button.md b/docs/ore-styled/Button.md index 10abc33..9de6415 100644 --- a/docs/ore-styled/Button.md +++ b/docs/ore-styled/Button.md @@ -1,10 +1,9 @@ --- -sidebar_position: 2 description: "Themed button with seven visual variants." --- # Button -Themed button with seven visual variants. Built on top of the [`Button`](/docs/ui/components/controls/Button) primitive and the [theme](./theme.md) token map. +Themed button with seven visual variants. Built on top of the [`Button`](/docs/ui/components/Button) primitive and the [theme](./theme.md) token map. ![Button](/img/ore-styled/Button.png) @@ -17,7 +16,7 @@ import { Button } from '@bedrock-core/ore-styled'; ## Usage ```tsx - ``` @@ -30,8 +29,8 @@ When `children` is a string the button automatically wraps it in a `Text` styled | --- | --- | --- | --- | | `variant` | `'hero' \| 'primary' \| 'secondary' \| 'contrast' \| 'danger' \| 'realm' \| 'transparent'` | `'primary'`, or `'secondary'` for `action={'exit'}` | The texture set and text style. `hero` is the primary texture with the `minecraftTen` heading font; `transparent` has no shell, for icon-only or inline actions | | `children` | `string \| JSX.Node` | — | A string is auto-wrapped in a themed `Text`; any other node is rendered as-is | -| `action` | `(event: PressEvent) => unknown \| Promise` \| `'submit'` \| `'exit'` | — | What the press does: a handler, or a form's own two actions. Use `to` instead when the press opens another screen | -| `to` | `ScreenKey` | — | The screen this button opens, `:`. A button with one is a [``](/docs/ui/components/controls/Link) | +| `onPress` | `(event: PressEvent) => unknown \| Promise` | — | Runs on the press, with the player who pressed. A form's submit and exit are `Form.Button`; use `to` when the press opens another screen | +| `to` | `ScreenKey` | — | The screen this button opens, `:`. A button with one is a [``](/docs/ui/components/Link) | | `replace` | `boolean` | `false` | With `to`: take the place of the screen this button is on rather than stacking over it | | `back` | `boolean` | `false` | The way back, in place of `to` — the player's own stack decides where | | `enabled` | `boolean` | `true` | `false` draws the disabled texture, ignores the press, and applies the disabled text color to string children | @@ -40,12 +39,12 @@ Inherits [control props](/docs/ui/components/control-props). ## A form's two actions -Inside a [``](/docs/ui/components/roots/Form) a button is the form's own control rather than a handler: `action={'submit'}` submits and `action={'exit'}` dismisses. Exactly one submit is required, at most one exit beside it. +Inside a [``](/docs/ui/components/Form) the form's own two controls are `Form.Button`s rather than handlers: `type={'submit'}` submits and `type={'exit'}` dismisses. Exactly one submit is required, at most one exit beside it. ```tsx - - + {'Save'} + {'Cancel'} ``` @@ -53,7 +52,7 @@ Keep the default variants — primary for the submit, secondary for the exit — ## A press or a destination -`action` as a handler is script: only this realm can run it. `to` and `back` are **data** the build reads off the element, which is what lets a screen of buttons be [described to another addon](/docs/ui/guides/navigation#static-screens) and shown by a realm running none of your script. +`onPress` is script: only this realm can run it. `to` and `back` are **data** the build reads off the element, which is what lets a screen of buttons be [described to another addon](/docs/ui/guides/navigation#static-screens) and shown by a realm running none of your script. Reach for `to` whenever the press simply opens a screen, and keep a handler for the presses that do something. @@ -68,13 +67,13 @@ Reach for `to` whenever the press simply opens a screen, and keep a handler for ```tsx - - - - - - - + + + + + + + ``` @@ -89,7 +88,7 @@ Reach for `to` whenever the press simply opens a screen, and keep a handler for ### Custom children ```tsx - ``` diff --git a/docs/ore-styled/Card.md b/docs/ore-styled/Card.md index 448e3ec..e625d04 100644 --- a/docs/ore-styled/Card.md +++ b/docs/ore-styled/Card.md @@ -1,10 +1,9 @@ --- -sidebar_position: 3 description: "Themed container that wraps the Panel primitive with a Minecraft card background, standard padding, and gap." --- # Card -Themed container that wraps the [`Panel`](/docs/ui/components/layout/Panel) primitive with a Minecraft card background, standard padding, and gap. Use it to group related content into a single visual unit. Six visual variants cover the flat and raised surfaces in default, light, and dark tones. +Themed container that wraps the [`Panel`](/docs/ui/components/Panel) primitive with a Minecraft card background, standard padding, and gap. Use it to group related content into a single visual unit. Six visual variants cover the flat and raised surfaces in default, light, and dark tones. ![Card](/img/ore-styled/Card.png) @@ -80,8 +79,8 @@ Inherits [control props](/docs/ui/components/control-props). Use them to size th {'§lConfirm purchase'} {'Spend 32 emeralds?'} - - + + ``` diff --git a/docs/ore-styled/Checkbox.md b/docs/ore-styled/Checkbox.md index 349c94c..d447597 100644 --- a/docs/ore-styled/Checkbox.md +++ b/docs/ore-styled/Checkbox.md @@ -1,5 +1,4 @@ --- -sidebar_position: 8 description: "A themed boolean that draws as a native field on a modal and a press everywhere else." --- # Checkbox @@ -26,9 +25,9 @@ import { Checkbox } from '@bedrock-core/ore-styled'; | Screen | What it becomes | What reaches script | | --- | --- | --- | -| [``](/docs/ui/components/roots/Form) | a native [`Toggle`](/docs/ui/components/controls/Toggle) the engine owns | nothing until submit — the value arrives at `values[name]` | -| [``](/docs/ui/components/roots/Screen) | a press that holds its own state | `onChange`, on every press | -| [``](/docs/ui/components/roots/Container) | an item taken and put straight back | `onChange`, on every press | +| [``](/docs/ui/components/Form) | a native [`Toggle`](/docs/ui/components/Toggle) the engine owns | nothing until submit — the value arrives at `values[name]` | +| [``](/docs/ui/components/Screen) | a press that holds its own state | `onChange`, on every press | +| [``](/docs/ui/components/Container) | an item taken and put straight back | `onChange`, on every press | So `name` is the modal's prop and required there — a native field with no name has nothing to report under — while `on` and `onChange` only do anything where a press reaches script. You can write all of them and move the control between screens; each host uses the ones it can. @@ -52,7 +51,7 @@ The theme's textures are defaults, not a lock: `background`, `backgroundHover`, ```tsx apply(values.notify === true)}> - + {'Save'} ``` diff --git a/docs/ore-styled/Divider.md b/docs/ore-styled/Divider.md index df21e4b..bd2fcba 100644 --- a/docs/ore-styled/Divider.md +++ b/docs/ore-styled/Divider.md @@ -1,5 +1,4 @@ --- -sidebar_position: 4 description: "Thin horizontal or vertical separator." --- # Divider diff --git a/docs/ore-styled/Dropdown.md b/docs/ore-styled/Dropdown.md index f1f6cd1..a0fe163 100644 --- a/docs/ore-styled/Dropdown.md +++ b/docs/ore-styled/Dropdown.md @@ -1,5 +1,4 @@ --- -sidebar_position: 13 description: "A themed dropdown for a modal form, with the options given as a string array." --- # Dropdown @@ -16,7 +15,7 @@ import { Dropdown } from '@bedrock-core/ore-styled'; ## Usage -Render it inside a [`