@utopia-studio-design/design-system-cli 0.4.1 → 0.5.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.
Files changed (125) hide show
  1. package/README.md +23 -0
  2. package/bin/utopia-ds-mcp.mjs +9 -2
  3. package/bin/utopia-ds.mjs +106 -8
  4. package/data/blocks/activity-feed/ActivityFeedBlock.tsx +255 -0
  5. package/data/blocks/activity-feed/README.md +16 -0
  6. package/data/blocks/activity-feed/activity-feed-contract.ts +96 -0
  7. package/data/blocks/activity-feed/activity-feed-fixture.ts +22 -0
  8. package/data/blocks/activity-feed/activity-feed.css +154 -0
  9. package/data/blocks/agent-status/AgentStatusBlock.tsx +313 -0
  10. package/data/blocks/agent-status/README.md +15 -0
  11. package/data/blocks/agent-status/agent-status-contract.ts +133 -0
  12. package/data/blocks/agent-status/agent-status-fixture.ts +79 -0
  13. package/data/blocks/agent-status/agent-status.css +216 -0
  14. package/data/blocks/analytics-dashboard/AnalyticsDashboardBlocks.tsx +107 -0
  15. package/data/blocks/analytics-dashboard/AnalyticsMetricBlocks.tsx +87 -0
  16. package/data/blocks/analytics-dashboard/README.md +17 -0
  17. package/data/blocks/analytics-dashboard/analytics-dashboard.css +92 -0
  18. package/data/blocks/calendar-application/CalendarApplicationBlocks.tsx +519 -0
  19. package/data/blocks/calendar-application/README.md +20 -0
  20. package/data/blocks/calendar-application/calendar-application.css +216 -0
  21. package/data/blocks/calendar-application/calendar-localization.ts +90 -0
  22. package/data/blocks/calendar-application/calendar-panel-contract.ts +72 -0
  23. package/data/blocks/dashboard-composer/CeramicPuckAdapter.tsx +380 -0
  24. package/data/blocks/dashboard-composer/DashboardComposerBlocks.tsx +337 -0
  25. package/data/blocks/dashboard-composer/README.md +16 -0
  26. package/data/blocks/dashboard-composer/RegistryDataBlocks.tsx +238 -0
  27. package/data/blocks/dashboard-composer/dashboard-composer.css +328 -0
  28. package/data/blocks/database-workspace/DatabaseWorkspaceBlocks.tsx +240 -0
  29. package/data/blocks/database-workspace/README.md +9 -0
  30. package/data/blocks/database-workspace/database-workspace.css +107 -0
  31. package/data/blocks/interaction-workbench/InteractionWorkbench.tsx +271 -0
  32. package/data/blocks/interaction-workbench/README.md +9 -0
  33. package/data/blocks/interaction-workbench/interaction-workbench.css +226 -0
  34. package/data/docs/calendar.md +164 -0
  35. package/data/docs/charts.md +95 -0
  36. package/data/docs/composition-registry.md +174 -0
  37. package/data/docs/dashboard-composer.md +94 -0
  38. package/data/docs/database.md +68 -0
  39. package/data/docs/examples/dashboard-layout.v1.json +65 -0
  40. package/data/docs/foundations.md +1 -1
  41. package/data/docs/interaction-foundation.md +109 -0
  42. package/data/docs/quick-start-ai.md +23 -1
  43. package/data/manifests/blocks.json +392 -0
  44. package/data/manifests/catalog.json +7 -4
  45. package/data/manifests/components.json +179 -0
  46. package/data/manifests/composition-registry.json +427 -0
  47. package/data/manifests/motion-profiles.json +1 -1
  48. package/data/manifests/patterns.json +113 -1
  49. package/data/manifests/templates.json +346 -0
  50. package/data/manifests/theme-renacore.json +142 -0
  51. package/data/manifests/themes.json +314 -28
  52. package/data/templates/analytics-dashboard/AnalyticsDashboardBlocks.tsx +107 -0
  53. package/data/templates/analytics-dashboard/AnalyticsMetricBlocks.tsx +87 -0
  54. package/data/templates/analytics-dashboard/README.md +6 -0
  55. package/data/templates/analytics-dashboard/analytics-dashboard.css +92 -0
  56. package/data/templates/analytics-dashboard/index.html +13 -0
  57. package/data/templates/analytics-dashboard/main.tsx +196 -0
  58. package/data/templates/analytics-dashboard/styles.css +120 -0
  59. package/data/templates/analytics-dashboard/template.manifest.json +17 -0
  60. package/data/templates/calendar-application/CalendarApplicationBlocks.tsx +519 -0
  61. package/data/templates/calendar-application/README.md +10 -0
  62. package/data/templates/calendar-application/calendar-application.css +216 -0
  63. package/data/templates/calendar-application/calendar-localization.ts +90 -0
  64. package/data/templates/calendar-application/index.html +14 -0
  65. package/data/templates/calendar-application/main.tsx +409 -0
  66. package/data/templates/calendar-application/styles.css +248 -0
  67. package/data/templates/calendar-application/template.manifest.json +27 -0
  68. package/data/templates/composition-registry-lab/README.md +9 -0
  69. package/data/templates/composition-registry-lab/index.html +14 -0
  70. package/data/templates/composition-registry-lab/main.tsx +217 -0
  71. package/data/templates/composition-registry-lab/sample-layout.json +63 -0
  72. package/data/templates/composition-registry-lab/styles.css +343 -0
  73. package/data/templates/composition-registry-lab/template.manifest.json +34 -0
  74. package/data/templates/dashboard-composer/ActivityFeedBlock.tsx +255 -0
  75. package/data/templates/dashboard-composer/AgentStatusBlock.tsx +313 -0
  76. package/data/templates/dashboard-composer/AnalyticsDashboardBlocks.tsx +107 -0
  77. package/data/templates/dashboard-composer/AnalyticsMetricBlocks.tsx +87 -0
  78. package/data/templates/dashboard-composer/CalendarApplicationBlocks.tsx +519 -0
  79. package/data/templates/dashboard-composer/CeramicPuckAdapter.tsx +380 -0
  80. package/data/templates/dashboard-composer/DashboardComposerBlocks.tsx +337 -0
  81. package/data/templates/dashboard-composer/DatabaseWorkspaceBlocks.tsx +240 -0
  82. package/data/templates/dashboard-composer/README.md +53 -0
  83. package/data/templates/dashboard-composer/RegistryDataBlocks.tsx +238 -0
  84. package/data/templates/dashboard-composer/activity-feed-contract.ts +96 -0
  85. package/data/templates/dashboard-composer/activity-feed-fixture.ts +22 -0
  86. package/data/templates/dashboard-composer/activity-feed.css +154 -0
  87. package/data/templates/dashboard-composer/agent-status-contract.ts +133 -0
  88. package/data/templates/dashboard-composer/agent-status-fixture.ts +79 -0
  89. package/data/templates/dashboard-composer/agent-status-lab/index.html +19 -0
  90. package/data/templates/dashboard-composer/agent-status-lab/main.tsx +151 -0
  91. package/data/templates/dashboard-composer/agent-status-lab/styles.css +139 -0
  92. package/data/templates/dashboard-composer/agent-status.css +216 -0
  93. package/data/templates/dashboard-composer/analytics-dashboard.css +92 -0
  94. package/data/templates/dashboard-composer/calendar-application.css +216 -0
  95. package/data/templates/dashboard-composer/calendar-localization.ts +90 -0
  96. package/data/templates/dashboard-composer/calendar-panel-contract.ts +72 -0
  97. package/data/templates/dashboard-composer/dashboard-composer.css +328 -0
  98. package/data/templates/dashboard-composer/database-workspace.css +107 -0
  99. package/data/templates/dashboard-composer/index.html +14 -0
  100. package/data/templates/dashboard-composer/main.tsx +550 -0
  101. package/data/templates/dashboard-composer/sample-layout.json +147 -0
  102. package/data/templates/dashboard-composer/styles.css +198 -0
  103. package/data/templates/dashboard-composer/template.manifest.json +34 -0
  104. package/data/templates/dashboard-composer/visual-editor/PuckEditorSurface.tsx +132 -0
  105. package/data/templates/dashboard-composer/visual-editor/VisualEditorApp.tsx +343 -0
  106. package/data/templates/dashboard-composer/visual-editor/index.html +17 -0
  107. package/data/templates/dashboard-composer/visual-editor/main.tsx +95 -0
  108. package/data/templates/dashboard-composer/visual-editor/styles.css +310 -0
  109. package/data/templates/database-workspace/DatabaseWorkspaceBlocks.tsx +240 -0
  110. package/data/templates/database-workspace/README.md +5 -0
  111. package/data/templates/database-workspace/database-workspace.css +107 -0
  112. package/data/templates/database-workspace/index.html +14 -0
  113. package/data/templates/database-workspace/main.tsx +247 -0
  114. package/data/templates/database-workspace/styles.css +121 -0
  115. package/data/templates/database-workspace/template.manifest.json +19 -0
  116. package/data/templates/interaction-lab/InteractionWorkbench.tsx +271 -0
  117. package/data/templates/interaction-lab/README.md +7 -0
  118. package/data/templates/interaction-lab/index.html +14 -0
  119. package/data/templates/interaction-lab/interaction-workbench.css +226 -0
  120. package/data/templates/interaction-lab/main.tsx +104 -0
  121. package/data/templates/interaction-lab/styles.css +224 -0
  122. package/data/templates/interaction-lab/template.manifest.json +36 -0
  123. package/lib/api.mjs +72 -5
  124. package/lib/composition-runtime.mjs +382 -0
  125. package/package.json +4 -1
