@21stware/rpui 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +113 -0
- package/dist/canvas/annotation.d.ts +10 -0
- package/dist/canvas/main-view.d.ts +9 -0
- package/dist/canvas/page.d.ts +3 -0
- package/dist/core/dom.d.ts +12 -0
- package/dist/core/icons.d.ts +2 -0
- package/dist/core/style.d.ts +3 -0
- package/dist/primitives/controls.d.ts +40 -0
- package/dist/primitives/data-display.d.ts +40 -0
- package/dist/primitives/layout.d.ts +21 -0
- package/dist/primitives/navigation.d.ts +27 -0
- package/dist/registry.d.ts +1 -0
- package/dist/rpui.d.ts +2 -0
- package/dist/rpui.js +982 -0
- package/dist/rpui.js.map +1 -0
- package/llms.txt +195 -0
- package/package.json +46 -0
- package/skill.txt +143 -0
package/dist/rpui.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rpui.js","sources":["../src/core/dom.ts","../src/core/style.ts","../src/canvas/annotation.ts","../src/canvas/main-view.ts","../src/canvas/page.ts","../src/primitives/layout.ts","../src/core/icons.ts","../src/primitives/controls.ts","../src/primitives/navigation.ts","../src/primitives/data-display.ts","../src/registry.ts","../src/rpui.ts"],"sourcesContent":["export function attr(el: Element, name: string, fallback = ''): string { return el.getAttribute(name) ?? fallback; }\nexport function intAttr(el: Element, name: string, fallback: number): number { const raw = el.getAttribute(name); const value = raw === null || raw === '' ? NaN : Number(raw); return Number.isFinite(value) ? value : fallback; }\nexport function escapeHtml(value: string): string { return value.replace(/[&<>'\"]/g, c => ({ '&':'&', '<':'<', '>':'>', \"'\":''', '\"':'"' }[c] || c)); }\nexport function csv(el: Element, name: string, fallback: string): string[] { return attr(el, name, fallback).split(',').map(s => s.trim()).filter(Boolean); }\n\nexport const deviceWidths: Record<string, number> = { web: 1440, ipad: 834, mobile: 390 };\nexport function resolveWidth(el: Element, fallback: number): number { const raw = el.getAttribute('width'); const width = raw === null || raw === '' ? NaN : Number(raw); if (Number.isFinite(width)) return width; return deviceWidths[attr(el,'device')] ?? fallback; }\nexport function hasExplicitNumericHeight(el: Element): boolean { const raw = el.getAttribute('height'); return raw !== null && raw !== '' && Number.isFinite(Number(raw)); }\nexport function usesAutoHeight(el: Element): boolean { const raw = el.getAttribute('height'); return raw === 'auto' || el.hasAttribute('auto-height') || (!!el.getAttribute('device') && !hasExplicitNumericHeight(el)); }\nexport function resolveHeight(el: Element, fallback: number): number { const raw = el.getAttribute('height'); const height = raw === null || raw === '' ? NaN : Number(raw); return Number.isFinite(height) ? height : fallback; }\nexport function isTopAnnotation(node: Node): node is HTMLElement { if (!(node instanceof HTMLElement)) return false; const tag = node.tagName.toLowerCase(); return tag === 'rp-annotation' || tag === 'proto-annotation'; }\nexport function isViewportNode(node: Node): node is HTMLElement { if (!(node instanceof HTMLElement)) return false; const tag = node.tagName.toLowerCase(); return tag === 'rp-viewport' || tag === 'snap-viewport'; }\nexport function define(name: string, ctor: CustomElementConstructor) {\n if (customElements.get(name)) return;\n const Alias = class extends (ctor as { new(): HTMLElement }) {};\n customElements.define(name, Alias as CustomElementConstructor);\n}\n\n\n","export const RPUI_STYLE_ID = \"rpui-runtime-style\";\n\nexport const style = `\n:root { --rp-bg:#f0f2f5; --rp-surface:#fff; --rp-surface-soft:#f9fafb; --rp-text:#111827; --rp-muted:#6b7280; --rp-border:#e5e7eb; --rp-border-strong:#d1d5db; --rp-primary:#2563eb; --rp-success:#059669; --rp-warning:#d97706; --rp-danger:#dc2626; --rp-purple:#7c3aed; --rp-radius-sm:4px; --rp-radius-md:8px; --rp-radius-lg:12px; --rp-shadow:0 8px 28px rgba(15,23,42,.08); --rp-font:-apple-system,BlinkMacSystemFont,\"Segoe UI\",sans-serif; }\n* { box-sizing:border-box; }\nbody { margin:0; font-family:var(--rp-font); color:var(--rp-text); background:var(--rp-bg); }\n.rp-icon { display:inline-block; flex:0 0 auto; vertical-align:-0.16em; }\nrp-page, proto-page { display:block; min-height:100vh; padding:32px 40px; overflow:auto; }\n.rp-page-shell { display:grid; grid-template-columns:max-content max-content; gap:24px; min-height:100vh; align-items:start; }\n.rp-page-main { display:flex; flex-direction:column; min-width:0; overflow:visible; }\n.rp-page-header { flex:0 0 auto; width:fit-content; max-width:none; margin:0 0 22px; }\n.rp-page-title-row { display:flex; align-items:baseline; gap:12px; flex-wrap:wrap; }\n.rp-page-title { margin:0; font-size:28px; line-height:1.2; letter-spacing:-.02em; }\n.rp-page-route { font-size:13px; color:var(--rp-muted); font-family:ui-monospace,SFMono-Regular,Menlo,monospace; background:rgba(255,255,255,.7); border:1px solid var(--rp-border); border-radius:999px; padding:3px 9px; }\n.rp-page-description { margin:10px 0 0; color:#374151; line-height:1.6; font-size:14px; }\n.rp-page-body { flex:0 1 auto; display:block; width:fit-content; max-width:100%; min-height:0; overflow:visible; }\n.rp-annotation-pane { min-width:380px; max-width:680px; position:sticky; top:0; height:100vh; overflow-y:auto; overflow-x:auto; padding:0 0 48px 0; align-self:start; }\n.rp-annotation-pane-inner { padding:4px 12px 24px 6px; }\nrp-main-view, proto-main-view { display:block; width:fit-content; margin:0 0 28px; position:relative; }\n.rp-main-shell { position:relative; overflow:visible; border:1px solid var(--rp-border-strong); border-radius:var(--rp-radius-md); background:var(--rp-surface); box-shadow:var(--rp-shadow); }\n.rp-main-stage-clip { overflow:hidden; border-radius:var(--rp-radius-md); }\n.rp-main-stage { position:relative; transform-origin:top left; background:var(--rp-surface); }\n.rp-pin { position:absolute; z-index:20; display:grid; place-items:center; width:24px; height:24px; color:#fff; font-size:11px; font-weight:700; background:var(--rp-primary); border-radius:50% 50% 50% 0; transform:translate(-6px,-6px) rotate(-45deg); box-shadow:0 2px 8px rgba(37,99,235,.25); cursor:pointer; }\n.rp-pin > span { transform:rotate(45deg); }\n.rp-pin:hover { opacity:0.85; }\nrp-annotation, proto-annotation { display:block; width:fit-content; max-width:980px; margin:14px 0; line-height:1.65; color:#1f2937; font-size:14px; }\nrp-annotation rp-annotation, proto-annotation proto-annotation, rp-annotation proto-annotation, proto-annotation rp-annotation { margin:10px 0 8px 22px; }\n.rp-annotation-head { display:flex; align-items:center; gap:8px; margin:0 0 4px; width:fit-content; }\n.rp-annotation-title { font-weight:700; color:#111827; }\n.rp-annotation-marker { display:inline-grid; place-items:center; flex:0 0 auto; color:#fff; font-size:10px; font-weight:700; line-height:1; }\n.rp-annotation-marker.drop { width:22px; height:22px; background:var(--rp-primary); border-radius:50% 50% 50% 0; transform:rotate(-45deg); }\n.rp-annotation-marker.drop > span { transform:rotate(45deg); }\n.rp-annotation-marker.circle { width:13px; height:13px; background:var(--rp-purple); border-radius:50%; }\n.rp-annotation-marker.triangle { width:0; height:0; border-left:7px solid transparent; border-right:7px solid transparent; border-bottom:13px solid var(--rp-success); }\n.rp-annotation-body { display:block; width:fit-content; max-width:920px; }\n.rp-annotation-body > :not(rp-annotation):not(proto-annotation):not(rp-enum):not(proto-enum) { max-width:820px; }\n.rp-annotation-pane rp-annotation, .rp-annotation-pane proto-annotation { max-width:none; }\n.rp-annotation-pane .rp-annotation-body { max-width:none; }\n.rp-annotation-pane .rp-annotation-body > :not(rp-annotation):not(proto-annotation):not(rp-enum):not(proto-enum) { max-width:420px; }\n.rp-annotation-body p { margin:0 0 8px; }\nrp-enum, proto-enum { display:flex; align-items:flex-start; flex-wrap:wrap; gap:10px; width:fit-content; margin:8px 0 12px; }\n.rp-annotation-pane rp-enum, .rp-annotation-pane proto-enum { flex-wrap:wrap; }\nrp-enum-item, proto-enum-item { display:block; flex:0 0 auto; width:fit-content; min-width:180px; max-width:600px; border:1px solid #f0f0f0; border-radius:var(--rp-radius-md); background:#fff; overflow:hidden; }\n.rp-enum-label { display:flex; align-items:flex-start; gap:6px; padding:5px 9px 4px; font-size:12px; font-weight:650; color:#374151; }\n.rp-enum-index { display:inline-grid; place-items:center; min-width:16px; height:16px; padding:0 4px; background:#111827; color:#fff; font-size:10px; font-weight:750; border-radius:3px; flex:0 0 auto; margin-top:1px; }\n.rp-enum-label-text { display:block; }\n.rp-enum-description { display:block; margin-top:2px; font-size:11px; line-height:1.35; font-weight:400; color:var(--rp-muted); }\n.rp-enum-content { display:block; width:fit-content; padding:8px; }\n.rp-annotation-title { font-weight:700; color:#111827; cursor:pointer; }\n.rp-annotation-title:hover { color:var(--rp-primary); }\n.rp-section-focus { outline:2px dashed var(--rp-primary); outline-offset:4px; border-radius:4px; }\nsnap-viewport, rp-viewport { display:flex; flex-direction:column; width:var(--snap-width,1440px); height:var(--snap-height,900px); background:#f8fafc; overflow:hidden; color:#111827; }\nsnap-layout, rp-layout { display:grid; grid-template-columns:var(--snap-columns,1fr); grid-template-rows:var(--snap-rows,auto); gap:var(--snap-gap,0); align-content:start; width:fit-content; max-width:100%; min-width:0; }\nsnap-layout > *, rp-layout > * { min-width:0; }\nsnap-viewport snap-layout, rp-viewport rp-layout { width:100%; }\nsnap-viewport > snap-layout, rp-viewport > rp-layout { flex:1 1 auto; min-height:0; }\nsnap-viewport > snap-navbar, rp-viewport > rp-navbar { flex:0 0 auto; }\nsnap-panel, rp-panel { display:block; width:fit-content; max-width:100%; background:#fff; border:1px solid var(--rp-border); border-radius:var(--rp-radius-md); padding:var(--snap-padding,16px); }\nsnap-viewport snap-panel, rp-viewport rp-panel { width:auto; min-width:0; }\nsnap-panel[elevation=\"1\"], rp-panel[elevation=\"1\"] { box-shadow:0 4px 16px rgba(15,23,42,.06); }\nsnap-panel[elevation=\"2\"], rp-panel[elevation=\"2\"] { box-shadow:var(--rp-shadow); }\nsnap-navbar, rp-navbar { display:flex; align-items:center; gap:14px; height:var(--snap-height,64px); padding:0 24px; background:#fff; border-bottom:1px solid var(--rp-border); }\nsnap-sidebar, rp-sidebar { display:block; width:var(--snap-width,260px); min-height:0; background:#fff; border-right:1px solid var(--rp-border); padding:14px; }\nsnap-viewport snap-sidebar, rp-viewport rp-sidebar { min-height:100%; }\nsnap-sidebar[collapsed], rp-sidebar[collapsed] { width:72px; }\nsnap-logo, rp-logo { display:inline-grid; place-items:center; width:var(--snap-size,82px); height:32px; border-radius:8px; background:#111827; color:#fff; font-size:12px; font-weight:800; letter-spacing:.08em; }\nsnap-search, rp-search, snap-input, rp-input, snap-date-picker, rp-date-picker { display:inline-flex; align-items:center; gap:8px; width:280px; min-height:36px; padding:0 11px; border:1px solid var(--rp-border-strong); border-radius:8px; background:#fff; color:#111827; }\nsnap-textarea, rp-textarea { display:block; width:320px; min-height:calc(var(--snap-rows,3) * 24px + 22px); padding:9px 11px; border:1px solid var(--rp-border-strong); border-radius:8px; background:#fff; color:#111827; white-space:pre-wrap; }\nsnap-search[state=\"focus\"], rp-search[state=\"focus\"], snap-input[state=\"focus\"], rp-input[state=\"focus\"], snap-textarea[state=\"focus\"], rp-textarea[state=\"focus\"], snap-date-picker[state=\"focus\"], rp-date-picker[state=\"focus\"] { border-color:var(--rp-primary); box-shadow:0 0 0 3px rgba(37,99,235,.12); }\nsnap-search[state=\"filled\"], rp-search[state=\"filled\"], snap-input[state=\"filled\"], rp-input[state=\"filled\"], snap-textarea[state=\"filled\"], rp-textarea[state=\"filled\"], snap-date-picker[state=\"filled\"], rp-date-picker[state=\"filled\"] { border-color:#93c5fd; background:#f8fbff; }\nsnap-search[state=\"error\"], rp-search[state=\"error\"], snap-input[state=\"error\"], rp-input[state=\"error\"], snap-textarea[state=\"error\"], rp-textarea[state=\"error\"], snap-date-picker[state=\"error\"], rp-date-picker[state=\"error\"] { border-color:var(--rp-danger); box-shadow:0 0 0 3px rgba(220,38,38,.1); }\nsnap-search[state=\"disabled\"], rp-search[state=\"disabled\"], snap-input[state=\"disabled\"], rp-input[state=\"disabled\"], snap-textarea[state=\"disabled\"], rp-textarea[state=\"disabled\"], snap-date-picker[state=\"disabled\"], rp-date-picker[state=\"disabled\"] { opacity:.55; background:#f3f4f6; }\nsnap-input[label], rp-input[label], snap-date-picker[label], rp-date-picker[label] { display:inline-grid; align-items:start; gap:6px; width:280px; min-height:0; padding:0; border:0; background:transparent; box-shadow:none; }\nsnap-input[label][state=\"focus\"], rp-input[label][state=\"focus\"], snap-input[label][state=\"filled\"], rp-input[label][state=\"filled\"], snap-input[label][state=\"error\"], rp-input[label][state=\"error\"], snap-date-picker[label][state=\"focus\"], rp-date-picker[label][state=\"focus\"], snap-date-picker[label][state=\"filled\"], rp-date-picker[label][state=\"filled\"], snap-date-picker[label][state=\"error\"], rp-date-picker[label][state=\"error\"] { border:0; background:transparent; box-shadow:none; }\n.rp-field-control { display:flex; align-items:center; gap:8px; min-height:36px; padding:0 11px; border:1px solid var(--rp-border-strong); border-radius:8px; background:#fff; color:#111827; }\nsnap-input[state=\"focus\"] .rp-field-control, rp-input[state=\"focus\"] .rp-field-control, snap-date-picker[state=\"focus\"] .rp-field-control, rp-date-picker[state=\"focus\"] .rp-field-control { border-color:var(--rp-primary); box-shadow:0 0 0 3px rgba(37,99,235,.12); }\nsnap-input[state=\"filled\"] .rp-field-control, rp-input[state=\"filled\"] .rp-field-control, snap-date-picker[state=\"filled\"] .rp-field-control, rp-date-picker[state=\"filled\"] .rp-field-control { border-color:#93c5fd; background:#f8fbff; }\nsnap-input[state=\"error\"] .rp-field-control, rp-input[state=\"error\"] .rp-field-control, snap-date-picker[state=\"error\"] .rp-field-control, rp-date-picker[state=\"error\"] .rp-field-control { border-color:var(--rp-danger); box-shadow:0 0 0 3px rgba(220,38,38,.1); }\n.rp-field-label { display:block; margin:0 0 6px; color:#374151; font-size:12px; font-weight:650; }\n.rp-placeholder { color:#9ca3af; }\n.rp-value { color:#111827; }\n.rp-error-text { color:var(--rp-danger); font-size:12px; }\nsnap-select, rp-select { display:inline-block; width:var(--snap-width,280px); }\n.rp-select-control { display:flex; align-items:center; gap:8px; min-height:36px; padding:0 11px; border:1px solid var(--rp-border-strong); border-radius:8px; background:#fff; }\nsnap-select[state=\"expanded\"] .rp-select-control, rp-select[state=\"expanded\"] .rp-select-control { border-color:var(--rp-primary); box-shadow:0 0 0 3px rgba(37,99,235,.12); }\nsnap-select[state=\"disabled\"], rp-select[state=\"disabled\"] { opacity:.55; }\n.rp-select-value { flex:1 1 auto; min-width:0; }\n.rp-select-options { display:none; margin-top:6px; padding:5px; border:1px solid var(--rp-border); border-radius:8px; background:#fff; box-shadow:0 10px 18px rgba(15,23,42,.08); }\nsnap-select[state=\"expanded\"] .rp-select-options, rp-select[state=\"expanded\"] .rp-select-options { display:grid; gap:2px; }\n.rp-select-option { padding:7px 8px; border-radius:6px; font-size:13px; color:#374151; }\n.rp-select-option.selected { background:#eff6ff; color:#1d4ed8; font-weight:700; }\nsnap-badge, rp-badge { display:inline-grid; place-items:center; min-width:20px; height:20px; padding:0 6px; border-radius:999px; background:#ef4444; color:#fff; font-size:11px; font-weight:750; }\nsnap-avatar, rp-avatar { display:inline-grid; place-items:center; width:var(--snap-size,32px); height:var(--snap-size,32px); border-radius:999px; background:#e0e7ff; color:#3730a3; font-size:12px; font-weight:800; }\nsnap-list, rp-list { display:flex; flex-direction:column; gap:4px; width:100%; }\nsnap-list-item, rp-list-item { display:flex; align-items:center; gap:8px; width:100%; min-width:180px; height:36px; padding:0 10px; border-radius:8px; color:#374151; }\nsnap-list-item[state=\"selected\"], rp-list-item[state=\"selected\"] { background:#eff6ff; color:#1d4ed8; font-weight:700; }\nsnap-list-item[state=\"disabled\"], rp-list-item[state=\"disabled\"] { opacity:.5; }\n.rp-list-label { flex:1 1 auto; }\n.rp-list-badge { margin-left:auto; min-width:18px; height:18px; border-radius:999px; display:grid; place-items:center; padding:0 6px; background:#e5e7eb; color:#374151; font-size:11px; font-weight:700; }\nsnap-tabs, rp-tabs { display:flex; gap:6px; border-bottom:1px solid var(--rp-border); margin-bottom:12px; width:fit-content; }\nsnap-tab, rp-tab { display:inline-flex; align-items:center; gap:6px; padding:9px 13px; border-bottom:2px solid transparent; color:#6b7280; font-size:14px; }\nsnap-tab.rp-tab-active, rp-tab.rp-tab-active { color:var(--rp-primary); border-bottom-color:var(--rp-primary); font-weight:700; }\nsnap-button, rp-button { display:inline-flex; align-items:center; justify-content:center; gap:7px; min-height:34px; padding:0 12px; border-radius:8px; border:1px solid var(--rp-border); background:#fff; color:#374151; font-size:13px; font-weight:650; }\nsnap-button[size=\"sm\"], rp-button[size=\"sm\"] { min-height:28px; padding:0 9px; font-size:12px; border-radius:6px; }\nsnap-button[size=\"lg\"], rp-button[size=\"lg\"] { min-height:40px; padding:0 16px; font-size:14px; }\nsnap-button[variant=\"primary\"], rp-button[variant=\"primary\"] { border-color:var(--rp-primary); background:var(--rp-primary); color:#fff; }\nsnap-button[variant=\"secondary\"], rp-button[variant=\"secondary\"] { border-color:#bfdbfe; background:#eff6ff; color:#1d4ed8; }\nsnap-button[variant=\"danger\"], rp-button[variant=\"danger\"] { border-color:var(--rp-danger); color:var(--rp-danger); }\nsnap-button[variant=\"link\"], rp-button[variant=\"link\"] { border-color:transparent; background:transparent; color:var(--rp-primary); padding-inline:2px; }\nsnap-button[variant=\"ghost\"], rp-button[variant=\"ghost\"] { border-color:transparent; background:transparent; }\nsnap-button[state=\"disabled\"], rp-button[state=\"disabled\"], snap-button[disabled], rp-button[disabled] { opacity:.5; }\nsnap-button-group, rp-button-group { display:inline-flex; gap:0; width:fit-content; }\nsnap-button-group > snap-button, rp-button-group > rp-button { border-radius:0; margin-left:-1px; }\nsnap-button-group > :first-child { border-radius:8px 0 0 8px; margin-left:0; }\nsnap-button-group > :last-child { border-radius:0 8px 8px 0; }\nsnap-table, rp-table { display:table; border-collapse:collapse; width:fit-content; min-width:720px; max-width:980px; background:#fff; border:1px solid var(--rp-border); border-radius:8px; overflow:hidden; }\nsnap-viewport snap-table, rp-viewport rp-table { width:100%; max-width:none; }\n.rp-table-row { display:table-row; }\n.rp-table-cell { display:table-cell; padding:11px 12px; border-bottom:1px solid var(--rp-border); font-size:13px; vertical-align:middle; white-space:nowrap; }\n.rp-table-head .rp-table-cell { background:#f9fafb; color:#6b7280; font-size:12px; font-weight:750; }\n.rp-table-row:last-child .rp-table-cell { border-bottom:0; }\nsnap-table-row, rp-table-row { display:grid; grid-template-columns:44px 150px 240px 90px 90px; align-items:center; min-width:560px; border:1px solid var(--rp-border); border-radius:8px; overflow:hidden; background:#fff; }\nsnap-table-row > span, rp-table-row > span { padding:10px 12px; font-size:13px; }\nsnap-table-row[state=\"unread\"], rp-table-row[state=\"unread\"] { background:#eff6ff; font-weight:700; }\nsnap-table-row[state=\"selected\"], rp-table-row[state=\"selected\"] { outline:2px solid rgba(37,99,235,.35); background:#f8fbff; }\nsnap-table-row[state=\"highlighted\"], rp-table-row[state=\"highlighted\"] { background:#fffbeb; }\nsnap-table-row[state=\"disabled\"], rp-table-row[state=\"disabled\"] { opacity:.5; }\nsnap-bulk-action-bar, rp-bulk-action-bar { display:flex; align-items:center; gap:8px; width:fit-content; padding:8px 10px; margin:0 0 10px; border:1px solid #bfdbfe; background:#eff6ff; border-radius:8px; color:#1e40af; font-size:13px; font-weight:650; }\nsnap-empty, rp-empty { display:grid; justify-items:center; gap:8px; width:fit-content; min-width:240px; padding:24px; border:1px dashed var(--rp-border-strong); border-radius:10px; background:#fff; color:#6b7280; text-align:center; }\n.rp-empty-title { color:#111827; font-weight:700; }\n.rp-empty-desc { font-size:13px; }\nsnap-loading, rp-loading { display:grid; gap:8px; min-width:260px; color:var(--rp-primary); }\n.rp-skeleton-line { height:14px; border-radius:999px; background:linear-gradient(90deg,#f3f4f6,#e5e7eb,#f3f4f6); }\n.rp-spinner { display:inline-grid; place-items:center; width:32px; height:32px; }\nsnap-alert, rp-alert, snap-toast, rp-toast { display:flex; align-items:flex-start; gap:8px; width:fit-content; max-width:420px; padding:10px 12px; border:1px solid var(--rp-border); border-radius:8px; background:#fff; font-size:13px; }\nsnap-alert[type=\"info\"], rp-alert[type=\"info\"], snap-toast[type=\"info\"], rp-toast[type=\"info\"] { border-color:#bfdbfe; background:#eff6ff; color:#1e40af; }\nsnap-alert[type=\"success\"], rp-alert[type=\"success\"], snap-toast[type=\"success\"], rp-toast[type=\"success\"] { border-color:#bbf7d0; background:#f0fdf4; color:#166534; }\nsnap-alert[type=\"warning\"], rp-alert[type=\"warning\"], snap-toast[type=\"warning\"], rp-toast[type=\"warning\"] { border-color:#fde68a; background:#fffbeb; color:#92400e; }\nsnap-alert[type=\"error\"], rp-alert[type=\"error\"], snap-toast[type=\"error\"], rp-toast[type=\"error\"] { border-color:#fecaca; background:#fef2f2; color:#991b1b; }\nsnap-dropdown, rp-dropdown, snap-popover, rp-popover { display:block; width:var(--snap-width,300px); padding:8px; border:1px solid var(--rp-border); border-radius:10px; background:#fff; box-shadow:0 12px 24px rgba(15,23,42,.1); }\nsnap-tooltip, rp-tooltip { display:inline-block; width:fit-content; max-width:240px; padding:6px 8px; border-radius:6px; background:#111827; color:#fff; font-size:12px; }\n.rp-overlay-title { margin:0 0 8px; color:#111827; font-size:14px; font-weight:750; }\nsnap-modal, rp-modal { display:block; width:min(var(--snap-width,480px), 100%); border:1px solid var(--rp-border); border-radius:12px; background:#fff; box-shadow:0 24px 48px rgba(15,23,42,.18); overflow:hidden; }\nsnap-drawer, rp-drawer { display:block; width:min(var(--snap-width,360px), 100%); min-height:320px; border:1px solid var(--rp-border); background:#fff; box-shadow:0 18px 40px rgba(15,23,42,.14); }\n.rp-modal-head, .rp-drawer-head { display:flex; align-items:center; justify-content:space-between; padding:14px 16px; border-bottom:1px solid var(--rp-border); font-weight:750; }\n.rp-modal-body, .rp-drawer-body { padding:16px; }\n.rp-modal-footer { display:flex; justify-content:flex-end; gap:8px; padding:12px 16px; border-top:1px solid var(--rp-border); background:#f9fafb; }\nsnap-card, rp-card { display:block; width:auto; min-width:220px; padding:14px; border:1px solid var(--rp-border); border-radius:10px; background:#fff; }\n.rp-card-image { display:grid; place-items:center; height:120px; margin:-14px -14px 12px; border-radius:10px 10px 0 0; background:#f3f4f6; color:#6b7280; }\n.rp-card-title { display:block; color:#111827; font-weight:750; }\n.rp-card-subtitle { display:block; margin-top:4px; color:#6b7280; font-size:13px; }\n.rp-card-footer { margin:12px -14px -14px; padding:10px 14px; border-top:1px solid var(--rp-border); background:#f9fafb; }\nsnap-stat-card, rp-stat-card { display:grid; gap:6px; width:auto; min-width:0; padding:16px; border:1px solid var(--rp-border); border-radius:10px; background:#fff; }\n.rp-stat-label { color:#6b7280; font-size:12px; font-weight:650; }\n.rp-stat-value { color:#111827; font-size:26px; font-weight:800; }\n.rp-stat-change { font-size:12px; font-weight:700; }\nsnap-stat-card[trend=\"up\"] .rp-stat-change, rp-stat-card[trend=\"up\"] .rp-stat-change { color:var(--rp-success); }\nsnap-stat-card[trend=\"down\"] .rp-stat-change, rp-stat-card[trend=\"down\"] .rp-stat-change { color:var(--rp-danger); }\nsnap-tag, rp-tag { display:inline-flex; align-items:center; gap:5px; height:24px; padding:0 8px; border-radius:999px; background:#eef2ff; color:#3730a3; font-size:12px; font-weight:650; }\nsnap-tag[color=\"green\"], rp-tag[color=\"green\"] { background:#dcfce7; color:#166534; }\nsnap-tag[color=\"orange\"], rp-tag[color=\"orange\"] { background:#ffedd5; color:#9a3412; }\nsnap-tag[color=\"red\"], rp-tag[color=\"red\"] { background:#fee2e2; color:#991b1b; }\nsnap-checkbox, rp-checkbox, snap-radio, rp-radio { display:inline-flex; align-items:center; gap:8px; font-size:13px; }\n.rp-box { display:inline-grid; place-items:center; width:16px; height:16px; border:1px solid var(--rp-border-strong); border-radius:4px; color:#fff; }\nsnap-checkbox[state=\"checked\"] .rp-box, rp-checkbox[state=\"checked\"] .rp-box, snap-radio[state=\"checked\"] .rp-box, rp-radio[state=\"checked\"] .rp-box, snap-checkbox[state=\"indeterminate\"] .rp-box, rp-checkbox[state=\"indeterminate\"] .rp-box { background:var(--rp-primary); border-color:var(--rp-primary); }\nsnap-checkbox[state=\"disabled\"], rp-checkbox[state=\"disabled\"], snap-radio[state=\"disabled\"], rp-radio[state=\"disabled\"] { opacity:.5; }\nsnap-radio .rp-box, rp-radio .rp-box { border-radius:999px; }\nsnap-toggle, rp-toggle { display:inline-flex; align-items:center; gap:8px; font-size:13px; }\n.rp-toggle-track { width:34px; height:20px; border-radius:999px; background:#d1d5db; padding:2px; }\n.rp-toggle-dot { width:16px; height:16px; border-radius:999px; background:#fff; transition:none; }\nsnap-toggle[state=\"on\"] .rp-toggle-track, rp-toggle[state=\"on\"] .rp-toggle-track { background:var(--rp-primary); }\nsnap-toggle[state=\"on\"] .rp-toggle-dot, rp-toggle[state=\"on\"] .rp-toggle-dot { margin-left:14px; }\nsnap-toggle[state=\"disabled\"], rp-toggle[state=\"disabled\"] { opacity:.5; }\nsnap-form, rp-form { display:grid; gap:12px; width:fit-content; }\nsnap-form[layout=\"horizontal\"], rp-form[layout=\"horizontal\"] { grid-template-columns:max-content 1fr; align-items:start; }\nsnap-form-item, rp-form-item { display:grid; gap:6px; width:fit-content; }\n.rp-form-label { color:#374151; font-size:12px; font-weight:700; }\n.rp-form-label.required::after { content:\" *\"; color:var(--rp-danger); }\n.rp-form-error { color:var(--rp-danger); font-size:12px; }\nsnap-upload, rp-upload { display:grid; justify-items:center; gap:8px; width:280px; padding:18px; border:1px dashed var(--rp-border-strong); border-radius:10px; background:#fff; color:#6b7280; text-align:center; font-size:13px; }\nsnap-upload[state=\"has-file\"], rp-upload[state=\"has-file\"] { justify-items:start; border-style:solid; color:#374151; }\nsnap-upload[state=\"uploading\"], rp-upload[state=\"uploading\"] { border-color:#bfdbfe; background:#eff6ff; color:#1e40af; }\nsnap-image-placeholder, rp-image-placeholder { display:grid; place-items:center; width:var(--snap-width,160px); height:var(--snap-height,100px); background:#f3f4f6; border:1px dashed var(--rp-border-strong); border-radius:8px; color:#6b7280; font-size:12px; }\nsnap-progress, rp-progress { display:block; width:180px; height:8px; border-radius:999px; background:#e5e7eb; overflow:hidden; }\nsnap-progress[kind=\"circle\"], rp-progress[kind=\"circle\"], snap-progress[style=\"circle\"], rp-progress[style=\"circle\"] { display:grid; place-items:center; width:52px; height:52px; border-radius:999px; background:conic-gradient(var(--rp-primary) var(--progress,40%), #e5e7eb 0); font-size:12px; font-weight:750; }\n.rp-progress-bar { display:block; height:100%; width:var(--progress,40%); background:var(--rp-primary); }\nsnap-progress[status=\"success\"] .rp-progress-bar, rp-progress[status=\"success\"] .rp-progress-bar { background:var(--rp-success); }\nsnap-progress[status=\"error\"] .rp-progress-bar, rp-progress[status=\"error\"] .rp-progress-bar { background:var(--rp-danger); }\nsnap-pagination, rp-pagination { display:inline-flex; align-items:center; gap:6px; width:fit-content; font-size:13px; }\n.rp-page-btn { display:inline-grid; place-items:center; min-width:30px; height:30px; padding:0 8px; border:1px solid var(--rp-border); border-radius:6px; background:#fff; color:#374151; }\n.rp-page-btn.active { border-color:var(--rp-primary); background:var(--rp-primary); color:#fff; font-weight:750; }\nsnap-steps, rp-steps { display:flex; align-items:center; gap:8px; width:fit-content; }\n.rp-step { display:inline-flex; align-items:center; gap:6px; color:#6b7280; font-size:13px; }\n.rp-step-dot { display:inline-grid; place-items:center; width:22px; height:22px; border-radius:999px; border:1px solid var(--rp-border-strong); background:#fff; color:#6b7280; font-size:11px; font-weight:750; }\n.rp-step.active { color:var(--rp-primary); font-weight:750; }\n.rp-step.active .rp-step-dot { border-color:var(--rp-primary); background:var(--rp-primary); color:#fff; }\n.rp-step.done .rp-step-dot { border-color:var(--rp-success); background:var(--rp-success); color:#fff; }\n.rp-step-sep { width:28px; height:1px; background:var(--rp-border); }\nsnap-breadcrumb, rp-breadcrumb { display:inline-flex; align-items:center; gap:6px; color:#6b7280; font-size:13px; }\n.rp-breadcrumb-current { color:#111827; font-weight:650; }\n`;\n\nexport function injectStyle() {\n if (document.getElementById(RPUI_STYLE_ID)) return;\n const el = document.createElement(\"style\");\n el.id = RPUI_STYLE_ID;\n el.textContent = style;\n document.head.appendChild(el);\n}\n","import { injectStyle } from '../core/style';\nimport { attr, escapeHtml } from '../core/dom';\n\nexport class RpAnnotation extends HTMLElement {\n connectedCallback() {\n injectStyle();\n if (this.dataset.rpReady) return;\n this.dataset.rpReady = 'true';\n const existing = Array.from(this.childNodes);\n const depth = this.annotationDepth();\n const id = attr(this, 'id');\n const label = attr(this, 'label', id ? `Annotation ${id}` : 'Annotation');\n\n // Assign section path: top-level uses id, nested uses parent-path + sibling index\n let sectionPath: string;\n if (id) {\n sectionPath = id;\n } else {\n const parentSection = (this.closest('[data-rp-section]') as HTMLElement | null)?.dataset.rpSection ?? '';\n const siblings = this.parentElement ? Array.from(this.parentElement.children).filter(\n el => el.tagName.toLowerCase() === 'rp-annotation' || el.tagName.toLowerCase() === 'proto-annotation'\n ) : [];\n const idx = siblings.indexOf(this) + 1;\n sectionPath = parentSection ? `${parentSection}-${idx}` : String(idx);\n }\n this.dataset.rpSection = sectionPath;\n\n const marker = document.createElement('span');\n const kind = id ? 'drop' : depth <= 1 ? 'circle' : 'triangle';\n marker.className = `rp-annotation-marker ${kind}`;\n marker.innerHTML = kind === 'drop' ? `<span>${escapeHtml(id)}</span>` : '';\n\n const head = document.createElement('div');\n head.className = 'rp-annotation-head';\n head.append(marker);\n\n const title = document.createElement('span');\n title.className = 'rp-annotation-title';\n title.textContent = label;\n title.addEventListener('click', () => {\n const url = new URL(location.href);\n url.searchParams.set('section', sectionPath);\n history.pushState(null, '', url);\n window.dispatchEvent(new CustomEvent('rp-section', { detail: sectionPath }));\n });\n head.append(title);\n\n const body = document.createElement('div');\n body.className = 'rp-annotation-body';\n existing.forEach(n => body.appendChild(n));\n this.append(head, body);\n }\n\n annotationDepth() {\n let d = 0; let p = this.parentElement;\n while (p) {\n if (p.tagName.toLowerCase() === 'rp-annotation' || p.tagName.toLowerCase() === 'proto-annotation') d++;\n p = p.parentElement;\n }\n return d;\n }\n}\n\nexport class RpEnum extends HTMLElement { connectedCallback() { injectStyle(); } }\n\nexport class RpEnumItem extends HTMLElement {\n connectedCallback() {\n injectStyle();\n if (this.dataset.rpReady) return;\n this.dataset.rpReady = 'true';\n const children = Array.from(this.childNodes);\n\n // Compute 1-based index among same-tag siblings\n const parent = this.parentElement;\n const siblings = parent ? Array.from(parent.children).filter(\n el => el.tagName.toLowerCase() === 'rp-enum-item' || el.tagName.toLowerCase() === 'proto-enum-item'\n ) : [];\n const idx = siblings.indexOf(this) + 1;\n\n const labelEl = document.createElement('span');\n labelEl.className = 'rp-enum-label';\n\n const idxBadge = document.createElement('span');\n idxBadge.className = 'rp-enum-index';\n idxBadge.textContent = String(idx);\n\n const labelText = document.createElement('span');\n labelText.className = 'rp-enum-label-text';\n labelText.textContent = attr(this, 'label', 'State');\n\n const description = attr(this, 'description');\n if (description) {\n const desc = document.createElement('span');\n desc.className = 'rp-enum-description';\n desc.textContent = description;\n labelText.appendChild(desc);\n }\n\n labelEl.append(idxBadge, labelText);\n\n const content = document.createElement('div');\n content.className = 'rp-enum-content';\n children.forEach(n => content.appendChild(n));\n this.append(labelEl, content);\n }\n}\n\n\n","import { injectStyle } from '../core/style';\nimport { attr, escapeHtml, isViewportNode, resolveHeight, resolveWidth, usesAutoHeight } from '../core/dom';\n\nexport class RpMainView extends HTMLElement {\n private ro?: ResizeObserver;\n private frame = 0;\n\n connectedCallback() {\n injectStyle();\n if (!this.dataset.rpReady) {\n this.dataset.rpReady = 'true';\n const width = resolveWidth(this, 1440);\n const height = resolveHeight(this, 900);\n const autoHeight = usesAutoHeight(this);\n const scale = Number(attr(this, 'scale', '0.7')) || 0.7;\n const children = Array.from(this.childNodes);\n const shell = document.createElement('div');\n shell.className = 'rp-main-shell';\n shell.style.width = `${width * scale}px`;\n if (!autoHeight) shell.style.height = `${height * scale}px`;\n const stage = document.createElement('div');\n stage.className = 'rp-main-stage';\n stage.style.width = `${width}px`;\n stage.style.minHeight = autoHeight ? '0' : `${height}px`;\n stage.style.height = autoHeight ? 'auto' : `${height}px`;\n stage.style.transform = `scale(${scale})`;\n const clip = document.createElement('div');\n clip.className = 'rp-main-stage-clip';\n children.forEach(n => {\n if (isViewportNode(n)) {\n if (!n.hasAttribute('width') && !n.hasAttribute('device')) n.style.setProperty('--snap-width', `${width}px`);\n if (!n.hasAttribute('height')) n.style.setProperty('--snap-height', autoHeight ? 'auto' : `${height}px`);\n }\n stage.appendChild(n);\n });\n clip.appendChild(stage);\n shell.appendChild(clip);\n this.appendChild(shell);\n }\n this.scheduleRender();\n this.ro = new ResizeObserver(() => this.scheduleRender());\n this.ro.observe(this);\n const stage = this.querySelector<HTMLElement>('.rp-main-stage');\n if (stage) this.ro.observe(stage);\n }\n\n disconnectedCallback() { this.ro?.disconnect(); if (this.frame) cancelAnimationFrame(this.frame); }\n\n scheduleRender() {\n if (this.frame) return;\n this.frame = requestAnimationFrame(() => { this.frame = 0; this.syncAutoHeight(); this.renderPins(); });\n }\n\n syncAutoHeight() {\n if (!usesAutoHeight(this)) return;\n const shell = this.querySelector<HTMLElement>('.rp-main-shell');\n const stage = this.querySelector<HTMLElement>('.rp-main-stage');\n if (!shell || !stage) return;\n const scale = Number(attr(this, 'scale', '0.7')) || 0.7;\n const next = `${Math.ceil(stage.scrollHeight * scale)}px`;\n if (shell.style.height !== next) shell.style.height = next;\n }\n\n renderPins() {\n const shell = this.querySelector<HTMLElement>('.rp-main-shell');\n const stage = this.querySelector<HTMLElement>('.rp-main-stage');\n if (!shell || !stage) return;\n shell.querySelectorAll('.rp-pin').forEach(p => p.remove());\n const shellRect = shell.getBoundingClientRect();\n stage.querySelectorAll<HTMLElement>('[data-pin]').forEach(target => {\n const id = target.dataset.pin;\n if (!id) return;\n const r = target.getBoundingClientRect();\n const pin = document.createElement('span');\n pin.className = 'rp-pin';\n pin.style.left = `${r.left - shellRect.left}px`;\n pin.style.top = `${r.top - shellRect.top}px`;\n pin.innerHTML = `<span>${escapeHtml(id)}</span>`;\n pin.addEventListener('click', () => {\n const url = new URL(location.href);\n url.searchParams.set('section', id);\n history.pushState(null, '', url);\n window.dispatchEvent(new CustomEvent('rp-section', { detail: id }));\n });\n shell.appendChild(pin);\n });\n }\n}\n\n","import { injectStyle } from '../core/style';\nimport { attr, escapeHtml, isTopAnnotation } from '../core/dom';\n\nfunction activateSection(path: string, pane: Element | null) {\n document.querySelectorAll('.rp-section-focus').forEach(el => el.classList.remove('rp-section-focus'));\n const target = document.querySelector(`[data-rp-section=\"${CSS.escape(path)}\"]`);\n if (!target) return;\n target.classList.add('rp-section-focus');\n if (pane) {\n const paneEl = pane as HTMLElement;\n const targetRect = (target as HTMLElement).getBoundingClientRect();\n const paneRect = paneEl.getBoundingClientRect();\n paneEl.scrollTo({ top: paneEl.scrollTop + targetRect.top - paneRect.top - 20, behavior: 'smooth' });\n }\n setTimeout(() => target.classList.remove('rp-section-focus'), 3000);\n}\n\nexport class RpPage extends HTMLElement {\n connectedCallback() {\n injectStyle();\n if (this.dataset.rpReady) return;\n this.dataset.rpReady = 'true';\n const pageTitle = attr(this,'title','Untitled');\n const route = attr(this,'route','/');\n const description = attr(this,'description','');\n this.removeAttribute('title');\n const existing = Array.from(this.childNodes);\n\n const header = document.createElement('div');\n header.className = 'rp-page-header';\n header.innerHTML = `<div class=\"rp-page-title-row\"><h1 class=\"rp-page-title\">${escapeHtml(pageTitle)}</h1><span class=\"rp-page-route\">${escapeHtml(route)}</span></div><p class=\"rp-page-description\">${escapeHtml(description)}</p>`;\n\n const body = document.createElement('div');\n body.className = 'rp-page-body';\n const main = document.createElement('main');\n main.className = 'rp-page-main';\n const pane = document.createElement('aside');\n pane.className = 'rp-annotation-pane';\n pane.setAttribute('aria-label', 'Annotations');\n const paneInner = document.createElement('div');\n paneInner.className = 'rp-annotation-pane-inner';\n\n existing.forEach(n => (isTopAnnotation(n) ? paneInner : body).appendChild(n));\n pane.appendChild(paneInner);\n main.append(header, body);\n\n const shell = document.createElement('div');\n shell.className = 'rp-page-shell';\n shell.append(main, pane);\n this.appendChild(shell);\n\n // Bind header max-width to main view rendered width so description never drives page width\n requestAnimationFrame(() => {\n const mv = body.querySelector<HTMLElement>('rp-main-view, proto-main-view');\n if (mv) header.style.maxWidth = `${mv.offsetWidth}px`;\n });\n\n // Section routing: handle URL and clicks\n const go = () => {\n const sec = new URLSearchParams(location.search).get('section');\n if (sec) activateSection(sec, pane);\n };\n window.addEventListener('popstate', go);\n window.addEventListener('rp-section', (e) => activateSection((e as CustomEvent).detail, pane));\n requestAnimationFrame(go);\n }\n}\n\n\n","import { injectStyle } from '../core/style';\nimport { attr, hasExplicitNumericHeight, resolveHeight, resolveWidth, usesAutoHeight } from '../core/dom';\n\nexport class GenericElement extends HTMLElement { connectedCallback() { injectStyle(); } }\nexport class ViewportElement extends HTMLElement {\n connectedCallback() {\n injectStyle();\n if (this.hasAttribute('width') || this.hasAttribute('device')) this.style.setProperty('--snap-width', `${resolveWidth(this,1440)}px`);\n if (hasExplicitNumericHeight(this)) this.style.setProperty('--snap-height', `${resolveHeight(this,900)}px`);\n else if (usesAutoHeight(this)) this.style.setProperty('--snap-height', 'auto');\n }\n}\nexport class LayoutElement extends HTMLElement { connectedCallback() { injectStyle(); this.style.setProperty('--snap-columns', attr(this,'columns','1fr')); this.style.setProperty('--snap-rows', attr(this,'rows','auto')); if (this.hasAttribute('gap')) this.style.setProperty('--snap-gap', `${attr(this,'gap','0')}px`); } }\nexport class PanelElement extends HTMLElement { connectedCallback() { injectStyle(); this.style.setProperty('--snap-padding', `${attr(this,'padding','16')}px`); } }\nexport class NavbarElement extends HTMLElement { connectedCallback() { injectStyle(); this.style.setProperty('--snap-height', `${attr(this,'height','64')}px`); } }\nexport class SidebarElement extends HTMLElement { connectedCallback() { injectStyle(); this.style.setProperty('--snap-width', `${attr(this,'width','260')}px`); } }\nexport class LogoElement extends HTMLElement { connectedCallback() { injectStyle(); if (this.hasAttribute('size')) this.style.setProperty('--snap-size', `${attr(this,'size','82')}px`); if (!this.innerHTML.trim()) this.textContent = attr(this,'label','LOGO'); } }\n\n","export type IconName = 'search' | 'bell' | 'user' | 'inbox' | 'archive' | 'at-sign' | 'check' | 'trash-2' | 'x' | 'loader' | 'image' | 'circle-alert' | 'chevron-down' | 'layout-dashboard' | 'message-square' | 'settings' | 'plus' | 'file' | 'users' | 'shield' | 'calendar' | 'upload' | 'empty' | 'chevron-left' | 'chevron-right' | 'minus' | 'alert-triangle' | 'info' | 'circle-check' | 'circle';\n\nconst iconPaths: Record<IconName, string> = {\n search: '<circle cx=\"11\" cy=\"11\" r=\"8\"/><path d=\"m21 21-4.3-4.3\"/>',\n bell: '<path d=\"M10.3 21a1.9 1.9 0 0 0 3.4 0\"/><path d=\"M18 8a6 6 0 0 0-12 0c0 7-3 7-3 9h18c0-2-3-2-3-9\"/>',\n user: '<path d=\"M20 21a8 8 0 0 0-16 0\"/><circle cx=\"12\" cy=\"7\" r=\"4\"/>',\n inbox: '<polyline points=\"22 12 16 12 14 15 10 15 8 12 2 12\"/><path d=\"M5.5 5h13L22 12v7a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2v-7z\"/>',\n archive: '<rect width=\"20\" height=\"5\" x=\"2\" y=\"3\" rx=\"1\"/><path d=\"M4 8v11a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8\"/><path d=\"M10 12h4\"/>',\n 'at-sign': '<circle cx=\"12\" cy=\"12\" r=\"4\"/><path d=\"M16 8v5a3 3 0 0 0 6 0v-1a10 10 0 1 0-4 8\"/>',\n check: '<path d=\"M20 6 9 17l-5-5\"/>',\n 'trash-2': '<path d=\"M3 6h18\"/><path d=\"M8 6V4h8v2\"/><path d=\"M19 6l-1 14H6L5 6\"/><path d=\"M10 11v6\"/><path d=\"M14 11v6\"/>',\n x: '<path d=\"M18 6 6 18\"/><path d=\"m6 6 12 12\"/>',\n loader: '<path d=\"M21 12a9 9 0 1 1-6.2-8.6\"/>',\n image: '<rect width=\"18\" height=\"18\" x=\"3\" y=\"3\" rx=\"2\"/><circle cx=\"9\" cy=\"9\" r=\"2\"/><path d=\"m21 15-3.1-3.1a2 2 0 0 0-2.8 0L6 21\"/>',\n 'circle-alert': '<circle cx=\"12\" cy=\"12\" r=\"10\"/><path d=\"M12 8v4\"/><path d=\"M12 16h.01\"/>',\n 'chevron-down': '<path d=\"m6 9 6 6 6-6\"/>',\n 'layout-dashboard': '<rect width=\"7\" height=\"9\" x=\"3\" y=\"3\" rx=\"1\"/><rect width=\"7\" height=\"5\" x=\"14\" y=\"3\" rx=\"1\"/><rect width=\"7\" height=\"9\" x=\"14\" y=\"12\" rx=\"1\"/><rect width=\"7\" height=\"5\" x=\"3\" y=\"16\" rx=\"1\"/>',\n 'message-square': '<path d=\"M21 15a4 4 0 0 1-4 4H7l-4 4V7a4 4 0 0 1 4-4h10a4 4 0 0 1 4 4z\"/>',\n settings: '<path d=\"M12.2 2h-.4l-1 3a7 7 0 0 0-1.6.7l-3-1.4-.3.3-2 3 .2.4 2.6 2a7 7 0 0 0 0 2l-2.6 2-.2.4 2 3 .3.3 3-1.4a7 7 0 0 0 1.6.7l1 3h.4l1-3a7 7 0 0 0 1.6-.7l3 1.4.3-.3 2-3-.2-.4-2.6-2a7 7 0 0 0 0-2l2.6-2 .2-.4-2-3-.3-.3-3 1.4a7 7 0 0 0-1.6-.7z\"/><circle cx=\"12\" cy=\"12\" r=\"3\"/>',\n plus: '<path d=\"M5 12h14\"/><path d=\"M12 5v14\"/>',\n file: '<path d=\"M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z\"/><path d=\"M14 2v6h6\"/>',\n users: '<path d=\"M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2\"/><circle cx=\"9\" cy=\"7\" r=\"4\"/><path d=\"M22 21v-2a4 4 0 0 0-3-3.9\"/><path d=\"M16 3.1a4 4 0 0 1 0 7.8\"/>',\n shield: '<path d=\"M20 13c0 5-3.5 7.5-8 9-4.5-1.5-8-4-8-9V5l8-3 8 3z\"/>',\n calendar: '<path d=\"M8 2v4\"/><path d=\"M16 2v4\"/><rect width=\"18\" height=\"18\" x=\"3\" y=\"4\" rx=\"2\"/><path d=\"M3 10h18\"/>',\n upload: '<path d=\"M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4\"/><path d=\"m17 8-5-5-5 5\"/><path d=\"M12 3v12\"/>',\n empty: '<path d=\"M4 7h16\"/><path d=\"M5 7l1.5 13h11L19 7\"/><path d=\"M9 11h6\"/>',\n 'chevron-left': '<path d=\"m15 18-6-6 6-6\"/>',\n 'chevron-right': '<path d=\"m9 18 6-6-6-6\"/>',\n minus: '<path d=\"M5 12h14\"/>',\n 'alert-triangle': '<path d=\"m21.7 18-8-14a2 2 0 0 0-3.4 0l-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.7-3Z\"/><path d=\"M12 9v4\"/><path d=\"M12 17h.01\"/>',\n info: '<circle cx=\"12\" cy=\"12\" r=\"10\"/><path d=\"M12 16v-4\"/><path d=\"M12 8h.01\"/>',\n 'circle-check': '<circle cx=\"12\" cy=\"12\" r=\"10\"/><path d=\"m9 12 2 2 4-4\"/>',\n circle: '<circle cx=\"12\" cy=\"12\" r=\"10\"/>'\n};\n\nexport function icon(name?: string, size = 16): string {\n const key = (name || 'file') as IconName;\n const paths = iconPaths[key] || iconPaths.file;\n return `<svg class=\"rp-icon\" width=\"${size}\" height=\"${size}\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\">${paths}</svg>`;\n}\n\n\n","import { injectStyle } from '../core/style';\nimport { attr, csv, escapeHtml } from '../core/dom';\nimport { icon } from '../core/icons';\n\nexport class FieldElement extends HTMLElement { connectedCallback() { injectStyle(); if (this.dataset.rpReady) return; this.dataset.rpReady='true'; const value = attr(this,'value'); const placeholder = attr(this,'placeholder','Search'); const label = attr(this,'label'); const error = attr(this,'error-message'); const showValue = value || attr(this,'state') === 'filled'; const content = `${this.fieldIcon()}<span class=\"${showValue ? 'rp-value' : 'rp-placeholder'}\">${escapeHtml(value || placeholder)}</span>${this.hasAttribute('has-clear-button') ? icon('x',14) : ''}`; this.innerHTML = label || error ? `<span class=\"rp-field-label\">${escapeHtml(label)}</span><span class=\"rp-field-control\">${content}</span>${error ? `<span class=\"rp-error-text\">${escapeHtml(error)}</span>` : ''}` : content; } fieldIcon() { return icon(this.tagName.toLowerCase().includes('date-picker') ? 'calendar' : 'search'); } }\nexport class TextareaElement extends HTMLElement { connectedCallback() { injectStyle(); if (this.dataset.rpReady) return; this.dataset.rpReady = 'true'; this.style.setProperty('--snap-rows', attr(this,'rows','3')); const value = attr(this,'value') || attr(this,'placeholder','Textarea'); this.innerHTML = `<span class=\"${attr(this,'value') ? 'rp-value' : 'rp-placeholder'}\">${escapeHtml(value)}</span>`; } }\nexport class SelectElement extends HTMLElement { connectedCallback() { injectStyle(); if (this.dataset.rpReady) return; this.dataset.rpReady = 'true'; const options = csv(this, 'options', '选项 A,选项 B,选项 C'); const value = attr(this, 'value', options[0] || 'Select'); const label = attr(this, 'label'); this.innerHTML = `${label ? `<span class=\"rp-field-label\">${escapeHtml(label)}</span>` : ''}<span class=\"rp-select-control\"><span class=\"rp-select-value\">${escapeHtml(value)}</span>${icon('chevron-down')}</span><span class=\"rp-select-options\">${options.map(o => `<span class=\"rp-select-option${o === value ? ' selected' : ''}\">${escapeHtml(o)}</span>`).join('')}</span>`; } }\nexport class ButtonElement extends HTMLElement { connectedCallback() { injectStyle(); if (this.dataset.rpReady) return; this.dataset.rpReady='true'; const label = attr(this,'label', this.textContent?.trim() || 'Button'); const ic = attr(this,'icon'); const loading = attr(this,'state') === 'loading'; this.innerHTML = `${loading ? icon('loader') : ic ? icon(ic) : ''}<span>${escapeHtml(label)}</span>`; } }\nexport class CheckboxElement extends HTMLElement { connectedCallback() { injectStyle(); if (this.dataset.rpReady) return; this.dataset.rpReady='true'; const state = attr(this,'state'); const mark = state === 'checked' ? icon('check',12) : state === 'indeterminate' ? icon('minus',12) : ''; this.innerHTML = `<span class=\"rp-box\">${mark}</span><span>${escapeHtml(attr(this,'label',''))}</span>`; } }\nexport class RadioElement extends HTMLElement { connectedCallback() { injectStyle(); if (this.dataset.rpReady) return; this.dataset.rpReady='true'; const checked = attr(this,'state') === 'checked'; this.innerHTML = `<span class=\"rp-box\">${checked ? icon('circle',8) : ''}</span><span>${escapeHtml(attr(this,'label',''))}</span>`; } }\nexport class ToggleElement extends HTMLElement { connectedCallback() { injectStyle(); if (this.dataset.rpReady) return; this.dataset.rpReady='true'; this.innerHTML = `<span class=\"rp-toggle-track\"><span class=\"rp-toggle-dot\"></span></span><span>${escapeHtml(attr(this,'label',''))}</span>`; } }\nexport class FormElement extends HTMLElement { connectedCallback() { injectStyle(); } }\nexport class FormItemElement extends HTMLElement { connectedCallback() { injectStyle(); if (this.dataset.rpReady) return; this.dataset.rpReady = 'true'; const children = Array.from(this.childNodes); const label = attr(this,'label'); const error = attr(this,'error'); this.innerHTML = `${label ? `<span class=\"rp-form-label${this.hasAttribute('required') ? ' required' : ''}\">${escapeHtml(label)}</span>` : ''}`; children.forEach(n => this.appendChild(n)); if (error) this.insertAdjacentHTML('beforeend', `<span class=\"rp-form-error\">${escapeHtml(error)}</span>`); } }\nexport class DatePickerElement extends FieldElement { fieldIcon() { return icon('calendar'); } }\nexport class UploadElement extends HTMLElement { connectedCallback() { injectStyle(); if (this.dataset.rpReady) return; this.dataset.rpReady = 'true'; const state = attr(this,'state','empty'); if (state === 'has-file') this.innerHTML = `${icon('file')}<span>${escapeHtml(attr(this,'file','document.pdf'))}</span>`; else if (state === 'uploading') this.innerHTML = `${icon('loader')}<span>上传中...</span><span class=\"rp-progress-bar\" style=\"width:${escapeHtml(attr(this,'progress','60'))}%\"></span>`; else this.innerHTML = `${icon('upload',24)}<span>${escapeHtml(attr(this,'label','点击或拖拽文件上传'))}</span>`; } }\nexport class ImagePlaceholderElement extends HTMLElement { connectedCallback() { injectStyle(); this.style.setProperty('--snap-width', `${attr(this,'width','160')}px`); this.style.setProperty('--snap-height', `${attr(this,'height','100')}px`); if (!this.innerHTML.trim()) this.innerHTML = `${icon('image')} ${escapeHtml(attr(this,'label','Image'))}`; } }\nexport class ProgressElement extends HTMLElement { connectedCallback() { injectStyle(); if (this.dataset.rpReady) return; this.dataset.rpReady='true'; const value = attr(this,'value','40'); this.style.setProperty('--progress', `${value}%`); const kind = attr(this,'kind', attr(this,'style')); this.innerHTML = kind === 'circle' ? `${escapeHtml(value)}%` : '<span class=\"rp-progress-bar\"></span>'; } }\n\n","import { injectStyle } from '../core/style';\nimport { attr, csv, intAttr, escapeHtml } from '../core/dom';\nimport { icon } from '../core/icons';\n\nexport class BadgeElement extends HTMLElement { connectedCallback() { injectStyle(); const count = attr(this,'count','0'); const max = intAttr(this,'max',99); const n = Number(count); this.textContent = Number.isFinite(n) && n > max ? `${max}+` : count; } }\nexport class AvatarElement extends HTMLElement { connectedCallback() { injectStyle(); const size = attr(this,'size','32'); this.style.setProperty('--snap-size', `${size}px`); if (!this.textContent?.trim()) this.textContent = attr(this,'initials','U'); } }\nexport class ListElement extends HTMLElement { connectedCallback() { injectStyle(); if (this.dataset.rpReady || this.children.length) return; this.dataset.rpReady='true'; const items = intAttr(this,'items',3); const state = attr(this,'state'); this.innerHTML = Array.from({length: items}, (_,i)=>`<snap-list-item label=\"${['全部','未读','@ 我','已归档','设置'][i] || `Item ${i+1}`}\" icon=\"${['inbox','message-square','at-sign','archive','settings'][i] || 'file'}\"${state === 'first-selected' && i === 0 ? ' state=\"selected\"' : ''}></snap-list-item>`).join(''); } }\nexport class ListItemElement extends HTMLElement { connectedCallback() { injectStyle(); if (this.dataset.rpReady) return; this.dataset.rpReady='true'; const label = attr(this,'label', this.textContent?.trim() || 'Item'); const badge = attr(this,'badge'); const ic = attr(this,'icon'); this.innerHTML = `${ic ? icon(ic) : ''}<span class=\"rp-list-label\">${escapeHtml(label)}</span>${badge ? `<span class=\"rp-list-badge\">${escapeHtml(badge)}</span>` : ''}`; } }\nexport class TabsElement extends HTMLElement { connectedCallback() { injectStyle(); const active = attr(this,'active','0'); const numeric = Number(active); const children = Array.from(this.children) as HTMLElement[]; children.forEach((child, i) => { const label = child.getAttribute('label') || child.textContent?.trim() || ''; const isActive = Number.isFinite(numeric) ? i === numeric : label === active; child.classList.toggle('rp-tab-active', isActive); }); } }\nexport class TabElement extends HTMLElement { connectedCallback() { injectStyle(); if (this.dataset.rpReady) return; this.dataset.rpReady='true'; const label = attr(this,'label', this.textContent?.trim() || 'Tab'); const badge = attr(this,'badge'); this.innerHTML = `<span>${escapeHtml(label)}</span>${badge ? `<span class=\"rp-list-badge\">${escapeHtml(badge)}</span>` : ''}`; } }\nexport class PaginationElement extends HTMLElement { connectedCallback() { injectStyle(); if (this.dataset.rpReady) return; this.dataset.rpReady = 'true'; const total = intAttr(this,'total',10); const current = intAttr(this,'current',1); const pageSize = intAttr(this,'page-size',10); const pages = Math.max(1, Math.ceil(total / pageSize)); const visible = Array.from({length: Math.min(pages,5)}, (_,i)=>i+1); this.innerHTML = `<span class=\"rp-page-btn\">${icon('chevron-left',14)}</span>${visible.map(p=>`<span class=\"rp-page-btn${p===current?' active':''}\">${p}</span>`).join('')}<span class=\"rp-page-btn\">${icon('chevron-right',14)}</span><span>共 ${total} 条</span>`; } }\nexport class StepsElement extends HTMLElement { connectedCallback() { injectStyle(); if (this.dataset.rpReady) return; this.dataset.rpReady = 'true'; const steps = csv(this,'steps','步骤一,步骤二,步骤三'); const active = intAttr(this,'active',0); this.innerHTML = steps.map((s,i)=>`<span class=\"rp-step ${i < active ? 'done' : i === active ? 'active' : ''}\"><span class=\"rp-step-dot\">${i < active ? icon('check',12) : i + 1}</span>${escapeHtml(s)}</span>${i < steps.length - 1 ? '<span class=\"rp-step-sep\"></span>' : ''}`).join(''); } }\nexport class BreadcrumbElement extends HTMLElement { connectedCallback() { injectStyle(); if (this.dataset.rpReady) return; this.dataset.rpReady = 'true'; const items = csv(this,'items','首页,当前页'); this.innerHTML = items.map((item,i)=>`<span class=\"${i===items.length-1?'rp-breadcrumb-current':''}\">${escapeHtml(item)}</span>${i < items.length - 1 ? '<span>/</span>' : ''}`).join(''); } }\n\n\n","import { injectStyle } from '../core/style';\nimport { attr, csv, escapeHtml, intAttr } from '../core/dom';\nimport { icon } from '../core/icons';\n\nexport function sampleCell(c:string, j:number, i:number) { const lower = c.toLowerCase(); if (c.includes('发件') || lower.includes('name')) return ['张三','李四','系统通知','运营助手','王五','安全团队'][i%6]; if (c.includes('预览') || lower.includes('preview')) return ['请确认新的项目评审时间','本周周报已发送','你的账号存在新的登录','活动报名已通过审核','附件已更新','安全策略变更提醒'][i%6]; if (c.includes('时间') || lower.includes('time')) return ['09:12','昨天','周二','5月30日','5月28日','5月20日'][i%6]; if (c.includes('状态') || lower.includes('status')) return i % 2 ? '未读' : '已读'; return `Data ${i+1}-${j+1}`; }\nexport class TableElement extends HTMLElement { connectedCallback() { injectStyle(); if (this.dataset.rpReady) return; this.dataset.rpReady='true'; const cols = csv(this,'columns','Name,Preview,Time,Status'); const rows = intAttr(this,'rows',4); const hasCheckbox = this.hasAttribute('has-checkbox'); const hasAction = this.hasAttribute('has-action'); const finalCols = hasAction ? [...cols, '操作'] : cols; const headCells = `${hasCheckbox ? '<span class=\"rp-table-cell\">✓</span>' : ''}${finalCols.map(c=>`<span class=\"rp-table-cell\">${escapeHtml(c)}</span>`).join('')}`; const body = Array.from({length: rows}, (_,i) => `<div class=\"rp-table-row\">${hasCheckbox ? `<span class=\"rp-table-cell\"><span class=\"rp-box\">${i===1 ? icon('check',12) : ''}</span></span>` : ''}${finalCols.map((c,j)=>`<span class=\"rp-table-cell\">${c === '操作' ? '<snap-button label=\"查看\" variant=\"link\"></snap-button>' : escapeHtml(sampleCell(c,j,i))}</span>`).join('')}</div>`).join(''); this.innerHTML = `<div class=\"rp-table-row rp-table-head\">${headCells}</div>${body}`; } }\nexport class TableRowElement extends HTMLElement { connectedCallback() { injectStyle(); if (this.dataset.rpReady) return; this.dataset.rpReady='true'; this.innerHTML = `<span><span class=\"rp-box\">${attr(this,'state')==='selected'?icon('check',12):''}</span></span><span>张三</span><span>消息内容预览文本</span><span>09:12</span><span>${escapeHtml(attr(this,'state','default'))}</span>`; } }\nexport class BulkActionBarElement extends HTMLElement { connectedCallback() { injectStyle(); if (this.dataset.rpReady) return; this.dataset.rpReady='true'; const count = attr(this,'count','1'); const actions = csv(this,'actions','确认,取消'); this.innerHTML = `${icon('check')}<span>已选 ${escapeHtml(count)} 项</span>${actions.map(a=>`<snap-button label=\"${escapeHtml(a)}\" variant=\"ghost\"></snap-button>`).join('')}`; } }\nexport class EmptyElement extends HTMLElement { connectedCallback() { injectStyle(); if (this.dataset.rpReady) return; this.dataset.rpReady='true'; this.innerHTML = `${icon('empty',28)}<span class=\"rp-empty-title\">${escapeHtml(attr(this,'label','暂无数据'))}</span><span class=\"rp-empty-desc\">${escapeHtml(attr(this,'description',''))}</span>${this.hasAttribute('has-action') ? '<snap-button label=\"新建\" variant=\"primary\" icon=\"plus\"></snap-button>' : ''}`; } }\nexport class LoadingElement extends HTMLElement { connectedCallback() { injectStyle(); if (this.dataset.rpReady) return; this.dataset.rpReady='true'; const rows = intAttr(this,'rows',3); this.innerHTML = attr(this,'kind') === 'spinner' || attr(this,'style') === 'spinner' ? `<span class=\"rp-spinner\">${icon('loader',24)}</span>` : Array.from({length: rows}, (_,i)=>`<span class=\"rp-skeleton-line\" style=\"width:${220 - i*24}px\"></span>`).join(''); } }\nexport class AlertElement extends HTMLElement { connectedCallback() { injectStyle(); if (this.dataset.rpReady) return; this.dataset.rpReady='true'; const type = attr(this,'type','info'); const title = attr(this,'title', type === 'error' ? '错误' : '提示'); const message = attr(this,'message',''); const ic = type === 'error' ? 'circle-alert' : type === 'warning' ? 'alert-triangle' : type === 'success' ? 'circle-check' : 'info'; this.innerHTML = `${icon(ic)}<span><strong>${escapeHtml(title)}</strong>${message ? `<br>${escapeHtml(message)}` : ''}</span>${this.hasAttribute('closable') ? icon('x',14) : ''}`; } }\nexport class OverlayElement extends HTMLElement { connectedCallback() { injectStyle(); if (this.dataset.rpReady) return; this.dataset.rpReady = 'true'; const children = Array.from(this.childNodes); const title = attr(this,'title'); if (!title) return; const head = document.createElement('div'); head.className = 'rp-overlay-title'; head.textContent = title; this.prepend(head); children.forEach(n => this.appendChild(n)); } }\nexport class TooltipElement extends HTMLElement { connectedCallback() { injectStyle(); if (!this.textContent?.trim()) this.textContent = attr(this,'text','提示内容'); } }\nexport class ModalElement extends HTMLElement { connectedCallback() { injectStyle(); if (this.dataset.rpReady) return; this.dataset.rpReady = 'true'; this.style.setProperty('--snap-width', `${attr(this,'width','480')}px`); const children = Array.from(this.childNodes); const body = document.createElement('div'); body.className = 'rp-modal-body'; children.forEach(n => body.appendChild(n)); this.innerHTML = `<div class=\"rp-modal-head\"><span>${escapeHtml(attr(this,'title','标题'))}</span>${icon('x',14)}</div>`; this.appendChild(body); if (this.hasAttribute('has-footer')) this.insertAdjacentHTML('beforeend', '<div class=\"rp-modal-footer\"><snap-button label=\"取消\"></snap-button><snap-button label=\"确认\" variant=\"primary\"></snap-button></div>'); } }\nexport class DrawerElement extends HTMLElement { connectedCallback() { injectStyle(); if (this.dataset.rpReady) return; this.dataset.rpReady = 'true'; this.style.setProperty('--snap-width', `${attr(this,'width','360')}px`); const children = Array.from(this.childNodes); const body = document.createElement('div'); body.className = 'rp-drawer-body'; children.forEach(n => body.appendChild(n)); this.innerHTML = `<div class=\"rp-drawer-head\"><span>${escapeHtml(attr(this,'title','抽屉'))}</span>${icon('x',14)}</div>`; this.appendChild(body); } }\nexport class CardElement extends HTMLElement { connectedCallback() { injectStyle(); if (this.dataset.rpReady) return; this.dataset.rpReady = 'true'; const children = Array.from(this.childNodes); const title = attr(this,'title'); const subtitle = attr(this,'subtitle'); this.innerHTML = `${this.hasAttribute('has-image') ? `<span class=\"rp-card-image\">${icon('image')} Image</span>` : ''}${title ? `<span class=\"rp-card-title\">${escapeHtml(title)}</span>` : ''}${subtitle ? `<span class=\"rp-card-subtitle\">${escapeHtml(subtitle)}</span>` : ''}`; children.forEach(n => this.appendChild(n)); if (this.hasAttribute('has-footer')) this.insertAdjacentHTML('beforeend', '<span class=\"rp-card-footer\"><snap-button label=\"查看\" variant=\"secondary\"></snap-button></span>'); } }\nexport class StatCardElement extends HTMLElement { connectedCallback() { injectStyle(); if (this.dataset.rpReady) return; this.dataset.rpReady = 'true'; this.innerHTML = `<span class=\"rp-stat-label\">${escapeHtml(attr(this,'label','指标'))}</span><span class=\"rp-stat-value\">${escapeHtml(attr(this,'value','128'))}</span><span class=\"rp-stat-change\">${escapeHtml(attr(this,'change','0%'))}</span>`; } }\nexport class TagElement extends HTMLElement { connectedCallback() { injectStyle(); if (this.dataset.rpReady) return; this.dataset.rpReady = 'true'; const label = attr(this,'label', this.textContent?.trim() || 'Tag'); this.innerHTML = `<span>${escapeHtml(label)}</span>${this.hasAttribute('closable') ? icon('x',12) : ''}`; } }\n\n","import { define } from './core/dom';\nimport { RpAnnotation, RpEnum, RpEnumItem } from './canvas/annotation';\nimport { RpMainView } from './canvas/main-view';\nimport { RpPage } from './canvas/page';\nimport { GenericElement, LayoutElement, LogoElement, NavbarElement, PanelElement, SidebarElement, ViewportElement } from './primitives/layout';\nimport { ButtonElement, CheckboxElement, DatePickerElement, FieldElement, FormElement, FormItemElement, ImagePlaceholderElement, ProgressElement, RadioElement, SelectElement, TextareaElement, ToggleElement, UploadElement } from './primitives/controls';\nimport { AvatarElement, BadgeElement, BreadcrumbElement, ListElement, ListItemElement, PaginationElement, StepsElement, TabElement, TabsElement } from './primitives/navigation';\nimport { AlertElement, BulkActionBarElement, CardElement, DrawerElement, EmptyElement, LoadingElement, ModalElement, OverlayElement, StatCardElement, TableElement, TableRowElement, TagElement, TooltipElement } from './primitives/data-display';\n\nexport function registerAll() { define('rp-page', RpPage); define('proto-page', RpPage); define('rp-main-view', RpMainView); define('proto-main-view', RpMainView); define('rp-annotation', RpAnnotation); define('proto-annotation', RpAnnotation); define('rp-enum', RpEnum); define('proto-enum', RpEnum); define('rp-enum-item', RpEnumItem); define('proto-enum-item', RpEnumItem); const pairs: Array<[string, CustomElementConstructor]> = [ ['viewport', ViewportElement], ['layout', LayoutElement], ['panel', PanelElement], ['navbar', NavbarElement], ['sidebar', SidebarElement], ['logo', LogoElement], ['search', FieldElement], ['input', FieldElement], ['textarea', TextareaElement], ['select', SelectElement], ['badge', BadgeElement], ['avatar', AvatarElement], ['list', ListElement], ['list-item', ListItemElement], ['tabs', TabsElement], ['tab', TabElement], ['button', ButtonElement], ['button-group', GenericElement], ['table', TableElement], ['table-row', TableRowElement], ['bulk-action-bar', BulkActionBarElement], ['empty', EmptyElement], ['loading', LoadingElement], ['alert', AlertElement], ['toast', AlertElement], ['dropdown', OverlayElement], ['popover', OverlayElement], ['tooltip', TooltipElement], ['modal', ModalElement], ['drawer', DrawerElement], ['card', CardElement], ['stat-card', StatCardElement], ['tag', TagElement], ['checkbox', CheckboxElement], ['radio', RadioElement], ['toggle', ToggleElement], ['form', FormElement], ['form-item', FormItemElement], ['date-picker', DatePickerElement], ['upload', UploadElement], ['image-placeholder', ImagePlaceholderElement], ['progress', ProgressElement], ['pagination', PaginationElement], ['steps', StepsElement], ['breadcrumb', BreadcrumbElement] ]; for (const [suffix, ctor] of pairs) { define(`snap-${suffix}`, ctor); define(`rp-${suffix}`, ctor); } }\n\n\n","import { registerAll } from './registry';\n\nregisterAll();\n\nexport { registerAll };\n"],"names":["stage"],"mappings":"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"}
|
package/llms.txt
ADDED
|
@@ -0,0 +1,195 @@
|
|
|
1
|
+
# RPUI Web Components Reference for LLMs
|
|
2
|
+
|
|
3
|
+
RPUI means Readable Prototype UI. It is a static prototype specification and rendering runtime implemented with native Web Components.
|
|
4
|
+
|
|
5
|
+
A generated prototype imports one file only:
|
|
6
|
+
|
|
7
|
+
```html
|
|
8
|
+
<script type="module" src="./dist/rpui.js"></script>
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
`dist/rpui.js` registers all custom elements and injects runtime CSS plus Lucide-style inline SVG icons. Do not import external CSS, image CDNs, icon CDNs, or UI frameworks.
|
|
12
|
+
|
|
13
|
+
## Core model
|
|
14
|
+
|
|
15
|
+
RPUI has two layers:
|
|
16
|
+
|
|
17
|
+
1. Canvas layer: page shell, main snapshot view, numbered pins, annotations, nested annotations, and state enums.
|
|
18
|
+
2. Snapshot Primitive layer: static UI building blocks for product UI snapshots and annotation slices.
|
|
19
|
+
|
|
20
|
+
Use `rp-*` tags for new work. Compatibility aliases are available:
|
|
21
|
+
|
|
22
|
+
- `proto-*` aliases exist for canvas tags.
|
|
23
|
+
- `snap-*` aliases exist for snapshot primitive tags.
|
|
24
|
+
|
|
25
|
+
## Canvas tags
|
|
26
|
+
|
|
27
|
+
```html
|
|
28
|
+
<rp-page title="页面标题" route="/route" description="页面说明">
|
|
29
|
+
<rp-main-view device="web" scale="0.65">
|
|
30
|
+
<rp-viewport device="web">
|
|
31
|
+
<!-- fixed-width, auto-height main snapshot built with rp-* primitives -->
|
|
32
|
+
</rp-viewport>
|
|
33
|
+
</rp-main-view>
|
|
34
|
+
|
|
35
|
+
<rp-annotation id="1" label="区域说明">...</rp-annotation>
|
|
36
|
+
</rp-page>
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
Tags:
|
|
40
|
+
|
|
41
|
+
- `<rp-page title="..." route="..." description="...">` — root document canvas. It keeps the title/main snapshot on the left and moves top-level annotations to the right-side scroll pane.
|
|
42
|
+
- `<rp-main-view device="web|ipad|mobile" width="..." height="auto|900" scale="0.65">` — scaled main snapshot frame. Device presets are fixed width with auto height unless a numeric `height` is provided.
|
|
43
|
+
- `<rp-viewport device="web|ipad|mobile" width="..." height="auto|900">` — snapshot viewport. Use the same `device` as the main view for clarity.
|
|
44
|
+
- `<rp-annotation id="1" label="...">` — top-level annotation linked to `data-pin="1"`; rendered in the right annotation pane.
|
|
45
|
+
- `<rp-annotation label="...">` — nested annotation; no `id` required.
|
|
46
|
+
- `<rp-enum>` — horizontal state/variant container.
|
|
47
|
+
- `<rp-enum-item label="..." description="...">` — one explicit state/variant card with optional short description.
|
|
48
|
+
|
|
49
|
+
## Pin rule
|
|
50
|
+
|
|
51
|
+
Inside `<rp-main-view>`, add `data-pin="N"` to meaningful regions. Number pins from 1 without gaps.
|
|
52
|
+
|
|
53
|
+
Every `data-pin="N"` must have a matching top-level annotation:
|
|
54
|
+
|
|
55
|
+
```html
|
|
56
|
+
<rp-navbar data-pin="1">...</rp-navbar>
|
|
57
|
+
<rp-annotation id="1" label="顶部导航">...</rp-annotation>
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
RPUI renders water-drop pins automatically. Never write pin DOM manually.
|
|
61
|
+
|
|
62
|
+
## Layout and state rules
|
|
63
|
+
|
|
64
|
+
- RPUI is static. Do not create interactions.
|
|
65
|
+
- Do not use `onclick`, hover behavior, runtime focus, timers, API calls, or framework state.
|
|
66
|
+
- Do not use external images; use `<rp-image-placeholder>`.
|
|
67
|
+
- Do not use `position:absolute` or `position:fixed` in snapshot content. RPUI owns pin positioning.
|
|
68
|
+
- Do not use raw `div`, `button`, `input`, or `table` to represent product UI. Use `rp-*` primitives.
|
|
69
|
+
- Basic text and simple inline HTML are allowed inside annotations.
|
|
70
|
+
- Top-level annotations render automatically in the right-side annotation pane. Do not manually create annotation pane wrappers.
|
|
71
|
+
- The title/route/description and main snapshot stay visible on the left while the annotation pane scrolls independently on both axes.
|
|
72
|
+
- Keep annotations compact and document-flow oriented. Do not stretch annotation content to full width.
|
|
73
|
+
- Choose a device preset for new prototypes: `web` (1440px), `ipad` (834px), or `mobile` (390px). Presets use fixed width and auto height unless a numeric height is provided.
|
|
74
|
+
- In the main snapshot, keep selects/dropdowns/popovers collapsed unless the page's primary representative state truly requires the overlay to be visible. Prefer showing expanded select/dropdown contents in annotation enums so they do not obscure the main layout.
|
|
75
|
+
- Use `<rp-enum>` for state families, permission variants, hidden interaction results, and validation branches. Use `rp-enum-item description="..."` for a short clarification of a state.
|
|
76
|
+
|
|
77
|
+
## Snapshot primitives
|
|
78
|
+
|
|
79
|
+
### Containers
|
|
80
|
+
|
|
81
|
+
- `<rp-viewport device="web|ipad|mobile" width="1440" height="auto|900">` — fixed-width snapshot viewport; presets default to auto height.
|
|
82
|
+
- `<rp-layout columns="260px 1fr" rows="auto" gap="16">` — CSS grid container.
|
|
83
|
+
- `<rp-panel padding="24" elevation="1|2">` — white panel/card shell.
|
|
84
|
+
- `<rp-card title="..." subtitle="..." has-image has-footer>` — content card.
|
|
85
|
+
- `<rp-modal width="480" title="..." has-footer>` — static opened modal.
|
|
86
|
+
- `<rp-drawer side="left|right" width="360" title="...">` — static opened drawer.
|
|
87
|
+
- `<rp-dropdown width="300" title="...">` — static opened dropdown.
|
|
88
|
+
- `<rp-popover width="300" title="...">` — static opened popover.
|
|
89
|
+
- `<rp-tooltip text="..." position="top|bottom|left|right">` — visible tooltip bubble.
|
|
90
|
+
|
|
91
|
+
### Navigation
|
|
92
|
+
|
|
93
|
+
- `<rp-navbar height="64">` — top navigation container.
|
|
94
|
+
- `<rp-sidebar width="260" collapsed>` — side navigation container.
|
|
95
|
+
- `<rp-logo size="82" label="LOGO">` — logo placeholder.
|
|
96
|
+
- `<rp-list items="4" state="first-selected">` — generated list when no children are provided.
|
|
97
|
+
- `<rp-list-item label="..." icon="inbox" badge="12" state="default|selected|disabled">`.
|
|
98
|
+
- `<rp-tabs active="0">` with `<rp-tab label="全部" badge="12">`; `active` can be index or label.
|
|
99
|
+
- `<rp-breadcrumb items="首页,设置,用户管理">`.
|
|
100
|
+
- `<rp-pagination total="128" current="2" page-size="20">`.
|
|
101
|
+
- `<rp-steps steps="填写信息,确认,完成" active="1">`.
|
|
102
|
+
|
|
103
|
+
### Data and content display
|
|
104
|
+
|
|
105
|
+
- `<rp-table rows="6" columns="发件人,消息预览,时间,状态" has-checkbox has-action>` — generated static table.
|
|
106
|
+
- `<rp-table-row state="default|selected|unread|highlighted|disabled">` — standalone row slice.
|
|
107
|
+
- `<rp-bulk-action-bar count="3" actions="标为已读,归档,删除">`.
|
|
108
|
+
- `<rp-empty label="暂无数据" description="..." has-action>`.
|
|
109
|
+
- `<rp-loading rows="4" kind="skeleton|spinner">` (`style="spinner"` also works for compatibility).
|
|
110
|
+
- `<rp-image-placeholder width="160" height="100" label="Image">`.
|
|
111
|
+
- `<rp-avatar size="32" initials="OC">`.
|
|
112
|
+
- `<rp-badge count="120" max="99">`.
|
|
113
|
+
- `<rp-tag label="已启用" color="green|orange|red" closable>`.
|
|
114
|
+
- `<rp-stat-card label="活跃用户" value="12,480" trend="up|down|flat" change="+12%">`.
|
|
115
|
+
|
|
116
|
+
### Forms and controls
|
|
117
|
+
|
|
118
|
+
All form states are explicit through attributes; there is no runtime focus or input behavior.
|
|
119
|
+
|
|
120
|
+
- `<rp-search state="default|focus|filled|error|disabled" placeholder="..." value="..." has-clear-button>`.
|
|
121
|
+
- `<rp-input state="default|focus|filled|error|disabled" label="..." placeholder="..." value="..." has-clear-button error-message="...">`.
|
|
122
|
+
- `<rp-textarea state="default|focus|filled|error|disabled" rows="3" placeholder="..." value="...">`.
|
|
123
|
+
- `<rp-select state="collapsed|expanded|disabled" label="..." value="..." options="A,B,C">`.
|
|
124
|
+
- `<rp-date-picker state="default|focus|filled|error|disabled" value="2026-06-07">`.
|
|
125
|
+
- `<rp-checkbox state="unchecked|checked|indeterminate|disabled" label="...">`.
|
|
126
|
+
- `<rp-radio state="unchecked|checked|disabled" label="...">`.
|
|
127
|
+
- `<rp-toggle state="on|off|disabled" label="...">`.
|
|
128
|
+
- `<rp-button label="..." variant="primary|secondary|ghost|danger|link" state="default|disabled|loading" icon="plus" size="sm|md|lg">`.
|
|
129
|
+
- `<rp-button-group>...</rp-button-group>`.
|
|
130
|
+
- `<rp-form layout="vertical|horizontal">`.
|
|
131
|
+
- `<rp-form-item label="..." required error="...">...</rp-form-item>`.
|
|
132
|
+
- `<rp-upload state="empty|has-file|uploading" file="document.pdf" progress="60">`.
|
|
133
|
+
|
|
134
|
+
### Feedback
|
|
135
|
+
|
|
136
|
+
- `<rp-alert type="info|success|warning|error" title="..." message="..." closable>`.
|
|
137
|
+
- `<rp-toast type="info|success|warning|error" title="..." message="..." closable>`.
|
|
138
|
+
- `<rp-progress value="40" kind="bar|circle" status="success|error">`.
|
|
139
|
+
|
|
140
|
+
## Icon rule
|
|
141
|
+
|
|
142
|
+
Use Lucide icon names through the `icon` attribute when available:
|
|
143
|
+
|
|
144
|
+
```html
|
|
145
|
+
<rp-button label="新建" icon="plus" variant="primary"></rp-button>
|
|
146
|
+
<rp-list-item label="已归档" icon="archive"></rp-list-item>
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
The runtime renders inline SVG. Do not import lucide or any icon CDN.
|
|
150
|
+
|
|
151
|
+
## State coverage checklist
|
|
152
|
+
|
|
153
|
+
For each page, consider whether these states apply:
|
|
154
|
+
|
|
155
|
+
- loaded with normal data
|
|
156
|
+
- empty data
|
|
157
|
+
- loading/skeleton/spinner
|
|
158
|
+
- error/retry
|
|
159
|
+
- search default/focus/filled/no-result
|
|
160
|
+
- filter collapsed/expanded
|
|
161
|
+
- row default/selected/unread/highlighted/disabled
|
|
162
|
+
- bulk selection off/on
|
|
163
|
+
- pagination first/middle/last/no more pages
|
|
164
|
+
- permission variants: readonly/admin/owner/external collaborator
|
|
165
|
+
- destructive confirmation
|
|
166
|
+
- validation default/filled/error/disabled
|
|
167
|
+
|
|
168
|
+
## Recommended complete HTML shape
|
|
169
|
+
|
|
170
|
+
```html
|
|
171
|
+
<!doctype html>
|
|
172
|
+
<html lang="zh-CN">
|
|
173
|
+
<head>
|
|
174
|
+
<meta charset="UTF-8" />
|
|
175
|
+
<script type="module" src="./dist/rpui.js"></script>
|
|
176
|
+
</head>
|
|
177
|
+
<body>
|
|
178
|
+
<rp-page title="页面标题" route="/route" description="页面说明">
|
|
179
|
+
<rp-main-view device="web" scale="0.65">
|
|
180
|
+
<rp-viewport device="web">
|
|
181
|
+
<!-- main snapshot built only with rp-* primitives -->
|
|
182
|
+
</rp-viewport>
|
|
183
|
+
</rp-main-view>
|
|
184
|
+
|
|
185
|
+
<rp-annotation id="1" label="区域说明">
|
|
186
|
+
简短说明此区域的职责。
|
|
187
|
+
<rp-enum>
|
|
188
|
+
<rp-enum-item label="默认" description="正常可用的数据态。"><rp-empty label="示例"></rp-empty></rp-enum-item>
|
|
189
|
+
<rp-enum-item label="加载" description="首次进入或刷新时展示。"><rp-loading rows="3"></rp-loading></rp-enum-item>
|
|
190
|
+
</rp-enum>
|
|
191
|
+
</rp-annotation>
|
|
192
|
+
</rp-page>
|
|
193
|
+
</body>
|
|
194
|
+
</html>
|
|
195
|
+
```
|
package/package.json
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@21stware/rpui",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Readable Prototype UI: static UI prototype canvas and snapshot primitives implemented as Web Components.",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "dist/rpui.js",
|
|
7
|
+
"module": "dist/rpui.js",
|
|
8
|
+
"types": "dist/rpui.d.ts",
|
|
9
|
+
"exports": {
|
|
10
|
+
".": {
|
|
11
|
+
"types": "./dist/rpui.d.ts",
|
|
12
|
+
"default": "./dist/rpui.js"
|
|
13
|
+
},
|
|
14
|
+
"./dist/rpui.js": "./dist/rpui.js",
|
|
15
|
+
"./llms.txt": "./llms.txt",
|
|
16
|
+
"./skill.txt": "./skill.txt"
|
|
17
|
+
},
|
|
18
|
+
"sideEffects": true,
|
|
19
|
+
"files": [
|
|
20
|
+
"dist",
|
|
21
|
+
"llms.txt",
|
|
22
|
+
"skill.txt",
|
|
23
|
+
"README.md"
|
|
24
|
+
],
|
|
25
|
+
"scripts": {
|
|
26
|
+
"dev": "vite --open /preview/",
|
|
27
|
+
"typecheck": "tsc -p tsconfig.json --noEmit",
|
|
28
|
+
"build:js": "vite build",
|
|
29
|
+
"build:types": "tsc -p tsconfig.types.json",
|
|
30
|
+
"build": "npm run clean && npm run typecheck && npm run build:js && npm run build:types",
|
|
31
|
+
"release": "npm run build",
|
|
32
|
+
"clean": "rm -rf dist && mkdir -p dist"
|
|
33
|
+
},
|
|
34
|
+
"keywords": [
|
|
35
|
+
"web-components",
|
|
36
|
+
"prototype",
|
|
37
|
+
"ui",
|
|
38
|
+
"snapshot",
|
|
39
|
+
"llm"
|
|
40
|
+
],
|
|
41
|
+
"license": "MIT",
|
|
42
|
+
"devDependencies": {
|
|
43
|
+
"typescript": "^5.8.3",
|
|
44
|
+
"vite": "^5.4.11"
|
|
45
|
+
}
|
|
46
|
+
}
|
package/skill.txt
ADDED
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
# RPUI Prototype Implementation Skill
|
|
2
|
+
|
|
3
|
+
Use this skill when converting product requirements, screenshots, existing UI code, or design notes into a static RPUI prototype.
|
|
4
|
+
|
|
5
|
+
## Goal
|
|
6
|
+
|
|
7
|
+
Create one readable, static, self-contained HTML prototype that fully exposes a product page's UI structure, interaction states, permissions, loading states, empty states, error states, validation states, and edge cases.
|
|
8
|
+
|
|
9
|
+
RPUI does not simulate interaction. It lays out interaction results spatially so reviewers can understand the complete state space without clicking anything. Treat it like baking time-based UI behavior into a document-flow canvas.
|
|
10
|
+
|
|
11
|
+
## Required inputs
|
|
12
|
+
|
|
13
|
+
Prefer these inputs, in priority order:
|
|
14
|
+
|
|
15
|
+
1. Product requirement or user story.
|
|
16
|
+
2. Screenshot or design draft.
|
|
17
|
+
3. Existing code with conditional rendering.
|
|
18
|
+
4. Permission matrix or role notes.
|
|
19
|
+
5. Known loading, empty, error, validation, and edge cases.
|
|
20
|
+
|
|
21
|
+
If some inputs are missing, infer common SaaS/product UI states and make assumptions explicit in annotations.
|
|
22
|
+
|
|
23
|
+
## Output contract
|
|
24
|
+
|
|
25
|
+
Output a complete HTML file that imports exactly one RPUI runtime file:
|
|
26
|
+
|
|
27
|
+
```html
|
|
28
|
+
<script type="module" src="./dist/rpui.js"></script>
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
The document must contain:
|
|
32
|
+
|
|
33
|
+
1. one `<rp-page>` root with `title`, `route`, and `description`,
|
|
34
|
+
2. exactly one `<rp-main-view>` containing the main page snapshot,
|
|
35
|
+
3. snapshot content built with `rp-*` primitives,
|
|
36
|
+
4. numbered `data-pin="N"` anchors on meaningful main-view regions,
|
|
37
|
+
5. matching top-level `<rp-annotation id="N" label="...">` blocks,
|
|
38
|
+
6. `<rp-enum>` and `<rp-enum-item>` blocks for conditional states and variants.
|
|
39
|
+
|
|
40
|
+
## Implementation steps
|
|
41
|
+
|
|
42
|
+
1. Identify the page route, page title, and one-sentence description.
|
|
43
|
+
2. Choose a device preset: `web` for desktop/admin pages, `ipad` for tablet layouts, or `mobile` for phone layouts. Prefer fixed-width, auto-height prototypes.
|
|
44
|
+
3. Choose the most complex representative main snapshot: loaded data, selected rows, expanded drawers/modals when they are central to the page, active validation, and role-specific controls when relevant.
|
|
45
|
+
4. Build the main snapshot inside `<rp-main-view device="web|ipad|mobile">` using only `rp-*` snapshot primitives, usually inside an `<rp-viewport device="web|ipad|mobile">`.
|
|
46
|
+
5. Add `data-pin="N"` to every meaningful UI region. Number pins from 1 without gaps.
|
|
47
|
+
6. For every `data-pin="N"`, create one top-level `<rp-annotation id="N" label="...">`. The runtime places top-level annotations in the right-side annotation pane.
|
|
48
|
+
7. Keep annotation text concise and specific. Avoid large prose blocks and card-like padding wrappers.
|
|
49
|
+
8. Use nested `<rp-annotation>` only when a rule belongs to a smaller sub-region.
|
|
50
|
+
9. Put repeated/conditional state families in `<rp-enum>`.
|
|
51
|
+
10. Use `<rp-enum-item label="..." description="...">` for every state: default, focus, filled, selected, disabled, empty, loading, error, permission-specific, and data-size variants. `description` is optional and should be short.
|
|
52
|
+
11. Validate that no interactive JavaScript, event attributes, external images, external CSS, or CDN icons are used.
|
|
53
|
+
|
|
54
|
+
## Authoring rules
|
|
55
|
+
|
|
56
|
+
- Use `rp-*` tags for new work. `proto-*` and `snap-*` are compatibility aliases only.
|
|
57
|
+
- Use `<rp-page>`, not arbitrary root containers.
|
|
58
|
+
- Use `<rp-main-view>` once per prototype page.
|
|
59
|
+
- Use `rp-*` tags for both the main snapshot and UI slices inside annotations.
|
|
60
|
+
- Do not use direct `div`, `button`, `input`, `table`, or similar product UI HTML. Use RPUI primitives instead. Basic text and simple inline annotation markup are allowed.
|
|
61
|
+
- Do not write CSS or JavaScript in the prototype unless implementing or extending RPUI itself.
|
|
62
|
+
- Do not use `position:absolute` or `position:fixed` in snapshot content. RPUI owns pin positioning.
|
|
63
|
+
- Do not hide important content behind interactions. Expand it into the annotation area with `<rp-enum>`.
|
|
64
|
+
- Do not stretch annotation blocks to full width. The runtime provides a right-side annotation pane; keep annotation content compact inside it.
|
|
65
|
+
- Keep select/dropdown/popover overlays collapsed in the main snapshot unless visibility is essential to the representative state. Put expanded overlay contents in annotation enums or local slices so the main layout remains readable.
|
|
66
|
+
- Use `rp-enum-item description="..."` for short state notes, not long prose.
|
|
67
|
+
- Prefer `device="web"`, `device="ipad"`, or `device="mobile"` over hand-tuned width/height values. Use explicit numeric `height` only when a fixed-height clipped viewport is intentional.
|
|
68
|
+
|
|
69
|
+
## State coverage checklist
|
|
70
|
+
|
|
71
|
+
For every page, check whether these states apply:
|
|
72
|
+
|
|
73
|
+
- Loaded with normal data.
|
|
74
|
+
- Empty data.
|
|
75
|
+
- Loading or skeleton/spinner.
|
|
76
|
+
- Error or retry.
|
|
77
|
+
- Search default, focus, filled, no result.
|
|
78
|
+
- Filter collapsed and expanded.
|
|
79
|
+
- Row default, selected, unread, highlighted, disabled.
|
|
80
|
+
- Bulk selection off and on.
|
|
81
|
+
- Pagination first, middle, last, no more pages.
|
|
82
|
+
- Permission variants such as readonly, admin, owner, external collaborator.
|
|
83
|
+
- Destructive action confirmation.
|
|
84
|
+
- Validation default, filled, error, disabled.
|
|
85
|
+
- Overlay states such as dropdown, popover, modal, drawer, tooltip.
|
|
86
|
+
- Upload empty, has-file, uploading.
|
|
87
|
+
|
|
88
|
+
## Primitive selection guide
|
|
89
|
+
|
|
90
|
+
Use the smallest primitive that communicates the requirement:
|
|
91
|
+
|
|
92
|
+
- page shell: `rp-page`, `rp-main-view`, `rp-viewport`
|
|
93
|
+
- layout: `rp-layout`, `rp-panel`, `rp-card`
|
|
94
|
+
- navigation: `rp-navbar`, `rp-sidebar`, `rp-tabs`, `rp-breadcrumb`, `rp-pagination`, `rp-steps`
|
|
95
|
+
- data: `rp-table`, `rp-table-row`, `rp-list`, `rp-list-item`, `rp-stat-card`, `rp-tag`, `rp-badge`, `rp-avatar`
|
|
96
|
+
- forms: `rp-input`, `rp-search`, `rp-textarea`, `rp-select`, `rp-date-picker`, `rp-checkbox`, `rp-radio`, `rp-toggle`, `rp-form`, `rp-form-item`, `rp-upload`, `rp-button`
|
|
97
|
+
- states: `rp-empty`, `rp-loading`, `rp-alert`, `rp-toast`, `rp-progress`
|
|
98
|
+
- overlays: `rp-dropdown`, `rp-popover`, `rp-tooltip`, `rp-modal`, `rp-drawer`
|
|
99
|
+
|
|
100
|
+
Refer to `llms.txt` for the complete component attributes.
|
|
101
|
+
|
|
102
|
+
## Minimal template
|
|
103
|
+
|
|
104
|
+
```html
|
|
105
|
+
<!doctype html>
|
|
106
|
+
<html lang="zh-CN">
|
|
107
|
+
<head>
|
|
108
|
+
<meta charset="UTF-8" />
|
|
109
|
+
<script type="module" src="./dist/rpui.js"></script>
|
|
110
|
+
</head>
|
|
111
|
+
<body>
|
|
112
|
+
<rp-page title="页面标题" route="/route" description="页面说明">
|
|
113
|
+
<rp-main-view device="web" scale="0.65">
|
|
114
|
+
<rp-viewport device="web">
|
|
115
|
+
<!-- main snapshot -->
|
|
116
|
+
</rp-viewport>
|
|
117
|
+
</rp-main-view>
|
|
118
|
+
|
|
119
|
+
<rp-annotation id="1" label="区域说明">
|
|
120
|
+
简短说明此区域的职责。
|
|
121
|
+
<rp-enum>
|
|
122
|
+
<rp-enum-item label="默认" description="正常可用的数据态。"><rp-empty label="示例"></rp-empty></rp-enum-item>
|
|
123
|
+
<rp-enum-item label="加载中" description="首次进入或刷新时展示。"><rp-loading rows="3"></rp-loading></rp-enum-item>
|
|
124
|
+
<rp-enum-item label="错误" description="服务端或网络异常时展示。"><rp-alert type="error" title="加载失败" message="请重试"></rp-alert></rp-enum-item>
|
|
125
|
+
</rp-enum>
|
|
126
|
+
</rp-annotation>
|
|
127
|
+
</rp-page>
|
|
128
|
+
</body>
|
|
129
|
+
</html>
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
## Quality bar
|
|
133
|
+
|
|
134
|
+
A good RPUI prototype can be reviewed by engineering, product, design, and QA without running the real application. QA should be able to derive test cases from annotations. Engineering should be able to derive conditional rendering requirements from enum items. Design should be able to see whether hidden states were missed.
|
|
135
|
+
|
|
136
|
+
Before finishing, check:
|
|
137
|
+
|
|
138
|
+
- pin numbers are continuous and all have matching annotations,
|
|
139
|
+
- the main snapshot shows the most complex useful state,
|
|
140
|
+
- hidden interaction results are expanded into enums,
|
|
141
|
+
- role/permission differences are visible,
|
|
142
|
+
- annotations are compact and document-flow oriented,
|
|
143
|
+
- no forbidden direct product UI HTML, scripts, event handlers, or external resources are present.
|