@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.
- package/CHANGELOG.md +30 -0
- package/README.md +29 -16
- package/build/components/actions/actions.cjs +6 -23
- package/build/components/actions/actions.cjs.map +3 -3
- package/build/components/commands/commands.cjs +1 -60
- package/build/components/commands/commands.cjs.map +2 -2
- package/build/{utils/grid-model-change → components/widget-attribute-controls}/index.cjs +7 -9
- package/build/components/widget-attribute-controls/index.cjs.map +7 -0
- package/build/components/widget-attribute-controls/widget-attribute-controls.cjs +93 -0
- package/build/components/widget-attribute-controls/widget-attribute-controls.cjs.map +7 -0
- package/build/components/widget-chrome/widget-chrome.cjs +28 -69
- package/build/components/widget-chrome/widget-chrome.cjs.map +2 -2
- package/build/components/{layout-settings → widget-frame}/index.cjs +9 -7
- package/build/components/widget-frame/index.cjs.map +7 -0
- package/build/components/widget-frame/widget-frame.cjs +193 -0
- package/build/components/widget-frame/widget-frame.cjs.map +7 -0
- package/build/{utils/migrate-layout → components/widget-header}/index.cjs +7 -7
- package/build/components/widget-header/index.cjs.map +7 -0
- package/build/components/widget-header/widget-header-infotip.cjs +166 -0
- package/build/components/widget-header/widget-header-infotip.cjs.map +7 -0
- package/build/components/widget-header/widget-header.cjs +176 -0
- package/build/components/widget-header/widget-header.cjs.map +7 -0
- package/build/components/{widget-settings/utils/get-admin-menu-inset.cjs → widget-layout-controls/index.cjs} +8 -18
- package/build/components/widget-layout-controls/index.cjs.map +7 -0
- package/build/components/{widgets/widget-layout-toolbar.cjs → widget-layout-controls/widget-layout-controls.cjs} +9 -100
- package/build/components/widget-layout-controls/widget-layout-controls.cjs.map +7 -0
- package/build/components/widget-picker/widget-picker.cjs +5 -93
- package/build/components/widget-picker/widget-picker.cjs.map +3 -3
- package/build/components/widget-preview-chrome/index.cjs +31 -0
- package/build/components/widget-preview-chrome/index.cjs.map +7 -0
- package/build/components/{widget-settings/widget-settings-toolbar.cjs → widget-preview-chrome/widget-preview-chrome.cjs} +41 -23
- package/build/components/widget-preview-chrome/widget-preview-chrome.cjs.map +7 -0
- package/build/components/widget-settings/index.cjs +3 -3
- package/build/components/widget-settings/index.cjs.map +1 -1
- package/build/components/widget-settings/utils/index.cjs +0 -3
- package/build/components/widget-settings/utils/index.cjs.map +2 -2
- package/build/components/widget-settings/widget-settings-trigger.cjs +22 -28
- package/build/components/widget-settings/widget-settings-trigger.cjs.map +2 -2
- package/build/components/widget-settings/widget-settings.cjs +40 -57
- package/build/components/widget-settings/widget-settings.cjs.map +2 -2
- package/build/components/widget-toolbar/widget-toolbar.cjs +7 -4
- package/build/components/widget-toolbar/widget-toolbar.cjs.map +2 -2
- package/build/components/widgets/widget-resize-handle.cjs +4 -4
- package/build/components/widgets/widget-resize-handle.cjs.map +2 -2
- package/build/components/widgets/widgets.cjs +18 -11
- package/build/components/widgets/widgets.cjs.map +2 -2
- package/build/context/dashboard-context.cjs +31 -80
- package/build/context/dashboard-context.cjs.map +2 -2
- package/build/context/ui-context.cjs +2 -18
- package/build/context/ui-context.cjs.map +2 -2
- package/build/types.cjs.map +1 -1
- package/build/utils/index.cjs +2 -5
- package/build/utils/index.cjs.map +2 -2
- package/build/widget-dashboard.cjs +0 -4
- package/build/widget-dashboard.cjs.map +2 -2
- package/build-module/components/actions/actions.mjs +7 -24
- package/build-module/components/actions/actions.mjs.map +2 -2
- package/build-module/components/commands/commands.mjs +2 -67
- package/build-module/components/commands/commands.mjs.map +2 -2
- package/build-module/components/widget-attribute-controls/index.mjs +6 -0
- package/build-module/components/widget-attribute-controls/index.mjs.map +7 -0
- package/build-module/components/widget-attribute-controls/widget-attribute-controls.mjs +68 -0
- package/build-module/components/widget-attribute-controls/widget-attribute-controls.mjs.map +7 -0
- package/build-module/components/widget-chrome/widget-chrome.mjs +29 -76
- package/build-module/components/widget-chrome/widget-chrome.mjs.map +2 -2
- package/build-module/components/widget-frame/index.mjs +7 -0
- package/build-module/components/widget-frame/index.mjs.map +7 -0
- package/build-module/components/widget-frame/widget-frame.mjs +157 -0
- package/build-module/components/widget-frame/widget-frame.mjs.map +7 -0
- package/build-module/components/widget-header/index.mjs +6 -0
- package/build-module/components/widget-header/index.mjs.map +7 -0
- package/build-module/components/widget-header/widget-header-infotip.mjs +141 -0
- package/build-module/components/widget-header/widget-header-infotip.mjs.map +7 -0
- package/build-module/components/widget-header/widget-header.mjs +141 -0
- package/build-module/components/widget-header/widget-header.mjs.map +7 -0
- package/build-module/components/widget-layout-controls/index.mjs +6 -0
- package/build-module/components/widget-layout-controls/index.mjs.map +7 -0
- package/build-module/components/widget-layout-controls/widget-layout-controls.mjs +90 -0
- package/build-module/components/widget-layout-controls/widget-layout-controls.mjs.map +7 -0
- package/build-module/components/widget-picker/widget-picker.mjs +6 -94
- package/build-module/components/widget-picker/widget-picker.mjs.map +3 -3
- package/build-module/components/widget-preview-chrome/index.mjs +6 -0
- package/build-module/components/widget-preview-chrome/index.mjs.map +7 -0
- package/build-module/components/{widget-settings/widget-settings-toolbar.mjs → widget-preview-chrome/widget-preview-chrome.mjs} +37 -19
- package/build-module/components/widget-preview-chrome/widget-preview-chrome.mjs.map +7 -0
- package/build-module/components/widget-settings/index.mjs +2 -2
- package/build-module/components/widget-settings/index.mjs.map +1 -1
- package/build-module/components/widget-settings/utils/index.mjs +0 -2
- package/build-module/components/widget-settings/utils/index.mjs.map +2 -2
- package/build-module/components/widget-settings/widget-settings-trigger.mjs +23 -29
- package/build-module/components/widget-settings/widget-settings-trigger.mjs.map +2 -2
- package/build-module/components/widget-settings/widget-settings.mjs +40 -57
- package/build-module/components/widget-settings/widget-settings.mjs.map +2 -2
- package/build-module/components/widget-toolbar/widget-toolbar.mjs +7 -4
- package/build-module/components/widget-toolbar/widget-toolbar.mjs.map +2 -2
- package/build-module/components/widgets/widget-resize-handle.mjs +4 -4
- package/build-module/components/widgets/widget-resize-handle.mjs.map +2 -2
- package/build-module/components/widgets/widgets.mjs +18 -11
- package/build-module/components/widgets/widgets.mjs.map +2 -2
- package/build-module/context/dashboard-context.mjs +31 -80
- package/build-module/context/dashboard-context.mjs.map +2 -2
- package/build-module/context/ui-context.mjs +2 -18
- package/build-module/context/ui-context.mjs.map +2 -2
- package/build-module/types.mjs.map +1 -1
- package/build-module/utils/index.mjs +1 -3
- package/build-module/utils/index.mjs.map +2 -2
- package/build-module/widget-dashboard.mjs +0 -4
- package/build-module/widget-dashboard.mjs.map +2 -2
- package/build-types/components/actions/actions.d.ts.map +1 -1
- package/build-types/components/commands/commands.d.ts.map +1 -1
- package/build-types/components/commands/use-pending-when-edit-mode.d.ts +1 -1
- package/build-types/components/commands/use-pending-when-edit-mode.d.ts.map +1 -1
- package/build-types/components/no-widgets-state/no-widgets-state.d.ts +1 -1
- package/build-types/components/no-widgets-state/no-widgets-state.d.ts.map +1 -1
- package/build-types/components/widget-attribute-controls/index.d.ts +2 -0
- package/build-types/components/widget-attribute-controls/index.d.ts.map +1 -0
- package/build-types/components/widget-attribute-controls/widget-attribute-controls.d.ts +23 -0
- package/build-types/components/widget-attribute-controls/widget-attribute-controls.d.ts.map +1 -0
- package/build-types/components/widget-chrome/widget-chrome.d.ts +8 -8
- package/build-types/components/widget-chrome/widget-chrome.d.ts.map +1 -1
- package/build-types/components/widget-frame/index.d.ts +3 -0
- package/build-types/components/widget-frame/index.d.ts.map +1 -0
- package/build-types/components/widget-frame/widget-frame.d.ts +25 -0
- package/build-types/components/widget-frame/widget-frame.d.ts.map +1 -0
- package/build-types/components/widget-header/index.d.ts +3 -0
- package/build-types/components/widget-header/index.d.ts.map +1 -0
- package/build-types/components/widget-header/widget-header-infotip.d.ts +20 -0
- package/build-types/components/widget-header/widget-header-infotip.d.ts.map +1 -0
- package/build-types/components/widget-header/widget-header.d.ts +38 -0
- package/build-types/components/widget-header/widget-header.d.ts.map +1 -0
- package/build-types/components/widget-layout-controls/index.d.ts +3 -0
- package/build-types/components/widget-layout-controls/index.d.ts.map +1 -0
- package/build-types/components/widget-layout-controls/widget-layout-controls.d.ts +14 -0
- package/build-types/components/widget-layout-controls/widget-layout-controls.d.ts.map +1 -0
- package/build-types/components/widget-picker/widget-picker.d.ts +1 -1
- package/build-types/components/widget-picker/widget-picker.d.ts.map +1 -1
- package/build-types/components/widget-preview-chrome/index.d.ts +3 -0
- package/build-types/components/widget-preview-chrome/index.d.ts.map +1 -0
- package/build-types/components/widget-preview-chrome/widget-preview-chrome.d.ts +15 -0
- package/build-types/components/widget-preview-chrome/widget-preview-chrome.d.ts.map +1 -0
- package/build-types/components/widget-settings/index.d.ts +2 -2
- package/build-types/components/widget-settings/utils/index.d.ts +0 -1
- package/build-types/components/widget-settings/utils/index.d.ts.map +1 -1
- package/build-types/components/widget-settings/widget-settings-trigger.d.ts +7 -5
- package/build-types/components/widget-settings/widget-settings-trigger.d.ts.map +1 -1
- package/build-types/components/widget-settings/widget-settings.d.ts +5 -4
- package/build-types/components/widget-settings/widget-settings.d.ts.map +1 -1
- package/build-types/components/widget-toolbar/widget-toolbar.d.ts +10 -7
- package/build-types/components/widget-toolbar/widget-toolbar.d.ts.map +1 -1
- package/build-types/components/widgets/widgets.d.ts.map +1 -1
- package/build-types/context/dashboard-context.d.ts +23 -40
- package/build-types/context/dashboard-context.d.ts.map +1 -1
- package/build-types/context/ui-context.d.ts +0 -18
- package/build-types/context/ui-context.d.ts.map +1 -1
- package/build-types/context/widget-context.d.ts +1 -1
- package/build-types/context/widget-context.d.ts.map +1 -1
- package/build-types/types.d.ts +9 -15
- package/build-types/types.d.ts.map +1 -1
- package/build-types/utils/index.d.ts +0 -1
- package/build-types/utils/index.d.ts.map +1 -1
- package/build-types/widget-dashboard.d.ts +5 -5
- package/build-types/widget-dashboard.d.ts.map +1 -1
- package/package.json +20 -20
- package/src/components/actions/actions.module.css +7 -7
- package/src/components/actions/actions.tsx +5 -25
- package/src/components/commands/commands.tsx +3 -70
- package/src/components/widget-attribute-controls/index.ts +1 -0
- package/src/components/widget-attribute-controls/widget-attribute-controls.tsx +108 -0
- package/src/components/widget-chrome/widget-chrome.module.css +6 -71
- package/src/components/widget-chrome/widget-chrome.tsx +31 -136
- package/src/components/widget-frame/index.ts +2 -0
- package/src/components/widget-frame/widget-frame.module.css +17 -0
- package/src/components/widget-frame/widget-frame.tsx +138 -0
- package/src/components/widget-header/index.ts +2 -0
- package/src/components/widget-header/widget-header-infotip.tsx +82 -0
- package/src/components/widget-header/widget-header.module.css +59 -0
- package/src/components/widget-header/widget-header.tsx +104 -0
- package/src/components/widget-layout-controls/index.ts +2 -0
- package/src/components/{widgets/widget-layout-toolbar.tsx → widget-layout-controls/widget-layout-controls.tsx} +12 -13
- package/src/components/widget-picker/widget-picker.tsx +5 -10
- package/src/components/widget-preview-chrome/index.ts +2 -0
- package/src/components/widget-preview-chrome/widget-preview-chrome.module.css +22 -0
- package/src/components/widget-preview-chrome/widget-preview-chrome.tsx +65 -0
- package/src/components/widget-settings/index.ts +2 -2
- package/src/components/widget-settings/utils/index.ts +0 -1
- package/src/components/widget-settings/widget-settings-trigger.tsx +39 -44
- package/src/components/widget-settings/widget-settings.tsx +10 -28
- package/src/components/widget-toolbar/widget-toolbar.module.css +13 -10
- package/src/components/widget-toolbar/widget-toolbar.tsx +14 -8
- package/src/components/widgets/widget-resize-handle.module.css +21 -21
- package/src/components/widgets/widget-resize-handle.tsx +2 -2
- package/src/components/widgets/widgets.module.css +20 -11
- package/src/components/widgets/widgets.tsx +33 -10
- package/src/context/dashboard-context.tsx +70 -133
- package/src/context/ui-context.tsx +1 -39
- package/src/test/actions.test.tsx +7 -77
- package/src/test/commands.test.tsx +6 -45
- package/src/test/staging.test.tsx +82 -144
- package/src/test/widget-dashboard.test.tsx +24 -0
- package/src/types.ts +9 -16
- package/src/utils/index.ts +0 -1
- package/src/widget-dashboard.tsx +4 -8
- package/build/components/layout-settings/index.cjs.map +0 -7
- package/build/components/layout-settings/layout-model-edit-field/index.cjs +0 -186
- package/build/components/layout-settings/layout-model-edit-field/index.cjs.map +0 -7
- package/build/components/layout-settings/layout-model-edit-field/thumbnail-grid.cjs +0 -53
- package/build/components/layout-settings/layout-model-edit-field/thumbnail-grid.cjs.map +0 -7
- package/build/components/layout-settings/layout-model-edit-field/thumbnail-masonry.cjs +0 -53
- package/build/components/layout-settings/layout-model-edit-field/thumbnail-masonry.cjs.map +0 -7
- package/build/components/layout-settings/layout-settings.cjs +0 -207
- package/build/components/layout-settings/layout-settings.cjs.map +0 -7
- package/build/components/widget-settings/utils/get-admin-menu-inset.cjs.map +0 -7
- package/build/components/widget-settings/widget-settings-toolbar.cjs.map +0 -7
- package/build/components/widgets/widget-layout-toolbar.cjs.map +0 -7
- package/build/utils/grid-model-change/grid-model-change.cjs +0 -56
- package/build/utils/grid-model-change/grid-model-change.cjs.map +0 -7
- package/build/utils/grid-model-change/index.cjs.map +0 -7
- package/build/utils/migrate-layout/index.cjs.map +0 -7
- package/build/utils/migrate-layout/migrate-layout.cjs +0 -94
- package/build/utils/migrate-layout/migrate-layout.cjs.map +0 -7
- package/build-module/components/layout-settings/index.mjs +0 -6
- package/build-module/components/layout-settings/index.mjs.map +0 -7
- package/build-module/components/layout-settings/layout-model-edit-field/index.mjs +0 -151
- package/build-module/components/layout-settings/layout-model-edit-field/index.mjs.map +0 -7
- package/build-module/components/layout-settings/layout-model-edit-field/thumbnail-grid.mjs +0 -28
- package/build-module/components/layout-settings/layout-model-edit-field/thumbnail-grid.mjs.map +0 -7
- package/build-module/components/layout-settings/layout-model-edit-field/thumbnail-masonry.mjs +0 -28
- package/build-module/components/layout-settings/layout-model-edit-field/thumbnail-masonry.mjs.map +0 -7
- package/build-module/components/layout-settings/layout-settings.mjs +0 -187
- package/build-module/components/layout-settings/layout-settings.mjs.map +0 -7
- package/build-module/components/widget-settings/utils/get-admin-menu-inset.mjs +0 -16
- package/build-module/components/widget-settings/utils/get-admin-menu-inset.mjs.map +0 -7
- package/build-module/components/widget-settings/widget-settings-toolbar.mjs.map +0 -7
- package/build-module/components/widgets/widget-layout-toolbar.mjs +0 -181
- package/build-module/components/widgets/widget-layout-toolbar.mjs.map +0 -7
- package/build-module/utils/grid-model-change/grid-model-change.mjs +0 -30
- package/build-module/utils/grid-model-change/grid-model-change.mjs.map +0 -7
- package/build-module/utils/grid-model-change/index.mjs +0 -7
- package/build-module/utils/grid-model-change/index.mjs.map +0 -7
- package/build-module/utils/migrate-layout/index.mjs +0 -6
- package/build-module/utils/migrate-layout/index.mjs.map +0 -7
- package/build-module/utils/migrate-layout/migrate-layout.mjs +0 -69
- package/build-module/utils/migrate-layout/migrate-layout.mjs.map +0 -7
- package/build-types/components/layout-settings/index.d.ts +0 -2
- package/build-types/components/layout-settings/index.d.ts.map +0 -1
- package/build-types/components/layout-settings/layout-model-edit-field/index.d.ts +0 -17
- package/build-types/components/layout-settings/layout-model-edit-field/index.d.ts.map +0 -1
- package/build-types/components/layout-settings/layout-model-edit-field/thumbnail-grid.d.ts +0 -6
- package/build-types/components/layout-settings/layout-model-edit-field/thumbnail-grid.d.ts.map +0 -1
- package/build-types/components/layout-settings/layout-model-edit-field/thumbnail-masonry.d.ts +0 -6
- package/build-types/components/layout-settings/layout-model-edit-field/thumbnail-masonry.d.ts.map +0 -1
- package/build-types/components/layout-settings/layout-settings.d.ts +0 -14
- package/build-types/components/layout-settings/layout-settings.d.ts.map +0 -1
- package/build-types/components/widget-settings/utils/get-admin-menu-inset.d.ts +0 -17
- package/build-types/components/widget-settings/utils/get-admin-menu-inset.d.ts.map +0 -1
- package/build-types/components/widget-settings/widget-settings-toolbar.d.ts +0 -20
- package/build-types/components/widget-settings/widget-settings-toolbar.d.ts.map +0 -1
- package/build-types/components/widgets/widget-layout-toolbar.d.ts +0 -14
- package/build-types/components/widgets/widget-layout-toolbar.d.ts.map +0 -1
- package/build-types/utils/grid-model-change/grid-model-change.d.ts +0 -20
- package/build-types/utils/grid-model-change/grid-model-change.d.ts.map +0 -1
- package/build-types/utils/grid-model-change/index.d.ts +0 -2
- package/build-types/utils/grid-model-change/index.d.ts.map +0 -1
- package/build-types/utils/migrate-layout/index.d.ts +0 -2
- package/build-types/utils/migrate-layout/index.d.ts.map +0 -1
- package/build-types/utils/migrate-layout/migrate-layout.d.ts +0 -36
- package/build-types/utils/migrate-layout/migrate-layout.d.ts.map +0 -1
- package/src/components/layout-settings/index.ts +0 -1
- package/src/components/layout-settings/layout-model-edit-field/index.tsx +0 -98
- package/src/components/layout-settings/layout-model-edit-field/style.module.css +0 -34
- package/src/components/layout-settings/layout-model-edit-field/thumbnail-grid.tsx +0 -28
- package/src/components/layout-settings/layout-model-edit-field/thumbnail-masonry.tsx +0 -28
- package/src/components/layout-settings/layout-settings.tsx +0 -217
- package/src/components/widget-picker/widget-picker.module.css +0 -11
- package/src/components/widget-settings/utils/get-admin-menu-inset.ts +0 -30
- package/src/components/widget-settings/widget-settings-toolbar.module.css +0 -25
- package/src/components/widget-settings/widget-settings-toolbar.tsx +0 -45
- package/src/components/widgets/widget-layout-toolbar.module.css +0 -6
- package/src/utils/grid-model-change/grid-model-change.ts +0 -53
- package/src/utils/grid-model-change/index.ts +0 -1
- package/src/utils/migrate-layout/index.ts +0 -1
- package/src/utils/migrate-layout/migrate-layout.ts +0 -156
- package/src/utils/migrate-layout/test/migrate-layout.test.ts +0 -114
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
*/
|
|
4
4
|
import { useCallback } from '@wordpress/element';
|
|
5
5
|
import { __ } from '@wordpress/i18n';
|
|
6
|
-
import {
|
|
6
|
+
import { moreVertical } from '@wordpress/icons';
|
|
7
7
|
// Dashboard is still experimental.
|
|
8
8
|
// eslint-disable-next-line @wordpress/use-recommended-components
|
|
9
9
|
import { IconButton } from '@wordpress/ui';
|
|
@@ -12,13 +12,13 @@ import type { WidgetType } from '@wordpress/widget-primitives';
|
|
|
12
12
|
/**
|
|
13
13
|
* Internal dependencies
|
|
14
14
|
*/
|
|
15
|
+
import { useDashboardInternalContext } from '../../context/dashboard-context';
|
|
15
16
|
import { useDashboardUIContext } from '../../context/ui-context';
|
|
16
|
-
import { getAdminMenuInset } from './utils';
|
|
17
17
|
import type { DashboardWidget } from '../../types';
|
|
18
18
|
|
|
19
19
|
export interface WidgetSettingsTriggerProps {
|
|
20
20
|
/**
|
|
21
|
-
* The instance whose settings
|
|
21
|
+
* The instance whose settings surface this control opens.
|
|
22
22
|
*/
|
|
23
23
|
widget: DashboardWidget< unknown >;
|
|
24
24
|
|
|
@@ -30,10 +30,12 @@ export interface WidgetSettingsTriggerProps {
|
|
|
30
30
|
}
|
|
31
31
|
|
|
32
32
|
/**
|
|
33
|
-
* Per-instance
|
|
33
|
+
* Per-instance control that toggles the shared settings surface by writing the
|
|
34
34
|
* instance `uuid` to the UI context; the single `WidgetSettings` at the root
|
|
35
|
-
* reacts to it.
|
|
36
|
-
*
|
|
35
|
+
* reacts to it. Clicking the control of the instance whose settings surface is
|
|
36
|
+
* already open closes it. Returns `null` when no attribute needs that surface
|
|
37
|
+
* (none, or all already promoted to the prominent one), so chrome can mount it
|
|
38
|
+
* unconditionally.
|
|
37
39
|
*
|
|
38
40
|
* @param {WidgetSettingsTriggerProps} props Component props.
|
|
39
41
|
*/
|
|
@@ -41,56 +43,49 @@ export function WidgetSettingsTrigger( {
|
|
|
41
43
|
widget,
|
|
42
44
|
widgetType,
|
|
43
45
|
}: WidgetSettingsTriggerProps ): React.ReactNode {
|
|
44
|
-
const {
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
setSettingsDrawerInset,
|
|
48
|
-
} = useDashboardUIContext();
|
|
46
|
+
const { settingsWidgetUuid, setSettingsWidgetUuid } =
|
|
47
|
+
useDashboardUIContext();
|
|
48
|
+
const { cancel, flushAutoSave } = useDashboardInternalContext();
|
|
49
49
|
|
|
50
|
-
const
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
50
|
+
const toggle = useCallback( () => {
|
|
51
|
+
// Re-clicking the open instance's control closes the settings surface,
|
|
52
|
+
// discarding staged edits like any other non-Save exit.
|
|
53
|
+
if ( settingsWidgetUuid === widget.uuid ) {
|
|
54
|
+
cancel();
|
|
55
|
+
setSettingsWidgetUuid( null );
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
// Persist any pending prominent-surface edit before opening, so the
|
|
59
|
+
// settings surface's edits stay isolated and its Cancel discards only
|
|
60
|
+
// its own changes.
|
|
61
|
+
flushAutoSave();
|
|
62
|
+
setSettingsWidgetUuid( widget.uuid );
|
|
63
|
+
}, [
|
|
64
|
+
cancel,
|
|
65
|
+
flushAutoSave,
|
|
66
|
+
settingsWidgetUuid,
|
|
67
|
+
setSettingsWidgetUuid,
|
|
68
|
+
widget.uuid,
|
|
69
|
+
] );
|
|
67
70
|
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
},
|
|
74
|
-
[
|
|
75
|
-
setSettingsDrawerSide,
|
|
76
|
-
setSettingsDrawerInset,
|
|
77
|
-
setSettingsWidgetUuid,
|
|
78
|
-
widget.uuid,
|
|
79
|
-
]
|
|
71
|
+
// Surface the settings UI only when there are attributes not already
|
|
72
|
+
// promoted inline; if every attribute is high-relevance, a second
|
|
73
|
+
// surface would just repeat the prominent one.
|
|
74
|
+
const hasNonPromotedAttributes = widgetType.attributes?.some(
|
|
75
|
+
( attribute ) => attribute.relevance !== 'high'
|
|
80
76
|
);
|
|
81
|
-
|
|
82
|
-
if ( ! widgetType.attributes?.length ) {
|
|
77
|
+
if ( ! hasNonPromotedAttributes ) {
|
|
83
78
|
return null;
|
|
84
79
|
}
|
|
85
80
|
|
|
86
81
|
return (
|
|
87
82
|
<IconButton
|
|
88
|
-
icon={
|
|
83
|
+
icon={ moreVertical }
|
|
89
84
|
label={ __( 'Widget settings' ) }
|
|
90
85
|
variant="minimal"
|
|
91
86
|
tone="neutral"
|
|
92
87
|
size="compact"
|
|
93
|
-
onClick={
|
|
88
|
+
onClick={ toggle }
|
|
94
89
|
/>
|
|
95
90
|
);
|
|
96
91
|
}
|
|
@@ -22,13 +22,14 @@ type WidgetAttributes = Record< string, unknown >;
|
|
|
22
22
|
/**
|
|
23
23
|
* Side drawer that edits one instance's attributes, mounted once at the
|
|
24
24
|
* dashboard root. It resolves the active instance from `settingsWidgetUuid`
|
|
25
|
-
* in the UI context (set by the per-instance
|
|
26
|
-
* declarative `attributes` through `DataForm`, and enters from the
|
|
27
|
-
*
|
|
25
|
+
* in the UI context (set by the per-instance settings trigger), renders the
|
|
26
|
+
* type's declarative `attributes` through `DataForm`, and enters from the
|
|
27
|
+
* inline-end edge.
|
|
28
28
|
*
|
|
29
29
|
* Edits write to the staging layer, so they preview live behind the drawer
|
|
30
30
|
* and are published on Save or reverted on any other exit. Available in
|
|
31
|
-
* normal mode only; the
|
|
31
|
+
* normal mode only; the settings entry point is hidden while the layout is
|
|
32
|
+
* being edited.
|
|
32
33
|
*/
|
|
33
34
|
export function WidgetSettings(): React.ReactNode {
|
|
34
35
|
const {
|
|
@@ -39,12 +40,8 @@ export function WidgetSettings(): React.ReactNode {
|
|
|
39
40
|
cancel: cancelStaging,
|
|
40
41
|
hasUncommittedChanges,
|
|
41
42
|
} = useDashboardInternalContext();
|
|
42
|
-
const {
|
|
43
|
-
|
|
44
|
-
setSettingsWidgetUuid,
|
|
45
|
-
settingsDrawerSide,
|
|
46
|
-
settingsDrawerInset,
|
|
47
|
-
} = useDashboardUIContext();
|
|
43
|
+
const { settingsWidgetUuid, setSettingsWidgetUuid } =
|
|
44
|
+
useDashboardUIContext();
|
|
48
45
|
|
|
49
46
|
const open = settingsWidgetUuid !== null;
|
|
50
47
|
|
|
@@ -117,7 +114,7 @@ export function WidgetSettings(): React.ReactNode {
|
|
|
117
114
|
const handleOpenChange = useCallback(
|
|
118
115
|
( nextOpen: boolean ) => {
|
|
119
116
|
// Any path out of the drawer other than Save discards the
|
|
120
|
-
// staged edits
|
|
117
|
+
// staged edits.
|
|
121
118
|
if ( ! nextOpen ) {
|
|
122
119
|
cancelStaging();
|
|
123
120
|
close();
|
|
@@ -126,17 +123,6 @@ export function WidgetSettings(): React.ReactNode {
|
|
|
126
123
|
[ cancelStaging, close ]
|
|
127
124
|
);
|
|
128
125
|
|
|
129
|
-
// For a left drawer, clear the fixed admin menu on the inline-start
|
|
130
|
-
// edge so the drawer lands beside it. The admin bar at the top is
|
|
131
|
-
// cleared in the CSS module.
|
|
132
|
-
const popupStyle = useMemo< React.CSSProperties >(
|
|
133
|
-
() =>
|
|
134
|
-
settingsDrawerSide === 'left' && settingsDrawerInset > 0
|
|
135
|
-
? { marginLeft: settingsDrawerInset }
|
|
136
|
-
: {},
|
|
137
|
-
[ settingsDrawerSide, settingsDrawerInset ]
|
|
138
|
-
);
|
|
139
|
-
|
|
140
126
|
const hasForm = !! widget && !! widgetType && fields.length > 0;
|
|
141
127
|
|
|
142
128
|
if ( ! hasForm ) {
|
|
@@ -152,15 +138,11 @@ export function WidgetSettings(): React.ReactNode {
|
|
|
152
138
|
<Drawer.Root
|
|
153
139
|
open={ open }
|
|
154
140
|
onOpenChange={ handleOpenChange }
|
|
155
|
-
swipeDirection=
|
|
141
|
+
swipeDirection="right"
|
|
156
142
|
modal={ false }
|
|
157
143
|
disablePointerDismissal
|
|
158
144
|
>
|
|
159
|
-
<Drawer.Popup
|
|
160
|
-
size="medium"
|
|
161
|
-
className={ styles.popup }
|
|
162
|
-
style={ popupStyle }
|
|
163
|
-
>
|
|
145
|
+
<Drawer.Popup size="medium" className={ styles.popup }>
|
|
164
146
|
<Drawer.Header>
|
|
165
147
|
<Drawer.Title>{ title }</Drawer.Title>
|
|
166
148
|
<Drawer.CloseIcon />
|
|
@@ -1,12 +1,15 @@
|
|
|
1
|
-
|
|
2
|
-
* Per-tile toolbar shell: anchored top-right (the grid item is the positioned
|
|
3
|
-
* ancestor) with the shared padding and radius. Variants add the background.
|
|
4
|
-
*/
|
|
5
|
-
.widgetToolbar {
|
|
6
|
-
position: absolute;
|
|
7
|
-
inset-block-start: var(--wpds-dimension-padding-sm);
|
|
8
|
-
inset-inline-end: var(--wpds-dimension-padding-sm);
|
|
9
|
-
z-index: 1;
|
|
1
|
+
.widget-toolbar {
|
|
10
2
|
padding: var(--wpds-dimension-padding-xs);
|
|
11
|
-
|
|
3
|
+
background: var(--wpds-color-background-surface-neutral-strong);
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
.elevated {
|
|
7
|
+
--_wp-widget-dashboard-elevation-xs:
|
|
8
|
+
0 1px 1px rgba(0, 0, 0, 0.03),
|
|
9
|
+
0 1px 2px rgba(0, 0, 0, 0.02),
|
|
10
|
+
0 3px 3px rgba(0, 0, 0, 0.02),
|
|
11
|
+
0 4px 4px rgba(0, 0, 0, 0.01);
|
|
12
|
+
|
|
13
|
+
border: 1px solid var(--wpds-color-stroke-surface-neutral-weak);
|
|
14
|
+
box-shadow: var(--_wp-widget-dashboard-elevation-xs);
|
|
12
15
|
}
|
|
@@ -15,30 +15,36 @@ import { Stack } from '@wordpress/ui';
|
|
|
15
15
|
import styles from './widget-toolbar.module.css';
|
|
16
16
|
|
|
17
17
|
export interface WidgetToolbarProps {
|
|
18
|
-
/**
|
|
18
|
+
/**
|
|
19
|
+
* The active mode's controls.
|
|
20
|
+
*/
|
|
19
21
|
children: ReactNode;
|
|
20
22
|
|
|
21
|
-
/**
|
|
22
|
-
|
|
23
|
+
/**
|
|
24
|
+
* Lift the toolbar with a shadow while customizing.
|
|
25
|
+
*/
|
|
26
|
+
editMode?: boolean;
|
|
23
27
|
}
|
|
24
28
|
|
|
25
29
|
/**
|
|
26
|
-
*
|
|
27
|
-
*
|
|
28
|
-
* a toolbar lines up with the title when they overlap.
|
|
30
|
+
* The per-tile toolbar chip holding the active mode's controls.
|
|
31
|
+
* Always visible; lifted with a shadow only while customizing.
|
|
29
32
|
*
|
|
30
33
|
* @param {WidgetToolbarProps} props Component props.
|
|
31
34
|
*/
|
|
32
35
|
export function WidgetToolbar( {
|
|
33
36
|
children,
|
|
34
|
-
|
|
37
|
+
editMode = false,
|
|
35
38
|
}: WidgetToolbarProps ): React.ReactNode {
|
|
36
39
|
return (
|
|
37
40
|
<Stack
|
|
38
41
|
direction="row"
|
|
39
42
|
align="center"
|
|
40
43
|
gap="xs"
|
|
41
|
-
className={ clsx(
|
|
44
|
+
className={ clsx(
|
|
45
|
+
styles[ 'widget-toolbar' ],
|
|
46
|
+
editMode && styles.elevated
|
|
47
|
+
) }
|
|
42
48
|
>
|
|
43
49
|
{ children }
|
|
44
50
|
</Stack>
|
|
@@ -26,13 +26,13 @@
|
|
|
26
26
|
* Larger box = hit target; small `::after` = visual only (still uses
|
|
27
27
|
* logical borders so RTL needs no mirroring).
|
|
28
28
|
*/
|
|
29
|
-
.
|
|
29
|
+
.handle-corner {
|
|
30
30
|
width: var(--wpds-dimension-size-sm);
|
|
31
31
|
height: var(--wpds-dimension-size-sm);
|
|
32
32
|
cursor: nwse-resize;
|
|
33
33
|
}
|
|
34
34
|
|
|
35
|
-
.
|
|
35
|
+
.handle-corner::after {
|
|
36
36
|
content: "";
|
|
37
37
|
position: absolute;
|
|
38
38
|
bottom: var(--widget-resize-handle-visual-inset);
|
|
@@ -54,13 +54,13 @@
|
|
|
54
54
|
transform-origin: 100% 100%;
|
|
55
55
|
}
|
|
56
56
|
|
|
57
|
-
[dir="rtl"] .
|
|
57
|
+
[dir="rtl"] .handle-corner::after {
|
|
58
58
|
transform-origin: 0% 100%;
|
|
59
59
|
}
|
|
60
60
|
|
|
61
|
-
.
|
|
62
|
-
.
|
|
63
|
-
.
|
|
61
|
+
.handle-corner.resizing::after,
|
|
62
|
+
.handle-corner:hover::after,
|
|
63
|
+
.handle-corner:focus-visible::after {
|
|
64
64
|
transform: scale(var(--widget-resize-handle-hover-scale));
|
|
65
65
|
border-block-end:
|
|
66
66
|
var(--wpds-border-width-sm) solid
|
|
@@ -70,7 +70,7 @@
|
|
|
70
70
|
var(--wpds-color-foreground-interactive-brand-active);
|
|
71
71
|
}
|
|
72
72
|
|
|
73
|
-
.
|
|
73
|
+
.handle-horizontal {
|
|
74
74
|
display: flex;
|
|
75
75
|
align-items: center;
|
|
76
76
|
justify-content: center;
|
|
@@ -82,7 +82,7 @@
|
|
|
82
82
|
}
|
|
83
83
|
|
|
84
84
|
@media not ( prefers-reduced-motion ) {
|
|
85
|
-
.
|
|
85
|
+
.handle-corner::after {
|
|
86
86
|
transition:
|
|
87
87
|
transform var(--wpds-motion-duration-xs)
|
|
88
88
|
var(--wpds-motion-easing-balanced),
|
|
@@ -92,7 +92,7 @@
|
|
|
92
92
|
var(--wpds-motion-easing-balanced);
|
|
93
93
|
}
|
|
94
94
|
|
|
95
|
-
.
|
|
95
|
+
.handle-horizontal::after {
|
|
96
96
|
transition:
|
|
97
97
|
transform var(--wpds-motion-duration-xs)
|
|
98
98
|
var(--wpds-motion-easing-balanced),
|
|
@@ -101,7 +101,7 @@
|
|
|
101
101
|
}
|
|
102
102
|
}
|
|
103
103
|
|
|
104
|
-
.
|
|
104
|
+
.handle-horizontal::after {
|
|
105
105
|
content: "";
|
|
106
106
|
width: var(--wpds-border-width-sm);
|
|
107
107
|
height: var(--wpds-dimension-size-3xs);
|
|
@@ -110,26 +110,26 @@
|
|
|
110
110
|
transform-origin: 50% 100%;
|
|
111
111
|
}
|
|
112
112
|
|
|
113
|
-
.
|
|
114
|
-
.
|
|
115
|
-
.
|
|
113
|
+
.handle-horizontal.resizing::after,
|
|
114
|
+
.handle-horizontal:hover::after,
|
|
115
|
+
.handle-horizontal:focus-visible::after {
|
|
116
116
|
transform: scale(var(--widget-resize-handle-hover-scale));
|
|
117
117
|
background-color: var(--wpds-color-foreground-interactive-brand-active);
|
|
118
118
|
}
|
|
119
119
|
|
|
120
120
|
@media (forced-colors: active) {
|
|
121
|
-
.
|
|
122
|
-
.
|
|
123
|
-
.
|
|
124
|
-
.
|
|
121
|
+
.handle-corner::after,
|
|
122
|
+
.handle-corner.resizing::after,
|
|
123
|
+
.handle-corner:hover::after,
|
|
124
|
+
.handle-corner:focus-visible::after {
|
|
125
125
|
border-block-end-color: Highlight;
|
|
126
126
|
border-inline-end-color: Highlight;
|
|
127
127
|
}
|
|
128
128
|
|
|
129
|
-
.
|
|
130
|
-
.
|
|
131
|
-
.
|
|
132
|
-
.
|
|
129
|
+
.handle-horizontal::after,
|
|
130
|
+
.handle-horizontal.resizing::after,
|
|
131
|
+
.handle-horizontal:hover::after,
|
|
132
|
+
.handle-horizontal:focus-visible::after {
|
|
133
133
|
background-color: Highlight;
|
|
134
134
|
}
|
|
135
135
|
}
|
|
@@ -36,7 +36,7 @@ export const WidgetResizeHandle = forwardRef<
|
|
|
36
36
|
ref={ ref }
|
|
37
37
|
className={ clsx(
|
|
38
38
|
styles.handle,
|
|
39
|
-
styles
|
|
39
|
+
styles[ 'handle-horizontal' ],
|
|
40
40
|
isResizing && styles.resizing
|
|
41
41
|
) }
|
|
42
42
|
{ ...listeners }
|
|
@@ -50,7 +50,7 @@ export const WidgetResizeHandle = forwardRef<
|
|
|
50
50
|
ref={ ref }
|
|
51
51
|
className={ clsx(
|
|
52
52
|
styles.handle,
|
|
53
|
-
styles
|
|
53
|
+
styles[ 'handle-corner' ],
|
|
54
54
|
isResizing && styles.resizing
|
|
55
55
|
) }
|
|
56
56
|
{ ...listeners }
|
|
@@ -1,11 +1,14 @@
|
|
|
1
1
|
.grid {
|
|
2
|
-
/* stylelint-disable-next-line property-no-unknown -- container queries for the dashboard grid surface */
|
|
3
2
|
container-type: inline-size;
|
|
4
3
|
container-name: widget-dashboard;
|
|
5
4
|
width: 100%;
|
|
6
5
|
/* Placeholder and drag-preview radii: match `.tile` and `@wordpress/ui` Card (`--wpds-border-radius-lg`). */
|
|
7
6
|
--wp-grid-placeholder-radius: var(--wpds-border-radius-lg);
|
|
8
7
|
--wp-grid-drag-preview-radius: var(--wpds-border-radius-lg);
|
|
8
|
+
/* Reserve top paint space so scroll containers do not clip tile focus rings. */
|
|
9
|
+
--wp-widget-dashboard-tile-focus-offset: 2px;
|
|
10
|
+
--wp-widget-dashboard-focus-ring-reserve: calc(var(--wpds-border-width-focus) + var(--wp-widget-dashboard-tile-focus-offset));
|
|
11
|
+
padding-block-start: var(--wp-widget-dashboard-focus-ring-reserve);
|
|
9
12
|
}
|
|
10
13
|
|
|
11
14
|
.tile {
|
|
@@ -14,16 +17,22 @@
|
|
|
14
17
|
}
|
|
15
18
|
|
|
16
19
|
/*
|
|
17
|
-
* Edit-mode tiles
|
|
18
|
-
*
|
|
20
|
+
* Edit-mode tiles keep their resting shadow on hover; only the drag preview
|
|
21
|
+
* (`.drag-preview-frame` on `@wordpress/grid`) uses a stronger shadow.
|
|
19
22
|
*/
|
|
20
|
-
.
|
|
21
|
-
|
|
23
|
+
.tile-edit-mode {
|
|
24
|
+
--_wp-widget-dashboard-elevation-xs:
|
|
25
|
+
0 1px 1px rgba(0, 0, 0, 0.03),
|
|
26
|
+
0 1px 2px rgba(0, 0, 0, 0.02),
|
|
27
|
+
0 3px 3px rgba(0, 0, 0, 0.02),
|
|
28
|
+
0 4px 4px rgba(0, 0, 0, 0.01);
|
|
29
|
+
|
|
30
|
+
box-shadow: var(--_wp-widget-dashboard-elevation-xs);
|
|
22
31
|
}
|
|
23
32
|
|
|
24
|
-
.
|
|
33
|
+
.tile-edit-mode:focus-visible {
|
|
25
34
|
outline: var(--wpds-border-width-focus) solid var(--wpds-color-stroke-focus);
|
|
26
|
-
outline-offset: 2px;
|
|
35
|
+
outline-offset: var(--wp-widget-dashboard-tile-focus-offset, 2px);
|
|
27
36
|
}
|
|
28
37
|
|
|
29
38
|
/*
|
|
@@ -31,13 +40,13 @@
|
|
|
31
40
|
* `height: 100%` keeps the inner `.tile` height: 100% chain alive
|
|
32
41
|
* (without it, the wrapper auto-sizes and the cloned tile collapses
|
|
33
42
|
* to content height). Drag elevation is owned by the grid
|
|
34
|
-
* `.drag-preview-frame
|
|
35
|
-
*
|
|
43
|
+
* `.drag-preview-frame`; strip the cloned tile shadow so it does not stack on
|
|
44
|
+
* the frame.
|
|
36
45
|
*/
|
|
37
|
-
.
|
|
46
|
+
.drag-preview {
|
|
38
47
|
height: 100%;
|
|
39
48
|
}
|
|
40
49
|
|
|
41
|
-
.
|
|
50
|
+
.drag-preview .tile {
|
|
42
51
|
box-shadow: none;
|
|
43
52
|
}
|
|
@@ -21,9 +21,11 @@ import type { WidgetName } from '@wordpress/widget-primitives';
|
|
|
21
21
|
*/
|
|
22
22
|
import { useDashboardInternalContext } from '../../context/dashboard-context';
|
|
23
23
|
import { useDashboardContainerColumnCount } from '../../hooks/use-dashboard-container-column-count';
|
|
24
|
+
import { WidgetAttributeControls } from '../widget-attribute-controls';
|
|
24
25
|
import { WidgetChrome } from '../widget-chrome';
|
|
25
|
-
import {
|
|
26
|
-
import {
|
|
26
|
+
import { WidgetHeader } from '../widget-header';
|
|
27
|
+
import { WidgetLayoutControls } from '../widget-layout-controls';
|
|
28
|
+
import { WidgetToolbar } from '../widget-toolbar';
|
|
27
29
|
import { WidgetResizeHandle } from './widget-resize-handle';
|
|
28
30
|
import styles from './widgets.module.css';
|
|
29
31
|
import type {
|
|
@@ -132,37 +134,58 @@ export const Widgets = forwardRef< HTMLDivElement, WidgetsProps >(
|
|
|
132
134
|
( type ) => type.name === widget.type
|
|
133
135
|
);
|
|
134
136
|
const hasSettings = !! widgetType?.attributes?.length;
|
|
137
|
+
const isFullBleed = widgetType?.presentation === 'full-bleed';
|
|
135
138
|
|
|
136
|
-
//
|
|
137
|
-
//
|
|
138
|
-
|
|
139
|
+
// The active mode's controls: layout while customizing, the
|
|
140
|
+
// attribute controls (high-relevance fields on the prominent
|
|
141
|
+
// surface, plus a settings entry point when needed)
|
|
142
|
+
// otherwise.
|
|
143
|
+
let controls: React.ReactNode;
|
|
139
144
|
if ( editMode ) {
|
|
140
|
-
|
|
145
|
+
controls = <WidgetLayoutControls widget={ widget } />;
|
|
141
146
|
} else if ( hasSettings && widgetType ) {
|
|
142
|
-
|
|
143
|
-
<
|
|
147
|
+
controls = (
|
|
148
|
+
<WidgetAttributeControls
|
|
144
149
|
widget={ widget }
|
|
145
150
|
widgetType={ widgetType }
|
|
146
151
|
/>
|
|
147
152
|
);
|
|
148
153
|
}
|
|
149
154
|
|
|
155
|
+
const toolbar = controls ? (
|
|
156
|
+
<WidgetToolbar editMode={ editMode }>
|
|
157
|
+
{ controls }
|
|
158
|
+
</WidgetToolbar>
|
|
159
|
+
) : undefined;
|
|
160
|
+
|
|
161
|
+
// Normal mode hosts the toolbar in the in-card header, beside the
|
|
162
|
+
// identity. Customize controls and full-bleed widgets need it in
|
|
163
|
+
// the grid's actionable-area slot instead: the slot sits outside
|
|
164
|
+
// the draggable card, so the controls stay clickable (in-card they
|
|
165
|
+
// would be captured by the drag listeners).
|
|
166
|
+
const inSlot = editMode || isFullBleed;
|
|
167
|
+
const actionableArea =
|
|
168
|
+
inSlot && toolbar ? (
|
|
169
|
+
<WidgetHeader overlay>{ toolbar }</WidgetHeader>
|
|
170
|
+
) : undefined;
|
|
171
|
+
|
|
150
172
|
return (
|
|
151
173
|
<WidgetChrome
|
|
152
174
|
key={ widget.uuid }
|
|
153
175
|
widget={ widget }
|
|
154
176
|
index={ index }
|
|
155
177
|
className={ clsx( styles.tile, {
|
|
156
|
-
[ styles
|
|
178
|
+
[ styles[ 'tile-edit-mode' ] ]: editMode,
|
|
157
179
|
} ) }
|
|
158
180
|
actionableArea={ actionableArea }
|
|
181
|
+
headerToolbar={ ! inSlot ? toolbar : undefined }
|
|
159
182
|
/>
|
|
160
183
|
);
|
|
161
184
|
} );
|
|
162
185
|
|
|
163
186
|
const renderDragPreview = useCallback(
|
|
164
187
|
( { children: clone }: DragPreviewRenderProps ) => (
|
|
165
|
-
<div className={ styles
|
|
188
|
+
<div className={ styles[ 'drag-preview' ] }>{ clone }</div>
|
|
166
189
|
),
|
|
167
190
|
[]
|
|
168
191
|
);
|