@adia-ai/web-components 0.0.3 → 0.0.5
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 +29 -22
- package/a2ui/index.js +1 -1
- package/components/chat/chat.css +1 -2
- package/components/code/code.css +2 -0
- package/components/pane/pane.a2ui.json +10 -0
- package/components/pane/pane.css +40 -6
- package/components/pane/pane.js +13 -1
- package/components/pane/pane.yaml +12 -0
- package/package.json +2 -2
- package/patterns/adia-chat/css/adia-chat.tokens.css +1 -1
- package/patterns/adia-editor/adia-editor.a2ui.json +12 -0
- package/patterns/adia-editor/adia-editor.yaml +17 -0
- package/patterns/adia-editor/css/adia-editor.layout.css +70 -3
- package/patterns/adia-editor/css/adia-editor.tokens.css +1 -1
- package/patterns/app-nav-group/app-nav-group.css +3 -0
- package/patterns/app-shell/app-shell.a2ui.json +12 -0
- package/patterns/app-shell/app-shell.yaml +17 -0
- package/patterns/app-shell/css/app-shell.main.css +72 -3
- package/patterns/app-shell/css/app-shell.sidebar.css +37 -1
- package/patterns/app-shell/css/app-shell.tokens.css +1 -3
- package/styles/tokens.css +12 -0
- package/patterns/adia-chat/index.html +0 -93
- package/patterns/adia-editor/index.html +0 -179
- package/patterns/app-shell/index.html +0 -112
package/README.md
CHANGED
|
@@ -44,40 +44,45 @@ web-components/
|
|
|
44
44
|
│ ├── markdown.js lightweight markdown renderer
|
|
45
45
|
│ └── transport.js SSE / streaming helpers for LLM adapters
|
|
46
46
|
│
|
|
47
|
-
├── components/ — 80 *-
|
|
47
|
+
├── components/ — 80 *-ui custom elements
|
|
48
48
|
│ └── <tag>/
|
|
49
49
|
│ ├── <tag>.js class definition (extends AdiaElement)
|
|
50
50
|
│ ├── <tag>.css @scope(tag-ui) two-block: tokens + styles
|
|
51
51
|
│ ├── <tag>.yaml authoring contract (props, slots, events, examples)
|
|
52
52
|
│ └── <tag>.a2ui.json generated — do NOT edit
|
|
53
53
|
│
|
|
54
|
-
├── patterns/ — Higher-level compositions
|
|
55
|
-
│ ├── app-shell, app-nav
|
|
56
|
-
│ ├── adia-chat, adia-editor, gen-ui
|
|
57
|
-
│
|
|
54
|
+
├── patterns/ — Higher-level compositions
|
|
55
|
+
│ ├── app-shell, app-nav*, section-nav* — admin layout scaffolding
|
|
56
|
+
│ ├── adia-chat, adia-editor, gen-ui — LLM + editor + gen-UI patterns
|
|
57
|
+
│ ├── a2ui-root — A2UI declarative host (moved
|
|
58
|
+
│ │ from a2ui/ in 0.0.4; pairs
|
|
59
|
+
│ │ with @adia-ai/a2ui-utils)
|
|
60
|
+
│ └── index.js — registers all patterns
|
|
58
61
|
│
|
|
59
62
|
├── traits/ — 40 composable behaviors via defineTrait()
|
|
60
63
|
│ (pressable, focusTrap, confetti, resizable, …)
|
|
61
64
|
│
|
|
62
|
-
├── a2ui/ —
|
|
63
|
-
│
|
|
64
|
-
│
|
|
65
|
-
│
|
|
66
|
-
│
|
|
67
|
-
│
|
|
68
|
-
│
|
|
69
|
-
│ └── manifest-runtime.js surface manifest loader
|
|
65
|
+
├── a2ui/ — deprecation shim for one release
|
|
66
|
+
│ └── index.js Re-exports @adia-ai/a2ui-utils with a
|
|
67
|
+
│ one-time console.warn. Removed in 0.1.0.
|
|
68
|
+
│ All actual A2UI runtime code (renderer,
|
|
69
|
+
│ registry, streams, surface manifest,
|
|
70
|
+
│ wiring, dockables, controllers) lives in
|
|
71
|
+
│ `@adia-ai/a2ui-utils` at packages/a2ui/utils/.
|
|
70
72
|
│
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
│
|
|
77
|
-
└── scripts/ — Build + dev utilities
|
|
78
|
-
└── build-components.mjs YAML → .a2ui.json per-component
|
|
73
|
+
└── styles/ — Global tokens and CSS layering
|
|
74
|
+
├── tokens.css all --a-* design tokens
|
|
75
|
+
├── colors/ primitives / semantics / scrims
|
|
76
|
+
├── typography.css, space.css, radius.css, shadow.css
|
|
77
|
+
└── themes/*.css 8 themes (ocean, forest, sunset, …)
|
|
79
78
|
```
|
|
80
79
|
|
|
80
|
+
Build + dev utilities (including `build-a2ui-data.mjs`, `qa-training.mjs`,
|
|
81
|
+
`a2ui-to-html.cjs`, `mcp-call.cjs`, `mcp-pipeline.cjs`, `screenshot.cjs`)
|
|
82
|
+
live at the repo-root `scripts/` directory rather than inside this
|
|
83
|
+
package — they span the monorepo (MCP server, gen-ui-training data,
|
|
84
|
+
component catalog) and aren't scoped to web-components alone.
|
|
85
|
+
|
|
81
86
|
## Component contract
|
|
82
87
|
|
|
83
88
|
Every component is a single-file class extending `AdiaElement` (or
|
|
@@ -133,7 +138,9 @@ examples.
|
|
|
133
138
|
## A2UI runtime
|
|
134
139
|
|
|
135
140
|
```javascript
|
|
136
|
-
import { A2UIRenderer } from '@adia-ai/
|
|
141
|
+
import { A2UIRenderer } from '@adia-ai/a2ui-utils';
|
|
142
|
+
// (The old `@adia-ai/web-components/a2ui` subpath still resolves in 0.0.4
|
|
143
|
+
// via a deprecation shim that prints a console.warn; removed in 0.1.0.)
|
|
137
144
|
|
|
138
145
|
const renderer = new A2UIRenderer({ target: document.getElementById('canvas') });
|
|
139
146
|
renderer.apply({
|
package/a2ui/index.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* DEPRECATED — the `@adia-ai/web-components/a2ui` subpath.
|
|
3
3
|
*
|
|
4
4
|
* The A2UI runtime was extracted into its own package `@adia-ai/a2ui-utils`
|
|
5
|
-
* in 0.0.
|
|
5
|
+
* in 0.0.4. This file is a temporary re-export shim for one release so
|
|
6
6
|
* existing consumers don't break on upgrade. It will be removed in 0.1.0.
|
|
7
7
|
*
|
|
8
8
|
* Migrate:
|
package/components/chat/chat.css
CHANGED
|
@@ -10,8 +10,7 @@
|
|
|
10
10
|
--chat-messages-padding: var(--a-space-4);
|
|
11
11
|
--chat-messages-gap: var(--a-space-3);
|
|
12
12
|
--chat-footer-padding: var(--a-space-3);
|
|
13
|
-
|
|
14
|
-
--chat-footer-min-height: 36px;
|
|
13
|
+
--chat-footer-min-height: var(--a-chrome-pane-footer-height);
|
|
15
14
|
|
|
16
15
|
/* ── Motion ── */
|
|
17
16
|
--chat-cursor-duration: 0.8s;
|
package/components/code/code.css
CHANGED
|
@@ -45,6 +45,7 @@
|
|
|
45
45
|
flex-direction: row;
|
|
46
46
|
align-items: center;
|
|
47
47
|
justify-content: space-between;
|
|
48
|
+
min-height: var(--a-chrome-pane-header-height);
|
|
48
49
|
padding: var(--code-py) var(--code-px);
|
|
49
50
|
background: var(--code-header-bg);
|
|
50
51
|
border-bottom: 1px solid var(--code-border);
|
|
@@ -112,6 +113,7 @@
|
|
|
112
113
|
flex-direction: row;
|
|
113
114
|
align-items: center;
|
|
114
115
|
justify-content: space-between;
|
|
116
|
+
min-height: var(--a-chrome-pane-footer-height);
|
|
115
117
|
padding: var(--code-py) var(--code-px);
|
|
116
118
|
background: var(--code-header-bg);
|
|
117
119
|
border-top: 1px solid var(--code-border);
|
|
@@ -35,6 +35,16 @@
|
|
|
35
35
|
"description": "Component property: resizable.",
|
|
36
36
|
"type": "boolean",
|
|
37
37
|
"default": false
|
|
38
|
+
},
|
|
39
|
+
"side": {
|
|
40
|
+
"description": "Opts a pane into horizontal-sibling chrome: suppresses the default\nfour-sided border and moves the resize grabber to the inner edge\n(right edge for `leading`, left edge for `trailing`). Also flips the\nresize-drag direction so `trailing` panes grow when dragged leftward.\nUnset keeps the pane-intrinsic chrome (full border, right-edge\ngrabber when resizable).\n",
|
|
41
|
+
"type": "string",
|
|
42
|
+
"enum": [
|
|
43
|
+
"",
|
|
44
|
+
"leading",
|
|
45
|
+
"trailing"
|
|
46
|
+
],
|
|
47
|
+
"default": ""
|
|
38
48
|
}
|
|
39
49
|
},
|
|
40
50
|
"required": [
|
package/components/pane/pane.css
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
--pane-border: var(--a-border-subtle);
|
|
6
6
|
--pane-radius: var(--a-radius-lg);
|
|
7
7
|
/* Component-intrinsic measurement; no --a-space-* equivalent */
|
|
8
|
-
--pane-bar-height:
|
|
8
|
+
--pane-bar-height: var(--a-chrome-pane-header-height);
|
|
9
9
|
--pane-header-px: var(--a-space-3);
|
|
10
10
|
--pane-header-py: var(--a-space-2);
|
|
11
11
|
--pane-header-fg: var(--a-fg);
|
|
@@ -54,6 +54,23 @@
|
|
|
54
54
|
overflow: hidden;
|
|
55
55
|
}
|
|
56
56
|
|
|
57
|
+
/* Side-aware border treatment.
|
|
58
|
+
`leading` — pane sits at the leading edge of a horizontal row, so
|
|
59
|
+
the only visual separator it needs is on its trailing
|
|
60
|
+
edge (right in LTR).
|
|
61
|
+
`trailing` — mirror: only a leading-edge border (left in LTR).
|
|
62
|
+
Default (no side attr) keeps the full 4-sided border. */
|
|
63
|
+
:scope[side="leading"],
|
|
64
|
+
:scope[side="trailing"] {
|
|
65
|
+
border: none;
|
|
66
|
+
}
|
|
67
|
+
:scope[side="leading"] {
|
|
68
|
+
border-inline-end: 1px solid var(--pane-border);
|
|
69
|
+
}
|
|
70
|
+
:scope[side="trailing"] {
|
|
71
|
+
border-inline-start: 1px solid var(--pane-border);
|
|
72
|
+
}
|
|
73
|
+
|
|
57
74
|
/* ── Pane header ── */
|
|
58
75
|
> header {
|
|
59
76
|
display: flex;
|
|
@@ -76,7 +93,7 @@
|
|
|
76
93
|
|
|
77
94
|
/* Collapse indicator — stamped by JS as icon-ui */
|
|
78
95
|
> header > [slot="chevron"] {
|
|
79
|
-
--a-icon-size:
|
|
96
|
+
--a-icon-size: var(--a-caret-size);
|
|
80
97
|
flex-shrink: 0;
|
|
81
98
|
margin-inline-start: auto;
|
|
82
99
|
color: var(--pane-chevron-fg);
|
|
@@ -101,16 +118,23 @@
|
|
|
101
118
|
display: none;
|
|
102
119
|
}
|
|
103
120
|
|
|
104
|
-
/* Section header
|
|
121
|
+
/* Section header — section's padding is the single source of horizontal inset;
|
|
122
|
+
content inside the section must not add its own padding. */
|
|
105
123
|
> section > header {
|
|
106
124
|
font-size: var(--pane-section-header-size);
|
|
107
125
|
color: var(--pane-section-header-fg);
|
|
108
|
-
padding-bottom: var(--pane-gap
|
|
126
|
+
padding-bottom: var(--pane-col-gap);
|
|
109
127
|
text-transform: uppercase;
|
|
110
128
|
letter-spacing: 0.06em;
|
|
111
129
|
font-weight: var(--pane-section-header-weight);
|
|
112
130
|
}
|
|
113
131
|
|
|
132
|
+
/* Defensive: a data-col directly under a section inherits the section's inset;
|
|
133
|
+
adding its own padding would compound and misalign with the section header. */
|
|
134
|
+
> section > [data-col] {
|
|
135
|
+
padding: 0;
|
|
136
|
+
}
|
|
137
|
+
|
|
114
138
|
/* Section divider between sections */
|
|
115
139
|
> section + section {
|
|
116
140
|
border-top: 1px solid var(--pane-border);
|
|
@@ -143,11 +167,16 @@
|
|
|
143
167
|
border-bottom: none;
|
|
144
168
|
}
|
|
145
169
|
|
|
146
|
-
/* ── Resize handle ──
|
|
170
|
+
/* ── Resize handle ──
|
|
171
|
+
Default (no side) positions the grabber on the right edge. When
|
|
172
|
+
`side="trailing"` is set, flip the grabber to the left edge so it
|
|
173
|
+
sits on the pane's "inner" side (where it meets the sibling
|
|
174
|
+
content/pane in a horizontal row). `inset-inline-*` lets the rules
|
|
175
|
+
stay LTR/RTL-safe. */
|
|
147
176
|
[slot="resize"] {
|
|
148
177
|
position: absolute;
|
|
149
178
|
top: 0;
|
|
150
|
-
|
|
179
|
+
inset-inline-end: 0;
|
|
151
180
|
bottom: 0;
|
|
152
181
|
width: var(--pane-resize-width);
|
|
153
182
|
cursor: col-resize;
|
|
@@ -156,6 +185,11 @@
|
|
|
156
185
|
z-index: 1;
|
|
157
186
|
}
|
|
158
187
|
|
|
188
|
+
:scope[side="trailing"] > [slot="resize"] {
|
|
189
|
+
inset-inline-end: auto;
|
|
190
|
+
inset-inline-start: 0;
|
|
191
|
+
}
|
|
192
|
+
|
|
159
193
|
[slot="resize"]:hover {
|
|
160
194
|
background: var(--pane-resize-fg-hover);
|
|
161
195
|
}
|
package/components/pane/pane.js
CHANGED
|
@@ -19,6 +19,12 @@
|
|
|
19
19
|
* resizable — boolean, enables drag-to-resize (width)
|
|
20
20
|
* min-width — minimum width when resizing (default: 200)
|
|
21
21
|
* max-width — maximum width when resizing (default: 600)
|
|
22
|
+
* side — 'leading' | 'trailing' | '' (default). When set, the
|
|
23
|
+
* pane is treated as a horizontal sibling: the default
|
|
24
|
+
* four-sided border is suppressed, only the inner-edge
|
|
25
|
+
* border is drawn, the resize grabber moves to that
|
|
26
|
+
* inner edge, and the resize-drag direction flips so
|
|
27
|
+
* trailing panes grow when dragged leftward.
|
|
22
28
|
*
|
|
23
29
|
* JS API:
|
|
24
30
|
* pane.collapsed = true/false
|
|
@@ -33,6 +39,7 @@ class AdiaPane extends AdiaElement {
|
|
|
33
39
|
resizable: { type: Boolean, default: false, reflect: true },
|
|
34
40
|
minWidth: { type: Number, default: 200, attribute: 'min-width', reflect: true },
|
|
35
41
|
maxWidth: { type: Number, default: 9999, attribute: 'max-width', reflect: true },
|
|
42
|
+
side: { type: String, default: '', reflect: true },
|
|
36
43
|
};
|
|
37
44
|
|
|
38
45
|
static template = () => null;
|
|
@@ -116,7 +123,12 @@ class AdiaPane extends AdiaElement {
|
|
|
116
123
|
|
|
117
124
|
#onResizeMove = (e) => {
|
|
118
125
|
if (!this.#dragging) return;
|
|
119
|
-
|
|
126
|
+
// For a trailing pane the grabber sits on the LEFT edge but the pane
|
|
127
|
+
// is anchored on the RIGHT side of its flex row — dragging leftward
|
|
128
|
+
// should GROW the pane (grabber moves further left = more width),
|
|
129
|
+
// not shrink it. Negate dx in that case.
|
|
130
|
+
const sign = this.side === 'trailing' ? -1 : 1;
|
|
131
|
+
const dx = (e.clientX - this.#startX) * sign;
|
|
120
132
|
const w = Math.max(this.minWidth, Math.min(this.maxWidth, this.#startW + dx));
|
|
121
133
|
this.style.width = `${w}px`;
|
|
122
134
|
};
|
|
@@ -26,6 +26,18 @@ props:
|
|
|
26
26
|
description: "Component property: resizable."
|
|
27
27
|
type: boolean
|
|
28
28
|
default: false
|
|
29
|
+
side:
|
|
30
|
+
description: |
|
|
31
|
+
Opts a pane into horizontal-sibling chrome: suppresses the default
|
|
32
|
+
four-sided border and moves the resize grabber to the inner edge
|
|
33
|
+
(right edge for `leading`, left edge for `trailing`). Also flips the
|
|
34
|
+
resize-drag direction so `trailing` panes grow when dragged leftward.
|
|
35
|
+
Unset keeps the pane-intrinsic chrome (full border, right-edge
|
|
36
|
+
grabber when resizable).
|
|
37
|
+
type: string
|
|
38
|
+
default: ""
|
|
39
|
+
enum: ["", leading, trailing]
|
|
40
|
+
reflect: true
|
|
29
41
|
events: {}
|
|
30
42
|
slots:
|
|
31
43
|
header:
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@adia-ai/web-components",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.5",
|
|
4
4
|
"description": "AdiaUI web components — vanilla custom elements. A2UI runtime (renderer, registry, streams, wiring) lives in @adia-ai/a2ui-utils.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"exports": {
|
|
@@ -28,7 +28,7 @@
|
|
|
28
28
|
"./core/provider.js"
|
|
29
29
|
],
|
|
30
30
|
"dependencies": {
|
|
31
|
-
"@adia-ai/a2ui-utils": "^0.0.
|
|
31
|
+
"@adia-ai/a2ui-utils": "^0.0.2"
|
|
32
32
|
},
|
|
33
33
|
"publishConfig": {
|
|
34
34
|
"access": "public",
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
--chat-radius: unset;
|
|
10
10
|
|
|
11
11
|
/* Header */
|
|
12
|
-
--chat-header-height:
|
|
12
|
+
--chat-header-height: var(--a-chrome-app-header-height);
|
|
13
13
|
--chat-header-px: var(--a-space-4);
|
|
14
14
|
--chat-header-gap: var(--a-space-2);
|
|
15
15
|
--chat-header-border: 1px solid var(--a-border-subtle);
|
|
@@ -39,8 +39,20 @@
|
|
|
39
39
|
"Toolbar"
|
|
40
40
|
],
|
|
41
41
|
"slots": {
|
|
42
|
+
"description": {
|
|
43
|
+
"description": "Secondary metadata inside <header> or <footer> — document name, artboard size, zoom level, etc. Muted color, --a-ui-sm size."
|
|
44
|
+
},
|
|
42
45
|
"default": {
|
|
43
46
|
"description": "Author provides header, [data-editor-body] wrapping pane-ui[data-left], [data-canvas], pane-ui[data-right], and an optional footer."
|
|
47
|
+
},
|
|
48
|
+
"action": {
|
|
49
|
+
"description": "Trailing control cluster inside <header> or <footer>. The first [slot=\"action\"] child pushes itself (and siblings) to the end of the bar; subsequent [slot=\"action\"] siblings flow with gap."
|
|
50
|
+
},
|
|
51
|
+
"heading": {
|
|
52
|
+
"description": "Primary label inside <header> or <footer>. Rendered with --editor-title-weight + the strong foreground token."
|
|
53
|
+
},
|
|
54
|
+
"icon": {
|
|
55
|
+
"description": "Leading glyph inside <header> or <footer> — status dot, app icon, zoom badge, etc. Muted color, size-aware."
|
|
44
56
|
}
|
|
45
57
|
},
|
|
46
58
|
"states": [
|
|
@@ -20,6 +20,23 @@ slots:
|
|
|
20
20
|
description: >-
|
|
21
21
|
Author provides header, [data-editor-body] wrapping pane-ui[data-left],
|
|
22
22
|
[data-canvas], pane-ui[data-right], and an optional footer.
|
|
23
|
+
icon:
|
|
24
|
+
description: >-
|
|
25
|
+
Leading glyph inside <header> or <footer> — status dot, app icon,
|
|
26
|
+
zoom badge, etc. Muted color, size-aware.
|
|
27
|
+
heading:
|
|
28
|
+
description: >-
|
|
29
|
+
Primary label inside <header> or <footer>. Rendered with
|
|
30
|
+
--editor-title-weight + the strong foreground token.
|
|
31
|
+
description:
|
|
32
|
+
description: >-
|
|
33
|
+
Secondary metadata inside <header> or <footer> — document name,
|
|
34
|
+
artboard size, zoom level, etc. Muted color, --a-ui-sm size.
|
|
35
|
+
action:
|
|
36
|
+
description: >-
|
|
37
|
+
Trailing control cluster inside <header> or <footer>. The first
|
|
38
|
+
[slot="action"] child pushes itself (and siblings) to the end of
|
|
39
|
+
the bar; subsequent [slot="action"] siblings flow with gap.
|
|
23
40
|
|
|
24
41
|
states:
|
|
25
42
|
- name: idle
|
|
@@ -20,7 +20,16 @@ adia-editor-ui {
|
|
|
20
20
|
background: var(--editor-bg);
|
|
21
21
|
}
|
|
22
22
|
|
|
23
|
-
/* ── Top bar ──
|
|
23
|
+
/* ── Top bar ──
|
|
24
|
+
Slot contract (shared with > footer below):
|
|
25
|
+
[slot="icon"] leading glyph (status dot, app icon, etc.)
|
|
26
|
+
[slot="heading"] primary label; strong-weight token
|
|
27
|
+
[slot="description"] secondary metadata; muted
|
|
28
|
+
[slot="action"] trailing control cluster; first pushes to end
|
|
29
|
+
Authors may also place raw inline content (spans, buttons) directly
|
|
30
|
+
— those flow in source order. `[data-title]` / `<span data-spacer>`
|
|
31
|
+
are kept working for one release as deprecated hooks; migrate to
|
|
32
|
+
slots. */
|
|
24
33
|
adia-editor-ui > header {
|
|
25
34
|
display: flex;
|
|
26
35
|
align-items: center;
|
|
@@ -33,11 +42,36 @@ adia-editor-ui > header {
|
|
|
33
42
|
flex-shrink: 0;
|
|
34
43
|
}
|
|
35
44
|
|
|
36
|
-
adia-editor-ui > header [data-title]
|
|
45
|
+
adia-editor-ui > header [data-title],
|
|
46
|
+
adia-editor-ui > header > [slot="heading"] {
|
|
37
47
|
font-weight: var(--editor-title-weight);
|
|
38
48
|
color: var(--editor-bar-fg-strong);
|
|
39
49
|
}
|
|
40
50
|
|
|
51
|
+
adia-editor-ui > header > [slot="icon"] {
|
|
52
|
+
display: flex;
|
|
53
|
+
align-items: center;
|
|
54
|
+
flex-shrink: 0;
|
|
55
|
+
color: var(--editor-bar-fg);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
adia-editor-ui > header > [slot="description"] {
|
|
59
|
+
color: var(--editor-bar-fg);
|
|
60
|
+
font-size: var(--a-ui-sm);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
adia-editor-ui > header > [slot="action"] {
|
|
64
|
+
display: flex;
|
|
65
|
+
align-items: center;
|
|
66
|
+
gap: var(--editor-bar-gap);
|
|
67
|
+
flex-shrink: 0;
|
|
68
|
+
margin-inline-start: auto;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
adia-editor-ui > header > [slot="action"] ~ [slot="action"] {
|
|
72
|
+
margin-inline-start: 0;
|
|
73
|
+
}
|
|
74
|
+
|
|
41
75
|
/* ── Body: pane | canvas | pane ── */
|
|
42
76
|
adia-editor-ui > [data-editor-body] {
|
|
43
77
|
display: flex;
|
|
@@ -72,7 +106,11 @@ adia-editor-ui pane-ui[data-right] {
|
|
|
72
106
|
width: var(--editor-pane-width-right);
|
|
73
107
|
}
|
|
74
108
|
|
|
75
|
-
/* ── Bottom bar ──
|
|
109
|
+
/* ── Bottom bar ──
|
|
110
|
+
Same slot contract as > header above (icon / heading / description
|
|
111
|
+
/ action). Statusbar is structurally identical to the topbar —
|
|
112
|
+
both are 36px-min chrome bands with left-aligned label content and
|
|
113
|
+
a trailing action cluster. */
|
|
76
114
|
adia-editor-ui > footer {
|
|
77
115
|
display: flex;
|
|
78
116
|
align-items: center;
|
|
@@ -84,3 +122,32 @@ adia-editor-ui > footer {
|
|
|
84
122
|
color: var(--editor-bar-fg);
|
|
85
123
|
flex-shrink: 0;
|
|
86
124
|
}
|
|
125
|
+
|
|
126
|
+
adia-editor-ui > footer > [slot="heading"] {
|
|
127
|
+
font-weight: var(--editor-title-weight);
|
|
128
|
+
color: var(--editor-bar-fg-strong);
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
adia-editor-ui > footer > [slot="icon"] {
|
|
132
|
+
display: flex;
|
|
133
|
+
align-items: center;
|
|
134
|
+
flex-shrink: 0;
|
|
135
|
+
color: var(--editor-bar-fg);
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
adia-editor-ui > footer > [slot="description"] {
|
|
139
|
+
color: var(--editor-bar-fg);
|
|
140
|
+
font-size: var(--a-ui-sm);
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
adia-editor-ui > footer > [slot="action"] {
|
|
144
|
+
display: flex;
|
|
145
|
+
align-items: center;
|
|
146
|
+
gap: var(--editor-bar-gap);
|
|
147
|
+
flex-shrink: 0;
|
|
148
|
+
margin-inline-start: auto;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
adia-editor-ui > footer > [slot="action"] ~ [slot="action"] {
|
|
152
|
+
margin-inline-start: 0;
|
|
153
|
+
}
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
--editor-border: 1px solid var(--a-border-subtle);
|
|
9
9
|
|
|
10
10
|
/* Top/bottom bars */
|
|
11
|
-
--editor-bar-height:
|
|
11
|
+
--editor-bar-height: var(--a-chrome-pane-header-height);
|
|
12
12
|
--editor-bar-px: var(--a-space-3);
|
|
13
13
|
--editor-bar-gap: var(--a-space-2);
|
|
14
14
|
--editor-bar-font: var(--a-ui-size);
|
|
@@ -16,6 +16,9 @@
|
|
|
16
16
|
--nav-group-bg-hover: var(--a-bg-muted);
|
|
17
17
|
--nav-group-icon-size: calc(var(--nav-group-row-height) - var(--a-space-2));
|
|
18
18
|
--nav-group-badge-size: var(--a-ui-sm);
|
|
19
|
+
|
|
20
|
+
--nav-item-child-height: var(--a-size-sm);
|
|
21
|
+
--nav-item-child-font: var(--nav-group-font-size);
|
|
19
22
|
}
|
|
20
23
|
|
|
21
24
|
:scope {
|
|
@@ -74,8 +74,20 @@
|
|
|
74
74
|
"Command"
|
|
75
75
|
],
|
|
76
76
|
"slots": {
|
|
77
|
+
"description": {
|
|
78
|
+
"description": "Secondary metadata inside any chrome bar. Muted + --a-ui-sm size."
|
|
79
|
+
},
|
|
77
80
|
"default": {
|
|
78
81
|
"description": "Author-supplied page DOM. Expected structure — aside[data-sidebar] for navigation, main for content, optional dialog[data-command] for Cmd+K."
|
|
82
|
+
},
|
|
83
|
+
"action": {
|
|
84
|
+
"description": "Trailing control cluster inside any chrome bar. The first [slot=\"action\"] child pushes itself (and siblings) to the end; subsequent siblings flow with gap. Coexists with legacy <span data-spacer> / <div data-actions> hooks for one release — new code should prefer slots."
|
|
85
|
+
},
|
|
86
|
+
"heading": {
|
|
87
|
+
"description": "Primary label inside any chrome bar. Medium-weight + strong fg."
|
|
88
|
+
},
|
|
89
|
+
"icon": {
|
|
90
|
+
"description": "Leading glyph inside any chrome bar — > main > header / footer and [data-sidebar] > header / footer. Muted color, flex-align."
|
|
79
91
|
}
|
|
80
92
|
},
|
|
81
93
|
"states": [
|
|
@@ -39,6 +39,23 @@ slots:
|
|
|
39
39
|
description: >-
|
|
40
40
|
Author-supplied page DOM. Expected structure — aside[data-sidebar] for
|
|
41
41
|
navigation, main for content, optional dialog[data-command] for Cmd+K.
|
|
42
|
+
icon:
|
|
43
|
+
description: >-
|
|
44
|
+
Leading glyph inside any chrome bar — > main > header / footer and
|
|
45
|
+
[data-sidebar] > header / footer. Muted color, flex-align.
|
|
46
|
+
heading:
|
|
47
|
+
description: >-
|
|
48
|
+
Primary label inside any chrome bar. Medium-weight + strong fg.
|
|
49
|
+
description:
|
|
50
|
+
description: >-
|
|
51
|
+
Secondary metadata inside any chrome bar. Muted + --a-ui-sm size.
|
|
52
|
+
action:
|
|
53
|
+
description: >-
|
|
54
|
+
Trailing control cluster inside any chrome bar. The first
|
|
55
|
+
[slot="action"] child pushes itself (and siblings) to the end;
|
|
56
|
+
subsequent siblings flow with gap. Coexists with legacy
|
|
57
|
+
<span data-spacer> / <div data-actions> hooks for one release —
|
|
58
|
+
new code should prefer slots.
|
|
42
59
|
|
|
43
60
|
states:
|
|
44
61
|
- name: idle
|
|
@@ -13,7 +13,19 @@ app-shell-ui > main {
|
|
|
13
13
|
}
|
|
14
14
|
|
|
15
15
|
/* ── Main > header (topbar) ──
|
|
16
|
-
Contains: sidebar toggle, breadcrumb, spacer, action buttons
|
|
16
|
+
Contains: sidebar toggle, breadcrumb, spacer, action buttons.
|
|
17
|
+
|
|
18
|
+
Slot contract (shared with > main > footer and [data-sidebar] >
|
|
19
|
+
header/footer) — identical to card-ui / drawer-ui / adia-editor-ui:
|
|
20
|
+
[slot="icon"] leading glyph
|
|
21
|
+
[slot="heading"] primary label; strong weight + strong fg
|
|
22
|
+
[slot="description"] secondary metadata; muted fg + --a-ui-sm
|
|
23
|
+
[slot="action"] trailing cluster; first pushes to end
|
|
24
|
+
The legacy data-sidebar-toggle / breadcrumb-ui / <span data-spacer>
|
|
25
|
+
/ <div data-actions> hooks (see app-shell.helpers.css) remain
|
|
26
|
+
fully supported — slots are additive, not a replacement. Use slots
|
|
27
|
+
for simpler chrome surfaces; keep breadcrumb + data-actions for
|
|
28
|
+
docs-style shells where those conventions carry semantic weight. */
|
|
17
29
|
app-shell-ui > main > header {
|
|
18
30
|
display: flex;
|
|
19
31
|
align-items: center;
|
|
@@ -25,6 +37,31 @@ app-shell-ui > main > header {
|
|
|
25
37
|
flex-shrink: 0;
|
|
26
38
|
}
|
|
27
39
|
|
|
40
|
+
app-shell-ui > main > header > [slot="icon"] {
|
|
41
|
+
display: flex;
|
|
42
|
+
align-items: center;
|
|
43
|
+
flex-shrink: 0;
|
|
44
|
+
color: var(--page-header-fg-muted);
|
|
45
|
+
}
|
|
46
|
+
app-shell-ui > main > header > [slot="heading"] {
|
|
47
|
+
font-weight: var(--a-weight-medium);
|
|
48
|
+
color: var(--a-fg);
|
|
49
|
+
}
|
|
50
|
+
app-shell-ui > main > header > [slot="description"] {
|
|
51
|
+
color: var(--page-header-fg-muted);
|
|
52
|
+
font-size: var(--a-ui-sm);
|
|
53
|
+
}
|
|
54
|
+
app-shell-ui > main > header > [slot="action"] {
|
|
55
|
+
display: flex;
|
|
56
|
+
align-items: center;
|
|
57
|
+
gap: var(--page-actions-gap);
|
|
58
|
+
flex-shrink: 0;
|
|
59
|
+
margin-inline-start: auto;
|
|
60
|
+
}
|
|
61
|
+
app-shell-ui > main > header > [slot="action"] ~ [slot="action"] {
|
|
62
|
+
margin-inline-start: 0;
|
|
63
|
+
}
|
|
64
|
+
|
|
28
65
|
/* ── Main > section (scroll container) ──
|
|
29
66
|
Wraps [data-content-root]. Scrolls vertically, hides scrollbar. */
|
|
30
67
|
app-shell-ui > main > section {
|
|
@@ -39,7 +76,11 @@ app-shell-ui > main > section {
|
|
|
39
76
|
app-shell-ui > main > section::-webkit-scrollbar { display: none; }
|
|
40
77
|
|
|
41
78
|
/* ── Main > footer (status bar) ──
|
|
42
|
-
|
|
79
|
+
Legacy pattern: last-child auto-pushed to trailing edge via
|
|
80
|
+
margin-inline-start: auto (works when authors use a simple
|
|
81
|
+
<span>…</span><span>version</span> shape).
|
|
82
|
+
Slot pattern: same icon / heading / description / action vocabulary
|
|
83
|
+
as > main > header (see comment block above). */
|
|
43
84
|
app-shell-ui > main > footer {
|
|
44
85
|
flex-shrink: 0;
|
|
45
86
|
display: flex;
|
|
@@ -53,6 +94,34 @@ app-shell-ui > main > footer {
|
|
|
53
94
|
color: var(--page-header-fg-muted);
|
|
54
95
|
}
|
|
55
96
|
|
|
56
|
-
|
|
97
|
+
/* Legacy: bare <span>…</span><span>version</span> shapes. Only kicks
|
|
98
|
+
in when NO slot="action" is present, so it doesn't fight the slot
|
|
99
|
+
rule below. */
|
|
100
|
+
app-shell-ui > main > footer:not(:has(> [slot="action"])) > :last-child {
|
|
57
101
|
margin-inline-start: auto;
|
|
58
102
|
}
|
|
103
|
+
|
|
104
|
+
app-shell-ui > main > footer > [slot="icon"] {
|
|
105
|
+
display: flex;
|
|
106
|
+
align-items: center;
|
|
107
|
+
flex-shrink: 0;
|
|
108
|
+
color: var(--page-header-fg-muted);
|
|
109
|
+
}
|
|
110
|
+
app-shell-ui > main > footer > [slot="heading"] {
|
|
111
|
+
font-weight: var(--a-weight-medium);
|
|
112
|
+
color: var(--a-fg);
|
|
113
|
+
}
|
|
114
|
+
app-shell-ui > main > footer > [slot="description"] {
|
|
115
|
+
color: var(--page-header-fg-muted);
|
|
116
|
+
font-size: var(--a-ui-sm);
|
|
117
|
+
}
|
|
118
|
+
app-shell-ui > main > footer > [slot="action"] {
|
|
119
|
+
display: flex;
|
|
120
|
+
align-items: center;
|
|
121
|
+
gap: var(--page-actions-gap);
|
|
122
|
+
flex-shrink: 0;
|
|
123
|
+
margin-inline-start: auto;
|
|
124
|
+
}
|
|
125
|
+
app-shell-ui > main > footer > [slot="action"] ~ [slot="action"] {
|
|
126
|
+
margin-inline-start: 0;
|
|
127
|
+
}
|
|
@@ -60,7 +60,13 @@
|
|
|
60
60
|
width: var(--page-sidebar-width-trailing);
|
|
61
61
|
}
|
|
62
62
|
|
|
63
|
-
/* ── Sidebar header / footer ──
|
|
63
|
+
/* ── Sidebar header / footer ──
|
|
64
|
+
Share the same slot contract as > main > header/footer (see
|
|
65
|
+
app-shell.main.css top-of-file comment): icon / heading /
|
|
66
|
+
description / action. Sidebar chromes are typically single-child
|
|
67
|
+
(a workspace-select or user-select) so the slot rules rarely come
|
|
68
|
+
into play — but they stay consistent for authors that compose
|
|
69
|
+
richer sidebar chromes. */
|
|
64
70
|
[data-sidebar] > header,
|
|
65
71
|
[data-sidebar] > footer {
|
|
66
72
|
display: flex;
|
|
@@ -83,6 +89,36 @@
|
|
|
83
89
|
border-top: var(--page-border);
|
|
84
90
|
}
|
|
85
91
|
|
|
92
|
+
[data-sidebar] > header > [slot="icon"],
|
|
93
|
+
[data-sidebar] > footer > [slot="icon"] {
|
|
94
|
+
display: flex;
|
|
95
|
+
align-items: center;
|
|
96
|
+
flex-shrink: 0;
|
|
97
|
+
color: var(--page-header-fg-muted);
|
|
98
|
+
}
|
|
99
|
+
[data-sidebar] > header > [slot="heading"],
|
|
100
|
+
[data-sidebar] > footer > [slot="heading"] {
|
|
101
|
+
font-weight: var(--a-weight-medium);
|
|
102
|
+
color: var(--a-fg);
|
|
103
|
+
}
|
|
104
|
+
[data-sidebar] > header > [slot="description"],
|
|
105
|
+
[data-sidebar] > footer > [slot="description"] {
|
|
106
|
+
color: var(--page-header-fg-muted);
|
|
107
|
+
font-size: var(--a-ui-sm);
|
|
108
|
+
}
|
|
109
|
+
[data-sidebar] > header > [slot="action"],
|
|
110
|
+
[data-sidebar] > footer > [slot="action"] {
|
|
111
|
+
display: flex;
|
|
112
|
+
align-items: center;
|
|
113
|
+
gap: var(--page-actions-gap);
|
|
114
|
+
flex-shrink: 0;
|
|
115
|
+
margin-inline-start: auto;
|
|
116
|
+
}
|
|
117
|
+
[data-sidebar] > header > [slot="action"] ~ [slot="action"],
|
|
118
|
+
[data-sidebar] > footer > [slot="action"] ~ [slot="action"] {
|
|
119
|
+
margin-inline-start: 0;
|
|
120
|
+
}
|
|
121
|
+
|
|
86
122
|
/* ── Sidebar section (scrollable body) ── */
|
|
87
123
|
[data-sidebar] > section {
|
|
88
124
|
flex: 1;
|
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
--page-main-border: var(--page-border); /* main inline borders (separate so modes can override) */
|
|
20
20
|
|
|
21
21
|
/* Header / footer bars — shared by topbar + bottombar */
|
|
22
|
-
--page-header-height:
|
|
22
|
+
--page-header-height: var(--a-chrome-app-header-height);
|
|
23
23
|
--page-header-px: var(--a-space-3);
|
|
24
24
|
--page-header-gap: var(--a-space-3);
|
|
25
25
|
--page-header-font: var(--a-ui-size);
|
|
@@ -108,8 +108,6 @@
|
|
|
108
108
|
--nav-item-trailing-border: var(--a-border-subtle);
|
|
109
109
|
--nav-item-trailing-radius: var(--a-radius-sm);
|
|
110
110
|
--nav-item-trailing-px: var(--a-space-0-5);
|
|
111
|
-
--nav-item-child-height: var(--a-size-sm);
|
|
112
|
-
--nav-item-child-font: var(--a-ui-sm);
|
|
113
111
|
|
|
114
112
|
/* Global icon size bump */
|
|
115
113
|
--a-icon-size: 18px;
|
package/styles/tokens.css
CHANGED
|
@@ -102,6 +102,18 @@
|
|
|
102
102
|
--a-size-lg: calc(var(--a-density) * 2.25rem); /* 36px at d=1 */
|
|
103
103
|
--a-size: var(--a-size-md);
|
|
104
104
|
|
|
105
|
+
/* ── Chrome heights — global app/feature UI ──
|
|
106
|
+
App-level chrome (top-level headers, footers, toolbars) is 48px;
|
|
107
|
+
pane-level chrome (pane headers, footers, toolbars) is 36px.
|
|
108
|
+
Fixed values — these are structural measurements, not typographic,
|
|
109
|
+
so they don't scale with --a-density. */
|
|
110
|
+
--a-chrome-app-header-height: 48px;
|
|
111
|
+
--a-chrome-app-footer-height: 48px;
|
|
112
|
+
--a-chrome-app-toolbar-height: 48px;
|
|
113
|
+
--a-chrome-pane-header-height: 36px;
|
|
114
|
+
--a-chrome-pane-footer-height: 36px;
|
|
115
|
+
--a-chrome-pane-toolbar-height: 36px;
|
|
116
|
+
|
|
105
117
|
/* ── Toggle-control size (check, radio, switch) ──
|
|
106
118
|
Tighter additive scale than --a-size: 16 / 20 / 24 px at d=1. */
|
|
107
119
|
--a-toggle-size: calc(var(--a-size-sm) - var(--a-space-1)); /* 20px at d=1 — md default */
|
|
@@ -1,93 +0,0 @@
|
|
|
1
|
-
<!doctype html>
|
|
2
|
-
<html lang="en">
|
|
3
|
-
<head>
|
|
4
|
-
<meta charset="UTF-8" />
|
|
5
|
-
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
6
|
-
<title>AdiaUI — Chat</title>
|
|
7
|
-
<link rel="stylesheet" href="../../styles/tokens.css" />
|
|
8
|
-
<link rel="stylesheet" href="../../styles/styles.css" />
|
|
9
|
-
<link rel="stylesheet" href="adia-chat.css" />
|
|
10
|
-
<style>
|
|
11
|
-
body {
|
|
12
|
-
font-family: var(--a-font-family);
|
|
13
|
-
margin: 0;
|
|
14
|
-
height: 100dvh;
|
|
15
|
-
display: flex;
|
|
16
|
-
flex-direction: column;
|
|
17
|
-
}
|
|
18
|
-
</style>
|
|
19
|
-
</head>
|
|
20
|
-
<body>
|
|
21
|
-
|
|
22
|
-
<adia-chat-ui id="chat" proxy-url="/api/chat" model="claude-haiku-4-5-20251001"
|
|
23
|
-
style="flex:1; border:none; border-radius:0;">
|
|
24
|
-
<header>
|
|
25
|
-
<span data-chat-name>Factory Chat</span>
|
|
26
|
-
<span data-chat-status></span>
|
|
27
|
-
</header>
|
|
28
|
-
<section data-chat-messages>
|
|
29
|
-
<empty-state-ui data-chat-empty icon="chat-circle"
|
|
30
|
-
heading="AdiaUI Chat"
|
|
31
|
-
description="Type a message to start a conversation. Connects to LLM model via proxy if available.">
|
|
32
|
-
</empty-state-ui>
|
|
33
|
-
</section>
|
|
34
|
-
<footer>
|
|
35
|
-
<chat-input-ui data-chat-input placeholder="Message Claude..."></chat-input-ui>
|
|
36
|
-
</footer>
|
|
37
|
-
</adia-chat-ui>
|
|
38
|
-
|
|
39
|
-
<script type="module">
|
|
40
|
-
import '../../components/index.js';
|
|
41
|
-
import '../../patterns/index.js';
|
|
42
|
-
|
|
43
|
-
const chat = document.getElementById('chat');
|
|
44
|
-
|
|
45
|
-
// Wire the model picker inside chat-input-ui. Same list as
|
|
46
|
-
// /site/playground/gen-ui — extract to a shared constant when a third
|
|
47
|
-
// consumer appears.
|
|
48
|
-
customElements.whenDefined('chat-input-ui').then(() => {
|
|
49
|
-
const chatInput = chat.querySelector('[data-chat-input]');
|
|
50
|
-
if (!chatInput) return;
|
|
51
|
-
chatInput.models = [
|
|
52
|
-
{ label: 'Anthropic', options: [
|
|
53
|
-
{ value: 'claude-haiku-4-5-20251001', label: 'Haiku 4.5' },
|
|
54
|
-
{ value: 'claude-sonnet-4-6', label: 'Sonnet 4.6' },
|
|
55
|
-
]},
|
|
56
|
-
{ label: 'OpenAI', options: [
|
|
57
|
-
{ value: 'gpt-4o-mini', label: 'GPT-4o Mini' },
|
|
58
|
-
]},
|
|
59
|
-
{ label: 'Google', options: [
|
|
60
|
-
{ value: 'gemini-2.5-flash', label: 'Gemini 2.5 Flash' },
|
|
61
|
-
]},
|
|
62
|
-
];
|
|
63
|
-
chatInput.model = 'claude-haiku-4-5-20251001';
|
|
64
|
-
// Keep <adia-chat-ui>'s `model` attribute in lockstep with the chat-input
|
|
65
|
-
// picker so every send uses the user's current selection.
|
|
66
|
-
chatInput.addEventListener('change', () => {
|
|
67
|
-
if (chatInput.model) chat.setAttribute('model', chatInput.model);
|
|
68
|
-
});
|
|
69
|
-
});
|
|
70
|
-
|
|
71
|
-
// Test proxy availability — fallback to simulated if not running
|
|
72
|
-
fetch('/api/chat', { method: 'OPTIONS' }).catch(() => {
|
|
73
|
-
chat.removeAttribute('proxy-url');
|
|
74
|
-
const empty = chat.querySelector('[data-chat-empty]');
|
|
75
|
-
if (empty) empty.setAttribute('description', 'No API proxy detected. Run `node server.js` with API keys. Responses are simulated.');
|
|
76
|
-
|
|
77
|
-
chat.addEventListener('submit', async (e) => {
|
|
78
|
-
const { text } = e.detail;
|
|
79
|
-
chat.appendMessage({ role: 'user', content: text });
|
|
80
|
-
chat.appendMessage({ role: 'assistant', content: '' });
|
|
81
|
-
chat.startStreaming();
|
|
82
|
-
|
|
83
|
-
const response = `You said: "${text}"\n\nThis is a **simulated** response.\n\n\`\`\`js\nconsole.log("Hello from AdiaUI!");\n\`\`\`\n\nStart the proxy with \`node server.js\` for real LLM responses.`;
|
|
84
|
-
for (const char of response) {
|
|
85
|
-
await new Promise(r => setTimeout(r, 12));
|
|
86
|
-
chat.appendChunk(char);
|
|
87
|
-
}
|
|
88
|
-
chat.stopStreaming();
|
|
89
|
-
});
|
|
90
|
-
});
|
|
91
|
-
</script>
|
|
92
|
-
</body>
|
|
93
|
-
</html>
|
|
@@ -1,179 +0,0 @@
|
|
|
1
|
-
<!doctype html>
|
|
2
|
-
<html lang="en">
|
|
3
|
-
<head>
|
|
4
|
-
<meta charset="UTF-8" />
|
|
5
|
-
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
6
|
-
<title>AdiaUI — Editor</title>
|
|
7
|
-
<link rel="stylesheet" href="../../styles/tokens.css" />
|
|
8
|
-
<link rel="stylesheet" href="../../styles/styles.css" />
|
|
9
|
-
<link rel="stylesheet" href="adia-editor.css" />
|
|
10
|
-
<style>
|
|
11
|
-
body {
|
|
12
|
-
font-family: var(--a-font-family);
|
|
13
|
-
margin: 0;
|
|
14
|
-
height: 100dvh;
|
|
15
|
-
display: flex;
|
|
16
|
-
flex-direction: column;
|
|
17
|
-
}
|
|
18
|
-
</style>
|
|
19
|
-
</head>
|
|
20
|
-
<body>
|
|
21
|
-
|
|
22
|
-
<adia-editor-ui style="flex:1;">
|
|
23
|
-
<header>
|
|
24
|
-
<span data-title>AdiaUI</span>
|
|
25
|
-
<span data-spacer></span>
|
|
26
|
-
<button-ui icon="moon" variant="ghost" size="sm"></button-ui>
|
|
27
|
-
<button-ui icon="gear" variant="ghost" size="sm"></button-ui>
|
|
28
|
-
</header>
|
|
29
|
-
|
|
30
|
-
<div data-editor-body>
|
|
31
|
-
|
|
32
|
-
<!-- ═══ LEFT PANE — Navigator ═══ -->
|
|
33
|
-
<pane-ui data-left resizable>
|
|
34
|
-
<header>Navigator</header>
|
|
35
|
-
<section>
|
|
36
|
-
<header>Layers</header>
|
|
37
|
-
<tree-ui>
|
|
38
|
-
<tree-item-ui text="Page" icon="folder">
|
|
39
|
-
<tree-item-ui text="Header" icon="folder">
|
|
40
|
-
<tree-item-ui text="Logo" icon="folder"></tree-item-ui>
|
|
41
|
-
<tree-item-ui text="Nav" icon="folder">
|
|
42
|
-
<tree-item-ui text="Home" icon="folder"></tree-item-ui>
|
|
43
|
-
<tree-item-ui text="About" icon="folder"></tree-item-ui>
|
|
44
|
-
<tree-item-ui text="Contact" icon="folder"></tree-item-ui>
|
|
45
|
-
</tree-item-ui>
|
|
46
|
-
</tree-item-ui>
|
|
47
|
-
<tree-item-ui text="Hero" icon="folder">
|
|
48
|
-
<tree-item-ui text="Heading" icon="folder"></tree-item-ui>
|
|
49
|
-
<tree-item-ui text="Subheading" icon="folder"></tree-item-ui>
|
|
50
|
-
<tree-item-ui text="CTA Button" icon="folder"></tree-item-ui>
|
|
51
|
-
</tree-item-ui>
|
|
52
|
-
<tree-item-ui text="Card Grid" icon="folder">
|
|
53
|
-
<tree-item-ui text="Card 1" icon="folder"></tree-item-ui>
|
|
54
|
-
<tree-item-ui text="Card 2" icon="folder"></tree-item-ui>
|
|
55
|
-
<tree-item-ui text="Card 3" icon="folder"></tree-item-ui>
|
|
56
|
-
</tree-item-ui>
|
|
57
|
-
<tree-item-ui text="Footer" icon="folder">
|
|
58
|
-
<tree-item-ui text="Links" icon="folder"></tree-item-ui>
|
|
59
|
-
<tree-item-ui text="Copyright" icon="folder"></tree-item-ui>
|
|
60
|
-
</tree-item-ui>
|
|
61
|
-
</tree-item-ui>
|
|
62
|
-
</tree-ui>
|
|
63
|
-
</section>
|
|
64
|
-
</pane-ui>
|
|
65
|
-
|
|
66
|
-
<!-- ═══ CANVAS ═══ -->
|
|
67
|
-
<div data-canvas>Canvas</div>
|
|
68
|
-
|
|
69
|
-
<!-- ═══ RIGHT PANE — Inspector ═══ -->
|
|
70
|
-
<pane-ui data-right resizable>
|
|
71
|
-
<header>Inspector</header>
|
|
72
|
-
|
|
73
|
-
<section>
|
|
74
|
-
<header>Layout</header>
|
|
75
|
-
<div data-col style="padding:var(--a-space-2);">
|
|
76
|
-
<div style="display:grid; grid-template-columns:1fr 1fr; gap:var(--a-space-2);">
|
|
77
|
-
<input-ui prefix="X" placeholder="0" suffix="px"></input-ui>
|
|
78
|
-
<input-ui prefix="Y" placeholder="0" suffix="px"></input-ui>
|
|
79
|
-
<input-ui prefix="W" placeholder="auto" suffix="px"></input-ui>
|
|
80
|
-
<input-ui prefix="H" placeholder="auto" suffix="px"></input-ui>
|
|
81
|
-
</div>
|
|
82
|
-
<select-ui id="display-select" label="Display" placeholder="block"></select-ui>
|
|
83
|
-
<select-ui id="position-select" label="Position" placeholder="relative"></select-ui>
|
|
84
|
-
</div>
|
|
85
|
-
</section>
|
|
86
|
-
|
|
87
|
-
<section>
|
|
88
|
-
<header>Spacing</header>
|
|
89
|
-
<div data-col style="padding:var(--a-space-2);">
|
|
90
|
-
<div style="display:grid; grid-template-columns:1fr 1fr; gap:var(--a-space-2);">
|
|
91
|
-
<range-ui label="Padding" value="16" min="0" max="64" step="1" suffix="px"></range-ui>
|
|
92
|
-
<range-ui label="Margin" value="0" min="0" max="64" step="1" suffix="px"></range-ui>
|
|
93
|
-
<range-ui label="Gap" value="8" min="0" max="48" step="1" suffix="px"></range-ui>
|
|
94
|
-
<range-ui label="Radius" value="6" min="0" max="32" step="1" suffix="px"></range-ui>
|
|
95
|
-
</div>
|
|
96
|
-
</div>
|
|
97
|
-
</section>
|
|
98
|
-
|
|
99
|
-
<section>
|
|
100
|
-
<header>Typography</header>
|
|
101
|
-
<div data-col style="padding:var(--a-space-2);">
|
|
102
|
-
<select-ui id="font-select" label="Family" placeholder="GT Standard"></select-ui>
|
|
103
|
-
<div style="display:grid; grid-template-columns:1fr 1fr; gap:var(--a-space-2);">
|
|
104
|
-
<range-ui label="Size" value="14" min="8" max="72" step="1" suffix="px"></range-ui>
|
|
105
|
-
<range-ui label="Weight" value="400" min="100" max="900" step="100"></range-ui>
|
|
106
|
-
<range-ui label="Leading" value="1.5" min="0.8" max="2.5" step="0.05"></range-ui>
|
|
107
|
-
<range-ui label="Tracking" value="0" min="-0.05" max="0.1" step="0.005" suffix="em"></range-ui>
|
|
108
|
-
</div>
|
|
109
|
-
<segmented-ui value="left">
|
|
110
|
-
<segment-ui value="left" text="Left"></segment-ui>
|
|
111
|
-
<segment-ui value="center" text="Center"></segment-ui>
|
|
112
|
-
<segment-ui value="right" text="Right"></segment-ui>
|
|
113
|
-
</segmented-ui>
|
|
114
|
-
</div>
|
|
115
|
-
</section>
|
|
116
|
-
|
|
117
|
-
<section>
|
|
118
|
-
<header>Appearance</header>
|
|
119
|
-
<div data-col style="padding:var(--a-space-2);">
|
|
120
|
-
<input-ui label="Background" placeholder="#000000" prefix="#"></input-ui>
|
|
121
|
-
<input-ui label="Border" placeholder="none"></input-ui>
|
|
122
|
-
<range-ui label="Opacity" value="1" min="0" max="1" step="0.01"></range-ui>
|
|
123
|
-
<select-ui id="overflow-select" label="Overflow" placeholder="visible"></select-ui>
|
|
124
|
-
</div>
|
|
125
|
-
</section>
|
|
126
|
-
|
|
127
|
-
<footer>
|
|
128
|
-
<button-ui text="Apply" variant="primary" stretch></button-ui>
|
|
129
|
-
</footer>
|
|
130
|
-
</pane-ui>
|
|
131
|
-
|
|
132
|
-
</div>
|
|
133
|
-
|
|
134
|
-
<footer>
|
|
135
|
-
<span>Ready</span>
|
|
136
|
-
<span data-spacer></span>
|
|
137
|
-
<span>1280 × 800</span>
|
|
138
|
-
<span>100%</span>
|
|
139
|
-
</footer>
|
|
140
|
-
</adia-editor-ui>
|
|
141
|
-
|
|
142
|
-
<script type="module">
|
|
143
|
-
import '../../components/index.js';
|
|
144
|
-
import '../../patterns/index.js';
|
|
145
|
-
|
|
146
|
-
customElements.whenDefined('select-ui').then(() => {
|
|
147
|
-
document.getElementById('display-select').options = [
|
|
148
|
-
{ value: 'block', label: 'Block' },
|
|
149
|
-
{ value: 'flex', label: 'Flex' },
|
|
150
|
-
{ value: 'grid', label: 'Grid' },
|
|
151
|
-
{ value: 'inline', label: 'Inline' },
|
|
152
|
-
{ value: 'none', label: 'None' },
|
|
153
|
-
];
|
|
154
|
-
document.getElementById('position-select').options = [
|
|
155
|
-
{ value: 'relative', label: 'Relative' },
|
|
156
|
-
{ value: 'absolute', label: 'Absolute' },
|
|
157
|
-
{ value: 'fixed', label: 'Fixed' },
|
|
158
|
-
{ value: 'sticky', label: 'Sticky' },
|
|
159
|
-
];
|
|
160
|
-
document.getElementById('font-select').options = [
|
|
161
|
-
{ label: 'Sans', options: [
|
|
162
|
-
{ value: 'gt-standard', label: 'GT Standard' },
|
|
163
|
-
{ value: 'supply-sans', label: 'Supply Sans' },
|
|
164
|
-
]},
|
|
165
|
-
{ label: 'Mono', options: [
|
|
166
|
-
{ value: 'gt-standard-mono', label: 'GT Standard Mono' },
|
|
167
|
-
{ value: 'supply-mono', label: 'Supply Mono' },
|
|
168
|
-
]},
|
|
169
|
-
];
|
|
170
|
-
document.getElementById('overflow-select').options = [
|
|
171
|
-
{ value: 'visible', label: 'Visible' },
|
|
172
|
-
{ value: 'hidden', label: 'Hidden' },
|
|
173
|
-
{ value: 'auto', label: 'Auto' },
|
|
174
|
-
{ value: 'scroll', label: 'Scroll' },
|
|
175
|
-
];
|
|
176
|
-
});
|
|
177
|
-
</script>
|
|
178
|
-
</body>
|
|
179
|
-
</html>
|
|
@@ -1,112 +0,0 @@
|
|
|
1
|
-
<!doctype html>
|
|
2
|
-
<html lang="en">
|
|
3
|
-
<head>
|
|
4
|
-
<meta charset="UTF-8" />
|
|
5
|
-
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
6
|
-
<title>AdiaUI — App Shell</title>
|
|
7
|
-
<link rel="stylesheet" href="../../styles/tokens.css" />
|
|
8
|
-
<link rel="stylesheet" href="../../styles/styles.css" />
|
|
9
|
-
<link rel="stylesheet" href="app-shell.css" />
|
|
10
|
-
<link rel="stylesheet" href="app-nav.css" />
|
|
11
|
-
</head>
|
|
12
|
-
<body>
|
|
13
|
-
<app-shell-ui mode="rounded borderless">
|
|
14
|
-
|
|
15
|
-
<!-- ═══════════════ LEFT SIDEBAR ═══════════════ -->
|
|
16
|
-
<aside data-sidebar="leading">
|
|
17
|
-
<header>
|
|
18
|
-
<select-ui id="workspace-select" avatar="" value="adia-ui" variant="ghost" style="flex:1"></select-ui>
|
|
19
|
-
</header>
|
|
20
|
-
|
|
21
|
-
<section>
|
|
22
|
-
<app-nav-ui id="nav">
|
|
23
|
-
<app-nav-item-ui icon="magnifying-glass" text="Search" value="search">
|
|
24
|
-
<span slot="icon"><icon-ui name="magnifying-glass"></icon-ui></span>
|
|
25
|
-
<span slot="text">Search</span>
|
|
26
|
-
</app-nav-item-ui>
|
|
27
|
-
<hr data-nav-divider />
|
|
28
|
-
<app-nav-group-ui icon="house" text="Home">
|
|
29
|
-
<app-nav-item-ui text="Dashboard" value="dashboard" selected></app-nav-item-ui>
|
|
30
|
-
<app-nav-item-ui text="Analytics" value="analytics"></app-nav-item-ui>
|
|
31
|
-
<app-nav-item-ui text="Reports" value="reports"></app-nav-item-ui>
|
|
32
|
-
</app-nav-group-ui>
|
|
33
|
-
<app-nav-group-ui icon="gear" text="Settings">
|
|
34
|
-
<app-nav-item-ui text="General" value="general"></app-nav-item-ui>
|
|
35
|
-
<app-nav-item-ui text="Team" value="team"></app-nav-item-ui>
|
|
36
|
-
<app-nav-item-ui text="Billing" value="billing"></app-nav-item-ui>
|
|
37
|
-
</app-nav-group-ui>
|
|
38
|
-
</app-nav-ui>
|
|
39
|
-
</section>
|
|
40
|
-
|
|
41
|
-
<footer>
|
|
42
|
-
<select-ui id="user-select" avatar="https://i.pravatar.cc/32?u=demo" value="demo" variant="ghost" style="flex:1"></select-ui>
|
|
43
|
-
</footer>
|
|
44
|
-
<div data-resize></div>
|
|
45
|
-
</aside>
|
|
46
|
-
|
|
47
|
-
<!-- ═══════════════ MAIN ═══════════════ -->
|
|
48
|
-
<main>
|
|
49
|
-
<header>
|
|
50
|
-
<button-ui data-sidebar-toggle="leading" icon="sidebar" variant="ghost" size="sm"></button-ui>
|
|
51
|
-
<breadcrumb-ui>
|
|
52
|
-
<a href="#">Home</a>
|
|
53
|
-
<span>Dashboard</span>
|
|
54
|
-
</breadcrumb-ui>
|
|
55
|
-
<span data-spacer></span>
|
|
56
|
-
<div data-actions>
|
|
57
|
-
<button-ui icon="moon" variant="ghost" size="sm"></button-ui>
|
|
58
|
-
</div>
|
|
59
|
-
</header>
|
|
60
|
-
|
|
61
|
-
<section>
|
|
62
|
-
<article data-content-root>
|
|
63
|
-
<div data-content-header>
|
|
64
|
-
<header>
|
|
65
|
-
<div>
|
|
66
|
-
<h1>Dashboard</h1>
|
|
67
|
-
<div data-actions>
|
|
68
|
-
<button-ui text="Export" variant="outline" size="sm"></button-ui>
|
|
69
|
-
</div>
|
|
70
|
-
</div>
|
|
71
|
-
<p>Welcome back. Here's what's happening.</p>
|
|
72
|
-
</header>
|
|
73
|
-
</div>
|
|
74
|
-
<div data-content-body>
|
|
75
|
-
<section data-tab-content>
|
|
76
|
-
<p style="color:var(--a-fg-muted); text-align:center;">
|
|
77
|
-
App Shell pattern demo. Resize the sidebar, toggle collapse, and explore the navigation.
|
|
78
|
-
</p>
|
|
79
|
-
</section>
|
|
80
|
-
</div>
|
|
81
|
-
</article>
|
|
82
|
-
</section>
|
|
83
|
-
|
|
84
|
-
<footer>
|
|
85
|
-
<span>AdiaUI App Shell</span>
|
|
86
|
-
<span data-spacer></span>
|
|
87
|
-
<span>v0.1.0</span>
|
|
88
|
-
</footer>
|
|
89
|
-
</main>
|
|
90
|
-
|
|
91
|
-
</app-shell-ui>
|
|
92
|
-
|
|
93
|
-
<script type="module">
|
|
94
|
-
import '../../components/index.js';
|
|
95
|
-
import '../../patterns/index.js';
|
|
96
|
-
|
|
97
|
-
customElements.whenDefined('select-ui').then(() => {
|
|
98
|
-
document.getElementById('workspace-select').options = [
|
|
99
|
-
{ label: 'Workspaces', options: [
|
|
100
|
-
{ value: 'adia-ui', icon: 'stack', label: 'AdiaUI' },
|
|
101
|
-
{ value: 'acme', icon: 'chart-bar', label: 'Acme App' },
|
|
102
|
-
]},
|
|
103
|
-
];
|
|
104
|
-
document.getElementById('user-select').options = [
|
|
105
|
-
{ header: true, avatar: 'https://i.pravatar.cc/32?u=demo', label: 'Demo User', description: 'demo@example.com' },
|
|
106
|
-
{ separator: true },
|
|
107
|
-
{ action: 'logout', icon: 'sign-out', label: 'Log out' },
|
|
108
|
-
];
|
|
109
|
-
});
|
|
110
|
-
</script>
|
|
111
|
-
</body>
|
|
112
|
-
</html>
|