@delmaredigital/payload-experiments 0.2.0-rc.3 → 0.2.0-rc.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (85) hide show
  1. package/README.md +22 -0
  2. package/dist/admin/PreviewLinks.js +8 -4
  3. package/dist/admin/TestsDashboardCards.d.ts +3 -0
  4. package/dist/admin/TestsDashboardCards.js +52 -0
  5. package/dist/admin/TestsNavLink.d.ts +3 -1
  6. package/dist/admin/TestsNavLink.js +62 -18
  7. package/dist/admin/actions/ConfirmDialog.d.ts +1 -0
  8. package/dist/admin/actions/ConfirmDialog.js +7 -5
  9. package/dist/admin/components/ChipsInput.d.ts +12 -0
  10. package/dist/admin/components/ChipsInput.js +96 -0
  11. package/dist/admin/components/RootViewMessage.d.ts +5 -0
  12. package/dist/admin/components/RootViewMessage.js +15 -0
  13. package/dist/admin/components/chipsInput.css +11 -0
  14. package/dist/admin/copy/audience.d.ts +4 -0
  15. package/dist/admin/copy/audience.js +4 -0
  16. package/dist/admin/copy/goals.d.ts +44 -0
  17. package/dist/admin/copy/goals.js +46 -0
  18. package/dist/admin/copy/review.d.ts +1 -0
  19. package/dist/admin/copy/review.js +1 -0
  20. package/dist/admin/copy/surface.d.ts +4 -0
  21. package/dist/admin/copy/surface.js +4 -0
  22. package/dist/admin/dashboard.css +35 -0
  23. package/dist/admin/paths.d.ts +1 -0
  24. package/dist/admin/paths.js +1 -0
  25. package/dist/admin/previewLinks.model.d.ts +9 -0
  26. package/dist/admin/previewLinks.model.js +34 -0
  27. package/dist/admin/results/ArmTable.js +2 -1
  28. package/dist/admin/results/CappedCell.js +2 -1
  29. package/dist/admin/results/CiChart.js +8 -7
  30. package/dist/admin/results/DataQualityPanel.js +3 -2
  31. package/dist/admin/results/VerdictCard.js +3 -2
  32. package/dist/admin/styles.css +8 -8
  33. package/dist/admin/styles.d.ts +1 -0
  34. package/dist/admin/styles.js +1 -0
  35. package/dist/admin/surface/SurfaceShell.d.ts +1 -0
  36. package/dist/admin/surface/SurfaceShell.js +1 -0
  37. package/dist/admin/surface/TestsHome.js +1 -1
  38. package/dist/admin/surface/TestsSurface.js +10 -1
  39. package/dist/admin/surface/goals/GoalForm.d.ts +7 -0
  40. package/dist/admin/surface/goals/GoalForm.js +470 -0
  41. package/dist/admin/surface/goals/GoalsBreadcrumb.d.ts +5 -0
  42. package/dist/admin/surface/goals/GoalsBreadcrumb.js +47 -0
  43. package/dist/admin/surface/goals/GoalsList.d.ts +6 -0
  44. package/dist/admin/surface/goals/GoalsList.js +135 -0
  45. package/dist/admin/surface/goals/data.d.ts +3 -0
  46. package/dist/admin/surface/goals/data.js +24 -0
  47. package/dist/admin/surface/goals/goals.css +15 -0
  48. package/dist/admin/surface/goals/goals.model.d.ts +30 -0
  49. package/dist/admin/surface/goals/goals.model.js +26 -0
  50. package/dist/admin/surface/newTest/newTest.css +6 -6
  51. package/dist/admin/surface/readiness/Banner.js +5 -4
  52. package/dist/admin/surface/results/ResultsBody.js +3 -2
  53. package/dist/admin/surface/setting/setting.css +11 -11
  54. package/dist/admin/surface/surface.css +29 -29
  55. package/dist/admin/surface/test/GoalSection.js +32 -1
  56. package/dist/admin/surface/test/TargetingSection.js +27 -10
  57. package/dist/admin/surface/test/VersionsSection.js +6 -5
  58. package/dist/admin/surface/test/testPage.css +12 -12
  59. package/dist/admin/targeting/targeting.model.d.ts +6 -1
  60. package/dist/admin/targeting/targeting.model.js +18 -2
  61. package/dist/admin/theme.css +44 -0
  62. package/dist/admin/theme.d.ts +50 -0
  63. package/dist/admin/theme.js +49 -0
  64. package/dist/admin/views/ExperimentsRootView.js +18 -18
  65. package/dist/collections/events.js +1 -0
  66. package/dist/collections/identities.js +1 -0
  67. package/dist/collections/layers.js +1 -0
  68. package/dist/collections/metricValidation.d.ts +3 -0
  69. package/dist/collections/metricValidation.js +9 -0
  70. package/dist/collections/metrics.js +4 -5
  71. package/dist/collections/phases.js +1 -0
  72. package/dist/collections/snapshots.js +1 -0
  73. package/dist/exports/adminClient.d.ts +1 -0
  74. package/dist/exports/adminClient.js +1 -0
  75. package/dist/globals/state.js +1 -0
  76. package/dist/plugin.js +8 -2
  77. package/dist/puck/editor/CreateExperimentDrawer.d.ts +1 -0
  78. package/dist/puck/editor/CreateExperimentDrawer.js +34 -25
  79. package/dist/puck/editor/ExperimentSlotEditor.d.ts +1 -0
  80. package/dist/puck/editor/ExperimentSlotEditor.js +137 -78
  81. package/dist/puck/editor/copy.d.ts +3 -1
  82. package/dist/puck/editor/copy.js +3 -1
  83. package/dist/puck/editor/editor.css +302 -0
  84. package/dist/types/surface.d.ts +2 -1
  85. package/package.json +2 -1
