@vibes.diy/base 14.3.0 → 14.3.2
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/attachments/composer-file-drop.d.ts +11 -0
- package/attachments/composer-file-drop.js +35 -0
- package/attachments/composer-file-drop.js.map +1 -0
- package/components/BuildCard.d.ts +0 -6
- package/components/BuildCard.js +5 -9
- package/components/BuildCard.js.map +1 -1
- package/components/EditorTabStrip.d.ts +2 -1
- package/components/EditorTabStrip.js +3 -3
- package/components/EditorTabStrip.js.map +1 -1
- package/components/RemixInviteView.d.ts +4 -0
- package/components/RemixInviteView.js +11 -0
- package/components/RemixInviteView.js.map +1 -0
- package/components/SharePanelView.d.ts +2 -1
- package/components/SharePanelView.js +61 -31
- package/components/SharePanelView.js.map +1 -1
- package/components/StyleControls.js +73 -39
- package/components/StyleControls.js.map +1 -1
- package/components/SubTabStrip.d.ts +3 -1
- package/components/SubTabStrip.js +11 -8
- package/components/SubTabStrip.js.map +1 -1
- package/components/UnifiedVibeCard.d.ts +3 -0
- package/components/UnifiedVibeCard.js +520 -218
- package/components/UnifiedVibeCard.js.map +1 -1
- package/components/index.d.ts +1 -0
- package/components/index.js +1 -0
- package/components/index.js.map +1 -1
- package/index.d.ts +1 -0
- package/index.js +1 -0
- package/index.js.map +1 -1
- package/package.json +4 -4
|
@@ -14,10 +14,13 @@ import { CodingIndicator } from "./CodingIndicator.js";
|
|
|
14
14
|
import { CopyLinkIconButton } from "./LinkLineControls.js";
|
|
15
15
|
import { AttachmentButton, AttachmentChips } from "./AttachmentRow.js";
|
|
16
16
|
import { useAttachments } from "../attachments/use-attachments.js";
|
|
17
|
+
import { composerFileDrop } from "../attachments/composer-file-drop.js";
|
|
17
18
|
import { PeopleIcon } from "./icons/index.js";
|
|
18
19
|
import { HOME_BRAND_FONT } from "./homeBrandFont.js";
|
|
19
20
|
import { SAFE_AREA_TOP } from "../theme/safe-area.js";
|
|
20
21
|
const UNIFIED_VIBE_CARD_DARK_VARS = `
|
|
22
|
+
--uvc-closed-build-bg: #28262f;
|
|
23
|
+
--uvc-closed-build-text: #b5afc2;
|
|
21
24
|
--color-dark-primary: #e0e0e0;
|
|
22
25
|
--color-dark-secondary: #aaaaaa;
|
|
23
26
|
--color-dark-decorative-00: #333333;
|
|
@@ -30,7 +33,6 @@ const UNIFIED_VIBE_CARD_DARK_VARS = `
|
|
|
30
33
|
values here so an explicit .dark host also darkens fields and borders. */
|
|
31
34
|
--vibes-field-bg: var(--vibes-ink-deep, #141414);
|
|
32
35
|
--vibes-card-border: var(--vibes-gray-mid, #555555);
|
|
33
|
-
--uvc-card-shadow: rgba(255,255,255,0.75);
|
|
34
36
|
--uvc-amber-text: #fbbf24;
|
|
35
37
|
--uvc-blue-text: #93c5fd;
|
|
36
38
|
--uvc-purple-text: #c4b5fd;
|
|
@@ -39,7 +41,6 @@ const UNIFIED_VIBE_CARD_DARK_VARS = `
|
|
|
39
41
|
--uvc-suggestion-text: #e5e7eb;
|
|
40
42
|
--uvc-helper-text: #c2cbd8;
|
|
41
43
|
--uvc-build-text: #bac4d2;
|
|
42
|
-
--uvc-nav-chat: #c4b5fd;
|
|
43
44
|
--uvc-nav-edit: #fb923c;
|
|
44
45
|
--uvc-nav-share: #4ade80;
|
|
45
46
|
--uvc-nav-faq: #cbd5e1;
|
|
@@ -51,12 +52,216 @@ const UNIFIED_VIBE_CARD_DARK_VARS = `
|
|
|
51
52
|
--color-light-background-00: var(--color-dark-background-00, #1a1a1a);
|
|
52
53
|
--color-light-background-01: var(--color-dark-background-01, #222222);
|
|
53
54
|
--color-light-background-02: var(--color-dark-background-02, #222222);`;
|
|
55
|
+
const UNIFIED_VIBE_CARD_GLASS_LIGHT_VARS = `
|
|
56
|
+
--uvc-submit-arrow:var(--vibes-cream, #fffff0);
|
|
57
|
+
--uvc-submit-fill:rgba(64,89,114,.2);
|
|
58
|
+
--uvc-notch-width: 52px;
|
|
59
|
+
--uvc-notch-opacity: .5;
|
|
60
|
+
--uvc-notch-fill: repeating-linear-gradient(0deg,rgba(255,255,255,.1) 0 .4px,transparent .4px 1px),linear-gradient(180deg,rgba(16,26,24,.65),rgba(16,26,24,.4) 30%,rgba(16,26,24,.9) 72%,rgba(16,26,24,.55));
|
|
61
|
+
--uvc-notch-shadow: inset 0 1px 0 rgba(255,255,255,.45),inset 0 -1px 1px rgba(0,0,0,.2),0 1px 2px rgba(16,26,24,.18);
|
|
62
|
+
--uvc-composer-border: rgba(16,26,24,.28);
|
|
63
|
+
--uvc-glass-fill: rgba(255,255,255,.15);
|
|
64
|
+
--uvc-glass-edge: rgba(255,255,255,.3);
|
|
65
|
+
--uvc-glass-highlight: rgba(255,255,255,.8);
|
|
66
|
+
--uvc-menu-strip: rgba(255,255,255,.18);
|
|
67
|
+
--uvc-menu-tab: rgba(255,255,255,.45);
|
|
68
|
+
--uvc-share-muted: #424954;
|
|
69
|
+
--uvc-glass-shadow: 0 8px 32px rgba(0,0,0,.1), inset 0 1px 0 rgba(255,255,255,.5), inset 0 -1px 0 rgba(255,255,255,.1), inset 0 0 20px 10px rgba(255,255,255,1);
|
|
70
|
+
--color-light-background-00: rgba(255,255,255,.24);
|
|
71
|
+
--color-light-background-01: rgba(255,255,255,.2);
|
|
72
|
+
--uvc-suggestion-bg: rgba(255,255,255,.28);
|
|
73
|
+
--vibes-field-bg: rgba(255,255,255,.2);
|
|
74
|
+
--uvc-nav-home: #2563eb;`;
|
|
75
|
+
const UNIFIED_VIBE_CARD_GLASS_DARK_VARS = `
|
|
76
|
+
--uvc-submit-arrow:#aaa;
|
|
77
|
+
--uvc-submit-fill:#000;
|
|
78
|
+
--uvc-notch-opacity: .25;
|
|
79
|
+
--uvc-notch-width: 52px;
|
|
80
|
+
--uvc-notch-fill: repeating-linear-gradient(90deg,rgba(255,255,255,.18) 0 .6px,transparent .6px 2px),linear-gradient(180deg,rgba(230,255,245,.6),rgba(230,255,245,.3) 40%,rgba(210,239,228,.12) 58%,rgba(210,239,228,.2));
|
|
81
|
+
--uvc-notch-shadow: inset 0 0 0 1px rgba(230,255,245,.2),0 1px 2px rgba(0,0,0,.3);
|
|
82
|
+
--uvc-composer-border: rgba(210,239,228,.28);
|
|
83
|
+
--uvc-glass-fill: rgba(16,26,24,.72);
|
|
84
|
+
--uvc-glass-edge: rgba(210,239,228,.28);
|
|
85
|
+
--uvc-glass-highlight: rgba(230,255,245,.32);
|
|
86
|
+
--uvc-menu-strip: rgba(16,26,24,.18);
|
|
87
|
+
--uvc-menu-tab: rgba(230,255,245,.12);
|
|
88
|
+
--uvc-share-muted: #b7becb;
|
|
89
|
+
--uvc-glass-shadow: 0 8px 32px rgba(0,0,0,.24), inset 0 1px 0 rgba(255,255,255,.22), inset 0 -1px 0 rgba(255,255,255,.05), inset 0 0 20px 4px rgba(210,239,228,.07);
|
|
90
|
+
--color-light-background-00: rgba(16,26,24,.28);
|
|
91
|
+
--color-light-background-01: rgba(16,26,24,.24);
|
|
92
|
+
--uvc-suggestion-bg: rgba(16,26,24,.32);
|
|
93
|
+
--vibes-field-bg: rgba(16,26,24,.28);
|
|
94
|
+
--uvc-nav-home: #93b4ff;`;
|
|
95
|
+
const UNIFIED_VIBE_CARD_OBSIDIAN_VARS = `
|
|
96
|
+
--uvc-glass-fill: rgba(6,9,10,.94);
|
|
97
|
+
--uvc-glass-edge: rgba(255,255,255,.12);
|
|
98
|
+
--uvc-glass-highlight: rgba(255,255,255,.25);
|
|
99
|
+
--uvc-glass-shadow: 0 4px 16px rgba(0,0,0,.28), inset 0 1px 0 rgba(255,255,255,.12), inset 0 -1px 0 rgba(255,255,255,.035), inset 0 0 12px rgba(255,255,255,.02);
|
|
100
|
+
--uvc-nav-home: #93b4ff;`;
|
|
101
|
+
const UNIFIED_VIBE_CARD_NAV_LIGHT_VARS = `
|
|
102
|
+
--uvc-glass-fill:rgba(255,255,255,.08);
|
|
103
|
+
--uvc-glass-edge:rgba(255,255,255,.3);
|
|
104
|
+
--uvc-glass-highlight:rgba(255,255,255,.8);
|
|
105
|
+
--uvc-glass-shadow:0 4px 16px rgba(0,0,0,.1),inset 0 1px 0 rgba(255,255,255,.35),inset 0 -1px 0 rgba(255,255,255,.08);
|
|
106
|
+
--uvc-nav-home:#2d5bd1; --uvc-nav-edit:#a34b0a; --uvc-nav-share:#18713b;
|
|
107
|
+
--uvc-nav-fill:rgba(255,255,240,.92);
|
|
108
|
+
--uvc-nav-border:color-mix(in srgb,currentColor 65%,transparent);
|
|
109
|
+
--uvc-nav-selected-width:1px;
|
|
110
|
+
--uvc-nav-selected-shadow:inset 0 0 5px 1px color-mix(in srgb,currentColor 45%,transparent),inset 0 0 2px color-mix(in srgb,currentColor 25%,transparent);`;
|
|
111
|
+
const UNIFIED_VIBE_CARD_NAV_DARK_VARS = `${UNIFIED_VIBE_CARD_OBSIDIAN_VARS}
|
|
112
|
+
--uvc-nav-edit:#fb923c; --uvc-nav-share:#4ade80;
|
|
113
|
+
--uvc-nav-fill:rgba(0,0,0,.5);
|
|
114
|
+
--uvc-nav-border:currentColor;
|
|
115
|
+
--uvc-nav-selected-width:3px;
|
|
116
|
+
--uvc-nav-selected-shadow:inset 0 4px 8px 1px rgba(0,0,0,.85),inset 0 1px 3px rgba(0,0,0,.65),inset 0 -1px 0 color-mix(in srgb,currentColor 45%,transparent);`;
|
|
54
117
|
const unifiedVibeCardDarkCss = `
|
|
118
|
+
[data-unified-vibe-card] {${UNIFIED_VIBE_CARD_GLASS_LIGHT_VARS}
|
|
119
|
+
}
|
|
55
120
|
@media (prefers-color-scheme: dark) {
|
|
56
|
-
[data-unified-vibe-card], [data-vibe-handle-menu], [data-vibe-version-menu] {${UNIFIED_VIBE_CARD_DARK_VARS}
|
|
121
|
+
[data-unified-vibe-card], [data-vibe-handle-menu], [data-vibe-version-menu], [data-vibe-closed-build-status] {${UNIFIED_VIBE_CARD_DARK_VARS}
|
|
122
|
+
}
|
|
123
|
+
[data-unified-vibe-card] {${UNIFIED_VIBE_CARD_GLASS_DARK_VARS}
|
|
57
124
|
}
|
|
58
125
|
}
|
|
59
|
-
.dark [data-unified-vibe-card], .dark [data-vibe-handle-menu], .dark [data-vibe-version-menu] {${UNIFIED_VIBE_CARD_DARK_VARS}
|
|
126
|
+
.dark [data-unified-vibe-card], .dark [data-vibe-handle-menu], .dark [data-vibe-version-menu], .dark [data-vibe-closed-build-status] {${UNIFIED_VIBE_CARD_DARK_VARS}
|
|
127
|
+
}
|
|
128
|
+
.dark [data-unified-vibe-card] {${UNIFIED_VIBE_CARD_GLASS_DARK_VARS}
|
|
129
|
+
}
|
|
130
|
+
/* The detached row owns its theme independently of the card content. */
|
|
131
|
+
[data-vibe-card-nav] {${UNIFIED_VIBE_CARD_DARK_VARS}${UNIFIED_VIBE_CARD_NAV_LIGHT_VARS}
|
|
132
|
+
}
|
|
133
|
+
[data-vibe-switch-glass] {${UNIFIED_VIBE_CARD_OBSIDIAN_VARS}
|
|
134
|
+
}
|
|
135
|
+
/* The card's layout still includes its footer. Only its glass surface ends
|
|
136
|
+
at the former divider: retain the outer 1px border and footer's 1px top
|
|
137
|
+
border as transparent spacing so the circles and switch never move. */
|
|
138
|
+
[data-unified-vibe-card]::before {
|
|
139
|
+
content: ""; position: absolute; inset: -1px -1px 50px; border-radius: 14px;
|
|
140
|
+
}
|
|
141
|
+
/* The agent panel retains its existing 50px switch reservation, without the
|
|
142
|
+
ordinary nav row's extra divider pixel. Its body ends one pixel lower. */
|
|
143
|
+
[data-unified-vibe-card][data-vibe-agent-panel="true"]::before { bottom: 49px; }
|
|
144
|
+
[data-vibe-card-nav] { position: relative; isolation: isolate; }
|
|
145
|
+
[data-vibe-card-nav]::before {
|
|
146
|
+
content: ""; position: absolute; left: 2px; top: 50%; transform: translateY(-50%); z-index: -1;
|
|
147
|
+
width: calc(3 * var(--uvc-nav-size, 38px) + 2 * var(--uvc-nav-gap, 6px) + 12px);
|
|
148
|
+
height: calc(var(--uvc-nav-size, 38px) + 10px); border-radius: 999px;
|
|
149
|
+
}
|
|
150
|
+
[data-unified-vibe-card]::before, [data-vibe-card-nav]::before, [data-vibe-switch-glass]::before {
|
|
151
|
+
box-sizing: border-box; border: 1px solid transparent; pointer-events: none;
|
|
152
|
+
}
|
|
153
|
+
[data-unified-vibe-card]::before, [data-vibe-card-nav]::before, [data-vibe-switch-glass]::before {
|
|
154
|
+
background: linear-gradient(to right, transparent, var(--uvc-glass-highlight), transparent) top / 100% 1px no-repeat,
|
|
155
|
+
linear-gradient(to bottom, var(--uvc-glass-highlight), transparent, var(--uvc-glass-edge)) left / 1px 100% no-repeat,
|
|
156
|
+
var(--uvc-glass-fill);
|
|
157
|
+
backdrop-filter: blur(24px); -webkit-backdrop-filter: blur(24px);
|
|
158
|
+
box-shadow: var(--uvc-glass-shadow);
|
|
159
|
+
}
|
|
160
|
+
[data-vibe-card-nav]::before { backdrop-filter:blur(8px); -webkit-backdrop-filter:blur(8px); }
|
|
161
|
+
@media (prefers-color-scheme: dark) {
|
|
162
|
+
[data-vibe-card-nav] {${UNIFIED_VIBE_CARD_NAV_DARK_VARS}}
|
|
163
|
+
[data-vibe-card-nav]::before { backdrop-filter:blur(24px); -webkit-backdrop-filter:blur(24px); }
|
|
164
|
+
}
|
|
165
|
+
.dark [data-vibe-card-nav] {${UNIFIED_VIBE_CARD_NAV_DARK_VARS}}
|
|
166
|
+
.dark [data-vibe-card-nav]::before { backdrop-filter:blur(24px); -webkit-backdrop-filter:blur(24px); }
|
|
167
|
+
.light [data-vibe-card-nav] {${UNIFIED_VIBE_CARD_NAV_LIGHT_VARS}}
|
|
168
|
+
.light [data-vibe-card-nav]::before { backdrop-filter:blur(8px); -webkit-backdrop-filter:blur(8px); }
|
|
169
|
+
[data-vibe-card-nav] [data-vibe-nav-selected="true"] svg { stroke-width:3; }
|
|
170
|
+
/* The arrival uses the fitted glass surface, leaving the brand artwork untouched.
|
|
171
|
+
Keying the layer by status replays same-color arrivals without a JS timer. */
|
|
172
|
+
[data-vibe-switch-glass]:has([data-vibe-switch-highlight])::before { visibility:hidden; }
|
|
173
|
+
[data-vibe-switch-rest] {
|
|
174
|
+
background:linear-gradient(to right,transparent,var(--uvc-glass-highlight),transparent) top/100% 1px no-repeat,
|
|
175
|
+
linear-gradient(to bottom,var(--uvc-glass-highlight),transparent,var(--uvc-glass-edge)) left/1px 100% no-repeat,var(--uvc-glass-fill);
|
|
176
|
+
box-shadow:var(--uvc-glass-shadow);
|
|
177
|
+
animation:uvc-notification-rest 7s forwards;
|
|
178
|
+
}
|
|
179
|
+
[data-vibe-switch-highlight] {
|
|
180
|
+
--uvc-arrival-fill:color-mix(in srgb,currentColor 80%,transparent);
|
|
181
|
+
--uvc-arrival-edge:color-mix(in srgb,color-mix(in srgb,currentColor 50%,white) 60%,transparent);
|
|
182
|
+
--uvc-arrival-highlight:color-mix(in srgb,color-mix(in srgb,currentColor 20%,white) 90%,transparent);
|
|
183
|
+
background:linear-gradient(to right,transparent,var(--uvc-arrival-highlight),transparent) top/100% 1px no-repeat,
|
|
184
|
+
linear-gradient(to bottom,var(--uvc-arrival-highlight),transparent,var(--uvc-arrival-edge)) left/1px 100% no-repeat,var(--uvc-arrival-fill);
|
|
185
|
+
box-shadow:0 4px 16px rgba(0,0,0,.2),inset 0 1px 0 var(--uvc-arrival-highlight),inset 0 -1px 0 var(--uvc-arrival-edge),inset 0 0 12px rgba(255,255,255,.06);
|
|
186
|
+
animation:uvc-notification-glass 7s forwards;
|
|
187
|
+
}
|
|
188
|
+
/* Preserve the original Amber material for the yellow/pending status. */
|
|
189
|
+
[data-vibe-switch-highlight][data-arrival-amber="true"] {
|
|
190
|
+
--uvc-arrival-fill:rgba(191,142,66,.8);
|
|
191
|
+
--uvc-arrival-edge:rgba(255,229,167,.6);
|
|
192
|
+
--uvc-arrival-highlight:rgba(255,246,218,.9);
|
|
193
|
+
}
|
|
194
|
+
[data-vibe-switch-highlight], [data-vibe-switch-rest] {
|
|
195
|
+
box-sizing:border-box; border:1px solid transparent; pointer-events:none;
|
|
196
|
+
backdrop-filter:blur(24px); -webkit-backdrop-filter:blur(24px);
|
|
197
|
+
}
|
|
198
|
+
@keyframes uvc-notification-rest {
|
|
199
|
+
0%,100% { opacity:1; }
|
|
200
|
+
14.3%,71.4% { opacity:0; }
|
|
201
|
+
}
|
|
202
|
+
@keyframes uvc-notification-glass {
|
|
203
|
+
0% { opacity:0; }
|
|
204
|
+
14.3%,71.4% { opacity:1; }
|
|
205
|
+
100% { opacity:0; }
|
|
206
|
+
}
|
|
207
|
+
@media (prefers-reduced-motion:reduce) {
|
|
208
|
+
[data-vibe-switch-highlight] { animation-name:uvc-notification-glass-reduced; }
|
|
209
|
+
[data-vibe-switch-rest] { animation-name:uvc-notification-rest-reduced; }
|
|
210
|
+
}
|
|
211
|
+
@keyframes uvc-notification-rest-reduced {
|
|
212
|
+
0%,71.4% { opacity:0; }
|
|
213
|
+
100% { opacity:1; }
|
|
214
|
+
}
|
|
215
|
+
@keyframes uvc-notification-glass-reduced {
|
|
216
|
+
0%,71.4% { opacity:1; }
|
|
217
|
+
100% { opacity:0; }
|
|
218
|
+
}
|
|
219
|
+
/* Fit the painted 102px logo, excluding the SVG's transparent side margins.
|
|
220
|
+
Match the nav oval's height without moving the existing 120×44 hit target. */
|
|
221
|
+
[data-vibe-switch-glass] { isolation: isolate; }
|
|
222
|
+
[data-vibe-switch-glass]::before, [data-vibe-switch-highlight], [data-vibe-switch-rest] {
|
|
223
|
+
content: ""; position: absolute; left: 6px; right: 6px; top: calc(50% + 1px);
|
|
224
|
+
height: calc(var(--uvc-nav-size, 38px) + 10px); transform: translateY(-50%);
|
|
225
|
+
border-radius: 999px; z-index: -1;
|
|
226
|
+
}
|
|
227
|
+
[data-unified-vibe-card] form.vibes-edit-field {
|
|
228
|
+
--vibes-card-border: var(--uvc-composer-border);
|
|
229
|
+
}
|
|
230
|
+
/* The selected Frost header rule fades at both ends at half opacity,
|
|
231
|
+
without consuming any of the card's content height. */
|
|
232
|
+
[data-vibe-card-header]::after {
|
|
233
|
+
content: ""; position: absolute; bottom: 0; left: 0; right: 0; height: 1px;
|
|
234
|
+
background: linear-gradient(90deg, transparent, var(--uvc-glass-edge) 22%, var(--uvc-glass-edge) 78%, transparent);
|
|
235
|
+
opacity: .5; pointer-events: none;
|
|
236
|
+
}
|
|
237
|
+
/* A · Line: the clip edge sits under the painted switch, inside the 120px
|
|
238
|
+
hit box (whose SVG has transparent air at its left). 22px padding leaves
|
|
239
|
+
the resting strip at right:132px without changing the switch geometry. */
|
|
240
|
+
[data-vibe-closed-build-status] {
|
|
241
|
+
position: absolute; left: 12px; right: 110px; bottom: 17px;
|
|
242
|
+
z-index: 2; display: flex; justify-content: flex-end; padding-right: 22px;
|
|
243
|
+
overflow: hidden; pointer-events: none; box-sizing: border-box;
|
|
244
|
+
}
|
|
245
|
+
[data-vibe-closed-build-line] {
|
|
246
|
+
min-width: 0; max-width: 100%; box-sizing: border-box;
|
|
247
|
+
padding: 3px 5px; border-radius: 3px;
|
|
248
|
+
background: var(--uvc-closed-build-bg, #fff);
|
|
249
|
+
color: var(--uvc-closed-build-text, #6d6973);
|
|
250
|
+
font: 12px/18px Inter, system-ui, sans-serif;
|
|
251
|
+
transform: translateX(calc(100% + 22px));
|
|
252
|
+
transition: transform 240ms cubic-bezier(.22,.68,0,1);
|
|
253
|
+
overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
|
|
254
|
+
}
|
|
255
|
+
[data-vibe-closed-build-line][data-revealed="true"] { transform: translateX(0); }
|
|
256
|
+
[data-vibe-closed-build-line] [data-testid="thinking-line"] {
|
|
257
|
+
display: flex; align-items: baseline; gap: 6px; min-width: 0;
|
|
258
|
+
}
|
|
259
|
+
[data-vibe-closed-build-line] [data-testid="thinking-line-glyph"] { flex-shrink: 0; }
|
|
260
|
+
[data-vibe-closed-build-line] [data-testid="thinking-line-verb"] {
|
|
261
|
+
min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
|
|
262
|
+
}
|
|
263
|
+
@media (prefers-reduced-motion: reduce) {
|
|
264
|
+
[data-vibe-closed-build-line] { transition: none; }
|
|
60
265
|
}
|
|
61
266
|
/* Composer submit button: a blue pulsating glow while the field holds unsent
|
|
62
267
|
content, nudging the user to send it — the same "something's live, act on it"
|
|
@@ -126,14 +331,14 @@ const unifiedVibeCardDarkCss = `
|
|
|
126
331
|
animation: none;
|
|
127
332
|
}
|
|
128
333
|
}
|
|
129
|
-
/*
|
|
334
|
+
/* Three shrink-proof nav circles (Home / Edit / Share) share the footer with the 120px logo spacer.
|
|
130
335
|
Compact size/gap steps keep them clear of the logo on narrow phones without
|
|
131
336
|
flex shrinking circles into ovals. */
|
|
132
337
|
@media (max-width: 400px) {
|
|
133
|
-
[data-unified-vibe-card] { --uvc-nav-size: 34px; --uvc-nav-gap: 4px; }
|
|
338
|
+
[data-unified-vibe-card], [data-vibe-switch-glass] { --uvc-nav-size: 34px; --uvc-nav-gap: 4px; }
|
|
134
339
|
}
|
|
135
340
|
@media (max-width: 360px) {
|
|
136
|
-
[data-unified-vibe-card] { --uvc-nav-size: 30px; }
|
|
341
|
+
[data-unified-vibe-card], [data-vibe-switch-glass] { --uvc-nav-size: 30px; }
|
|
137
342
|
}
|
|
138
343
|
/* Composer input row — a FIELD, not a button (Storybook audition C2, #4578).
|
|
139
344
|
It used to wear a hard 2px/3px offset shadow over the card's own grey, which
|
|
@@ -220,9 +425,25 @@ const unifiedVibeCardDarkCss = `
|
|
|
220
425
|
}
|
|
221
426
|
[data-vibe-card-editor-tabs] [role="tab"] {
|
|
222
427
|
min-height: 36px;
|
|
223
|
-
padding-inline:
|
|
428
|
+
padding-inline: 3px !important;
|
|
224
429
|
font-size: 14px !important;
|
|
225
430
|
}
|
|
431
|
+
/* Share and Chat/editor strips are pinned outside their content scrollers.
|
|
432
|
+
Continue the card glass across both menus; standalone strips retain their
|
|
433
|
+
opaque surfaces so scrolling text cannot show through them. */
|
|
434
|
+
[data-unified-vibe-card] [data-share-panel] > [role="tablist"],
|
|
435
|
+
[data-unified-vibe-card] [data-vibe-card-editor-tabs] [role="tablist"] {
|
|
436
|
+
background: var(--uvc-menu-strip);
|
|
437
|
+
border-color: var(--uvc-glass-edge);
|
|
438
|
+
}
|
|
439
|
+
[data-unified-vibe-card] [data-share-panel] > [role="tablist"] [role="tab"][aria-selected="true"],
|
|
440
|
+
[data-unified-vibe-card] [data-vibe-card-editor-tabs] [role="tab"][aria-selected="true"] {
|
|
441
|
+
background: var(--uvc-menu-tab);
|
|
442
|
+
box-shadow: inset 0 1px 0 var(--uvc-glass-edge);
|
|
443
|
+
}
|
|
444
|
+
[data-unified-vibe-card] [data-share-secondary] {
|
|
445
|
+
color: var(--uvc-share-muted);
|
|
446
|
+
}
|
|
226
447
|
[data-unified-vibe-card] [data-testid="build-card"] {
|
|
227
448
|
--text-secondary: var(--uvc-build-text, #526071);
|
|
228
449
|
}
|
|
@@ -253,8 +474,67 @@ const unifiedVibeCardDarkCss = `
|
|
|
253
474
|
}`;
|
|
254
475
|
const CARD_VIEWPORT_HEIGHT = "80%";
|
|
255
476
|
const CARD_FULL_VIEWPORT_HEIGHT = "94%";
|
|
477
|
+
function ClosedBuildStatus({ visible, content }) {
|
|
478
|
+
const [retainedContent, setRetainedContent] = useState(visible ? content : undefined);
|
|
479
|
+
const [revealed, setRevealed] = useState(false);
|
|
480
|
+
const [reducedMotion, setReducedMotion] = useState(false);
|
|
481
|
+
useEffect(() => {
|
|
482
|
+
if (typeof window.matchMedia !== "function")
|
|
483
|
+
return;
|
|
484
|
+
const media = window.matchMedia("(prefers-reduced-motion: reduce)");
|
|
485
|
+
function updateMotion() {
|
|
486
|
+
setReducedMotion(media.matches);
|
|
487
|
+
}
|
|
488
|
+
updateMotion();
|
|
489
|
+
media.addEventListener("change", updateMotion);
|
|
490
|
+
return () => media.removeEventListener("change", updateMotion);
|
|
491
|
+
}, []);
|
|
492
|
+
useEffect(() => {
|
|
493
|
+
if (visible)
|
|
494
|
+
setRetainedContent(content);
|
|
495
|
+
}, [visible, content]);
|
|
496
|
+
useEffect(() => {
|
|
497
|
+
let firstFrame;
|
|
498
|
+
let secondFrame;
|
|
499
|
+
let exitTimer;
|
|
500
|
+
if (visible) {
|
|
501
|
+
if (reducedMotion)
|
|
502
|
+
setRevealed(true);
|
|
503
|
+
else
|
|
504
|
+
firstFrame = requestAnimationFrame(() => {
|
|
505
|
+
secondFrame = requestAnimationFrame(() => setRevealed(true));
|
|
506
|
+
});
|
|
507
|
+
}
|
|
508
|
+
else {
|
|
509
|
+
setRevealed(false);
|
|
510
|
+
if (reducedMotion)
|
|
511
|
+
setRetainedContent(undefined);
|
|
512
|
+
else
|
|
513
|
+
exitTimer = setTimeout(() => setRetainedContent(undefined), 240);
|
|
514
|
+
}
|
|
515
|
+
return () => {
|
|
516
|
+
if (firstFrame !== undefined)
|
|
517
|
+
cancelAnimationFrame(firstFrame);
|
|
518
|
+
if (secondFrame !== undefined)
|
|
519
|
+
cancelAnimationFrame(secondFrame);
|
|
520
|
+
clearTimeout(exitTimer);
|
|
521
|
+
};
|
|
522
|
+
}, [visible, reducedMotion]);
|
|
523
|
+
if (retainedContent === undefined || retainedContent === null)
|
|
524
|
+
return undefined;
|
|
525
|
+
return (React.createElement("div", { "data-vibe-closed-build-status": true, "data-testid": "closed-build-status", "aria-hidden": visible ? undefined : true, inert: !visible },
|
|
526
|
+
React.createElement("div", { "data-vibe-closed-build-line": true, "data-revealed": revealed }, retainedContent)));
|
|
527
|
+
}
|
|
256
528
|
export function UnifiedVibeCard(props) {
|
|
257
529
|
const { appTitle, appSlug, isTwinkling, isTeasing, open: controlledOpen, onOpenChange } = props;
|
|
530
|
+
const editorTabDisabled = props.editorTab === undefined ? false : props.disabledEditorTabs?.includes(props.editorTab) === true;
|
|
531
|
+
const editorTabForRender = editorTabDisabled ? "edit-chat" : props.editorTab;
|
|
532
|
+
const retainedEditorVisible = props.editorVisible === true && editorTabDisabled === false;
|
|
533
|
+
const retainedEditorMounted = props.retainedEditor != null && editorTabDisabled === false;
|
|
534
|
+
const switchGlassColor = props.switchOvalColor ??
|
|
535
|
+
(props.versionLocked || props.publishState === "draft" || props.onViewDraft !== undefined
|
|
536
|
+
? ovalColors.yellow
|
|
537
|
+
: ovalColors.neutral);
|
|
258
538
|
const [internalOpen, setInternalOpen] = useState(false);
|
|
259
539
|
const open = controlledOpen ?? internalOpen;
|
|
260
540
|
const setOpen = (next) => {
|
|
@@ -413,10 +693,11 @@ export function UnifiedVibeCard(props) {
|
|
|
413
693
|
setEverOpened(true);
|
|
414
694
|
}, [open]);
|
|
415
695
|
const retained = Boolean(props.keepMounted) && everOpened;
|
|
416
|
-
const
|
|
696
|
+
const internalScrollRegionRef = useRef(null);
|
|
697
|
+
const scrollRegionRef = props.scrollContainerRef ?? internalScrollRegionRef;
|
|
417
698
|
const chipsRegionRef = useRef(null);
|
|
418
699
|
const stickToBottomRef = useRef(true);
|
|
419
|
-
const hasHistory = props.historyBody != null && props.body == null;
|
|
700
|
+
const hasHistory = (props.historyBody != null || props.streamBody != null) && props.body == null;
|
|
420
701
|
const streamLive = props.streamBody != null && props.streamSettled !== true;
|
|
421
702
|
const chipBuildLive = streamLive && props.activeChip !== undefined;
|
|
422
703
|
const visibleChips = props.activeChip === undefined || props.chips?.slice(0, 3).includes(props.activeChip) === true
|
|
@@ -571,7 +852,8 @@ export function UnifiedVibeCard(props) {
|
|
|
571
852
|
const resizeValueNow = Math.round(Math.min(Math.max(userHeight ?? cardRef.current?.offsetHeight ?? 0, RESIZE_MIN), resizeValueMax));
|
|
572
853
|
return (React.createElement(React.Fragment, null,
|
|
573
854
|
React.createElement("style", null, unifiedVibeCardDarkCss),
|
|
574
|
-
|
|
855
|
+
React.createElement(ClosedBuildStatus, { visible: open === false && hidden === false && props.closedBuildStatus !== undefined && props.closedBuildStatus !== null, content: props.closedBuildStatus }),
|
|
856
|
+
!hidden && (mounted || retained) && (React.createElement("div", { ref: cardRef, role: "dialog", "aria-label": "Vibe menu", "data-unified-vibe-card": true, "data-vibe-agent-panel": agentPanelActive, className: props.className, "aria-hidden": mounted ? undefined : true, inert: mounted ? undefined : true, style: {
|
|
575
857
|
position: "absolute",
|
|
576
858
|
left: 2,
|
|
577
859
|
right: 2,
|
|
@@ -580,12 +862,11 @@ export function UnifiedVibeCard(props) {
|
|
|
580
862
|
borderRadius: 14,
|
|
581
863
|
maxHeight: cardHeight,
|
|
582
864
|
height: cardHeight,
|
|
583
|
-
overflow: "
|
|
865
|
+
overflow: "visible",
|
|
584
866
|
display: "flex",
|
|
585
867
|
flexDirection: "column",
|
|
586
|
-
background: "
|
|
587
|
-
border: "1px solid
|
|
588
|
-
boxShadow: "0 8px 40px var(--uvc-card-shadow, rgba(0,0,0,0.75))",
|
|
868
|
+
background: "transparent",
|
|
869
|
+
border: "1px solid transparent",
|
|
589
870
|
transformOrigin: "bottom right",
|
|
590
871
|
transform: grown ? "scale(1)" : "scale(0)",
|
|
591
872
|
transition: dragging ? scaleTransition : `${scaleTransition}, max-height 0.24s ease, height 0.24s ease`,
|
|
@@ -593,6 +874,7 @@ export function UnifiedVibeCard(props) {
|
|
|
593
874
|
...(mounted ? null : { visibility: "hidden" }),
|
|
594
875
|
} },
|
|
595
876
|
React.createElement("div", { "data-vibe-card-content": true, style: {
|
|
877
|
+
position: "relative",
|
|
596
878
|
display: "flex",
|
|
597
879
|
flexDirection: "column",
|
|
598
880
|
minHeight: 0,
|
|
@@ -600,216 +882,233 @@ export function UnifiedVibeCard(props) {
|
|
|
600
882
|
opacity: grown ? 1 : 0,
|
|
601
883
|
transition: grown ? "opacity 0.18s ease 0.14s" : "opacity 0.1s ease",
|
|
602
884
|
}, className: "text-light-primary dark:text-dark-primary" },
|
|
603
|
-
React.createElement("div", { style: {
|
|
885
|
+
React.createElement("div", { "data-vibe-card-body": true, style: {
|
|
604
886
|
display: "flex",
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
userSelect: "none",
|
|
887
|
+
flexDirection: "column",
|
|
888
|
+
flex: "1 1 auto",
|
|
889
|
+
minHeight: 0,
|
|
890
|
+
overflow: "hidden",
|
|
891
|
+
borderRadius: 13,
|
|
611
892
|
} },
|
|
612
|
-
React.createElement("div", { "data-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
bottom: 0,
|
|
618
|
-
zIndex: 0,
|
|
619
|
-
cursor: "ns-resize",
|
|
620
|
-
touchAction: "none",
|
|
621
|
-
} },
|
|
622
|
-
React.createElement("span", { "aria-hidden": true, style: {
|
|
623
|
-
position: "absolute",
|
|
624
|
-
top: 4,
|
|
625
|
-
left: "50%",
|
|
626
|
-
transform: "translateX(-50%)",
|
|
627
|
-
width: 44,
|
|
628
|
-
height: 4,
|
|
629
|
-
borderRadius: 999,
|
|
630
|
-
background: "var(--color-light-decorative-01, #ddd)",
|
|
631
|
-
} })),
|
|
632
|
-
React.createElement("div", { style: {
|
|
633
|
-
position: "relative",
|
|
634
|
-
width: 30,
|
|
635
|
-
height: 30,
|
|
636
|
-
borderRadius: 8,
|
|
893
|
+
React.createElement("div", { "data-vibe-card-header": true, style: {
|
|
894
|
+
display: "flex",
|
|
895
|
+
alignItems: "center",
|
|
896
|
+
gap: 8,
|
|
897
|
+
padding: "10px 10px 10px",
|
|
637
898
|
flexShrink: 0,
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
border: "1px solid rgba(0,0,0,0.15)",
|
|
641
|
-
pointerEvents: "none",
|
|
899
|
+
position: "relative",
|
|
900
|
+
userSelect: "none",
|
|
642
901
|
} },
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
902
|
+
React.createElement("div", { "data-testid": "vibe-card-resize-handle", role: "separator", "aria-orientation": "horizontal", "aria-label": "Resize chat height", "aria-valuemin": RESIZE_MIN, "aria-valuemax": resizeValueMax, "aria-valuenow": resizeValueNow, tabIndex: 0, onPointerDown: onHandlePointerDown, onPointerMove: onHandlePointerMove, onPointerUp: endHandleDrag, onPointerCancel: cancelHandleDrag, onKeyDown: onHandleKeyDown, onDoubleClick: () => clearForcedHeight(), style: {
|
|
903
|
+
position: "absolute",
|
|
904
|
+
top: 0,
|
|
905
|
+
left: 0,
|
|
906
|
+
right: 0,
|
|
907
|
+
bottom: 0,
|
|
908
|
+
zIndex: 0,
|
|
909
|
+
cursor: "ns-resize",
|
|
910
|
+
touchAction: "none",
|
|
911
|
+
} },
|
|
912
|
+
React.createElement("span", { "aria-hidden": true, style: {
|
|
913
|
+
position: "absolute",
|
|
914
|
+
top: 4,
|
|
915
|
+
left: "50%",
|
|
916
|
+
transform: "translateX(-50%)",
|
|
917
|
+
width: "var(--uvc-notch-width, 44px)",
|
|
918
|
+
height: 4,
|
|
919
|
+
borderRadius: 999,
|
|
920
|
+
background: "var(--uvc-notch-fill)",
|
|
921
|
+
boxShadow: "var(--uvc-notch-shadow)",
|
|
922
|
+
opacity: "var(--uvc-notch-opacity)",
|
|
923
|
+
} })),
|
|
924
|
+
React.createElement("div", { style: {
|
|
925
|
+
position: "relative",
|
|
926
|
+
width: 30,
|
|
927
|
+
height: 30,
|
|
928
|
+
borderRadius: 8,
|
|
929
|
+
flexShrink: 0,
|
|
651
930
|
overflow: "hidden",
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
931
|
+
background: "var(--vibes-cream, #fffff0)",
|
|
932
|
+
border: "1px solid rgba(0,0,0,0.15)",
|
|
933
|
+
pointerEvents: "none",
|
|
934
|
+
} },
|
|
935
|
+
props.appIconUrl && (React.createElement("img", { src: props.appIconUrl, alt: "", style: { width: "100%", height: "100%", objectFit: "cover", transform: "scale(2)" } })),
|
|
936
|
+
React.createElement(CodingIndicator, { active: props.coding === true })),
|
|
937
|
+
React.createElement("div", { style: { lineHeight: 1.2, minWidth: 0, flex: "1 1 auto" } },
|
|
938
|
+
React.createElement("strong", { style: {
|
|
939
|
+
fontFamily: HOME_BRAND_FONT,
|
|
940
|
+
display: "block",
|
|
941
|
+
fontSize: 13,
|
|
942
|
+
lineHeight: 1.3,
|
|
943
|
+
overflow: "hidden",
|
|
944
|
+
textOverflow: "ellipsis",
|
|
945
|
+
whiteSpace: "nowrap",
|
|
946
|
+
} }, appTitle),
|
|
947
|
+
appSlug &&
|
|
948
|
+
(props.onOpenApp === undefined && props.onCopyAppUrl === undefined ? (React.createElement("div", { className: "text-light-secondary dark:text-dark-secondary", style: { fontSize: 12, overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" } }, appSlug)) : (React.createElement("div", { "data-vibe-card-header-controls": "true", "data-testid": "vibe-card-slug-line", style: { position: "relative", zIndex: 1, display: "flex", alignItems: "center", gap: 4, minWidth: 0 } },
|
|
949
|
+
props.onOpenApp === undefined ? (React.createElement("span", { className: "text-light-secondary dark:text-dark-secondary", style: {
|
|
950
|
+
fontSize: 12,
|
|
951
|
+
minWidth: 0,
|
|
952
|
+
overflow: "hidden",
|
|
953
|
+
textOverflow: "ellipsis",
|
|
954
|
+
whiteSpace: "nowrap",
|
|
955
|
+
} }, appSlug)) : (React.createElement("button", { type: "button", "data-testid": "vibe-card-slug-link", onClick: props.onOpenApp, className: "text-light-secondary dark:text-dark-secondary", style: {
|
|
956
|
+
font: "inherit",
|
|
957
|
+
fontSize: 12,
|
|
958
|
+
lineHeight: "20px",
|
|
959
|
+
overflow: "hidden",
|
|
960
|
+
textOverflow: "ellipsis",
|
|
961
|
+
whiteSpace: "nowrap",
|
|
962
|
+
minWidth: 0,
|
|
963
|
+
textDecoration: "underline",
|
|
964
|
+
textUnderlineOffset: 2,
|
|
965
|
+
background: "none",
|
|
966
|
+
border: "none",
|
|
967
|
+
padding: 0,
|
|
968
|
+
cursor: "pointer",
|
|
969
|
+
textAlign: "left",
|
|
970
|
+
} }, appSlug)),
|
|
971
|
+
props.onCopyAppUrl !== undefined && (React.createElement(CopyLinkIconButton, { onCopy: props.onCopyAppUrl, color: "currentColor" })))))),
|
|
972
|
+
(() => {
|
|
973
|
+
const badges = [
|
|
974
|
+
props.publishState === "old" ? React.createElement(DraftBadge, { key: "old", variant: "old" }) : null,
|
|
975
|
+
props.publishState === "draft" && !props.versionLocked ? React.createElement(DraftBadge, { key: "draft", variant: "draft" }) : null,
|
|
976
|
+
props.versionLocked ? React.createElement(LockedBadge, { key: "locked" }) : null,
|
|
977
|
+
!props.publishState && props.onViewDraft && !props.versionLocked ? (React.createElement(ViewDraftBadge, { key: "view-draft", onClick: props.onViewDraft })) : null,
|
|
978
|
+
].filter(Boolean);
|
|
979
|
+
return badges.length === 0 ? null : (React.createElement("div", { "data-vibe-card-header-controls": "true", style: { position: "relative", zIndex: 1, display: "flex", alignItems: "center", gap: 10, flexShrink: 0 } }, badges));
|
|
980
|
+
})(),
|
|
981
|
+
React.createElement("div", { "data-vibe-card-header-controls": "true", style: {
|
|
982
|
+
position: "relative",
|
|
983
|
+
zIndex: 1,
|
|
984
|
+
marginLeft: "auto",
|
|
985
|
+
display: "flex",
|
|
986
|
+
alignItems: "center",
|
|
987
|
+
gap: 10,
|
|
988
|
+
flexShrink: 0,
|
|
989
|
+
maxWidth: "38%",
|
|
990
|
+
minWidth: 0,
|
|
991
|
+
} }, props.hideViewerTag ? null : props.handleSlug ? (React.createElement("div", { ref: pickerWrapRef, style: { position: "relative", minWidth: 0, maxWidth: "100%" } },
|
|
992
|
+
React.createElement(ViewerTagView, { slug: props.handleSlug, displayName: `@${props.handleSlug}`, avatarUrl: props.handleAvatarUrl, editable: Boolean(props.onPickAvatar), onPickFile: props.onPickAvatar, onTagClick: pickerInteractive ? () => setPickerOpen(!pickerOpen) : undefined, tagExpanded: pickerOpen, tagLabel: "Account and handles", style: {
|
|
993
|
+
background: "var(--color-light-background-01, #eee)",
|
|
994
|
+
border: "1px solid var(--color-light-decorative-01, #ddd)",
|
|
995
|
+
color: "var(--color-light-primary, #333)",
|
|
996
|
+
fontSize: 13,
|
|
997
|
+
padding: "3px 8px 3px 4px",
|
|
998
|
+
minWidth: 0,
|
|
999
|
+
maxWidth: "100%",
|
|
1000
|
+
} }))) : props.viewerPending ? (React.createElement(ViewerTagView, { slug: "", pending: true })) : props.viewerNeedsHandle && !pickerInteractive ? (React.createElement(ViewerTagView, { slug: "", needsHandle: true, onChooseHandle: props.onChooseHandle })) : props.viewerNeedsHandle ? (React.createElement("div", { ref: pickerWrapRef },
|
|
1001
|
+
React.createElement(ViewerTagView, { slug: "?", displayName: "Account", onTagClick: () => setPickerOpen(!pickerOpen), tagExpanded: pickerOpen, tagLabel: "Account and handles" }))) : pickerInteractive ? (React.createElement("div", { ref: pickerWrapRef },
|
|
1002
|
+
React.createElement(ViewerTagView, { slug: "?", displayName: "Account", onTagClick: () => setPickerOpen(!pickerOpen), tagExpanded: pickerOpen, tagLabel: "Account and handles" }))) : (React.createElement(ViewerTagView, { slug: "?", anonymous: true, onSignIn: props.onSignIn })))),
|
|
674
1003
|
(() => {
|
|
675
|
-
const
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
1004
|
+
const wizardBanner = (props.publishWizardActive === true || props.publishWizardError === true) && props.onPublish;
|
|
1005
|
+
if (wizardBanner && props.selectedNav !== "share") {
|
|
1006
|
+
return (React.createElement("div", { style: { padding: "0 14px", flexShrink: 0 } },
|
|
1007
|
+
React.createElement(PublishBanner, { variant: props.publishState === "draft" || props.publishState === "old" ? props.publishState : undefined, onPublish: props.onPublish, publishing: props.publishing, wizardActive: props.publishWizardActive, wizardError: props.publishWizardError, escapeRevealed: props.publishEscapeRevealed, onPublishWithoutAccess: props.onPublishWithoutAccess, onRetryWizard: props.onRetryWizard })));
|
|
1008
|
+
}
|
|
1009
|
+
if (props.autoPublishError === true && props.selectedNav !== "share") {
|
|
1010
|
+
return (React.createElement("div", { style: { padding: "0 14px", flexShrink: 0 } },
|
|
1011
|
+
React.createElement(PublishBanner, { variant: undefined, autoPublishError: true, onRetryAutoPublish: props.onRetryAutoPublish })));
|
|
1012
|
+
}
|
|
1013
|
+
if (props.statusBanner && props.selectedNav !== "share") {
|
|
1014
|
+
return React.createElement("div", { style: { padding: "0 14px", flexShrink: 0 } }, props.statusBanner);
|
|
1015
|
+
}
|
|
1016
|
+
if (props.versionLocked === true && props.selectedNav !== "share") {
|
|
1017
|
+
return (React.createElement("div", { style: { padding: "0 14px", flexShrink: 0 } },
|
|
1018
|
+
React.createElement(PublishBanner, { variant: undefined, locked: true, onUnlock: props.onUnlock })));
|
|
1019
|
+
}
|
|
1020
|
+
if (props.signedOutSavePrompt && props.selectedNav !== "share") {
|
|
1021
|
+
return (React.createElement("div", { style: { padding: "0 14px", flexShrink: 0 } },
|
|
1022
|
+
React.createElement(SignedOutSavePrompt, { onSignIn: props.onSignIn })));
|
|
1023
|
+
}
|
|
1024
|
+
if (props.selectedNav === "share")
|
|
1025
|
+
return null;
|
|
1026
|
+
const hasPendingVersion = props.publishState === "draft" || props.publishState === "old";
|
|
1027
|
+
if (hasPendingVersion && Boolean(props.onPublish)) {
|
|
1028
|
+
return (React.createElement("div", { style: { padding: "0 14px", flexShrink: 0 } },
|
|
1029
|
+
React.createElement(PublishBanner, { variant: props.publishState === "draft" || props.publishState === "old" ? props.publishState : undefined, onPublish: props.onPublish, publishing: props.publishing })));
|
|
1030
|
+
}
|
|
1031
|
+
return null;
|
|
682
1032
|
})(),
|
|
683
|
-
React.createElement("div", { "data-vibe-card-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
1033
|
+
editorTabForRender != null && props.selectedNav !== "share" && !agentPanelActive && (React.createElement("div", { "data-vibe-card-editor-tabs": true, style: { padding: "0 14px 6px", flexShrink: 0 } },
|
|
1034
|
+
React.createElement(EditorTabStrip, { tab: editorTabForRender, disabledTabs: props.disabledEditorTabs, onTab: (t) => {
|
|
1035
|
+
if (props.disabledEditorTabs?.includes(t) === true)
|
|
1036
|
+
return;
|
|
1037
|
+
props.onEditorTab?.(t);
|
|
1038
|
+
}, standing: {
|
|
1039
|
+
viewerMode: props.viewerMode,
|
|
1040
|
+
memberReadOnly: props.memberReadOnly,
|
|
1041
|
+
adminMode: props.adminMode,
|
|
1042
|
+
versionLocked: props.versionLocked,
|
|
1043
|
+
publishState: props.publishState,
|
|
1044
|
+
publishAccess: props.publishAccess,
|
|
1045
|
+
} }))),
|
|
1046
|
+
(props.body == null || editorTabDisabled) && props.composerControls && !agentPanelActive && (React.createElement("div", { "data-testid": "vibe-card-composer-controls", "aria-hidden": streamLive ? true : undefined, inert: streamLive ? true : undefined, style: {
|
|
1047
|
+
padding: "0 14px",
|
|
1048
|
+
marginBottom: 6,
|
|
690
1049
|
flexShrink: 0,
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
React.createElement(
|
|
704
|
-
React.createElement(
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
adminMode: props.adminMode,
|
|
740
|
-
versionLocked: props.versionLocked,
|
|
741
|
-
publishState: props.publishState,
|
|
742
|
-
publishAccess: props.publishAccess,
|
|
743
|
-
} }))),
|
|
744
|
-
props.body == null && props.composerControls && !agentPanelActive && (React.createElement("div", { "data-testid": "vibe-card-composer-controls", "aria-hidden": streamLive ? true : undefined, inert: streamLive ? true : undefined, style: {
|
|
745
|
-
padding: "0 14px",
|
|
746
|
-
marginBottom: 6,
|
|
747
|
-
flexShrink: 0,
|
|
748
|
-
...(streamLive ? { visibility: "hidden" } : null),
|
|
749
|
-
} }, props.composerControls)),
|
|
750
|
-
React.createElement("div", { ref: scrollRegionRef, "data-testid": "vibe-card-scroll", style: {
|
|
751
|
-
padding: "0 14px 4px",
|
|
752
|
-
overflowY: "auto",
|
|
753
|
-
overflowX: "hidden",
|
|
754
|
-
flex: "1 1 auto",
|
|
755
|
-
minHeight: 0,
|
|
756
|
-
...((props.bodyFill && props.body) || agentPanelActive || props.body == null
|
|
757
|
-
? { display: "flex", flexDirection: "column" }
|
|
758
|
-
: null),
|
|
759
|
-
} },
|
|
760
|
-
props.retainedEditor != null && (React.createElement("div", { hidden: !props.editorVisible || agentPanelActive, inert: !props.editorVisible || agentPanelActive ? true : undefined, style: props.editorVisible && !agentPanelActive ? { flex: "1 1 auto", minHeight: 0 } : { display: "none" } }, props.retainedEditor)),
|
|
761
|
-
agentPanelActive ? (React.createElement("div", { style: { flex: "1 1 auto", minHeight: 0 } }, props.agentPanel)) : props.editorVisible && props.retainedEditor != null ? null : props.editorTab === "standing" ? (React.createElement(ViewerStandingView, { viewerMode: props.viewerMode, memberReadOnly: props.memberReadOnly, adminMode: props.adminMode, versionLocked: props.versionLocked, publishState: props.publishState, publishAccess: props.publishAccess, myGrant: props.myGrant, onToggleAdmin: props.onToggleAdmin, onUnlock: props.onUnlock })) : props.body != null ? (props.bodyFill ? (React.createElement("div", { style: { flex: "1 1 auto", minHeight: 0 } }, props.body)) : (props.body)) : (React.createElement(React.Fragment, null,
|
|
762
|
-
React.createElement("div", { ref: chipsRegionRef, style: streamFillActive
|
|
763
|
-
? { flex: "1 1 auto", minHeight: 0, display: "flex", flexDirection: "column" }
|
|
764
|
-
: { flex: "1 0 auto", minHeight: 0 } },
|
|
765
|
-
props.historyBody && (React.createElement("div", { "data-testid": "vibe-card-history", "aria-hidden": props.streamBody ? true : undefined, inert: props.streamBody ? true : undefined, style: { marginBottom: 8, ...(props.streamBody ? { display: "none" } : null) } }, props.historyBody)),
|
|
766
|
-
React.createElement("div", { "data-testid": "vibe-card-stream-region", style: {
|
|
767
|
-
position: "relative",
|
|
768
|
-
...(chipBuildLive ? { display: "flex", flexDirection: "column" } : {}),
|
|
769
|
-
...(streamFillActive ? { flex: "1 1 auto", minHeight: 0 } : null),
|
|
770
|
-
} },
|
|
771
|
-
props.streamBody && (React.createElement("div", { "data-testid": streamLive ? undefined : "vibe-card-stream-settled", style: streamLive
|
|
772
|
-
? {
|
|
773
|
-
...(chipBuildLive ? { flex: "1 1 auto" } : { position: "absolute", inset: 0 }),
|
|
774
|
-
display: "flex",
|
|
775
|
-
flexDirection: "column",
|
|
776
|
-
minHeight: 0,
|
|
777
|
-
}
|
|
778
|
-
: { marginBottom: 8 } },
|
|
779
|
-
React.createElement("div", { style: streamLive ? { flex: "1 1 auto", minHeight: 0, overflowY: "auto" } : undefined }, props.streamBody),
|
|
780
|
-
props.liveDuringBuild === true && React.createElement(PendingMessages, { messages: queued }))),
|
|
781
|
-
React.createElement("div", { "aria-hidden": streamLive && !chipBuildLive ? true : undefined, inert: streamLive && !chipBuildLive ? true : undefined, style: streamLive && !chipBuildLive ? { visibility: "hidden" } : { flexShrink: 0 } }, (props.seedOffer || props.upgradeChips || (visibleChips && visibleChips.length > 0)) && (React.createElement("div", { className: "mx-auto mt-2 w-full max-w-5xl" },
|
|
782
|
-
React.createElement(ChatMessageRow, { role: "ai", rowAttrs: { "data-message-role": "suggestions" } },
|
|
783
|
-
React.createElement("div", { className: "vibes-chip-well flex flex-col", "data-testid": "vibe-chip-set" },
|
|
784
|
-
(props.seedOffer || props.upgradeChips) && (React.createElement("div", { className: "flex flex-col gap-[6px]", inert: props.activeChip !== undefined },
|
|
785
|
-
props.seedOffer,
|
|
786
|
-
props.upgradeChips)),
|
|
787
|
-
visibleChips && visibleChips.length > 0 && (React.createElement(OptionButtons, { options: visibleChips, activeOption: props.activeChip, inSet: true, isFirst: props.activeChip === undefined, firstMessage: props.isOwner
|
|
788
|
-
? "Suggested requests:"
|
|
789
|
-
: "Describe a change to remix your own copy of this app:", onSelect: (o) => {
|
|
790
|
-
const r = props.onSelectChip?.(o);
|
|
791
|
-
return r && typeof r === "object" && "then" in r ? r.then((ok) => ok ?? false) : false;
|
|
792
|
-
}, decorate: (option) => decorateChip(option, props) }))))))),
|
|
793
|
-
props.streamFooter !== undefined && React.createElement("div", { className: "mx-auto w-full max-w-5xl" }, props.streamFooter)))))),
|
|
794
|
-
props.body == null && !agentPanelActive && (React.createElement("div", { style: { flexShrink: 0, padding: "0 14px 10px" } },
|
|
795
|
-
React.createElement(OtherRow, { value: draft, onValueChange: setDraft, queued: queued, onQueuedChange: setQueued, onSubmitOther: props.onSubmitOther, generating: props.generating, liveDuringBuild: props.liveDuringBuild, canSendNow: props.canSendNow, onStop: props.onStop, stopDisabled: props.stopDisabled, attachmentsCtl: attachmentsCtl }))),
|
|
1050
|
+
...(streamLive ? { visibility: "hidden" } : null),
|
|
1051
|
+
} }, props.composerControls)),
|
|
1052
|
+
React.createElement("div", { ref: scrollRegionRef, "data-testid": "vibe-card-scroll", style: {
|
|
1053
|
+
padding: "0 14px 4px",
|
|
1054
|
+
overflowY: "auto",
|
|
1055
|
+
overflowX: "hidden",
|
|
1056
|
+
flex: "1 1 auto",
|
|
1057
|
+
minHeight: 0,
|
|
1058
|
+
...((props.bodyFill && props.body) || agentPanelActive || props.body == null
|
|
1059
|
+
? { display: "flex", flexDirection: "column" }
|
|
1060
|
+
: null),
|
|
1061
|
+
} },
|
|
1062
|
+
retainedEditorMounted && (React.createElement("div", { hidden: !retainedEditorVisible || agentPanelActive, inert: !retainedEditorVisible || agentPanelActive ? true : undefined, style: retainedEditorVisible && !agentPanelActive ? { flex: "1 1 auto", minHeight: 0 } : { display: "none" } }, props.retainedEditor)),
|
|
1063
|
+
agentPanelActive ? (React.createElement("div", { style: { flex: "1 1 auto", minHeight: 0 } }, props.agentPanel)) : retainedEditorVisible && props.retainedEditor != null ? null : editorTabForRender === "standing" ? (React.createElement(ViewerStandingView, { viewerMode: props.viewerMode, memberReadOnly: props.memberReadOnly, adminMode: props.adminMode, versionLocked: props.versionLocked, publishState: props.publishState, publishAccess: props.publishAccess, myGrant: props.myGrant, onToggleAdmin: props.onToggleAdmin, onUnlock: props.onUnlock })) : props.body != null && editorTabDisabled === false ? (props.bodyFill ? (React.createElement("div", { style: { flex: "1 1 auto", minHeight: 0 } }, props.body)) : (props.body)) : (React.createElement(React.Fragment, null,
|
|
1064
|
+
React.createElement("div", { ref: chipsRegionRef, style: streamFillActive
|
|
1065
|
+
? { flex: "1 1 auto", minHeight: 0, display: "flex", flexDirection: "column" }
|
|
1066
|
+
: { flex: "1 0 auto", minHeight: 0 } },
|
|
1067
|
+
props.historyBody && (React.createElement("div", { "data-testid": "vibe-card-history", "aria-hidden": props.streamBody ? true : undefined, inert: props.streamBody ? true : undefined, style: { marginBottom: 8, ...(props.streamBody ? { display: "none" } : null) } }, props.historyBody)),
|
|
1068
|
+
React.createElement("div", { "data-testid": "vibe-card-stream-region", style: {
|
|
1069
|
+
position: "relative",
|
|
1070
|
+
...(chipBuildLive ? { display: "flex", flexDirection: "column" } : {}),
|
|
1071
|
+
...(streamFillActive ? { flex: "1 1 auto", minHeight: 0 } : null),
|
|
1072
|
+
} },
|
|
1073
|
+
props.streamBody && (React.createElement("div", { "data-testid": streamLive ? undefined : "vibe-card-stream-settled", style: streamLive
|
|
1074
|
+
? {
|
|
1075
|
+
...(chipBuildLive ? { flex: "1 1 auto" } : { position: "absolute", inset: 0 }),
|
|
1076
|
+
display: "flex",
|
|
1077
|
+
flexDirection: "column",
|
|
1078
|
+
minHeight: 0,
|
|
1079
|
+
}
|
|
1080
|
+
: { marginBottom: 8 } },
|
|
1081
|
+
React.createElement("div", { style: streamLive ? { flex: "1 1 auto", minHeight: 0, overflowY: "auto" } : undefined }, props.streamBody),
|
|
1082
|
+
props.liveDuringBuild === true && React.createElement(PendingMessages, { messages: queued }))),
|
|
1083
|
+
React.createElement("div", { "aria-hidden": streamLive && !chipBuildLive ? true : undefined, inert: streamLive && !chipBuildLive ? true : undefined, style: streamLive && !chipBuildLive ? { visibility: "hidden" } : { flexShrink: 0 } }, (props.seedOffer || props.upgradeChips || (visibleChips && visibleChips.length > 0)) && (React.createElement("div", { className: "mx-auto mt-2 w-full max-w-5xl" },
|
|
1084
|
+
React.createElement(ChatMessageRow, { role: "ai", rowAttrs: { "data-message-role": "suggestions" } },
|
|
1085
|
+
React.createElement("div", { className: "vibes-chip-well flex flex-col", "data-testid": "vibe-chip-set" },
|
|
1086
|
+
(props.seedOffer || props.upgradeChips) && (React.createElement("div", { className: "flex flex-col gap-[6px]", inert: props.activeChip !== undefined },
|
|
1087
|
+
props.seedOffer,
|
|
1088
|
+
props.upgradeChips)),
|
|
1089
|
+
visibleChips && visibleChips.length > 0 && (React.createElement(OptionButtons, { options: visibleChips, activeOption: props.activeChip, inSet: true, isFirst: props.activeChip === undefined, firstMessage: props.isOwner
|
|
1090
|
+
? "Suggested requests:"
|
|
1091
|
+
: "Describe a change to remix your own copy of this app:", onSelect: (o) => {
|
|
1092
|
+
const r = props.onSelectChip?.(o);
|
|
1093
|
+
return r && typeof r === "object" && "then" in r ? r.then((ok) => ok ?? false) : false;
|
|
1094
|
+
}, decorate: (option) => decorateChip(option, props) }))))))),
|
|
1095
|
+
props.streamFooter !== undefined && React.createElement("div", { className: "mx-auto w-full max-w-5xl" }, props.streamFooter)))))),
|
|
1096
|
+
(props.body == null || editorTabDisabled) && !agentPanelActive && (React.createElement("div", { style: { flexShrink: 0, padding: "0 14px 10px" } },
|
|
1097
|
+
React.createElement(OtherRow, { value: draft, onValueChange: setDraft, queued: queued, onQueuedChange: setQueued, onSubmitOther: props.onSubmitOther, generating: props.generating, liveDuringBuild: props.liveDuringBuild, canSendNow: props.canSendNow, onStop: props.onStop, stopDisabled: props.stopDisabled, attachmentsCtl: attachmentsCtl })))),
|
|
796
1098
|
agentPanelActive ? (React.createElement("div", { "aria-hidden": true, style: { display: "flex", flexShrink: 0, padding: "0 8px" } },
|
|
797
|
-
React.createElement("div", { style: { width: 120, height: 50, marginLeft: "auto" } }))) : (React.createElement("div", { style: {
|
|
1099
|
+
React.createElement("div", { style: { width: 120, height: 50, marginLeft: "auto" } }))) : (React.createElement("div", { "data-vibe-card-nav": true, style: {
|
|
798
1100
|
display: "flex",
|
|
799
1101
|
alignItems: "center",
|
|
800
1102
|
gap: "var(--uvc-nav-gap, 6px)",
|
|
801
1103
|
padding: "0 8px",
|
|
802
|
-
borderTop: "1px solid
|
|
1104
|
+
borderTop: "1px solid transparent",
|
|
803
1105
|
flexShrink: 0,
|
|
804
1106
|
} },
|
|
805
|
-
React.createElement(NavIcon, { label: "Home", color: "#2563eb", onClick: props.onHome },
|
|
1107
|
+
React.createElement(NavIcon, { label: "Home", color: "var(--uvc-nav-home, #2563eb)", onClick: props.onHome },
|
|
806
1108
|
React.createElement("svg", { width: "17", height: "17", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: 2.2, strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": "true" },
|
|
807
1109
|
React.createElement("path", { d: "M3 12l9-9 9 9" }),
|
|
808
1110
|
React.createElement("path", { d: "M5 10v10a1 1 0 001 1h4v-6h4v6h4a1 1 0 001-1V10" }))),
|
|
809
|
-
React.createElement(NavIcon, { label: "
|
|
810
|
-
React.createElement("svg", { width: "17", height: "17", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: 2, "aria-hidden": "true" },
|
|
811
|
-
React.createElement("path", { d: "M21 11a8 8 0 01-8 8H7l-4 3V11a9 9 0 0118 0Z" }))),
|
|
812
|
-
React.createElement(NavIcon, { label: "Edit", color: "var(--uvc-nav-edit, #c2410c)", selected: ["edit", "standing", "code", "files", "data", "style", "settings", "faq"].includes(props.selectedNav ?? "edit"), onClick: props.onEdit },
|
|
1111
|
+
React.createElement(NavIcon, { label: "Edit", color: "var(--uvc-nav-edit, #c2410c)", selected: ["edit", "edit-chat", "standing", "code", "files", "data", "style", "settings", "faq"].includes(props.selectedNav ?? "edit"), onClick: props.onEdit ?? props.onChat },
|
|
813
1112
|
React.createElement("svg", { width: "17", height: "17", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: 2.2, strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": "true" },
|
|
814
1113
|
React.createElement("path", { d: "M12 20h9" }),
|
|
815
1114
|
React.createElement("path", { d: "M16.5 3.5a2.121 2.121 0 0 1 3 3L7 19l-4 1 1-4 12.5-12.5z" }))),
|
|
@@ -917,7 +1216,7 @@ export function UnifiedVibeCard(props) {
|
|
|
917
1216
|
} },
|
|
918
1217
|
React.createElement("span", { "aria-hidden": true, style: { width: 6, height: 6, borderRadius: "50%", background: "#f59e0b" } }),
|
|
919
1218
|
"draft")),
|
|
920
|
-
React.createElement("button", { type: "button", "aria-label": open
|
|
1219
|
+
React.createElement("button", { type: "button", "data-vibe-switch-glass": true, "aria-label": open
|
|
921
1220
|
? "Close vibe menu"
|
|
922
1221
|
: (props.pendingRequestCount ?? 0) > 0
|
|
923
1222
|
?
|
|
@@ -933,10 +1232,10 @@ export function UnifiedVibeCard(props) {
|
|
|
933
1232
|
position: "relative",
|
|
934
1233
|
overflow: "visible",
|
|
935
1234
|
} },
|
|
936
|
-
React.createElement(
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
1235
|
+
switchGlassColor !== ovalColors.neutral && (React.createElement(React.Fragment, { key: `${switchGlassColor}|${props.switchOvalStatusKey ?? ""}` },
|
|
1236
|
+
React.createElement("span", { "data-vibe-switch-rest": true, "aria-hidden": "true" }),
|
|
1237
|
+
React.createElement("span", { "data-vibe-switch-highlight": true, "data-testid": "vibe-switch-highlight", "data-arrival-amber": switchGlassColor === ovalColors.yellow, "aria-hidden": "true", style: { color: switchGlassColor } }))),
|
|
1238
|
+
React.createElement(VibesSwitch, { size: 60, style: { position: "absolute", right: 0, bottom: 0, pointerEvents: "none" }, isActive: !open, isTwinkling: !open && isTwinkling, isTeasing: !open && isTeasing }),
|
|
940
1239
|
!open && (props.pendingRequestCount ?? 0) > 0 && (React.createElement("span", { "data-testid": "vibe-switch-pending-badge", "aria-hidden": "true", style: {
|
|
941
1240
|
position: "absolute",
|
|
942
1241
|
top: -4,
|
|
@@ -1218,22 +1517,22 @@ function FastPathToggle({ blessed, onClick }) {
|
|
|
1218
1517
|
function NavIcon({ label, color, selected, onClick, buttonRef, badgeCount, children, }) {
|
|
1219
1518
|
const showBadge = typeof badgeCount === "number" && badgeCount > 0;
|
|
1220
1519
|
const badgeText = showBadge ? (badgeCount > 99 ? "99+" : String(badgeCount)) : "";
|
|
1221
|
-
return (React.createElement("button", { ref: buttonRef, type: "button", "aria-label": showBadge ? `${label} (${badgeCount})` : label, title: label, onClick: onClick, style: {
|
|
1520
|
+
return (React.createElement("button", { ref: buttonRef, type: "button", "aria-label": showBadge ? `${label} (${badgeCount})` : label, title: label, "data-vibe-nav-selected": selected === true, onClick: onClick, style: {
|
|
1222
1521
|
position: "relative",
|
|
1223
1522
|
width: "var(--uvc-nav-size, 38px)",
|
|
1224
1523
|
height: "var(--uvc-nav-size, 38px)",
|
|
1225
1524
|
flexShrink: 0,
|
|
1226
1525
|
boxSizing: "border-box",
|
|
1227
1526
|
borderRadius: "50%",
|
|
1228
|
-
background: "
|
|
1527
|
+
background: "var(--uvc-nav-fill)",
|
|
1229
1528
|
display: "flex",
|
|
1230
1529
|
alignItems: "center",
|
|
1231
1530
|
justifyContent: "center",
|
|
1232
1531
|
color,
|
|
1233
1532
|
fontSize: 16,
|
|
1234
1533
|
cursor: "pointer",
|
|
1235
|
-
border:
|
|
1236
|
-
boxShadow: selected ?
|
|
1534
|
+
border: selected ? "var(--uvc-nav-selected-width) solid currentColor" : "1px solid var(--uvc-nav-border)",
|
|
1535
|
+
boxShadow: selected ? "var(--uvc-nav-selected-shadow)" : "none",
|
|
1237
1536
|
} },
|
|
1238
1537
|
children,
|
|
1239
1538
|
showBadge ? (React.createElement("span", { "aria-hidden": "true", style: {
|
|
@@ -1334,9 +1633,10 @@ function OtherRow({ value, onValueChange, queued, onQueuedChange, onSubmitOther,
|
|
|
1334
1633
|
const submitDisabled = attachmentsCtl.busy || (Boolean(generating) && attachmentsCtl.readyAttachments.length > 0);
|
|
1335
1634
|
const sendNow = liveDuringBuild === true && canSendNow === true && queued.length === 0 && attachmentsCtl.readyAttachments.length === 0;
|
|
1336
1635
|
const hasUnsentContent = value.trim() !== "" || attachmentsCtl.readyAttachments.length > 0;
|
|
1636
|
+
const composerDrop = composerFileDrop({ onFiles: attachmentsCtl.add });
|
|
1337
1637
|
return (React.createElement(React.Fragment, null,
|
|
1338
1638
|
React.createElement(AttachmentChips, { chips: attachmentsCtl.attachments, onRemove: attachmentsCtl.remove }),
|
|
1339
|
-
React.createElement("form", { onSubmit: (e) => {
|
|
1639
|
+
React.createElement("form", { onDragOver: composerDrop.onDragOver, onDrop: composerDrop.onDrop, onSubmit: (e) => {
|
|
1340
1640
|
e.preventDefault();
|
|
1341
1641
|
const text = value.trim();
|
|
1342
1642
|
const files = attachmentsCtl.readyAttachments;
|
|
@@ -1391,7 +1691,9 @@ function OtherRow({ value, onValueChange, queued, onQueuedChange, onSubmitOther,
|
|
|
1391
1691
|
? "Sends when the current change finishes"
|
|
1392
1692
|
: undefined, style: {
|
|
1393
1693
|
...OTHER_ROW_BUTTON_STYLE,
|
|
1394
|
-
background: "var(--
|
|
1694
|
+
background: "var(--uvc-submit-fill, rgba(64,89,114,.2))",
|
|
1695
|
+
color: "var(--uvc-submit-arrow, var(--vibes-cream, #fffff0))",
|
|
1696
|
+
boxShadow: "none",
|
|
1395
1697
|
opacity: submitDisabled ? 0.5 : 1,
|
|
1396
1698
|
cursor: submitDisabled ? "default" : "pointer",
|
|
1397
1699
|
} },
|