@wordpress/widget-dashboard 0.2.0 → 0.3.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 (283) hide show
  1. package/CHANGELOG.md +30 -0
  2. package/README.md +29 -16
  3. package/build/components/actions/actions.cjs +6 -23
  4. package/build/components/actions/actions.cjs.map +3 -3
  5. package/build/components/commands/commands.cjs +1 -60
  6. package/build/components/commands/commands.cjs.map +2 -2
  7. package/build/{utils/grid-model-change → components/widget-attribute-controls}/index.cjs +7 -9
  8. package/build/components/widget-attribute-controls/index.cjs.map +7 -0
  9. package/build/components/widget-attribute-controls/widget-attribute-controls.cjs +93 -0
  10. package/build/components/widget-attribute-controls/widget-attribute-controls.cjs.map +7 -0
  11. package/build/components/widget-chrome/widget-chrome.cjs +28 -69
  12. package/build/components/widget-chrome/widget-chrome.cjs.map +2 -2
  13. package/build/components/{layout-settings → widget-frame}/index.cjs +9 -7
  14. package/build/components/widget-frame/index.cjs.map +7 -0
  15. package/build/components/widget-frame/widget-frame.cjs +193 -0
  16. package/build/components/widget-frame/widget-frame.cjs.map +7 -0
  17. package/build/{utils/migrate-layout → components/widget-header}/index.cjs +7 -7
  18. package/build/components/widget-header/index.cjs.map +7 -0
  19. package/build/components/widget-header/widget-header-infotip.cjs +166 -0
  20. package/build/components/widget-header/widget-header-infotip.cjs.map +7 -0
  21. package/build/components/widget-header/widget-header.cjs +176 -0
  22. package/build/components/widget-header/widget-header.cjs.map +7 -0
  23. package/build/components/{widget-settings/utils/get-admin-menu-inset.cjs → widget-layout-controls/index.cjs} +8 -18
  24. package/build/components/widget-layout-controls/index.cjs.map +7 -0
  25. package/build/components/{widgets/widget-layout-toolbar.cjs → widget-layout-controls/widget-layout-controls.cjs} +9 -100
  26. package/build/components/widget-layout-controls/widget-layout-controls.cjs.map +7 -0
  27. package/build/components/widget-picker/widget-picker.cjs +5 -93
  28. package/build/components/widget-picker/widget-picker.cjs.map +3 -3
  29. package/build/components/widget-preview-chrome/index.cjs +31 -0
  30. package/build/components/widget-preview-chrome/index.cjs.map +7 -0
  31. package/build/components/{widget-settings/widget-settings-toolbar.cjs → widget-preview-chrome/widget-preview-chrome.cjs} +41 -23
  32. package/build/components/widget-preview-chrome/widget-preview-chrome.cjs.map +7 -0
  33. package/build/components/widget-settings/index.cjs +3 -3
  34. package/build/components/widget-settings/index.cjs.map +1 -1
  35. package/build/components/widget-settings/utils/index.cjs +0 -3
  36. package/build/components/widget-settings/utils/index.cjs.map +2 -2
  37. package/build/components/widget-settings/widget-settings-trigger.cjs +22 -28
  38. package/build/components/widget-settings/widget-settings-trigger.cjs.map +2 -2
  39. package/build/components/widget-settings/widget-settings.cjs +40 -57
  40. package/build/components/widget-settings/widget-settings.cjs.map +2 -2
  41. package/build/components/widget-toolbar/widget-toolbar.cjs +7 -4
  42. package/build/components/widget-toolbar/widget-toolbar.cjs.map +2 -2
  43. package/build/components/widgets/widget-resize-handle.cjs +4 -4
  44. package/build/components/widgets/widget-resize-handle.cjs.map +2 -2
  45. package/build/components/widgets/widgets.cjs +18 -11
  46. package/build/components/widgets/widgets.cjs.map +2 -2
  47. package/build/context/dashboard-context.cjs +31 -80
  48. package/build/context/dashboard-context.cjs.map +2 -2
  49. package/build/context/ui-context.cjs +2 -18
  50. package/build/context/ui-context.cjs.map +2 -2
  51. package/build/types.cjs.map +1 -1
  52. package/build/utils/index.cjs +2 -5
  53. package/build/utils/index.cjs.map +2 -2
  54. package/build/widget-dashboard.cjs +0 -4
  55. package/build/widget-dashboard.cjs.map +2 -2
  56. package/build-module/components/actions/actions.mjs +7 -24
  57. package/build-module/components/actions/actions.mjs.map +2 -2
  58. package/build-module/components/commands/commands.mjs +2 -67
  59. package/build-module/components/commands/commands.mjs.map +2 -2
  60. package/build-module/components/widget-attribute-controls/index.mjs +6 -0
  61. package/build-module/components/widget-attribute-controls/index.mjs.map +7 -0
  62. package/build-module/components/widget-attribute-controls/widget-attribute-controls.mjs +68 -0
  63. package/build-module/components/widget-attribute-controls/widget-attribute-controls.mjs.map +7 -0
  64. package/build-module/components/widget-chrome/widget-chrome.mjs +29 -76
  65. package/build-module/components/widget-chrome/widget-chrome.mjs.map +2 -2
  66. package/build-module/components/widget-frame/index.mjs +7 -0
  67. package/build-module/components/widget-frame/index.mjs.map +7 -0
  68. package/build-module/components/widget-frame/widget-frame.mjs +157 -0
  69. package/build-module/components/widget-frame/widget-frame.mjs.map +7 -0
  70. package/build-module/components/widget-header/index.mjs +6 -0
  71. package/build-module/components/widget-header/index.mjs.map +7 -0
  72. package/build-module/components/widget-header/widget-header-infotip.mjs +141 -0
  73. package/build-module/components/widget-header/widget-header-infotip.mjs.map +7 -0
  74. package/build-module/components/widget-header/widget-header.mjs +141 -0
  75. package/build-module/components/widget-header/widget-header.mjs.map +7 -0
  76. package/build-module/components/widget-layout-controls/index.mjs +6 -0
  77. package/build-module/components/widget-layout-controls/index.mjs.map +7 -0
  78. package/build-module/components/widget-layout-controls/widget-layout-controls.mjs +90 -0
  79. package/build-module/components/widget-layout-controls/widget-layout-controls.mjs.map +7 -0
  80. package/build-module/components/widget-picker/widget-picker.mjs +6 -94
  81. package/build-module/components/widget-picker/widget-picker.mjs.map +3 -3
  82. package/build-module/components/widget-preview-chrome/index.mjs +6 -0
  83. package/build-module/components/widget-preview-chrome/index.mjs.map +7 -0
  84. package/build-module/components/{widget-settings/widget-settings-toolbar.mjs → widget-preview-chrome/widget-preview-chrome.mjs} +37 -19
  85. package/build-module/components/widget-preview-chrome/widget-preview-chrome.mjs.map +7 -0
  86. package/build-module/components/widget-settings/index.mjs +2 -2
  87. package/build-module/components/widget-settings/index.mjs.map +1 -1
  88. package/build-module/components/widget-settings/utils/index.mjs +0 -2
  89. package/build-module/components/widget-settings/utils/index.mjs.map +2 -2
  90. package/build-module/components/widget-settings/widget-settings-trigger.mjs +23 -29
  91. package/build-module/components/widget-settings/widget-settings-trigger.mjs.map +2 -2
  92. package/build-module/components/widget-settings/widget-settings.mjs +40 -57
  93. package/build-module/components/widget-settings/widget-settings.mjs.map +2 -2
  94. package/build-module/components/widget-toolbar/widget-toolbar.mjs +7 -4
  95. package/build-module/components/widget-toolbar/widget-toolbar.mjs.map +2 -2
  96. package/build-module/components/widgets/widget-resize-handle.mjs +4 -4
  97. package/build-module/components/widgets/widget-resize-handle.mjs.map +2 -2
  98. package/build-module/components/widgets/widgets.mjs +18 -11
  99. package/build-module/components/widgets/widgets.mjs.map +2 -2
  100. package/build-module/context/dashboard-context.mjs +31 -80
  101. package/build-module/context/dashboard-context.mjs.map +2 -2
  102. package/build-module/context/ui-context.mjs +2 -18
  103. package/build-module/context/ui-context.mjs.map +2 -2
  104. package/build-module/types.mjs.map +1 -1
  105. package/build-module/utils/index.mjs +1 -3
  106. package/build-module/utils/index.mjs.map +2 -2
  107. package/build-module/widget-dashboard.mjs +0 -4
  108. package/build-module/widget-dashboard.mjs.map +2 -2
  109. package/build-types/components/actions/actions.d.ts.map +1 -1
  110. package/build-types/components/commands/commands.d.ts.map +1 -1
  111. package/build-types/components/commands/use-pending-when-edit-mode.d.ts +1 -1
  112. package/build-types/components/commands/use-pending-when-edit-mode.d.ts.map +1 -1
  113. package/build-types/components/no-widgets-state/no-widgets-state.d.ts +1 -1
  114. package/build-types/components/no-widgets-state/no-widgets-state.d.ts.map +1 -1
  115. package/build-types/components/widget-attribute-controls/index.d.ts +2 -0
  116. package/build-types/components/widget-attribute-controls/index.d.ts.map +1 -0
  117. package/build-types/components/widget-attribute-controls/widget-attribute-controls.d.ts +23 -0
  118. package/build-types/components/widget-attribute-controls/widget-attribute-controls.d.ts.map +1 -0
  119. package/build-types/components/widget-chrome/widget-chrome.d.ts +8 -8
  120. package/build-types/components/widget-chrome/widget-chrome.d.ts.map +1 -1
  121. package/build-types/components/widget-frame/index.d.ts +3 -0
  122. package/build-types/components/widget-frame/index.d.ts.map +1 -0
  123. package/build-types/components/widget-frame/widget-frame.d.ts +25 -0
  124. package/build-types/components/widget-frame/widget-frame.d.ts.map +1 -0
  125. package/build-types/components/widget-header/index.d.ts +3 -0
  126. package/build-types/components/widget-header/index.d.ts.map +1 -0
  127. package/build-types/components/widget-header/widget-header-infotip.d.ts +20 -0
  128. package/build-types/components/widget-header/widget-header-infotip.d.ts.map +1 -0
  129. package/build-types/components/widget-header/widget-header.d.ts +38 -0
  130. package/build-types/components/widget-header/widget-header.d.ts.map +1 -0
  131. package/build-types/components/widget-layout-controls/index.d.ts +3 -0
  132. package/build-types/components/widget-layout-controls/index.d.ts.map +1 -0
  133. package/build-types/components/widget-layout-controls/widget-layout-controls.d.ts +14 -0
  134. package/build-types/components/widget-layout-controls/widget-layout-controls.d.ts.map +1 -0
  135. package/build-types/components/widget-picker/widget-picker.d.ts +1 -1
  136. package/build-types/components/widget-picker/widget-picker.d.ts.map +1 -1
  137. package/build-types/components/widget-preview-chrome/index.d.ts +3 -0
  138. package/build-types/components/widget-preview-chrome/index.d.ts.map +1 -0
  139. package/build-types/components/widget-preview-chrome/widget-preview-chrome.d.ts +15 -0
  140. package/build-types/components/widget-preview-chrome/widget-preview-chrome.d.ts.map +1 -0
  141. package/build-types/components/widget-settings/index.d.ts +2 -2
  142. package/build-types/components/widget-settings/utils/index.d.ts +0 -1
  143. package/build-types/components/widget-settings/utils/index.d.ts.map +1 -1
  144. package/build-types/components/widget-settings/widget-settings-trigger.d.ts +7 -5
  145. package/build-types/components/widget-settings/widget-settings-trigger.d.ts.map +1 -1
  146. package/build-types/components/widget-settings/widget-settings.d.ts +5 -4
  147. package/build-types/components/widget-settings/widget-settings.d.ts.map +1 -1
  148. package/build-types/components/widget-toolbar/widget-toolbar.d.ts +10 -7
  149. package/build-types/components/widget-toolbar/widget-toolbar.d.ts.map +1 -1
  150. package/build-types/components/widgets/widgets.d.ts.map +1 -1
  151. package/build-types/context/dashboard-context.d.ts +23 -40
  152. package/build-types/context/dashboard-context.d.ts.map +1 -1
  153. package/build-types/context/ui-context.d.ts +0 -18
  154. package/build-types/context/ui-context.d.ts.map +1 -1
  155. package/build-types/context/widget-context.d.ts +1 -1
  156. package/build-types/context/widget-context.d.ts.map +1 -1
  157. package/build-types/types.d.ts +9 -15
  158. package/build-types/types.d.ts.map +1 -1
  159. package/build-types/utils/index.d.ts +0 -1
  160. package/build-types/utils/index.d.ts.map +1 -1
  161. package/build-types/widget-dashboard.d.ts +5 -5
  162. package/build-types/widget-dashboard.d.ts.map +1 -1
  163. package/package.json +20 -20
  164. package/src/components/actions/actions.module.css +7 -7
  165. package/src/components/actions/actions.tsx +5 -25
  166. package/src/components/commands/commands.tsx +3 -70
  167. package/src/components/widget-attribute-controls/index.ts +1 -0
  168. package/src/components/widget-attribute-controls/widget-attribute-controls.tsx +108 -0
  169. package/src/components/widget-chrome/widget-chrome.module.css +6 -71
  170. package/src/components/widget-chrome/widget-chrome.tsx +31 -136
  171. package/src/components/widget-frame/index.ts +2 -0
  172. package/src/components/widget-frame/widget-frame.module.css +17 -0
  173. package/src/components/widget-frame/widget-frame.tsx +138 -0
  174. package/src/components/widget-header/index.ts +2 -0
  175. package/src/components/widget-header/widget-header-infotip.tsx +82 -0
  176. package/src/components/widget-header/widget-header.module.css +59 -0
  177. package/src/components/widget-header/widget-header.tsx +104 -0
  178. package/src/components/widget-layout-controls/index.ts +2 -0
  179. package/src/components/{widgets/widget-layout-toolbar.tsx → widget-layout-controls/widget-layout-controls.tsx} +12 -13
  180. package/src/components/widget-picker/widget-picker.tsx +5 -10
  181. package/src/components/widget-preview-chrome/index.ts +2 -0
  182. package/src/components/widget-preview-chrome/widget-preview-chrome.module.css +22 -0
  183. package/src/components/widget-preview-chrome/widget-preview-chrome.tsx +65 -0
  184. package/src/components/widget-settings/index.ts +2 -2
  185. package/src/components/widget-settings/utils/index.ts +0 -1
  186. package/src/components/widget-settings/widget-settings-trigger.tsx +39 -44
  187. package/src/components/widget-settings/widget-settings.tsx +10 -28
  188. package/src/components/widget-toolbar/widget-toolbar.module.css +13 -10
  189. package/src/components/widget-toolbar/widget-toolbar.tsx +14 -8
  190. package/src/components/widgets/widget-resize-handle.module.css +21 -21
  191. package/src/components/widgets/widget-resize-handle.tsx +2 -2
  192. package/src/components/widgets/widgets.module.css +20 -11
  193. package/src/components/widgets/widgets.tsx +33 -10
  194. package/src/context/dashboard-context.tsx +70 -133
  195. package/src/context/ui-context.tsx +1 -39
  196. package/src/test/actions.test.tsx +7 -77
  197. package/src/test/commands.test.tsx +6 -45
  198. package/src/test/staging.test.tsx +82 -144
  199. package/src/test/widget-dashboard.test.tsx +24 -0
  200. package/src/types.ts +9 -16
  201. package/src/utils/index.ts +0 -1
  202. package/src/widget-dashboard.tsx +4 -8
  203. package/build/components/layout-settings/index.cjs.map +0 -7
  204. package/build/components/layout-settings/layout-model-edit-field/index.cjs +0 -186
  205. package/build/components/layout-settings/layout-model-edit-field/index.cjs.map +0 -7
  206. package/build/components/layout-settings/layout-model-edit-field/thumbnail-grid.cjs +0 -53
  207. package/build/components/layout-settings/layout-model-edit-field/thumbnail-grid.cjs.map +0 -7
  208. package/build/components/layout-settings/layout-model-edit-field/thumbnail-masonry.cjs +0 -53
  209. package/build/components/layout-settings/layout-model-edit-field/thumbnail-masonry.cjs.map +0 -7
  210. package/build/components/layout-settings/layout-settings.cjs +0 -207
  211. package/build/components/layout-settings/layout-settings.cjs.map +0 -7
  212. package/build/components/widget-settings/utils/get-admin-menu-inset.cjs.map +0 -7
  213. package/build/components/widget-settings/widget-settings-toolbar.cjs.map +0 -7
  214. package/build/components/widgets/widget-layout-toolbar.cjs.map +0 -7
  215. package/build/utils/grid-model-change/grid-model-change.cjs +0 -56
  216. package/build/utils/grid-model-change/grid-model-change.cjs.map +0 -7
  217. package/build/utils/grid-model-change/index.cjs.map +0 -7
  218. package/build/utils/migrate-layout/index.cjs.map +0 -7
  219. package/build/utils/migrate-layout/migrate-layout.cjs +0 -94
  220. package/build/utils/migrate-layout/migrate-layout.cjs.map +0 -7
  221. package/build-module/components/layout-settings/index.mjs +0 -6
  222. package/build-module/components/layout-settings/index.mjs.map +0 -7
  223. package/build-module/components/layout-settings/layout-model-edit-field/index.mjs +0 -151
  224. package/build-module/components/layout-settings/layout-model-edit-field/index.mjs.map +0 -7
  225. package/build-module/components/layout-settings/layout-model-edit-field/thumbnail-grid.mjs +0 -28
  226. package/build-module/components/layout-settings/layout-model-edit-field/thumbnail-grid.mjs.map +0 -7
  227. package/build-module/components/layout-settings/layout-model-edit-field/thumbnail-masonry.mjs +0 -28
  228. package/build-module/components/layout-settings/layout-model-edit-field/thumbnail-masonry.mjs.map +0 -7
  229. package/build-module/components/layout-settings/layout-settings.mjs +0 -187
  230. package/build-module/components/layout-settings/layout-settings.mjs.map +0 -7
  231. package/build-module/components/widget-settings/utils/get-admin-menu-inset.mjs +0 -16
  232. package/build-module/components/widget-settings/utils/get-admin-menu-inset.mjs.map +0 -7
  233. package/build-module/components/widget-settings/widget-settings-toolbar.mjs.map +0 -7
  234. package/build-module/components/widgets/widget-layout-toolbar.mjs +0 -181
  235. package/build-module/components/widgets/widget-layout-toolbar.mjs.map +0 -7
  236. package/build-module/utils/grid-model-change/grid-model-change.mjs +0 -30
  237. package/build-module/utils/grid-model-change/grid-model-change.mjs.map +0 -7
  238. package/build-module/utils/grid-model-change/index.mjs +0 -7
  239. package/build-module/utils/grid-model-change/index.mjs.map +0 -7
  240. package/build-module/utils/migrate-layout/index.mjs +0 -6
  241. package/build-module/utils/migrate-layout/index.mjs.map +0 -7
  242. package/build-module/utils/migrate-layout/migrate-layout.mjs +0 -69
  243. package/build-module/utils/migrate-layout/migrate-layout.mjs.map +0 -7
  244. package/build-types/components/layout-settings/index.d.ts +0 -2
  245. package/build-types/components/layout-settings/index.d.ts.map +0 -1
  246. package/build-types/components/layout-settings/layout-model-edit-field/index.d.ts +0 -17
  247. package/build-types/components/layout-settings/layout-model-edit-field/index.d.ts.map +0 -1
  248. package/build-types/components/layout-settings/layout-model-edit-field/thumbnail-grid.d.ts +0 -6
  249. package/build-types/components/layout-settings/layout-model-edit-field/thumbnail-grid.d.ts.map +0 -1
  250. package/build-types/components/layout-settings/layout-model-edit-field/thumbnail-masonry.d.ts +0 -6
  251. package/build-types/components/layout-settings/layout-model-edit-field/thumbnail-masonry.d.ts.map +0 -1
  252. package/build-types/components/layout-settings/layout-settings.d.ts +0 -14
  253. package/build-types/components/layout-settings/layout-settings.d.ts.map +0 -1
  254. package/build-types/components/widget-settings/utils/get-admin-menu-inset.d.ts +0 -17
  255. package/build-types/components/widget-settings/utils/get-admin-menu-inset.d.ts.map +0 -1
  256. package/build-types/components/widget-settings/widget-settings-toolbar.d.ts +0 -20
  257. package/build-types/components/widget-settings/widget-settings-toolbar.d.ts.map +0 -1
  258. package/build-types/components/widgets/widget-layout-toolbar.d.ts +0 -14
  259. package/build-types/components/widgets/widget-layout-toolbar.d.ts.map +0 -1
  260. package/build-types/utils/grid-model-change/grid-model-change.d.ts +0 -20
  261. package/build-types/utils/grid-model-change/grid-model-change.d.ts.map +0 -1
  262. package/build-types/utils/grid-model-change/index.d.ts +0 -2
  263. package/build-types/utils/grid-model-change/index.d.ts.map +0 -1
  264. package/build-types/utils/migrate-layout/index.d.ts +0 -2
  265. package/build-types/utils/migrate-layout/index.d.ts.map +0 -1
  266. package/build-types/utils/migrate-layout/migrate-layout.d.ts +0 -36
  267. package/build-types/utils/migrate-layout/migrate-layout.d.ts.map +0 -1
  268. package/src/components/layout-settings/index.ts +0 -1
  269. package/src/components/layout-settings/layout-model-edit-field/index.tsx +0 -98
  270. package/src/components/layout-settings/layout-model-edit-field/style.module.css +0 -34
  271. package/src/components/layout-settings/layout-model-edit-field/thumbnail-grid.tsx +0 -28
  272. package/src/components/layout-settings/layout-model-edit-field/thumbnail-masonry.tsx +0 -28
  273. package/src/components/layout-settings/layout-settings.tsx +0 -217
  274. package/src/components/widget-picker/widget-picker.module.css +0 -11
  275. package/src/components/widget-settings/utils/get-admin-menu-inset.ts +0 -30
  276. package/src/components/widget-settings/widget-settings-toolbar.module.css +0 -25
  277. package/src/components/widget-settings/widget-settings-toolbar.tsx +0 -45
  278. package/src/components/widgets/widget-layout-toolbar.module.css +0 -6
  279. package/src/utils/grid-model-change/grid-model-change.ts +0 -53
  280. package/src/utils/grid-model-change/index.ts +0 -1
  281. package/src/utils/migrate-layout/index.ts +0 -1
  282. package/src/utils/migrate-layout/migrate-layout.ts +0 -156
  283. package/src/utils/migrate-layout/test/migrate-layout.test.ts +0 -114