@@ -0,0 +1,50 @@
1
+ /** every Payload token reference lives in theme.css; porting to Payload 4 edits that file only */
2
+ export declare const theme: {
3
+ readonly color: {
4
+ readonly bg: "var(--xp-bg)";
5
+ readonly text: "var(--xp-text)";
6
+ readonly surface: "var(--xp-surface)";
7
+ readonly surfaceRaised: "var(--xp-surface-raised)";
8
+ readonly border: "var(--xp-border)";
9
+ readonly borderStrong: "var(--xp-border-strong)";
10
+ readonly borderControl: "var(--xp-border-control)";
11
+ readonly inputBorder: "var(--xp-input-border)";
12
+ readonly borderAccent: "var(--xp-border-accent)";
13
+ readonly accent: "var(--xp-accent)";
14
+ readonly textMuted: "var(--xp-text-muted)";
15
+ readonly textStrong: "var(--xp-text-strong)";
16
+ readonly textEmphasis: "var(--xp-text-emphasis)";
17
+ readonly inputBg: "var(--xp-input-bg)";
18
+ readonly overlay: "var(--xp-overlay)";
19
+ readonly successSurface: "var(--xp-success-surface)";
20
+ readonly successBg: "var(--xp-success-bg)";
21
+ readonly success: "var(--xp-success)";
22
+ readonly successText: "var(--xp-success-text)";
23
+ readonly successTextStrong: "var(--xp-success-text-strong)";
24
+ readonly warningSurface: "var(--xp-warning-surface)";
25
+ readonly warningBg: "var(--xp-warning-bg)";
26
+ readonly warning: "var(--xp-warning)";
27
+ readonly warningText: "var(--xp-warning-text)";
28
+ readonly warningTextStrong: "var(--xp-warning-text-strong)";
29
+ readonly errorSurface: "var(--xp-error-surface)";
30
+ readonly error: "var(--xp-error)";
31
+ readonly errorText: "var(--xp-error-text)";
32
+ };
33
+ readonly radius: {
34
+ readonly small: "var(--xp-radius)";
35
+ readonly large: "var(--xp-radius-large)";
36
+ };
37
+ readonly space: {
38
+ readonly 1: "var(--xp-space-1)";
39
+ readonly 2: "var(--xp-space-2)";
40
+ readonly 3: "var(--xp-space-3)";
41
+ readonly 4: "var(--xp-space-4)";
42
+ readonly 5: "var(--xp-space-5)";
43
+ readonly 6: "var(--xp-space-6)";
44
+ };
45
+ readonly font: {
46
+ readonly body: "var(--xp-font-body)";
47
+ readonly small: "var(--xp-font-size-small)";
48
+ readonly size: "var(--xp-font-size-body)";
49
+ };
50
+ };
@@ -0,0 +1,49 @@
1
+ /** every Payload token reference lives in theme.css; porting to Payload 4 edits that file only */ export const theme = {
2
+ color: {
3
+ bg: 'var(--xp-bg)',
4
+ text: 'var(--xp-text)',
5
+ surface: 'var(--xp-surface)',
6
+ surfaceRaised: 'var(--xp-surface-raised)',
7
+ border: 'var(--xp-border)',
8
+ borderStrong: 'var(--xp-border-strong)',
9
+ borderControl: 'var(--xp-border-control)',
10
+ inputBorder: 'var(--xp-input-border)',
11
+ borderAccent: 'var(--xp-border-accent)',
12
+ accent: 'var(--xp-accent)',
13
+ textMuted: 'var(--xp-text-muted)',
14
+ textStrong: 'var(--xp-text-strong)',
15
+ textEmphasis: 'var(--xp-text-emphasis)',
16
+ inputBg: 'var(--xp-input-bg)',
17
+ overlay: 'var(--xp-overlay)',
18
+ successSurface: 'var(--xp-success-surface)',
19
+ successBg: 'var(--xp-success-bg)',
20
+ success: 'var(--xp-success)',
21
+ successText: 'var(--xp-success-text)',
22
+ successTextStrong: 'var(--xp-success-text-strong)',
23
+ warningSurface: 'var(--xp-warning-surface)',
24
+ warningBg: 'var(--xp-warning-bg)',
25
+ warning: 'var(--xp-warning)',
26
+ warningText: 'var(--xp-warning-text)',
27
+ warningTextStrong: 'var(--xp-warning-text-strong)',
28
+ errorSurface: 'var(--xp-error-surface)',
29
+ error: 'var(--xp-error)',
30
+ errorText: 'var(--xp-error-text)'
31
+ },
32
+ radius: {
33
+ small: 'var(--xp-radius)',
34
+ large: 'var(--xp-radius-large)'
35
+ },
36
+ space: {
37
+ 1: 'var(--xp-space-1)',
38
+ 2: 'var(--xp-space-2)',
39
+ 3: 'var(--xp-space-3)',
40
+ 4: 'var(--xp-space-4)',
41
+ 5: 'var(--xp-space-5)',
42
+ 6: 'var(--xp-space-6)'
43
+ },
44
+ font: {
45
+ body: 'var(--xp-font-body)',
46
+ small: 'var(--xp-font-size-small)',
47
+ size: 'var(--xp-font-size-body)'
48
+ }
49
+ };
@@ -18,7 +18,11 @@ export async function ExperimentsRootView({ initPageResult, params, searchParams
18
18
  let id;
19
19
  if (tail.length === 0) route = 'home';
20
20
  else if (tail.length === 1 && tail[0] === 'new') route = 'new';
21
- else if (tail.length === 1) {
21
+ else if (tail.length === 1 && tail[0] === 'goals') route = 'goals';
22
+ else if (tail.length === 2 && tail[0] === 'goals') {
23
+ route = tail[1] === 'new' ? 'goalNew' : 'goal';
24
+ if (route === 'goal') id = tail[1];
25
+ } else if (tail.length === 1) {
22
26
  route = 'test';
23
27
  id = tail[0];
24
28
  } else if (tail.length === 2 && tail[1] === 'results') {
@@ -41,6 +45,8 @@ export async function ExperimentsRootView({ initPageResult, params, searchParams
41
45
  path: `${login}?redirect=${encodeURIComponent(currentPath)}`
42
46
  }));
43
47
  }
48
+ // Keep the server export importable in plain Node; Next loads the CSS-bearing client boundary when this view renders.
49
+ const { RootViewMessage } = await import('../components/RootViewMessage.js');
44
50
  const options = xpOptionsFromReq(req);
45
51
  async function permits(access) {
46
52
  try {
@@ -60,12 +66,7 @@ export async function ExperimentsRootView({ initPageResult, params, searchParams
60
66
  canManage,
61
67
  canReadResults
62
68
  }) !== 'ok') {
63
- return /*#__PURE__*/ _jsx("div", {
64
- style: {
65
- padding: 'var(--base)',
66
- color: 'var(--theme-text)',
67
- background: 'var(--theme-bg)'
68
- },
69
+ return /*#__PURE__*/ _jsx(RootViewMessage, {
69
70
  children: SURFACE_COPY.noAccess
70
71
  });
71
72
  }
@@ -131,7 +132,11 @@ export async function ExperimentsRootView({ initPageResult, params, searchParams
131
132
  }
132
133
  }))).flat() : undefined;
133
134
  const descriptions = options.admin?.descriptions;
135
+ const returnToTest = (await searchParams)?.return;
134
136
  const clientProps = {
137
+ ...typeof returnToTest === 'string' && /^[\w-]+$/.test(returnToTest) ? {
138
+ returnToTest
139
+ } : {},
135
140
  route,
136
141
  ...id === undefined ? {} : {
137
142
  id
@@ -155,6 +160,12 @@ export async function ExperimentsRootView({ initPageResult, params, searchParams
155
160
  }
156
161
  } : {}
157
162
  };
163
+ function TestsSurfaceFallback() {
164
+ return /*#__PURE__*/ _jsx(RootViewMessage, {
165
+ alert: true,
166
+ children: SURFACE_COPY.notInstalled
167
+ });
168
+ }
158
169
  return RenderServerComponent({
159
170
  Component: XP_TESTS_SURFACE,
160
171
  Fallback: TestsSurfaceFallback,
@@ -162,14 +173,3 @@ export async function ExperimentsRootView({ initPageResult, params, searchParams
162
173
  clientProps
163
174
  });
164
175
  }
165
- function TestsSurfaceFallback() {
166
- return /*#__PURE__*/ _jsx("div", {
167
- role: "alert",
168
- style: {
169
- padding: 'var(--base)',
170
- color: 'var(--theme-text)',
171
- background: 'var(--theme-bg)'
172
- },
173
- children: SURFACE_COPY.notInstalled
174
- });
175
- }
@@ -4,6 +4,7 @@ export function eventsCollection(options) {
4
4
  slug: 'xp-events',
5
5
  graphQL: false,
6
6
  disableDuplicate: true,
7
+ versions: false,
7
8
  admin: {
8
9
  hidden: true
9
10
  },
@@ -4,6 +4,7 @@ export function identitiesCollection(options) {
4
4
  slug: 'xp-identities',
5
5
  graphQL: false,
6
6
  disableDuplicate: true,
7
+ versions: false,
7
8
  admin: {
8
9
  hidden: true
9
10
  },
@@ -12,6 +12,7 @@ export function layersCollection(options) {
12
12
  slug: 'xp-layers',
13
13
  graphQL: false,
14
14
  disableDuplicate: true,
15
+ versions: false,
15
16
  // group:false hides navigation while keeping collection routes reachable (hidden causes 404s).
16
17
  labels: {
17
18
  singular: 'Test group',
@@ -0,0 +1,3 @@
1
+ /** Shared with the goals form; preserve Payload's field validation messages. */
2
+ export declare function validateCappingType(value: unknown, capValue: unknown, sourceKind?: string): true | string;
3
+ export declare function validateCappingValue(value: unknown, type: unknown): true | string;
@@ -0,0 +1,9 @@
1
+ /** Shared with the goals form; preserve Payload's field validation messages. */ export function validateCappingType(value, capValue, sourceKind) {
2
+ const hasCapping = value != null || capValue != null;
3
+ if (hasCapping && sourceKind && sourceKind !== 'revenue') return 'Count and yes-or-no goals cannot use a limit.';
4
+ return !hasCapping || value === 'percentile' || value === 'absolute' || 'Choose how to set the limit.';
5
+ }
6
+ export function validateCappingValue(value, type) {
7
+ if (value == null && !type) return true;
8
+ return typeof value === 'number' && Number.isFinite(value) && value >= 0 && (type === 'absolute' || type === 'percentile' && value > 0 && value <= 1) || 'Enter a valid limit (for past amounts, use a number greater than 0 and at most 1).';
9
+ }
@@ -1,12 +1,14 @@
1
1
  import { XP_METRIC_SOURCE_SELECT } from '../admin/paths.js';
2
2
  import { managedAccess } from './access.js';
3
3
  import { serializeMetricSources } from './serialize.js';
4
+ import { validateCappingType, validateCappingValue } from './metricValidation.js';
4
5
  export function metricsCollection(options) {
5
6
  const sources = serializeMetricSources(options);
6
7
  return {
7
8
  slug: 'xp-metrics',
8
9
  graphQL: false,
9
10
  disableDuplicate: true,
11
+ versions: false,
10
12
  // group:false hides navigation while keeping collection routes reachable (hidden causes 404s).
11
13
  labels: {
12
14
  singular: 'Goal',
@@ -125,10 +127,8 @@ export function metricsCollection(options) {
125
127
  description: 'Choose whether the limit comes from past amounts or a fixed amount.'
126
128
  },
127
129
  validate: (value, { data, siblingData })=>{
128
- const hasCapping = value != null || siblingData?.value != null;
129
130
  const source = sources.find((source)=>source.id === data?.source);
130
- if (hasCapping && source && source.kind !== 'revenue') return 'Count and yes-or-no goals cannot use a limit.';
131
- return !hasCapping || value === 'percentile' || value === 'absolute' || 'Choose how to set the limit.';
131
+ return validateCappingType(value, siblingData?.value, source?.kind);
132
132
  }
133
133
  },
134
134
  {
@@ -140,8 +140,7 @@ export function metricsCollection(options) {
140
140
  description: 'For past amounts, enter how much of the usual range to keep, such as 0.99 to limit only the largest 1%; or enter a fixed amount.'
141
141
  },
142
142
  validate: (value, { siblingData })=>{
143
- if (value == null && !siblingData?.type) return true;
144
- return typeof value === 'number' && Number.isFinite(value) && value >= 0 && (siblingData?.type === 'absolute' || siblingData?.type === 'percentile' && value > 0 && value <= 1) || 'Enter a valid limit (for past amounts, use a number greater than 0 and at most 1).';
143
+ return validateCappingValue(value, siblingData?.type);
145
144
  }
146
145
  }
147
146
  ]
@@ -4,6 +4,7 @@ export function phasesCollection(options) {
4
4
  slug: 'xp-phases',
5
5
  graphQL: false,
6
6
  disableDuplicate: true,
7
+ versions: false,
7
8
  admin: {
8
9
  hidden: true
9
10
  },
@@ -4,6 +4,7 @@ export function snapshotsCollection(options) {
4
4
  slug: 'xp-results-snapshots',
5
5
  graphQL: false,
6
6
  disableDuplicate: true,
7
+ versions: false,
7
8
  admin: {
8
9
  hidden: true
9
10
  },
@@ -3,3 +3,4 @@ export { MetricSourceSelect } from '../admin/MetricSourceSelect.js';
3
3
  export { ArmSelectField } from '../admin/armSelect/ArmSelectField.js';
4
4
  export { TestsNavLink } from '../admin/TestsNavLink.js';
5
5
  export { TestsSurface } from '../admin/surface/TestsSurface.js';
6
+ export { TestsDashboardCards } from '../admin/TestsDashboardCards.js';
@@ -4,3 +4,4 @@ export { MetricSourceSelect } from '../admin/MetricSourceSelect.js';
4
4
  export { ArmSelectField } from '../admin/armSelect/ArmSelectField.js';
5
5
  export { TestsNavLink } from '../admin/TestsNavLink.js';
6
6
  export { TestsSurface } from '../admin/surface/TestsSurface.js';
7
+ export { TestsDashboardCards } from '../admin/TestsDashboardCards.js';
@@ -4,6 +4,7 @@ export function stateGlobal(options) {
4
4
  slug: 'xp-state',
5
5
  dbName: 'xp_state',
6
6
  graphQL: false,
7
+ versions: false,
7
8
  admin: {
8
9
  hidden: true
9
10
  },
package/dist/plugin.js CHANGED
@@ -15,6 +15,8 @@ export function createExperimentsPlugin(input) {
15
15
  // Erase the user subtype only at this non-generic factory boundary.
16
16
  const { collections, globals } = buildCollections(options);
17
17
  const onInit = createOnInit(options);
18
+ const beforeDashboard = config.admin?.components?.beforeDashboard ?? [];
19
+ const beforeNavLinks = config.admin?.components?.beforeNavLinks ?? [];
18
20
  return {
19
21
  ...config,
20
22
  admin: {
@@ -35,8 +37,12 @@ export function createExperimentsPlugin(input) {
35
37
  path: '/experiments/:segments*'
36
38
  }
37
39
  },
38
- afterNavLinks: [
39
- ...config.admin?.components?.afterNavLinks ?? [],
40
+ beforeDashboard: beforeDashboard.includes(paths.XP_TESTS_DASHBOARD_CARDS) ? beforeDashboard : [
41
+ ...beforeDashboard,
42
+ paths.XP_TESTS_DASHBOARD_CARDS
43
+ ],
44
+ beforeNavLinks: beforeNavLinks.includes(paths.XP_TESTS_NAV_LINK) ? beforeNavLinks : [
45
+ ...beforeNavLinks,
40
46
  paths.XP_TESTS_NAV_LINK
41
47
  ]
42
48
  }
@@ -1,4 +1,5 @@
1
1
  import type { ExperimentRef } from '../../types/puck.js';
2
+ import './editor.css';
2
3
  export declare function CreateExperimentDrawer({ onCreate, onClose, initialName }: {
3
4
  initialName?: string;
4
5
  onCreate: (experiment: ExperimentRef) => void;
@@ -3,8 +3,10 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
3
  import { useId, useRef, useState } from 'react';
4
4
  import { CreateRefused, createTest } from './createTest.js';
5
5
  import { editorCopy } from './copy.js';
6
+ import './editor.css';
6
7
  export function CreateExperimentDrawer({ onCreate, onClose, initialName = '' }) {
7
8
  const titleId = useId();
9
+ const nameId = useId();
8
10
  const [name, setName] = useState(initialName);
9
11
  const inFlight = useRef(false);
10
12
  const [pending, setPending] = useState(false);
@@ -30,27 +32,26 @@ export function CreateExperimentDrawer({ onCreate, onClose, initialName = '' })
30
32
  }
31
33
  }
32
34
  return /*#__PURE__*/ _jsxs("aside", {
35
+ className: "xp-slot-root xp-slot-drawer",
33
36
  role: "dialog",
34
37
  "aria-labelledby": titleId,
35
- style: {
36
- padding: 16,
37
- border: '1px solid #aaa',
38
- background: 'Canvas',
39
- color: 'CanvasText'
40
- },
41
38
  children: [
42
39
  /*#__PURE__*/ _jsx("h3", {
40
+ className: "xp-slot-title",
43
41
  id: titleId,
44
42
  children: editorCopy.createLabel
45
43
  }),
46
- /*#__PURE__*/ _jsxs("label", {
47
- style: {
48
- display: 'block',
49
- marginBottom: 8
50
- },
44
+ /*#__PURE__*/ _jsxs("div", {
45
+ className: "xp-slot-field",
51
46
  children: [
52
- editorCopy.name,
47
+ /*#__PURE__*/ _jsx("label", {
48
+ className: "xp-slot-label",
49
+ htmlFor: nameId,
50
+ children: editorCopy.name
51
+ }),
53
52
  /*#__PURE__*/ _jsx("input", {
53
+ className: "xp-slot-input",
54
+ id: nameId,
54
55
  value: name,
55
56
  disabled: pending,
56
57
  onChange: (event)=>setName(event.currentTarget.value)
@@ -58,22 +59,30 @@ export function CreateExperimentDrawer({ onCreate, onClose, initialName = '' })
58
59
  ]
59
60
  }),
60
61
  error ? /*#__PURE__*/ _jsx("p", {
62
+ className: "xp-slot-error",
61
63
  role: "alert",
62
64
  children: error
63
65
  }) : null,
64
- /*#__PURE__*/ _jsx("button", {
65
- type: "button",
66
- disabled: pending || !name.trim(),
67
- onClick: ()=>{
68
- void submitNew();
69
- },
70
- children: pending ? editorCopy.creating : editorCopy.createLabel
71
- }),
72
- /*#__PURE__*/ _jsx("button", {
73
- type: "button",
74
- disabled: pending,
75
- onClick: onClose,
76
- children: editorCopy.cancel
66
+ /*#__PURE__*/ _jsxs("div", {
67
+ className: "xp-slot-actions",
68
+ children: [
69
+ /*#__PURE__*/ _jsx("button", {
70
+ className: "xp-slot-button xp-slot-button-primary",
71
+ type: "button",
72
+ disabled: pending || !name.trim(),
73
+ onClick: ()=>{
74
+ void submitNew();
75
+ },
76
+ children: pending ? editorCopy.creating : editorCopy.createLabel
77
+ }),
78
+ /*#__PURE__*/ _jsx("button", {
79
+ className: "xp-slot-button",
80
+ type: "button",
81
+ disabled: pending,
82
+ onClick: onClose,
83
+ children: editorCopy.cancel
84
+ })
85
+ ]
77
86
  })
78
87
  ]
79
88
  });
@@ -1,3 +1,4 @@
1
1
  import { type ComponentConfig } from '@puckeditor/core';
2
2
  import type { ExperimentSlotProps } from '../../types/puck.js';
3
+ import './editor.css';
3
4
  export declare const ExperimentSlotEditor: ComponentConfig<ExperimentSlotProps>;