@21stware/rpui 0.1.1 → 0.3.1
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 +47 -87
- package/dist/canvas/annotation.d.ts +6 -0
- package/dist/core/icons.d.ts +1 -1
- package/dist/core/style.d.ts +1 -1
- package/dist/gallery.d.ts +5 -0
- package/dist/gallery.js +2654 -0
- package/dist/gallery.js.map +1 -0
- package/dist/primitives/agent.d.ts +39 -0
- package/dist/primitives/controls.d.ts +21 -0
- package/dist/primitives/data-display.d.ts +75 -0
- package/dist/primitives/ios.d.ts +33 -0
- package/dist/primitives/layout.d.ts +9 -0
- package/dist/primitives/macos.d.ts +33 -0
- package/dist/primitives/navigation.d.ts +21 -0
- package/dist/rpml-loader.d.ts +2 -0
- package/dist/rpml-loader.js +27 -0
- package/dist/rpml-loader.js.map +1 -0
- package/dist/rpui.d.ts +2 -1
- package/dist/rpui.js +1769 -235
- package/dist/rpui.js.map +1 -1
- package/dist/serve/cli.d.ts +1 -0
- package/dist/serve.js +143 -0
- package/package.json +14 -22
- package/LICENSE +0 -20
- package/llms.txt +0 -195
- package/skill.txt +0 -143
package/dist/rpui.js
CHANGED
|
@@ -38,12 +38,12 @@ function resolveHeight(el, fallback) {
|
|
|
38
38
|
function isTopAnnotation(node) {
|
|
39
39
|
if (!(node instanceof HTMLElement)) return false;
|
|
40
40
|
const tag = node.tagName.toLowerCase();
|
|
41
|
-
return tag === "
|
|
41
|
+
return tag === "annotation-el" || tag === "annotation-el";
|
|
42
42
|
}
|
|
43
43
|
function isViewportNode(node) {
|
|
44
44
|
if (!(node instanceof HTMLElement)) return false;
|
|
45
45
|
const tag = node.tagName.toLowerCase();
|
|
46
|
-
return tag === "
|
|
46
|
+
return tag === "viewport-el" || tag === "viewport-el";
|
|
47
47
|
}
|
|
48
48
|
function define(name, ctor) {
|
|
49
49
|
if (customElements.get(name)) return;
|
|
@@ -51,205 +51,677 @@ function define(name, ctor) {
|
|
|
51
51
|
};
|
|
52
52
|
customElements.define(name, Alias);
|
|
53
53
|
}
|
|
54
|
+
const PRIMITIVES = [
|
|
55
|
+
// layout
|
|
56
|
+
"viewport",
|
|
57
|
+
"layout",
|
|
58
|
+
"panel",
|
|
59
|
+
"sidebar",
|
|
60
|
+
"logo",
|
|
61
|
+
"split-pane",
|
|
62
|
+
"divider",
|
|
63
|
+
"spacer",
|
|
64
|
+
// controls
|
|
65
|
+
"search",
|
|
66
|
+
"input",
|
|
67
|
+
"textarea",
|
|
68
|
+
"select",
|
|
69
|
+
"button",
|
|
70
|
+
"button-group",
|
|
71
|
+
"checkbox",
|
|
72
|
+
"radio",
|
|
73
|
+
"toggle",
|
|
74
|
+
"form",
|
|
75
|
+
"form-item",
|
|
76
|
+
"date-picker",
|
|
77
|
+
"upload",
|
|
78
|
+
"image-placeholder",
|
|
79
|
+
"progress",
|
|
80
|
+
"slider",
|
|
81
|
+
"range",
|
|
82
|
+
"number-input",
|
|
83
|
+
"rating",
|
|
84
|
+
"pin-input",
|
|
85
|
+
"color-swatch",
|
|
86
|
+
"autocomplete",
|
|
87
|
+
// navigation
|
|
88
|
+
"badge",
|
|
89
|
+
"avatar",
|
|
90
|
+
"list",
|
|
91
|
+
"list-item",
|
|
92
|
+
"tabs",
|
|
93
|
+
"tab",
|
|
94
|
+
"pagination",
|
|
95
|
+
"steps",
|
|
96
|
+
"breadcrumb",
|
|
97
|
+
"segmented",
|
|
98
|
+
"command-palette",
|
|
99
|
+
"context-menu",
|
|
100
|
+
"menu",
|
|
101
|
+
"menu-item",
|
|
102
|
+
"toc",
|
|
103
|
+
"kbd",
|
|
104
|
+
// data display
|
|
105
|
+
"table",
|
|
106
|
+
"table-row",
|
|
107
|
+
"bulk-action-bar",
|
|
108
|
+
"empty",
|
|
109
|
+
"loading",
|
|
110
|
+
"alert",
|
|
111
|
+
"toast",
|
|
112
|
+
"dropdown",
|
|
113
|
+
"popover",
|
|
114
|
+
"tooltip",
|
|
115
|
+
"modal",
|
|
116
|
+
"drawer",
|
|
117
|
+
"card",
|
|
118
|
+
"stat-card",
|
|
119
|
+
"tag",
|
|
120
|
+
"chip",
|
|
121
|
+
"tree",
|
|
122
|
+
"tree-item",
|
|
123
|
+
"timeline",
|
|
124
|
+
"timeline-item",
|
|
125
|
+
"calendar",
|
|
126
|
+
"kanban",
|
|
127
|
+
"kanban-column",
|
|
128
|
+
"kanban-card",
|
|
129
|
+
"code-block",
|
|
130
|
+
"diff",
|
|
131
|
+
"image-grid",
|
|
132
|
+
"key-value",
|
|
133
|
+
"kv-row",
|
|
134
|
+
"accordion",
|
|
135
|
+
"accordion-item",
|
|
136
|
+
"banner",
|
|
137
|
+
"skeleton",
|
|
138
|
+
"countdown",
|
|
139
|
+
"result",
|
|
140
|
+
"permission-gate",
|
|
141
|
+
"quota-bar",
|
|
142
|
+
"api-key",
|
|
143
|
+
"audit-row",
|
|
144
|
+
"workflow-node",
|
|
145
|
+
// iOS
|
|
146
|
+
"ios-navbar",
|
|
147
|
+
"ios-tabbar",
|
|
148
|
+
"ios-list",
|
|
149
|
+
"ios-list-item",
|
|
150
|
+
"ios-action-sheet",
|
|
151
|
+
"ios-alert",
|
|
152
|
+
"ios-switch",
|
|
153
|
+
"ios-segmented",
|
|
154
|
+
"ios-button",
|
|
155
|
+
"ios-search",
|
|
156
|
+
"ios-stepper",
|
|
157
|
+
// macOS
|
|
158
|
+
"macos-window",
|
|
159
|
+
"macos-toolbar",
|
|
160
|
+
"macos-menubar",
|
|
161
|
+
"macos-sidebar",
|
|
162
|
+
"macos-source-item",
|
|
163
|
+
"macos-segmented",
|
|
164
|
+
"macos-popover",
|
|
165
|
+
"macos-sheet",
|
|
166
|
+
"macos-stepper",
|
|
167
|
+
"macos-disclosure",
|
|
168
|
+
"macos-table",
|
|
169
|
+
// agent / conversational UI
|
|
170
|
+
"chat",
|
|
171
|
+
"user-message",
|
|
172
|
+
"assistant-message",
|
|
173
|
+
"system-message",
|
|
174
|
+
"tool-call",
|
|
175
|
+
"agent-output",
|
|
176
|
+
"reasoning",
|
|
177
|
+
"message-actions",
|
|
178
|
+
"suggestions",
|
|
179
|
+
"typing",
|
|
180
|
+
"composer",
|
|
181
|
+
"citation",
|
|
182
|
+
"token-usage"
|
|
183
|
+
];
|
|
184
|
+
function primitiveComponentTag(lang) {
|
|
185
|
+
return lang.includes("-") ? lang : `${lang}-el`;
|
|
186
|
+
}
|
|
187
|
+
const EXPLICIT = {
|
|
188
|
+
// canvas
|
|
189
|
+
page: "page-el",
|
|
190
|
+
view: "main-view",
|
|
191
|
+
annotation: "annotation-el",
|
|
192
|
+
enum: "enum-el",
|
|
193
|
+
"enum-item": "enum-item",
|
|
194
|
+
viewport: "viewport-el",
|
|
195
|
+
// curated primitive rename
|
|
196
|
+
navigator: "navbar-el"
|
|
197
|
+
};
|
|
198
|
+
const LANG_TO_COMPONENT = (() => {
|
|
199
|
+
const map = {};
|
|
200
|
+
for (const lang of PRIMITIVES) map[lang] = primitiveComponentTag(lang);
|
|
201
|
+
for (const [lang, comp] of Object.entries(EXPLICIT)) map[lang] = comp;
|
|
202
|
+
return map;
|
|
203
|
+
})();
|
|
204
|
+
(() => {
|
|
205
|
+
const map = {};
|
|
206
|
+
for (const [lang, comp] of Object.entries(LANG_TO_COMPONENT)) map[comp] = lang;
|
|
207
|
+
return map;
|
|
208
|
+
})();
|
|
209
|
+
function toComponentTag(tag) {
|
|
210
|
+
return LANG_TO_COMPONENT[tag.toLowerCase()] ?? tag;
|
|
211
|
+
}
|
|
212
|
+
function expandSelfClosing(source) {
|
|
213
|
+
return source.replace(
|
|
214
|
+
/<([a-zA-Z][\w:-]*)((?:"[^"]*"|'[^']*'|[^>"'])*?)\/>/g,
|
|
215
|
+
(_m, tag, attrs) => `<${tag}${attrs}></${tag}>`
|
|
216
|
+
);
|
|
217
|
+
}
|
|
218
|
+
function rewriteTags(source) {
|
|
219
|
+
return source.replace(
|
|
220
|
+
/<(\/?)([a-zA-Z][\w:-]*)((?:"[^"]*"|'[^']*'|[^>])*)>/g,
|
|
221
|
+
(_m, slash, tag, rest) => `<${slash}${toComponentTag(tag)}${rest}>`
|
|
222
|
+
);
|
|
223
|
+
}
|
|
224
|
+
function normalize(source) {
|
|
225
|
+
return rewriteTags(expandSelfClosing(source.trim()));
|
|
226
|
+
}
|
|
227
|
+
function parseToPage(source) {
|
|
228
|
+
const holder = document.createElement("div");
|
|
229
|
+
holder.innerHTML = normalize(source);
|
|
230
|
+
const root = holder.querySelector("page-el") ?? holder.firstElementChild;
|
|
231
|
+
if (!root) throw new Error("RPML parse error: no <page> root element found");
|
|
232
|
+
return root;
|
|
233
|
+
}
|
|
54
234
|
const RPUI_STYLE_ID = "rpui-runtime-style";
|
|
55
235
|
const style = `
|
|
56
236
|
: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; }
|
|
57
237
|
* { box-sizing:border-box; }
|
|
58
238
|
body { margin:0; font-family:var(--rp-font); color:var(--rp-text); background:var(--rp-bg); }
|
|
59
239
|
.rp-icon { display:inline-block; flex:0 0 auto; vertical-align:-0.16em; }
|
|
60
|
-
|
|
61
|
-
.
|
|
62
|
-
.
|
|
63
|
-
.
|
|
64
|
-
.
|
|
65
|
-
.
|
|
66
|
-
.
|
|
67
|
-
.
|
|
68
|
-
.
|
|
69
|
-
.
|
|
70
|
-
.
|
|
71
|
-
|
|
240
|
+
page-el, page-el { display:block; min-height:100vh; padding:32px 40px; overflow:auto; }
|
|
241
|
+
.page-el-shell { display:grid; grid-template-columns:max-content max-content; gap:24px; min-height:100vh; align-items:start; }
|
|
242
|
+
.page-el-main { display:flex; flex-direction:column; min-width:0; overflow:visible; }
|
|
243
|
+
.page-el-header { flex:0 0 auto; width:fit-content; max-width:none; margin:0 0 22px; }
|
|
244
|
+
.page-el-title-row { display:flex; align-items:baseline; gap:12px; flex-wrap:wrap; }
|
|
245
|
+
.page-el-title { margin:0; font-size:28px; line-height:1.2; letter-spacing:-.02em; }
|
|
246
|
+
.page-el-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; }
|
|
247
|
+
.page-el-description { margin:10px 0 0; color:#374151; line-height:1.6; font-size:14px; }
|
|
248
|
+
.page-el-body { flex:0 1 auto; display:block; width:fit-content; max-width:100%; min-height:0; overflow:visible; }
|
|
249
|
+
.annotation-el-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; }
|
|
250
|
+
.annotation-el-pane-inner { padding:4px 12px 24px 6px; }
|
|
251
|
+
main-view, main-view { display:block; width:fit-content; margin:0 0 28px; position:relative; }
|
|
72
252
|
.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); }
|
|
73
253
|
.rp-main-stage-clip { overflow:hidden; border-radius:var(--rp-radius-md); }
|
|
74
254
|
.rp-main-stage { position:relative; transform-origin:top left; background:var(--rp-surface); }
|
|
75
255
|
.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; }
|
|
76
256
|
.rp-pin > span { transform:rotate(45deg); }
|
|
77
257
|
.rp-pin:hover { opacity:0.85; }
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
.
|
|
81
|
-
.
|
|
82
|
-
.
|
|
83
|
-
.
|
|
84
|
-
.
|
|
85
|
-
.
|
|
86
|
-
.
|
|
87
|
-
.
|
|
88
|
-
.
|
|
89
|
-
.rp-
|
|
90
|
-
.
|
|
91
|
-
.
|
|
92
|
-
.
|
|
93
|
-
|
|
94
|
-
.
|
|
95
|
-
|
|
96
|
-
.
|
|
97
|
-
|
|
98
|
-
.
|
|
99
|
-
.
|
|
100
|
-
.
|
|
101
|
-
.
|
|
102
|
-
.
|
|
258
|
+
annotation-el, annotation-el { display:block; width:fit-content; max-width:980px; margin:14px 0; line-height:1.65; color:#1f2937; font-size:14px; }
|
|
259
|
+
annotation-el annotation-el, annotation-el annotation-el, annotation-el annotation-el, annotation-el annotation-el { margin:10px 0 8px 22px; }
|
|
260
|
+
.annotation-el-head { display:flex; align-items:center; gap:8px; margin:0 0 4px; width:fit-content; }
|
|
261
|
+
.annotation-el-title { font-weight:700; color:#111827; }
|
|
262
|
+
.annotation-el-marker { display:inline-grid; place-items:center; flex:0 0 auto; color:#fff; font-size:10px; font-weight:700; line-height:1; }
|
|
263
|
+
.annotation-el-marker.drop { width:22px; height:22px; background:var(--rp-primary); border-radius:50% 50% 50% 0; transform:rotate(-45deg); }
|
|
264
|
+
.annotation-el-marker.drop > span { transform:rotate(45deg); }
|
|
265
|
+
.annotation-el-marker.circle { width:16px; height:16px; background:var(--rp-purple); border-radius:50%; }
|
|
266
|
+
.annotation-el-marker.triangle { width:18px; height:16px; background:var(--rp-success); clip-path:polygon(50% 0, 100% 100%, 0 100%); }
|
|
267
|
+
.annotation-el-marker.triangle > span { transform:translateY(2px); font-size:9px; }
|
|
268
|
+
.annotation-el-body { display:block; position:relative; width:fit-content; max-width:920px; }
|
|
269
|
+
.rp-pin-slice { width:18px; height:18px; font-size:10px; box-shadow:0 1px 5px rgba(37,99,235,.3); }
|
|
270
|
+
.annotation-el-body > :not(annotation-el):not(annotation-el):not(enum-el):not(enum-el) { max-width:820px; }
|
|
271
|
+
.annotation-el-pane annotation-el, .annotation-el-pane annotation-el { max-width:none; }
|
|
272
|
+
.annotation-el-pane .annotation-el-body { max-width:none; }
|
|
273
|
+
.annotation-el-pane .annotation-el-body > :not(annotation-el):not(annotation-el):not(enum-el):not(enum-el) { max-width:420px; }
|
|
274
|
+
.annotation-el-body p { margin:0 0 8px; }
|
|
275
|
+
enum-el, enum-el { display:flex; align-items:flex-start; flex-wrap:wrap; gap:10px; width:fit-content; margin:8px 0 12px; }
|
|
276
|
+
.annotation-el-pane enum-el, .annotation-el-pane enum-el { flex-wrap:wrap; }
|
|
277
|
+
enum-item, 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; }
|
|
278
|
+
.enum-el-label { display:flex; align-items:flex-start; gap:6px; padding:5px 9px 4px; font-size:12px; font-weight:650; color:#374151; }
|
|
279
|
+
.enum-el-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; }
|
|
280
|
+
.enum-el-label-text { display:block; }
|
|
281
|
+
.enum-el-description { display:block; margin-top:2px; font-size:11px; line-height:1.35; font-weight:400; color:var(--rp-muted); }
|
|
282
|
+
.enum-el-content { display:block; width:fit-content; padding:8px; }
|
|
283
|
+
.annotation-el-title { font-weight:700; color:#111827; cursor:pointer; }
|
|
284
|
+
.annotation-el-title:hover { color:var(--rp-primary); }
|
|
103
285
|
.rp-section-focus { outline:2px dashed var(--rp-primary); outline-offset:4px; border-radius:4px; }
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
286
|
+
viewport-el, viewport-el { display:flex; flex-direction:column; width:var(--snap-width,1440px); height:var(--snap-height,900px); background:#f8fafc; overflow:hidden; color:#111827; }
|
|
287
|
+
layout-el, layout-el { 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; }
|
|
288
|
+
layout-el > *, layout-el > * { min-width:0; }
|
|
289
|
+
viewport-el layout-el, viewport-el layout-el { width:100%; }
|
|
290
|
+
viewport-el > layout-el, viewport-el > layout-el { flex:1 1 auto; min-height:0; }
|
|
291
|
+
viewport-el > navbar-el, viewport-el > navbar-el { flex:0 0 auto; }
|
|
292
|
+
panel-el, panel-el { 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); }
|
|
293
|
+
viewport-el panel-el, viewport-el panel-el { width:auto; min-width:0; }
|
|
294
|
+
panel-el[elevation="1"], panel-el[elevation="1"] { box-shadow:0 4px 16px rgba(15,23,42,.06); }
|
|
295
|
+
panel-el[elevation="2"], panel-el[elevation="2"] { box-shadow:var(--rp-shadow); }
|
|
296
|
+
navbar-el, navbar-el { display:flex; align-items:center; gap:14px; height:var(--snap-height,64px); padding:0 24px; background:#fff; border-bottom:1px solid var(--rp-border); }
|
|
297
|
+
sidebar-el, sidebar-el { display:block; width:var(--snap-width,260px); min-height:0; background:#fff; border-right:1px solid var(--rp-border); padding:14px; }
|
|
298
|
+
viewport-el sidebar-el, viewport-el sidebar-el { min-height:100%; }
|
|
299
|
+
sidebar-el[collapsed], sidebar-el[collapsed] { width:72px; }
|
|
300
|
+
logo-el, logo-el { 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; }
|
|
301
|
+
search-el, search-el, input-el, input-el, date-picker, 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; }
|
|
302
|
+
textarea-el, textarea-el { 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; }
|
|
303
|
+
search-el[state="focus"], search-el[state="focus"], input-el[state="focus"], input-el[state="focus"], textarea-el[state="focus"], textarea-el[state="focus"], date-picker[state="focus"], date-picker[state="focus"] { border-color:var(--rp-primary); box-shadow:0 0 0 3px rgba(37,99,235,.12); }
|
|
304
|
+
search-el[state="filled"], search-el[state="filled"], input-el[state="filled"], input-el[state="filled"], textarea-el[state="filled"], textarea-el[state="filled"], date-picker[state="filled"], date-picker[state="filled"] { border-color:#93c5fd; background:#f8fbff; }
|
|
305
|
+
search-el[state="error"], search-el[state="error"], input-el[state="error"], input-el[state="error"], textarea-el[state="error"], textarea-el[state="error"], date-picker[state="error"], date-picker[state="error"] { border-color:var(--rp-danger); box-shadow:0 0 0 3px rgba(220,38,38,.1); }
|
|
306
|
+
search-el[state="disabled"], search-el[state="disabled"], input-el[state="disabled"], input-el[state="disabled"], textarea-el[state="disabled"], textarea-el[state="disabled"], date-picker[state="disabled"], date-picker[state="disabled"] { opacity:.55; background:#f3f4f6; }
|
|
307
|
+
input-el[label], input-el[label], date-picker[label], 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; }
|
|
308
|
+
input-el[label][state="focus"], input-el[label][state="focus"], input-el[label][state="filled"], input-el[label][state="filled"], input-el[label][state="error"], input-el[label][state="error"], date-picker[label][state="focus"], date-picker[label][state="focus"], date-picker[label][state="filled"], date-picker[label][state="filled"], date-picker[label][state="error"], date-picker[label][state="error"] { border:0; background:transparent; box-shadow:none; }
|
|
127
309
|
.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; }
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
310
|
+
input-el[state="focus"] .rp-field-control, input-el[state="focus"] .rp-field-control, date-picker[state="focus"] .rp-field-control, date-picker[state="focus"] .rp-field-control { border-color:var(--rp-primary); box-shadow:0 0 0 3px rgba(37,99,235,.12); }
|
|
311
|
+
input-el[state="filled"] .rp-field-control, input-el[state="filled"] .rp-field-control, date-picker[state="filled"] .rp-field-control, date-picker[state="filled"] .rp-field-control { border-color:#93c5fd; background:#f8fbff; }
|
|
312
|
+
input-el[state="error"] .rp-field-control, input-el[state="error"] .rp-field-control, date-picker[state="error"] .rp-field-control, date-picker[state="error"] .rp-field-control { border-color:var(--rp-danger); box-shadow:0 0 0 3px rgba(220,38,38,.1); }
|
|
131
313
|
.rp-field-label { display:block; margin:0 0 6px; color:#374151; font-size:12px; font-weight:650; }
|
|
132
314
|
.rp-placeholder { color:#9ca3af; }
|
|
133
315
|
.rp-value { color:#111827; }
|
|
134
316
|
.rp-error-text { color:var(--rp-danger); font-size:12px; }
|
|
135
|
-
|
|
136
|
-
.
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
.
|
|
140
|
-
.
|
|
141
|
-
|
|
142
|
-
.
|
|
143
|
-
.
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
.
|
|
151
|
-
.
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
.
|
|
171
|
-
.
|
|
172
|
-
.
|
|
173
|
-
.
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
.
|
|
183
|
-
.
|
|
184
|
-
|
|
185
|
-
.
|
|
317
|
+
select-el, select-el { display:inline-block; width:280px; max-width:100%; }
|
|
318
|
+
.select-el-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; }
|
|
319
|
+
select-el[state="expanded"] .select-el-control, select-el[state="expanded"] .select-el-control { border-color:var(--rp-primary); box-shadow:0 0 0 3px rgba(37,99,235,.12); }
|
|
320
|
+
select-el[state="disabled"], select-el[state="disabled"] { opacity:.55; }
|
|
321
|
+
.select-el-value { flex:1 1 auto; min-width:0; }
|
|
322
|
+
.select-el-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); }
|
|
323
|
+
select-el[state="expanded"] .select-el-options, select-el[state="expanded"] .select-el-options { display:grid; gap:2px; }
|
|
324
|
+
.select-el-option { padding:7px 8px; border-radius:6px; font-size:13px; color:#374151; }
|
|
325
|
+
.select-el-option.selected { background:#eff6ff; color:#1d4ed8; font-weight:700; }
|
|
326
|
+
badge-el, badge-el { 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; }
|
|
327
|
+
avatar-el, avatar-el { 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; }
|
|
328
|
+
list-el, list-el { display:flex; flex-direction:column; gap:4px; width:100%; }
|
|
329
|
+
list-item, list-item { display:flex; align-items:center; gap:8px; width:100%; min-width:180px; height:36px; padding:0 10px; border-radius:8px; color:#374151; }
|
|
330
|
+
list-item[state="selected"], list-item[state="selected"] { background:#eff6ff; color:#1d4ed8; font-weight:700; }
|
|
331
|
+
list-item[state="disabled"], list-item[state="disabled"] { opacity:.5; }
|
|
332
|
+
.list-el-label { flex:1 1 auto; }
|
|
333
|
+
.list-el-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; }
|
|
334
|
+
tabs-el, tabs-el { display:flex; gap:6px; border-bottom:1px solid var(--rp-border); margin-bottom:12px; width:fit-content; }
|
|
335
|
+
tab-el, tab-el { display:inline-flex; align-items:center; gap:6px; padding:9px 13px; border-bottom:2px solid transparent; color:#6b7280; font-size:14px; }
|
|
336
|
+
tab-el.tab-el-active, tab-el.tab-el-active { color:var(--rp-primary); border-bottom-color:var(--rp-primary); font-weight:700; }
|
|
337
|
+
button-el, button-el { 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; }
|
|
338
|
+
button-el[size="sm"], button-el[size="sm"] { min-height:28px; padding:0 9px; font-size:12px; border-radius:6px; }
|
|
339
|
+
button-el[size="lg"], button-el[size="lg"] { min-height:40px; padding:0 16px; font-size:14px; }
|
|
340
|
+
button-el[variant="primary"], button-el[variant="primary"] { border-color:var(--rp-primary); background:var(--rp-primary); color:#fff; }
|
|
341
|
+
button-el[variant="secondary"], button-el[variant="secondary"] { border-color:#bfdbfe; background:#eff6ff; color:#1d4ed8; }
|
|
342
|
+
button-el[variant="danger"], button-el[variant="danger"] { border-color:var(--rp-danger); color:var(--rp-danger); }
|
|
343
|
+
button-el[variant="link"], button-el[variant="link"] { border-color:transparent; background:transparent; color:var(--rp-primary); padding-inline:2px; }
|
|
344
|
+
button-el[variant="ghost"], button-el[variant="ghost"] { border-color:transparent; background:transparent; }
|
|
345
|
+
button-el[state="disabled"], button-el[state="disabled"], button-el[disabled], button-el[disabled] { opacity:.5; }
|
|
346
|
+
button-group, button-group { display:inline-flex; gap:0; width:fit-content; }
|
|
347
|
+
button-group > button-el, button-group > button-el { border-radius:0; margin-left:-1px; }
|
|
348
|
+
button-group > :first-child { border-radius:8px 0 0 8px; margin-left:0; }
|
|
349
|
+
button-group > :last-child { border-radius:0 8px 8px 0; }
|
|
350
|
+
table-el, table-el { 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; }
|
|
351
|
+
viewport-el table-el, viewport-el table-el { width:100%; max-width:none; }
|
|
352
|
+
.table-row { display:table-row; }
|
|
353
|
+
.table-el-cell { display:table-cell; padding:11px 12px; border-bottom:1px solid var(--rp-border); font-size:13px; vertical-align:middle; white-space:nowrap; }
|
|
354
|
+
.table-el-head .table-el-cell { background:#f9fafb; color:#6b7280; font-size:12px; font-weight:750; }
|
|
355
|
+
.table-row:last-child .table-el-cell { border-bottom:0; }
|
|
356
|
+
table-row, 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; }
|
|
357
|
+
table-row > span, table-row > span { padding:10px 12px; font-size:13px; }
|
|
358
|
+
table-row[state="unread"], table-row[state="unread"] { background:#eff6ff; font-weight:700; }
|
|
359
|
+
table-row[state="selected"], table-row[state="selected"] { outline:2px solid rgba(37,99,235,.35); background:#f8fbff; }
|
|
360
|
+
table-row[state="highlighted"], table-row[state="highlighted"] { background:#fffbeb; }
|
|
361
|
+
table-row[state="disabled"], table-row[state="disabled"] { opacity:.5; }
|
|
362
|
+
bulk-action-bar, 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; }
|
|
363
|
+
empty-el, empty-el { 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; }
|
|
364
|
+
.empty-el-title { color:#111827; font-weight:700; }
|
|
365
|
+
.empty-el-desc { font-size:13px; }
|
|
366
|
+
loading-el, loading-el { display:grid; gap:8px; min-width:260px; color:var(--rp-primary); }
|
|
367
|
+
.skeleton-el-line { height:14px; border-radius:999px; background:linear-gradient(90deg,#f3f4f6,#e5e7eb,#f3f4f6); }
|
|
186
368
|
.rp-spinner { display:inline-grid; place-items:center; width:32px; height:32px; }
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
369
|
+
alert-el, alert-el, toast-el, toast-el { 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; }
|
|
370
|
+
alert-el[type="info"], alert-el[type="info"], toast-el[type="info"], toast-el[type="info"] { border-color:#bfdbfe; background:#eff6ff; color:#1e40af; }
|
|
371
|
+
alert-el[type="success"], alert-el[type="success"], toast-el[type="success"], toast-el[type="success"] { border-color:#bbf7d0; background:#f0fdf4; color:#166534; }
|
|
372
|
+
alert-el[type="warning"], alert-el[type="warning"], toast-el[type="warning"], toast-el[type="warning"] { border-color:#fde68a; background:#fffbeb; color:#92400e; }
|
|
373
|
+
alert-el[type="error"], alert-el[type="error"], toast-el[type="error"], toast-el[type="error"] { border-color:#fecaca; background:#fef2f2; color:#991b1b; }
|
|
374
|
+
dropdown-el, dropdown-el, popover-el, popover-el { 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); }
|
|
375
|
+
tooltip-el, tooltip-el { display:inline-block; width:fit-content; max-width:240px; padding:6px 8px; border-radius:6px; background:#111827; color:#fff; font-size:12px; }
|
|
194
376
|
.rp-overlay-title { margin:0 0 8px; color:#111827; font-size:14px; font-weight:750; }
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
.
|
|
198
|
-
.
|
|
199
|
-
.
|
|
200
|
-
|
|
201
|
-
.
|
|
202
|
-
.
|
|
203
|
-
.
|
|
204
|
-
.
|
|
205
|
-
|
|
377
|
+
modal-el, modal-el { 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; }
|
|
378
|
+
drawer-el, drawer-el { 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); }
|
|
379
|
+
.modal-el-head, .drawer-el-head { display:flex; align-items:center; justify-content:space-between; padding:14px 16px; border-bottom:1px solid var(--rp-border); font-weight:750; }
|
|
380
|
+
.modal-el-body, .drawer-el-body { padding:16px; }
|
|
381
|
+
.modal-el-footer { display:flex; justify-content:flex-end; gap:8px; padding:12px 16px; border-top:1px solid var(--rp-border); background:#f9fafb; }
|
|
382
|
+
card-el, card-el { display:block; width:auto; min-width:220px; padding:14px; border:1px solid var(--rp-border); border-radius:10px; background:#fff; }
|
|
383
|
+
.card-el-image { display:grid; place-items:center; height:120px; margin:-14px -14px 12px; border-radius:10px 10px 0 0; background:#f3f4f6; color:#6b7280; }
|
|
384
|
+
.card-el-title { display:block; color:#111827; font-weight:750; }
|
|
385
|
+
.card-el-subtitle { display:block; margin-top:4px; color:#6b7280; font-size:13px; }
|
|
386
|
+
.card-el-footer { display:block; margin:12px -14px -14px; padding:10px 14px; border-top:1px solid var(--rp-border); background:#f9fafb; }
|
|
387
|
+
stat-card, stat-card { display:grid; gap:6px; width:auto; min-width:0; padding:16px; border:1px solid var(--rp-border); border-radius:10px; background:#fff; }
|
|
206
388
|
.rp-stat-label { color:#6b7280; font-size:12px; font-weight:650; }
|
|
207
389
|
.rp-stat-value { color:#111827; font-size:26px; font-weight:800; }
|
|
208
390
|
.rp-stat-change { font-size:12px; font-weight:700; }
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
391
|
+
stat-card[trend="up"] .rp-stat-change, stat-card[trend="up"] .rp-stat-change { color:var(--rp-success); }
|
|
392
|
+
stat-card[trend="down"] .rp-stat-change, stat-card[trend="down"] .rp-stat-change { color:var(--rp-danger); }
|
|
393
|
+
tag-el, tag-el { 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; }
|
|
394
|
+
tag-el[color="green"], tag-el[color="green"] { background:#dcfce7; color:#166534; }
|
|
395
|
+
tag-el[color="orange"], tag-el[color="orange"] { background:#ffedd5; color:#9a3412; }
|
|
396
|
+
tag-el[color="red"], tag-el[color="red"] { background:#fee2e2; color:#991b1b; }
|
|
397
|
+
checkbox-el, checkbox-el, radio-el, radio-el { display:inline-flex; align-items:center; gap:8px; font-size:13px; }
|
|
216
398
|
.rp-box { display:inline-grid; place-items:center; width:16px; height:16px; border:1px solid var(--rp-border-strong); border-radius:4px; color:#fff; }
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
.
|
|
222
|
-
.
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
.
|
|
231
|
-
.
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
.
|
|
244
|
-
|
|
399
|
+
checkbox-el[state="checked"] .rp-box, checkbox-el[state="checked"] .rp-box, radio-el[state="checked"] .rp-box, radio-el[state="checked"] .rp-box, checkbox-el[state="indeterminate"] .rp-box, checkbox-el[state="indeterminate"] .rp-box { background:var(--rp-primary); border-color:var(--rp-primary); }
|
|
400
|
+
checkbox-el[state="disabled"], checkbox-el[state="disabled"], radio-el[state="disabled"], radio-el[state="disabled"] { opacity:.5; }
|
|
401
|
+
radio-el .rp-box, radio-el .rp-box { border-radius:999px; }
|
|
402
|
+
toggle-el, toggle-el { display:inline-flex; align-items:center; gap:8px; font-size:13px; }
|
|
403
|
+
.toggle-el-track { display:flex; align-items:center; width:34px; height:20px; border-radius:999px; background:#d1d5db; padding:2px; }
|
|
404
|
+
.toggle-el-dot { display:block; width:16px; height:16px; border-radius:999px; background:#fff; box-shadow:0 1px 2px rgba(0,0,0,.2); transition:none; }
|
|
405
|
+
toggle-el[state="on"] .toggle-el-track, toggle-el[state="on"] .toggle-el-track { background:var(--rp-primary); }
|
|
406
|
+
toggle-el[state="on"] .toggle-el-dot, toggle-el[state="on"] .toggle-el-dot { margin-left:14px; }
|
|
407
|
+
toggle-el[state="disabled"], toggle-el[state="disabled"] { opacity:.5; }
|
|
408
|
+
form-el, form-el { display:grid; gap:12px; width:fit-content; max-width:100%; }
|
|
409
|
+
form-el[layout="horizontal"], form-el[layout="horizontal"] { grid-template-columns:max-content 1fr; align-items:start; }
|
|
410
|
+
form-item, form-item { display:grid; gap:6px; width:fit-content; max-width:100%; }
|
|
411
|
+
form-item > *, form-item > * { max-width:100%; }
|
|
412
|
+
.form-el-label { color:#374151; font-size:12px; font-weight:700; }
|
|
413
|
+
.form-el-label.required::after { content:" *"; color:var(--rp-danger); }
|
|
414
|
+
.form-el-error { color:var(--rp-danger); font-size:12px; }
|
|
415
|
+
upload-el, upload-el { 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; }
|
|
416
|
+
upload-el[state="has-file"], upload-el[state="has-file"] { justify-items:start; border-style:solid; color:#374151; }
|
|
417
|
+
upload-el[state="uploading"], upload-el[state="uploading"] { border-color:#bfdbfe; background:#eff6ff; color:#1e40af; }
|
|
418
|
+
image-placeholder, 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; }
|
|
419
|
+
progress-el, progress-el { display:block; width:180px; height:8px; border-radius:999px; background:#e5e7eb; overflow:hidden; }
|
|
420
|
+
progress-el[kind="circle"], progress-el[kind="circle"], progress-el[style="circle"], progress-el[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; }
|
|
421
|
+
.progress-el-bar { display:block; height:100%; width:var(--progress,40%); background:var(--rp-primary); }
|
|
422
|
+
progress-el[status="success"] .progress-el-bar, progress-el[status="success"] .progress-el-bar { background:var(--rp-success); }
|
|
423
|
+
progress-el[status="error"] .progress-el-bar, progress-el[status="error"] .progress-el-bar { background:var(--rp-danger); }
|
|
424
|
+
pagination-el, pagination-el { display:inline-flex; align-items:center; gap:6px; width:fit-content; font-size:13px; }
|
|
425
|
+
.page-el-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; }
|
|
426
|
+
.page-el-btn.active { border-color:var(--rp-primary); background:var(--rp-primary); color:#fff; font-weight:750; }
|
|
427
|
+
steps-el, steps-el { display:flex; align-items:center; gap:8px; width:fit-content; }
|
|
245
428
|
.rp-step { display:inline-flex; align-items:center; gap:6px; color:#6b7280; font-size:13px; }
|
|
246
429
|
.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; }
|
|
247
430
|
.rp-step.active { color:var(--rp-primary); font-weight:750; }
|
|
248
431
|
.rp-step.active .rp-step-dot { border-color:var(--rp-primary); background:var(--rp-primary); color:#fff; }
|
|
249
432
|
.rp-step.done .rp-step-dot { border-color:var(--rp-success); background:var(--rp-success); color:#fff; }
|
|
250
433
|
.rp-step-sep { width:28px; height:1px; background:var(--rp-border); }
|
|
251
|
-
|
|
252
|
-
.
|
|
434
|
+
breadcrumb-el, breadcrumb-el { display:inline-flex; align-items:center; gap:6px; color:#6b7280; font-size:13px; }
|
|
435
|
+
.breadcrumb-el-current { color:#111827; font-weight:650; }
|
|
436
|
+
|
|
437
|
+
/* --- data input --- */
|
|
438
|
+
slider-el, slider-el { display:inline-flex; align-items:center; gap:10px; width:220px; }
|
|
439
|
+
.slider-el-track { position:relative; flex:1; height:4px; border-radius:999px; background:#e5e7eb; }
|
|
440
|
+
.slider-el-fill { position:absolute; height:100%; border-radius:999px; background:var(--rp-primary); }
|
|
441
|
+
.slider-el-thumb { position:absolute; top:50%; width:16px; height:16px; margin-left:-8px; transform:translateY(-50%); border-radius:50%; background:#fff; border:1px solid var(--rp-border-strong); }
|
|
442
|
+
.slider-el-value { font-size:12px; color:#374151; min-width:24px; }
|
|
443
|
+
range-el, range-el { display:inline-flex; align-items:center; width:220px; }
|
|
444
|
+
number-input, number-input { display:inline-flex; align-items:center; gap:6px; min-height:34px; padding:0 4px 0 11px; border:1px solid var(--rp-border-strong); border-radius:8px; background:#fff; width:120px; }
|
|
445
|
+
.rp-num-value { flex:1; font-size:13px; }
|
|
446
|
+
.rp-num-steppers { display:flex; flex-direction:column; }
|
|
447
|
+
.rp-num-step { display:grid; place-items:center; width:20px; height:15px; color:#6b7280; cursor:pointer; }
|
|
448
|
+
rating-el, rating-el { display:inline-flex; gap:2px; color:#d1d5db; }
|
|
449
|
+
.rp-star.filled { color:#f59e0b; }
|
|
450
|
+
pin-input, pin-input { display:inline-flex; gap:8px; }
|
|
451
|
+
.rp-pin-cell { display:grid; place-items:center; width:40px; height:46px; border:1px solid var(--rp-border-strong); border-radius:8px; font-size:18px; font-weight:700; background:#fff; }
|
|
452
|
+
.rp-pin-cell.active { border-color:var(--rp-primary); }
|
|
453
|
+
color-swatch, color-swatch { display:inline-flex; align-items:center; gap:8px; padding:4px 10px 4px 4px; border:1px solid var(--rp-border); border-radius:8px; background:#fff; }
|
|
454
|
+
.rp-swatch-chip { width:24px; height:24px; border-radius:6px; border:1px solid rgba(0,0,0,.1); }
|
|
455
|
+
.rp-swatch-hex { font-family:ui-monospace,Menlo,monospace; font-size:12px; color:#374151; }
|
|
456
|
+
autocomplete-el, autocomplete-el { display:inline-block; width:280px; }
|
|
457
|
+
.rp-ac-options { display:grid; gap:1px; margin-top:6px; padding:5px; border:1px solid var(--rp-border); border-radius:8px; background:#fff; }
|
|
458
|
+
.rp-ac-option { padding:7px 8px; border-radius:6px; font-size:13px; color:#374151; }
|
|
459
|
+
.rp-ac-option:first-child { background:#eff6ff; color:#1d4ed8; }
|
|
460
|
+
|
|
461
|
+
/* --- data display additions --- */
|
|
462
|
+
chip-el, chip-el { display:inline-flex; align-items:center; gap:5px; height:26px; padding:0 9px; border-radius:999px; border:1px solid var(--rp-border); background:#f9fafb; color:#374151; font-size:12px; }
|
|
463
|
+
tree-el, tree-el { display:flex; flex-direction:column; gap:1px; width:fit-content; min-width:240px; }
|
|
464
|
+
.tree-el-row { display:flex; align-items:center; gap:6px; padding:5px 8px; border-radius:6px; color:#374151; font-size:13px; padding-left:calc(8px + var(--tree-level,0) * 18px); }
|
|
465
|
+
.tree-el-row.selected { background:#eff6ff; color:#1d4ed8; font-weight:650; }
|
|
466
|
+
.tree-el-spacer { display:inline-block; width:12px; }
|
|
467
|
+
.tree-el-label { flex:1; }
|
|
468
|
+
timeline-el, timeline-el { display:flex; flex-direction:column; width:fit-content; min-width:260px; }
|
|
469
|
+
timeline-item, timeline-item { display:flex; gap:12px; padding-bottom:16px; position:relative; }
|
|
470
|
+
timeline-item:not(:last-child)::before, timeline-item:not(:last-child)::before { content:''; position:absolute; left:6px; top:16px; bottom:0; width:2px; background:var(--rp-border); }
|
|
471
|
+
.timeline-el-dot { flex:0 0 auto; width:14px; height:14px; margin-top:2px; border-radius:50%; background:#fff; border:2px solid var(--rp-border-strong); z-index:1; }
|
|
472
|
+
.timeline-el-dot.active { border-color:var(--rp-primary); background:var(--rp-primary); }
|
|
473
|
+
.timeline-el-dot.done { border-color:var(--rp-success); background:var(--rp-success); }
|
|
474
|
+
.timeline-el-dot.error { border-color:var(--rp-danger); background:var(--rp-danger); }
|
|
475
|
+
.timeline-el-main { flex:1; }
|
|
476
|
+
.timeline-el-head { display:flex; align-items:baseline; gap:8px; }
|
|
477
|
+
.timeline-el-label { font-weight:650; color:#111827; font-size:13px; }
|
|
478
|
+
.timeline-el-time { font-size:12px; color:#9ca3af; }
|
|
479
|
+
.timeline-el-content { font-size:13px; color:#6b7280; margin-top:2px; }
|
|
480
|
+
calendar-el, calendar-el { display:inline-block; width:280px; padding:12px; border:1px solid var(--rp-border); border-radius:10px; background:#fff; }
|
|
481
|
+
.rp-cal-head { text-align:center; font-weight:700; font-size:14px; margin-bottom:10px; }
|
|
482
|
+
.rp-cal-grid { display:grid; grid-template-columns:repeat(7,1fr); gap:2px; }
|
|
483
|
+
.rp-cal-dow { display:grid; place-items:center; height:24px; font-size:11px; color:#9ca3af; }
|
|
484
|
+
.rp-cal-cell { display:grid; place-items:center; height:32px; border-radius:6px; font-size:13px; color:#374151; }
|
|
485
|
+
.rp-cal-cell.selected { background:var(--rp-primary); color:#fff; font-weight:700; }
|
|
486
|
+
.rp-cal-cell.muted { color:transparent; }
|
|
487
|
+
kanban-el, kanban-el { display:flex; gap:12px; width:fit-content; align-items:flex-start; }
|
|
488
|
+
kanban-column, kanban-column { display:flex; flex-direction:column; width:200px; padding:10px; border-radius:10px; background:#f3f4f6; }
|
|
489
|
+
.kanban-el-head { display:flex; align-items:center; justify-content:space-between; font-weight:650; font-size:13px; margin-bottom:8px; color:#374151; }
|
|
490
|
+
.kanban-el-count { display:grid; place-items:center; min-width:18px; height:18px; padding:0 5px; border-radius:999px; background:#e5e7eb; font-size:11px; }
|
|
491
|
+
.kanban-el-body { display:flex; flex-direction:column; gap:8px; }
|
|
492
|
+
kanban-card, kanban-card { display:block; padding:10px; border-radius:8px; background:#fff; border:1px solid var(--rp-border); }
|
|
493
|
+
.kanban-card-title { display:block; font-size:13px; color:#111827; }
|
|
494
|
+
.kanban-card-tag { display:inline-block; margin-top:6px; padding:1px 7px; border-radius:999px; background:#eef2ff; color:#3730a3; font-size:11px; }
|
|
495
|
+
code-block, code-block { display:block; width:fit-content; min-width:320px; border:1px solid var(--rp-border); border-radius:8px; overflow:hidden; background:#0f172a; }
|
|
496
|
+
.rp-code-head { padding:6px 12px; font-family:ui-monospace,Menlo,monospace; font-size:11px; color:#94a3b8; background:#1e293b; }
|
|
497
|
+
.rp-code-body { padding:10px 0; }
|
|
498
|
+
.rp-code-line { display:flex; align-items:center; gap:12px; padding:1px 12px; }
|
|
499
|
+
.rp-code-ln { width:20px; text-align:right; color:#475569; font-family:ui-monospace,Menlo,monospace; font-size:11px; }
|
|
500
|
+
.rp-code-bar { height:8px; border-radius:3px; background:#334155; }
|
|
501
|
+
diff-el, diff-el { display:block; width:fit-content; min-width:320px; border:1px solid var(--rp-border); border-radius:8px; overflow:hidden; font-family:ui-monospace,Menlo,monospace; }
|
|
502
|
+
.diff-el-line { display:flex; align-items:center; gap:10px; padding:2px 10px; }
|
|
503
|
+
.diff-el-line.add { background:#dcfce7; }
|
|
504
|
+
.diff-el-line.del { background:#fee2e2; }
|
|
505
|
+
.diff-el-sign { width:10px; color:#6b7280; }
|
|
506
|
+
.diff-el-line.add .rp-code-bar { background:#86efac; }
|
|
507
|
+
.diff-el-line.del .rp-code-bar { background:#fca5a5; }
|
|
508
|
+
.diff-el-line.ctx .rp-code-bar { background:#e5e7eb; }
|
|
509
|
+
image-grid, image-grid { display:grid; grid-template-columns:repeat(var(--grid-cols,3),1fr); gap:8px; width:fit-content; }
|
|
510
|
+
.rp-grid-cell { display:grid; place-items:center; width:80px; height:80px; border-radius:8px; background:#f3f4f6; color:#9ca3af; }
|
|
511
|
+
key-value, key-value { display:flex; flex-direction:column; width:fit-content; min-width:240px; border:1px solid var(--rp-border); border-radius:8px; overflow:hidden; }
|
|
512
|
+
kv-row, kv-row { display:flex; border-bottom:1px solid var(--rp-border); }
|
|
513
|
+
kv-row:last-child, kv-row:last-child { border-bottom:0; }
|
|
514
|
+
.rp-kv-key { width:120px; padding:8px 12px; background:#f9fafb; color:#6b7280; font-size:13px; }
|
|
515
|
+
.rp-kv-val { flex:1; padding:8px 12px; color:#111827; font-size:13px; }
|
|
516
|
+
accordion-el, accordion-el { display:flex; flex-direction:column; width:fit-content; min-width:320px; border:1px solid var(--rp-border); border-radius:8px; overflow:hidden; }
|
|
517
|
+
accordion-item, accordion-item { display:block; border-bottom:1px solid var(--rp-border); }
|
|
518
|
+
accordion-item:last-child, accordion-item:last-child { border-bottom:0; }
|
|
519
|
+
.accordion-el-head { display:flex; align-items:center; gap:8px; padding:11px 14px; font-weight:650; font-size:13px; color:#111827; }
|
|
520
|
+
.accordion-el-body { padding:0 14px 14px 36px; font-size:13px; color:#6b7280; }
|
|
521
|
+
banner-el, banner-el { display:flex; align-items:center; gap:10px; width:fit-content; min-width:480px; padding:12px 16px; border-radius:8px; font-size:13px; background:#eff6ff; color:#1e40af; border:1px solid #bfdbfe; }
|
|
522
|
+
banner-el[type="success"], banner-el[type="success"] { background:#f0fdf4; color:#166534; border-color:#bbf7d0; }
|
|
523
|
+
banner-el[type="warning"], banner-el[type="warning"] { background:#fffbeb; color:#92400e; border-color:#fde68a; }
|
|
524
|
+
banner-el[type="error"], banner-el[type="error"] { background:#fef2f2; color:#991b1b; border-color:#fecaca; }
|
|
525
|
+
.banner-el-text { flex:1; }
|
|
526
|
+
skeleton-el, skeleton-el { display:flex; flex-direction:column; gap:8px; width:fit-content; min-width:240px; }
|
|
527
|
+
.rp-skel { border-radius:8px; background:linear-gradient(90deg,#f3f4f6,#e5e7eb,#f3f4f6); }
|
|
528
|
+
.rp-skel-block { height:120px; }
|
|
529
|
+
.rp-skel-avatar { width:40px; height:40px; border-radius:50%; }
|
|
530
|
+
.rp-skel-avatar.sm { width:28px; height:28px; }
|
|
531
|
+
.rp-skel-row { display:flex; align-items:center; gap:10px; }
|
|
532
|
+
countdown-el, countdown-el { display:inline-flex; align-items:center; gap:5px; padding:3px 9px; border-radius:999px; background:#fef2f2; color:#991b1b; font-size:12px; font-weight:650; font-variant-numeric:tabular-nums; }
|
|
533
|
+
result-el, result-el { display:grid; justify-items:center; gap:8px; width:fit-content; min-width:280px; padding:32px; text-align:center; }
|
|
534
|
+
.result-el-icon.success { color:var(--rp-success); }
|
|
535
|
+
.result-el-icon.error { color:var(--rp-danger); }
|
|
536
|
+
.result-el-icon.empty { color:#9ca3af; }
|
|
537
|
+
.result-el-title { font-size:16px; font-weight:700; color:#111827; }
|
|
538
|
+
.result-el-desc { font-size:13px; color:#6b7280; }
|
|
539
|
+
permission-gate, permission-gate { display:block; position:relative; width:fit-content; }
|
|
540
|
+
.rp-gate-content { opacity:.4; filter:grayscale(1); pointer-events:none; }
|
|
541
|
+
.rp-gate-overlay { position:absolute; inset:0; display:flex; align-items:center; justify-content:center; gap:6px; background:rgba(255,255,255,.6); color:#6b7280; font-size:12px; font-weight:650; border-radius:8px; }
|
|
542
|
+
quota-bar, quota-bar { display:block; width:fit-content; min-width:240px; }
|
|
543
|
+
.rp-quota-head { display:flex; justify-content:space-between; font-size:12px; color:#374151; margin-bottom:5px; }
|
|
544
|
+
.rp-quota-num.danger { color:var(--rp-danger); font-weight:700; }
|
|
545
|
+
.rp-quota-track { display:block; height:8px; border-radius:999px; background:#e5e7eb; overflow:hidden; }
|
|
546
|
+
.rp-quota-fill { display:block; height:100%; background:var(--rp-primary); }
|
|
547
|
+
.rp-quota-fill.danger { background:var(--rp-danger); }
|
|
548
|
+
api-key, api-key { display:inline-flex; align-items:center; gap:8px; padding:6px 8px 6px 12px; border:1px solid var(--rp-border); border-radius:8px; background:#f9fafb; }
|
|
549
|
+
.rp-apikey-val { font-family:ui-monospace,Menlo,monospace; font-size:12px; color:#374151; }
|
|
550
|
+
.rp-apikey-copy { display:grid; place-items:center; width:26px; height:26px; border-radius:6px; color:#6b7280; }
|
|
551
|
+
audit-row, audit-row { display:flex; align-items:baseline; gap:8px; padding:8px 0; border-bottom:1px solid var(--rp-border); width:fit-content; min-width:320px; font-size:13px; }
|
|
552
|
+
.rp-audit-actor { font-weight:650; color:#111827; }
|
|
553
|
+
.rp-audit-action { flex:1; color:#6b7280; }
|
|
554
|
+
.rp-audit-time { color:#9ca3af; font-size:12px; }
|
|
555
|
+
workflow-node, workflow-node { display:inline-flex; align-items:center; gap:7px; padding:7px 12px; border:1px solid var(--rp-border); border-radius:8px; background:#fff; font-size:13px; }
|
|
556
|
+
.rp-wf-icon.done { color:var(--rp-success); }
|
|
557
|
+
.rp-wf-icon.active { color:var(--rp-primary); }
|
|
558
|
+
.rp-wf-icon.error { color:var(--rp-danger); }
|
|
559
|
+
.rp-wf-icon.default { color:#9ca3af; }
|
|
560
|
+
|
|
561
|
+
/* --- navigation & layout additions --- */
|
|
562
|
+
segmented-el, segmented-el { display:inline-flex; padding:2px; border-radius:8px; background:#f3f4f6; gap:2px; }
|
|
563
|
+
.rp-seg-item { padding:5px 14px; border-radius:6px; font-size:13px; color:#6b7280; }
|
|
564
|
+
.rp-seg-item.active { background:#fff; color:#111827; font-weight:650; }
|
|
565
|
+
command-palette, command-palette { display:block; width:520px; border:1px solid var(--rp-border); border-radius:12px; background:#fff; overflow:hidden; }
|
|
566
|
+
.rp-cmdk-input { display:flex; align-items:center; gap:10px; padding:14px 16px; border-bottom:1px solid var(--rp-border); }
|
|
567
|
+
.rp-cmdk-list { padding:6px; }
|
|
568
|
+
.rp-cmdk-item { display:flex; align-items:center; gap:10px; padding:9px 10px; border-radius:8px; font-size:13px; color:#374151; }
|
|
569
|
+
.rp-cmdk-item.active { background:#eff6ff; color:#1d4ed8; }
|
|
570
|
+
context-menu, context-menu, menu-el, menu-el { display:inline-flex; flex-direction:column; min-width:180px; padding:5px; border:1px solid var(--rp-border); border-radius:10px; background:#fff; }
|
|
571
|
+
.menu-item, menu-item, menu-item { display:flex; align-items:center; gap:8px; padding:7px 10px; border-radius:6px; font-size:13px; color:#374151; }
|
|
572
|
+
.menu-item.danger, menu-item.danger, menu-item.danger { color:var(--rp-danger); }
|
|
573
|
+
.menu-item.disabled, menu-item.disabled, menu-item.disabled { opacity:.45; }
|
|
574
|
+
.menu-el-label { flex:1; }
|
|
575
|
+
.menu-el-shortcut { color:#9ca3af; font-size:12px; }
|
|
576
|
+
toc-el, toc-el { display:flex; flex-direction:column; gap:2px; width:fit-content; min-width:160px; border-left:2px solid var(--rp-border); }
|
|
577
|
+
.toc-el-item { padding:4px 12px; font-size:13px; color:#6b7280; border-left:2px solid transparent; margin-left:-2px; }
|
|
578
|
+
.toc-el-item.active { color:var(--rp-primary); border-left-color:var(--rp-primary); font-weight:650; }
|
|
579
|
+
kbd-el, kbd-el { display:inline-flex; align-items:center; gap:3px; }
|
|
580
|
+
.kbd-el-key { display:inline-grid; place-items:center; min-width:20px; height:20px; padding:0 5px; border:1px solid var(--rp-border-strong); border-bottom-width:2px; border-radius:5px; background:#f9fafb; font-size:11px; font-family:var(--rp-font); color:#374151; }
|
|
581
|
+
.kbd-el-plus { color:#9ca3af; font-size:11px; }
|
|
582
|
+
split-pane, split-pane { display:grid; grid-template-columns:var(--snap-columns,1fr 1fr); width:fit-content; border:1px solid var(--rp-border); border-radius:8px; overflow:hidden; }
|
|
583
|
+
split-pane > *, split-pane > * { padding:14px; }
|
|
584
|
+
split-pane > *:not(:last-child), split-pane > *:not(:last-child) { border-right:1px solid var(--rp-border); }
|
|
585
|
+
divider-el, divider-el { display:block; height:1px; background:var(--rp-border); margin:12px 0; }
|
|
586
|
+
divider-el.divider-el-v, divider-el.divider-el-v { display:inline-block; width:1px; height:auto; align-self:stretch; margin:0 12px; }
|
|
587
|
+
spacer-el, spacer-el { display:block; height:var(--snap-size,16px); }
|
|
588
|
+
|
|
589
|
+
/* --- iOS --- */
|
|
590
|
+
ios-navbar, ios-navbar { display:block; background:rgba(249,249,249,.94); border-bottom:1px solid #d8d8dc; padding:6px 12px; font-family:-apple-system,BlinkMacSystemFont,sans-serif; }
|
|
591
|
+
.ios-navbar-row { display:grid; grid-template-columns:1fr auto 1fr; align-items:center; min-height:36px; }
|
|
592
|
+
.rp-ios-nav-leading { display:flex; align-items:center; gap:2px; color:#007aff; font-size:15px; }
|
|
593
|
+
.rp-ios-nav-title { text-align:center; font-weight:600; font-size:16px; color:#000; }
|
|
594
|
+
.rp-ios-nav-trailing { text-align:right; color:#007aff; font-size:15px; }
|
|
595
|
+
.rp-ios-nav-large { font-size:30px; font-weight:700; color:#000; padding:2px 2px 6px; }
|
|
596
|
+
ios-tabbar, ios-tabbar { display:flex; background:rgba(249,249,249,.94); border-top:1px solid #d8d8dc; padding:6px 0 4px; }
|
|
597
|
+
.rp-ios-tab { flex:1; display:flex; flex-direction:column; align-items:center; gap:2px; color:#8e8e93; font-size:10px; }
|
|
598
|
+
.rp-ios-tab.active { color:#007aff; }
|
|
599
|
+
.rp-ios-tab-label { font-size:10px; }
|
|
600
|
+
ios-list, ios-list { display:block; border-radius:10px; background:#fff; overflow:hidden; width:fit-content; min-width:300px; border:1px solid #e5e5ea; font-family:-apple-system,sans-serif; }
|
|
601
|
+
.ios-list-header { padding:6px 16px; font-size:13px; color:#6d6d72; background:#f2f2f7; text-transform:none; }
|
|
602
|
+
ios-list-item, ios-list-item { display:flex; align-items:center; gap:10px; padding:11px 16px; border-bottom:1px solid #e5e5ea; font-size:15px; color:#000; }
|
|
603
|
+
ios-list-item:last-child, ios-list-item:last-child { border-bottom:0; }
|
|
604
|
+
.rp-ios-li-icon { display:grid; place-items:center; width:28px; height:28px; border-radius:6px; background:#007aff; color:#fff; }
|
|
605
|
+
.rp-ios-li-label { flex:1; }
|
|
606
|
+
.rp-ios-li-detail { color:#8e8e93; }
|
|
607
|
+
.rp-ios-li-chevron { color:#c7c7cc; }
|
|
608
|
+
ios-action-sheet, ios-action-sheet { display:flex; flex-direction:column; gap:8px; width:fit-content; min-width:320px; padding:8px; font-family:-apple-system,sans-serif; }
|
|
609
|
+
.rp-ios-as-group { border-radius:14px; overflow:hidden; background:rgba(255,255,255,.82); backdrop-filter:blur(20px); }
|
|
610
|
+
.rp-ios-as-title { padding:14px; text-align:center; font-size:13px; color:#8e8e93; border-bottom:1px solid #d1d1d6; }
|
|
611
|
+
.rp-ios-as-action { padding:16px; text-align:center; font-size:18px; color:#007aff; border-bottom:1px solid #d1d1d6; }
|
|
612
|
+
.rp-ios-as-action:last-child { border-bottom:0; }
|
|
613
|
+
.rp-ios-as-action.destructive { color:#ff3b30; }
|
|
614
|
+
.rp-ios-as-action.cancel { font-weight:600; }
|
|
615
|
+
ios-alert, ios-alert { display:block; width:270px; border-radius:14px; overflow:hidden; background:rgba(255,255,255,.92); backdrop-filter:blur(20px); font-family:-apple-system,sans-serif; }
|
|
616
|
+
.ios-alert-body { padding:18px 16px 14px; text-align:center; }
|
|
617
|
+
.ios-alert-title { font-size:17px; font-weight:600; color:#000; }
|
|
618
|
+
.ios-alert-msg { margin-top:3px; font-size:13px; color:#000; }
|
|
619
|
+
.ios-alert-actions { display:flex; border-top:1px solid #d1d1d6; }
|
|
620
|
+
.ios-alert-btn { flex:1; padding:11px; text-align:center; font-size:17px; color:#007aff; }
|
|
621
|
+
.ios-alert-btn.primary { font-weight:600; }
|
|
622
|
+
.ios-alert-btn:not(:last-child) { border-right:1px solid #d1d1d6; }
|
|
623
|
+
ios-switch, ios-switch { display:inline-flex; align-items:center; gap:8px; font-family:-apple-system,sans-serif; font-size:15px; }
|
|
624
|
+
.ios-switch-track { width:51px; height:31px; border-radius:999px; background:#34c759; padding:2px; }
|
|
625
|
+
.ios-switch-dot { display:block; width:27px; height:27px; border-radius:50%; background:#fff; margin-left:20px; }
|
|
626
|
+
ios-segmented, ios-segmented { display:inline-flex; padding:2px; border-radius:9px; background:#767680; background:rgba(118,118,128,.12); gap:2px; font-family:-apple-system,sans-serif; }
|
|
627
|
+
.rp-ios-seg-item { padding:6px 16px; border-radius:7px; font-size:13px; color:#000; }
|
|
628
|
+
.rp-ios-seg-item.active { background:#fff; font-weight:600; }
|
|
629
|
+
ios-button, ios-button { display:inline-grid; place-items:center; min-height:34px; padding:0 16px; border-radius:8px; background:#007aff; color:#fff; font-size:15px; font-weight:600; font-family:-apple-system,sans-serif; }
|
|
630
|
+
ios-button[variant="tinted"], ios-button[variant="tinted"] { background:rgba(0,122,255,.15); color:#007aff; }
|
|
631
|
+
ios-button[variant="plain"], ios-button[variant="plain"] { background:transparent; color:#007aff; }
|
|
632
|
+
ios-search, ios-search { display:inline-flex; align-items:center; gap:6px; width:280px; height:36px; padding:0 10px; border-radius:10px; background:rgba(118,118,128,.12); color:#8e8e93; font-size:15px; font-family:-apple-system,sans-serif; }
|
|
633
|
+
ios-stepper, ios-stepper { display:inline-flex; align-items:center; border-radius:8px; background:rgba(118,118,128,.12); }
|
|
634
|
+
.rp-ios-step { display:grid; place-items:center; width:46px; height:32px; color:#000; }
|
|
635
|
+
.rp-ios-step-div { width:1px; height:18px; background:rgba(0,0,0,.15); }
|
|
636
|
+
|
|
637
|
+
/* --- macOS --- */
|
|
638
|
+
macos-window, macos-window { display:block; width:fit-content; min-width:480px; border-radius:10px; overflow:hidden; border:1px solid #d1d1d6; background:#fff; font-family:-apple-system,sans-serif; }
|
|
639
|
+
.rp-mac-titlebar { display:flex; align-items:center; gap:10px; height:38px; padding:0 14px; background:#ececec; border-bottom:1px solid #d1d1d6; }
|
|
640
|
+
.rp-mac-lights { display:flex; gap:8px; }
|
|
641
|
+
.rp-mac-light { width:12px; height:12px; border-radius:50%; }
|
|
642
|
+
.rp-mac-light.close { background:#ff5f57; }
|
|
643
|
+
.rp-mac-light.min { background:#febc2e; }
|
|
644
|
+
.rp-mac-light.max { background:#28c840; }
|
|
645
|
+
.rp-mac-title { flex:1; text-align:center; font-size:13px; font-weight:600; color:#3c3c43; }
|
|
646
|
+
.rp-mac-window-body { padding:0; }
|
|
647
|
+
macos-toolbar, macos-toolbar { display:flex; align-items:center; gap:10px; padding:8px 14px; background:#f6f6f6; border-bottom:1px solid #d1d1d6; }
|
|
648
|
+
macos-menubar, macos-menubar { display:flex; align-items:center; gap:18px; height:26px; padding:0 14px; background:rgba(246,246,246,.9); border-bottom:1px solid #d1d1d6; font-size:13px; font-family:-apple-system,sans-serif; }
|
|
649
|
+
.rp-mac-menubar-apple { color:#000; }
|
|
650
|
+
.rp-mac-menu-title { color:#000; }
|
|
651
|
+
.rp-mac-menu-title.active { background:#007aff; color:#fff; padding:1px 7px; border-radius:4px; }
|
|
652
|
+
macos-sidebar, macos-sidebar { display:flex; flex-direction:column; gap:1px; width:220px; padding:8px; background:rgba(246,246,246,.85); font-family:-apple-system,sans-serif; }
|
|
653
|
+
macos-source-item, macos-source-item { display:flex; align-items:center; gap:7px; padding:5px 8px; border-radius:6px; font-size:13px; color:#3c3c43; }
|
|
654
|
+
macos-source-item.selected, macos-source-item.selected { background:#007aff; color:#fff; }
|
|
655
|
+
.rp-mac-source-group { padding:8px 8px 3px; font-size:11px; font-weight:700; color:#8e8e93; text-transform:uppercase; }
|
|
656
|
+
macos-segmented, macos-segmented { display:inline-flex; border:1px solid #c4c4c7; border-radius:6px; overflow:hidden; font-family:-apple-system,sans-serif; }
|
|
657
|
+
.rp-mac-seg-item { padding:4px 14px; font-size:13px; color:#000; background:#fff; border-right:1px solid #c4c4c7; }
|
|
658
|
+
.rp-mac-seg-item:last-child { border-right:0; }
|
|
659
|
+
.rp-mac-seg-item.active { background:#007aff; color:#fff; }
|
|
660
|
+
macos-popover, macos-popover { display:inline-block; position:relative; }
|
|
661
|
+
.rp-mac-pop-arrow { display:block; width:16px; height:8px; margin:0 auto -1px; clip-path:polygon(50% 0,100% 100%,0 100%); background:#fff; border:1px solid #d1d1d6; }
|
|
662
|
+
.rp-mac-pop-body { min-width:220px; padding:12px; border-radius:10px; border:1px solid #d1d1d6; background:#fff; }
|
|
663
|
+
.rp-mac-pop-title { font-weight:600; font-size:13px; margin-bottom:8px; }
|
|
664
|
+
macos-sheet, macos-sheet { display:block; width:fit-content; min-width:420px; border-radius:10px; background:#fff; box-shadow:0 24px 60px rgba(0,0,0,.3); padding:18px; font-family:-apple-system,sans-serif; }
|
|
665
|
+
.rp-mac-sheet-title { font-size:15px; font-weight:700; margin-bottom:12px; }
|
|
666
|
+
.rp-mac-sheet-actions { display:flex; justify-content:flex-end; gap:8px; margin-top:16px; }
|
|
667
|
+
macos-stepper, macos-stepper { display:inline-flex; flex-direction:column; border:1px solid #c4c4c7; border-radius:5px; overflow:hidden; }
|
|
668
|
+
.rp-mac-step { display:grid; place-items:center; width:22px; height:13px; background:#fff; color:#3c3c43; }
|
|
669
|
+
.rp-mac-step.up { border-bottom:1px solid #c4c4c7; }
|
|
670
|
+
macos-disclosure, macos-disclosure { display:block; font-family:-apple-system,sans-serif; }
|
|
671
|
+
.rp-mac-disc-head { display:flex; align-items:center; gap:5px; font-size:13px; font-weight:600; color:#000; }
|
|
672
|
+
.rp-mac-disc-tri { display:inline-flex; transition:none; }
|
|
673
|
+
.rp-mac-disc-tri.open { transform:rotate(90deg); }
|
|
674
|
+
.rp-mac-disc-body { padding:8px 0 0 18px; font-size:13px; color:#3c3c43; }
|
|
675
|
+
macos-table, macos-table { display:flex; flex-direction:column; width:fit-content; min-width:360px; border:1px solid #d1d1d6; border-radius:6px; overflow:hidden; font-family:-apple-system,sans-serif; }
|
|
676
|
+
.rp-mac-tr { display:flex; }
|
|
677
|
+
.rp-mac-tr.rp-mac-th { background:#f6f6f6; border-bottom:1px solid #d1d1d6; font-size:12px; font-weight:600; color:#3c3c43; }
|
|
678
|
+
.rp-mac-tr.alt { background:#f5f8ff; }
|
|
679
|
+
.rp-mac-td { flex:1; display:flex; align-items:center; gap:6px; padding:6px 12px; font-size:13px; color:#3c3c43; }
|
|
680
|
+
.rp-mac-cell-bar { height:8px; border-radius:3px; background:#e5e7eb; }
|
|
681
|
+
|
|
682
|
+
/* --- agent / conversational UI (Codex-style: single column, de-bubbled) --- */
|
|
683
|
+
chat-el, chat-el { display:flex; flex-direction:column; gap:24px; width:fit-content; min-width:520px; max-width:680px; }
|
|
684
|
+
user-message, user-message, assistant-message, assistant-message { display:block; }
|
|
685
|
+
.rp-msg-role { font-size:12px; font-weight:700; color:#9ca3af; letter-spacing:.02em; margin:0 0 6px; }
|
|
686
|
+
.rp-msg-content { display:flex; flex-direction:column; gap:12px; font-size:14px; line-height:1.7; color:#1f2937; }
|
|
687
|
+
user-message .rp-msg-content, user-message .rp-msg-content { color:#111827; }
|
|
688
|
+
system-message, system-message { display:flex; justify-content:center; }
|
|
689
|
+
.rp-sysmsg-line { padding:3px 12px; border-radius:999px; background:#f3f4f6; color:#6b7280; font-size:12px; }
|
|
690
|
+
tool-call, tool-call { display:block; width:fit-content; min-width:280px; max-width:600px; }
|
|
691
|
+
.rp-tool-head { display:flex; align-items:center; gap:8px; font-size:13px; color:#6b7280; }
|
|
692
|
+
.rp-tool-glyph { display:inline-flex; }
|
|
693
|
+
.rp-tool-glyph.done { color:var(--rp-success); }
|
|
694
|
+
.rp-tool-glyph.running { color:var(--rp-primary); }
|
|
695
|
+
.rp-tool-glyph.error { color:var(--rp-danger); }
|
|
696
|
+
.rp-tool-name { font-family:ui-monospace,Menlo,monospace; font-weight:650; color:#374151; }
|
|
697
|
+
.rp-tool-args-inline { font-family:ui-monospace,Menlo,monospace; color:#9ca3af; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
|
|
698
|
+
.rp-tool-body { margin-top:8px; padding-left:21px; }
|
|
699
|
+
agent-output, agent-output { display:block; width:fit-content; min-width:280px; max-width:600px; border:1px solid var(--rp-border); border-radius:8px; overflow:hidden; background:#f8fafc; }
|
|
700
|
+
.rp-output-head { padding:6px 12px; font-size:12px; color:#6b7280; border-bottom:1px solid var(--rp-border); font-family:ui-monospace,Menlo,monospace; }
|
|
701
|
+
.rp-output-body { padding:12px; font-family:ui-monospace,Menlo,monospace; font-size:12.5px; line-height:1.6; color:#334155; white-space:pre-wrap; }
|
|
702
|
+
reasoning-el, reasoning-el { display:block; width:fit-content; min-width:280px; max-width:600px; }
|
|
703
|
+
.rp-reason-head { display:flex; align-items:center; gap:6px; font-size:13px; color:#9ca3af; }
|
|
704
|
+
.rp-reason-body { margin-top:8px; padding-left:19px; border-left:2px solid var(--rp-border); font-size:13px; line-height:1.7; color:#6b7280; }
|
|
705
|
+
message-actions, message-actions { display:inline-flex; gap:2px; }
|
|
706
|
+
.rp-msg-action { display:grid; place-items:center; width:28px; height:28px; border-radius:6px; color:#9ca3af; cursor:pointer; }
|
|
707
|
+
.rp-msg-action:hover { background:#f3f4f6; color:#374151; }
|
|
708
|
+
suggestions-el, suggestions-el { display:flex; flex-wrap:wrap; gap:8px; }
|
|
709
|
+
.rp-suggestion { padding:7px 13px; border:1px solid var(--rp-border); border-radius:8px; font-size:13px; color:#374151; background:#fff; cursor:pointer; }
|
|
710
|
+
.rp-suggestion:hover { border-color:var(--rp-border-strong); background:#f9fafb; }
|
|
711
|
+
typing-el, typing-el { display:flex; align-items:center; }
|
|
712
|
+
.typing-el-dots { display:inline-flex; gap:4px; }
|
|
713
|
+
.typing-el-dots > span { width:7px; height:7px; border-radius:50%; background:#c7c7cc; }
|
|
714
|
+
composer-el, composer-el { display:flex; align-items:center; gap:10px; width:fit-content; min-width:520px; max-width:680px; padding:9px 9px 9px 14px; border:1px solid var(--rp-border-strong); border-radius:14px; background:#fff; }
|
|
715
|
+
.composer-el-attach { display:inline-flex; color:#9ca3af; }
|
|
716
|
+
.composer-el-input { flex:1; font-size:14px; }
|
|
717
|
+
.composer-el-send { display:grid; place-items:center; width:32px; height:32px; border-radius:8px; background:#111827; color:#fff; }
|
|
718
|
+
.composer-el-send.streaming { background:var(--rp-danger); }
|
|
719
|
+
citation-el, citation-el { display:inline-flex; align-items:center; gap:6px; max-width:280px; padding:3px 9px 3px 3px; border:1px solid var(--rp-border); border-radius:6px; background:#f9fafb; font-size:12px; color:#374151; }
|
|
720
|
+
.rp-cite-idx { display:grid; place-items:center; width:17px; height:17px; border-radius:4px; background:#e5e7eb; color:#374151; font-size:11px; font-weight:700; }
|
|
721
|
+
.rp-cite-title { overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
|
|
722
|
+
token-usage, token-usage { display:inline-flex; align-items:center; gap:7px; font-size:12px; color:#9ca3af; }
|
|
723
|
+
.rp-token-track { width:90px; height:5px; border-radius:999px; background:#e5e7eb; overflow:hidden; }
|
|
724
|
+
.rp-token-fill { display:block; height:100%; background:#9ca3af; }
|
|
253
725
|
`;
|
|
254
726
|
function injectStyle() {
|
|
255
727
|
if (document.getElementById(RPUI_STYLE_ID)) return;
|
|
@@ -259,10 +731,18 @@ function injectStyle() {
|
|
|
259
731
|
document.head.appendChild(el);
|
|
260
732
|
}
|
|
261
733
|
class RpAnnotation extends HTMLElement {
|
|
734
|
+
constructor() {
|
|
735
|
+
super(...arguments);
|
|
736
|
+
__publicField(this, "ro");
|
|
737
|
+
__publicField(this, "frame", 0);
|
|
738
|
+
}
|
|
262
739
|
connectedCallback() {
|
|
263
740
|
var _a;
|
|
264
741
|
injectStyle();
|
|
265
|
-
if (this.dataset.rpReady)
|
|
742
|
+
if (this.dataset.rpReady) {
|
|
743
|
+
this.setupSlicePins();
|
|
744
|
+
return;
|
|
745
|
+
}
|
|
266
746
|
this.dataset.rpReady = "true";
|
|
267
747
|
const existing = Array.from(this.childNodes);
|
|
268
748
|
const depth = this.annotationDepth();
|
|
@@ -274,7 +754,7 @@ class RpAnnotation extends HTMLElement {
|
|
|
274
754
|
} else {
|
|
275
755
|
const parentSection = ((_a = this.closest("[data-rp-section]")) == null ? void 0 : _a.dataset.rpSection) ?? "";
|
|
276
756
|
const siblings = this.parentElement ? Array.from(this.parentElement.children).filter(
|
|
277
|
-
(el) => el.tagName.toLowerCase() === "
|
|
757
|
+
(el) => el.tagName.toLowerCase() === "annotation-el" || el.tagName.toLowerCase() === "annotation-el"
|
|
278
758
|
) : [];
|
|
279
759
|
const idx = siblings.indexOf(this) + 1;
|
|
280
760
|
sectionPath = parentSection ? `${parentSection}-${idx}` : String(idx);
|
|
@@ -282,13 +762,14 @@ class RpAnnotation extends HTMLElement {
|
|
|
282
762
|
this.dataset.rpSection = sectionPath;
|
|
283
763
|
const marker = document.createElement("span");
|
|
284
764
|
const kind = id ? "drop" : depth <= 1 ? "circle" : "triangle";
|
|
285
|
-
marker.className = `
|
|
286
|
-
|
|
765
|
+
marker.className = `annotation-el-marker ${kind}`;
|
|
766
|
+
const localIndex = id || sectionPath.split("-").pop() || "";
|
|
767
|
+
marker.innerHTML = `<span>${escapeHtml(localIndex)}</span>`;
|
|
287
768
|
const head = document.createElement("div");
|
|
288
|
-
head.className = "
|
|
769
|
+
head.className = "annotation-el-head";
|
|
289
770
|
head.append(marker);
|
|
290
771
|
const title = document.createElement("span");
|
|
291
|
-
title.className = "
|
|
772
|
+
title.className = "annotation-el-title";
|
|
292
773
|
title.textContent = label;
|
|
293
774
|
title.addEventListener("click", () => {
|
|
294
775
|
const url = new URL(location.href);
|
|
@@ -298,15 +779,56 @@ class RpAnnotation extends HTMLElement {
|
|
|
298
779
|
});
|
|
299
780
|
head.append(title);
|
|
300
781
|
const body = document.createElement("div");
|
|
301
|
-
body.className = "
|
|
782
|
+
body.className = "annotation-el-body";
|
|
302
783
|
existing.forEach((n) => body.appendChild(n));
|
|
303
784
|
this.append(head, body);
|
|
785
|
+
this.setupSlicePins();
|
|
786
|
+
}
|
|
787
|
+
disconnectedCallback() {
|
|
788
|
+
var _a;
|
|
789
|
+
(_a = this.ro) == null ? void 0 : _a.disconnect();
|
|
790
|
+
if (this.frame) cancelAnimationFrame(this.frame);
|
|
791
|
+
}
|
|
792
|
+
// A UI slice inside this annotation may carry data-pin markers on sub-regions.
|
|
793
|
+
// Render pins on those slices so their numbers connect to the deeper annotations
|
|
794
|
+
// that explain them — mirroring how main-view pins top-level regions.
|
|
795
|
+
setupSlicePins() {
|
|
796
|
+
var _a;
|
|
797
|
+
const body = this.querySelector(":scope > .annotation-el-body");
|
|
798
|
+
if (!body || !body.querySelector("[data-pin]")) return;
|
|
799
|
+
(_a = this.ro) == null ? void 0 : _a.disconnect();
|
|
800
|
+
this.scheduleSlicePins(body);
|
|
801
|
+
this.ro = new ResizeObserver(() => this.scheduleSlicePins(body));
|
|
802
|
+
this.ro.observe(this);
|
|
803
|
+
}
|
|
804
|
+
scheduleSlicePins(body) {
|
|
805
|
+
if (this.frame) return;
|
|
806
|
+
this.frame = requestAnimationFrame(() => {
|
|
807
|
+
this.frame = 0;
|
|
808
|
+
this.renderSlicePins(body);
|
|
809
|
+
});
|
|
810
|
+
}
|
|
811
|
+
renderSlicePins(body) {
|
|
812
|
+
body.querySelectorAll(":scope > .rp-pin").forEach((p) => p.remove());
|
|
813
|
+
const bodyRect = body.getBoundingClientRect();
|
|
814
|
+
body.querySelectorAll("[data-pin]").forEach((target) => {
|
|
815
|
+
if (target.closest("annotation-el, annotation-el") !== this) return;
|
|
816
|
+
const pinId = target.dataset.pin;
|
|
817
|
+
if (!pinId) return;
|
|
818
|
+
const r = target.getBoundingClientRect();
|
|
819
|
+
const pin = document.createElement("span");
|
|
820
|
+
pin.className = "rp-pin rp-pin-slice";
|
|
821
|
+
pin.style.left = `${r.left - bodyRect.left}px`;
|
|
822
|
+
pin.style.top = `${r.top - bodyRect.top}px`;
|
|
823
|
+
pin.innerHTML = `<span>${escapeHtml(pinId)}</span>`;
|
|
824
|
+
body.appendChild(pin);
|
|
825
|
+
});
|
|
304
826
|
}
|
|
305
827
|
annotationDepth() {
|
|
306
828
|
let d = 0;
|
|
307
829
|
let p = this.parentElement;
|
|
308
830
|
while (p) {
|
|
309
|
-
if (p.tagName.toLowerCase() === "
|
|
831
|
+
if (p.tagName.toLowerCase() === "annotation-el" || p.tagName.toLowerCase() === "annotation-el") d++;
|
|
310
832
|
p = p.parentElement;
|
|
311
833
|
}
|
|
312
834
|
return d;
|
|
@@ -325,27 +847,27 @@ class RpEnumItem extends HTMLElement {
|
|
|
325
847
|
const children = Array.from(this.childNodes);
|
|
326
848
|
const parent = this.parentElement;
|
|
327
849
|
const siblings = parent ? Array.from(parent.children).filter(
|
|
328
|
-
(el) => el.tagName.toLowerCase() === "
|
|
850
|
+
(el) => el.tagName.toLowerCase() === "enum-item" || el.tagName.toLowerCase() === "enum-item"
|
|
329
851
|
) : [];
|
|
330
852
|
const idx = siblings.indexOf(this) + 1;
|
|
331
853
|
const labelEl = document.createElement("span");
|
|
332
|
-
labelEl.className = "
|
|
854
|
+
labelEl.className = "enum-el-label";
|
|
333
855
|
const idxBadge = document.createElement("span");
|
|
334
|
-
idxBadge.className = "
|
|
856
|
+
idxBadge.className = "enum-el-index";
|
|
335
857
|
idxBadge.textContent = String(idx);
|
|
336
858
|
const labelText = document.createElement("span");
|
|
337
|
-
labelText.className = "
|
|
859
|
+
labelText.className = "enum-el-label-text";
|
|
338
860
|
labelText.textContent = attr(this, "label", "State");
|
|
339
861
|
const description = attr(this, "description");
|
|
340
862
|
if (description) {
|
|
341
863
|
const desc = document.createElement("span");
|
|
342
|
-
desc.className = "
|
|
864
|
+
desc.className = "enum-el-description";
|
|
343
865
|
desc.textContent = description;
|
|
344
866
|
labelText.appendChild(desc);
|
|
345
867
|
}
|
|
346
868
|
labelEl.append(idxBadge, labelText);
|
|
347
869
|
const content = document.createElement("div");
|
|
348
|
-
content.className = "
|
|
870
|
+
content.className = "enum-el-content";
|
|
349
871
|
children.forEach((n) => content.appendChild(n));
|
|
350
872
|
this.append(labelEl, content);
|
|
351
873
|
}
|
|
@@ -397,7 +919,10 @@ class RpMainView extends HTMLElement {
|
|
|
397
919
|
disconnectedCallback() {
|
|
398
920
|
var _a;
|
|
399
921
|
(_a = this.ro) == null ? void 0 : _a.disconnect();
|
|
400
|
-
if (this.frame)
|
|
922
|
+
if (this.frame) {
|
|
923
|
+
cancelAnimationFrame(this.frame);
|
|
924
|
+
this.frame = 0;
|
|
925
|
+
}
|
|
401
926
|
}
|
|
402
927
|
scheduleRender() {
|
|
403
928
|
if (this.frame) return;
|
|
@@ -465,26 +990,26 @@ class RpPage extends HTMLElement {
|
|
|
465
990
|
this.removeAttribute("title");
|
|
466
991
|
const existing = Array.from(this.childNodes);
|
|
467
992
|
const header = document.createElement("div");
|
|
468
|
-
header.className = "
|
|
469
|
-
header.innerHTML = `<div class="
|
|
993
|
+
header.className = "page-el-header";
|
|
994
|
+
header.innerHTML = `<div class="page-el-title-row"><h1 class="page-el-title">${escapeHtml(pageTitle)}</h1><span class="page-el-route">${escapeHtml(route)}</span></div><p class="page-el-description">${escapeHtml(description)}</p>`;
|
|
470
995
|
const body = document.createElement("div");
|
|
471
|
-
body.className = "
|
|
996
|
+
body.className = "page-el-body";
|
|
472
997
|
const main = document.createElement("main");
|
|
473
|
-
main.className = "
|
|
998
|
+
main.className = "page-el-main";
|
|
474
999
|
const pane = document.createElement("aside");
|
|
475
|
-
pane.className = "
|
|
1000
|
+
pane.className = "annotation-el-pane";
|
|
476
1001
|
pane.setAttribute("aria-label", "Annotations");
|
|
477
1002
|
const paneInner = document.createElement("div");
|
|
478
|
-
paneInner.className = "
|
|
1003
|
+
paneInner.className = "annotation-el-pane-inner";
|
|
479
1004
|
existing.forEach((n) => (isTopAnnotation(n) ? paneInner : body).appendChild(n));
|
|
480
1005
|
pane.appendChild(paneInner);
|
|
481
1006
|
main.append(header, body);
|
|
482
1007
|
const shell = document.createElement("div");
|
|
483
|
-
shell.className = "
|
|
1008
|
+
shell.className = "page-el-shell";
|
|
484
1009
|
shell.append(main, pane);
|
|
485
1010
|
this.appendChild(shell);
|
|
486
1011
|
requestAnimationFrame(() => {
|
|
487
|
-
const mv = body.querySelector("
|
|
1012
|
+
const mv = body.querySelector("main-view, main-view");
|
|
488
1013
|
if (mv) header.style.maxWidth = `${mv.offsetWidth}px`;
|
|
489
1014
|
});
|
|
490
1015
|
const go = () => {
|
|
@@ -542,6 +1067,24 @@ class LogoElement extends HTMLElement {
|
|
|
542
1067
|
if (!this.innerHTML.trim()) this.textContent = attr(this, "label", "LOGO");
|
|
543
1068
|
}
|
|
544
1069
|
}
|
|
1070
|
+
class SplitPaneElement extends HTMLElement {
|
|
1071
|
+
connectedCallback() {
|
|
1072
|
+
injectStyle();
|
|
1073
|
+
this.style.setProperty("--snap-columns", attr(this, "columns", "1fr 1fr"));
|
|
1074
|
+
}
|
|
1075
|
+
}
|
|
1076
|
+
class DividerElement extends HTMLElement {
|
|
1077
|
+
connectedCallback() {
|
|
1078
|
+
injectStyle();
|
|
1079
|
+
if (this.hasAttribute("vertical")) this.classList.add("divider-el-v");
|
|
1080
|
+
}
|
|
1081
|
+
}
|
|
1082
|
+
class SpacerElement extends HTMLElement {
|
|
1083
|
+
connectedCallback() {
|
|
1084
|
+
injectStyle();
|
|
1085
|
+
if (this.hasAttribute("size")) this.style.setProperty("--snap-size", `${attr(this, "size", "16")}px`);
|
|
1086
|
+
}
|
|
1087
|
+
}
|
|
545
1088
|
const iconPaths = {
|
|
546
1089
|
search: '<circle cx="11" cy="11" r="8"/><path d="m21 21-4.3-4.3"/>',
|
|
547
1090
|
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"/>',
|
|
@@ -572,7 +1115,39 @@ const iconPaths = {
|
|
|
572
1115
|
"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"/>',
|
|
573
1116
|
info: '<circle cx="12" cy="12" r="10"/><path d="M12 16v-4"/><path d="M12 8h.01"/>',
|
|
574
1117
|
"circle-check": '<circle cx="12" cy="12" r="10"/><path d="m9 12 2 2 4-4"/>',
|
|
575
|
-
circle: '<circle cx="12" cy="12" r="10"/>'
|
|
1118
|
+
circle: '<circle cx="12" cy="12" r="10"/>',
|
|
1119
|
+
"chevron-up": '<path d="m18 15-6-6-6 6"/>',
|
|
1120
|
+
star: '<path d="M12 2l3 6.3 6.9 1-5 4.9 1.2 6.8-6.1-3.2-6.1 3.2 1.2-6.8-5-4.9 6.9-1z"/>',
|
|
1121
|
+
copy: '<rect width="13" height="13" x="9" y="9" rx="2"/><path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"/>',
|
|
1122
|
+
lock: '<rect width="18" height="11" x="3" y="11" rx="2"/><path d="M7 11V7a5 5 0 0 1 10 0v4"/>',
|
|
1123
|
+
"circle-x": '<circle cx="12" cy="12" r="10"/><path d="m15 9-6 6"/><path d="m9 9 6 6"/>',
|
|
1124
|
+
"more-horizontal": '<circle cx="12" cy="12" r="1"/><circle cx="19" cy="12" r="1"/><circle cx="5" cy="12" r="1"/>',
|
|
1125
|
+
"more-vertical": '<circle cx="12" cy="12" r="1"/><circle cx="12" cy="5" r="1"/><circle cx="12" cy="19" r="1"/>',
|
|
1126
|
+
grip: '<circle cx="9" cy="6" r="1"/><circle cx="9" cy="12" r="1"/><circle cx="9" cy="18" r="1"/><circle cx="15" cy="6" r="1"/><circle cx="15" cy="12" r="1"/><circle cx="15" cy="18" r="1"/>',
|
|
1127
|
+
folder: '<path d="M20 20a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2h-7.9a2 2 0 0 1-1.69-.9L9.6 3.9A2 2 0 0 0 7.93 3H4a2 2 0 0 0-2 2v13a2 2 0 0 0 2 2z"/>',
|
|
1128
|
+
"file-code": '<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"/><path d="m9 13-2 2 2 2"/><path d="m15 13 2 2-2 2"/>',
|
|
1129
|
+
"git-branch": '<line x1="6" x2="6" y1="3" y2="15"/><circle cx="18" cy="6" r="3"/><circle cx="6" cy="18" r="3"/><path d="M18 9a9 9 0 0 1-9 9"/>',
|
|
1130
|
+
clock: '<circle cx="12" cy="12" r="10"/><polyline points="12 6 12 12 16 14"/>',
|
|
1131
|
+
key: '<circle cx="7.5" cy="15.5" r="5.5"/><path d="m21 2-9.6 9.6"/><path d="m15.5 7.5 3 3L22 7l-3-3"/>',
|
|
1132
|
+
zap: '<path d="M4 14a1 1 0 0 1-.78-1.63l9.9-10.2a.5.5 0 0 1 .86.46l-1.92 6.02A1 1 0 0 0 13 10h7a1 1 0 0 1 .78 1.63l-9.9 10.2a.5.5 0 0 1-.86-.46l1.92-6.02A1 1 0 0 0 11 14z"/>',
|
|
1133
|
+
home: '<path d="m3 9 9-7 9 7v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z"/><polyline points="9 22 9 12 15 12 15 22"/>',
|
|
1134
|
+
heart: '<path d="M19 14c1.49-1.46 3-3.21 3-5.5A5.5 5.5 0 0 0 16.5 3c-1.76 0-3 .5-4.5 2-1.5-1.5-2.74-2-4.5-2A5.5 5.5 0 0 0 2 8.5c0 2.3 1.5 4.05 3 5.5l7 7Z"/>',
|
|
1135
|
+
bookmark: '<path d="m19 21-7-4-7 4V5a2 2 0 0 1 2-2h10a2 2 0 0 1 2 2z"/>',
|
|
1136
|
+
download: '<path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"/><polyline points="7 10 12 15 17 10"/><line x1="12" x2="12" y1="15" y2="3"/>',
|
|
1137
|
+
edit: '<path d="M11 4H4a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-7"/><path d="M18.5 2.5a2.1 2.1 0 0 1 3 3L12 15l-4 1 1-4Z"/>',
|
|
1138
|
+
eye: '<path d="M2 12s3-7 10-7 10 7 10 7-3 7-10 7-10-7-10-7Z"/><circle cx="12" cy="12" r="3"/>',
|
|
1139
|
+
filter: '<polygon points="22 3 2 3 10 12.46 10 19 14 21 14 12.46 22 3"/>',
|
|
1140
|
+
refresh: '<path d="M3 12a9 9 0 0 1 9-9 9.75 9.75 0 0 1 6.74 2.74L21 8"/><path d="M21 3v5h-5"/><path d="M21 12a9 9 0 0 1-9 9 9.75 9.75 0 0 1-6.74-2.74L3 16"/><path d="M3 21v-5h5"/>',
|
|
1141
|
+
sparkles: '<path d="M9.9 2.5 12 8l5.5 2.1L12 12l-2.1 5.5L7.8 12 2.3 9.9 7.8 8z"/><path d="M18 5l.9 2.1L21 8l-2.1.9L18 11l-.9-2.1L15 8l2.1-.9z"/>',
|
|
1142
|
+
bot: '<rect width="16" height="11" x="4" y="9" rx="2"/><path d="M12 5v4"/><circle cx="12" cy="4" r="1"/><path d="M9 13v1.5"/><path d="M15 13v1.5"/>',
|
|
1143
|
+
wrench: '<path d="M14.7 6.3a4 4 0 0 0-5.4 5.4L3 18l3 3 6.3-6.3a4 4 0 0 0 5.4-5.4l-2.6 2.6-2.4-.6-.6-2.4z"/>',
|
|
1144
|
+
terminal: '<polyline points="4 17 10 11 4 5"/><line x1="12" x2="20" y1="19" y2="19"/>',
|
|
1145
|
+
"thumbs-up": '<path d="M7 10v11"/><path d="M15 5.9 14 10h5.5a2 2 0 0 1 2 2.4l-1.4 7A2 2 0 0 1 18 21H7V10l4-8a2 2 0 0 1 3 1.7z"/>',
|
|
1146
|
+
"thumbs-down": '<path d="M17 14V3"/><path d="M9 18.1 10 14H4.5a2 2 0 0 1-2-2.4l1.4-7A2 2 0 0 1 6 3h11v11l-4 8a2 2 0 0 1-3-1.7z"/>',
|
|
1147
|
+
send: '<path d="M14.5 9.5 21 3l-6.5 18-2.5-7-7-2.5z"/>',
|
|
1148
|
+
stop: '<rect width="14" height="14" x="5" y="5" rx="2"/>',
|
|
1149
|
+
paperclip: '<path d="m21 8-9.5 9.5a4 4 0 0 1-5.7-5.7L13 4.6a2.7 2.7 0 0 1 3.8 3.8L9.5 15.7a1.3 1.3 0 0 1-1.9-1.9l7.4-7.4"/>',
|
|
1150
|
+
globe: '<circle cx="12" cy="12" r="10"/><path d="M2 12h20"/><path d="M12 2a15 15 0 0 1 0 20 15 15 0 0 1 0-20z"/>'
|
|
576
1151
|
};
|
|
577
1152
|
function icon(name, size = 16) {
|
|
578
1153
|
const key = name || "file";
|
|
@@ -614,7 +1189,7 @@ class SelectElement extends HTMLElement {
|
|
|
614
1189
|
const options = csv(this, "options", "选项 A,选项 B,选项 C");
|
|
615
1190
|
const value = attr(this, "value", options[0] || "Select");
|
|
616
1191
|
const label = attr(this, "label");
|
|
617
|
-
this.innerHTML = `${label ? `<span class="rp-field-label">${escapeHtml(label)}</span>` : ""}<span class="
|
|
1192
|
+
this.innerHTML = `${label ? `<span class="rp-field-label">${escapeHtml(label)}</span>` : ""}<span class="select-el-control"><span class="select-el-value">${escapeHtml(value)}</span>${icon("chevron-down")}</span><span class="select-el-options">${options.map((o) => `<span class="select-el-option${o === value ? " selected" : ""}">${escapeHtml(o)}</span>`).join("")}</span>`;
|
|
618
1193
|
}
|
|
619
1194
|
}
|
|
620
1195
|
class ButtonElement extends HTMLElement {
|
|
@@ -653,7 +1228,7 @@ class ToggleElement extends HTMLElement {
|
|
|
653
1228
|
injectStyle();
|
|
654
1229
|
if (this.dataset.rpReady) return;
|
|
655
1230
|
this.dataset.rpReady = "true";
|
|
656
|
-
this.innerHTML = `<span class="
|
|
1231
|
+
this.innerHTML = `<span class="toggle-el-track"><span class="toggle-el-dot"></span></span><span>${escapeHtml(attr(this, "label", ""))}</span>`;
|
|
657
1232
|
}
|
|
658
1233
|
}
|
|
659
1234
|
class FormElement extends HTMLElement {
|
|
@@ -669,9 +1244,9 @@ class FormItemElement extends HTMLElement {
|
|
|
669
1244
|
const children = Array.from(this.childNodes);
|
|
670
1245
|
const label = attr(this, "label");
|
|
671
1246
|
const error = attr(this, "error");
|
|
672
|
-
this.innerHTML = `${label ? `<span class="
|
|
1247
|
+
this.innerHTML = `${label ? `<span class="form-el-label${this.hasAttribute("required") ? " required" : ""}">${escapeHtml(label)}</span>` : ""}`;
|
|
673
1248
|
children.forEach((n) => this.appendChild(n));
|
|
674
|
-
if (error) this.insertAdjacentHTML("beforeend", `<span class="
|
|
1249
|
+
if (error) this.insertAdjacentHTML("beforeend", `<span class="form-el-error">${escapeHtml(error)}</span>`);
|
|
675
1250
|
}
|
|
676
1251
|
}
|
|
677
1252
|
class DatePickerElement extends FieldElement {
|
|
@@ -686,7 +1261,7 @@ class UploadElement extends HTMLElement {
|
|
|
686
1261
|
this.dataset.rpReady = "true";
|
|
687
1262
|
const state = attr(this, "state", "empty");
|
|
688
1263
|
if (state === "has-file") this.innerHTML = `${icon("file")}<span>${escapeHtml(attr(this, "file", "document.pdf"))}</span>`;
|
|
689
|
-
else if (state === "uploading") this.innerHTML = `${icon("loader")}<span>上传中...</span><span class="
|
|
1264
|
+
else if (state === "uploading") this.innerHTML = `${icon("loader")}<span>上传中...</span><span class="progress-el-bar" style="width:${escapeHtml(attr(this, "progress", "60"))}%"></span>`;
|
|
690
1265
|
else this.innerHTML = `${icon("upload", 24)}<span>${escapeHtml(attr(this, "label", "点击或拖拽文件上传"))}</span>`;
|
|
691
1266
|
}
|
|
692
1267
|
}
|
|
@@ -706,7 +1281,84 @@ class ProgressElement extends HTMLElement {
|
|
|
706
1281
|
const value = attr(this, "value", "40");
|
|
707
1282
|
this.style.setProperty("--progress", `${value}%`);
|
|
708
1283
|
const kind = attr(this, "kind", attr(this, "style"));
|
|
709
|
-
this.innerHTML = kind === "circle" ? `${escapeHtml(value)}%` : '<span class="
|
|
1284
|
+
this.innerHTML = kind === "circle" ? `${escapeHtml(value)}%` : '<span class="progress-el-bar"></span>';
|
|
1285
|
+
}
|
|
1286
|
+
}
|
|
1287
|
+
class SliderElement extends HTMLElement {
|
|
1288
|
+
connectedCallback() {
|
|
1289
|
+
injectStyle();
|
|
1290
|
+
if (this.dataset.rpReady) return;
|
|
1291
|
+
this.dataset.rpReady = "true";
|
|
1292
|
+
const min = intAttr(this, "min", 0);
|
|
1293
|
+
const max = intAttr(this, "max", 100);
|
|
1294
|
+
const value = intAttr(this, "value", 40);
|
|
1295
|
+
const pct = max > min ? Math.max(0, Math.min(100, (value - min) / (max - min) * 100)) : 0;
|
|
1296
|
+
const label = attr(this, "label");
|
|
1297
|
+
this.innerHTML = `${label ? `<span class="rp-field-label">${escapeHtml(label)}</span>` : ""}<span class="slider-el-track"><span class="slider-el-fill" style="width:${pct}%"></span><span class="slider-el-thumb" style="left:${pct}%"></span></span>${this.hasAttribute("show-value") ? `<span class="slider-el-value">${value}</span>` : ""}`;
|
|
1298
|
+
}
|
|
1299
|
+
}
|
|
1300
|
+
class RangeElement extends HTMLElement {
|
|
1301
|
+
connectedCallback() {
|
|
1302
|
+
injectStyle();
|
|
1303
|
+
if (this.dataset.rpReady) return;
|
|
1304
|
+
this.dataset.rpReady = "true";
|
|
1305
|
+
const min = intAttr(this, "min", 0);
|
|
1306
|
+
const max = intAttr(this, "max", 100);
|
|
1307
|
+
const low = intAttr(this, "low", 25);
|
|
1308
|
+
const high = intAttr(this, "high", 75);
|
|
1309
|
+
const span = max - min || 1;
|
|
1310
|
+
const l = (low - min) / span * 100;
|
|
1311
|
+
const h = (high - min) / span * 100;
|
|
1312
|
+
this.innerHTML = `<span class="slider-el-track"><span class="slider-el-fill" style="left:${l}%;width:${h - l}%"></span><span class="slider-el-thumb" style="left:${l}%"></span><span class="slider-el-thumb" style="left:${h}%"></span></span>`;
|
|
1313
|
+
}
|
|
1314
|
+
}
|
|
1315
|
+
class NumberInputElement extends HTMLElement {
|
|
1316
|
+
connectedCallback() {
|
|
1317
|
+
injectStyle();
|
|
1318
|
+
if (this.dataset.rpReady) return;
|
|
1319
|
+
this.dataset.rpReady = "true";
|
|
1320
|
+
const value = attr(this, "value", "0");
|
|
1321
|
+
this.innerHTML = `<span class="rp-num-value">${escapeHtml(value)}</span><span class="rp-num-steppers"><span class="rp-num-step">${icon("chevron-up", 12)}</span><span class="rp-num-step">${icon("chevron-down", 12)}</span></span>`;
|
|
1322
|
+
}
|
|
1323
|
+
}
|
|
1324
|
+
class RatingElement extends HTMLElement {
|
|
1325
|
+
connectedCallback() {
|
|
1326
|
+
injectStyle();
|
|
1327
|
+
if (this.dataset.rpReady) return;
|
|
1328
|
+
this.dataset.rpReady = "true";
|
|
1329
|
+
const max = intAttr(this, "max", 5);
|
|
1330
|
+
const value = intAttr(this, "value", 3);
|
|
1331
|
+
this.innerHTML = Array.from({ length: max }, (_, i) => `<span class="rp-star${i < value ? " filled" : ""}">${icon("star", 16)}</span>`).join("");
|
|
1332
|
+
}
|
|
1333
|
+
}
|
|
1334
|
+
class PinInputElement extends HTMLElement {
|
|
1335
|
+
connectedCallback() {
|
|
1336
|
+
injectStyle();
|
|
1337
|
+
if (this.dataset.rpReady) return;
|
|
1338
|
+
this.dataset.rpReady = "true";
|
|
1339
|
+
const len = intAttr(this, "length", 4);
|
|
1340
|
+
const value = attr(this, "value", "");
|
|
1341
|
+
const chars = value.split("");
|
|
1342
|
+
this.innerHTML = Array.from({ length: len }, (_, i) => `<span class="rp-pin-cell${i === chars.length ? " active" : ""}">${escapeHtml(chars[i] || "")}</span>`).join("");
|
|
1343
|
+
}
|
|
1344
|
+
}
|
|
1345
|
+
class ColorSwatchElement extends HTMLElement {
|
|
1346
|
+
connectedCallback() {
|
|
1347
|
+
injectStyle();
|
|
1348
|
+
if (this.dataset.rpReady) return;
|
|
1349
|
+
this.dataset.rpReady = "true";
|
|
1350
|
+
const value = attr(this, "value", "#2563eb");
|
|
1351
|
+
this.innerHTML = `<span class="rp-swatch-chip" style="background:${escapeHtml(value)}"></span><span class="rp-swatch-hex">${escapeHtml(attr(this, "label", value))}</span>`;
|
|
1352
|
+
}
|
|
1353
|
+
}
|
|
1354
|
+
class AutocompleteElement extends HTMLElement {
|
|
1355
|
+
connectedCallback() {
|
|
1356
|
+
injectStyle();
|
|
1357
|
+
if (this.dataset.rpReady) return;
|
|
1358
|
+
this.dataset.rpReady = "true";
|
|
1359
|
+
const value = attr(this, "value");
|
|
1360
|
+
const options = csv(this, "options", "选项一,选项二,选项三");
|
|
1361
|
+
this.innerHTML = `<span class="rp-field-control">${icon("search")}<span class="${value ? "rp-value" : "rp-placeholder"}">${escapeHtml(value || attr(this, "placeholder", "输入以搜索"))}</span></span>${this.hasAttribute("open") ? `<span class="rp-ac-options">${options.map((o) => `<span class="rp-ac-option">${escapeHtml(o)}</span>`).join("")}</span>` : ""}`;
|
|
710
1362
|
}
|
|
711
1363
|
}
|
|
712
1364
|
class BadgeElement extends HTMLElement {
|
|
@@ -734,7 +1386,7 @@ class ListElement extends HTMLElement {
|
|
|
734
1386
|
this.dataset.rpReady = "true";
|
|
735
1387
|
const items = intAttr(this, "items", 3);
|
|
736
1388
|
const state = attr(this, "state");
|
|
737
|
-
this.innerHTML = Array.from({ length: items }, (_, i) => `<
|
|
1389
|
+
this.innerHTML = Array.from({ length: items }, (_, i) => `<list-item label="${["全部", "未读", "@ 我", "已归档", "设置"][i] || `Item ${i + 1}`}" icon="${["inbox", "message-square", "at-sign", "archive", "settings"][i] || "file"}"${state === "first-selected" && i === 0 ? ' state="selected"' : ""}></list-item>`).join("");
|
|
738
1390
|
}
|
|
739
1391
|
}
|
|
740
1392
|
class ListItemElement extends HTMLElement {
|
|
@@ -746,7 +1398,7 @@ class ListItemElement extends HTMLElement {
|
|
|
746
1398
|
const label = attr(this, "label", ((_a = this.textContent) == null ? void 0 : _a.trim()) || "Item");
|
|
747
1399
|
const badge = attr(this, "badge");
|
|
748
1400
|
const ic = attr(this, "icon");
|
|
749
|
-
this.innerHTML = `${ic ? icon(ic) : ""}<span class="
|
|
1401
|
+
this.innerHTML = `${ic ? icon(ic) : ""}<span class="list-el-label">${escapeHtml(label)}</span>${badge ? `<span class="list-el-badge">${escapeHtml(badge)}</span>` : ""}`;
|
|
750
1402
|
}
|
|
751
1403
|
}
|
|
752
1404
|
class TabsElement extends HTMLElement {
|
|
@@ -759,7 +1411,7 @@ class TabsElement extends HTMLElement {
|
|
|
759
1411
|
var _a;
|
|
760
1412
|
const label = child.getAttribute("label") || ((_a = child.textContent) == null ? void 0 : _a.trim()) || "";
|
|
761
1413
|
const isActive = Number.isFinite(numeric) ? i === numeric : label === active;
|
|
762
|
-
child.classList.toggle("
|
|
1414
|
+
child.classList.toggle("tab-el-active", isActive);
|
|
763
1415
|
});
|
|
764
1416
|
}
|
|
765
1417
|
}
|
|
@@ -771,7 +1423,7 @@ class TabElement extends HTMLElement {
|
|
|
771
1423
|
this.dataset.rpReady = "true";
|
|
772
1424
|
const label = attr(this, "label", ((_a = this.textContent) == null ? void 0 : _a.trim()) || "Tab");
|
|
773
1425
|
const badge = attr(this, "badge");
|
|
774
|
-
this.innerHTML = `<span>${escapeHtml(label)}</span>${badge ? `<span class="
|
|
1426
|
+
this.innerHTML = `<span>${escapeHtml(label)}</span>${badge ? `<span class="list-el-badge">${escapeHtml(badge)}</span>` : ""}`;
|
|
775
1427
|
}
|
|
776
1428
|
}
|
|
777
1429
|
class PaginationElement extends HTMLElement {
|
|
@@ -784,7 +1436,7 @@ class PaginationElement extends HTMLElement {
|
|
|
784
1436
|
const pageSize = intAttr(this, "page-size", 10);
|
|
785
1437
|
const pages = Math.max(1, Math.ceil(total / pageSize));
|
|
786
1438
|
const visible = Array.from({ length: Math.min(pages, 5) }, (_, i) => i + 1);
|
|
787
|
-
this.innerHTML = `<span class="
|
|
1439
|
+
this.innerHTML = `<span class="page-el-btn">${icon("chevron-left", 14)}</span>${visible.map((p) => `<span class="page-el-btn${p === current ? " active" : ""}">${p}</span>`).join("")}<span class="page-el-btn">${icon("chevron-right", 14)}</span><span>共 ${total} 条</span>`;
|
|
788
1440
|
}
|
|
789
1441
|
}
|
|
790
1442
|
class StepsElement extends HTMLElement {
|
|
@@ -803,7 +1455,74 @@ class BreadcrumbElement extends HTMLElement {
|
|
|
803
1455
|
if (this.dataset.rpReady) return;
|
|
804
1456
|
this.dataset.rpReady = "true";
|
|
805
1457
|
const items = csv(this, "items", "首页,当前页");
|
|
806
|
-
this.innerHTML = items.map((item, i) => `<span class="${i === items.length - 1 ? "
|
|
1458
|
+
this.innerHTML = items.map((item, i) => `<span class="${i === items.length - 1 ? "breadcrumb-el-current" : ""}">${escapeHtml(item)}</span>${i < items.length - 1 ? "<span>/</span>" : ""}`).join("");
|
|
1459
|
+
}
|
|
1460
|
+
}
|
|
1461
|
+
class SegmentedElement extends HTMLElement {
|
|
1462
|
+
connectedCallback() {
|
|
1463
|
+
injectStyle();
|
|
1464
|
+
if (this.dataset.rpReady) return;
|
|
1465
|
+
this.dataset.rpReady = "true";
|
|
1466
|
+
const options = csv(this, "options", "日,周,月");
|
|
1467
|
+
const active = attr(this, "active", "0");
|
|
1468
|
+
const idx = Number(active);
|
|
1469
|
+
this.innerHTML = options.map((o, i) => `<span class="rp-seg-item${(Number.isFinite(idx) ? i === idx : o === active) ? " active" : ""}">${escapeHtml(o)}</span>`).join("");
|
|
1470
|
+
}
|
|
1471
|
+
}
|
|
1472
|
+
class CommandPaletteElement extends HTMLElement {
|
|
1473
|
+
connectedCallback() {
|
|
1474
|
+
injectStyle();
|
|
1475
|
+
if (this.dataset.rpReady) return;
|
|
1476
|
+
this.dataset.rpReady = "true";
|
|
1477
|
+
const query = attr(this, "query");
|
|
1478
|
+
const results = csv(this, "results", "新建文件,打开设置,搜索工单,切换主题");
|
|
1479
|
+
this.innerHTML = `<div class="rp-cmdk-input">${icon("search")}<span class="${query ? "rp-value" : "rp-placeholder"}">${escapeHtml(query || "输入命令…")}</span></div><div class="rp-cmdk-list">${results.map((r, i) => `<div class="rp-cmdk-item${i === 0 ? " active" : ""}">${icon("zap", 14)}<span>${escapeHtml(r)}</span></div>`).join("")}</div>`;
|
|
1480
|
+
}
|
|
1481
|
+
}
|
|
1482
|
+
class ContextMenuElement extends HTMLElement {
|
|
1483
|
+
connectedCallback() {
|
|
1484
|
+
injectStyle();
|
|
1485
|
+
if (this.dataset.rpReady || this.children.length) return;
|
|
1486
|
+
this.dataset.rpReady = "true";
|
|
1487
|
+
const items = csv(this, "items", "复制,重命名,移动到,删除");
|
|
1488
|
+
this.innerHTML = items.map((it) => `<div class="menu-item${it === "删除" ? " danger" : ""}"><span>${escapeHtml(it)}</span></div>`).join("");
|
|
1489
|
+
}
|
|
1490
|
+
}
|
|
1491
|
+
class MenuElement extends HTMLElement {
|
|
1492
|
+
connectedCallback() {
|
|
1493
|
+
injectStyle();
|
|
1494
|
+
}
|
|
1495
|
+
}
|
|
1496
|
+
class MenuItemElement extends HTMLElement {
|
|
1497
|
+
connectedCallback() {
|
|
1498
|
+
var _a;
|
|
1499
|
+
injectStyle();
|
|
1500
|
+
if (this.dataset.rpReady) return;
|
|
1501
|
+
this.dataset.rpReady = "true";
|
|
1502
|
+
const label = attr(this, "label", ((_a = this.textContent) == null ? void 0 : _a.trim()) || "菜单项");
|
|
1503
|
+
const ic = attr(this, "icon");
|
|
1504
|
+
const shortcut = attr(this, "shortcut");
|
|
1505
|
+
const disabled = attr(this, "state") === "disabled";
|
|
1506
|
+
this.innerHTML = `${ic ? icon(ic, 14) : ""}<span class="menu-el-label">${escapeHtml(label)}</span>${shortcut ? `<span class="menu-el-shortcut">${escapeHtml(shortcut)}</span>` : ""}`;
|
|
1507
|
+
if (disabled) this.classList.add("disabled");
|
|
1508
|
+
}
|
|
1509
|
+
}
|
|
1510
|
+
class TocElement extends HTMLElement {
|
|
1511
|
+
connectedCallback() {
|
|
1512
|
+
injectStyle();
|
|
1513
|
+
if (this.dataset.rpReady || this.children.length) return;
|
|
1514
|
+
this.dataset.rpReady = "true";
|
|
1515
|
+
const items = csv(this, "items", "概述,安装,用法,API,常见问题");
|
|
1516
|
+
this.innerHTML = items.map((it, i) => `<span class="toc-el-item${i === 0 ? " active" : ""}">${escapeHtml(it)}</span>`).join("");
|
|
1517
|
+
}
|
|
1518
|
+
}
|
|
1519
|
+
class KbdElement extends HTMLElement {
|
|
1520
|
+
connectedCallback() {
|
|
1521
|
+
injectStyle();
|
|
1522
|
+
if (this.dataset.rpReady) return;
|
|
1523
|
+
this.dataset.rpReady = "true";
|
|
1524
|
+
const keys = csv(this, "keys", "⌘,K");
|
|
1525
|
+
this.innerHTML = keys.map((k) => `<kbd class="kbd-el-key">${escapeHtml(k)}</kbd>`).join('<span class="kbd-el-plus">+</span>');
|
|
807
1526
|
}
|
|
808
1527
|
}
|
|
809
1528
|
function sampleCell(c, j, i) {
|
|
@@ -824,9 +1543,9 @@ class TableElement extends HTMLElement {
|
|
|
824
1543
|
const hasCheckbox = this.hasAttribute("has-checkbox");
|
|
825
1544
|
const hasAction = this.hasAttribute("has-action");
|
|
826
1545
|
const finalCols = hasAction ? [...cols, "操作"] : cols;
|
|
827
|
-
const headCells = `${hasCheckbox ? '<span class="
|
|
828
|
-
const body = Array.from({ length: rows }, (_, i) => `<div class="
|
|
829
|
-
this.innerHTML = `<div class="
|
|
1546
|
+
const headCells = `${hasCheckbox ? '<span class="table-el-cell">✓</span>' : ""}${finalCols.map((c) => `<span class="table-el-cell">${escapeHtml(c)}</span>`).join("")}`;
|
|
1547
|
+
const body = Array.from({ length: rows }, (_, i) => `<div class="table-row">${hasCheckbox ? `<span class="table-el-cell"><span class="rp-box">${i === 1 ? icon("check", 12) : ""}</span></span>` : ""}${finalCols.map((c, j) => `<span class="table-el-cell">${c === "操作" ? '<button-el label="查看" variant="link"></button-el>' : escapeHtml(sampleCell(c, j, i))}</span>`).join("")}</div>`).join("");
|
|
1548
|
+
this.innerHTML = `<div class="table-row table-el-head">${headCells}</div>${body}`;
|
|
830
1549
|
}
|
|
831
1550
|
}
|
|
832
1551
|
class TableRowElement extends HTMLElement {
|
|
@@ -844,7 +1563,7 @@ class BulkActionBarElement extends HTMLElement {
|
|
|
844
1563
|
this.dataset.rpReady = "true";
|
|
845
1564
|
const count = attr(this, "count", "1");
|
|
846
1565
|
const actions = csv(this, "actions", "确认,取消");
|
|
847
|
-
this.innerHTML = `${icon("check")}<span>已选 ${escapeHtml(count)} 项</span>${actions.map((a) => `<
|
|
1566
|
+
this.innerHTML = `${icon("check")}<span>已选 ${escapeHtml(count)} 项</span>${actions.map((a) => `<button-el label="${escapeHtml(a)}" variant="ghost"></button-el>`).join("")}`;
|
|
848
1567
|
}
|
|
849
1568
|
}
|
|
850
1569
|
class EmptyElement extends HTMLElement {
|
|
@@ -852,7 +1571,7 @@ class EmptyElement extends HTMLElement {
|
|
|
852
1571
|
injectStyle();
|
|
853
1572
|
if (this.dataset.rpReady) return;
|
|
854
1573
|
this.dataset.rpReady = "true";
|
|
855
|
-
this.innerHTML = `${icon("empty", 28)}<span class="
|
|
1574
|
+
this.innerHTML = `${icon("empty", 28)}<span class="empty-el-title">${escapeHtml(attr(this, "label", "暂无数据"))}</span><span class="empty-el-desc">${escapeHtml(attr(this, "description", ""))}</span>${this.hasAttribute("has-action") ? '<button-el label="新建" variant="primary" icon="plus"></button-el>' : ""}`;
|
|
856
1575
|
}
|
|
857
1576
|
}
|
|
858
1577
|
class LoadingElement extends HTMLElement {
|
|
@@ -861,7 +1580,7 @@ class LoadingElement extends HTMLElement {
|
|
|
861
1580
|
if (this.dataset.rpReady) return;
|
|
862
1581
|
this.dataset.rpReady = "true";
|
|
863
1582
|
const rows = intAttr(this, "rows", 3);
|
|
864
|
-
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="
|
|
1583
|
+
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="skeleton-el-line" style="width:${220 - i * 24}px"></span>`).join("");
|
|
865
1584
|
}
|
|
866
1585
|
}
|
|
867
1586
|
class AlertElement extends HTMLElement {
|
|
@@ -906,11 +1625,11 @@ class ModalElement extends HTMLElement {
|
|
|
906
1625
|
this.style.setProperty("--snap-width", `${attr(this, "width", "480")}px`);
|
|
907
1626
|
const children = Array.from(this.childNodes);
|
|
908
1627
|
const body = document.createElement("div");
|
|
909
|
-
body.className = "
|
|
1628
|
+
body.className = "modal-el-body";
|
|
910
1629
|
children.forEach((n) => body.appendChild(n));
|
|
911
|
-
this.innerHTML = `<div class="
|
|
1630
|
+
this.innerHTML = `<div class="modal-el-head"><span>${escapeHtml(attr(this, "title", "标题"))}</span>${icon("x", 14)}</div>`;
|
|
912
1631
|
this.appendChild(body);
|
|
913
|
-
if (this.hasAttribute("has-footer")) this.insertAdjacentHTML("beforeend", '<div class="
|
|
1632
|
+
if (this.hasAttribute("has-footer")) this.insertAdjacentHTML("beforeend", '<div class="modal-el-footer"><button-el label="取消"></button-el><button-el label="确认" variant="primary"></button-el></div>');
|
|
914
1633
|
}
|
|
915
1634
|
}
|
|
916
1635
|
class DrawerElement extends HTMLElement {
|
|
@@ -921,9 +1640,9 @@ class DrawerElement extends HTMLElement {
|
|
|
921
1640
|
this.style.setProperty("--snap-width", `${attr(this, "width", "360")}px`);
|
|
922
1641
|
const children = Array.from(this.childNodes);
|
|
923
1642
|
const body = document.createElement("div");
|
|
924
|
-
body.className = "
|
|
1643
|
+
body.className = "drawer-el-body";
|
|
925
1644
|
children.forEach((n) => body.appendChild(n));
|
|
926
|
-
this.innerHTML = `<div class="
|
|
1645
|
+
this.innerHTML = `<div class="drawer-el-head"><span>${escapeHtml(attr(this, "title", "抽屉"))}</span>${icon("x", 14)}</div>`;
|
|
927
1646
|
this.appendChild(body);
|
|
928
1647
|
}
|
|
929
1648
|
}
|
|
@@ -935,9 +1654,9 @@ class CardElement extends HTMLElement {
|
|
|
935
1654
|
const children = Array.from(this.childNodes);
|
|
936
1655
|
const title = attr(this, "title");
|
|
937
1656
|
const subtitle = attr(this, "subtitle");
|
|
938
|
-
this.innerHTML = `${this.hasAttribute("has-image") ? `<span class="
|
|
1657
|
+
this.innerHTML = `${this.hasAttribute("has-image") ? `<span class="card-el-image">${icon("image")} Image</span>` : ""}${title ? `<span class="card-el-title">${escapeHtml(title)}</span>` : ""}${subtitle ? `<span class="card-el-subtitle">${escapeHtml(subtitle)}</span>` : ""}`;
|
|
939
1658
|
children.forEach((n) => this.appendChild(n));
|
|
940
|
-
if (this.hasAttribute("has-footer")) this.insertAdjacentHTML("beforeend", '<span class="
|
|
1659
|
+
if (this.hasAttribute("has-footer")) this.insertAdjacentHTML("beforeend", '<span class="card-el-footer"><button-el label="查看" variant="secondary"></button-el></span>');
|
|
941
1660
|
}
|
|
942
1661
|
}
|
|
943
1662
|
class StatCardElement extends HTMLElement {
|
|
@@ -958,25 +1677,840 @@ class TagElement extends HTMLElement {
|
|
|
958
1677
|
this.innerHTML = `<span>${escapeHtml(label)}</span>${this.hasAttribute("closable") ? icon("x", 12) : ""}`;
|
|
959
1678
|
}
|
|
960
1679
|
}
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
1680
|
+
class ChipElement extends HTMLElement {
|
|
1681
|
+
connectedCallback() {
|
|
1682
|
+
var _a;
|
|
1683
|
+
injectStyle();
|
|
1684
|
+
if (this.dataset.rpReady) return;
|
|
1685
|
+
this.dataset.rpReady = "true";
|
|
1686
|
+
const label = attr(this, "label", ((_a = this.textContent) == null ? void 0 : _a.trim()) || "Chip");
|
|
1687
|
+
const ic = attr(this, "icon");
|
|
1688
|
+
this.innerHTML = `${ic ? icon(ic, 12) : ""}<span>${escapeHtml(label)}</span>${this.hasAttribute("closable") ? icon("x", 11) : ""}`;
|
|
1689
|
+
}
|
|
1690
|
+
}
|
|
1691
|
+
class TreeElement extends HTMLElement {
|
|
1692
|
+
connectedCallback() {
|
|
1693
|
+
injectStyle();
|
|
1694
|
+
}
|
|
1695
|
+
}
|
|
1696
|
+
class TreeItemElement extends HTMLElement {
|
|
1697
|
+
connectedCallback() {
|
|
1698
|
+
injectStyle();
|
|
1699
|
+
if (this.dataset.rpReady) return;
|
|
1700
|
+
this.dataset.rpReady = "true";
|
|
1701
|
+
const level = intAttr(this, "level", 0);
|
|
1702
|
+
const label = attr(this, "label", "Node");
|
|
1703
|
+
const ic = attr(this, "icon");
|
|
1704
|
+
const expandable = this.hasAttribute("expanded") || this.hasAttribute("collapsed");
|
|
1705
|
+
const expanded = this.hasAttribute("expanded");
|
|
1706
|
+
const caret = expandable ? icon(expanded ? "chevron-down" : "chevron-right", 12) : '<span class="tree-el-spacer"></span>';
|
|
1707
|
+
this.style.setProperty("--tree-level", String(level));
|
|
1708
|
+
this.innerHTML = `<span class="tree-el-row${attr(this, "state") === "selected" ? " selected" : ""}">${caret}${icon(ic || (expandable ? "folder" : "file"), 14)}<span class="tree-el-label">${escapeHtml(label)}</span></span>`;
|
|
1709
|
+
}
|
|
1710
|
+
}
|
|
1711
|
+
class TimelineElement extends HTMLElement {
|
|
1712
|
+
connectedCallback() {
|
|
1713
|
+
injectStyle();
|
|
1714
|
+
}
|
|
1715
|
+
}
|
|
1716
|
+
class TimelineItemElement extends HTMLElement {
|
|
1717
|
+
connectedCallback() {
|
|
1718
|
+
injectStyle();
|
|
1719
|
+
if (this.dataset.rpReady) return;
|
|
1720
|
+
this.dataset.rpReady = "true";
|
|
1721
|
+
const children = Array.from(this.childNodes);
|
|
1722
|
+
const label = attr(this, "label");
|
|
1723
|
+
const time = attr(this, "time");
|
|
1724
|
+
const state = attr(this, "state", "default");
|
|
1725
|
+
const dot = `<span class="timeline-el-dot ${state}"></span>`;
|
|
1726
|
+
const head = `<div class="timeline-el-head"><span class="timeline-el-label">${escapeHtml(label)}</span>${time ? `<span class="timeline-el-time">${escapeHtml(time)}</span>` : ""}</div>`;
|
|
1727
|
+
const body = document.createElement("div");
|
|
1728
|
+
body.className = "timeline-el-content";
|
|
1729
|
+
children.forEach((n) => body.appendChild(n));
|
|
1730
|
+
this.innerHTML = `${dot}<div class="timeline-el-main">${head}</div>`;
|
|
1731
|
+
this.querySelector(".timeline-el-main").appendChild(body);
|
|
1732
|
+
}
|
|
1733
|
+
}
|
|
1734
|
+
class CalendarElement extends HTMLElement {
|
|
1735
|
+
connectedCallback() {
|
|
1736
|
+
injectStyle();
|
|
1737
|
+
if (this.dataset.rpReady) return;
|
|
1738
|
+
this.dataset.rpReady = "true";
|
|
1739
|
+
const month = attr(this, "month", "2026 年 6 月");
|
|
1740
|
+
const selected = intAttr(this, "selected", 15);
|
|
1741
|
+
const dows = ["一", "二", "三", "四", "五", "六", "日"];
|
|
1742
|
+
const cells = Array.from({ length: 35 }, (_, i) => {
|
|
1743
|
+
const day = i - 1;
|
|
1744
|
+
const valid = day >= 1 && day <= 30;
|
|
1745
|
+
return `<span class="rp-cal-cell${valid && day === selected ? " selected" : ""}${valid ? "" : " muted"}">${valid ? day : ""}</span>`;
|
|
1746
|
+
}).join("");
|
|
1747
|
+
this.innerHTML = `<div class="rp-cal-head"><span>${escapeHtml(month)}</span></div><div class="rp-cal-grid">${dows.map((d) => `<span class="rp-cal-dow">${d}</span>`).join("")}${cells}</div>`;
|
|
1748
|
+
}
|
|
1749
|
+
}
|
|
1750
|
+
class KanbanElement extends HTMLElement {
|
|
1751
|
+
connectedCallback() {
|
|
1752
|
+
injectStyle();
|
|
1753
|
+
}
|
|
1754
|
+
}
|
|
1755
|
+
class KanbanColumnElement extends HTMLElement {
|
|
1756
|
+
connectedCallback() {
|
|
1757
|
+
injectStyle();
|
|
1758
|
+
if (this.dataset.rpReady) return;
|
|
1759
|
+
this.dataset.rpReady = "true";
|
|
1760
|
+
const children = Array.from(this.childNodes);
|
|
1761
|
+
const title = attr(this, "title", "列");
|
|
1762
|
+
const count = attr(this, "count");
|
|
1763
|
+
const head = document.createElement("div");
|
|
1764
|
+
head.className = "kanban-el-head";
|
|
1765
|
+
head.innerHTML = `<span>${escapeHtml(title)}</span>${count ? `<span class="kanban-el-count">${escapeHtml(count)}</span>` : ""}`;
|
|
1766
|
+
const body = document.createElement("div");
|
|
1767
|
+
body.className = "kanban-el-body";
|
|
1768
|
+
children.forEach((n) => body.appendChild(n));
|
|
1769
|
+
this.append(head, body);
|
|
1770
|
+
}
|
|
1771
|
+
}
|
|
1772
|
+
class KanbanCardElement extends HTMLElement {
|
|
1773
|
+
connectedCallback() {
|
|
1774
|
+
injectStyle();
|
|
1775
|
+
if (this.dataset.rpReady) return;
|
|
1776
|
+
this.dataset.rpReady = "true";
|
|
1777
|
+
const label = attr(this, "label", "卡片");
|
|
1778
|
+
const tag = attr(this, "tag");
|
|
1779
|
+
this.innerHTML = `<span class="kanban-card-title">${escapeHtml(label)}</span>${tag ? `<span class="kanban-card-tag">${escapeHtml(tag)}</span>` : ""}`;
|
|
1780
|
+
}
|
|
1781
|
+
}
|
|
1782
|
+
class CodeBlockElement extends HTMLElement {
|
|
1783
|
+
connectedCallback() {
|
|
1784
|
+
injectStyle();
|
|
1785
|
+
if (this.dataset.rpReady) return;
|
|
1786
|
+
this.dataset.rpReady = "true";
|
|
1787
|
+
const lines = intAttr(this, "lines", 5);
|
|
1788
|
+
const lang = attr(this, "lang", "ts");
|
|
1789
|
+
const body = Array.from({ length: lines }, (_, i) => `<span class="rp-code-line"><span class="rp-code-ln">${i + 1}</span><span class="rp-code-bar" style="width:${40 + i * 37 % 50}%"></span></span>`).join("");
|
|
1790
|
+
this.innerHTML = `<div class="rp-code-head">${escapeHtml(lang)}</div><div class="rp-code-body">${body}</div>`;
|
|
1791
|
+
}
|
|
1792
|
+
}
|
|
1793
|
+
class DiffElement extends HTMLElement {
|
|
1794
|
+
connectedCallback() {
|
|
1795
|
+
injectStyle();
|
|
1796
|
+
if (this.dataset.rpReady) return;
|
|
1797
|
+
this.dataset.rpReady = "true";
|
|
1798
|
+
const rows = intAttr(this, "rows", 4);
|
|
1799
|
+
const body = Array.from({ length: rows }, (_, i) => {
|
|
1800
|
+
const kind = i % 3 === 0 ? "add" : i % 3 === 1 ? "del" : "ctx";
|
|
1801
|
+
const sign = kind === "add" ? "+" : kind === "del" ? "-" : " ";
|
|
1802
|
+
return `<span class="diff-el-line ${kind}"><span class="diff-el-sign">${sign}</span><span class="rp-code-bar" style="width:${45 + i * 29 % 45}%"></span></span>`;
|
|
1803
|
+
}).join("");
|
|
1804
|
+
this.innerHTML = body;
|
|
1805
|
+
}
|
|
1806
|
+
}
|
|
1807
|
+
class ImageGridElement extends HTMLElement {
|
|
1808
|
+
connectedCallback() {
|
|
1809
|
+
injectStyle();
|
|
1810
|
+
if (this.dataset.rpReady) return;
|
|
1811
|
+
this.dataset.rpReady = "true";
|
|
1812
|
+
const count = intAttr(this, "count", 6);
|
|
1813
|
+
const cols = intAttr(this, "columns", 3);
|
|
1814
|
+
this.style.setProperty("--grid-cols", String(cols));
|
|
1815
|
+
this.innerHTML = Array.from({ length: count }, () => `<span class="rp-grid-cell">${icon("image", 20)}</span>`).join("");
|
|
1816
|
+
}
|
|
1817
|
+
}
|
|
1818
|
+
class KeyValueElement extends HTMLElement {
|
|
1819
|
+
connectedCallback() {
|
|
1820
|
+
injectStyle();
|
|
1821
|
+
}
|
|
1822
|
+
}
|
|
1823
|
+
class KvRowElement extends HTMLElement {
|
|
1824
|
+
connectedCallback() {
|
|
1825
|
+
injectStyle();
|
|
1826
|
+
if (this.dataset.rpReady) return;
|
|
1827
|
+
this.dataset.rpReady = "true";
|
|
1828
|
+
this.innerHTML = `<span class="rp-kv-key">${escapeHtml(attr(this, "label", "键"))}</span><span class="rp-kv-val">${escapeHtml(attr(this, "value", "值"))}</span>`;
|
|
1829
|
+
}
|
|
1830
|
+
}
|
|
1831
|
+
class AccordionElement extends HTMLElement {
|
|
1832
|
+
connectedCallback() {
|
|
1833
|
+
injectStyle();
|
|
1834
|
+
}
|
|
1835
|
+
}
|
|
1836
|
+
class AccordionItemElement extends HTMLElement {
|
|
1837
|
+
connectedCallback() {
|
|
1838
|
+
injectStyle();
|
|
1839
|
+
if (this.dataset.rpReady) return;
|
|
1840
|
+
this.dataset.rpReady = "true";
|
|
1841
|
+
const children = Array.from(this.childNodes);
|
|
1842
|
+
const label = attr(this, "label", "分节");
|
|
1843
|
+
const expanded = this.hasAttribute("expanded");
|
|
1844
|
+
const head = document.createElement("div");
|
|
1845
|
+
head.className = "accordion-el-head";
|
|
1846
|
+
head.innerHTML = `${icon(expanded ? "chevron-down" : "chevron-right", 14)}<span>${escapeHtml(label)}</span>`;
|
|
1847
|
+
this.appendChild(head);
|
|
1848
|
+
if (expanded) {
|
|
1849
|
+
const body = document.createElement("div");
|
|
1850
|
+
body.className = "accordion-el-body";
|
|
1851
|
+
children.forEach((n) => body.appendChild(n));
|
|
1852
|
+
this.appendChild(body);
|
|
1853
|
+
}
|
|
1854
|
+
}
|
|
1855
|
+
}
|
|
1856
|
+
class BannerElement extends HTMLElement {
|
|
1857
|
+
connectedCallback() {
|
|
1858
|
+
injectStyle();
|
|
1859
|
+
if (this.dataset.rpReady) return;
|
|
1860
|
+
this.dataset.rpReady = "true";
|
|
1861
|
+
const type = attr(this, "type", "info");
|
|
1862
|
+
const ic = type === "error" ? "circle-alert" : type === "warning" ? "alert-triangle" : type === "success" ? "circle-check" : "info";
|
|
1863
|
+
this.innerHTML = `${icon(ic)}<span class="banner-el-text"><strong>${escapeHtml(attr(this, "title", "通知"))}</strong>${attr(this, "message") ? ` ${escapeHtml(attr(this, "message"))}` : ""}</span>${this.hasAttribute("has-action") ? '<button-el label="查看" variant="link"></button-el>' : ""}${this.hasAttribute("closable") ? icon("x", 14) : ""}`;
|
|
1864
|
+
}
|
|
1865
|
+
}
|
|
1866
|
+
class SkeletonElement extends HTMLElement {
|
|
1867
|
+
connectedCallback() {
|
|
1868
|
+
injectStyle();
|
|
1869
|
+
if (this.dataset.rpReady) return;
|
|
1870
|
+
this.dataset.rpReady = "true";
|
|
1871
|
+
const shape = attr(this, "shape", "line");
|
|
1872
|
+
if (shape === "avatar") this.innerHTML = '<span class="rp-skel rp-skel-avatar"></span>';
|
|
1873
|
+
else if (shape === "card") this.innerHTML = '<span class="rp-skel rp-skel-block"></span><span class="skeleton-el-line" style="width:70%"></span><span class="skeleton-el-line" style="width:50%"></span>';
|
|
1874
|
+
else if (shape === "list") this.innerHTML = Array.from({ length: 3 }, () => '<span class="rp-skel-row"><span class="rp-skel rp-skel-avatar sm"></span><span class="skeleton-el-line" style="width:60%"></span></span>').join("");
|
|
1875
|
+
else this.innerHTML = '<span class="skeleton-el-line"></span>';
|
|
1876
|
+
}
|
|
1877
|
+
}
|
|
1878
|
+
class CountdownElement extends HTMLElement {
|
|
1879
|
+
connectedCallback() {
|
|
1880
|
+
injectStyle();
|
|
1881
|
+
if (this.dataset.rpReady) return;
|
|
1882
|
+
this.dataset.rpReady = "true";
|
|
1883
|
+
this.innerHTML = `${icon("clock", 13)}<span>${escapeHtml(attr(this, "value", "02:45:18"))}</span>`;
|
|
1884
|
+
}
|
|
1885
|
+
}
|
|
1886
|
+
class ResultElement extends HTMLElement {
|
|
1887
|
+
connectedCallback() {
|
|
1888
|
+
injectStyle();
|
|
1889
|
+
if (this.dataset.rpReady) return;
|
|
1890
|
+
this.dataset.rpReady = "true";
|
|
1891
|
+
const status = attr(this, "status", "success");
|
|
1892
|
+
const ic = status === "error" ? "circle-x" : status === "empty" ? "empty" : "circle-check";
|
|
1893
|
+
this.innerHTML = `<span class="result-el-icon ${status}">${icon(ic, 40)}</span><span class="result-el-title">${escapeHtml(attr(this, "title", "操作成功"))}</span><span class="result-el-desc">${escapeHtml(attr(this, "description", ""))}</span>${this.hasAttribute("has-action") ? '<button-el label="返回" variant="primary"></button-el>' : ""}`;
|
|
1894
|
+
}
|
|
1895
|
+
}
|
|
1896
|
+
class PermissionGateElement extends HTMLElement {
|
|
1897
|
+
connectedCallback() {
|
|
1898
|
+
injectStyle();
|
|
1899
|
+
if (this.dataset.rpReady) return;
|
|
1900
|
+
this.dataset.rpReady = "true";
|
|
1901
|
+
const children = Array.from(this.childNodes);
|
|
1902
|
+
const wrap = document.createElement("div");
|
|
1903
|
+
wrap.className = "rp-gate-content";
|
|
1904
|
+
children.forEach((n) => wrap.appendChild(n));
|
|
1905
|
+
const overlay = document.createElement("div");
|
|
1906
|
+
overlay.className = "rp-gate-overlay";
|
|
1907
|
+
overlay.innerHTML = `${icon("lock", 16)}<span>${escapeHtml(attr(this, "reason", "无权限"))}</span>`;
|
|
1908
|
+
this.append(wrap, overlay);
|
|
1909
|
+
}
|
|
1910
|
+
}
|
|
1911
|
+
class QuotaBarElement extends HTMLElement {
|
|
1912
|
+
connectedCallback() {
|
|
1913
|
+
injectStyle();
|
|
1914
|
+
if (this.dataset.rpReady) return;
|
|
1915
|
+
this.dataset.rpReady = "true";
|
|
1916
|
+
const used = intAttr(this, "used", 70);
|
|
1917
|
+
const limit = intAttr(this, "limit", 100);
|
|
1918
|
+
const pct = limit ? Math.min(100, used / limit * 100) : 0;
|
|
1919
|
+
const danger = pct >= 90;
|
|
1920
|
+
this.innerHTML = `<div class="rp-quota-head"><span>${escapeHtml(attr(this, "label", "用量"))}</span><span class="rp-quota-num${danger ? " danger" : ""}">${used} / ${limit}</span></div><span class="rp-quota-track"><span class="rp-quota-fill${danger ? " danger" : ""}" style="width:${pct}%"></span></span>`;
|
|
1921
|
+
}
|
|
1922
|
+
}
|
|
1923
|
+
class ApiKeyElement extends HTMLElement {
|
|
1924
|
+
connectedCallback() {
|
|
1925
|
+
injectStyle();
|
|
1926
|
+
if (this.dataset.rpReady) return;
|
|
1927
|
+
this.dataset.rpReady = "true";
|
|
1928
|
+
const value = attr(this, "value", "sk_live_••••••••••••3f9a");
|
|
1929
|
+
this.innerHTML = `<span class="rp-apikey-val">${escapeHtml(value)}</span><span class="rp-apikey-copy">${icon("copy", 14)}</span>`;
|
|
1930
|
+
}
|
|
1931
|
+
}
|
|
1932
|
+
class AuditRowElement extends HTMLElement {
|
|
1933
|
+
connectedCallback() {
|
|
1934
|
+
injectStyle();
|
|
1935
|
+
if (this.dataset.rpReady) return;
|
|
1936
|
+
this.dataset.rpReady = "true";
|
|
1937
|
+
this.innerHTML = `<span class="rp-audit-actor">${escapeHtml(attr(this, "actor", "用户"))}</span><span class="rp-audit-action">${escapeHtml(attr(this, "action", "执行了操作"))}</span><span class="rp-audit-time">${escapeHtml(attr(this, "time", "刚刚"))}</span>`;
|
|
1938
|
+
}
|
|
1939
|
+
}
|
|
1940
|
+
class WorkflowNodeElement extends HTMLElement {
|
|
1941
|
+
connectedCallback() {
|
|
1942
|
+
injectStyle();
|
|
1943
|
+
if (this.dataset.rpReady) return;
|
|
1944
|
+
this.dataset.rpReady = "true";
|
|
1945
|
+
const state = attr(this, "state", "default");
|
|
1946
|
+
const ic = state === "done" ? "circle-check" : state === "active" ? "circle" : state === "error" ? "circle-x" : "circle";
|
|
1947
|
+
this.innerHTML = `<span class="rp-wf-icon ${state}">${icon(ic, 16)}</span><span class="rp-wf-label">${escapeHtml(attr(this, "label", "节点"))}</span>`;
|
|
1948
|
+
}
|
|
1949
|
+
}
|
|
1950
|
+
class IosNavbarElement extends HTMLElement {
|
|
1951
|
+
connectedCallback() {
|
|
1952
|
+
injectStyle();
|
|
1953
|
+
if (this.dataset.rpReady) return;
|
|
1954
|
+
this.dataset.rpReady = "true";
|
|
1955
|
+
const title = attr(this, "title", "标题");
|
|
1956
|
+
const large = this.hasAttribute("large");
|
|
1957
|
+
const back = attr(this, "back");
|
|
1958
|
+
const trailing = attr(this, "trailing");
|
|
1959
|
+
this.innerHTML = `<div class="ios-navbar-row"><span class="rp-ios-nav-leading">${back ? `${icon("chevron-left", 18)}<span>${escapeHtml(back)}</span>` : ""}</span><span class="rp-ios-nav-title${large ? " inline" : ""}">${large ? "" : escapeHtml(title)}</span><span class="rp-ios-nav-trailing">${trailing ? escapeHtml(trailing) : ""}</span></div>${large ? `<div class="rp-ios-nav-large">${escapeHtml(title)}</div>` : ""}`;
|
|
1960
|
+
}
|
|
1961
|
+
}
|
|
1962
|
+
class IosTabbarElement extends HTMLElement {
|
|
1963
|
+
connectedCallback() {
|
|
1964
|
+
injectStyle();
|
|
1965
|
+
if (this.dataset.rpReady) return;
|
|
1966
|
+
this.dataset.rpReady = "true";
|
|
1967
|
+
const items = csv(this, "items", "首页,搜索,通知,我的");
|
|
1968
|
+
const icons = csv(this, "icons", "home,search,bell,user");
|
|
1969
|
+
const active = intAttr(this, "active", 0);
|
|
1970
|
+
this.innerHTML = items.map((it, i) => `<span class="rp-ios-tab${i === active ? " active" : ""}">${icon(icons[i] || "circle", 22)}<span class="rp-ios-tab-label">${escapeHtml(it)}</span></span>`).join("");
|
|
1971
|
+
}
|
|
1972
|
+
}
|
|
1973
|
+
class IosListElement extends HTMLElement {
|
|
1974
|
+
connectedCallback() {
|
|
1975
|
+
injectStyle();
|
|
1976
|
+
if (this.dataset.rpReady) return;
|
|
1977
|
+
this.dataset.rpReady = "true";
|
|
1978
|
+
const header = attr(this, "header");
|
|
1979
|
+
if (header) {
|
|
1980
|
+
const h = document.createElement("div");
|
|
1981
|
+
h.className = "ios-list-header";
|
|
1982
|
+
h.textContent = header;
|
|
1983
|
+
this.insertBefore(h, this.firstChild);
|
|
1984
|
+
}
|
|
1985
|
+
}
|
|
1986
|
+
}
|
|
1987
|
+
class IosListItemElement extends HTMLElement {
|
|
1988
|
+
connectedCallback() {
|
|
1989
|
+
injectStyle();
|
|
1990
|
+
if (this.dataset.rpReady) return;
|
|
1991
|
+
this.dataset.rpReady = "true";
|
|
1992
|
+
const label = attr(this, "label", "项");
|
|
1993
|
+
const detail = attr(this, "detail");
|
|
1994
|
+
const ic = attr(this, "icon");
|
|
1995
|
+
const chevron = this.hasAttribute("chevron");
|
|
1996
|
+
this.innerHTML = `${ic ? `<span class="rp-ios-li-icon">${icon(ic, 16)}</span>` : ""}<span class="rp-ios-li-label">${escapeHtml(label)}</span>${detail ? `<span class="rp-ios-li-detail">${escapeHtml(detail)}</span>` : ""}${chevron ? `<span class="rp-ios-li-chevron">${icon("chevron-right", 16)}</span>` : ""}`;
|
|
1997
|
+
}
|
|
1998
|
+
}
|
|
1999
|
+
class IosActionSheetElement extends HTMLElement {
|
|
2000
|
+
connectedCallback() {
|
|
2001
|
+
injectStyle();
|
|
2002
|
+
if (this.dataset.rpReady) return;
|
|
2003
|
+
this.dataset.rpReady = "true";
|
|
2004
|
+
const title = attr(this, "title");
|
|
2005
|
+
const actions = csv(this, "actions", "拍照,从相册选择,选择文件");
|
|
2006
|
+
const destructive = attr(this, "destructive");
|
|
2007
|
+
const group = `<div class="rp-ios-as-group">${title ? `<div class="rp-ios-as-title">${escapeHtml(title)}</div>` : ""}${actions.map((a) => `<div class="rp-ios-as-action${a === destructive ? " destructive" : ""}">${escapeHtml(a)}</div>`).join("")}</div>`;
|
|
2008
|
+
const cancel = `<div class="rp-ios-as-group"><div class="rp-ios-as-action cancel">取消</div></div>`;
|
|
2009
|
+
this.innerHTML = group + cancel;
|
|
2010
|
+
}
|
|
2011
|
+
}
|
|
2012
|
+
class IosAlertElement extends HTMLElement {
|
|
2013
|
+
connectedCallback() {
|
|
2014
|
+
injectStyle();
|
|
2015
|
+
if (this.dataset.rpReady) return;
|
|
2016
|
+
this.dataset.rpReady = "true";
|
|
2017
|
+
const title = attr(this, "title", "提示");
|
|
2018
|
+
const message = attr(this, "message", "");
|
|
2019
|
+
const actions = csv(this, "actions", "取消,确定");
|
|
2020
|
+
this.innerHTML = `<div class="ios-alert-body"><div class="ios-alert-title">${escapeHtml(title)}</div>${message ? `<div class="ios-alert-msg">${escapeHtml(message)}</div>` : ""}</div><div class="ios-alert-actions">${actions.map((a, i) => `<span class="ios-alert-btn${i === actions.length - 1 ? " primary" : ""}">${escapeHtml(a)}</span>`).join("")}</div>`;
|
|
2021
|
+
}
|
|
2022
|
+
}
|
|
2023
|
+
class IosSwitchElement extends HTMLElement {
|
|
2024
|
+
connectedCallback() {
|
|
2025
|
+
injectStyle();
|
|
2026
|
+
if (this.dataset.rpReady) return;
|
|
2027
|
+
this.dataset.rpReady = "true";
|
|
2028
|
+
const label = attr(this, "label");
|
|
2029
|
+
this.innerHTML = `${label ? `<span class="ios-switch-label">${escapeHtml(label)}</span>` : ""}<span class="ios-switch-track"><span class="ios-switch-dot"></span></span>`;
|
|
2030
|
+
}
|
|
2031
|
+
}
|
|
2032
|
+
class IosSegmentedElement extends HTMLElement {
|
|
2033
|
+
connectedCallback() {
|
|
2034
|
+
injectStyle();
|
|
2035
|
+
if (this.dataset.rpReady) return;
|
|
2036
|
+
this.dataset.rpReady = "true";
|
|
2037
|
+
const options = csv(this, "options", "第一,第二,第三");
|
|
2038
|
+
const active = intAttr(this, "active", 0);
|
|
2039
|
+
this.innerHTML = options.map((o, i) => `<span class="rp-ios-seg-item${i === active ? " active" : ""}">${escapeHtml(o)}</span>`).join("");
|
|
2040
|
+
}
|
|
2041
|
+
}
|
|
2042
|
+
class IosButtonElement extends HTMLElement {
|
|
2043
|
+
connectedCallback() {
|
|
2044
|
+
var _a;
|
|
2045
|
+
injectStyle();
|
|
2046
|
+
if (this.dataset.rpReady) return;
|
|
2047
|
+
this.dataset.rpReady = "true";
|
|
2048
|
+
this.innerHTML = `<span>${escapeHtml(attr(this, "label", ((_a = this.textContent) == null ? void 0 : _a.trim()) || "按钮"))}</span>`;
|
|
2049
|
+
}
|
|
2050
|
+
}
|
|
2051
|
+
class IosSearchElement extends HTMLElement {
|
|
2052
|
+
connectedCallback() {
|
|
2053
|
+
injectStyle();
|
|
2054
|
+
if (this.dataset.rpReady) return;
|
|
2055
|
+
this.dataset.rpReady = "true";
|
|
2056
|
+
const value = attr(this, "value");
|
|
2057
|
+
this.innerHTML = `${icon("search", 15)}<span class="${value ? "rp-value" : "rp-placeholder"}">${escapeHtml(value || attr(this, "placeholder", "搜索"))}</span>`;
|
|
2058
|
+
}
|
|
2059
|
+
}
|
|
2060
|
+
class IosStepperElement extends HTMLElement {
|
|
2061
|
+
connectedCallback() {
|
|
2062
|
+
injectStyle();
|
|
2063
|
+
if (this.dataset.rpReady) return;
|
|
2064
|
+
this.dataset.rpReady = "true";
|
|
2065
|
+
this.innerHTML = `<span class="rp-ios-step minus">${icon("minus", 16)}</span><span class="rp-ios-step-div"></span><span class="rp-ios-step plus">${icon("plus", 16)}</span>`;
|
|
2066
|
+
}
|
|
2067
|
+
}
|
|
2068
|
+
class MacWindowElement extends HTMLElement {
|
|
2069
|
+
connectedCallback() {
|
|
2070
|
+
injectStyle();
|
|
2071
|
+
if (this.dataset.rpReady) return;
|
|
2072
|
+
this.dataset.rpReady = "true";
|
|
2073
|
+
const children = Array.from(this.childNodes);
|
|
2074
|
+
const title = attr(this, "title", "窗口");
|
|
2075
|
+
const titlebar = `<div class="rp-mac-titlebar"><span class="rp-mac-lights"><span class="rp-mac-light close"></span><span class="rp-mac-light min"></span><span class="rp-mac-light max"></span></span><span class="rp-mac-title">${escapeHtml(title)}</span></div>`;
|
|
2076
|
+
const body = document.createElement("div");
|
|
2077
|
+
body.className = "rp-mac-window-body";
|
|
2078
|
+
children.forEach((n) => body.appendChild(n));
|
|
2079
|
+
this.innerHTML = titlebar;
|
|
2080
|
+
this.appendChild(body);
|
|
2081
|
+
}
|
|
2082
|
+
}
|
|
2083
|
+
class MacToolbarElement extends HTMLElement {
|
|
2084
|
+
connectedCallback() {
|
|
2085
|
+
injectStyle();
|
|
2086
|
+
}
|
|
2087
|
+
}
|
|
2088
|
+
class MacMenubarElement extends HTMLElement {
|
|
2089
|
+
connectedCallback() {
|
|
2090
|
+
injectStyle();
|
|
2091
|
+
if (this.dataset.rpReady) return;
|
|
2092
|
+
this.dataset.rpReady = "true";
|
|
2093
|
+
const items = csv(this, "items", "文件,编辑,显示,窗口,帮助");
|
|
2094
|
+
this.innerHTML = `<span class="rp-mac-menubar-apple">${icon("home", 14)}</span>` + items.map((it, i) => `<span class="rp-mac-menu-title${i === 0 ? " active" : ""}">${escapeHtml(it)}</span>`).join("");
|
|
2095
|
+
}
|
|
2096
|
+
}
|
|
2097
|
+
class MacSidebarElement extends HTMLElement {
|
|
2098
|
+
connectedCallback() {
|
|
2099
|
+
injectStyle();
|
|
2100
|
+
}
|
|
2101
|
+
}
|
|
2102
|
+
class MacSourceItemElement extends HTMLElement {
|
|
2103
|
+
connectedCallback() {
|
|
2104
|
+
injectStyle();
|
|
2105
|
+
if (this.dataset.rpReady) return;
|
|
2106
|
+
this.dataset.rpReady = "true";
|
|
2107
|
+
const label = attr(this, "label", "项");
|
|
2108
|
+
const ic = attr(this, "icon");
|
|
2109
|
+
if (this.hasAttribute("group")) {
|
|
2110
|
+
this.classList.add("rp-mac-source-group");
|
|
2111
|
+
this.textContent = label;
|
|
2112
|
+
return;
|
|
2113
|
+
}
|
|
2114
|
+
this.innerHTML = `${ic ? icon(ic, 15) : ""}<span class="rp-mac-source-label">${escapeHtml(label)}</span>`;
|
|
2115
|
+
if (attr(this, "state") === "selected") this.classList.add("selected");
|
|
2116
|
+
}
|
|
2117
|
+
}
|
|
2118
|
+
class MacSegmentedElement extends HTMLElement {
|
|
2119
|
+
connectedCallback() {
|
|
2120
|
+
injectStyle();
|
|
2121
|
+
if (this.dataset.rpReady) return;
|
|
2122
|
+
this.dataset.rpReady = "true";
|
|
2123
|
+
const options = csv(this, "options", "全部,未读,标记");
|
|
2124
|
+
const active = intAttr(this, "active", 0);
|
|
2125
|
+
this.innerHTML = options.map((o, i) => `<span class="rp-mac-seg-item${i === active ? " active" : ""}">${escapeHtml(o)}</span>`).join("");
|
|
2126
|
+
}
|
|
2127
|
+
}
|
|
2128
|
+
class MacPopoverElement extends HTMLElement {
|
|
2129
|
+
connectedCallback() {
|
|
2130
|
+
injectStyle();
|
|
2131
|
+
if (this.dataset.rpReady) return;
|
|
2132
|
+
this.dataset.rpReady = "true";
|
|
2133
|
+
const children = Array.from(this.childNodes);
|
|
2134
|
+
const title = attr(this, "title");
|
|
2135
|
+
const arrow = '<span class="rp-mac-pop-arrow"></span>';
|
|
2136
|
+
const body = document.createElement("div");
|
|
2137
|
+
body.className = "rp-mac-pop-body";
|
|
2138
|
+
if (title) {
|
|
2139
|
+
const h = document.createElement("div");
|
|
2140
|
+
h.className = "rp-mac-pop-title";
|
|
2141
|
+
h.textContent = title;
|
|
2142
|
+
body.appendChild(h);
|
|
2143
|
+
}
|
|
2144
|
+
children.forEach((n) => body.appendChild(n));
|
|
2145
|
+
this.innerHTML = arrow;
|
|
2146
|
+
this.appendChild(body);
|
|
2147
|
+
}
|
|
2148
|
+
}
|
|
2149
|
+
class MacSheetElement extends HTMLElement {
|
|
2150
|
+
connectedCallback() {
|
|
2151
|
+
injectStyle();
|
|
2152
|
+
if (this.dataset.rpReady) return;
|
|
2153
|
+
this.dataset.rpReady = "true";
|
|
2154
|
+
const children = Array.from(this.childNodes);
|
|
2155
|
+
const title = attr(this, "title", "操作");
|
|
2156
|
+
const body = document.createElement("div");
|
|
2157
|
+
body.className = "rp-mac-sheet-body";
|
|
2158
|
+
children.forEach((n) => body.appendChild(n));
|
|
2159
|
+
this.innerHTML = `<div class="rp-mac-sheet-title">${escapeHtml(title)}</div>`;
|
|
2160
|
+
this.appendChild(body);
|
|
2161
|
+
this.insertAdjacentHTML("beforeend", '<div class="rp-mac-sheet-actions"><button-el label="取消"></button-el><button-el label="完成" variant="primary"></button-el></div>');
|
|
2162
|
+
}
|
|
2163
|
+
}
|
|
2164
|
+
class MacStepperElement extends HTMLElement {
|
|
2165
|
+
connectedCallback() {
|
|
2166
|
+
injectStyle();
|
|
2167
|
+
if (this.dataset.rpReady) return;
|
|
2168
|
+
this.dataset.rpReady = "true";
|
|
2169
|
+
this.innerHTML = `<span class="rp-mac-step up">${icon("chevron-up", 11)}</span><span class="rp-mac-step down">${icon("chevron-down", 11)}</span>`;
|
|
2170
|
+
}
|
|
2171
|
+
}
|
|
2172
|
+
class MacDisclosureElement extends HTMLElement {
|
|
2173
|
+
connectedCallback() {
|
|
2174
|
+
injectStyle();
|
|
2175
|
+
if (this.dataset.rpReady) return;
|
|
2176
|
+
this.dataset.rpReady = "true";
|
|
2177
|
+
const children = Array.from(this.childNodes);
|
|
2178
|
+
const label = attr(this, "label", "详情");
|
|
2179
|
+
const expanded = this.hasAttribute("expanded");
|
|
2180
|
+
const head = document.createElement("div");
|
|
2181
|
+
head.className = "rp-mac-disc-head";
|
|
2182
|
+
head.innerHTML = `<span class="rp-mac-disc-tri${expanded ? " open" : ""}">${icon("chevron-right", 12)}</span><span>${escapeHtml(label)}</span>`;
|
|
2183
|
+
this.appendChild(head);
|
|
2184
|
+
if (expanded) {
|
|
2185
|
+
const body = document.createElement("div");
|
|
2186
|
+
body.className = "rp-mac-disc-body";
|
|
2187
|
+
children.forEach((n) => body.appendChild(n));
|
|
2188
|
+
this.appendChild(body);
|
|
2189
|
+
}
|
|
2190
|
+
}
|
|
2191
|
+
}
|
|
2192
|
+
class MacTableElement extends HTMLElement {
|
|
2193
|
+
connectedCallback() {
|
|
2194
|
+
injectStyle();
|
|
2195
|
+
if (this.dataset.rpReady) return;
|
|
2196
|
+
this.dataset.rpReady = "true";
|
|
2197
|
+
const cols = csv(this, "columns", "名称,类型,大小");
|
|
2198
|
+
const rows = intAttr(this, "rows", 5);
|
|
2199
|
+
const head = `<div class="rp-mac-tr rp-mac-th">${cols.map((c, i) => `<span class="rp-mac-td">${escapeHtml(c)}${i === 0 ? icon("chevron-up", 10) : ""}</span>`).join("")}</div>`;
|
|
2200
|
+
const body = Array.from({ length: rows }, (_, r) => `<div class="rp-mac-tr${r % 2 ? " alt" : ""}">${cols.map((c, ci) => `<span class="rp-mac-td">${ci === 0 ? icon("file", 13) : ""}<span class="rp-mac-cell-bar" style="width:${50 + (r * 17 + ci * 23) % 40}%"></span></span>`).join("")}</div>`).join("");
|
|
2201
|
+
this.innerHTML = head + body;
|
|
2202
|
+
}
|
|
2203
|
+
}
|
|
2204
|
+
class ChatElement extends HTMLElement {
|
|
2205
|
+
connectedCallback() {
|
|
2206
|
+
injectStyle();
|
|
2207
|
+
}
|
|
2208
|
+
}
|
|
2209
|
+
class UserMessageElement extends HTMLElement {
|
|
2210
|
+
connectedCallback() {
|
|
2211
|
+
injectStyle();
|
|
2212
|
+
if (this.dataset.rpReady) return;
|
|
2213
|
+
this.dataset.rpReady = "true";
|
|
2214
|
+
const children = Array.from(this.childNodes);
|
|
2215
|
+
const text = attr(this, "text");
|
|
2216
|
+
const content = document.createElement("div");
|
|
2217
|
+
content.className = "rp-msg-content";
|
|
2218
|
+
if (text) content.textContent = text;
|
|
2219
|
+
else children.forEach((n) => content.appendChild(n));
|
|
2220
|
+
this.innerHTML = `<div class="rp-msg-role">You</div>`;
|
|
2221
|
+
this.appendChild(content);
|
|
2222
|
+
}
|
|
2223
|
+
}
|
|
2224
|
+
class AssistantMessageElement extends HTMLElement {
|
|
2225
|
+
connectedCallback() {
|
|
2226
|
+
injectStyle();
|
|
2227
|
+
if (this.dataset.rpReady) return;
|
|
2228
|
+
this.dataset.rpReady = "true";
|
|
2229
|
+
const children = Array.from(this.childNodes);
|
|
2230
|
+
const text = attr(this, "text");
|
|
2231
|
+
const name = attr(this, "name", "Assistant");
|
|
2232
|
+
const content = document.createElement("div");
|
|
2233
|
+
content.className = "rp-msg-content";
|
|
2234
|
+
if (text) content.textContent = text;
|
|
2235
|
+
else children.forEach((n) => content.appendChild(n));
|
|
2236
|
+
this.innerHTML = `<div class="rp-msg-role">${escapeHtml(name)}</div>`;
|
|
2237
|
+
this.appendChild(content);
|
|
2238
|
+
}
|
|
2239
|
+
}
|
|
2240
|
+
class SystemMessageElement extends HTMLElement {
|
|
2241
|
+
connectedCallback() {
|
|
2242
|
+
var _a;
|
|
2243
|
+
injectStyle();
|
|
2244
|
+
if (this.dataset.rpReady) return;
|
|
2245
|
+
this.dataset.rpReady = "true";
|
|
2246
|
+
const text = attr(this, "text", ((_a = this.textContent) == null ? void 0 : _a.trim()) || "系统消息");
|
|
2247
|
+
this.innerHTML = `<span class="rp-sysmsg-line">${escapeHtml(text)}</span>`;
|
|
2248
|
+
}
|
|
2249
|
+
}
|
|
2250
|
+
class ToolCallElement extends HTMLElement {
|
|
2251
|
+
connectedCallback() {
|
|
2252
|
+
injectStyle();
|
|
2253
|
+
if (this.dataset.rpReady) return;
|
|
2254
|
+
this.dataset.rpReady = "true";
|
|
2255
|
+
const children = Array.from(this.childNodes);
|
|
2256
|
+
const name = attr(this, "name", "tool");
|
|
2257
|
+
const state = attr(this, "state", "done");
|
|
2258
|
+
const glyph = state === "running" ? icon("loader", 13) : state === "error" ? icon("circle-x", 13) : icon("check", 13);
|
|
2259
|
+
const args = attr(this, "args");
|
|
2260
|
+
const head = `<div class="rp-tool-head"><span class="rp-tool-glyph ${state}">${glyph}</span><span class="rp-tool-name">${escapeHtml(name)}</span>${args ? `<span class="rp-tool-args-inline">${escapeHtml(args)}</span>` : ""}</div>`;
|
|
2261
|
+
const body = document.createElement("div");
|
|
2262
|
+
body.className = "rp-tool-body";
|
|
2263
|
+
children.forEach((n) => body.appendChild(n));
|
|
2264
|
+
this.innerHTML = head;
|
|
2265
|
+
if (children.length) this.appendChild(body);
|
|
2266
|
+
}
|
|
2267
|
+
}
|
|
2268
|
+
class AgentOutputElement extends HTMLElement {
|
|
2269
|
+
connectedCallback() {
|
|
2270
|
+
injectStyle();
|
|
2271
|
+
if (this.dataset.rpReady) return;
|
|
2272
|
+
this.dataset.rpReady = "true";
|
|
2273
|
+
const children = Array.from(this.childNodes);
|
|
2274
|
+
const label = attr(this, "label");
|
|
2275
|
+
const head = label ? `<div class="rp-output-head">${escapeHtml(label)}</div>` : "";
|
|
2276
|
+
const body = document.createElement("div");
|
|
2277
|
+
body.className = "rp-output-body";
|
|
2278
|
+
const text = attr(this, "text");
|
|
2279
|
+
if (text) body.textContent = text;
|
|
2280
|
+
else children.forEach((n) => body.appendChild(n));
|
|
2281
|
+
this.innerHTML = head;
|
|
2282
|
+
this.appendChild(body);
|
|
2283
|
+
}
|
|
2284
|
+
}
|
|
2285
|
+
class ReasoningElement extends HTMLElement {
|
|
2286
|
+
connectedCallback() {
|
|
2287
|
+
injectStyle();
|
|
2288
|
+
if (this.dataset.rpReady) return;
|
|
2289
|
+
this.dataset.rpReady = "true";
|
|
2290
|
+
const children = Array.from(this.childNodes);
|
|
2291
|
+
const expanded = this.hasAttribute("expanded");
|
|
2292
|
+
const head = `<div class="rp-reason-head">${icon(expanded ? "chevron-down" : "chevron-right", 13)}<span>Thought for a few seconds</span></div>`;
|
|
2293
|
+
this.innerHTML = head;
|
|
2294
|
+
if (expanded) {
|
|
2295
|
+
const body = document.createElement("div");
|
|
2296
|
+
body.className = "rp-reason-body";
|
|
2297
|
+
children.forEach((n) => body.appendChild(n));
|
|
2298
|
+
this.appendChild(body);
|
|
2299
|
+
}
|
|
2300
|
+
}
|
|
2301
|
+
}
|
|
2302
|
+
class MessageActionsElement extends HTMLElement {
|
|
2303
|
+
connectedCallback() {
|
|
2304
|
+
injectStyle();
|
|
2305
|
+
if (this.dataset.rpReady || this.children.length) return;
|
|
2306
|
+
this.dataset.rpReady = "true";
|
|
2307
|
+
const actions = csv(this, "actions", "copy,retry,up,down");
|
|
2308
|
+
const map = { copy: ["copy", "复制"], retry: ["refresh", "重试"], up: ["thumbs-up", "赞"], down: ["thumbs-down", "踩"], edit: ["edit", "编辑"], share: ["send", "分享"] };
|
|
2309
|
+
this.innerHTML = actions.map((a) => {
|
|
2310
|
+
const m = map[a] || ["circle", a];
|
|
2311
|
+
return `<span class="rp-msg-action" title="${escapeHtml(m[1])}">${icon(m[0], 14)}</span>`;
|
|
2312
|
+
}).join("");
|
|
2313
|
+
}
|
|
2314
|
+
}
|
|
2315
|
+
class SuggestionsElement extends HTMLElement {
|
|
2316
|
+
connectedCallback() {
|
|
2317
|
+
injectStyle();
|
|
2318
|
+
if (this.dataset.rpReady) return;
|
|
2319
|
+
this.dataset.rpReady = "true";
|
|
2320
|
+
const items = csv(this, "items", "总结要点,继续,给个例子");
|
|
2321
|
+
this.innerHTML = items.map((t) => `<span class="rp-suggestion">${escapeHtml(t)}</span>`).join("");
|
|
2322
|
+
}
|
|
2323
|
+
}
|
|
2324
|
+
class TypingElement extends HTMLElement {
|
|
2325
|
+
connectedCallback() {
|
|
2326
|
+
injectStyle();
|
|
2327
|
+
if (this.dataset.rpReady) return;
|
|
2328
|
+
this.dataset.rpReady = "true";
|
|
2329
|
+
this.innerHTML = `<span class="typing-el-dots"><span></span><span></span><span></span></span>`;
|
|
2330
|
+
}
|
|
2331
|
+
}
|
|
2332
|
+
class ComposerElement extends HTMLElement {
|
|
2333
|
+
connectedCallback() {
|
|
2334
|
+
injectStyle();
|
|
2335
|
+
if (this.dataset.rpReady) return;
|
|
2336
|
+
this.dataset.rpReady = "true";
|
|
2337
|
+
const value = attr(this, "value");
|
|
2338
|
+
const state = attr(this, "state", "idle");
|
|
2339
|
+
const sendIcon = state === "streaming" ? icon("stop", 16) : icon("send", 16);
|
|
2340
|
+
this.innerHTML = `<span class="composer-el-attach">${icon("paperclip", 16)}</span><span class="composer-el-input ${value ? "rp-value" : "rp-placeholder"}">${escapeHtml(value || attr(this, "placeholder", "给助手发消息…"))}</span><span class="composer-el-send ${state}">${sendIcon}</span>`;
|
|
2341
|
+
}
|
|
2342
|
+
}
|
|
2343
|
+
class CitationElement extends HTMLElement {
|
|
2344
|
+
connectedCallback() {
|
|
2345
|
+
var _a;
|
|
2346
|
+
injectStyle();
|
|
2347
|
+
if (this.dataset.rpReady) return;
|
|
2348
|
+
this.dataset.rpReady = "true";
|
|
2349
|
+
const index = attr(this, "index", "1");
|
|
2350
|
+
const title = attr(this, "title", ((_a = this.textContent) == null ? void 0 : _a.trim()) || "来源");
|
|
2351
|
+
this.innerHTML = `<span class="rp-cite-idx">${escapeHtml(index)}</span><span class="rp-cite-title">${escapeHtml(title)}</span>`;
|
|
2352
|
+
}
|
|
2353
|
+
}
|
|
2354
|
+
class TokenUsageElement extends HTMLElement {
|
|
2355
|
+
connectedCallback() {
|
|
2356
|
+
injectStyle();
|
|
2357
|
+
if (this.dataset.rpReady) return;
|
|
2358
|
+
this.dataset.rpReady = "true";
|
|
2359
|
+
const used = intAttr(this, "used", 1840);
|
|
2360
|
+
const limit = intAttr(this, "limit", 8e3);
|
|
2361
|
+
const pct = limit ? Math.min(100, used / limit * 100) : 0;
|
|
2362
|
+
this.innerHTML = `<span>${used.toLocaleString()} / ${limit.toLocaleString()} tokens</span><span class="rp-token-track"><span class="rp-token-fill" style="width:${pct}%"></span></span>`;
|
|
2363
|
+
}
|
|
2364
|
+
}
|
|
2365
|
+
function registerAll() {
|
|
2366
|
+
define("page-el", RpPage);
|
|
2367
|
+
define("main-view", RpMainView);
|
|
2368
|
+
define("annotation-el", RpAnnotation);
|
|
2369
|
+
define("enum-el", RpEnum);
|
|
2370
|
+
define("enum-item", RpEnumItem);
|
|
2371
|
+
const pairs = [
|
|
2372
|
+
// layout
|
|
2373
|
+
["viewport", ViewportElement],
|
|
2374
|
+
["layout", LayoutElement],
|
|
2375
|
+
["panel", PanelElement],
|
|
2376
|
+
["navigator", NavbarElement],
|
|
2377
|
+
["sidebar", SidebarElement],
|
|
2378
|
+
["logo", LogoElement],
|
|
2379
|
+
["split-pane", SplitPaneElement],
|
|
2380
|
+
["divider", DividerElement],
|
|
2381
|
+
["spacer", SpacerElement],
|
|
2382
|
+
// controls
|
|
2383
|
+
["search", FieldElement],
|
|
2384
|
+
["input", FieldElement],
|
|
2385
|
+
["textarea", TextareaElement],
|
|
2386
|
+
["select", SelectElement],
|
|
2387
|
+
["button", ButtonElement],
|
|
2388
|
+
["button-group", GenericElement],
|
|
2389
|
+
["checkbox", CheckboxElement],
|
|
2390
|
+
["radio", RadioElement],
|
|
2391
|
+
["toggle", ToggleElement],
|
|
2392
|
+
["form", FormElement],
|
|
2393
|
+
["form-item", FormItemElement],
|
|
2394
|
+
["date-picker", DatePickerElement],
|
|
2395
|
+
["upload", UploadElement],
|
|
2396
|
+
["image-placeholder", ImagePlaceholderElement],
|
|
2397
|
+
["progress", ProgressElement],
|
|
2398
|
+
["slider", SliderElement],
|
|
2399
|
+
["range", RangeElement],
|
|
2400
|
+
["number-input", NumberInputElement],
|
|
2401
|
+
["rating", RatingElement],
|
|
2402
|
+
["pin-input", PinInputElement],
|
|
2403
|
+
["color-swatch", ColorSwatchElement],
|
|
2404
|
+
["autocomplete", AutocompleteElement],
|
|
2405
|
+
// navigation
|
|
2406
|
+
["badge", BadgeElement],
|
|
2407
|
+
["avatar", AvatarElement],
|
|
2408
|
+
["list", ListElement],
|
|
2409
|
+
["list-item", ListItemElement],
|
|
2410
|
+
["tabs", TabsElement],
|
|
2411
|
+
["tab", TabElement],
|
|
2412
|
+
["pagination", PaginationElement],
|
|
2413
|
+
["steps", StepsElement],
|
|
2414
|
+
["breadcrumb", BreadcrumbElement],
|
|
2415
|
+
["segmented", SegmentedElement],
|
|
2416
|
+
["command-palette", CommandPaletteElement],
|
|
2417
|
+
["context-menu", ContextMenuElement],
|
|
2418
|
+
["menu", MenuElement],
|
|
2419
|
+
["menu-item", MenuItemElement],
|
|
2420
|
+
["toc", TocElement],
|
|
2421
|
+
["kbd", KbdElement],
|
|
2422
|
+
// data display
|
|
2423
|
+
["table", TableElement],
|
|
2424
|
+
["table-row", TableRowElement],
|
|
2425
|
+
["bulk-action-bar", BulkActionBarElement],
|
|
2426
|
+
["empty", EmptyElement],
|
|
2427
|
+
["loading", LoadingElement],
|
|
2428
|
+
["alert", AlertElement],
|
|
2429
|
+
["toast", AlertElement],
|
|
2430
|
+
["dropdown", OverlayElement],
|
|
2431
|
+
["popover", OverlayElement],
|
|
2432
|
+
["tooltip", TooltipElement],
|
|
2433
|
+
["modal", ModalElement],
|
|
2434
|
+
["drawer", DrawerElement],
|
|
2435
|
+
["card", CardElement],
|
|
2436
|
+
["stat-card", StatCardElement],
|
|
2437
|
+
["tag", TagElement],
|
|
2438
|
+
["chip", ChipElement],
|
|
2439
|
+
["tree", TreeElement],
|
|
2440
|
+
["tree-item", TreeItemElement],
|
|
2441
|
+
["timeline", TimelineElement],
|
|
2442
|
+
["timeline-item", TimelineItemElement],
|
|
2443
|
+
["calendar", CalendarElement],
|
|
2444
|
+
["kanban", KanbanElement],
|
|
2445
|
+
["kanban-column", KanbanColumnElement],
|
|
2446
|
+
["kanban-card", KanbanCardElement],
|
|
2447
|
+
["code-block", CodeBlockElement],
|
|
2448
|
+
["diff", DiffElement],
|
|
2449
|
+
["image-grid", ImageGridElement],
|
|
2450
|
+
["key-value", KeyValueElement],
|
|
2451
|
+
["kv-row", KvRowElement],
|
|
2452
|
+
["accordion", AccordionElement],
|
|
2453
|
+
["accordion-item", AccordionItemElement],
|
|
2454
|
+
["banner", BannerElement],
|
|
2455
|
+
["skeleton", SkeletonElement],
|
|
2456
|
+
["countdown", CountdownElement],
|
|
2457
|
+
["result", ResultElement],
|
|
2458
|
+
["permission-gate", PermissionGateElement],
|
|
2459
|
+
["quota-bar", QuotaBarElement],
|
|
2460
|
+
["api-key", ApiKeyElement],
|
|
2461
|
+
["audit-row", AuditRowElement],
|
|
2462
|
+
["workflow-node", WorkflowNodeElement],
|
|
2463
|
+
// iOS
|
|
2464
|
+
["ios-navbar", IosNavbarElement],
|
|
2465
|
+
["ios-tabbar", IosTabbarElement],
|
|
2466
|
+
["ios-list", IosListElement],
|
|
2467
|
+
["ios-list-item", IosListItemElement],
|
|
2468
|
+
["ios-action-sheet", IosActionSheetElement],
|
|
2469
|
+
["ios-alert", IosAlertElement],
|
|
2470
|
+
["ios-switch", IosSwitchElement],
|
|
2471
|
+
["ios-segmented", IosSegmentedElement],
|
|
2472
|
+
["ios-button", IosButtonElement],
|
|
2473
|
+
["ios-search", IosSearchElement],
|
|
2474
|
+
["ios-stepper", IosStepperElement],
|
|
2475
|
+
// macOS
|
|
2476
|
+
["macos-window", MacWindowElement],
|
|
2477
|
+
["macos-toolbar", MacToolbarElement],
|
|
2478
|
+
["macos-menubar", MacMenubarElement],
|
|
2479
|
+
["macos-sidebar", MacSidebarElement],
|
|
2480
|
+
["macos-source-item", MacSourceItemElement],
|
|
2481
|
+
["macos-segmented", MacSegmentedElement],
|
|
2482
|
+
["macos-popover", MacPopoverElement],
|
|
2483
|
+
["macos-sheet", MacSheetElement],
|
|
2484
|
+
["macos-stepper", MacStepperElement],
|
|
2485
|
+
["macos-disclosure", MacDisclosureElement],
|
|
2486
|
+
["macos-table", MacTableElement],
|
|
2487
|
+
// agent / conversational UI
|
|
2488
|
+
["chat", ChatElement],
|
|
2489
|
+
["user-message", UserMessageElement],
|
|
2490
|
+
["assistant-message", AssistantMessageElement],
|
|
2491
|
+
["system-message", SystemMessageElement],
|
|
2492
|
+
["tool-call", ToolCallElement],
|
|
2493
|
+
["agent-output", AgentOutputElement],
|
|
2494
|
+
["reasoning", ReasoningElement],
|
|
2495
|
+
["message-actions", MessageActionsElement],
|
|
2496
|
+
["suggestions", SuggestionsElement],
|
|
2497
|
+
["typing", TypingElement],
|
|
2498
|
+
["composer", ComposerElement],
|
|
2499
|
+
["citation", CitationElement],
|
|
2500
|
+
["token-usage", TokenUsageElement]
|
|
2501
|
+
];
|
|
2502
|
+
for (const [suffix] of pairs) {
|
|
2503
|
+
if (toComponentTag(suffix) === suffix && !suffix.includes("-"))
|
|
2504
|
+
console.warn(`[rpui] registry tag "${suffix}" missing from RPML vocabulary`);
|
|
2505
|
+
}
|
|
973
2506
|
for (const [suffix, ctor] of pairs) {
|
|
974
|
-
define(
|
|
975
|
-
define(`rp-${suffix}`, ctor);
|
|
2507
|
+
define(toComponentTag(suffix), ctor);
|
|
976
2508
|
}
|
|
977
2509
|
}
|
|
978
2510
|
registerAll();
|
|
979
2511
|
export {
|
|
980
|
-
|
|
2512
|
+
parseToPage,
|
|
2513
|
+
registerAll,
|
|
2514
|
+
rewriteTags
|
|
981
2515
|
};
|
|
982
2516
|
//# sourceMappingURL=rpui.js.map
|