UNPKG

@ryanhelsing/ry-ui

Version:

Framework-agnostic, Light DOM web components. CSS is the source of truth.

243 lines (183 loc) 5.34 kB
# Layout Components CSS-only layout primitives. No JavaScript needed. ## `<ry-page>` Top-level page shell. Contains header, main, footer. ```html <ry-page> <ry-header sticky>...</ry-header> <ry-main>...</ry-main> <ry-footer>...</ry-footer> </ry-page> ``` ## `<ry-header>` | Attribute | Values | Description | |-----------|--------|-------------| | `sticky` | boolean | Sticks to top of viewport | Horizontal flex with space-between. Two direct children = left and right. ```html <ry-header sticky> <ry-cluster><strong>App</strong></ry-cluster> <ry-cluster><ry-theme-toggle themes="light,dark"></ry-theme-toggle></ry-cluster> </ry-header> ``` ## `<ry-grid>` | Attribute | Values | Description | |-----------|--------|-------------| | `cols` | 1–6 | Number of columns | ```html <ry-grid cols="3"> <ry-card>One</ry-card> <ry-card>Two</ry-card> <ry-card>Three</ry-card> </ry-grid> ``` ## `<ry-stack>` Vertical flex layout. | Attribute | Values | Description | |-----------|--------|-------------| | `gap` | sm \| md \| lg | Vertical spacing | ```html <ry-stack gap="sm"> <p>Item 1</p> <p>Item 2</p> </ry-stack> ``` ## `<ry-cluster>` Horizontal flex, wraps. | Attribute | Values | Description | |-----------|--------|-------------| | `gap` | sm \| md \| lg | Horizontal spacing | ```html <ry-cluster> <ry-badge>A</ry-badge> <ry-badge>B</ry-badge> </ry-cluster> ``` ## `<ry-card>` Content container with padding and border. All cards lift subtly on hover. Add `interactive` for clickable cards. | Attribute | Values | Description | |-----------|--------|-------------| | `interactive` | boolean | Clickable card — cursor pointer, stronger hover lift, primary border, keyboard support | | `href` | URL | Navigate on click (requires `interactive`) | Events: `ry:click` (interactive cards only) ```html <!-- Static card --> <ry-card> <h3>Title</h3> <p>Content.</p> <ry-actions> <ry-button>Save</ry-button> <ry-button variant="ghost">Cancel</ry-button> </ry-actions> </ry-card> <!-- Interactive card with navigation --> <ry-card interactive href="/demos/goap"> <h3>GOAP</h3> <p>Goal-Oriented Action Planning</p> </ry-card> <!-- Interactive card with event --> <ry-card interactive> <h3>Click Me</h3> <p>Emits ry:click. Tab + Enter for keyboard.</p> </ry-card> ``` Hover behavior: - **All cards**: subtle lift (-2px) + border/shadow bump - **Interactive**: stronger lift (-3px), primary-colored border, snaps back on click - Clicks on child `<a>`, `<button>`, `<ry-button>` elements pass through normally ## `<ry-section>` Content section block. Adds bottom margin between sections, removed on last child. ```html <ry-main> <ry-section><h2>Section 1</h2><p>Content.</p></ry-section> <ry-section><h2>Section 2</h2><p>Content.</p></ry-section> </ry-main> ``` ## `<ry-aside>` Sidebar / secondary content block. ```html <ry-split> <ry-main>Primary content</ry-main> <ry-aside>Sidebar content</ry-aside> </ry-split> ``` ## `<ry-split>` Two-pane layout: content (flexible) + sidebar (fixed). Stacks vertically on mobile (<768px). | Attribute | Values | Description | |-----------|--------|-------------| | `resizable` | boolean | Enables drag handle between panes | | `persist` | string | localStorage key — saves/restores width as `ry-split:{key}` | CSS custom properties: | Property | Default | Description | |----------|---------|-------------| | `--ry-split-width` | `300px` | Sidebar width | | `--ry-split-min-width` | `100px` | Minimum width during resize | | `--ry-split-max-width` | `80%` | Maximum width during resize | Events: `ry:resize` — `e.detail.width` ```html <!-- Basic --> <ry-split> <div>Main content (flex: 1)</div> <div>Sidebar (300px)</div> </ry-split> <!-- Resizable with persistence --> <ry-split resizable persist="sidebar" style="--ry-split-width: 400px"> <main>Content</main> <aside>Resizable sidebar</aside> </ry-split> ``` Resize interaction: - **Drag** handle between panes (mouse + touch) - **Arrow keys** ±10px, **Shift+Arrow** ±50px - **Home/End** jump to min/max - **Double-click** handle to reset to default ## `<ry-center>` Centers content both horizontally and vertically. ```html <ry-center> <h1>Centered title</h1> <p>Centered paragraph</p> </ry-center> ``` ## `<ry-nav>` Horizontal navigation links. Use `aria-current="page"` to highlight the active link. ```html <ry-nav> <a href="/" aria-current="page">Home</a> <a href="/about">About</a> <a href="/contact">Contact</a> </ry-nav> ``` ## `<ry-logo>` Inline logo element. Bold, large text. Typically used inside `<ry-header>`. ```html <ry-header> <ry-logo>My App</ry-logo> <ry-nav>...</ry-nav> </ry-header> ``` ## `<ry-actions>` Horizontal button group. Use inside cards, modals, or any container. ```html <ry-actions> <ry-button>Primary</ry-button> <ry-button variant="ghost">Cancel</ry-button> </ry-actions> ``` ## `<ry-divider>` Horizontal or vertical separator line. | Attribute | Values | Description | |-----------|--------|-------------| | `vertical` | boolean | Vertical orientation (for use inside flex rows) | ```html <ry-stack> <p>Above</p> <ry-divider></ry-divider> <p>Below</p> </ry-stack> <ry-cluster> <span>Left</span> <ry-divider vertical></ry-divider> <span>Right</span> </ry-cluster> ```