@runtypelabs/persona 4.23.1 → 4.24.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/animations/glyph-cycle.d.cts +1 -1
- package/dist/animations/glyph-cycle.d.ts +1 -1
- package/dist/animations/{types-9Vxm-PPz.d.cts → types-Db61aI9J.d.cts} +25 -2
- package/dist/animations/{types-9Vxm-PPz.d.ts → types-Db61aI9J.d.ts} +25 -2
- package/dist/animations/wipe.d.cts +1 -1
- package/dist/animations/wipe.d.ts +1 -1
- package/dist/animations-extra.d.cts +25 -2
- package/dist/animations-extra.d.ts +25 -2
- package/dist/approval-ui-3NMYNXBD.js +1 -0
- package/dist/approval-ui.cjs +2 -2
- package/dist/approval-ui.d.cts +261 -40
- package/dist/approval-ui.d.ts +261 -40
- package/dist/approval-ui.js +2 -2
- package/dist/{artifacts-ui-F4N6VMKF.js → artifacts-ui-IGB5YKLO.js} +4 -4
- package/dist/artifacts-ui.d.cts +256 -28
- package/dist/artifacts-ui.d.ts +256 -28
- package/dist/{chunk-NIKYKSNZ.js → chunk-7CO4T5KB.js} +1 -1
- package/dist/codegen.cjs +11 -11
- package/dist/codegen.js +13 -13
- package/dist/context-mentions.d.cts +256 -28
- package/dist/context-mentions.d.ts +256 -28
- package/dist/event-stream-view.d.cts +256 -28
- package/dist/event-stream-view.d.ts +256 -28
- package/dist/forms-ui.d.cts +291 -30
- package/dist/forms-ui.d.ts +291 -30
- package/dist/history-view.d.cts +25 -2
- package/dist/history-view.d.ts +25 -2
- package/dist/index.cjs +70 -69
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +337 -51
- package/dist/index.d.ts +337 -51
- package/dist/index.global.js +57 -54
- package/dist/index.global.js.map +1 -1
- package/dist/index.js +70 -69
- package/dist/index.js.map +1 -1
- package/dist/install.global.js +1 -1
- package/dist/install.global.js.map +1 -1
- package/dist/launcher.global.js +2 -2
- package/dist/launcher.global.js.map +1 -1
- package/dist/session-reconnect.d.cts +256 -28
- package/dist/session-reconnect.d.ts +256 -28
- package/dist/smart-dom-reader.d.cts +256 -28
- package/dist/smart-dom-reader.d.ts +256 -28
- package/dist/theme-editor-preview.cjs +74 -73
- package/dist/theme-editor-preview.d.cts +263 -28
- package/dist/theme-editor-preview.d.ts +263 -28
- package/dist/theme-editor-preview.js +51 -50
- package/dist/theme-editor.cjs +10 -10
- package/dist/theme-editor.d.cts +276 -30
- package/dist/theme-editor.d.ts +276 -30
- package/dist/theme-editor.js +10 -10
- package/dist/theme-reference.cjs +1 -1
- package/dist/theme-reference.d.cts +1522 -11
- package/dist/theme-reference.d.ts +1522 -11
- package/dist/theme-reference.js +1 -1
- package/dist/widget.css +1 -1
- package/package.json +3 -2
- package/src/__fixtures__/defaults-parity.v4.json +776 -0
- package/src/approval-ui-entry.ts +0 -1
- package/src/approval-ui-loader.ts +5 -4
- package/src/approval-ui.ts +0 -1
- package/src/client-identity-proof.test.ts +193 -0
- package/src/client-session-warm.test.ts +216 -0
- package/src/client-visitor-history.test.ts +6 -0
- package/src/client.tool-pair-replay.test.ts +325 -0
- package/src/client.ts +154 -61
- package/src/codegen.test.ts +24 -0
- package/src/components/activity-row.test.ts +100 -0
- package/src/components/activity-row.ts +136 -0
- package/src/components/approval-actions.test.ts +8 -5
- package/src/components/approval-actions.ts +19 -6
- package/src/components/approval-bubble.test.ts +56 -9
- package/src/components/approval-bubble.ts +36 -41
- package/src/components/composer-builder.ts +5 -2
- package/src/components/composer-parts.ts +10 -2
- package/src/components/header-builder.test.ts +32 -0
- package/src/components/header-builder.ts +7 -4
- package/src/components/header-layouts.test.ts +12 -0
- package/src/components/header-layouts.ts +3 -2
- package/src/components/launcher.ts +11 -2
- package/src/components/message-bubble.test.ts +22 -0
- package/src/components/message-bubble.ts +7 -3
- package/src/components/panel.test.ts +52 -1
- package/src/components/panel.ts +47 -8
- package/src/components/pill-composer-builder.test.ts +2 -0
- package/src/components/pill-composer-builder.ts +0 -1
- package/src/components/reasoning-bubble.ts +29 -17
- package/src/components/suggestions.test.ts +1 -0
- package/src/components/suggestions.ts +0 -16
- package/src/components/tool-bubble.ts +131 -114
- package/src/components/tool-details.test.ts +87 -0
- package/src/components/tool-details.ts +102 -0
- package/src/components/welcome.test.ts +8 -0
- package/src/components/welcome.ts +4 -2
- package/src/defaults-parity.test.ts +158 -0
- package/src/defaults.test.ts +69 -0
- package/src/defaults.ts +128 -49
- package/src/generated/runtype-openapi-contract.ts +28 -13
- package/src/index-core.ts +2 -0
- package/src/install.test.ts +24 -0
- package/src/install.ts +3 -1
- package/src/launcher-global.ts +2 -1
- package/src/launcher-variants.test.ts +52 -0
- package/src/runtime/init-update-reset.test.ts +21 -0
- package/src/session.ts +61 -9
- package/src/styles/widget-styles.test.ts +19 -0
- package/src/styles/widget.css +295 -23
- package/src/theme-editor/index.ts +2 -0
- package/src/theme-editor/preview-utils.test.ts +8 -0
- package/src/theme-editor/preview-utils.ts +7 -3
- package/src/theme-editor/sections.test.ts +31 -0
- package/src/theme-editor/sections.ts +55 -1
- package/src/theme-editor/state-preferences.test.ts +49 -0
- package/src/theme-editor/state.ts +73 -15
- package/src/theme-reference.test.ts +20 -0
- package/src/theme-reference.ts +11 -5
- package/src/tool-call-display-defaults.test.ts +33 -1
- package/src/types/theme.ts +80 -3
- package/src/types.ts +179 -23
- package/src/ui.activity-row.test.ts +91 -0
- package/src/ui.approval-plugin.test.ts +63 -0
- package/src/ui.composer-compact.test.ts +24 -2
- package/src/ui.composer-placement.test.ts +23 -0
- package/src/ui.detached-panel.test.ts +33 -6
- package/src/ui.docked.test.ts +19 -0
- package/src/ui.header-update-stability.test.ts +25 -0
- package/src/ui.identity-proof.test.ts +58 -0
- package/src/ui.launcher-teaser.test.ts +25 -0
- package/src/ui.message-width.test.ts +17 -2
- package/src/ui.reasoning-display.test.ts +92 -0
- package/src/ui.rebuild-composer.test.ts +20 -3
- package/src/ui.scroll.test.ts +32 -0
- package/src/ui.session-init.test.ts +312 -0
- package/src/ui.status-indicator.test.ts +82 -0
- package/src/ui.suggest-replies.test.ts +11 -0
- package/src/ui.ts +363 -74
- package/src/ui.v5-defaults.test.ts +144 -0
- package/src/ui.welcome.test.ts +92 -3
- package/src/utils/__snapshots__/tokens-parity.test.ts.snap +811 -140
- package/src/utils/code-generators.ts +14 -0
- package/src/utils/composer-compact.test.ts +0 -2
- package/src/utils/composer-compact.ts +2 -4
- package/src/utils/composer-placement.ts +2 -3
- package/src/utils/config-merge.test.ts +81 -5
- package/src/utils/config-merge.ts +13 -3
- package/src/utils/defaults-provenance.ts +67 -0
- package/src/utils/dock.ts +7 -1
- package/src/utils/launcher-variant.ts +16 -0
- package/src/utils/panel-config.ts +97 -0
- package/src/utils/status-indicator.ts +39 -0
- package/src/utils/theme.test.ts +182 -0
- package/src/utils/theme.ts +131 -18
- package/src/utils/tokens.test.ts +122 -1
- package/src/utils/tokens.ts +177 -17
- package/src/utils/tool-pair-replay.ts +100 -0
- package/src/welcome.test.ts +23 -0
- package/src/welcome.ts +16 -9
- package/dist/approval-ui-K7R5Q5OC.js +0 -1
package/src/styles/widget.css
CHANGED
|
@@ -582,6 +582,7 @@
|
|
|
582
582
|
--persona-components-suggestion-chip-foreground,
|
|
583
583
|
var(--persona-text)
|
|
584
584
|
);
|
|
585
|
+
font-weight: var(--persona-components-suggestion-chip-fontWeight, 500);
|
|
585
586
|
font-size: var(--persona-components-suggestion-chip-fontSize, 0.8125rem);
|
|
586
587
|
line-height: var(--persona-components-suggestion-chip-lineHeight, 1.25);
|
|
587
588
|
}
|
|
@@ -606,6 +607,7 @@
|
|
|
606
607
|
var(--persona-text)
|
|
607
608
|
);
|
|
608
609
|
box-shadow: var(--persona-components-suggestion-card-shadow, none);
|
|
610
|
+
font-weight: var(--persona-components-suggestion-card-fontWeight, 500);
|
|
609
611
|
font-size: var(--persona-components-suggestion-card-fontSize, 0.875rem);
|
|
610
612
|
line-height: var(--persona-components-suggestion-card-lineHeight, 1.35);
|
|
611
613
|
}
|
|
@@ -630,6 +632,7 @@
|
|
|
630
632
|
--persona-components-suggestion-list-foreground,
|
|
631
633
|
var(--persona-text)
|
|
632
634
|
);
|
|
635
|
+
font-weight: var(--persona-components-suggestion-list-fontWeight, 500);
|
|
633
636
|
font-size: var(--persona-components-suggestion-list-fontSize, 0.875rem);
|
|
634
637
|
line-height: var(--persona-components-suggestion-list-lineHeight, 1.35);
|
|
635
638
|
}
|
|
@@ -2812,11 +2815,6 @@
|
|
|
2812
2815
|
}
|
|
2813
2816
|
}
|
|
2814
2817
|
|
|
2815
|
-
/* Prevent form container from showing focus styles */
|
|
2816
|
-
.persona-widget-composer:focus-within {
|
|
2817
|
-
outline: none !important;
|
|
2818
|
-
}
|
|
2819
|
-
|
|
2820
2818
|
.persona-widget-composer:focus-within textarea {
|
|
2821
2819
|
border: none !important;
|
|
2822
2820
|
outline: none !important;
|
|
@@ -2869,6 +2867,25 @@
|
|
|
2869
2867
|
border-color: var(--persona-composer-border-color, var(--persona-border, #e5e7eb));
|
|
2870
2868
|
}
|
|
2871
2869
|
|
|
2870
|
+
/* Focus belongs to the whole form, including its action controls. An outline
|
|
2871
|
+
adds no layout size and preserves custom resting shadows. Unset V4 tokens
|
|
2872
|
+
retain the resting border and no ring. Shared by compact and expanded forms. */
|
|
2873
|
+
[data-persona-root] .persona-widget-composer:focus-within {
|
|
2874
|
+
outline: var(--persona-components-composer-focusRing, none);
|
|
2875
|
+
outline-offset: 1px;
|
|
2876
|
+
}
|
|
2877
|
+
|
|
2878
|
+
[data-persona-root] .persona-widget-composer:not(.persona-pill-composer):focus-within {
|
|
2879
|
+
border-color: var(
|
|
2880
|
+
--persona-components-composer-focusBorderColor,
|
|
2881
|
+
var(--persona-composer-border-color, var(--persona-border, #e5e7eb))
|
|
2882
|
+
);
|
|
2883
|
+
}
|
|
2884
|
+
|
|
2885
|
+
[data-persona-root] .persona-pill-composer:focus-within {
|
|
2886
|
+
border-color: var(--persona-components-composer-focusBorderColor, var(--persona-border, #e5e7eb));
|
|
2887
|
+
}
|
|
2888
|
+
|
|
2872
2889
|
/* Composer type scale, themeable via `components.composer.fontSize` /
|
|
2873
2890
|
`.lineHeight`. Outranks the `persona-text-sm` utility on the textarea;
|
|
2874
2891
|
fallbacks match it. Applies to the pill composer's textarea too. */
|
|
@@ -2927,6 +2944,15 @@
|
|
|
2927
2944
|
Positioning lives here, never inline: a plugin-owned footer is exempt from
|
|
2928
2945
|
the cssText reset in applyFullHeightStyles, so an inline design would
|
|
2929
2946
|
diverge for plugin composers. */
|
|
2947
|
+
|
|
2948
|
+
/* Optional composer chrome tokens retain the legacy fallback in V4. */
|
|
2949
|
+
.persona-widget-footer.persona-border-t-persona-divider {
|
|
2950
|
+
border-top: var(--persona-components-composer-footerBorder, 1px solid var(--persona-divider));
|
|
2951
|
+
}
|
|
2952
|
+
[data-persona-composer-submit].persona-composer-control {
|
|
2953
|
+
border-radius: var(--persona-components-composer-sendButtonRadius, var(--persona-button-radius));
|
|
2954
|
+
}
|
|
2955
|
+
|
|
2930
2956
|
[data-persona-root][data-persona-composer-placement="overlay"] .persona-widget-footer {
|
|
2931
2957
|
position: absolute;
|
|
2932
2958
|
inset: auto 0 var(--persona-composer-lift, 0px) 0;
|
|
@@ -3087,6 +3113,25 @@
|
|
|
3087
3113
|
padding: 0;
|
|
3088
3114
|
}
|
|
3089
3115
|
|
|
3116
|
+
/* Inline per-control styles take precedence over these theme defaults. */
|
|
3117
|
+
.persona-header-control.persona-rounded-full {
|
|
3118
|
+
border-radius: var(--persona-components-header-controlBorderRadius, 9999px);
|
|
3119
|
+
}
|
|
3120
|
+
.persona-header-control:hover,
|
|
3121
|
+
.persona-header-control:focus-visible {
|
|
3122
|
+
--persona-header-control-state-fg: var(--persona-components-header-controlHoverForeground);
|
|
3123
|
+
}
|
|
3124
|
+
.persona-header-control.hover\:persona-bg-gray-100:hover {
|
|
3125
|
+
background-color: var(--persona-components-header-controlHoverBackground);
|
|
3126
|
+
}
|
|
3127
|
+
.persona-header-control:focus-visible {
|
|
3128
|
+
background-color: var(--persona-components-header-controlHoverBackground);
|
|
3129
|
+
outline: var(--persona-components-header-controlFocusOutline, revert);
|
|
3130
|
+
}
|
|
3131
|
+
[data-persona-defaults="v5"] .persona-header-control:focus-visible {
|
|
3132
|
+
outline-offset: 2px;
|
|
3133
|
+
}
|
|
3134
|
+
|
|
3090
3135
|
.persona-header-control--glyph > svg {
|
|
3091
3136
|
width: var(--persona-header-control-icon-size, 20px);
|
|
3092
3137
|
height: var(--persona-header-control-icon-size, 20px);
|
|
@@ -3340,6 +3385,7 @@
|
|
|
3340
3385
|
.persona-message-assistant-bubble {
|
|
3341
3386
|
border-radius: var(--persona-message-assistant-radius, var(--persona-radius-lg, 0.5rem));
|
|
3342
3387
|
border-color: var(--persona-message-assistant-border, var(--persona-border, #e5e7eb));
|
|
3388
|
+
border-width: var(--persona-message-assistant-border-width, 1px);
|
|
3343
3389
|
}
|
|
3344
3390
|
|
|
3345
3391
|
[data-persona-root] .persona-message-assistant-bubble.persona-shadow-sm {
|
|
@@ -3347,11 +3393,11 @@
|
|
|
3347
3393
|
}
|
|
3348
3394
|
|
|
3349
3395
|
[data-persona-root] .persona-message-user-bubble.persona-shadow-sm {
|
|
3350
|
-
box-shadow: var(--persona-message-user-shadow
|
|
3396
|
+
box-shadow: var(--persona-message-user-shadow);
|
|
3351
3397
|
}
|
|
3352
3398
|
|
|
3353
3399
|
[data-persona-root] .persona-tool-bubble.persona-shadow-sm {
|
|
3354
|
-
box-shadow: var(--persona-tool-bubble-shadow
|
|
3400
|
+
box-shadow: var(--persona-tool-bubble-shadow);
|
|
3355
3401
|
}
|
|
3356
3402
|
|
|
3357
3403
|
/* ==============================
|
|
@@ -3435,7 +3481,7 @@
|
|
|
3435
3481
|
}
|
|
3436
3482
|
|
|
3437
3483
|
[data-persona-root] .persona-reasoning-bubble.persona-shadow-sm {
|
|
3438
|
-
box-shadow: var(--persona-reasoning-bubble-shadow
|
|
3484
|
+
box-shadow: var(--persona-reasoning-bubble-shadow);
|
|
3439
3485
|
}
|
|
3440
3486
|
|
|
3441
3487
|
/* Artifact markdown (no .persona-message-bubble wrapper) */
|
|
@@ -4363,24 +4409,24 @@
|
|
|
4363
4409
|
/* Content areas: themed border and background for tool/reasoning bubbles */
|
|
4364
4410
|
.persona-tool-bubble .persona-border-t,
|
|
4365
4411
|
.persona-reasoning-bubble .persona-border-t {
|
|
4366
|
-
border-top-color: var(--cw-border, #e5e7eb);
|
|
4367
|
-
background-color: var(--cw-container, #f9fafb);
|
|
4412
|
+
border-top-color: var(--persona-cw-border, var(--cw-border, #e5e7eb));
|
|
4413
|
+
background-color: var(--persona-cw-container, var(--cw-container, #f9fafb));
|
|
4368
4414
|
}
|
|
4369
4415
|
|
|
4370
4416
|
/* Tool bubble code blocks: themed surface and border */
|
|
4371
4417
|
.persona-tool-bubble pre {
|
|
4372
|
-
background-color: var(--cw-surface, #ffffff);
|
|
4373
|
-
border-color: var(--cw-border, #f1f5f9);
|
|
4418
|
+
background-color: var(--persona-cw-surface, var(--cw-surface, #ffffff));
|
|
4419
|
+
border-color: var(--persona-cw-border, var(--cw-border, #f1f5f9));
|
|
4374
4420
|
}
|
|
4375
4421
|
|
|
4376
4422
|
/* Collapsible header hover (tool + reasoning) */
|
|
4377
|
-
.persona-tool-bubble button[data-expand-header],
|
|
4378
|
-
.persona-reasoning-bubble button[data-expand-header] {
|
|
4423
|
+
.persona-tool-bubble button[data-expand-header]:not(.persona-activity-header),
|
|
4424
|
+
.persona-reasoning-bubble button[data-expand-header]:not(.persona-activity-header) {
|
|
4379
4425
|
transition: background-color 0.15s ease;
|
|
4380
4426
|
}
|
|
4381
|
-
.persona-tool-bubble button[data-expand-header]:hover,
|
|
4382
|
-
.persona-reasoning-bubble button[data-expand-header]:hover {
|
|
4383
|
-
background-color: var(--cw-container, #f8fafc);
|
|
4427
|
+
.persona-tool-bubble button[data-expand-header]:not(.persona-activity-header):hover,
|
|
4428
|
+
.persona-reasoning-bubble button[data-expand-header]:not(.persona-activity-header):hover {
|
|
4429
|
+
background-color: var(--persona-cw-container, var(--cw-container, #f8fafc));
|
|
4384
4430
|
}
|
|
4385
4431
|
|
|
4386
4432
|
/* Collapsed live preview blocks: match expanded content's 1px border-top with transparent border */
|
|
@@ -4395,7 +4441,7 @@
|
|
|
4395
4441
|
--_dot-size: 6px;
|
|
4396
4442
|
--_branch-len: 0.75rem;
|
|
4397
4443
|
--_branch-y: 1.5rem;
|
|
4398
|
-
--_rail-color: var(--cw-border, #d1d5db);
|
|
4444
|
+
--_rail-color: var(--persona-cw-border, var(--cw-border, #d1d5db));
|
|
4399
4445
|
gap: 0;
|
|
4400
4446
|
}
|
|
4401
4447
|
|
|
@@ -4431,7 +4477,7 @@
|
|
|
4431
4477
|
height: var(--_dot-size);
|
|
4432
4478
|
border-radius: 999px;
|
|
4433
4479
|
border: var(--_rail-w) solid var(--_rail-color);
|
|
4434
|
-
background: var(--cw-surface, #fff);
|
|
4480
|
+
background: var(--persona-cw-surface, var(--cw-surface, #fff));
|
|
4435
4481
|
transform: translate(-50%, -50%);
|
|
4436
4482
|
}
|
|
4437
4483
|
|
|
@@ -4502,7 +4548,7 @@
|
|
|
4502
4548
|
height: var(--_dot-size);
|
|
4503
4549
|
border-radius: 999px;
|
|
4504
4550
|
border: var(--_rail-w) solid var(--_rail-color);
|
|
4505
|
-
background: var(--cw-surface, #fff);
|
|
4551
|
+
background: var(--persona-cw-surface, var(--cw-surface, #fff));
|
|
4506
4552
|
transform: translate(-50%, -50%);
|
|
4507
4553
|
z-index: 1;
|
|
4508
4554
|
}
|
|
@@ -4513,8 +4559,8 @@
|
|
|
4513
4559
|
|
|
4514
4560
|
/* Approval bubble defaults (overridden by inline styles when config exists) */
|
|
4515
4561
|
.persona-approval-bubble {
|
|
4516
|
-
background-color: var(--cw-surface, #ffffff);
|
|
4517
|
-
border-color: var(--cw-border, #e5e7eb);
|
|
4562
|
+
background-color: var(--persona-cw-surface, var(--cw-surface, #ffffff));
|
|
4563
|
+
border-color: var(--persona-cw-border, var(--cw-border, #e5e7eb));
|
|
4518
4564
|
}
|
|
4519
4565
|
|
|
4520
4566
|
/* Approval button hover/active states */
|
|
@@ -6798,7 +6844,9 @@
|
|
|
6798
6844
|
border-radius: 9999px;
|
|
6799
6845
|
box-shadow: 0 2px 8px rgba(15, 23, 42, 0.06);
|
|
6800
6846
|
color: var(--persona-primary, #111827);
|
|
6801
|
-
font: inherit;
|
|
6847
|
+
font-family: inherit;
|
|
6848
|
+
font-weight: 400;
|
|
6849
|
+
font-style: normal;
|
|
6802
6850
|
font-size: 13px;
|
|
6803
6851
|
line-height: 1.4;
|
|
6804
6852
|
cursor: pointer;
|
|
@@ -7181,3 +7229,227 @@
|
|
|
7181
7229
|
opacity: 0.6;
|
|
7182
7230
|
}
|
|
7183
7231
|
}
|
|
7232
|
+
|
|
7233
|
+
/* Both the critical and full launchers use these variant and placement rules. */
|
|
7234
|
+
[data-persona-launcher-variant="circle"] {
|
|
7235
|
+
width: var(--persona-components-launcher-size, 48px);
|
|
7236
|
+
height: var(--persona-components-launcher-size, 48px);
|
|
7237
|
+
padding: 0;
|
|
7238
|
+
gap: 0;
|
|
7239
|
+
justify-content: center;
|
|
7240
|
+
color: var(--persona-launcher-fg, var(--persona-text-inverse));
|
|
7241
|
+
}
|
|
7242
|
+
[data-persona-launcher-variant="circle"] [data-role="launcher-icon"] {
|
|
7243
|
+
color: inherit;
|
|
7244
|
+
}
|
|
7245
|
+
[data-persona-launcher-variant="circle"] [data-role="launcher-icon"].persona-bg-persona-primary {
|
|
7246
|
+
background: transparent;
|
|
7247
|
+
}
|
|
7248
|
+
[data-persona-launcher-variant="circle"] [data-role="launcher-icon"] svg {
|
|
7249
|
+
width: var(--persona-components-launcher-iconSize, 24px);
|
|
7250
|
+
height: var(--persona-components-launcher-iconSize, 24px);
|
|
7251
|
+
stroke: currentColor;
|
|
7252
|
+
}
|
|
7253
|
+
.persona-launcher-surface[data-teaser].persona-bottom-6,
|
|
7254
|
+
.persona-launcher-surface > button.persona-bottom-6 {
|
|
7255
|
+
bottom: var(--persona-components-launcher-offset, 1.5rem);
|
|
7256
|
+
}
|
|
7257
|
+
.persona-launcher-surface[data-teaser].persona-top-6,
|
|
7258
|
+
.persona-launcher-surface > button.persona-top-6 {
|
|
7259
|
+
top: var(--persona-components-launcher-offset, 1.5rem);
|
|
7260
|
+
}
|
|
7261
|
+
.persona-launcher-surface[data-teaser].persona-right-6,
|
|
7262
|
+
.persona-launcher-surface > button.persona-right-6 {
|
|
7263
|
+
right: var(--persona-components-launcher-offset, 1.5rem);
|
|
7264
|
+
}
|
|
7265
|
+
.persona-launcher-surface[data-teaser].persona-left-6,
|
|
7266
|
+
.persona-launcher-surface > button.persona-left-6 {
|
|
7267
|
+
left: var(--persona-components-launcher-offset, 1.5rem);
|
|
7268
|
+
}
|
|
7269
|
+
|
|
7270
|
+
/* Center the complete empty greeting group without trapping overflow above
|
|
7271
|
+
the scroll origin. Auto margins collapse naturally when content is tall. */
|
|
7272
|
+
[data-persona-root][data-persona-welcome-layout="centered"][data-persona-conversation-state="empty"]
|
|
7273
|
+
.persona-welcome:not([data-persona-welcome-overlay]) {
|
|
7274
|
+
margin-block: auto;
|
|
7275
|
+
flex-shrink: 0;
|
|
7276
|
+
}
|
|
7277
|
+
[data-persona-root][data-persona-welcome-layout="centered"][data-persona-welcome-anchor="center"][data-persona-conversation-state="empty"]
|
|
7278
|
+
.persona-welcome:not([data-persona-welcome-overlay]) {
|
|
7279
|
+
margin-block: auto 0;
|
|
7280
|
+
}
|
|
7281
|
+
[data-persona-root][data-persona-welcome-layout="centered"]
|
|
7282
|
+
.persona-welcome[data-persona-welcome-overlay] {
|
|
7283
|
+
display: flex;
|
|
7284
|
+
flex-direction: column;
|
|
7285
|
+
justify-content: safe center;
|
|
7286
|
+
}
|
|
7287
|
+
[data-persona-root][data-persona-welcome-layout="centered"][data-persona-welcome-anchor="center"]
|
|
7288
|
+
.persona-welcome[data-persona-welcome-overlay] {
|
|
7289
|
+
justify-content: safe flex-end;
|
|
7290
|
+
}
|
|
7291
|
+
[data-persona-root][data-persona-welcome-layout="centered"][data-persona-welcome-fullscreen="true"]
|
|
7292
|
+
.persona-suggestions[data-variant="card"][data-persona-suggestion-surface="starter"] {
|
|
7293
|
+
grid-template-columns: repeat(2, minmax(0, 1fr));
|
|
7294
|
+
}
|
|
7295
|
+
|
|
7296
|
+
/* An explicit top layout overrides the legacy hero's auto margins. Unspecified
|
|
7297
|
+
V4 heroes retain their original centering in empty and active transcripts. */
|
|
7298
|
+
[data-persona-root][data-persona-welcome-layout-explicit="top"]
|
|
7299
|
+
.persona-welcome:not([data-persona-welcome-overlay]) {
|
|
7300
|
+
margin-block: 0;
|
|
7301
|
+
}
|
|
7302
|
+
[data-persona-root][data-persona-welcome-layout-explicit="top"]
|
|
7303
|
+
.persona-welcome[data-persona-welcome-overlay] {
|
|
7304
|
+
justify-content: flex-start;
|
|
7305
|
+
}
|
|
7306
|
+
|
|
7307
|
+
/* Activity rows share geometry but retain the legacy kind-specific token aliases. */
|
|
7308
|
+
.persona-activity-row {
|
|
7309
|
+
width: 100%; color: var(--persona-muted); background: transparent;
|
|
7310
|
+
--persona-activity-height: var(--persona-components-activity-rowHeight, 32px);
|
|
7311
|
+
--persona-activity-label-size: var(--persona-components-activity-labelSize, 13px);
|
|
7312
|
+
--persona-activity-icon-size: var(--persona-components-activity-iconSize, 16px);
|
|
7313
|
+
--persona-activity-indent: var(--persona-components-activity-indent, 24px);
|
|
7314
|
+
--persona-activity-body-bg: var(--persona-components-activity-bodySurface, transparent);
|
|
7315
|
+
}
|
|
7316
|
+
.persona-tool-bubble.persona-activity-row {
|
|
7317
|
+
--persona-activity-height: var(--persona-components-toolBubble-rowHeight, var(--persona-components-activity-rowHeight, 32px));
|
|
7318
|
+
--persona-activity-label-size: var(--persona-components-toolBubble-labelSize, var(--persona-components-activity-labelSize, 13px));
|
|
7319
|
+
--persona-activity-icon-size: var(--persona-components-toolBubble-iconSize, var(--persona-components-activity-iconSize, 16px));
|
|
7320
|
+
--persona-activity-indent: var(--persona-components-toolBubble-indent, var(--persona-components-activity-indent, 24px));
|
|
7321
|
+
--persona-activity-body-bg: var(--persona-components-toolBubble-bodySurface, var(--persona-components-activity-bodySurface, transparent));
|
|
7322
|
+
}
|
|
7323
|
+
.persona-reasoning-bubble.persona-activity-row {
|
|
7324
|
+
box-shadow: var(--persona-reasoning-bubble-shadow, none);
|
|
7325
|
+
--persona-activity-height: var(--persona-components-reasoningBubble-rowHeight, var(--persona-components-activity-rowHeight, 32px));
|
|
7326
|
+
--persona-activity-label-size: var(--persona-components-reasoningBubble-labelSize, var(--persona-components-activity-labelSize, 13px));
|
|
7327
|
+
--persona-activity-icon-size: var(--persona-components-reasoningBubble-iconSize, var(--persona-components-activity-iconSize, 16px));
|
|
7328
|
+
--persona-activity-indent: var(--persona-components-reasoningBubble-indent, var(--persona-components-activity-indent, 24px));
|
|
7329
|
+
--persona-activity-body-bg: var(--persona-components-reasoningBubble-bodySurface, var(--persona-components-activity-bodySurface, transparent));
|
|
7330
|
+
}
|
|
7331
|
+
.persona-activity-header { display:flex; align-items:center; gap:8px; min-height:var(--persona-activity-height); padding:4px 0; background:transparent; border:0; color:inherit; font:inherit; text-align:left; max-width:100%; cursor:pointer; }
|
|
7332
|
+
/* Activity rows use foreground feedback; card hover surfaces stay on cards. */
|
|
7333
|
+
.persona-activity-header[data-expand-header] { transition:color 0.15s ease; }
|
|
7334
|
+
.persona-activity-header[data-expand-header]:hover,
|
|
7335
|
+
.persona-activity-header[data-expand-header]:focus-visible { color:var(--persona-text); }
|
|
7336
|
+
.persona-activity-header:focus-visible { outline:2px solid var(--persona-primary); outline-offset:3px; border-radius:4px; }
|
|
7337
|
+
.persona-activity-header:not([data-expand-header]) { cursor:default; }
|
|
7338
|
+
.persona-activity-label { min-width:0; }
|
|
7339
|
+
.persona-activity-label, .persona-activity-label > span { font-size:var(--persona-activity-label-size); color:inherit; }
|
|
7340
|
+
.persona-activity-icon { display:inline-flex; flex:none; width:var(--persona-activity-icon-size); height:var(--persona-activity-icon-size); }
|
|
7341
|
+
.persona-activity-icon svg { width:100%; height:100%; }
|
|
7342
|
+
.persona-activity-chevron { margin-left:0; flex:none; }
|
|
7343
|
+
.persona-activity-duration { font-size:12px; white-space:nowrap; }
|
|
7344
|
+
.persona-activity-row > .persona-activity-body { margin-left:var(--persona-activity-indent); padding:var(--persona-components-activity-bodyPadding, 8px 0); border:0; background:var(--persona-activity-body-bg); }
|
|
7345
|
+
.persona-activity-row[data-persona-tool-group] > .persona-activity-body {
|
|
7346
|
+
margin-left:var(--persona-components-activity-groupIndent, var(--persona-activity-indent));
|
|
7347
|
+
padding:var(--persona-components-activity-groupPadding, var(--persona-components-activity-bodyPadding, 8px 0));
|
|
7348
|
+
}
|
|
7349
|
+
.persona-activity-row > .persona-activity-body.persona-space-y-3 > :not([hidden]) ~ :not([hidden]) {
|
|
7350
|
+
margin-top:var(--persona-components-activity-sectionGap, 12px);
|
|
7351
|
+
}
|
|
7352
|
+
.persona-activity-row > [data-persona-tool-group-stack] > .persona-activity-group-child + .persona-activity-group-child {
|
|
7353
|
+
margin-top:var(--persona-components-activity-groupGap, 0px);
|
|
7354
|
+
}
|
|
7355
|
+
.persona-activity-row[data-activity-state="done"] > .persona-activity-header > .persona-activity-icon { color:var(--persona-success, #16a34a); }
|
|
7356
|
+
.persona-activity-row[data-activity-state="error"] > .persona-activity-header > .persona-activity-icon { color:var(--persona-danger, #dc2626); }
|
|
7357
|
+
.persona-activity-row[data-activity-state="denied"] > .persona-activity-header > .persona-activity-icon { color:var(--persona-warning-strong, #b45309); }
|
|
7358
|
+
.persona-activity-row[data-activity-state="awaiting-approval"] > .persona-activity-header > .persona-activity-icon { color:var(--persona-warning, #d97706); }
|
|
7359
|
+
.persona-activity-row[data-activity-state="running"] > .persona-activity-header > .persona-activity-icon { animation:persona-activity-spin 1s linear infinite; }
|
|
7360
|
+
@keyframes persona-activity-spin { to { transform:rotate(360deg); } }
|
|
7361
|
+
@keyframes persona-activity-enter { from { opacity:0; transform:translateY(3px); } to { opacity:1; transform:none; } }
|
|
7362
|
+
.persona-activity-group-child { animation:persona-activity-enter 160ms ease both; animation-delay:var(--persona-activity-stagger, 0ms); }
|
|
7363
|
+
@media (prefers-reduced-motion: reduce) {
|
|
7364
|
+
.persona-activity-row[data-activity-state="running"] > .persona-activity-header > .persona-activity-icon, .persona-activity-group-child { animation:none; }
|
|
7365
|
+
}
|
|
7366
|
+
.persona-activity-row[data-activity-group-shimmer][data-activity-state="running"] > .persona-activity-header > .persona-activity-label {
|
|
7367
|
+
background:linear-gradient(100deg, var(--persona-muted) 25%, var(--persona-text) 50%, var(--persona-muted) 75%);
|
|
7368
|
+
background-size:200% 100%; background-clip:text; -webkit-background-clip:text; color:transparent;
|
|
7369
|
+
animation:persona-activity-shimmer 2s linear infinite;
|
|
7370
|
+
}
|
|
7371
|
+
@keyframes persona-activity-shimmer { to { background-position:-200% 0; } }
|
|
7372
|
+
@media (prefers-reduced-motion: reduce) {
|
|
7373
|
+
.persona-activity-row[data-activity-group-shimmer] > .persona-activity-header > .persona-activity-label { animation:none; background:none; color:var(--persona-muted); }
|
|
7374
|
+
}
|
|
7375
|
+
|
|
7376
|
+
/* Keep the top edge soft only while earlier transcript content is out of view. */
|
|
7377
|
+
.persona-widget-container:has(> .persona-widget-body[data-persona-top-fade="true"]) {
|
|
7378
|
+
background-color: var(--persona-container);
|
|
7379
|
+
}
|
|
7380
|
+
.persona-widget-body[data-persona-top-fade="true"] {
|
|
7381
|
+
-webkit-mask-image: linear-gradient(to bottom, transparent, #000 var(--persona-components-message-topFadeHeight, 18px));
|
|
7382
|
+
mask-image: linear-gradient(to bottom, transparent, #000 var(--persona-components-message-topFadeHeight, 18px));
|
|
7383
|
+
}
|
|
7384
|
+
|
|
7385
|
+
/* Adjust only adjacent transcript activity, preserving normal message gaps. */
|
|
7386
|
+
.persona-widget-messages > [data-message-role]:has(.persona-activity-row) + [data-message-role]:has(.persona-activity-row) {
|
|
7387
|
+
margin-top:calc(var(--persona-components-activity-transcriptGap, var(--persona-transcript-gap)) - var(--persona-transcript-gap));
|
|
7388
|
+
}
|
|
7389
|
+
.persona-widget-messages > [data-message-role]:has(.persona-activity-row) + [data-message-role="assistant"]:not(:has(.persona-activity-row)) {
|
|
7390
|
+
margin-top:calc(var(--persona-components-activity-responseGap, var(--persona-transcript-gap)) - var(--persona-transcript-gap));
|
|
7391
|
+
}
|
|
7392
|
+
|
|
7393
|
+
.persona-reasoning-bubble.persona-activity-row > .persona-activity-body > .persona-whitespace-pre-wrap {
|
|
7394
|
+
font-size:var(--persona-components-activity-bodySize, 12px);
|
|
7395
|
+
line-height:var(--persona-components-activity-bodyLineHeight, inherit);
|
|
7396
|
+
font-weight:var(--persona-components-activity-bodyFontWeight, inherit);
|
|
7397
|
+
}
|
|
7398
|
+
|
|
7399
|
+
/* V5 tool details: a single request/response surface, plain text or structured data. */
|
|
7400
|
+
.persona-tool-detail {
|
|
7401
|
+
position: relative;
|
|
7402
|
+
padding: 10px 12px;
|
|
7403
|
+
border: 0 solid transparent;
|
|
7404
|
+
border-radius: 8px;
|
|
7405
|
+
background: color-mix(in srgb, var(--persona-muted) 5%, transparent);
|
|
7406
|
+
}
|
|
7407
|
+
.persona-tool-detail-label {
|
|
7408
|
+
font-size: 11px;
|
|
7409
|
+
line-height: 1.5;
|
|
7410
|
+
font-weight: 400;
|
|
7411
|
+
color: var(--persona-muted);
|
|
7412
|
+
padding-right: 32px;
|
|
7413
|
+
margin-bottom: 5px;
|
|
7414
|
+
}
|
|
7415
|
+
.persona-tool-detail .persona-tool-detail-value {
|
|
7416
|
+
margin: 0;
|
|
7417
|
+
padding: 0;
|
|
7418
|
+
border: 0;
|
|
7419
|
+
background: transparent;
|
|
7420
|
+
color: var(--persona-text);
|
|
7421
|
+
font-family: inherit;
|
|
7422
|
+
font-weight: 400;
|
|
7423
|
+
font-style: normal;
|
|
7424
|
+
font-size: 13px;
|
|
7425
|
+
line-height: 1.6;
|
|
7426
|
+
white-space: pre-wrap;
|
|
7427
|
+
overflow-wrap: anywhere;
|
|
7428
|
+
max-height: 240px;
|
|
7429
|
+
overflow: auto;
|
|
7430
|
+
}
|
|
7431
|
+
.persona-tool-detail .persona-tool-detail-code { font-family: var(--persona-font-mono, monospace); font-size: 12px; }
|
|
7432
|
+
.persona-tool-detail-copy {
|
|
7433
|
+
position: absolute;
|
|
7434
|
+
top: 8px;
|
|
7435
|
+
right: 8px;
|
|
7436
|
+
display: inline-flex;
|
|
7437
|
+
align-items: center;
|
|
7438
|
+
justify-content: center;
|
|
7439
|
+
width: 28px;
|
|
7440
|
+
height: 28px;
|
|
7441
|
+
padding: 0;
|
|
7442
|
+
border: 0;
|
|
7443
|
+
border-radius: 4px;
|
|
7444
|
+
background: transparent;
|
|
7445
|
+
color: var(--persona-muted);
|
|
7446
|
+
opacity: 0;
|
|
7447
|
+
cursor: pointer;
|
|
7448
|
+
}
|
|
7449
|
+
.persona-tool-detail:hover .persona-tool-detail-copy,
|
|
7450
|
+
.persona-tool-detail:focus-within .persona-tool-detail-copy,
|
|
7451
|
+
.persona-tool-detail-copy[data-copied="true"] { opacity: 1; }
|
|
7452
|
+
.persona-tool-detail-copy:hover { color: var(--persona-text); background: color-mix(in srgb, var(--persona-muted) 12%, transparent); }
|
|
7453
|
+
.persona-tool-detail-copy:focus-visible { outline: 2px solid var(--persona-primary); outline-offset: 2px; }
|
|
7454
|
+
@media (hover: none) { .persona-tool-detail-copy { opacity: 1; } }
|
|
7455
|
+
@media (pointer: coarse) { .persona-tool-detail-copy { width: 40px; height: 40px; top: 2px; right: 2px; } }
|
|
@@ -16,6 +16,14 @@ describe("theme editor preview demo data", () => {
|
|
|
16
16
|
expect(config.suggestionChips?.length).toBeGreaterThan(0);
|
|
17
17
|
});
|
|
18
18
|
|
|
19
|
+
it("keeps an authored v5 defaults opt-in in the preview config", () => {
|
|
20
|
+
const config = buildPreviewConfig({
|
|
21
|
+
config: { future: { v5Defaults: true } },
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
expect(config.future).toEqual({ v5Defaults: true });
|
|
25
|
+
});
|
|
26
|
+
|
|
19
27
|
it("seeds rich agent suggestions in the follow-ups scene", () => {
|
|
20
28
|
const config = buildPreviewConfig({ scene: "follow-ups" });
|
|
21
29
|
const messages = config.initialMessages ?? [];
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
import type { AgentWidgetConfig } from '../types';
|
|
8
8
|
import type { AgentWidgetMessage } from '../types';
|
|
9
9
|
import { createTheme } from '../utils/theme';
|
|
10
|
-
import {
|
|
10
|
+
import { resolveDefaults } from '../defaults';
|
|
11
11
|
|
|
12
12
|
// ─── Constants ──────────────────────────────────────────────────
|
|
13
13
|
|
|
@@ -693,9 +693,13 @@ function buildPreviewBaseConfig(
|
|
|
693
693
|
options: PreviewConfigOptions,
|
|
694
694
|
shellModeOverride?: 'light' | 'dark'
|
|
695
695
|
): AgentWidgetConfig {
|
|
696
|
-
const
|
|
696
|
+
const defaults = resolveDefaults(options.config);
|
|
697
|
+
const future = options.config?.future;
|
|
698
|
+
const theme = options.theme
|
|
699
|
+
? createTheme(options.theme, { validate: false, future })
|
|
700
|
+
: createTheme(undefined, { future });
|
|
697
701
|
return {
|
|
698
|
-
...
|
|
702
|
+
...defaults,
|
|
699
703
|
...options.config,
|
|
700
704
|
theme,
|
|
701
705
|
darkTheme: options.darkTheme,
|
|
@@ -5,12 +5,43 @@ import {
|
|
|
5
5
|
COMPONENT_SHAPE_SECTIONS,
|
|
6
6
|
COMPONENTS_SECTIONS,
|
|
7
7
|
CONFIGURE_SECTIONS,
|
|
8
|
+
getThemeEditorTabs,
|
|
8
9
|
INTERFACE_ROLES_SECTION,
|
|
10
|
+
resolveEditorFieldDefault,
|
|
9
11
|
STYLE_SECTIONS,
|
|
10
12
|
} from "./sections";
|
|
13
|
+
import { resolveDefaults } from "../defaults";
|
|
14
|
+
import { resolveThemeDefaults } from "../utils/tokens";
|
|
11
15
|
import { ALL_ROLES } from "./role-mappings";
|
|
12
16
|
|
|
13
17
|
describe("theme editor scroll-to-bottom controls", () => {
|
|
18
|
+
it("resolves field hints from the selected shared defaults tree", () => {
|
|
19
|
+
const v4Tabs = getThemeEditorTabs();
|
|
20
|
+
const v5Tabs = getThemeEditorTabs({ v5Defaults: true });
|
|
21
|
+
const headerIcon = v4Tabs
|
|
22
|
+
.flatMap((tab) => tab.sections)
|
|
23
|
+
.flatMap((section) => section.fields)
|
|
24
|
+
.find((field) => field.path === "launcher.headerIconSize");
|
|
25
|
+
|
|
26
|
+
expect(headerIcon?.defaultValue).toBe(
|
|
27
|
+
resolveDefaults().launcher?.headerIconSize
|
|
28
|
+
);
|
|
29
|
+
expect(resolveEditorFieldDefault({
|
|
30
|
+
id: "theme-surface",
|
|
31
|
+
label: "Surface",
|
|
32
|
+
type: "token-ref",
|
|
33
|
+
path: "theme.semantic.colors.surface",
|
|
34
|
+
}, { v5Defaults: true })).toBe(
|
|
35
|
+
resolveThemeDefaults({ v5Defaults: true }).semantic.colors.surface
|
|
36
|
+
);
|
|
37
|
+
const v5HeaderIcon = v5Tabs.flatMap((tab) => tab.sections)
|
|
38
|
+
.flatMap((section) => section.fields)
|
|
39
|
+
.find((field) => field.path === "launcher.headerIconSize");
|
|
40
|
+
expect(v5HeaderIcon?.defaultValue).toBe("20px");
|
|
41
|
+
expect(headerIcon?.defaultValue).toBe("40px");
|
|
42
|
+
expect(v5Tabs.map((tab) => tab.id)).toEqual(v4Tabs.map((tab) => tab.id));
|
|
43
|
+
});
|
|
44
|
+
|
|
14
45
|
it("exposes clear style semantics and independent role width controls", () => {
|
|
15
46
|
const section = CONFIGURE_SECTIONS.find((entry) => entry.id === "messages-layout");
|
|
16
47
|
const fieldsByPath = new Map(
|
|
@@ -5,11 +5,14 @@ import {
|
|
|
5
5
|
DEFAULT_FLOATING_LAUNCHER_MAX_WIDTH,
|
|
6
6
|
DEFAULT_FLOATING_LAUNCHER_WIDTH,
|
|
7
7
|
DEFAULT_INPUT_PLACEHOLDER,
|
|
8
|
+
resolveDefaults,
|
|
8
9
|
} from '../defaults';
|
|
9
10
|
import {
|
|
10
11
|
DEFAULT_PANEL_CANVAS_BACKGROUND,
|
|
11
12
|
DEFAULT_PANEL_INSET,
|
|
13
|
+
resolveThemeDefaults,
|
|
12
14
|
} from '../utils/tokens';
|
|
15
|
+
import type { AgentWidgetConfig } from '../types';
|
|
13
16
|
import { COLOR_FAMILIES } from './color-utils';
|
|
14
17
|
import {
|
|
15
18
|
ROLE_SURFACES,
|
|
@@ -1336,12 +1339,63 @@ export const STYLE_SECTIONS_V2: SectionDef[] = [
|
|
|
1336
1339
|
// ALL TABS
|
|
1337
1340
|
// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
1338
1341
|
|
|
1339
|
-
|
|
1342
|
+
const ALL_TABS_BASE: TabDef[] = [
|
|
1340
1343
|
{ id: 'style', label: 'Style', sections: STYLE_SECTIONS },
|
|
1341
1344
|
{ id: 'design-system', label: 'Design System', sections: COMPONENTS_SECTIONS },
|
|
1342
1345
|
{ id: 'configure', label: 'Configure', sections: CONFIGURE_SECTIONS },
|
|
1343
1346
|
];
|
|
1344
1347
|
|
|
1348
|
+
const getByPath = (value: unknown, path: string): unknown =>
|
|
1349
|
+
path.split('.').reduce<unknown>((current, key) =>
|
|
1350
|
+
current && typeof current === 'object'
|
|
1351
|
+
? (current as Record<string, unknown>)[key]
|
|
1352
|
+
: undefined, value);
|
|
1353
|
+
|
|
1354
|
+
/**
|
|
1355
|
+
* Resolves editor field metadata from the same versioned config and token
|
|
1356
|
+
* defaults as the widget. The static field value remains the fallback for
|
|
1357
|
+
* presentation-only values (such as intentionally blank optional tokens).
|
|
1358
|
+
*/
|
|
1359
|
+
export function resolveEditorFieldDefault(
|
|
1360
|
+
field: FieldDef,
|
|
1361
|
+
future?: AgentWidgetConfig['future']
|
|
1362
|
+
): unknown {
|
|
1363
|
+
const configDefaults = resolveDefaults({ future });
|
|
1364
|
+
const themeDefaults = resolveThemeDefaults(future);
|
|
1365
|
+
const path = field.path;
|
|
1366
|
+
const themePath = path.startsWith('theme.')
|
|
1367
|
+
? path.slice('theme.'.length)
|
|
1368
|
+
: path.startsWith('darkTheme.')
|
|
1369
|
+
? path.slice('darkTheme.'.length)
|
|
1370
|
+
: undefined;
|
|
1371
|
+
const resolved = themePath
|
|
1372
|
+
? getByPath(themeDefaults, themePath)
|
|
1373
|
+
: getByPath(configDefaults, path);
|
|
1374
|
+
return resolved === undefined ? field.defaultValue : resolved;
|
|
1375
|
+
}
|
|
1376
|
+
|
|
1377
|
+
/**
|
|
1378
|
+
* Returns editor tabs with default metadata resolved for the selected defaults
|
|
1379
|
+
* version. Callers keep authored values separate; this only drives UI hints.
|
|
1380
|
+
*/
|
|
1381
|
+
export function getThemeEditorTabs(
|
|
1382
|
+
future?: AgentWidgetConfig['future']
|
|
1383
|
+
): TabDef[] {
|
|
1384
|
+
return ALL_TABS_BASE.map((tab) => ({
|
|
1385
|
+
...tab,
|
|
1386
|
+
sections: tab.sections.map((section) => ({
|
|
1387
|
+
...section,
|
|
1388
|
+
fields: section.fields.map((field) => ({
|
|
1389
|
+
...field,
|
|
1390
|
+
defaultValue: resolveEditorFieldDefault(field, future),
|
|
1391
|
+
})),
|
|
1392
|
+
})),
|
|
1393
|
+
}));
|
|
1394
|
+
}
|
|
1395
|
+
|
|
1396
|
+
/** Legacy editor metadata, resolved through the v4 defaults tree. */
|
|
1397
|
+
export const ALL_TABS: TabDef[] = getThemeEditorTabs();
|
|
1398
|
+
|
|
1345
1399
|
// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
1346
1400
|
// HELPERS: light/dark scoping for dual-mode editing
|
|
1347
1401
|
// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
@@ -12,4 +12,53 @@ describe("ThemeEditorState preference reset", () => {
|
|
|
12
12
|
expect(state.get("features.artifacts.display.files")).toBeUndefined();
|
|
13
13
|
expect(state.getConfig()).not.toHaveProperty("features");
|
|
14
14
|
});
|
|
15
|
+
|
|
16
|
+
it("preserves an authored v5 defaults opt-in across state reset", () => {
|
|
17
|
+
const state = new ThemeEditorState(
|
|
18
|
+
undefined,
|
|
19
|
+
{ future: { v5Defaults: true } },
|
|
20
|
+
);
|
|
21
|
+
|
|
22
|
+
expect(state.getConfig().future?.v5Defaults).toBe(true);
|
|
23
|
+
expect(state.exportSnapshot().config.future).toEqual({ v5Defaults: true });
|
|
24
|
+
|
|
25
|
+
state.resetToDefaults();
|
|
26
|
+
|
|
27
|
+
expect(state.getConfig().future?.v5Defaults).toBe(true);
|
|
28
|
+
});
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
describe('version switching preserves authored values', () => {
|
|
32
|
+
it('rebases config and theme in both directions, including undo/redo', () => {
|
|
33
|
+
const state = new ThemeEditorState();
|
|
34
|
+
state.set('theme.components.header.controlSize', '32px');
|
|
35
|
+
state.set('features.toolCallDisplay.autoExpand', true);
|
|
36
|
+
state.set('future.v5Defaults', true);
|
|
37
|
+
expect(state.get('features.toolCallDisplay.variant')).toBe('row');
|
|
38
|
+
expect(state.get('features.toolCallDisplay.autoExpand')).toBe(true);
|
|
39
|
+
expect(state.get('theme.components.header.controlSize')).toBe('32px');
|
|
40
|
+
expect(state.get('theme.components.header.controlIconSize')).toBe('18px');
|
|
41
|
+
state.undo();
|
|
42
|
+
state.redo();
|
|
43
|
+
state.unset('future.v5Defaults');
|
|
44
|
+
expect(state.get('features.toolCallDisplay.variant')).toBeUndefined();
|
|
45
|
+
expect(state.get('theme.components.header.controlIconSize')).toBeUndefined();
|
|
46
|
+
state.set('future.v5Defaults', true);
|
|
47
|
+
expect(state.get('theme.components.header.controlSize')).toBe('32px');
|
|
48
|
+
});
|
|
49
|
+
it('preserves constructor overrides and same-batch edits regardless of order', () => {
|
|
50
|
+
const state = new ThemeEditorState({ components: { header: { controlSize: '40px' } } }, { features: { toolCallDisplay: { autoExpand: true } } });
|
|
51
|
+
state.setBatch({ 'theme.components.header.controlIconSize': '22px', 'future.v5Defaults': true });
|
|
52
|
+
expect(state.get('features.toolCallDisplay.variant')).toBe('row');
|
|
53
|
+
expect(state.get('theme.components.header.controlSize')).toBe('40px');
|
|
54
|
+
expect(state.get('theme.components.header.controlIconSize')).toBe('22px');
|
|
55
|
+
state.setBatch({ 'future.v5Defaults': false, 'theme.components.header.controlSize': '44px' });
|
|
56
|
+
expect(state.get('theme.components.header.controlSize')).toBe('44px');
|
|
57
|
+
});
|
|
58
|
+
it('keeps sparse configs sparse when defaults merging is disabled', () => {
|
|
59
|
+
const state = new ThemeEditorState(undefined, {}, { mergeDefaults: false });
|
|
60
|
+
state.set('future.v5Defaults', true);
|
|
61
|
+
expect(state.get('features')).toBeUndefined();
|
|
62
|
+
expect(state.get('theme.components.header.controlSize')).toBe('28px');
|
|
63
|
+
});
|
|
15
64
|
});
|