@wordpress/widget-dashboard 0.1.1 → 0.3.1-next.v.202607070741.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 (269) hide show
  1. package/CHANGELOG.md +24 -0
  2. package/README.md +10 -16
  3. package/build/components/actions/actions.cjs +2 -19
  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 +16 -63
  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 +173 -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/widgets.cjs +14 -7
  44. package/build/components/widgets/widgets.cjs.map +2 -2
  45. package/build/context/dashboard-context.cjs +31 -80
  46. package/build/context/dashboard-context.cjs.map +2 -2
  47. package/build/context/ui-context.cjs +2 -18
  48. package/build/context/ui-context.cjs.map +2 -2
  49. package/build/types.cjs.map +1 -1
  50. package/build/utils/index.cjs +2 -5
  51. package/build/utils/index.cjs.map +2 -2
  52. package/build/widget-dashboard.cjs +0 -4
  53. package/build/widget-dashboard.cjs.map +2 -2
  54. package/build-module/components/actions/actions.mjs +3 -20
  55. package/build-module/components/actions/actions.mjs.map +2 -2
  56. package/build-module/components/commands/commands.mjs +2 -67
  57. package/build-module/components/commands/commands.mjs.map +2 -2
  58. package/build-module/components/widget-attribute-controls/index.mjs +6 -0
  59. package/build-module/components/widget-attribute-controls/index.mjs.map +7 -0
  60. package/build-module/components/widget-attribute-controls/widget-attribute-controls.mjs +68 -0
  61. package/build-module/components/widget-attribute-controls/widget-attribute-controls.mjs.map +7 -0
  62. package/build-module/components/widget-chrome/widget-chrome.mjs +17 -70
  63. package/build-module/components/widget-chrome/widget-chrome.mjs.map +2 -2
  64. package/build-module/components/widget-frame/index.mjs +7 -0
  65. package/build-module/components/widget-frame/index.mjs.map +7 -0
  66. package/build-module/components/widget-frame/widget-frame.mjs +157 -0
  67. package/build-module/components/widget-frame/widget-frame.mjs.map +7 -0
  68. package/build-module/components/widget-header/index.mjs +6 -0
  69. package/build-module/components/widget-header/index.mjs.map +7 -0
  70. package/build-module/components/widget-header/widget-header-infotip.mjs +141 -0
  71. package/build-module/components/widget-header/widget-header-infotip.mjs.map +7 -0
  72. package/build-module/components/widget-header/widget-header.mjs +138 -0
  73. package/build-module/components/widget-header/widget-header.mjs.map +7 -0
  74. package/build-module/components/widget-layout-controls/index.mjs +6 -0
  75. package/build-module/components/widget-layout-controls/index.mjs.map +7 -0
  76. package/build-module/components/widget-layout-controls/widget-layout-controls.mjs +90 -0
  77. package/build-module/components/widget-layout-controls/widget-layout-controls.mjs.map +7 -0
  78. package/build-module/components/widget-picker/widget-picker.mjs +6 -94
  79. package/build-module/components/widget-picker/widget-picker.mjs.map +3 -3
  80. package/build-module/components/widget-preview-chrome/index.mjs +6 -0
  81. package/build-module/components/widget-preview-chrome/index.mjs.map +7 -0
  82. package/build-module/components/{widget-settings/widget-settings-toolbar.mjs → widget-preview-chrome/widget-preview-chrome.mjs} +37 -19
  83. package/build-module/components/widget-preview-chrome/widget-preview-chrome.mjs.map +7 -0
  84. package/build-module/components/widget-settings/index.mjs +2 -2
  85. package/build-module/components/widget-settings/index.mjs.map +1 -1
  86. package/build-module/components/widget-settings/utils/index.mjs +0 -2
  87. package/build-module/components/widget-settings/utils/index.mjs.map +2 -2
  88. package/build-module/components/widget-settings/widget-settings-trigger.mjs +23 -29
  89. package/build-module/components/widget-settings/widget-settings-trigger.mjs.map +2 -2
  90. package/build-module/components/widget-settings/widget-settings.mjs +40 -57
  91. package/build-module/components/widget-settings/widget-settings.mjs.map +2 -2
  92. package/build-module/components/widget-toolbar/widget-toolbar.mjs +7 -4
  93. package/build-module/components/widget-toolbar/widget-toolbar.mjs.map +2 -2
  94. package/build-module/components/widgets/widgets.mjs +14 -7
  95. package/build-module/components/widgets/widgets.mjs.map +2 -2
  96. package/build-module/context/dashboard-context.mjs +31 -80
  97. package/build-module/context/dashboard-context.mjs.map +2 -2
  98. package/build-module/context/ui-context.mjs +2 -18
  99. package/build-module/context/ui-context.mjs.map +2 -2
  100. package/build-module/types.mjs.map +1 -1
  101. package/build-module/utils/index.mjs +1 -3
  102. package/build-module/utils/index.mjs.map +2 -2
  103. package/build-module/widget-dashboard.mjs +0 -4
  104. package/build-module/widget-dashboard.mjs.map +2 -2
  105. package/build-types/components/actions/actions.d.ts.map +1 -1
  106. package/build-types/components/commands/commands.d.ts.map +1 -1
  107. package/build-types/components/widget-attribute-controls/index.d.ts +2 -0
  108. package/build-types/components/widget-attribute-controls/index.d.ts.map +1 -0
  109. package/build-types/components/widget-attribute-controls/widget-attribute-controls.d.ts +23 -0
  110. package/build-types/components/widget-attribute-controls/widget-attribute-controls.d.ts.map +1 -0
  111. package/build-types/components/widget-chrome/widget-chrome.d.ts +8 -8
  112. package/build-types/components/widget-chrome/widget-chrome.d.ts.map +1 -1
  113. package/build-types/components/widget-frame/index.d.ts +3 -0
  114. package/build-types/components/widget-frame/index.d.ts.map +1 -0
  115. package/build-types/components/widget-frame/widget-frame.d.ts +25 -0
  116. package/build-types/components/widget-frame/widget-frame.d.ts.map +1 -0
  117. package/build-types/components/widget-header/index.d.ts +3 -0
  118. package/build-types/components/widget-header/index.d.ts.map +1 -0
  119. package/build-types/components/widget-header/widget-header-infotip.d.ts +20 -0
  120. package/build-types/components/widget-header/widget-header-infotip.d.ts.map +1 -0
  121. package/build-types/components/widget-header/widget-header.d.ts +38 -0
  122. package/build-types/components/widget-header/widget-header.d.ts.map +1 -0
  123. package/build-types/components/widget-layout-controls/index.d.ts +3 -0
  124. package/build-types/components/widget-layout-controls/index.d.ts.map +1 -0
  125. package/build-types/components/widget-layout-controls/widget-layout-controls.d.ts +14 -0
  126. package/build-types/components/widget-layout-controls/widget-layout-controls.d.ts.map +1 -0
  127. package/build-types/components/widget-picker/widget-picker.d.ts.map +1 -1
  128. package/build-types/components/widget-preview-chrome/index.d.ts +3 -0
  129. package/build-types/components/widget-preview-chrome/index.d.ts.map +1 -0
  130. package/build-types/components/widget-preview-chrome/widget-preview-chrome.d.ts +15 -0
  131. package/build-types/components/widget-preview-chrome/widget-preview-chrome.d.ts.map +1 -0
  132. package/build-types/components/widget-settings/index.d.ts +2 -2
  133. package/build-types/components/widget-settings/utils/index.d.ts +0 -1
  134. package/build-types/components/widget-settings/utils/index.d.ts.map +1 -1
  135. package/build-types/components/widget-settings/widget-settings-trigger.d.ts +4 -3
  136. package/build-types/components/widget-settings/widget-settings-trigger.d.ts.map +1 -1
  137. package/build-types/components/widget-settings/widget-settings.d.ts +2 -2
  138. package/build-types/components/widget-settings/widget-settings.d.ts.map +1 -1
  139. package/build-types/components/widget-toolbar/widget-toolbar.d.ts +10 -7
  140. package/build-types/components/widget-toolbar/widget-toolbar.d.ts.map +1 -1
  141. package/build-types/components/widgets/widgets.d.ts.map +1 -1
  142. package/build-types/context/dashboard-context.d.ts +23 -40
  143. package/build-types/context/dashboard-context.d.ts.map +1 -1
  144. package/build-types/context/ui-context.d.ts +0 -18
  145. package/build-types/context/ui-context.d.ts.map +1 -1
  146. package/build-types/types.d.ts +9 -15
  147. package/build-types/types.d.ts.map +1 -1
  148. package/build-types/utils/index.d.ts +0 -1
  149. package/build-types/utils/index.d.ts.map +1 -1
  150. package/build-types/widget-dashboard.d.ts +5 -5
  151. package/build-types/widget-dashboard.d.ts.map +1 -1
  152. package/package.json +17 -17
  153. package/src/components/actions/actions.tsx +2 -22
  154. package/src/components/commands/commands.tsx +3 -70
  155. package/src/components/widget-attribute-controls/index.ts +1 -0
  156. package/src/components/widget-attribute-controls/widget-attribute-controls.tsx +108 -0
  157. package/src/components/widget-chrome/widget-chrome.module.css +3 -68
  158. package/src/components/widget-chrome/widget-chrome.tsx +19 -130
  159. package/src/components/widget-frame/index.ts +2 -0
  160. package/src/components/widget-frame/widget-frame.module.css +17 -0
  161. package/src/components/widget-frame/widget-frame.tsx +138 -0
  162. package/src/components/widget-header/index.ts +2 -0
  163. package/src/components/widget-header/widget-header-infotip.tsx +82 -0
  164. package/src/components/widget-header/widget-header.module.css +76 -0
  165. package/src/components/widget-header/widget-header.tsx +101 -0
  166. package/src/components/widget-layout-controls/index.ts +2 -0
  167. package/src/components/{widgets/widget-layout-toolbar.tsx → widget-layout-controls/widget-layout-controls.tsx} +12 -13
  168. package/src/components/widget-picker/widget-picker.tsx +5 -10
  169. package/src/components/widget-preview-chrome/index.ts +2 -0
  170. package/src/components/widget-preview-chrome/widget-preview-chrome.module.css +22 -0
  171. package/src/components/widget-preview-chrome/widget-preview-chrome.tsx +65 -0
  172. package/src/components/widget-settings/index.ts +2 -2
  173. package/src/components/widget-settings/utils/index.ts +0 -1
  174. package/src/components/widget-settings/widget-settings-trigger.tsx +36 -43
  175. package/src/components/widget-settings/widget-settings.tsx +7 -26
  176. package/src/components/widget-toolbar/widget-toolbar.module.css +6 -9
  177. package/src/components/widget-toolbar/widget-toolbar.tsx +14 -8
  178. package/src/components/widgets/widgets.module.css +0 -1
  179. package/src/components/widgets/widgets.tsx +30 -8
  180. package/src/context/dashboard-context.tsx +70 -133
  181. package/src/context/ui-context.tsx +1 -39
  182. package/src/test/actions.test.tsx +7 -77
  183. package/src/test/commands.test.tsx +6 -45
  184. package/src/test/staging.test.tsx +82 -144
  185. package/src/test/widget-dashboard.test.tsx +24 -0
  186. package/src/types.ts +9 -16
  187. package/src/utils/index.ts +0 -1
  188. package/src/widget-dashboard.tsx +4 -8
  189. package/build/components/layout-settings/index.cjs.map +0 -7
  190. package/build/components/layout-settings/layout-model-edit-field/index.cjs +0 -186
  191. package/build/components/layout-settings/layout-model-edit-field/index.cjs.map +0 -7
  192. package/build/components/layout-settings/layout-model-edit-field/thumbnail-grid.cjs +0 -53
  193. package/build/components/layout-settings/layout-model-edit-field/thumbnail-grid.cjs.map +0 -7
  194. package/build/components/layout-settings/layout-model-edit-field/thumbnail-masonry.cjs +0 -53
  195. package/build/components/layout-settings/layout-model-edit-field/thumbnail-masonry.cjs.map +0 -7
  196. package/build/components/layout-settings/layout-settings.cjs +0 -207
  197. package/build/components/layout-settings/layout-settings.cjs.map +0 -7
  198. package/build/components/widget-settings/utils/get-admin-menu-inset.cjs.map +0 -7
  199. package/build/components/widget-settings/widget-settings-toolbar.cjs.map +0 -7
  200. package/build/components/widgets/widget-layout-toolbar.cjs.map +0 -7
  201. package/build/utils/grid-model-change/grid-model-change.cjs +0 -56
  202. package/build/utils/grid-model-change/grid-model-change.cjs.map +0 -7
  203. package/build/utils/grid-model-change/index.cjs.map +0 -7
  204. package/build/utils/migrate-layout/index.cjs.map +0 -7
  205. package/build/utils/migrate-layout/migrate-layout.cjs +0 -94
  206. package/build/utils/migrate-layout/migrate-layout.cjs.map +0 -7
  207. package/build-module/components/layout-settings/index.mjs +0 -6
  208. package/build-module/components/layout-settings/index.mjs.map +0 -7
  209. package/build-module/components/layout-settings/layout-model-edit-field/index.mjs +0 -151
  210. package/build-module/components/layout-settings/layout-model-edit-field/index.mjs.map +0 -7
  211. package/build-module/components/layout-settings/layout-model-edit-field/thumbnail-grid.mjs +0 -28
  212. package/build-module/components/layout-settings/layout-model-edit-field/thumbnail-grid.mjs.map +0 -7
  213. package/build-module/components/layout-settings/layout-model-edit-field/thumbnail-masonry.mjs +0 -28
  214. package/build-module/components/layout-settings/layout-model-edit-field/thumbnail-masonry.mjs.map +0 -7
  215. package/build-module/components/layout-settings/layout-settings.mjs +0 -187
  216. package/build-module/components/layout-settings/layout-settings.mjs.map +0 -7
  217. package/build-module/components/widget-settings/utils/get-admin-menu-inset.mjs +0 -16
  218. package/build-module/components/widget-settings/utils/get-admin-menu-inset.mjs.map +0 -7
  219. package/build-module/components/widget-settings/widget-settings-toolbar.mjs.map +0 -7
  220. package/build-module/components/widgets/widget-layout-toolbar.mjs +0 -181
  221. package/build-module/components/widgets/widget-layout-toolbar.mjs.map +0 -7
  222. package/build-module/utils/grid-model-change/grid-model-change.mjs +0 -30
  223. package/build-module/utils/grid-model-change/grid-model-change.mjs.map +0 -7
  224. package/build-module/utils/grid-model-change/index.mjs +0 -7
  225. package/build-module/utils/grid-model-change/index.mjs.map +0 -7
  226. package/build-module/utils/migrate-layout/index.mjs +0 -6
  227. package/build-module/utils/migrate-layout/index.mjs.map +0 -7
  228. package/build-module/utils/migrate-layout/migrate-layout.mjs +0 -69
  229. package/build-module/utils/migrate-layout/migrate-layout.mjs.map +0 -7
  230. package/build-types/components/layout-settings/index.d.ts +0 -2
  231. package/build-types/components/layout-settings/index.d.ts.map +0 -1
  232. package/build-types/components/layout-settings/layout-model-edit-field/index.d.ts +0 -17
  233. package/build-types/components/layout-settings/layout-model-edit-field/index.d.ts.map +0 -1
  234. package/build-types/components/layout-settings/layout-model-edit-field/thumbnail-grid.d.ts +0 -6
  235. package/build-types/components/layout-settings/layout-model-edit-field/thumbnail-grid.d.ts.map +0 -1
  236. package/build-types/components/layout-settings/layout-model-edit-field/thumbnail-masonry.d.ts +0 -6
  237. package/build-types/components/layout-settings/layout-model-edit-field/thumbnail-masonry.d.ts.map +0 -1
  238. package/build-types/components/layout-settings/layout-settings.d.ts +0 -14
  239. package/build-types/components/layout-settings/layout-settings.d.ts.map +0 -1
  240. package/build-types/components/widget-settings/utils/get-admin-menu-inset.d.ts +0 -17
  241. package/build-types/components/widget-settings/utils/get-admin-menu-inset.d.ts.map +0 -1
  242. package/build-types/components/widget-settings/widget-settings-toolbar.d.ts +0 -20
  243. package/build-types/components/widget-settings/widget-settings-toolbar.d.ts.map +0 -1
  244. package/build-types/components/widgets/widget-layout-toolbar.d.ts +0 -14
  245. package/build-types/components/widgets/widget-layout-toolbar.d.ts.map +0 -1
  246. package/build-types/utils/grid-model-change/grid-model-change.d.ts +0 -20
  247. package/build-types/utils/grid-model-change/grid-model-change.d.ts.map +0 -1
  248. package/build-types/utils/grid-model-change/index.d.ts +0 -2
  249. package/build-types/utils/grid-model-change/index.d.ts.map +0 -1
  250. package/build-types/utils/migrate-layout/index.d.ts +0 -2
  251. package/build-types/utils/migrate-layout/index.d.ts.map +0 -1
  252. package/build-types/utils/migrate-layout/migrate-layout.d.ts +0 -36
  253. package/build-types/utils/migrate-layout/migrate-layout.d.ts.map +0 -1
  254. package/src/components/layout-settings/index.ts +0 -1
  255. package/src/components/layout-settings/layout-model-edit-field/index.tsx +0 -98
  256. package/src/components/layout-settings/layout-model-edit-field/style.module.css +0 -34
  257. package/src/components/layout-settings/layout-model-edit-field/thumbnail-grid.tsx +0 -28
  258. package/src/components/layout-settings/layout-model-edit-field/thumbnail-masonry.tsx +0 -28
  259. package/src/components/layout-settings/layout-settings.tsx +0 -217
  260. package/src/components/widget-picker/widget-picker.module.css +0 -11
  261. package/src/components/widget-settings/utils/get-admin-menu-inset.ts +0 -30
  262. package/src/components/widget-settings/widget-settings-toolbar.module.css +0 -25
  263. package/src/components/widget-settings/widget-settings-toolbar.tsx +0 -45
  264. package/src/components/widgets/widget-layout-toolbar.module.css +0 -6
  265. package/src/utils/grid-model-change/grid-model-change.ts +0 -53
  266. package/src/utils/grid-model-change/index.ts +0 -1
  267. package/src/utils/migrate-layout/index.ts +0 -1
  268. package/src/utils/migrate-layout/migrate-layout.ts +0 -156
  269. package/src/utils/migrate-layout/test/migrate-layout.test.ts +0 -114