@@ -0,0 +1,138 @@
1
+ /**
2
+ * External dependencies
3
+ */
4
+ import clsx from 'clsx';
5
+ import type { ReactNode } from 'react';
6
+
7
+ /**
8
+ * WordPress dependencies
9
+ */
10
+ import { Spinner } from '@wordpress/components';
11
+ import { Component, Suspense } from '@wordpress/element';
12
+ import { __ } from '@wordpress/i18n';
13
+ // eslint-disable-next-line @wordpress/use-recommended-components
14
+ import { Card, Notice, Stack, VisuallyHidden } from '@wordpress/ui';
15
+ import type { WidgetType } from '@wordpress/widget-primitives';
16
+
17
+ /**
18
+ * Internal dependencies
19
+ */
20
+ import { WidgetHeader } from '../widget-header';
21
+ import { WidgetRender } from '../widget-render';
22
+ import styles from './widget-frame.module.css';
23
+ import type { DashboardWidget } from '../../types';
24
+
25
+ interface ErrorBoundaryProps {
26
+ children: ReactNode;
27
+ }
28
+
29
+ interface ErrorBoundaryState {
30
+ hasError: boolean;
31
+ }
32
+
33
+ class WidgetErrorBoundary extends Component<
34
+ ErrorBoundaryProps,
35
+ ErrorBoundaryState
36
+ > {
37
+ state: ErrorBoundaryState = { hasError: false };
38
+
39
+ static getDerivedStateFromError(): ErrorBoundaryState {
40
+ return { hasError: true };
41
+ }
42
+
43
+ render() {
44
+ if ( this.state.hasError ) {
45
+ return (
46
+ <Notice.Root intent="error">
47
+ <Notice.Description>
48
+ { __( 'This widget encountered an error.' ) }
49
+ </Notice.Description>
50
+ </Notice.Root>
51
+ );
52
+ }
53
+ return this.props.children;
54
+ }
55
+ }
56
+
57
+ /* Centered spinner for resolving and Suspense waits. */
58
+ export function LoadingOverlay() {
59
+ return (
60
+ <Stack justify="center" align="center" className={ styles.loading }>
61
+ <Spinner />
62
+ </Stack>
63
+ );
64
+ }
65
+
66
+ export interface WidgetFrameProps {
67
+ widget: DashboardWidget< unknown >;
68
+ widgetType: WidgetType;
69
+ titleId: string;
70
+
71
+ /**
72
+ * Inert the body and identity while customizing.
73
+ */
74
+ editMode?: boolean;
75
+
76
+ /**
77
+ * Toolbar shown beside the identity in the in-card header.
78
+ */
79
+ headerToolbar?: ReactNode;
80
+ }
81
+
82
+ /**
83
+ * Shared framing: `presentation` into header + content, with the error/loading
84
+ * boundaries. Hosts supply the `Card.Root` and their own concerns.
85
+ *
86
+ * @param {WidgetFrameProps} props Component props.
87
+ */
88
+ export function WidgetFrame( {
89
+ widget,
90
+ widgetType,
91
+ titleId,
92
+ editMode = false,
93
+ headerToolbar,
94
+ }: WidgetFrameProps ) {
95
+ // full-bleed hides the header; full-bleed and content-bleed bleed the body.
96
+ const { presentation } = widgetType;
97
+ const isHeaderHidden = presentation === 'full-bleed';
98
+ const isBodyBleeding =
99
+ presentation === 'full-bleed' || presentation === 'content-bleed';
100
+
101
+ const body = (
102
+ <WidgetErrorBoundary>
103
+ <Suspense fallback={ <LoadingOverlay /> }>
104
+ <WidgetRender widget={ widget } widgetType={ widgetType } />
105
+ </Suspense>
106
+ </WidgetErrorBoundary>
107
+ );
108
+
109
+ return (
110
+ <>
111
+ { ! isHeaderHidden && (
112
+ <WidgetHeader
113
+ showIdentity
114
+ widgetType={ widgetType }
115
+ titleId={ titleId }
116
+ editMode={ editMode }
117
+ >
118
+ { headerToolbar }
119
+ </WidgetHeader>
120
+ ) }
121
+
122
+ <Card.Content
123
+ className={ clsx(
124
+ styles.content,
125
+ isBodyBleeding && styles[ 'bleed-content' ]
126
+ ) }
127
+ { ...( editMode ? { inert: 'true' } : {} ) }
128
+ >
129
+ { isHeaderHidden && widgetType.title && (
130
+ <VisuallyHidden render={ <h2 id={ titleId } /> }>
131
+ { widgetType.title }
132
+ </VisuallyHidden>
133
+ ) }
134
+ { body }
135
+ </Card.Content>
136
+ </>
137
+ );
138
+ }
@@ -0,0 +1,2 @@
1
+ export { WidgetHeader } from './widget-header';
2
+ export type { WidgetHeaderProps } from './widget-header';
@@ -0,0 +1,82 @@
1
+ /**
2
+ * WordPress dependencies
3
+ */
4
+ import { createInterpolateElement } from '@wordpress/element';
5
+ import { __ } from '@wordpress/i18n';
6
+ import { info } from '@wordpress/icons';
7
+ // eslint-disable-next-line @wordpress/use-recommended-components
8
+ import { Icon, Link, Popover, Stack, VisuallyHidden } from '@wordpress/ui';
9
+
10
+ /**
11
+ * Internal dependencies
12
+ */
13
+ import styles from './widget-header.module.css';
14
+
15
+ export interface WidgetInfotipProps {
16
+ /**
17
+ * Help content to display; may carry `<em>`/`<strong>`.
18
+ */
19
+ content: string;
20
+
21
+ /**
22
+ * Links rendered after the content.
23
+ */
24
+ links?: {
25
+ label: string;
26
+ href: string;
27
+ }[];
28
+ }
29
+
30
+ /**
31
+ * Header infotip: a click-open popover holding the widget type's help note.
32
+ *
33
+ * @param {WidgetInfotipProps} props Component props.
34
+ */
35
+ export function WidgetInfotip( {
36
+ content,
37
+ links,
38
+ }: WidgetInfotipProps ): React.ReactNode {
39
+ return (
40
+ <Popover.Root modal="trap-focus">
41
+ <Popover.Trigger
42
+ aria-label={ __( 'More information' ) }
43
+ className={ styles.help }
44
+ >
45
+ <Icon icon={ info } size={ 20 } />
46
+ </Popover.Trigger>
47
+
48
+ <Popover.Popup
49
+ className={ styles[ 'popover-popup' ] }
50
+ positioner={ <Popover.Positioner side="top" align="start" /> }
51
+ >
52
+ <Popover.Arrow />
53
+ <VisuallyHidden render={ <Popover.Title /> }>
54
+ { __( 'More information' ) }
55
+ </VisuallyHidden>
56
+
57
+ <Stack direction="column" align="start" gap="sm">
58
+ <Popover.Description>
59
+ { createInterpolateElement( content, {
60
+ em: <em />,
61
+ strong: <strong />,
62
+ } ) }
63
+ </Popover.Description>
64
+
65
+ { links && links.length > 0 && (
66
+ <Stack direction="row" align="start" gap="sm">
67
+ { links.map( ( link ) => (
68
+ <Link
69
+ key={ link.href }
70
+ href={ link.href }
71
+ className={ styles.link }
72
+ >
73
+ { link.label }
74
+ </Link>
75
+ ) ) }
76
+ </Stack>
77
+ ) }
78
+ </Stack>
79
+ </Popover.Popup>
80
+ </Popover.Root>
81
+ );
82
+ }
@@ -0,0 +1,59 @@
1
+ /* Tile header row: identity leads, toolbar trails. */
2
+ .widget-header {
3
+ display: flex;
4
+ align-items: center;
5
+ gap: var(--wpds-dimension-gap-sm);
6
+ }
7
+
8
+ .identity,
9
+ .toolbar {
10
+ display: flex;
11
+ align-items: center;
12
+ height: var(--wpds-dimension-size-lg);
13
+ }
14
+
15
+ .identity {
16
+ min-width: 0;
17
+ }
18
+
19
+ .icon {
20
+ display: inline-flex;
21
+ color: var(--wpds-color-foreground-content-neutral);
22
+ }
23
+
24
+ .popover-popup {
25
+ max-width: 300px;
26
+ }
27
+
28
+ .help {
29
+ display: inline-flex;
30
+ align-items: center;
31
+ padding: 0;
32
+ border: 0;
33
+ background: none;
34
+ color: var(--wpds-color-foreground-content-neutral-weak);
35
+ cursor: var(--wpds-cursor-control);
36
+ }
37
+
38
+ .link + .link {
39
+ border-inline-start: var(--wpds-border-width-xs) solid var(--wpds-color-stroke-surface-neutral);
40
+ padding-inline-start: var(--wpds-dimension-gap-sm);
41
+ }
42
+
43
+ .toolbar {
44
+ margin-inline-start: auto;
45
+ }
46
+
47
+ /* Floats over the tile; re-declares card padding outside Card.Root. */
48
+ .overlay {
49
+ position: absolute;
50
+ inset-block-start: 0;
51
+ inset-inline: 0;
52
+ z-index: 1;
53
+ pointer-events: none;
54
+ --wp-ui-card-padding: var(--wpds-dimension-padding-2xl);
55
+ }
56
+
57
+ .overlay .toolbar {
58
+ pointer-events: auto;
59
+ }
@@ -0,0 +1,104 @@
1
+ /**
2
+ * External dependencies
3
+ */
4
+ import clsx from 'clsx';
5
+ import type { ReactNode } from 'react';
6
+
7
+ /**
8
+ * WordPress dependencies
9
+ */
10
+ import { Card, Icon, Stack } from '@wordpress/ui';
11
+ import type { WidgetType } from '@wordpress/widget-primitives';
12
+
13
+ /**
14
+ * Internal dependencies
15
+ */
16
+ import { WidgetInfotip } from './widget-header-infotip';
17
+ import styles from './widget-header.module.css';
18
+
19
+ export interface WidgetHeaderProps {
20
+ /**
21
+ * Widget type, source of the icon, title, and help note shown as
22
+ * identity.
23
+ */
24
+ widgetType?: WidgetType;
25
+
26
+ /**
27
+ * Id linking the title to the tile's labelled region.
28
+ */
29
+ titleId?: string;
30
+
31
+ /**
32
+ * Render the icon + title cluster on the leading edge.
33
+ */
34
+ showIdentity?: boolean;
35
+
36
+ /**
37
+ * Float over the tile instead of sitting in the card flow.
38
+ */
39
+ overlay?: boolean;
40
+
41
+ /**
42
+ * Inert the identity while customizing, so it does not capture interaction.
43
+ */
44
+ editMode?: boolean;
45
+
46
+ /**
47
+ * Toolbar placed on the trailing edge.
48
+ */
49
+ children?: ReactNode;
50
+ }
51
+
52
+ /**
53
+ * Tile header row: identity (icon + title) and a toolbar on one line. Rendered
54
+ * in the card flow, or as an `overlay` in the grid slot for full-bleed widgets
55
+ * that have no in-card header.
56
+ *
57
+ * @param {WidgetHeaderProps} props Component props.
58
+ */
59
+ export function WidgetHeader( {
60
+ widgetType,
61
+ titleId,
62
+ showIdentity = false,
63
+ overlay = false,
64
+ editMode = false,
65
+ children,
66
+ }: WidgetHeaderProps ): React.ReactNode {
67
+ return (
68
+ <Card.Header
69
+ className={ clsx(
70
+ styles[ 'widget-header' ],
71
+ overlay && styles.overlay
72
+ ) }
73
+ >
74
+ { showIdentity && widgetType?.title && (
75
+ <Stack
76
+ direction="row"
77
+ align="center"
78
+ gap="sm"
79
+ className={ styles.identity }
80
+ { ...( editMode ? { inert: 'true' } : {} ) }
81
+ >
82
+ { widgetType.icon && (
83
+ <span className={ styles.icon } aria-hidden="true">
84
+ <Icon icon={ widgetType.icon } />
85
+ </span>
86
+ ) }
87
+
88
+ <Card.Title id={ titleId } render={ <h2 /> }>
89
+ { widgetType.title }
90
+ </Card.Title>
91
+
92
+ { widgetType.help && (
93
+ <WidgetInfotip
94
+ content={ widgetType.help.content }
95
+ links={ widgetType.help.links }
96
+ />
97
+ ) }
98
+ </Stack>
99
+ ) }
100
+
101
+ { children && <div className={ styles.toolbar }>{ children }</div> }
102
+ </Card.Header>
103
+ );
104
+ }
@@ -0,0 +1,2 @@
1
+ export { WidgetLayoutControls } from './widget-layout-controls';
2
+ export type { WidgetLayoutControlsProps } from './widget-layout-controls';
@@ -4,7 +4,6 @@
4
4
  import { privateApis as componentsPrivateApis } from '@wordpress/components';
