@delmaredigital/payload-experiments 0.2.0-rc.6 → 0.3.0-rc.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +129 -11
- package/dist/admin/PreviewLinks.d.ts +2 -1
- package/dist/admin/PreviewLinks.js +24 -16
- package/dist/admin/actions/ConfirmDialog.d.ts +7 -4
- package/dist/admin/actions/ConfirmDialog.js +37 -82
- package/dist/admin/actions/DecideDialog.d.ts +3 -1
- package/dist/admin/actions/DecideDialog.js +30 -13
- package/dist/admin/actions/MakeContentResult.d.ts +13 -2
- package/dist/admin/actions/MakeContentResult.js +115 -16
- package/dist/admin/actions/actions.model.d.ts +2 -4
- package/dist/admin/actions/actions.model.js +2 -3
- package/dist/admin/allocation.model.js +3 -5
- package/dist/admin/api.d.ts +10 -4
- package/dist/admin/api.js +11 -7
- package/dist/admin/copy/actions.d.ts +39 -3
- package/dist/admin/copy/actions.js +40 -4
- package/dist/admin/copy/armSelect.js +5 -5
- package/dist/admin/copy/arms.d.ts +1 -7
- package/dist/admin/copy/arms.js +1 -7
- package/dist/admin/copy/audience.d.ts +2 -1
- package/dist/admin/copy/audience.js +3 -2
- package/dist/admin/copy/common.d.ts +13 -6
- package/dist/admin/copy/common.js +14 -8
- package/dist/admin/copy/goals.d.ts +21 -6
- package/dist/admin/copy/goals.js +27 -6
- package/dist/admin/copy/readiness.d.ts +19 -0
- package/dist/admin/copy/readiness.js +19 -0
- package/dist/admin/copy/recommendation.d.ts +0 -3
- package/dist/admin/copy/recommendation.js +0 -3
- package/dist/admin/copy/results.d.ts +41 -2
- package/dist/admin/copy/results.js +42 -3
- package/dist/admin/copy/review.d.ts +1 -1
- package/dist/admin/copy/review.js +1 -1
- package/dist/admin/copy/setting.d.ts +2 -0
- package/dist/admin/copy/setting.js +2 -0
- package/dist/admin/copy/surface.d.ts +7 -4
- package/dist/admin/copy/surface.js +9 -4
- package/dist/admin/copy/testPage.d.ts +12 -0
- package/dist/admin/copy/testPage.js +12 -0
- package/dist/admin/format/date.d.ts +2 -0
- package/dist/admin/format/date.js +10 -0
- package/dist/admin/labels.d.ts +2 -7
- package/dist/admin/labels.js +2 -7
- package/dist/admin/previewLinks.model.d.ts +2 -2
- package/dist/admin/previewLinks.model.js +5 -7
- package/dist/admin/results/CiChart.js +11 -21
- package/dist/admin/results/DataQualityPanel.d.ts +4 -2
- package/dist/admin/results/DataQualityPanel.js +30 -17
- package/dist/admin/results/DataTable.d.ts +16 -0
- package/dist/admin/results/DataTable.js +152 -0
- package/dist/admin/results/StatTile.d.ts +7 -0
- package/dist/admin/results/StatTile.js +22 -0
- package/dist/admin/results/VerdictHero.d.ts +13 -0
- package/dist/admin/results/{VerdictCard.js → VerdictHero.js} +15 -12
- package/dist/admin/results/releasePages.model.d.ts +17 -0
- package/dist/admin/results/releasePages.model.js +10 -0
- package/dist/admin/results/results.css +64 -0
- package/dist/admin/results/results.model.d.ts +6 -2
- package/dist/admin/results/results.model.js +12 -5
- package/dist/admin/surface/ResultsRoute.d.ts +1 -1
- package/dist/admin/surface/ResultsRoute.js +60 -31
- package/dist/admin/surface/SurfaceShell.d.ts +11 -2
- package/dist/admin/surface/SurfaceShell.js +49 -14
- package/dist/admin/surface/TestsHome.d.ts +6 -1
- package/dist/admin/surface/TestsHome.js +183 -112
- package/dist/admin/surface/TestsSurface.js +56 -16
- package/dist/admin/surface/contracts.d.ts +1 -0
- package/dist/admin/surface/goals/GoalForm.js +341 -308
- package/dist/admin/surface/goals/GoalsList.js +123 -89
- package/dist/admin/surface/goals/data.d.ts +8 -2
- package/dist/admin/surface/goals/data.js +11 -3
- package/dist/admin/surface/goals/goals.css +10 -13
- package/dist/admin/surface/home.model.d.ts +7 -8
- package/dist/admin/surface/home.model.js +23 -12
- package/dist/admin/surface/newTest/NewTest.js +5 -5
- package/dist/admin/surface/pageBlock/parts.js +31 -26
- package/dist/admin/surface/readiness/ActionDialogs.js +43 -14
- package/dist/admin/surface/readiness/Banner.d.ts +3 -0
- package/dist/admin/surface/readiness/Banner.js +63 -36
- package/dist/admin/surface/readiness/SaveStatus.d.ts +1 -0
- package/dist/admin/surface/readiness/SaveStatus.js +6 -3
- package/dist/admin/surface/readiness/readiness.model.d.ts +2 -0
- package/dist/admin/surface/readiness/readiness.model.js +18 -9
- package/dist/admin/surface/readiness/useTransition.d.ts +1 -0
- package/dist/admin/surface/readiness/useTransition.js +2 -1
- package/dist/admin/surface/results/ReleasePages.d.ts +14 -0
- package/dist/admin/surface/results/ReleasePages.js +116 -0
- package/dist/admin/surface/results/ResultsBody.d.ts +15 -2
- package/dist/admin/surface/results/ResultsBody.js +281 -107
- package/dist/admin/surface/results/ResultsHeader.d.ts +10 -0
- package/dist/admin/surface/results/ResultsHeader.js +177 -0
- package/dist/admin/surface/results/recommendation.model.js +2 -6
- package/dist/admin/surface/results/useResults.d.ts +21 -3
- package/dist/admin/surface/results/useResults.js +2 -1
- package/dist/admin/surface/setting/parts.js +75 -88
- package/dist/admin/surface/setting/setting.css +3 -15
- package/dist/admin/surface/surface.css +62 -47
- package/dist/admin/surface/test/AdvancedSection.js +55 -48
- package/dist/admin/surface/test/GoalSection.js +39 -32
- package/dist/admin/surface/test/LengthSection.js +46 -34
- package/dist/admin/surface/test/Rail.d.ts +4 -0
- package/dist/admin/surface/test/Rail.js +83 -0
- package/dist/admin/surface/test/ReadinessBar.d.ts +5 -0
- package/dist/admin/surface/test/ReadinessBar.js +33 -0
- package/dist/admin/surface/test/Section.d.ts +1 -1
- package/dist/admin/surface/test/Section.js +36 -16
- package/dist/admin/surface/test/TargetingSection.js +168 -142
- package/dist/admin/surface/test/TestPage.d.ts +2 -1
- package/dist/admin/surface/test/TestPage.js +146 -59
- package/dist/admin/surface/test/VersionsSection.js +151 -120
- package/dist/admin/surface/test/fields.d.ts +11 -4
- package/dist/admin/surface/test/fields.js +84 -85
- package/dist/admin/surface/test/jumpToSection.d.ts +3 -0
- package/dist/admin/surface/test/jumpToSection.js +10 -0
- package/dist/admin/surface/test/pageParts.js +9 -3
- package/dist/admin/surface/test/testPage.css +81 -14
- package/dist/admin/surface/useTestDocument.d.ts +1 -0
- package/dist/admin/surface/useTestDocument.js +40 -9
- package/dist/admin/targeting/targeting.model.d.ts +1 -3
- package/dist/admin/targeting/targeting.model.js +3 -8
- package/dist/admin/theme.css +115 -36
- package/dist/admin/theme.d.ts +38 -0
- package/dist/admin/theme.js +38 -1
- package/dist/admin/useApi.d.ts +17 -2
- package/dist/admin/views/ExperimentsRootView.js +12 -2
- package/dist/collections/experiments/config.js +44 -1
- package/dist/collections/experiments/lockHook.js +16 -2
- package/dist/collections/identities.js +6 -1
- package/dist/collections/metrics.js +7 -0
- package/dist/collections/metricsGuards.d.ts +9 -0
- package/dist/collections/metricsGuards.js +33 -0
- package/dist/constants.d.ts +1 -0
- package/dist/constants.js +1 -0
- package/dist/contentDone.d.ts +4 -0
- package/dist/contentDone.js +5 -0
- package/dist/db/identities.d.ts +8 -7
- package/dist/db/identities.js +9 -6
- package/dist/db/metricUsage.d.ts +19 -0
- package/dist/db/metricUsage.js +54 -0
- package/dist/db/names.d.ts +5 -0
- package/dist/db/names.js +5 -0
- package/dist/db/publishedContent.d.ts +10 -0
- package/dist/db/publishedContent.js +43 -0
- package/dist/db/results.d.ts +2 -0
- package/dist/db/results.js +6 -2
- package/dist/db/snapshots.d.ts +18 -6
- package/dist/db/snapshots.js +23 -7
- package/dist/db/staleEdit.d.ts +6 -0
- package/dist/db/staleEdit.js +10 -0
- package/dist/db/sweep.js +11 -6
- package/dist/endpoints/events.js +3 -3
- package/dist/endpoints/index.js +19 -1
- package/dist/endpoints/recompute.js +2 -1
- package/dist/endpoints/results.js +5 -0
- package/dist/endpoints/sanitizeReadinessDetail.d.ts +1 -0
- package/dist/endpoints/sanitizeReadinessDetail.js +2 -0
- package/dist/endpoints/summary.js +20 -2
- package/dist/endpoints/transitions.d.ts +15 -0
- package/dist/endpoints/transitions.js +36 -0
- package/dist/errors.d.ts +8 -0
- package/dist/errors.js +28 -0
- package/dist/exports/adminClient.d.ts +1 -0
- package/dist/exports/adminClient.js +1 -0
- package/dist/exports/index.d.ts +2 -1
- package/dist/exports/index.js +1 -0
- package/dist/exports/puckEditor.d.ts +1 -0
- package/dist/exports/puckEditor.js +1 -0
- package/dist/exports/rsc.d.ts +5 -1
- package/dist/exports/rsc.js +2 -0
- package/dist/hooks/hostHook.js +3 -2
- package/dist/hooks/pageGuard.d.ts +5 -0
- package/dist/hooks/pageGuard.js +121 -0
- package/dist/labels/arms.d.ts +7 -0
- package/dist/labels/arms.js +7 -0
- package/dist/log.d.ts +7 -0
- package/dist/log.js +38 -0
- package/dist/manifest/compile.d.ts +5 -0
- package/dist/manifest/compile.js +5 -1
- package/dist/options.js +23 -0
- package/dist/plugin.js +26 -2
- package/dist/puck/copy.d.ts +1 -1
- package/dist/puck/copy.js +6 -6
- package/dist/puck/editor/editor.chrome.css +235 -0
- package/dist/puck/editor/editor.css +241 -43
- package/dist/results/aggregate.js +4 -3
- package/dist/results/analyse.d.ts +4 -1
- package/dist/results/analyse.js +27 -11
- package/dist/results/cuped.js +3 -2
- package/dist/results/identityCredit.d.ts +15 -7
- package/dist/results/identityCredit.js +32 -33
- package/dist/results/rolloutUnits.js +2 -1
- package/dist/results/snapshot.js +8 -2
- package/dist/results/srm.js +2 -1
- package/dist/results/verdict.d.ts +2 -0
- package/dist/results/verdict.js +18 -1
- package/dist/sanitizeReadinessDetail.d.ts +7 -0
- package/dist/sanitizeReadinessDetail.js +54 -0
- package/dist/server/linkIdentity.d.ts +10 -1
- package/dist/server/linkIdentity.js +20 -18
- package/dist/server/metadata.d.ts +5 -0
- package/dist/server/metadata.js +9 -1
- package/dist/server/recordContentChange.js +2 -1
- package/dist/server/recordExposures.js +3 -3
- package/dist/server/runResults.d.ts +3 -2
- package/dist/server/runResults.js +125 -34
- package/dist/server/trackConversion.js +5 -6
- package/dist/targeting/values.d.ts +4 -0
- package/dist/targeting/values.js +10 -0
- package/dist/transitions/addMetric.js +8 -0
- package/dist/transitions/archive.js +2 -3
- package/dist/transitions/checkStart.d.ts +6 -3
- package/dist/transitions/checkStart.js +15 -0
- package/dist/transitions/contentFields.d.ts +7 -0
- package/dist/transitions/contentFields.js +20 -0
- package/dist/transitions/decide.js +6 -1
- package/dist/transitions/deleteExperiment.js +2 -1
- package/dist/transitions/dismissContentEntry.d.ts +8 -0
- package/dist/transitions/dismissContentEntry.js +45 -0
- package/dist/transitions/makeContent.d.ts +5 -2
- package/dist/transitions/makeContent.js +217 -118
- package/dist/transitions/phaseRecord.d.ts +8 -2
- package/dist/transitions/placements.d.ts +1 -0
- package/dist/transitions/placements.js +4 -0
- package/dist/transitions/preflightData.d.ts +1 -1
- package/dist/transitions/preflightData.js +42 -4
- package/dist/transitions/releasePages.d.ts +8 -0
- package/dist/transitions/releasePages.js +26 -0
- package/dist/transitions/restoreContentEntry.d.ts +8 -0
- package/dist/transitions/restoreContentEntry.js +47 -0
- package/dist/transitions/start.js +30 -5
- package/dist/types/contracts.d.ts +14 -0
- package/dist/types/endpoints.d.ts +34 -3
- package/dist/types/index.d.ts +1 -0
- package/dist/types/index.js +1 -0
- package/dist/types/reasons.d.ts +3 -0
- package/dist/types/reasons.js +1 -0
- package/dist/types/snapshot.d.ts +6 -1
- package/dist/ui/Banner.d.ts +2 -0
- package/dist/ui/Banner.js +2 -0
- package/dist/ui/Breadcrumb.d.ts +7 -0
- package/dist/ui/Breadcrumb.js +25 -0
- package/dist/ui/Button.d.ts +15 -0
- package/dist/ui/Button.js +32 -0
- package/dist/ui/Card.d.ts +12 -0
- package/dist/ui/Card.js +40 -0
- package/dist/ui/Checkbox.d.ts +2 -0
- package/dist/ui/Checkbox.js +2 -0
- package/dist/{admin/components → ui}/ChipsInput.d.ts +4 -3
- package/dist/{admin/components → ui}/ChipsInput.js +20 -12
- package/dist/ui/Dialog.d.ts +13 -0
- package/dist/ui/Dialog.js +85 -0
- package/dist/ui/EmptyState.d.ts +2 -0
- package/dist/ui/EmptyState.js +2 -0
- package/dist/ui/Feedback.d.ts +24 -0
- package/dist/ui/Feedback.js +40 -0
- package/dist/ui/Inputs.d.ts +34 -0
- package/dist/ui/Inputs.js +225 -0
- package/dist/ui/NumberInput.d.ts +2 -0
- package/dist/ui/NumberInput.js +2 -0
- package/dist/ui/Range.d.ts +2 -0
- package/dist/ui/Range.js +2 -0
- package/dist/ui/SearchInput.d.ts +2 -0
- package/dist/ui/SearchInput.js +2 -0
- package/dist/ui/SectionCard.d.ts +2 -0
- package/dist/ui/SectionCard.js +2 -0
- package/dist/ui/Select.d.ts +2 -0
- package/dist/ui/Select.js +2 -0
- package/dist/ui/StatusChip.d.ts +2 -0
- package/dist/ui/StatusChip.js +2 -0
- package/dist/ui/Tabs.d.ts +14 -0
- package/dist/ui/Tabs.js +54 -0
- package/dist/ui/TextInput.d.ts +2 -0
- package/dist/ui/TextInput.js +2 -0
- package/dist/ui/Textarea.d.ts +2 -0
- package/dist/ui/Textarea.js +2 -0
- package/dist/ui/Toggle.d.ts +2 -0
- package/dist/ui/Toggle.js +2 -0
- package/dist/ui/accent.d.ts +21 -0
- package/dist/ui/accent.js +81 -0
- package/dist/ui/index.d.ts +9 -0
- package/dist/ui/index.js +9 -0
- package/dist/ui/ui.css +92 -0
- package/package.json +1 -1
- package/dist/admin/components/chipsInput.css +0 -11
- package/dist/admin/results/ArmTable.d.ts +0 -8
- package/dist/admin/results/ArmTable.js +0 -113
- package/dist/admin/results/VerdictCard.d.ts +0 -9
- package/dist/admin/surface/goals/GoalsBreadcrumb.d.ts +0 -5
- package/dist/admin/surface/goals/GoalsBreadcrumb.js +0 -47
- package/dist/admin/surface/test/TestHeader.d.ts +0 -4
- package/dist/admin/surface/test/TestHeader.js +0 -69
|
@@ -1,23 +1,90 @@
|
|
|
1
1
|
.xp-test-page { color: var(--xp-text); background: var(--xp-bg); max-width: 90rem; margin: 0 auto; padding: 1.5rem; }
|
|
2
|
+
.xp-test-page--setup { min-width: 0; padding: 0 0 160px; }
|
|
2
3
|
.xp-test-header { position: sticky; top: 0; z-index: 10; background: var(--xp-bg); padding: 1rem 0; border-bottom: 1px solid var(--xp-border); }
|
|
3
4
|
.xp-header-meta, .xp-section-actions { display: flex; flex-wrap: wrap; align-items: center; gap: 1rem; margin-block: 1rem; }
|
|
4
|
-
.xp-kind-chip, .xp-status-pill { border: 1px solid var(--xp-border-
|
|
5
|
+
.xp-kind-chip, .xp-status-pill { border: 1px solid var(--xp-border-strong); border-radius: 1rem; padding: .25rem .75rem; }
|
|
5
6
|
.xp-status-pill--success, .xp-content-ready, .xp-section-check--done { color: var(--xp-success-text); }
|
|
6
7
|
.xp-content-empty, .xp-status-pill--warning { color: var(--xp-warning-text); }
|
|
7
|
-
.xp-test-section
|
|
8
|
-
.xp-version-rows { display: grid;
|
|
9
|
-
.xp-version-row {
|
|
10
|
-
.xp-version-
|
|
11
|
-
.xp-
|
|
8
|
+
.xp-test-section, .xp-test-advanced { scroll-margin-top: var(--xp-space-6); }
|
|
9
|
+
.xp-version-rows { display: grid; grid-template-columns: minmax(0, 1.3fr) var(--xp-version-share-width) minmax(var(--xp-version-state-width), 1fr) var(--xp-version-remove-width); gap: var(--xp-space-3); align-items: center; }
|
|
10
|
+
.xp-version-row, .xp-version-grid-head { display: grid; grid-column: 1 / -1; grid-template-columns: subgrid; gap: var(--xp-space-3); align-items: center; }
|
|
11
|
+
.xp-version-grid-head { margin-bottom: var(--xp-space-2); font: var(--xp-text-small); color: var(--xp-text-2); }
|
|
12
|
+
.xp-version-row > .xp-field-error, .xp-version-row > [role=alert] { grid-column: 1 / -1; }
|
|
13
|
+
.xp-version-remove { grid-column: 4; }
|
|
14
|
+
.xp-grid-field .xp-ui-field { margin: 0; }
|
|
15
|
+
.xp-grid-field .xp-ui-field > label { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
|
|
16
|
+
.xp-version-content { display: flex; flex-wrap: nowrap; gap: var(--xp-space-2); align-items: center; min-width: 0; }
|
|
17
|
+
.xp-version-content .xp-ui-button { white-space: nowrap; }
|
|
18
|
+
.xp-content-chip { flex-shrink: 0; display: inline-flex; width: fit-content; border-radius: var(--xp-radius-chip); padding: var(--xp-space-half) var(--xp-space-2); font: var(--xp-text-small); background: var(--xp-surface-2); color: var(--xp-text-2); }
|
|
19
|
+
.xp-content-chip.xp-content-ready { background: var(--xp-success-bg); color: var(--xp-success); }
|
|
20
|
+
.xp-content-chip.xp-content-empty { background: var(--xp-warning-bg); color: var(--xp-warning); }
|
|
21
|
+
.xp-traffic-bar { display: flex; height: var(--xp-space-2); gap: var(--xp-space-half); margin-block: var(--xp-space-5) var(--xp-space-3); overflow: hidden; border-radius: var(--xp-space-1); }
|
|
12
22
|
.xp-traffic-bar > span { display: block; }
|
|
13
|
-
.xp-
|
|
14
|
-
.xp-
|
|
15
|
-
.xp-field
|
|
16
|
-
.xp-field
|
|
23
|
+
.xp-split-legend { display: flex; flex-wrap: wrap; gap: var(--xp-space-4); font: var(--xp-text-small); color: var(--xp-text-2); }
|
|
24
|
+
.xp-split-legend i { display: inline-block; width: var(--xp-legend-key-size); height: var(--xp-legend-key-size); border-radius: var(--xp-legend-key-radius); margin-right: var(--xp-space-one-half); }
|
|
25
|
+
.xp-field-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--xp-space-4); }
|
|
26
|
+
.xp-test-advanced .xp-field-grid { padding-top: var(--xp-space-4); }
|
|
27
|
+
.xp-field-grid > div { min-width: 0; }
|
|
28
|
+
.xp-field-grid p, .xp-page-binding p { color: var(--xp-text-2); font: var(--xp-text-small); }
|
|
29
|
+
.xp-read-only code { font-family: var(--xp-mono); overflow-wrap: anywhere; }
|
|
30
|
+
.xp-ui-checkbox-list { display: flex; flex-wrap: wrap; gap: var(--xp-space-2) var(--xp-space-4); }
|
|
31
|
+
.xp-duration-suggestion { align-items: center; margin-top: var(--xp-space-4); }
|
|
17
32
|
.xp-read-only { padding-block: .5rem; }
|
|
18
33
|
.xp-read-only p { margin-block: .5rem; }
|
|
19
34
|
.xp-field-error { color: var(--xp-error-text); }
|
|
20
|
-
|
|
21
|
-
.xp-
|
|
22
|
-
.xp-
|
|
23
|
-
|
|
35
|
+
|
|
36
|
+
.xp-targeting-row { display: grid; grid-template-columns: var(--xp-targeting-attribute-width) var(--xp-targeting-comparison-width) minmax(0, 1fr); align-items: start; gap: var(--xp-space-3); border: 1px solid var(--xp-border); border-radius: var(--xp-radius-control); padding: var(--xp-space-4); margin-bottom: var(--xp-space-4); }
|
|
37
|
+
.xp-targeting-row > .xp-ui-button-group, .xp-targeting-row > p { grid-column: 1 / -1; }
|
|
38
|
+
@media (max-width: 720px) {
|
|
39
|
+
.xp-version-rows { grid-template-columns: minmax(0, 1fr) var(--xp-version-share-width-mobile); }
|
|
40
|
+
.xp-version-content { flex-wrap: wrap; }
|
|
41
|
+
.xp-version-remove:empty { display: none; }
|
|
42
|
+
.xp-version-content, .xp-setting-values, .xp-version-remove { grid-column: 1 / -1; }
|
|
43
|
+
.xp-version-grid-head > :nth-child(n+3) { display: none; }
|
|
44
|
+
.xp-targeting-row, .xp-field-grid { grid-template-columns: 1fr; }
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
.xp-test-layout { display: grid; grid-template-columns: 220px minmax(0, 1fr); align-items: start; gap: var(--xp-space-8); }
|
|
48
|
+
.xp-test-content { display: grid; gap: var(--xp-space-8); min-width: 0; max-width: 760px; }
|
|
49
|
+
.xp-test-rail { position: sticky; top: var(--xp-space-6); min-width: 0; }
|
|
50
|
+
.xp-test-rail-list { list-style: none; padding: 0; margin: 0; display: flex; flex-direction: column; gap: var(--xp-space-1); }
|
|
51
|
+
.xp-test-rail-item { display: flex; align-items: center; gap: var(--xp-space-2); padding: var(--xp-space-2); border-radius: var(--xp-radius-control); color: var(--xp-text-2); text-decoration: none; font: var(--xp-text-small); }
|
|
52
|
+
.xp-test-rail-item:hover, .xp-test-rail-item.is-active { background: var(--xp-surface-2); color: var(--xp-text); }
|
|
53
|
+
.xp-test-rail-item.is-active { font-weight: 600; }
|
|
54
|
+
.xp-test-rail-item--advanced { margin-top: var(--xp-space-3); color: var(--xp-text-3); }
|
|
55
|
+
.xp-test-rail-mark { flex: none; color: var(--xp-text-3); }
|
|
56
|
+
.xp-test-rail-mark--done { color: var(--xp-success); }
|
|
57
|
+
.xp-test-sr-only { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
|
|
58
|
+
.xp-test-rail-item:focus-visible, .xp-test-advanced > summary:focus-visible, .xp-test-content h2:focus { outline: 2px solid var(--xp-focus); outline-offset: 2px; }
|
|
59
|
+
.xp-test-advanced { border: 1px solid var(--xp-border); border-radius: var(--xp-radius-card); background: var(--xp-surface); }
|
|
60
|
+
.xp-test-advanced > summary { cursor: pointer; display: flex; align-items: center; justify-content: space-between; gap: var(--xp-space-3); padding: var(--xp-space-4) var(--xp-space-5); color: var(--xp-text-2); }
|
|
61
|
+
.xp-test-advanced > summary h2 { margin: 0; font: var(--xp-text-body); }
|
|
62
|
+
.xp-test-advanced[open] > summary { border-bottom: 1px solid var(--xp-border); }
|
|
63
|
+
.xp-test-readiness-bar { position: fixed; bottom: 0; inset-inline: 0; z-index: 20; background: var(--xp-surface); border-top: 1px solid var(--xp-border); }
|
|
64
|
+
.xp-readiness { color: var(--xp-text); background: var(--xp-surface); padding: var(--xp-space-4); border: 1px solid var(--xp-border-strong); border-radius: var(--xp-radius-control); }
|
|
65
|
+
.xp-readiness--ready:not(.xp-readiness--bar) { background: var(--xp-success-bg); }
|
|
66
|
+
.xp-readiness--bar { display: grid; grid-template-columns: minmax(0, 1fr) auto; align-items: center; gap: var(--xp-space-2) var(--xp-space-4); padding-block: var(--xp-space-3); min-height: 64px; border: 0; border-radius: 0; }
|
|
67
|
+
.xp-readiness__state { display: flex; align-items: center; flex-wrap: wrap; gap: var(--xp-space-2); min-width: 0; }
|
|
68
|
+
.xp-readiness__state p, .xp-readiness--bar > p { margin: 0; }
|
|
69
|
+
.xp-readiness__state > p { font-weight: 500; }
|
|
70
|
+
.xp-readiness--bar .xp-save-status, .xp-readiness__separator { color: var(--xp-text-3); font: var(--xp-text-small); }
|
|
71
|
+
.xp-readiness__actions { display: flex; flex-wrap: wrap; align-items: center; gap: var(--xp-space-2); }
|
|
72
|
+
.xp-readiness--bar > .xp-readiness__actions { grid-column: 2; grid-row: 1 / span 3; justify-content: flex-end; }
|
|
73
|
+
@media (max-width: 960px) {
|
|
74
|
+
.xp-test-layout { grid-template-columns: minmax(0, 1fr); gap: var(--xp-space-5); }
|
|
75
|
+
.xp-test-rail { top: 0; z-index: 2; background: var(--xp-bg); padding-block: var(--xp-space-2); border-bottom: 1px solid var(--xp-border); }
|
|
76
|
+
.xp-test-rail-list { flex-direction: row; overflow-x: auto; }
|
|
77
|
+
.xp-test-rail-item { white-space: nowrap; }
|
|
78
|
+
.xp-test-rail-item--advanced { margin-top: 0; }
|
|
79
|
+
.xp-test-content { max-width: none; }
|
|
80
|
+
.xp-test-section, .xp-test-advanced { scroll-margin-top: 64px; }
|
|
81
|
+
}
|
|
82
|
+
@media (max-width: 720px) {
|
|
83
|
+
.xp-readiness--bar { grid-template-columns: minmax(0, 1fr); }
|
|
84
|
+
/* The sentence wraps under the save state here, so a trailing separator would dangle. */
|
|
85
|
+
.xp-readiness--bar .xp-readiness__separator { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); }
|
|
86
|
+
.xp-readiness--bar > .xp-readiness__actions { grid-column: 1; grid-row: auto; justify-content: flex-start; }
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
.xp-ui-checkbox-list > .xp-ui-field:has(input[type="search"]) { flex-basis: 100%; }
|
|
90
|
+
.xp-targeting-row .xp-ui-chips { margin-block: 0; }
|
|
@@ -17,6 +17,7 @@ export declare function useTestDocument(id: DocId, { apiRoute }: {
|
|
|
17
17
|
hasUnsaved: boolean;
|
|
18
18
|
loadState: "loading" | "ready" | "forbidden" | "missing" | "error";
|
|
19
19
|
saving: "idle" | "saving" | "saved" | "error";
|
|
20
|
+
stale: boolean;
|
|
20
21
|
/** Path-specific validation errors; _section is the fallback for a section-wide refusal. */
|
|
21
22
|
errors: Record<string, string>;
|
|
22
23
|
};
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
import { useCallback, useEffect, useRef, useState } from 'react';
|
|
3
3
|
import { API_MESSAGES, refusalMessage } from '../copy/common.js';
|
|
4
|
+
import { XP_IF_UPDATED_AT_HEADER } from '../../constants.js';
|
|
5
|
+
import { TEST_PAGE } from '../copy/testPage.js';
|
|
4
6
|
import { changedPatch, editablePatch, payloadFieldErrors } from './testDocument.model.js';
|
|
5
7
|
// Saves outlive their mounted reader. Reopening the same document must wait for its queue.
|
|
6
8
|
const drainingSaves = new Map();
|
|
@@ -12,6 +14,7 @@ const initialView = ()=>({
|
|
|
12
14
|
hasUnsaved: false,
|
|
13
15
|
loadState: 'loading',
|
|
14
16
|
saving: 'idle',
|
|
17
|
+
stale: false,
|
|
15
18
|
errors: {}
|
|
16
19
|
});
|
|
17
20
|
async function waitForDrain(draining, signal) {
|
|
@@ -49,7 +52,7 @@ function clearErrors(errors, patch) {
|
|
|
49
52
|
return Object.fromEntries(Object.entries(errors).filter(([path])=>!Object.hasOwn(patch, path.split('.')[0])));
|
|
50
53
|
}
|
|
51
54
|
function stage(session, partial) {
|
|
52
|
-
if (!session.saved || session.reloading || session.view.loadState !== 'ready' || session.controller.signal.aborted) return;
|
|
55
|
+
if (!session.saved || session.view.stale || session.reloading || session.view.loadState !== 'ready' || session.controller.signal.aborted) return;
|
|
53
56
|
const patch = editablePatch(session.saved.status, partial);
|
|
54
57
|
if (!Object.keys(patch).length) return;
|
|
55
58
|
session.pending = {
|
|
@@ -152,11 +155,13 @@ function stage(session, partial) {
|
|
|
152
155
|
}
|
|
153
156
|
session.publish();
|
|
154
157
|
}
|
|
155
|
-
async function readDocument() {
|
|
158
|
+
async function readDocument(forSave = false) {
|
|
156
159
|
const response = await fetch(url, {
|
|
157
160
|
method: 'GET',
|
|
158
161
|
credentials: 'include',
|
|
159
|
-
|
|
162
|
+
...forSave ? {} : {
|
|
163
|
+
signal: controller.signal
|
|
164
|
+
}
|
|
160
165
|
});
|
|
161
166
|
if (!response.ok) throw new Error(API_MESSAGES.unreadable);
|
|
162
167
|
const doc = await response.json();
|
|
@@ -165,32 +170,55 @@ function stage(session, partial) {
|
|
|
165
170
|
}
|
|
166
171
|
// Capture each commit now, then diff against the latest server document when its turn arrives.
|
|
167
172
|
function commit() {
|
|
168
|
-
if (!session.saved || session.reloading || controller.signal.aborted || !Object.keys(session.pending).length) return session.tail;
|
|
173
|
+
if (!session.saved || session.view.stale || session.reloading || controller.signal.aborted || !Object.keys(session.pending).length) return session.tail;
|
|
169
174
|
const queued = session.pending;
|
|
170
175
|
session.pending = {};
|
|
171
176
|
session.queue.push(queued);
|
|
172
177
|
session.view.saving = 'saving';
|
|
173
178
|
session.publish();
|
|
174
179
|
const step = async ()=>{
|
|
180
|
+
if (session.view.stale) return;
|
|
175
181
|
let saved = false;
|
|
176
182
|
let changed = false;
|
|
177
183
|
let failed = false;
|
|
178
184
|
try {
|
|
179
185
|
if (!session.saved) return;
|
|
186
|
+
if (typeof session.saved.updatedAt !== 'string' || !session.saved.updatedAt) {
|
|
187
|
+
session.saved = await readDocument(true);
|
|
188
|
+
if (typeof session.saved.updatedAt !== 'string' || !session.saved.updatedAt) throw new Error(API_MESSAGES.unreadable);
|
|
189
|
+
}
|
|
180
190
|
const patch = changedPatch(session.saved, queued);
|
|
181
191
|
changed = Object.keys(patch).length > 0;
|
|
182
192
|
if (changed) {
|
|
193
|
+
const headers = {
|
|
194
|
+
'Content-Type': 'application/json'
|
|
195
|
+
};
|
|
196
|
+
if (typeof session.saved.updatedAt === 'string') headers[XP_IF_UPDATED_AT_HEADER] = session.saved.updatedAt;
|
|
183
197
|
const response = await fetch(url, {
|
|
184
198
|
// Submitted saves belong to the queue, not the mounted reader's lifetime.
|
|
185
199
|
method: 'PATCH',
|
|
186
200
|
credentials: 'include',
|
|
187
|
-
headers
|
|
188
|
-
'Content-Type': 'application/json'
|
|
189
|
-
},
|
|
201
|
+
headers,
|
|
190
202
|
body: JSON.stringify(patch)
|
|
191
203
|
});
|
|
192
204
|
const body = await response.json().catch(()=>undefined);
|
|
193
|
-
|
|
205
|
+
const errors = body?.errors;
|
|
206
|
+
const staleError = response.status === 409 && Array.isArray(errors) ? errors.find((error)=>error?.code === 'stale-edit') : undefined;
|
|
207
|
+
if (staleError) {
|
|
208
|
+
session.view.stale = true;
|
|
209
|
+
// Keep every typed value visible, but discard all queued sends until Reload.
|
|
210
|
+
session.pending = [
|
|
211
|
+
...session.queue,
|
|
212
|
+
session.pending
|
|
213
|
+
].reduce((draft, edit)=>({
|
|
214
|
+
...draft,
|
|
215
|
+
...edit
|
|
216
|
+
}), {});
|
|
217
|
+
session.queue = [];
|
|
218
|
+
session.view.errors = {
|
|
219
|
+
_section: staleError.message || TEST_PAGE.staleEdit
|
|
220
|
+
};
|
|
221
|
+
} else if (!response.ok) session.view.errors = {
|
|
194
222
|
...session.view.errors,
|
|
195
223
|
...payloadFieldErrors(body)
|
|
196
224
|
};
|
|
@@ -199,9 +227,12 @@ function stage(session, partial) {
|
|
|
199
227
|
const doc = body?.doc;
|
|
200
228
|
const readable = doc && doc.id != null && doc.status;
|
|
201
229
|
// A 2xx has applied even if its response body was lost. Preserve it while re-reading.
|
|
230
|
+
// The old timestamp is no longer a valid baseline. The next queued save
|
|
231
|
+
// must recover it with a GET before sending another PATCH.
|
|
202
232
|
session.saved = readable ? doc : {
|
|
203
233
|
...session.saved,
|
|
204
|
-
...patch
|
|
234
|
+
...patch,
|
|
235
|
+
updatedAt: undefined
|
|
205
236
|
};
|
|
206
237
|
saved = true;
|
|
207
238
|
// Keep readiness pending even while recovering an unreadable successful PATCH body.
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { TargetingRule } from '../../types/contracts.js';
|
|
2
2
|
import type { SerializedAttributeKeys } from '../../types/admin.js';
|
|
3
3
|
import type { TargetingOp } from '../../targeting/ops.js';
|
|
4
|
+
export { readListValue } from '../../targeting/values.js';
|
|
4
5
|
type Attribute = SerializedAttributeKeys[string];
|
|
5
6
|
export type AttributeType = Attribute['type'];
|
|
6
7
|
export declare function opsFor(type?: AttributeType): readonly TargetingOp[];
|
|
@@ -13,11 +14,8 @@ export declare function valueInput(attribute?: Attribute, op?: TargetingOp): {
|
|
|
13
14
|
}[];
|
|
14
15
|
};
|
|
15
16
|
export declare function coerceValue(type: AttributeType, op: TargetingOp, raw: unknown): string | number | boolean | string[] | null;
|
|
16
|
-
/** Only the read boundary accepts legacy comma-separated document values. */
|
|
17
|
-
export declare function readListValue(raw: unknown): string[];
|
|
18
17
|
/** Normalize the read boundary before any whole-group edit. */
|
|
19
18
|
export declare function readTargetingRules(rules: TargetingRule[]): TargetingRule[];
|
|
20
19
|
export declare function rowPath(path: string): string;
|
|
21
20
|
export declare function emptyListHint(op: TargetingOp, value: unknown): string | undefined;
|
|
22
21
|
export declare function humaniseAttribute(key: string): string;
|
|
23
|
-
export {};
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { TARGETING_OPS, isOpValid } from '../../targeting/ops.js';
|
|
2
|
+
import { coerceListValue, readListValue } from '../../targeting/values.js';
|
|
2
3
|
import { NUMBER_OP_LABELS, STRING_OP_LABELS, AUDIENCE_COPY } from '../copy/audience.js';
|
|
4
|
+
export { readListValue } from '../../targeting/values.js';
|
|
3
5
|
export function opsFor(type) {
|
|
4
6
|
return type ? TARGETING_OPS[type] : [];
|
|
5
7
|
}
|
|
@@ -27,11 +29,7 @@ export function valueInput(attribute, op = 'eq') {
|
|
|
27
29
|
export function coerceValue(type, op, raw) {
|
|
28
30
|
if (!isOpValid(type, op)) return null;
|
|
29
31
|
if (type === 'string') {
|
|
30
|
-
if (op === 'in' || op === 'nin') return
|
|
31
|
-
...new Set((Array.isArray(raw) ? raw.map(String) : [
|
|
32
|
-
String(raw ?? '')
|
|
33
|
-
]).map((value)=>value.trim()).filter(Boolean))
|
|
34
|
-
];
|
|
32
|
+
if (op === 'in' || op === 'nin') return coerceListValue(raw);
|
|
35
33
|
return raw == null ? '' : String(raw);
|
|
36
34
|
}
|
|
37
35
|
if (type === 'number') {
|
|
@@ -41,9 +39,6 @@ export function coerceValue(type, op, raw) {
|
|
|
41
39
|
}
|
|
42
40
|
return raw === true || raw === 'true' ? true : raw === false || raw === 'false' ? false : null;
|
|
43
41
|
}
|
|
44
|
-
/** Only the read boundary accepts legacy comma-separated document values. */ export function readListValue(raw) {
|
|
45
|
-
return coerceValue('string', 'in', typeof raw === 'string' ? raw.split(',') : raw);
|
|
46
|
-
}
|
|
47
42
|
/** Normalize the read boundary before any whole-group edit. */ export function readTargetingRules(rules) {
|
|
48
43
|
return rules.map((rule)=>rule.op === 'in' || rule.op === 'nin' ? {
|
|
49
44
|
...rule,
|
package/dist/admin/theme.css
CHANGED
|
@@ -1,44 +1,123 @@
|
|
|
1
|
-
/* The Payload token boundary.
|
|
1
|
+
/* The only Payload token boundary. Reference: Payload 3.90.2; nearest neutral
|
|
2
|
+
elevation by RGB distance to the approved mockup, advancing toward the mockup
|
|
3
|
+
on collision so all five surface steps stay distinct (light / dark):
|
|
4
|
+
bg 50/0; surface 0/50; surface-2 100/100; surface-3 150/150;
|
|
5
|
+
accent-subtle 200/200;
|
|
6
|
+
border 100/100; border-strong 250/200; text 850/800;
|
|
7
|
+
text-2 650/550; text-3 450/350; accent 800/800; hover 900/900;
|
|
8
|
+
accent-fg 0/0; focus 800/800; series-muted 300/250.
|
|
9
|
+
Semantic and series hues are fixed mockup literals; only neutrals use Payload. */
|
|
2
10
|
:root, [data-theme] {
|
|
3
|
-
--xp-bg: var(--theme-
|
|
4
|
-
--xp-
|
|
5
|
-
--xp-surface: var(--theme-elevation-
|
|
6
|
-
--xp-surface-
|
|
7
|
-
--xp-border: var(--theme-elevation-
|
|
8
|
-
--xp-border-strong: var(--theme-elevation-
|
|
11
|
+
--xp-bg: var(--theme-elevation-50);
|
|
12
|
+
--xp-surface: var(--theme-elevation-0);
|
|
13
|
+
--xp-surface-2: var(--theme-elevation-100);
|
|
14
|
+
--xp-surface-3: var(--theme-elevation-150);
|
|
15
|
+
--xp-border: var(--theme-elevation-100);
|
|
16
|
+
--xp-border-strong: var(--theme-elevation-250);
|
|
17
|
+
--xp-text: var(--theme-elevation-850);
|
|
18
|
+
--xp-text-2: var(--theme-elevation-650);
|
|
19
|
+
--xp-text-3: var(--theme-elevation-450);
|
|
20
|
+
--xp-accent: var(--theme-elevation-800);
|
|
21
|
+
--xp-accent-hover: var(--theme-elevation-900);
|
|
22
|
+
--xp-accent-active: var(--theme-elevation-950);
|
|
23
|
+
--xp-accent-subtle: var(--theme-elevation-200);
|
|
24
|
+
--xp-accent-fg: var(--theme-elevation-0);
|
|
25
|
+
--xp-accent-text: var(--xp-text);
|
|
26
|
+
--xp-accent-text-decoration: none;
|
|
27
|
+
--xp-focus: var(--theme-elevation-800);
|
|
28
|
+
--xp-series-muted: var(--theme-elevation-300);
|
|
29
|
+
--xp-success: #1a6a3a;
|
|
30
|
+
--xp-success-bg: #e8f4ec;
|
|
31
|
+
--xp-success-border: #bddfc9;
|
|
32
|
+
--xp-warning: #8a5a0b;
|
|
33
|
+
--xp-warning-bg: #fbf3e1;
|
|
34
|
+
--xp-warning-border: #ecd6a2;
|
|
35
|
+
--xp-error: #a63030;
|
|
36
|
+
--xp-error-bg: #fbeaea;
|
|
37
|
+
--xp-error-border: #efc3c3;
|
|
38
|
+
--xp-series-a: #2a78d6;
|
|
39
|
+
--xp-series-b: #eb6834;
|
|
40
|
+
--xp-series-c: #8056b3;
|
|
41
|
+
--xp-radius-control: 8px;
|
|
42
|
+
--xp-radius-card: 12px;
|
|
43
|
+
--xp-radius-chip: 6px;
|
|
44
|
+
--xp-font: var(--font-body);
|
|
45
|
+
--xp-mono: var(--font-mono);
|
|
46
|
+
--xp-text-display: 600 28px/32px var(--xp-font);
|
|
47
|
+
--xp-text-title: 600 20px/28px var(--xp-font);
|
|
48
|
+
--xp-text-body: 400 15px/22px var(--xp-font);
|
|
49
|
+
--xp-text-small: 400 13px/18px var(--xp-font);
|
|
50
|
+
--xp-motion: 120ms;
|
|
51
|
+
--xp-space-half: 2px;
|
|
52
|
+
--xp-space-one-half: 6px;
|
|
53
|
+
--xp-version-share-width: 96px;
|
|
54
|
+
--xp-version-share-width-mobile: 84px;
|
|
55
|
+
--xp-version-state-width: 192px;
|
|
56
|
+
--xp-version-remove-width: 128px;
|
|
57
|
+
--xp-targeting-attribute-width: 150px;
|
|
58
|
+
--xp-targeting-comparison-width: 140px;
|
|
59
|
+
--xp-legend-key-size: 10px;
|
|
60
|
+
--xp-legend-key-radius: 3px;
|
|
61
|
+
--xp-space-1: 4px;
|
|
62
|
+
--xp-space-2: 8px;
|
|
63
|
+
--xp-space-3: 12px;
|
|
64
|
+
--xp-space-4: 16px;
|
|
65
|
+
--xp-space-5: 20px;
|
|
66
|
+
--xp-space-6: 24px;
|
|
67
|
+
--xp-space-7: 28px;
|
|
68
|
+
--xp-space-8: 32px;
|
|
69
|
+
--xp-surface-raised: var(--xp-surface-2);
|
|
9
70
|
--xp-border-control: var(--theme-elevation-250);
|
|
10
71
|
--xp-input-border: var(--theme-elevation-300);
|
|
11
72
|
--xp-border-accent: var(--theme-elevation-400);
|
|
12
|
-
--xp-
|
|
13
|
-
--xp-text-
|
|
14
|
-
--xp-text-
|
|
15
|
-
--xp-text-emphasis: var(--theme-elevation-900);
|
|
73
|
+
--xp-text-muted: var(--xp-text-2);
|
|
74
|
+
--xp-text-strong: var(--xp-text);
|
|
75
|
+
--xp-text-emphasis: var(--xp-text);
|
|
16
76
|
--xp-input-bg: var(--theme-input-bg);
|
|
17
77
|
--xp-overlay: var(--theme-overlay);
|
|
18
|
-
--xp-success-surface: var(--
|
|
19
|
-
--xp-success-
|
|
20
|
-
--xp-success: var(--
|
|
21
|
-
--xp-
|
|
22
|
-
--xp-
|
|
23
|
-
--xp-warning-
|
|
24
|
-
--xp-
|
|
25
|
-
--xp-
|
|
26
|
-
--xp-
|
|
27
|
-
--xp-
|
|
28
|
-
--xp-error-surface: var(--theme-error-100);
|
|
29
|
-
--xp-error: var(--theme-error-500);
|
|
30
|
-
--xp-error-text: var(--theme-error-600);
|
|
31
|
-
--xp-radius: var(--style-radius-s);
|
|
32
|
-
--xp-radius-large: var(--style-radius-m);
|
|
33
|
-
--xp-space-1: calc(var(--base) * 0.25);
|
|
34
|
-
--xp-space-2: calc(var(--base) * 0.5);
|
|
35
|
-
--xp-space-3: calc(var(--base) * 0.75);
|
|
36
|
-
--xp-space-4: calc(var(--base) * 1);
|
|
37
|
-
--xp-space-5: calc(var(--base) * 1.5);
|
|
38
|
-
--xp-space-6: calc(var(--base) * 2);
|
|
78
|
+
--xp-success-surface: var(--xp-success-bg);
|
|
79
|
+
--xp-success-text: var(--xp-success);
|
|
80
|
+
--xp-success-text-strong: var(--xp-success);
|
|
81
|
+
--xp-warning-surface: var(--xp-warning-bg);
|
|
82
|
+
--xp-warning-text: var(--xp-warning);
|
|
83
|
+
--xp-warning-text-strong: var(--xp-warning);
|
|
84
|
+
--xp-error-surface: var(--xp-error-bg);
|
|
85
|
+
--xp-error-text: var(--xp-error);
|
|
86
|
+
--xp-radius: var(--xp-radius-control);
|
|
87
|
+
--xp-radius-large: var(--xp-radius-card);
|
|
39
88
|
--xp-dash-card-gap: 12px;
|
|
40
|
-
--xp-dash-card-gap-small:
|
|
41
|
-
--xp-font-body: var(--font
|
|
42
|
-
--xp-font-size-small:
|
|
43
|
-
--xp-font-size-body:
|
|
89
|
+
--xp-dash-card-gap-small: 8px;
|
|
90
|
+
--xp-font-body: var(--xp-font);
|
|
91
|
+
--xp-font-size-small: 13px;
|
|
92
|
+
--xp-font-size-body: 15px;
|
|
93
|
+
}
|
|
94
|
+
[data-theme="dark"] {
|
|
95
|
+
--xp-bg: var(--theme-elevation-0);
|
|
96
|
+
--xp-surface: var(--theme-elevation-50);
|
|
97
|
+
--xp-surface-2: var(--theme-elevation-100);
|
|
98
|
+
--xp-surface-3: var(--theme-elevation-150);
|
|
99
|
+
--xp-border: var(--theme-elevation-100);
|
|
100
|
+
--xp-border-strong: var(--theme-elevation-200);
|
|
101
|
+
--xp-text: var(--theme-elevation-800);
|
|
102
|
+
--xp-text-2: var(--theme-elevation-550);
|
|
103
|
+
--xp-text-3: var(--theme-elevation-350);
|
|
104
|
+
--xp-accent: var(--theme-elevation-800);
|
|
105
|
+
--xp-accent-hover: var(--theme-elevation-900);
|
|
106
|
+
--xp-accent-active: var(--theme-elevation-1000);
|
|
107
|
+
--xp-accent-subtle: var(--theme-elevation-200);
|
|
108
|
+
--xp-accent-fg: var(--theme-elevation-0);
|
|
109
|
+
--xp-focus: var(--theme-elevation-800);
|
|
110
|
+
--xp-series-muted: var(--theme-elevation-250);
|
|
111
|
+
--xp-success: #7fd49c;
|
|
112
|
+
--xp-success-bg: #142b1d;
|
|
113
|
+
--xp-success-border: #23492f;
|
|
114
|
+
--xp-warning: #e7bd5c;
|
|
115
|
+
--xp-warning-bg: #2b2312;
|
|
116
|
+
--xp-warning-border: #4d3d17;
|
|
117
|
+
--xp-error: #f09494;
|
|
118
|
+
--xp-error-bg: #2f1717;
|
|
119
|
+
--xp-error-border: #5a2626;
|
|
120
|
+
--xp-series-a: #3987e5;
|
|
121
|
+
--xp-series-b: #d95926;
|
|
122
|
+
--xp-series-c: #b48ade;
|
|
44
123
|
}
|
package/dist/admin/theme.d.ts
CHANGED
|
@@ -1,9 +1,33 @@
|
|
|
1
|
+
/** Host accent rules (reference surfaces are defined by theme.css):
|
|
2
|
+
* (i) Foreground on accent, hover and active fills reaches 4.5:1 in both themes.
|
|
3
|
+
* (ii) Accent text moves toward the surface's opposite to reach 4.5:1; if the
|
|
4
|
+
* bounded search fails, use the neutral text token and underline it.
|
|
5
|
+
* (iii) Focus reaches 3:1 against the surface: darken on light, lighten on dark.
|
|
6
|
+
*/
|
|
7
|
+
export { deriveAccent } from '../ui/accent.js';
|
|
1
8
|
/** every Payload token reference lives in theme.css; porting to Payload 4 edits that file only */
|
|
2
9
|
export declare const theme: {
|
|
3
10
|
readonly color: {
|
|
4
11
|
readonly bg: "var(--xp-bg)";
|
|
5
12
|
readonly text: "var(--xp-text)";
|
|
6
13
|
readonly surface: "var(--xp-surface)";
|
|
14
|
+
readonly surface2: "var(--xp-surface-2)";
|
|
15
|
+
readonly surface3: "var(--xp-surface-3)";
|
|
16
|
+
readonly text2: "var(--xp-text-2)";
|
|
17
|
+
readonly text3: "var(--xp-text-3)";
|
|
18
|
+
readonly accentHover: "var(--xp-accent-hover)";
|
|
19
|
+
readonly accentActive: "var(--xp-accent-active)";
|
|
20
|
+
readonly accentText: "var(--xp-accent-text)";
|
|
21
|
+
readonly accentSubtle: "var(--xp-accent-subtle)";
|
|
22
|
+
readonly accentFg: "var(--xp-accent-fg)";
|
|
23
|
+
readonly focus: "var(--xp-focus)";
|
|
24
|
+
readonly successBorder: "var(--xp-success-border)";
|
|
25
|
+
readonly warningBorder: "var(--xp-warning-border)";
|
|
26
|
+
readonly errorBg: "var(--xp-error-bg)";
|
|
27
|
+
readonly errorBorder: "var(--xp-error-border)";
|
|
28
|
+
readonly seriesA: "var(--xp-series-a)";
|
|
29
|
+
readonly seriesB: "var(--xp-series-b)";
|
|
30
|
+
readonly seriesMuted: "var(--xp-series-muted)";
|
|
7
31
|
readonly surfaceRaised: "var(--xp-surface-raised)";
|
|
8
32
|
readonly border: "var(--xp-border)";
|
|
9
33
|
readonly borderStrong: "var(--xp-border-strong)";
|
|
@@ -30,7 +54,17 @@ export declare const theme: {
|
|
|
30
54
|
readonly error: "var(--xp-error)";
|
|
31
55
|
readonly errorText: "var(--xp-error-text)";
|
|
32
56
|
};
|
|
57
|
+
readonly motion: "var(--xp-motion)";
|
|
58
|
+
readonly type: {
|
|
59
|
+
readonly display: "var(--xp-text-display)";
|
|
60
|
+
readonly title: "var(--xp-text-title)";
|
|
61
|
+
readonly body: "var(--xp-text-body)";
|
|
62
|
+
readonly small: "var(--xp-text-small)";
|
|
63
|
+
};
|
|
33
64
|
readonly radius: {
|
|
65
|
+
readonly control: "var(--xp-radius-control)";
|
|
66
|
+
readonly card: "var(--xp-radius-card)";
|
|
67
|
+
readonly chip: "var(--xp-radius-chip)";
|
|
34
68
|
readonly small: "var(--xp-radius)";
|
|
35
69
|
readonly large: "var(--xp-radius-large)";
|
|
36
70
|
};
|
|
@@ -41,8 +75,12 @@ export declare const theme: {
|
|
|
41
75
|
readonly 4: "var(--xp-space-4)";
|
|
42
76
|
readonly 5: "var(--xp-space-5)";
|
|
43
77
|
readonly 6: "var(--xp-space-6)";
|
|
78
|
+
readonly 7: "var(--xp-space-7)";
|
|
79
|
+
readonly 8: "var(--xp-space-8)";
|
|
44
80
|
};
|
|
45
81
|
readonly font: {
|
|
82
|
+
readonly mono: "var(--xp-mono)";
|
|
83
|
+
readonly family: "var(--xp-font)";
|
|
46
84
|
readonly body: "var(--xp-font-body)";
|
|
47
85
|
readonly small: "var(--xp-font-size-small)";
|
|
48
86
|
readonly size: "var(--xp-font-size-body)";
|
package/dist/admin/theme.js
CHANGED
|
@@ -1,8 +1,31 @@
|
|
|
1
|
+
/** Host accent rules (reference surfaces are defined by theme.css):
|
|
2
|
+
* (i) Foreground on accent, hover and active fills reaches 4.5:1 in both themes.
|
|
3
|
+
* (ii) Accent text moves toward the surface's opposite to reach 4.5:1; if the
|
|
4
|
+
* bounded search fails, use the neutral text token and underline it.
|
|
5
|
+
* (iii) Focus reaches 3:1 against the surface: darken on light, lighten on dark.
|
|
6
|
+
*/ export { deriveAccent } from '../ui/accent.js';
|
|
1
7
|
/** every Payload token reference lives in theme.css; porting to Payload 4 edits that file only */ export const theme = {
|
|
2
8
|
color: {
|
|
3
9
|
bg: 'var(--xp-bg)',
|
|
4
10
|
text: 'var(--xp-text)',
|
|
5
11
|
surface: 'var(--xp-surface)',
|
|
12
|
+
surface2: 'var(--xp-surface-2)',
|
|
13
|
+
surface3: 'var(--xp-surface-3)',
|
|
14
|
+
text2: 'var(--xp-text-2)',
|
|
15
|
+
text3: 'var(--xp-text-3)',
|
|
16
|
+
accentHover: 'var(--xp-accent-hover)',
|
|
17
|
+
accentActive: 'var(--xp-accent-active)',
|
|
18
|
+
accentText: 'var(--xp-accent-text)',
|
|
19
|
+
accentSubtle: 'var(--xp-accent-subtle)',
|
|
20
|
+
accentFg: 'var(--xp-accent-fg)',
|
|
21
|
+
focus: 'var(--xp-focus)',
|
|
22
|
+
successBorder: 'var(--xp-success-border)',
|
|
23
|
+
warningBorder: 'var(--xp-warning-border)',
|
|
24
|
+
errorBg: 'var(--xp-error-bg)',
|
|
25
|
+
errorBorder: 'var(--xp-error-border)',
|
|
26
|
+
seriesA: 'var(--xp-series-a)',
|
|
27
|
+
seriesB: 'var(--xp-series-b)',
|
|
28
|
+
seriesMuted: 'var(--xp-series-muted)',
|
|
6
29
|
surfaceRaised: 'var(--xp-surface-raised)',
|
|
7
30
|
border: 'var(--xp-border)',
|
|
8
31
|
borderStrong: 'var(--xp-border-strong)',
|
|
@@ -29,7 +52,17 @@
|
|
|
29
52
|
error: 'var(--xp-error)',
|
|
30
53
|
errorText: 'var(--xp-error-text)'
|
|
31
54
|
},
|
|
55
|
+
motion: 'var(--xp-motion)',
|
|
56
|
+
type: {
|
|
57
|
+
display: 'var(--xp-text-display)',
|
|
58
|
+
title: 'var(--xp-text-title)',
|
|
59
|
+
body: 'var(--xp-text-body)',
|
|
60
|
+
small: 'var(--xp-text-small)'
|
|
61
|
+
},
|
|
32
62
|
radius: {
|
|
63
|
+
control: 'var(--xp-radius-control)',
|
|
64
|
+
card: 'var(--xp-radius-card)',
|
|
65
|
+
chip: 'var(--xp-radius-chip)',
|
|
33
66
|
small: 'var(--xp-radius)',
|
|
34
67
|
large: 'var(--xp-radius-large)'
|
|
35
68
|
},
|
|
@@ -39,9 +72,13 @@
|
|
|
39
72
|
3: 'var(--xp-space-3)',
|
|
40
73
|
4: 'var(--xp-space-4)',
|
|
41
74
|
5: 'var(--xp-space-5)',
|
|
42
|
-
6: 'var(--xp-space-6)'
|
|
75
|
+
6: 'var(--xp-space-6)',
|
|
76
|
+
7: 'var(--xp-space-7)',
|
|
77
|
+
8: 'var(--xp-space-8)'
|
|
43
78
|
},
|
|
44
79
|
font: {
|
|
80
|
+
mono: 'var(--xp-mono)',
|
|
81
|
+
family: 'var(--xp-font)',
|
|
45
82
|
body: 'var(--xp-font-body)',
|
|
46
83
|
small: 'var(--xp-font-size-small)',
|
|
47
84
|
size: 'var(--xp-font-size-body)'
|
package/dist/admin/useApi.d.ts
CHANGED
|
@@ -1,17 +1,32 @@
|
|
|
1
1
|
export declare function useApi(): {
|
|
2
2
|
start: (id: import("../types/contracts.js").DocId) => Promise<import("./api.js").ApiResult<import("../types/endpoints.js").TransitionSuccess>>;
|
|
3
|
-
allocate: (id: import("../types/contracts.js").DocId, body: import("../types/endpoints.js").AllocateBody
|
|
4
|
-
|
|
3
|
+
allocate: (id: import("../types/contracts.js").DocId, body: import("../types/endpoints.js").AllocateBody, options?: {
|
|
4
|
+
notFound?: string;
|
|
5
|
+
codes?: Readonly<Record<string, string>>;
|
|
6
|
+
fallback?: string;
|
|
7
|
+
}) => Promise<import("./api.js").ApiResult<import("../types/endpoints.js").TransitionSuccess>>;
|
|
8
|
+
addMetric: (id: import("../types/contracts.js").DocId, body: import("../types/endpoints.js").AddMetricBody, options?: {
|
|
9
|
+
notFound?: string;
|
|
10
|
+
codes?: Readonly<Record<string, string>>;
|
|
11
|
+
fallback?: string;
|
|
12
|
+
}) => Promise<import("./api.js").ApiResult<import("../types/endpoints.js").TransitionSuccess>>;
|
|
5
13
|
stop: (id: import("../types/contracts.js").DocId) => Promise<import("./api.js").ApiResult<import("../types/endpoints.js").TransitionSuccess>>;
|
|
6
14
|
decide: (id: import("../types/contracts.js").DocId, body: import("../types/endpoints.js").DecideBody) => Promise<import("./api.js").ApiResult<import("../types/endpoints.js").TransitionSuccess>>;
|
|
7
15
|
releaseHoldout: (id: import("../types/contracts.js").DocId) => Promise<import("./api.js").ApiResult<import("../types/endpoints.js").TransitionSuccess>>;
|
|
16
|
+
releasePages: (id: import("../types/contracts.js").DocId) => Promise<import("./api.js").ApiResult<import("../types/endpoints.js").TransitionSuccess>>;
|
|
8
17
|
makeContent: (id: import("../types/contracts.js").DocId) => Promise<import("./api.js").ApiResult<import("../types/endpoints.js").MakeContentResult>>;
|
|
18
|
+
dismissContentEntry: (id: import("../types/contracts.js").DocId, body: import("../types/endpoints.js").DismissContentEntryBody) => Promise<import("./api.js").ApiResult<import("../types/endpoints.js").DismissContentEntryResult>>;
|
|
19
|
+
restoreContentEntry: (id: import("../types/contracts.js").DocId, body: import("../types/endpoints.js").RestoreContentEntryBody) => Promise<import("./api.js").ApiResult<import("../types/endpoints.js").RestoreContentEntryResult>>;
|
|
9
20
|
archive: (id: import("../types/contracts.js").DocId, body: import("../types/endpoints.js").ArchiveBody) => Promise<import("./api.js").ApiResult<import("../types/endpoints.js").TransitionSuccess>>;
|
|
10
21
|
preflight: (id: import("../types/contracts.js").DocId) => Promise<import("./api.js").ApiResult<import("../types/endpoints.js").PreflightResult>>;
|
|
11
22
|
previewToken: (id: import("../types/contracts.js").DocId, arm: string) => Promise<import("./api.js").ApiResult<import("../types/endpoints.js").PreviewTokenResult>>;
|
|
12
23
|
results: (id: import("../types/contracts.js").DocId, options?: {
|
|
13
24
|
phase?: number;
|
|
14
25
|
series?: boolean;
|
|
26
|
+
} & {
|
|
27
|
+
notFound?: string;
|
|
28
|
+
codes?: Readonly<Record<string, string>>;
|
|
29
|
+
fallback?: string;
|
|
15
30
|
}) => Promise<import("./api.js").ApiResult<import("../types/endpoints.js").ResultsResponse>>;
|
|
16
31
|
recompute: (id: import("../types/contracts.js").DocId) => Promise<import("./api.js").ApiResult<{
|
|
17
32
|
snapshotId: string;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { jsx as _jsx } from "react/jsx-runtime";
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
+
import { accentStyles } from '../../ui/accent.js';
|
|
2
3
|
import { formatAdminURL } from 'payload/shared';
|
|
3
4
|
import { notFound, redirect } from 'next/navigation.js';
|
|
4
5
|
import { RenderServerComponent } from '@payloadcms/ui/elements/RenderServerComponent';
|
|
@@ -166,10 +167,19 @@ export async function ExperimentsRootView({ initPageResult, params, searchParams
|
|
|
166
167
|
children: SURFACE_COPY.notInstalled
|
|
167
168
|
});
|
|
168
169
|
}
|
|
169
|
-
|
|
170
|
+
const css = accentStyles(options.theme?.accent);
|
|
171
|
+
const surface = RenderServerComponent({
|
|
170
172
|
Component: XP_TESTS_SURFACE,
|
|
171
173
|
Fallback: TestsSurfaceFallback,
|
|
172
174
|
importMap: req.payload.importMap,
|
|
173
175
|
clientProps
|
|
174
176
|
});
|
|
177
|
+
return css ? /*#__PURE__*/ _jsxs(_Fragment, {
|
|
178
|
+
children: [
|
|
179
|
+
/*#__PURE__*/ _jsx("style", {
|
|
180
|
+
children: css
|
|
181
|
+
}),
|
|
182
|
+
surface
|
|
183
|
+
]
|
|
184
|
+
}) : surface;
|
|
175
185
|
}
|