@@ -60,23 +60,20 @@ function CommandsProbe( { names }: { names: string[] } ) {
60
60
  const COMMAND_NAMES = [
61
61
  'core/dashboard/customize',
62
62
  'core/dashboard/add-widgets',
63
+ 'core/dashboard/reset-to-default',
64
+ // Removed commands, probed to assert they stay unregistered.
63
65
  'core/dashboard/switch-to-masonry-layout',
64
66
  'core/dashboard/switch-to-grid-layout',
65
- 'core/dashboard/reset-to-default',
66
67
  ];
67
68
 
68
69
  interface HarnessProps {
69
70
  initialEditMode?: boolean;
70
- withGridSettings?: boolean;
71
71
  withLayoutReset?: boolean;
72
- gridModel?: 'grid' | 'masonry';
73
72
  }
74
73
 
75
74
  function Harness( {
76
75
  initialEditMode = false,
77
- withGridSettings = false,
78
76
  withLayoutReset = false,
79
- gridModel = 'grid',
80
77
  }: HarnessProps ) {
81
78
  const [ editMode, setEditMode ] = useState( initialEditMode );
82
79
 
@@ -88,10 +85,6 @@ function Harness( {
88
85
  editMode={ editMode }
89
86
  onEditChange={ setEditMode }
90
87
  onLayoutReset={ withLayoutReset ? async () => {} : undefined }
91
- gridSettings={
92
- withGridSettings ? { model: gridModel, columns: 6 } : undefined
93
- }
94
- onGridSettingsChange={ withGridSettings ? () => {} : undefined }
95
88
  >
96
89
  <WidgetDashboard.Commands />
97
90
  <CommandsProbe names={ COMMAND_NAMES } />
@@ -105,7 +98,7 @@ function getRegistered( probe: HTMLElement ): Record< string, boolean > {
105
98
 
106
99
  describe( 'WidgetDashboard.Commands', () => {
107
100
  it( 'sets the dashboard command context and registers core commands', () => {
108
- render( <Harness withGridSettings withLayoutReset /> );
101
+ render( <Harness withLayoutReset /> );
109
102
  const probe = screen.getByTestId( 'commands-probe' );
110
103
  const registered = getRegistered( probe );
111
104
 
@@ -119,7 +112,7 @@ describe( 'WidgetDashboard.Commands', () => {
119
112
  } );
120
113
 
121
114
  it( 'unregisters Customize while edit mode is active', () => {
122
- render( <Harness initialEditMode withGridSettings withLayoutReset /> );
115
+ render( <Harness initialEditMode withLayoutReset /> );
123
116
  const registered = getRegistered(
124
117
  screen.getByTestId( 'commands-probe' )
125
118
  );
@@ -128,15 +121,8 @@ describe( 'WidgetDashboard.Commands', () => {
128
121
  expect( registered[ 'core/dashboard/add-widgets' ] ).toBe( true );
129
122
  } );
130
123
 
131
- it( 'disables layout commands while edit mode is active', () => {
132
- render(
133
- <Harness
134
- initialEditMode
135
- withGridSettings
136
- withLayoutReset
137
- gridModel="grid"
138
- />
139
- );
124
+ it( 'does not register layout-model switch commands', () => {
125
+ render( <Harness withLayoutReset /> );
140
126
  const registered = getRegistered(
141
127
  screen.getByTestId( 'commands-probe' )
142
128
  );
@@ -148,29 +134,4 @@ describe( 'WidgetDashboard.Commands', () => {
148
134
  false
149
135
  );
150
136
  } );
151
-
152
- it( 'only registers the active layout-model switch command', () => {
153
- render( <Harness withGridSettings withLayoutReset gridModel="grid" /> );
154
- const registered = getRegistered(
155
- screen.getByTestId( 'commands-probe' )
156
- );
157
-
158
- expect( registered[ 'core/dashboard/switch-to-masonry-layout' ] ).toBe(
159
- true
160
- );
161
- expect( registered[ 'core/dashboard/switch-to-grid-layout' ] ).toBe(
162
- false
163
- );
164
- } );
165
-
166
- it( 'omits grid-settings commands when grid settings are not editable', () => {
167
- render( <Harness withLayoutReset /> );
168
- const registered = getRegistered(
169
- screen.getByTestId( 'commands-probe' )
170
- );
171
-
172
- expect( registered[ 'core/dashboard/switch-to-masonry-layout' ] ).toBe(
173
- false
174
- );
175
- } );
176
137
  } );
@@ -15,7 +15,7 @@ import type { WidgetType } from '@wordpress/widget-primitives';
15
15
  */
16
16
  import { useDashboardInternalContext } from '../context/dashboard-context';
17
17
  import { WidgetDashboard } from '../widget-dashboard';
18
- import type { DashboardWidget, WidgetGridSettings } from '../types';
18
+ import type { DashboardWidget } from '../types';
19
19
 
20
20
  const widgetTypes: WidgetType[] = [];
21
21
 
@@ -26,16 +26,13 @@ const initialLayout: DashboardWidget[] = [
26
26
 
27
27
  interface ProbeApi {
28
28
  layout: DashboardWidget[];
29
- gridSettings: WidgetGridSettings;
30
29
  hasUncommittedChanges: boolean;
31
30
  editMode: boolean;
32
31
  mutate: ( next: DashboardWidget[] ) => void;
33
- mutateGridSettings: ( next: WidgetGridSettings ) => void;
34
32
  commit: ( options?: { exitEditMode?: boolean } ) => void;
35
- cancel: ( options?: {
36
- exitEditMode?: boolean;
37
- revertLayout?: boolean;
38
- } ) => void;
33
+ cancel: () => void;
34
+ scheduleAutoSave: () => void;
35
+ flushAutoSave: () => void;
39
36
  }
40
37
 
41
38
  const probeRef: { current: ProbeApi | null } = { current: null };
@@ -45,13 +42,13 @@ function Probe() {
45
42
  useEffect( () => {
46
43
  probeRef.current = {
47
44
  layout: ctx.layout,
48
- gridSettings: ctx.gridSettings,
49
45
  hasUncommittedChanges: ctx.hasUncommittedChanges,
50
46
  editMode: ctx.editMode,
51
47
  mutate: ctx.onLayoutChange,
52
- mutateGridSettings: ctx.onGridSettingsChange,
53
48
  commit: ctx.commit,
54
49
  cancel: ctx.cancel,
50
+ scheduleAutoSave: ctx.scheduleAutoSave,
51
+ flushAutoSave: ctx.flushAutoSave,
55
52
  };
56
53
  } );
57
54
  return null;
@@ -67,24 +64,20 @@ function readProbe(): ProbeApi {
67
64
  interface HarnessProps {
68
65
  layout: DashboardWidget[];
69
66
  onLayoutChange: ( next: DashboardWidget[] ) => void;
70
- gridSettings?: WidgetGridSettings;
71
- onGridSettingsChange?: ( next: WidgetGridSettings ) => void;
67
+ initialEditMode?: boolean;
72
68
  }
73
69
 
74
70
  function Harness( {
75
71
  layout,
76
72
  onLayoutChange,
77
- gridSettings,
78
- onGridSettingsChange,
73
+ initialEditMode = true,
79
74
  }: HarnessProps ) {
80
- const [ editMode, setEditMode ] = useState( true );
75
+ const [ editMode, setEditMode ] = useState( initialEditMode );
81
76
 
82
77
  return (
83
78
  <WidgetDashboard
84
79
  layout={ layout }
85
80
  onLayoutChange={ onLayoutChange }
86
- gridSettings={ gridSettings }
87
- onGridSettingsChange={ onGridSettingsChange }
88
81
  widgetTypes={ widgetTypes }
89
82
  editMode={ editMode }
90
83
  onEditChange={ setEditMode }
@@ -286,191 +279,136 @@ describe( 'WidgetDashboard staging layer', () => {
286
279
  expect( readProbe().editMode ).toBe( true );
287
280
  } );
288
281
 
289
- describe( 'grid settings staging', () => {
290
- const initialSettings: WidgetGridSettings = {
291
- model: 'grid',
292
- rowHeight: 200,
293
- };
282
+ it( 'stays in edit mode when commit passes exitEditMode: false', () => {
283
+ const onLayoutChange = jest.fn();
284
+ render(
285
+ <Harness
286
+ layout={ initialLayout }
287
+ onLayoutChange={ onLayoutChange }
288
+ />
289
+ );
294
290
 
295
- it( 'keeps settings mutations in staging without firing onGridSettingsChange', () => {
296
- const onLayoutChange = jest.fn();
297
- const onGridSettingsChange = jest.fn();
298
- render(
299
- <Harness
300
- layout={ initialLayout }
301
- onLayoutChange={ onLayoutChange }
302
- gridSettings={ initialSettings }
303
- onGridSettingsChange={ onGridSettingsChange }
304
- />
305
- );
291
+ act( () => {
292
+ readProbe().mutate( [ initialLayout[ 0 ] ] );
293
+ } );
306
294
 
307
- expect( readProbe().hasUncommittedChanges ).toBe( false );
295
+ act( () => {
296
+ readProbe().commit( { exitEditMode: false } );
297
+ } );
308
298
 
309
- act( () => {
310
- readProbe().mutateGridSettings( {
311
- ...initialSettings,
312
- rowHeight: 300,
313
- } );
314
- } );
299
+ expect( readProbe().editMode ).toBe( true );
300
+ expect( onLayoutChange ).toHaveBeenCalledTimes( 1 );
301
+ } );
302
+
303
+ describe( 'inline auto-save', () => {
304
+ const moved: DashboardWidget[] = [
305
+ { ...initialLayout[ 1 ] },
306
+ { ...initialLayout[ 0 ] },
307
+ ];
308
+
309
+ beforeEach( () => {
310
+ jest.useFakeTimers();
311
+ } );
315
312
 
316
- expect( onGridSettingsChange ).not.toHaveBeenCalled();
317
- expect( readProbe().hasUncommittedChanges ).toBe( true );
318
- expect( readProbe().gridSettings.rowHeight ).toBe( 300 );
313
+ afterEach( () => {
314
+ jest.useRealTimers();
319
315
  } );
320
316
 
321
- it( 'publishes both layout and settings on commit', () => {
317
+ it( 'publishes a scheduled edit once the debounce elapses, staying in normal mode', () => {
322
318
  const onLayoutChange = jest.fn();
323
- const onGridSettingsChange = jest.fn();
324
319
  render(
325
320
  <Harness
326
321
  layout={ initialLayout }
327
322
  onLayoutChange={ onLayoutChange }
328
- gridSettings={ initialSettings }
329
- onGridSettingsChange={ onGridSettingsChange }
323
+ initialEditMode={ false }
330
324
  />
331
325
  );
332
326
 
333
327
  act( () => {
334
- readProbe().mutate( [ initialLayout[ 0 ] ] );
335
- readProbe().mutateGridSettings( {
336
- ...initialSettings,
337
- model: 'masonry',
338
- } );
328
+ readProbe().mutate( moved );
329
+ readProbe().scheduleAutoSave();
339
330
  } );
340
331
 
332
+ expect( onLayoutChange ).not.toHaveBeenCalled();
333
+
341
334
  act( () => {
342
- readProbe().commit();
335
+ jest.runOnlyPendingTimers();
343
336
  } );
344
337
 
345
338
  expect( onLayoutChange ).toHaveBeenCalledTimes( 1 );
346
- expect( onGridSettingsChange ).toHaveBeenCalledTimes( 1 );
347
- expect( onGridSettingsChange.mock.calls[ 0 ][ 0 ] ).toMatchObject( {
348
- model: 'masonry',
349
- } );
339
+ expect(
340
+ onLayoutChange.mock.calls[ 0 ][ 0 ].map(
341
+ ( w: DashboardWidget ) => w.uuid
342
+ )
343
+ ).toEqual( [ 'b', 'a' ] );
344
+ expect( readProbe().editMode ).toBe( false );
350
345
  } );
351
346
 
352
- it( 'reverts settings on cancel', () => {
347
+ it( 'publishes a pending edit immediately on flushAutoSave', () => {
353
348
  const onLayoutChange = jest.fn();
354
- const onGridSettingsChange = jest.fn();
355
349
  render(
356
350
  <Harness
357
351
  layout={ initialLayout }
358
352
  onLayoutChange={ onLayoutChange }
359
- gridSettings={ initialSettings }
360
- onGridSettingsChange={ onGridSettingsChange }
353
+ initialEditMode={ false }
361
354
  />
362
355
  );
363
356
 
364
357
  act( () => {
365
- readProbe().mutateGridSettings( {
366
- ...initialSettings,
367
- model: 'masonry',
368
- } );
358
+ readProbe().mutate( moved );
359
+ readProbe().scheduleAutoSave();
369
360
  } );
370
361
 
371
- expect( readProbe().hasUncommittedChanges ).toBe( true );
372
-
373
362
  act( () => {
374
- readProbe().cancel();
363
+ readProbe().flushAutoSave();
375
364
  } );
376
365
 
377
- expect( onGridSettingsChange ).not.toHaveBeenCalled();
378
- expect( readProbe().hasUncommittedChanges ).toBe( false );
379
- expect( readProbe().gridSettings.model ).toBe( 'grid' );
366
+ expect( onLayoutChange ).toHaveBeenCalledTimes( 1 );
380
367
  } );
381
368
 
382
- it( 'skips publishing settings when only the layout changed', () => {
369
+ it( 'flushes a pending edit on unmount instead of dropping it', () => {
383
370
  const onLayoutChange = jest.fn();
384
- const onGridSettingsChange = jest.fn();
385
- render(
371
+ const { unmount } = render(
386
372
  <Harness
387
373
  layout={ initialLayout }
388
374
  onLayoutChange={ onLayoutChange }
389
- gridSettings={ initialSettings }
390
- onGridSettingsChange={ onGridSettingsChange }
375
+ initialEditMode={ false }
391
376
  />
392
377
  );
393
378
 
394
379
  act( () => {
395
- readProbe().mutate( [ initialLayout[ 0 ] ] );
380
+ readProbe().mutate( moved );
381
+ readProbe().scheduleAutoSave();
396
382
  } );
397
383
 
398
- act( () => {
399
- readProbe().commit();
400
- } );
384
+ expect( onLayoutChange ).not.toHaveBeenCalled();
401
385
 
402
- expect( onLayoutChange ).toHaveBeenCalledTimes( 1 );
403
- expect( onGridSettingsChange ).not.toHaveBeenCalled();
404
- } );
405
- } );
406
-
407
- it( 'reverts only grid settings when cancel passes revertLayout: false', () => {
408
- const onLayoutChange = jest.fn();
409
- const onGridSettingsChange = jest.fn();
410
- const initialSettings: WidgetGridSettings = {
411
- model: 'grid',
412
- minColumnWidth: 350,
413
- rowHeight: 200,
414
- };
415
- render(
416
- <Harness
417
- layout={ initialLayout }
418
- onLayoutChange={ onLayoutChange }
419
- gridSettings={ initialSettings }
420
- onGridSettingsChange={ onGridSettingsChange }
421
- />
422
- );
386
+ unmount();
423
387
 
424
- act( () => {
425
- readProbe().mutate( [ initialLayout[ 0 ] ] );
426
- readProbe().mutateGridSettings( {
427
- ...initialSettings,
428
- minColumnWidth: 420,
429
- } );
388
+ expect( onLayoutChange ).toHaveBeenCalledTimes( 1 );
389
+ expect(
390
+ onLayoutChange.mock.calls[ 0 ][ 0 ].map(
391
+ ( w: DashboardWidget ) => w.uuid
392
+ )
393
+ ).toEqual( [ 'b', 'a' ] );
430
394
  } );
431
395
 
432
- expect( readProbe().hasUncommittedChanges ).toBe( true );
396
+ it( 'does not publish unscheduled staging on unmount', () => {
397
+ const onLayoutChange = jest.fn();
398
+ const { unmount } = render(
399
+ <Harness
400
+ layout={ initialLayout }
401
+ onLayoutChange={ onLayoutChange }
402
+ />
403
+ );
433
404
 
434
- act( () => {
435
- readProbe().cancel( {
436
- exitEditMode: false,
437
- revertLayout: false,
405
+ act( () => {
406
+ readProbe().mutate( moved );
438
407
  } );
439
- } );
440
408
 
441
- expect( readProbe().hasUncommittedChanges ).toBe( true );
442
- expect( readProbe().layout ).toHaveLength( 1 );
443
- expect( readProbe().gridSettings.minColumnWidth ).toBe( 350 );
444
- } );
409
+ unmount();
445
410
 
446
- it( 'stays in edit mode when commit or cancel passes exitEditMode: false', () => {
447
- const onLayoutChange = jest.fn();
448
- render(
449
- <Harness
450
- layout={ initialLayout }
451
- onLayoutChange={ onLayoutChange }
452
- />
453
- );
454
-
455
- act( () => {
456
- readProbe().mutate( [ initialLayout[ 0 ] ] );
457
- } );
458
-
459
- act( () => {
460
- readProbe().commit( { exitEditMode: false } );
411
+ expect( onLayoutChange ).not.toHaveBeenCalled();
461
412
  } );
462
-
463
- expect( readProbe().editMode ).toBe( true );
464
- expect( onLayoutChange ).toHaveBeenCalledTimes( 1 );
465
-
466
- act( () => {
467
- readProbe().mutate( [ initialLayout[ 0 ] ] );
468
- } );
469
-
470
- act( () => {
471
- readProbe().cancel( { exitEditMode: false } );
472
- } );
473
-
474
- expect( readProbe().editMode ).toBe( true );
475
413
  } );
476
414
  } );
@@ -45,6 +45,10 @@ const widgetTypes: WidgetType[] = [
45
45
  apiVersion: 1,
46
46
  name: 'test/greet',
47
47
  title: 'Greet',
48
+ help: {
49
+ content: 'Greetings at a glance.',
50
+ links: [ { label: 'Learn more', href: 'options-general.php' } ],
51
+ },
48
52
  renderModule: 'test-greet-module',
49
53
  },
50
54
  ];
@@ -101,6 +105,26 @@ describe( 'WidgetDashboard', () => {
101
105
  );
102
106
  } );
103
107
 
108
+ it( 'surfaces the widget type help note in the header', async () => {
109
+ render( <Harness /> );
110
+
111
+ // The infotip trigger opens a popover holding the note.
112
+ await userEvent.click(
113
+ await screen.findByRole( 'button', {
114
+ name: 'More information',
115
+ } )
116
+ );
117
+
118
+ expect(
119
+ await screen.findByText( 'Greetings at a glance.' )
120
+ ).toBeInTheDocument();
121
+
122
+ // The note's declared links render in the popover.
123
+ expect(
124
+ screen.getByRole( 'link', { name: 'Learn more' } )
125
+ ).toBeInTheDocument();
126
+ } );
127
+
104
128
  it( 'threads setAttributes into onLayoutChange on commit with merged attributes', async () => {
105
129
  const onChange = jest.fn();
106
130
  render( <Harness onLayoutChange={ onChange } /> );
package/src/types.ts CHANGED
@@ -34,10 +34,10 @@ export type MasonryTilePlacement = Omit< DashboardLanesLayoutItem, 'key' >;
34
34
  * Structurally a union of every supported per-model shape, but the
35
35
  * intended invariant is stronger than the type suggests: every
36
36
  * placement in a given layout must match the shape of the currently
37
- * active `gridSettings.model`. `migrateLayout` is the only correct
38
- * way to transition placements across model changes; the render
39
- * layer is allowed to trust the active model and treat each
40
- * placement as the matching shape.
37
+ * active `gridSettings.model`. Consumers that switch the model must
38
+ * supply placements in the new shape; the render layer is allowed to
39
+ * trust the active model and treat each placement as the matching
40
+ * shape.
41
41
  *
42
42
  * The type system cannot enforce that invariant on its own (there is
43
43
  * no discriminator on the placement itself), so consider this union a
@@ -74,7 +74,7 @@ export interface DashboardWidget< Item = unknown > {
74
74
  * Grid-model-specific placement (column/row spans, ordering,
75
75
  * etc.). Must match the shape implied by the dashboard's active
76
76
  * `gridSettings.model`; see `DashboardTilePlacement` for the
77
- * invariant and `migrateLayout` for the transition mechanism.
77
+ * invariant.
78
78
  */
79
79
  placement?: DashboardTilePlacement;
80
80
  }
@@ -115,8 +115,8 @@ export type WidgetGridModel = 'grid' | 'masonry';
115
115
 
116
116
  /**
117
117
  * Maximum column count for the widget dashboard on wide containers.
118
- * Not exposed in layout settings; container width steps the count down
119
- * to two and one column at fixed breakpoints.
118
+ * Not user-configurable; container width steps the count down to two
119
+ * and one column at fixed breakpoints.
120
120
  */
121
121
  export const WIDGET_DASHBOARD_COLUMN_COUNT = 4;
122
122
 
@@ -244,17 +244,10 @@ export interface WidgetDashboardProps {
244
244
 
245
245
  /**
246
246
  * Grid model configuration. See `WidgetGridSettings` for the shape.
247
+ * Read-only for the dashboard: the consumer owns the settings and
248
+ * their persistence.
247
249
  */
248
250
  gridSettings?: WidgetGridSettings;
249
251
 
250
- /**
251
- * Called when the user commits in-progress grid-settings edits via
252
- * the Done action. The dashboard maintains a staging copy of
253
- * settings internally; mutations stay local until commit. When
254
- * omitted, the `Layout settings` button in the customize toolbar is
255
- * hidden, since there is nowhere to persist the change.
256
- */
257
- onGridSettingsChange?: ( gridSettings: WidgetGridSettings ) => void;
258
-
259
252
  children?: ReactNode;
260
253
  }
@@ -1,2 +1 @@
1
1
  export { createDashboardWidget } from './create-dashboard-widget';
2
- export { migrateLayout } from './migrate-layout';
@@ -5,7 +5,6 @@ import { WidgetDashboardProvider } from './context/dashboard-context';
5
5
  import { WidgetDashboardUIProvider } from './context/ui-context';
6
6
  import { Actions } from './components/actions';
7
7
  import { Commands } from './components/commands';
8
- import { LayoutSettings } from './components/layout-settings';
9
8
  import { NoWidgetsState } from './components/no-widgets-state';
10
9
  import { ResetConfirmation } from './components/reset-confirmation';
11
10
  import { WidgetChrome } from './components/widget-chrome';
@@ -48,10 +47,10 @@ import type { WidgetDashboardProps } from './types';
48
47
  *
49
48
  * Children compose the dashboard's triggers and chrome: `Actions`,
50
49
  * `Widgets`, `Commands`, `NoWidgetsState`. The targets they open (the
51
- * widget inserter, the layout and widget settings editors, the reset
52
- * confirmation) are mounted by the engine and driven by shared UI state, so
53
- * a trigger works wherever it is composed without a matching target in the
54
- * tree. Omitting `children` renders the default arrangement.
50
+ * widget inserter, the widget settings editor, the reset confirmation) are
51
+ * mounted by the engine and driven by shared UI state, so a trigger works
52
+ * wherever it is composed without a matching target in the tree. Omitting
53
+ * `children` renders the default arrangement.
55
54
  */
56
55
  export const WidgetDashboard = Object.assign(
57
56
  function WidgetDashboard( {
@@ -64,7 +63,6 @@ export const WidgetDashboard = Object.assign(
64
63
  onEditChange,
65
64
  resolveWidgetModule,
66
65
  gridSettings,
67
- onGridSettingsChange,
68
66
  children,
69
67
  }: WidgetDashboardProps ) {
70
68
  return (
@@ -78,7 +76,6 @@ export const WidgetDashboard = Object.assign(
78
76
  onEditChange={ onEditChange }
79
77
  resolveWidgetModule={ resolveWidgetModule }
80
78
  gridSettings={ gridSettings }
81
- onGridSettingsChange={ onGridSettingsChange }
82
79
  >
83
80
  <WidgetDashboardUIProvider>
84
81
  { children ?? (
@@ -91,7 +88,6 @@ export const WidgetDashboard = Object.assign(
91
88
  ) }
92
89
 
93
90
  <WidgetInserter />
94
- <LayoutSettings />
95
91
  <WidgetSettings />
96
92
  <ResetConfirmation />
97
93
  </WidgetDashboardUIProvider>
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../../../src/components/layout-settings/index.ts"],
4
- "sourcesContent": ["export { LayoutSettings } from './layout-settings';\n"],
5
- "mappings": ";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,6BAA+B;",
6
- "names": []
7
- }