5
5
  import { __ } from '@wordpress/i18n';
6
6
  import { moreVertical, trash } from '@wordpress/icons';
7
- // Dashboard is still experimental.
8
7
  // eslint-disable-next-line @wordpress/use-recommended-components
9
8
  import { IconButton } from '@wordpress/ui';
10
9
 
@@ -13,8 +12,6 @@ import { IconButton } from '@wordpress/ui';
13
12
  */
14
13
  import { unlock } from '../../lock-unlock';
15
14
  import { useDashboardInternalContext } from '../../context/dashboard-context';
16
- import { WidgetToolbar } from '../widget-toolbar';
17
- import styles from './widget-layout-toolbar.module.css';
18
15
  import type { DashboardWidget, GridTilePlacement } from '../../types';
19
16
 
20
17
  const { Menu } = unlock( componentsPrivateApis );
@@ -24,21 +21,21 @@ type NamedGridWidth = Exclude<
24
21
  number
25
22
  >;
26
23
 
27
- export interface WidgetLayoutToolbarProps {
28
- /** The instance this toolbar manages within the layout. */
24
+ export interface WidgetLayoutControlsProps {
25
+ /**
26
+ * The instance these controls manage within the layout.
27
+ */
29
28
  widget: DashboardWidget< unknown >;
30
29
  }
31
30
 
32
31
  /**
33
- * Customize-mode per-tile toolbar: a width menu and removal, editing the
34
- * widget's place in the layout. Lives in the grid's `actionableArea` slot, so
35
- * it stays interactive while the card is `inert`.
32
+ * Customize-mode controls: width menu and removal.
36
33
  *
37
- * @param {WidgetLayoutToolbarProps} props Component props.
34
+ * @param {WidgetLayoutControlsProps} props Component props.
38
35
  */
39
- export function WidgetLayoutToolbar( {
36
+ export function WidgetLayoutControls( {
40
37
  widget,
41
- }: WidgetLayoutToolbarProps ): React.ReactNode {
38
+ }: WidgetLayoutControlsProps ): React.ReactNode {
42
39
  const { layout, onLayoutChange } = useDashboardInternalContext();
43
40
  const width = widget.placement?.width;
44
41
 
@@ -70,7 +67,7 @@ export function WidgetLayoutToolbar( {
70
67
  };
71
68
 
72
69
  return (
73
- <WidgetToolbar className={ styles.widgetLayoutToolbar }>
70
+ <>
74
71
  <Menu>
75
72
  <Menu.TriggerButton
76
73
  render={
@@ -83,6 +80,7 @@ export function WidgetLayoutToolbar( {
83
80
  />
84
81
  }
85
82
  />
83
+
86
84
  <Menu.Popover>
87
85
  <Menu.Group>
88
86
  <Menu.GroupLabel>{ __( 'Width' ) }</Menu.GroupLabel>
@@ -105,6 +103,7 @@ export function WidgetLayoutToolbar( {
105
103
  </Menu.Group>
106
104
  </Menu.Popover>
107
105
  </Menu>
106
+
108
107
  <IconButton
109
108
  icon={ trash }
110
109
  label={ __( 'Remove' ) }
@@ -113,6 +112,6 @@ export function WidgetLayoutToolbar( {
113
112
  tone="neutral"
114
113
  onClick={ onRemove }
115
114
  />
116
- </WidgetToolbar>
115
+ </>
117
116
  );
118
117
  }
@@ -3,7 +3,7 @@
3
3
  */
4
4
  import { DataViewsPicker, filterSortAndPaginate } from '@wordpress/dataviews';
5
5
  import type { Field, View } from '@wordpress/dataviews';
6
- import { Suspense, useMemo, useState } from '@wordpress/element';
6
+ import { useMemo, useState } from '@wordpress/element';
7
7
  import { __ } from '@wordpress/i18n';
8
8
  import type { WidgetType } from '@wordpress/widget-primitives';
9
9
 
@@ -12,8 +12,7 @@ import type { WidgetType } from '@wordpress/widget-primitives';
12
12
  */
13
13
  import { useDashboardInternalContext } from '../../context/dashboard-context';
14
14
  import { createDashboardWidget } from '../../utils/create-dashboard-widget';
15
- import { WidgetRender } from '../widget-render';
16
- import styles from './widget-picker.module.css';
15
+ import { WidgetPreviewChrome } from '../widget-preview-chrome';
17
16
 
18
17
  const DEFAULT_VIEW: View = {
19
18
  type: 'pickerGrid',
@@ -21,6 +20,8 @@ const DEFAULT_VIEW: View = {
21
20
  search: '',
22
21
  mediaField: 'preview',
23
22
  titleField: 'title',
23
+ // Larger default tile than the built-in 230.
24
+ layout: { previewSize: 290 },
24
25
  };
25
26
 
26
27
  const getItemId = ( item: WidgetType ) => item.name;
@@ -31,13 +32,7 @@ function WidgetPreview( { item }: { item: WidgetType } ) {
31
32
  [ item ]
32
33
  );
33
34
 
34
- return (
35
- <div className={ styles.preview } { ...{ inert: '' } }>
36
- <Suspense fallback={ null }>
37
- <WidgetRender widget={ exampleWidget } widgetType={ item } />
38
- </Suspense>
39
- </div>
40
- );
35
+ return <WidgetPreviewChrome widget={ exampleWidget } widgetType={ item } />;
41
36
  }
42
37
 
43
38
  const fields: Field< WidgetType >[] = [
@@ -0,0 +1,2 @@
1
+ export { WidgetPreviewChrome } from './widget-preview-chrome';
2
+ export type { WidgetPreviewChromeProps } from './widget-preview-chrome';
@@ -0,0 +1,22 @@
1
+ /* Fills the tile and clips the render; inert + click-transparent so the tile owns interaction. */
2
+ .viewport {
3
+ position: absolute;
4
+ inset: 0;
5
+ overflow: hidden;
6
+ border-radius: var(--wpds-border-radius-md);
7
+ background: var(--wpds-color-background-surface-neutral-weak);
8
+ pointer-events: none;
9
+ user-select: none;
10
+ }
11
+
12
+ /* Grid stretches the card to fill the tile regardless of the card's own height. */
13
+ .canvas {
14
+ display: grid;
15
+ width: 100%;
16
+ height: 100%;
17
+ }
18
+
19
+ .card {
20
+ height: 100%;
21
+ min-height: 0;
22
+ }
@@ -0,0 +1,65 @@
1
+ /**
2
+ * WordPress dependencies
3
+ */
4
+ import { useId, useMemo } from '@wordpress/element';
5
+ import { Card } from '@wordpress/ui';
6
+ import type { WidgetType } from '@wordpress/widget-primitives';
7
+
8
+ /**
9
+ * Internal dependencies
10
+ */
11
+ import { WidgetContextProvider } from '../../context/widget-context';
12
+ import { WidgetFrame } from '../widget-frame';
13
+ import styles from './widget-preview-chrome.module.css';
14
+ import type { DashboardWidget } from '../../types';
15
+
16
+ export interface WidgetPreviewChromeProps {
17
+ widget: DashboardWidget< unknown >;
18
+ widgetType: WidgetType;
19
+ index?: number;
20
+ }
21
+
22
+ /**
23
+ * Catalog host-chrome: the faithful `WidgetFrame` in a viewport that scales the
24
+ * card to fill the tile at any zoom; inert so the picker owns selection.
25
+ *
26
+ * @param {WidgetPreviewChromeProps} props Component props.
27
+ */
28
+ export function WidgetPreviewChrome( {
29
+ widget,
30
+ widgetType,
31
+ index = 0,
32
+ }: WidgetPreviewChromeProps ) {
33
+ const titleId = useId();
34
+
35
+ const contextValue = useMemo(
36
+ () => ( {
37
+ uuid: widget.uuid,
38
+ name: widget.type,
39
+ index,
40
+ } ),
41
+ [ widget.uuid, widget.type, index ]
42
+ );
43
+
44
+ return (
45
+ <WidgetContextProvider value={ contextValue }>
46
+ <div className={ styles.viewport } { ...{ inert: '' } }>
47
+ <div className={ styles.canvas }>
48
+ <Card.Root
49
+ render={ <section /> }
50
+ className={ styles.card }
51
+ aria-labelledby={
52
+ widgetType.title ? titleId : undefined
53
+ }
54
+ >
55
+ <WidgetFrame
56
+ widget={ widget }
57
+ widgetType={ widgetType }
58
+ titleId={ titleId }
59
+ />
60
+ </Card.Root>
61
+ </div>
62
+ </div>
63
+ </WidgetContextProvider>
64
+ );
65
+ }
@@ -1,4 +1,4 @@
1
1
  export { WidgetSettings } from './widget-settings';
2
2
  export { getWidgetSettingsTitle } from './utils';
3
- export { WidgetSettingsToolbar } from './widget-settings-toolbar';
4
- export type { WidgetSettingsToolbarProps } from './widget-settings-toolbar';
3
+ export { WidgetSettingsTrigger } from './widget-settings-trigger';
4
+ export type { WidgetSettingsTriggerProps } from './widget-settings-trigger';
@@ -1,2 +1 @@
1
- export { getAdminMenuInset } from './get-admin-menu-inset';
2
1
  export { getWidgetSettingsTitle } from './get-widget-settings';