first commit
This commit is contained in:
@@ -0,0 +1,16 @@
|
||||
// Callout box. variant: info | success | danger | warning.
|
||||
// Optional `title`; body from `message` prop or the slot.
|
||||
component Alert {
|
||||
props {
|
||||
variant = "info"
|
||||
title = ""
|
||||
message = ""
|
||||
class = ""
|
||||
}
|
||||
view {
|
||||
<div class="wire-alert wire-alert--{variant} {class}" role="alert">
|
||||
<div class="wire-alert__title">{title}</div>
|
||||
<div class="wire-alert__body"><slot>{message}</slot></div>
|
||||
</div>
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
// Rounded user image.
|
||||
component Avatar {
|
||||
props {
|
||||
src = ""
|
||||
alt = ""
|
||||
class = ""
|
||||
}
|
||||
view {
|
||||
<img class="wire-avatar {class}" src="{src}" alt="{alt}">
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
// Small status label. variant: default | primary | success | danger | warning.
|
||||
component Badge {
|
||||
props {
|
||||
label = ""
|
||||
variant = "default"
|
||||
class = ""
|
||||
}
|
||||
view {
|
||||
<span class="wire-badge wire-badge--{variant} {class}"><slot>{label}</slot></span>
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
// Button. variant: default | primary | danger | ghost — size: sm | md | lg.
|
||||
// Use the `label` prop, or put custom content in the slot.
|
||||
component Button {
|
||||
props {
|
||||
label = "Button"
|
||||
variant = "default"
|
||||
size = "md"
|
||||
type = "button"
|
||||
class = ""
|
||||
}
|
||||
view {
|
||||
<button type="{type}" class="wire-btn wire-btn--{variant} wire-btn--{size} {class}"><slot>{label}</slot></button>
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
// Surface container with padding, border, and rounded corners.
|
||||
component Card {
|
||||
props {
|
||||
class = ""
|
||||
}
|
||||
view {
|
||||
<div class="wire-card {class}"><slot></slot></div>
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
// Checkbox with an inline label.
|
||||
component Checkbox {
|
||||
props {
|
||||
name = ""
|
||||
label = ""
|
||||
class = ""
|
||||
}
|
||||
view {
|
||||
<label class="wire-check {class}">
|
||||
<input type="checkbox" name="{name}" class="wire-check__box">
|
||||
<span class="wire-check__label"><slot>{label}</slot></span>
|
||||
</label>
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
// Centered, max-width page container. Children go in the <slot>.
|
||||
component Container {
|
||||
props {
|
||||
class = ""
|
||||
}
|
||||
view {
|
||||
<div class="wire-container {class}"><slot></slot></div>
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
// Expand/collapse section using native <details> (no JS).
|
||||
component Disclosure {
|
||||
props {
|
||||
summary = "Details"
|
||||
class = ""
|
||||
}
|
||||
view {
|
||||
<details class="wire-disclosure {class}">
|
||||
<summary class="wire-disclosure__summary">{summary}</summary>
|
||||
<div class="wire-disclosure__body"><slot></slot></div>
|
||||
</details>
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
// Horizontal rule using theme border color.
|
||||
component Divider {
|
||||
props {
|
||||
class = ""
|
||||
}
|
||||
view {
|
||||
<hr class="wire-divider {class}">
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
// Drag-and-drop file uploader with per-file progress. Progressive enhancement:
|
||||
// the markup is inert until /__wrnexus/uploader.js loads (auto-injected when a
|
||||
// page contains `data-uploader`). Pairs with `handleUpload` on the server —
|
||||
// files POST to `endpoint`, which returns `{ ok, files:[{ key, url, … }] }`.
|
||||
//
|
||||
// <div data-component="file-upload" store="public" endpoint="/api/upload"
|
||||
// accept="image/*" max="10000000" multiple="true"></div>
|
||||
component FileUpload {
|
||||
props {
|
||||
store = "public"
|
||||
endpoint = "/api/upload"
|
||||
accept = ""
|
||||
multiple = false
|
||||
max = 0
|
||||
label = "Drag files here or click to browse"
|
||||
class = ""
|
||||
}
|
||||
view {
|
||||
<div class="wire-fileupload {class}" data-uploader="{store}" data-endpoint="{endpoint}" data-accept="{accept}" data-multiple="{multiple}" data-max="{max}" data-label="{label}"></div>
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
// Responsive-ish grid: `cols` columns (1–6) with a gap (scale 0–8).
|
||||
component Grid {
|
||||
props {
|
||||
cols = "2"
|
||||
gap = "4"
|
||||
class = ""
|
||||
}
|
||||
view {
|
||||
<div class="wire-grid wire-cols-{cols} wire-gap-{gap} {class}"><slot></slot></div>
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
// Horizontal stack: row layout with a gap and cross-axis alignment.
|
||||
// align: start | center | end | stretch
|
||||
component HStack {
|
||||
props {
|
||||
gap = "4"
|
||||
align = "center"
|
||||
class = ""
|
||||
}
|
||||
view {
|
||||
<div class="wire-hstack wire-gap-{gap} wire-items-{align} {class}"><slot></slot></div>
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
// Text input. Pairs with the validation system (name maps to a field).
|
||||
component Input {
|
||||
props {
|
||||
type = "text"
|
||||
name = ""
|
||||
value = ""
|
||||
placeholder = ""
|
||||
class = ""
|
||||
}
|
||||
view {
|
||||
<input type="{type}" name="{name}" value="{value}" placeholder="{placeholder}" class="wire-input {class}">
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
// Progress bar (native <progress>, themed).
|
||||
component Progress {
|
||||
props {
|
||||
value = 0
|
||||
max = 100
|
||||
class = ""
|
||||
}
|
||||
view {
|
||||
<progress class="wire-progress {class}" value="{value}" max="{max}"></progress>
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
// Radio input with an inline label.
|
||||
component Radio {
|
||||
props {
|
||||
name = ""
|
||||
value = ""
|
||||
label = ""
|
||||
class = ""
|
||||
}
|
||||
view {
|
||||
<label class="wire-check {class}">
|
||||
<input type="radio" name="{name}" value="{value}" class="wire-check__box">
|
||||
<span class="wire-check__label"><slot>{label}</slot></span>
|
||||
</label>
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
// Styled native select. Put <option>s in the slot.
|
||||
component Select {
|
||||
props {
|
||||
name = ""
|
||||
class = ""
|
||||
}
|
||||
view {
|
||||
<select name="{name}" class="wire-input wire-select {class}"><slot></slot></select>
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
// Loading placeholder (animated shimmer). Size it with width/height props.
|
||||
component Skeleton {
|
||||
props {
|
||||
width = "100%"
|
||||
height = "1rem"
|
||||
class = ""
|
||||
}
|
||||
view {
|
||||
<span class="wire-skeleton {class}" style="width: {width}; height: {height};" aria-hidden="true"></span>
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
// Flexible spacer: grows to push siblings apart inside a flex row/column.
|
||||
component Spacer {
|
||||
props {
|
||||
class = ""
|
||||
}
|
||||
view {
|
||||
<div class="wire-spacer {class}"></div>
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
// Loading spinner (pure CSS animation, no JS).
|
||||
component Spinner {
|
||||
props {
|
||||
class = ""
|
||||
}
|
||||
view {
|
||||
<span class="wire-spinner {class}" role="status" aria-label="Loading"></span>
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
// Vertical stack: lays children out in a column with a gap (scale 0–8).
|
||||
component Stack {
|
||||
props {
|
||||
gap = "4"
|
||||
class = ""
|
||||
}
|
||||
view {
|
||||
<div class="wire-stack wire-gap-{gap} {class}"><slot></slot></div>
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
// Toggle switch (an accessible checkbox styled as a switch).
|
||||
component Switch {
|
||||
props {
|
||||
name = ""
|
||||
label = ""
|
||||
class = ""
|
||||
}
|
||||
view {
|
||||
<label class="wire-switch {class}">
|
||||
<input type="checkbox" name="{name}" class="wire-switch__input" role="switch">
|
||||
<span class="wire-switch__track"><span class="wire-switch__thumb"></span></span>
|
||||
<span class="wire-switch__label"><slot>{label}</slot></span>
|
||||
</label>
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
// Themed table wrapper — put a <table>…</table> (or thead/tbody) in the slot.
|
||||
// Scrolls horizontally on small screens.
|
||||
component Table {
|
||||
props {
|
||||
class = ""
|
||||
}
|
||||
view {
|
||||
<div class="wire-table-wrap {class}">
|
||||
<table class="wire-table"><slot></slot></table>
|
||||
</div>
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
// Small tag / chip. variant: default | primary | success | danger | warning.
|
||||
component Tag {
|
||||
props {
|
||||
label = ""
|
||||
variant = "default"
|
||||
class = ""
|
||||
}
|
||||
view {
|
||||
<span class="wire-tag wire-tag--{variant} {class}"><slot>{label}</slot></span>
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
// Multi-line text input.
|
||||
component Textarea {
|
||||
props {
|
||||
name = ""
|
||||
placeholder = ""
|
||||
rows = "4"
|
||||
class = ""
|
||||
}
|
||||
view {
|
||||
<textarea name="{name}" placeholder="{placeholder}" rows="{rows}" class="wire-input wire-textarea {class}"><slot></slot></textarea>
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
// Theme switch button. The framework's theme runtime binds the click
|
||||
// (data-wire-theme-toggle), so no component JS is needed.
|
||||
component ThemeToggle {
|
||||
props {
|
||||
label = "Toggle theme"
|
||||
class = ""
|
||||
}
|
||||
view {
|
||||
<button type="button" class="wire-btn wire-btn--ghost {class}" data-wire-theme-toggle><slot>{label}</slot></button>
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
// CSS-only tooltip shown on hover/focus. Wrap the trigger content in the slot.
|
||||
component Tooltip {
|
||||
props {
|
||||
text = ""
|
||||
class = ""
|
||||
}
|
||||
view {
|
||||
<span class="wire-tooltip {class}" data-tooltip="{text}" tabindex="0"><slot></slot></span>
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user