@@ -0,0 +1,147 @@
1
+ {
2
+ "schemaVersion": 1,
3
+ "id": "personal-workspace",
4
+ "theme": "utopia-default",
5
+ "columns": 12,
6
+ "blocks": [
7
+ {
8
+ "id": "today-tasks",
9
+ "type": "todo-list",
10
+ "version": 1,
11
+ "placement": {
12
+ "column": 1,
13
+ "span": 4,
14
+ "order": 1,
15
+ "compactSpan": 12
16
+ },
17
+ "props": {
18
+ "title": "Today’s priorities",
19
+ "filter": "all",
20
+ "density": "default",
21
+ "showCompleted": true
22
+ },
23
+ "locked": false
24
+ },
25
+ {
26
+ "id": "team-calendar",
27
+ "type": "calendar-panel",
28
+ "version": 1,
29
+ "placement": {
30
+ "column": 5,
31
+ "span": 8,
32
+ "order": 2,
33
+ "compactSpan": 12
34
+ },
35
+ "props": {
36
+ "direction": "inherit",
37
+ "initialScrollHour": 8,
38
+ "locale": "en-US",
39
+ "secondaryCalendar": "none",
40
+ "showAgendaAlternative": false,
41
+ "view": "week",
42
+ "timeZone": "Asia/Seoul"
43
+ },
44
+ "locked": false
45
+ },
46
+ {
47
+ "id": "progress-metrics",
48
+ "type": "metric-grid",
49
+ "version": 1,
50
+ "placement": {
51
+ "column": 1,
52
+ "span": 6,
53
+ "order": 3,
54
+ "compactSpan": 12
55
+ },
56
+ "props": {
57
+ "metrics": ["open", "completed", "focus"],
58
+ "density": "compact",
59
+ "comparison": "previous-period"
60
+ },
61
+ "locked": true
62
+ },
63
+ {
64
+ "id": "workspace-activity",
65
+ "type": "activity-feed",
66
+ "version": 1,
67
+ "placement": {
68
+ "column": 7,
69
+ "span": 6,
70
+ "order": 4,
71
+ "compactSpan": 12
72
+ },
73
+ "props": {
74
+ "density": "default",
75
+ "direction": "inherit",
76
+ "groupBy": "day",
77
+ "locale": "en-US",
78
+ "pageSize": 3,
79
+ "showSources": true,
80
+ "timeZone": "Asia/Seoul"
81
+ },
82
+ "locked": false
83
+ },
84
+ {
85
+ "id": "agent-operations",
86
+ "type": "agent-status",
87
+ "version": 1,
88
+ "placement": {
89
+ "column": 1,
90
+ "span": 12,
91
+ "order": 5,
92
+ "compactSpan": 12
93
+ },
94
+ "props": {
95
+ "density": "default",
96
+ "direction": "inherit",
97
+ "filter": "all",
98
+ "locale": "en-US",
99
+ "maxItems": 4,
100
+ "showApprovals": true,
101
+ "timeZone": "Asia/Seoul"
102
+ },
103
+ "locked": false
104
+ },
105
+ {
106
+ "id": "delivery-issues",
107
+ "type": "issue-table",
108
+ "version": 1,
109
+ "placement": {
110
+ "column": 1,
111
+ "span": 6,
112
+ "order": 6,
113
+ "compactSpan": 12
114
+ },
115
+ "props": {
116
+ "view": "active",
117
+ "density": "compact",
118
+ "columns": ["title", "status", "priority", "owner", "due"]
119
+ },
120
+ "locked": false
121
+ },
122
+ {
123
+ "id": "delivery-throughput",
124
+ "type": "chart-panel",
125
+ "version": 1,
126
+ "placement": {
127
+ "column": 7,
128
+ "span": 6,
129
+ "order": 7,
130
+ "compactSpan": 12
131
+ },
132
+ "props": {
133
+ "chartType": "line",
134
+ "comparison": "previous-period",
135
+ "showTable": false
136
+ },
137
+ "locked": false
138
+ }
139
+ ],
140
+ "regions": [
141
+ {
142
+ "id": "progress-summary",
143
+ "locked": true,
144
+ "blockIds": ["progress-metrics"]
145
+ }
146
+ ]
147
+ }
@@ -0,0 +1,198 @@
1
+ * { box-sizing: border-box; }
2
+ html, body, #root {
3
+ min-block-size: 100%;
4
+ inline-size: 100%;
5
+ max-inline-size: 100%;
6
+ margin: 0;
7
+ }
8
+ html { scrollbar-gutter: stable; }
9
+ html,
10
+ body {
11
+ overflow-x: clip;
12
+ }
13
+ body { background: var(--background); color: var(--foreground); font-family: var(--font-sans); }
14
+ .skip-link { position: fixed; inset-block-start: var(--space-2); inset-inline-start: var(--space-2); z-index: var(--z-modal); translate: 0 -200%; }
15
+ .skip-link:focus { translate: 0; }
16
+
17
+ .dashboard-composer-template {
18
+ min-block-size: 100vh;
19
+ padding: var(--page-gutter);
20
+ background: var(--background);
21
+ color: var(--foreground);
22
+ text-align: start;
23
+ }
24
+
25
+ .dashboard-composer-template > * {
26
+ max-inline-size: var(--container-wide);
27
+ margin-inline: auto;
28
+ }
29
+
30
+ .dashboard-composer-template :is(h1, h2, p) {
31
+ margin: 0;
32
+ }
33
+
34
+ .composer-header,
35
+ .composer-controls,
36
+ .composer-palette {
37
+ display: flex;
38
+ align-items: end;
39
+ justify-content: space-between;
40
+ gap: var(--space-5);
41
+ padding-block: var(--space-5);
42
+ border-block-end: var(--border-width-hairline) solid var(--border);
43
+ }
44
+
45
+ .composer-header > div:first-child,
46
+ .composer-controls > div:first-child,
47
+ .composer-palette > div:first-child {
48
+ display: grid;
49
+ gap: var(--space-2);
50
+ max-inline-size: 52rem;
51
+ }
52
+
53
+ .composer-header > div:last-child,
54
+ .composer-controls > div:nth-child(2),
55
+ .composer-palette > div:last-child {
56
+ display: flex;
57
+ flex-wrap: wrap;
58
+ gap: var(--space-2);
59
+ }
60
+
61
+ .composer-header span,
62
+ .composer-controls > div:first-child > span,
63
+ .composer-palette > div:first-child > span {
64
+ color: var(--muted-foreground);
65
+ font-size: var(--font-size-eyebrow);
66
+ font-weight: var(--font-weight-semibold);
67
+ letter-spacing: var(--tracking-eyebrow);
68
+ text-transform: uppercase;
69
+ }
70
+
71
+ .composer-header p,
72
+ .composer-json p {
73
+ color: var(--muted-foreground);
74
+ line-height: var(--line-height-body);
75
+ }
76
+
77
+ .composer-controls {
78
+ display: grid;
79
+ grid-template-columns: minmax(14rem, .8fr) minmax(22rem, 1.2fr);
80
+ align-items: center;
81
+ }
82
+
83
+ .composer-controls > div:nth-child(2) {
84
+ justify-content: end;
85
+ }
86
+
87
+ .composer-controls output {
88
+ display: flex;
89
+ align-items: center;
90
+ grid-column: 1 / -1;
91
+ gap: var(--space-2);
92
+ min-inline-size: 0;
93
+ padding: var(--space-3);
94
+ border: var(--border-width-hairline) solid var(--interaction-selection-border);
95
+ background: var(--interaction-selection-surface);
96
+ color: var(--foreground);
97
+ }
98
+
99
+ .composer-controls output > span {
100
+ overflow-wrap: anywhere;
101
+ }
102
+
103
+ .composer-palette {
104
+ align-items: center;
105
+ }
106
+
107
+ .dashboard-composer-template > .ceramic-dashboard-renderer {
108
+ padding-block: var(--space-5);
109
+ }
110
+
111
+ .dashboard-composer-template .ceramic-dashboard-block[data-block-type='calendar-panel'] {
112
+ min-block-size: 34rem;
113
+ }
114
+
115
+ .dashboard-composer-template .ceramic-dashboard-block[data-block-type='todo-list'] {
116
+ min-block-size: 34rem;
117
+ }
118
+
119
+ .dashboard-composer-template .ceramic-dashboard-block[data-block-type='activity-feed'] {
120
+ min-block-size: 24rem;
121
+ }
122
+
123
+ .dashboard-composer-template .ceramic-dashboard-block[data-block-type='agent-status'] {
124
+ min-block-size: 30rem;
125
+ }
126
+
127
+ .dashboard-composer-template .ceramic-dashboard-block[data-block-type='issue-table'],
128
+ .dashboard-composer-template .ceramic-dashboard-block[data-block-type='chart-panel'] {
129
+ min-block-size: 34rem;
130
+ }
131
+
132
+ .dashboard-composer-template .ceramic-kpi-grid {
133
+ border: 0;
134
+ }
135
+
136
+ .composer-json {
137
+ margin-block: var(--space-4);
138
+ padding: var(--space-4);
139
+ border: var(--border-width-hairline) solid var(--border);
140
+ background: var(--surface);
141
+ }
142
+
143
+ .composer-json summary {
144
+ cursor: pointer;
145
+ font-weight: var(--font-weight-semibold);
146
+ }
147
+
148
+ .composer-json p {
149
+ margin-block-start: var(--space-2);
150
+ }
151
+
152
+ .composer-json pre {
153
+ max-block-size: 30rem;
154
+ overflow: auto;
155
+ margin-block-end: 0;
156
+ padding: var(--space-3);
157
+ background: var(--background);
158
+ font-size: var(--font-size-small);
159
+ }
160
+
161
+ @media (max-width: 64rem) {
162
+ .dashboard-composer-template .ceramic-dashboard-block[data-block-type='calendar-panel'],
163
+ .dashboard-composer-template .ceramic-dashboard-block[data-block-type='todo-list'] {
164
+ min-block-size: 30rem;
165
+ }
166
+ }
167
+
168
+ @media (max-width: 48rem) {
169
+ .composer-header,
170
+ .composer-palette {
171
+ align-items: stretch;
172
+ flex-direction: column;
173
+ }
174
+
175
+ .composer-header > div:last-child,
176
+ .composer-palette > div:last-child {
177
+ display: grid;
178
+ }
179
+
180
+ .composer-controls {
181
+ grid-template-columns: 1fr;
182
+ align-items: stretch;
183
+ }
184
+
185
+ .composer-controls > div:nth-child(2) {
186
+ display: grid;
187
+ justify-content: stretch;
188
+ }
189
+
190
+ .dashboard-composer-template .ceramic-dashboard-block[data-block-type='calendar-panel'],
191
+ .dashboard-composer-template .ceramic-dashboard-block[data-block-type='todo-list'],
192
+ .dashboard-composer-template .ceramic-dashboard-block[data-block-type='activity-feed'],
193
+ .dashboard-composer-template .ceramic-dashboard-block[data-block-type='agent-status'],
194
+ .dashboard-composer-template .ceramic-dashboard-block[data-block-type='issue-table'],
195
+ .dashboard-composer-template .ceramic-dashboard-block[data-block-type='chart-panel'] {
196
+ min-block-size: auto;
197
+ }
198
+ }
@@ -0,0 +1,34 @@
1
+ {
2
+ "id": "template-dashboard-composer",
3
+ "name": "Dashboard Composer",
4
+ "category": "application-dashboard",
5
+ "status": "available",
6
+ "purpose": "A live Ceramic Layout JSON runtime and optional Puck editing layer for real To-do, Calendar, Issue Table, Chart Panel, Activity Feed, Agent Status, and Metrics blocks.",
7
+ "packageImport": "@utopia-studio-design/design-system/Composition",
8
+ "packageDependencies": {
9
+ "@phosphor-icons/react": "^2.1.10",
10
+ "@puckeditor/core": "^0.22.4"
11
+ },
12
+ "sourcePath": "templates/dashboard-composer/main.tsx",
13
+ "entryPath": "templates/dashboard-composer/index.html",
14
+ "blocks": ["todo-list", "calendar-panel", "issue-table", "chart-panel", "activity-feed", "agent-status", "metric-grid"],
15
+ "features": {
16
+ "layoutRenderer": true,
17
+ "agentMutationValidation": true,
18
+ "humanArrangeControls": true,
19
+ "lockedRegions": true,
20
+ "darkMode": true,
21
+ "rtl": true,
22
+ "responsiveMinimum": "320px",
23
+ "puckAdapter": true,
24
+ "puckVersion": "0.22",
25
+ "selfHostedEditorAssets": true,
26
+ "agentStatusStateLab": true
27
+ },
28
+ "translations": {
29
+ "ar": {
30
+ "name": "مؤلف لوحة المعلومات",
31
+ "purpose": "وقت تشغيل مباشر لتخطيط Ceramic JSON يعرض كتل المهام والتقويم وجدول المشكلات والمخططات والنشاط وحالة الوكلاء والمقاييس الحقيقية ويعيد ترتيبها."
32
+ }
33
+ }
34
+ }
@@ -0,0 +1,132 @@
1
+ import {
2
+ Puck,
3
+ usePuck,
4
+ type Config,
5
+ type Data,
6
+ } from '@puckeditor/core'
7
+ import { useMemo } from 'react'
8
+ import { Button } from '@utopia-studio-design/design-system/Button'
9
+ import '@puckeditor/core/no-external.css'
10
+
11
+ export interface PuckEditorSurfaceProps {
12
+ config: Config
13
+ data: Data
14
+ onChange: (data: Data) => void
15
+ onPublish: (data: Data) => void
16
+ }
17
+
18
+ function CeramicPuckHeader({
19
+ onPublish,
20
+ }: {
21
+ onPublish: (data: Data) => void
22
+ }) {
23
+ const {
24
+ appState,
25
+ dispatch,
26
+ history,
27
+ } = usePuck()
28
+ const { leftSideBarVisible, rightSideBarVisible } = appState.ui
29
+
30
+ const togglePanel = (panel: 'left' | 'right') => {
31
+ const isCompact = window.matchMedia('(max-width: 637px)').matches
32
+ const visible = panel === 'left' ? leftSideBarVisible : rightSideBarVisible
33
+ dispatch({
34
+ type: 'setUi',
35
+ ui: {
36
+ [`${panel}SideBarVisible`]: !visible,
37
+ ...(isCompact
38
+ ? {
39
+ [panel === 'left' ? 'rightSideBarVisible' : 'leftSideBarVisible']: false,
40
+ }
41
+ : {}),
42
+ },
43
+ })
44
+ }
45
+
46
+ return (
47
+ <header className="ceramic-puck-chrome-header">
48
+ <div aria-label="Editor panels" className="ceramic-puck-panel-controls" role="group">
49
+ <Button
50
+ aria-label="Blocks panel"
51
+ aria-pressed={leftSideBarVisible}
52
+ size="sm"
53
+ variant="outline"
54
+ onClick={() => togglePanel('left')}
55
+ >
56
+ Blocks
57
+ </Button>
58
+ <Button
59
+ aria-label="Properties panel"
60
+ aria-pressed={rightSideBarVisible}
61
+ size="sm"
62
+ variant="outline"
63
+ onClick={() => togglePanel('right')}
64
+ >
65
+ Properties
66
+ </Button>
67
+ </div>
68
+
69
+ <h2>
70
+ <span>Ceramic Dashboard</span>
71
+ <code>Dashboard / Personal workspace</code>
72
+ </h2>
73
+
74
+ <div aria-label="Document actions" className="ceramic-puck-document-actions">
75
+ <Button
76
+ aria-label="Undo"
77
+ disabled={!history.hasPast}
78
+ size="sm"
79
+ variant="ghost"
80
+ onClick={history.back}
81
+ >
82
+ Undo
83
+ </Button>
84
+ <Button
85
+ aria-label="Redo"
86
+ disabled={!history.hasFuture}
87
+ size="sm"
88
+ variant="ghost"
89
+ onClick={history.forward}
90
+ >
91
+ Redo
92
+ </Button>
93
+ <Button size="sm" onClick={() => onPublish(appState.data)}>
94
+ Publish
95
+ </Button>
96
+ </div>
97
+ </header>
98
+ )
99
+ }
100
+
101
+ export default function PuckEditorSurface({
102
+ config,
103
+ data,
104
+ onChange,
105
+ onPublish,
106
+ }: PuckEditorSurfaceProps) {
107
+ const overrides = useMemo(
108
+ () => ({
109
+ header: () => <CeramicPuckHeader onPublish={onPublish} />,
110
+ }),
111
+ [onPublish],
112
+ )
113
+
114
+ return (
115
+ <Puck
116
+ config={config}
117
+ data={data}
118
+ height="100%"
119
+ iframe={{ enabled: false }}
120
+ overrides={overrides}
121
+ permissions={{ insert: true }}
122
+ ui={{ rightSideBarVisible: false }}
123
+ viewports={[
124
+ { width: 1280, height: 900, label: 'Desktop' },
125
+ { width: 768, height: 1024, label: 'Tablet' },
126
+ { width: 320, height: 800, label: 'Mobile' },
127
+ ]}
128
+ onChange={onChange}
129
+ onPublish={onPublish}
130
+ />
131
+ )
132
+ }