@wordpress/views 1.9.0 → 1.10.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 (39) hide show
  1. package/README.md +14 -0
  2. package/build/index.cjs +5 -2
  3. package/build/index.cjs.map +2 -2
  4. package/build/load-view.cjs +3 -1
  5. package/build/load-view.cjs.map +2 -2
  6. package/build/lock-unlock.cjs +37 -0
  7. package/build/lock-unlock.cjs.map +7 -0
  8. package/build/types.cjs.map +1 -1
  9. package/build/use-view-config.cjs +44 -0
  10. package/build/use-view-config.cjs.map +7 -0
  11. package/build/use-view.cjs +11 -7
  12. package/build/use-view.cjs.map +2 -2
  13. package/build-module/index.mjs +3 -1
  14. package/build-module/index.mjs.map +2 -2
  15. package/build-module/load-view.mjs +3 -1
  16. package/build-module/load-view.mjs.map +2 -2
  17. package/build-module/lock-unlock.mjs +11 -0
  18. package/build-module/lock-unlock.mjs.map +7 -0
  19. package/build-module/use-view-config.mjs +19 -0
  20. package/build-module/use-view-config.mjs.map +7 -0
  21. package/build-module/use-view.mjs +11 -7
  22. package/build-module/use-view.mjs.map +2 -2
  23. package/build-types/index.d.ts +1 -0
  24. package/build-types/index.d.ts.map +1 -1
  25. package/build-types/load-view.d.ts.map +1 -1
  26. package/build-types/lock-unlock.d.ts +2 -0
  27. package/build-types/lock-unlock.d.ts.map +1 -0
  28. package/build-types/types.d.ts +7 -1
  29. package/build-types/types.d.ts.map +1 -1
  30. package/build-types/use-view-config.d.ts +20 -0
  31. package/build-types/use-view-config.d.ts.map +1 -0
  32. package/build-types/use-view.d.ts.map +1 -1
  33. package/package.json +8 -6
  34. package/src/index.ts +1 -0
  35. package/src/load-view.ts +7 -1
  36. package/src/lock-unlock.ts +10 -0
  37. package/src/types.ts +8 -1
  38. package/src/use-view-config.ts +40 -0
  39. package/src/use-view.ts +15 -7
package/README.md CHANGED
@@ -51,4 +51,18 @@ _Returns_
51
51
 
52
52
  - `UseViewReturn`: Object with current view, modification state, and update functions.
53
53
 
54
+ ### useViewConfig
55
+
56
+ A hook that retrieves the view configuration for a given entity from the core data store.
57
+
58
+ _Parameters_
59
+
60
+ - _params_ `Object`:
61
+ - _params.kind_ `string`: The kind of the entity.
62
+ - _params.name_ `string`: The name of the entity.
63
+
64
+ _Returns_
65
+
66
+ - `Object`: An object containing the `default_view`, `default_layouts`, and `view_list` configuration for the entity.
67
+
54
68
  <!-- END TOKEN(Autogenerated API docs) -->
package/build/index.cjs CHANGED
@@ -21,14 +21,17 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
21
21
  var index_exports = {};
22
22
  __export(index_exports, {
23
23
  loadView: () => import_load_view.loadView,
24
- useView: () => import_use_view.useView
24
+ useView: () => import_use_view.useView,
25
+ useViewConfig: () => import_use_view_config.useViewConfig
25
26
  });
26
27
  module.exports = __toCommonJS(index_exports);
27
28
  var import_use_view = require("./use-view.cjs");
28
29
  var import_load_view = require("./load-view.cjs");
30
+ var import_use_view_config = require("./use-view-config.cjs");
29
31
  // Annotate the CommonJS export names for ESM import in node:
30
32
  0 && (module.exports = {
31
33
  loadView,
32
- useView
34
+ useView,
35
+ useViewConfig
33
36
  });
34
37
  //# sourceMappingURL=index.cjs.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../src/index.ts"],
4
- "sourcesContent": ["export { useView } from './use-view';\nexport { loadView } from './load-view';\n"],
5
- "mappings": ";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,sBAAwB;AACxB,uBAAyB;",
4
+ "sourcesContent": ["export { useView } from './use-view';\nexport { loadView } from './load-view';\nexport { useViewConfig } from './use-view-config';\n"],
5
+ "mappings": ";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,sBAAwB;AACxB,uBAAyB;AACzB,6BAA8B;",
6
6
  "names": []
7
7
  }
@@ -37,13 +37,15 @@ async function loadView(config) {
37
37
  const baseView = persistedView ?? defaultView;
38
38
  const page = queryParams?.page ?? 1;
39
39
  const search = queryParams?.search ?? "";
40
+ const layoutTypeDefaults = config.defaultLayouts?.[baseView?.type] ?? {};
41
+ const combinedOverrides = { ...layoutTypeDefaults, ...activeViewOverrides };
40
42
  return (0, import_filter_utils.mergeActiveViewOverrides)(
41
43
  {
42
44
  ...baseView,
43
45
  page,
44
46
  search
45
47
  },
46
- activeViewOverrides,
48
+ combinedOverrides,
47
49
  defaultView
48
50
  );
49
51
  }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../src/load-view.ts"],
4
- "sourcesContent": ["/**\n * WordPress dependencies\n */\nimport { select } from '@wordpress/data';\n// @ts-ignore - Preferences package is not typed\nimport { store as preferencesStore } from '@wordpress/preferences';\nimport type { View } from '@wordpress/dataviews';\n\n/**\n * Internal dependencies\n */\nimport { generatePreferenceKey } from './preference-keys';\nimport { mergeActiveViewOverrides } from './filter-utils';\nimport type { ViewConfig } from './types';\n\n/**\n * Async function for loading view state in route loaders.\n *\n * @param config Configuration object for loading the view.\n * @param config.kind Entity kind (e.g., 'postType', 'taxonomy', 'root').\n * @param config.name Specific entity name.\n * @param config.slug View identifier.\n * @param config.defaultView Default view configuration.\n * @param config.activeViewOverrides View overrides applied on top but never persisted.\n * @param config.queryParams Object with `page` and/or `search` from URL.\n * @return Promise resolving to the loaded view object.\n */\nexport async function loadView( config: ViewConfig ) {\n\tconst { kind, name, slug, defaultView, activeViewOverrides, queryParams } =\n\t\tconfig;\n\tconst preferenceKey = generatePreferenceKey( kind, name, slug );\n\tconst persistedView: View | undefined = select( preferencesStore ).get(\n\t\t'core/views',\n\t\tpreferenceKey\n\t) as View | undefined;\n\n\tconst baseView = persistedView ?? defaultView;\n\tconst page = queryParams?.page ?? 1;\n\tconst search = queryParams?.search ?? '';\n\n\treturn mergeActiveViewOverrides(\n\t\t{\n\t\t\t...baseView,\n\t\t\tpage,\n\t\t\tsearch,\n\t\t},\n\t\tactiveViewOverrides,\n\t\tdefaultView\n\t);\n}\n"],
5
- "mappings": ";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAGA,kBAAuB;AAEvB,yBAA0C;AAM1C,6BAAsC;AACtC,0BAAyC;AAezC,eAAsB,SAAU,QAAqB;AACpD,QAAM,EAAE,MAAM,MAAM,MAAM,aAAa,qBAAqB,YAAY,IACvE;AACD,QAAM,oBAAgB,8CAAuB,MAAM,MAAM,IAAK;AAC9D,QAAM,oBAAkC,oBAAQ,mBAAAA,KAAiB,EAAE;AAAA,IAClE;AAAA,IACA;AAAA,EACD;AAEA,QAAM,WAAW,iBAAiB;AAClC,QAAM,OAAO,aAAa,QAAQ;AAClC,QAAM,SAAS,aAAa,UAAU;AAEtC,aAAO;AAAA,IACN;AAAA,MACC,GAAG;AAAA,MACH;AAAA,MACA;AAAA,IACD;AAAA,IACA;AAAA,IACA;AAAA,EACD;AACD;",
4
+ "sourcesContent": ["/**\n * WordPress dependencies\n */\nimport { select } from '@wordpress/data';\n// @ts-ignore - Preferences package is not typed\nimport { store as preferencesStore } from '@wordpress/preferences';\nimport type { View } from '@wordpress/dataviews';\n\n/**\n * Internal dependencies\n */\nimport { generatePreferenceKey } from './preference-keys';\nimport { mergeActiveViewOverrides } from './filter-utils';\nimport type { ViewConfig } from './types';\n\n/**\n * Async function for loading view state in route loaders.\n *\n * @param config Configuration object for loading the view.\n * @param config.kind Entity kind (e.g., 'postType', 'taxonomy', 'root').\n * @param config.name Specific entity name.\n * @param config.slug View identifier.\n * @param config.defaultView Default view configuration.\n * @param config.activeViewOverrides View overrides applied on top but never persisted.\n * @param config.queryParams Object with `page` and/or `search` from URL.\n * @return Promise resolving to the loaded view object.\n */\nexport async function loadView( config: ViewConfig ) {\n\tconst { kind, name, slug, defaultView, activeViewOverrides, queryParams } =\n\t\tconfig;\n\tconst preferenceKey = generatePreferenceKey( kind, name, slug );\n\tconst persistedView: View | undefined = select( preferencesStore ).get(\n\t\t'core/views',\n\t\tpreferenceKey\n\t) as View | undefined;\n\n\tconst baseView = persistedView ?? defaultView;\n\tconst page = queryParams?.page ?? 1;\n\tconst search = queryParams?.search ?? '';\n\n\tconst layoutTypeDefaults =\n\t\tconfig.defaultLayouts?.[\n\t\t\tbaseView?.type as keyof typeof config.defaultLayouts\n\t\t] ?? {};\n\tconst combinedOverrides = { ...layoutTypeDefaults, ...activeViewOverrides };\n\n\treturn mergeActiveViewOverrides(\n\t\t{\n\t\t\t...baseView,\n\t\t\tpage,\n\t\t\tsearch,\n\t\t},\n\t\tcombinedOverrides,\n\t\tdefaultView\n\t);\n}\n"],
5
+ "mappings": ";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAGA,kBAAuB;AAEvB,yBAA0C;AAM1C,6BAAsC;AACtC,0BAAyC;AAezC,eAAsB,SAAU,QAAqB;AACpD,QAAM,EAAE,MAAM,MAAM,MAAM,aAAa,qBAAqB,YAAY,IACvE;AACD,QAAM,oBAAgB,8CAAuB,MAAM,MAAM,IAAK;AAC9D,QAAM,oBAAkC,oBAAQ,mBAAAA,KAAiB,EAAE;AAAA,IAClE;AAAA,IACA;AAAA,EACD;AAEA,QAAM,WAAW,iBAAiB;AAClC,QAAM,OAAO,aAAa,QAAQ;AAClC,QAAM,SAAS,aAAa,UAAU;AAEtC,QAAM,qBACL,OAAO,iBACN,UAAU,IACX,KAAK,CAAC;AACP,QAAM,oBAAoB,EAAE,GAAG,oBAAoB,GAAG,oBAAoB;AAE1E,aAAO;AAAA,IACN;AAAA,MACC,GAAG;AAAA,MACH;AAAA,MACA;AAAA,IACD;AAAA,IACA;AAAA,IACA;AAAA,EACD;AACD;",
6
6
  "names": ["preferencesStore"]
7
7
  }
@@ -0,0 +1,37 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // packages/views/src/lock-unlock.ts
21
+ var lock_unlock_exports = {};
22
+ __export(lock_unlock_exports, {
23
+ lock: () => lock,
24
+ unlock: () => unlock
25
+ });
26
+ module.exports = __toCommonJS(lock_unlock_exports);
27
+ var import_private_apis = require("@wordpress/private-apis");
28
+ var { lock, unlock } = (0, import_private_apis.__dangerousOptInToUnstableAPIsOnlyForCoreModules)(
29
+ "I acknowledge private features are not for use in themes or plugins and doing so will break in the next version of WordPress.",
30
+ "@wordpress/views"
31
+ );
32
+ // Annotate the CommonJS export names for ESM import in node:
33
+ 0 && (module.exports = {
34
+ lock,
35
+ unlock
36
+ });
37
+ //# sourceMappingURL=lock-unlock.cjs.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/lock-unlock.ts"],
4
+ "sourcesContent": ["/**\n * WordPress dependencies\n */\nimport { __dangerousOptInToUnstableAPIsOnlyForCoreModules } from '@wordpress/private-apis';\n\nexport const { lock, unlock } =\n\t__dangerousOptInToUnstableAPIsOnlyForCoreModules(\n\t\t'I acknowledge private features are not for use in themes or plugins and doing so will break in the next version of WordPress.',\n\t\t'@wordpress/views'\n\t);\n"],
5
+ "mappings": ";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAGA,0BAAiE;AAE1D,IAAM,EAAE,MAAM,OAAO,QAC3B;AAAA,EACC;AAAA,EACA;AACD;",
6
+ "names": []
7
+ }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../src/types.ts"],
4
- "sourcesContent": ["/**\n * WordPress dependencies\n */\nimport type { View } from '@wordpress/dataviews';\n\nexport type ActiveViewOverrides = {\n\t// scalar values\n\ttitleField?: View[ 'titleField' ];\n\tshowTitle?: View[ 'showTitle' ];\n\tmediaField?: View[ 'mediaField' ];\n\tshowMedia?: View[ 'showMedia' ];\n\tdescriptionField?: View[ 'descriptionField' ];\n\tshowDescription?: View[ 'showDescription' ];\n\tshowLevels?: View[ 'showLevels' ];\n\tinfiniteScrollEnabled?: View[ 'infiniteScrollEnabled' ];\n\t// array & object values\n\tfilters?: View[ 'filters' ];\n\tsort?: View[ 'sort' ];\n\tgroupBy?: View[ 'groupBy' ];\n\tlayout?: Record< string, unknown >;\n};\n\nexport interface ViewConfig {\n\t/**\n\t * Entity kind (e.g. postType, root).\n\t * Similar to core-data entity kinds.\n\t */\n\tkind: string;\n\n\t/**\n\t * Entity name (e.g. post, page, user, site).\n\t * Similar to core-data entity names.\n\t */\n\tname: string;\n\n\t/**\n\t * Identifier for the current view (all, published, mine, etc.)\n\t */\n\tslug: string;\n\n\t/**\n\t * Default view configuration\n\t */\n\tdefaultView: View;\n\n\t/**\n\t * View overrides applied on top of the persisted view but never persisted.\n\t * These represent tab-specific configuration (filters, sort) and\n\t * developer-defined view defaults that should override the persisted\n\t * view settings.\n\t */\n\tactiveViewOverrides?: ActiveViewOverrides;\n\n\t/**\n\t * Optional query parameters from URL (page, search)\n\t */\n\tqueryParams?: {\n\t\tpage?: number;\n\t\tsearch?: string;\n\t};\n\n\t/**\n\t * Callback for when URL query parameters should change\n\t */\n\tonChangeQueryParams?: ( params: {\n\t\tpage?: number;\n\t\tsearch?: string;\n\t} ) => void;\n}\n"],
4
+ "sourcesContent": ["/**\n * WordPress dependencies\n */\nimport type { View, SupportedLayouts } from '@wordpress/dataviews';\n\nexport type ActiveViewOverrides = {\n\t// scalar values\n\ttitleField?: View[ 'titleField' ];\n\tshowTitle?: View[ 'showTitle' ];\n\tmediaField?: View[ 'mediaField' ];\n\tshowMedia?: View[ 'showMedia' ];\n\tdescriptionField?: View[ 'descriptionField' ];\n\tshowDescription?: View[ 'showDescription' ];\n\tshowLevels?: View[ 'showLevels' ];\n\tinfiniteScrollEnabled?: View[ 'infiniteScrollEnabled' ];\n\t// array & object values\n\tfilters?: View[ 'filters' ];\n\tsort?: View[ 'sort' ];\n\tgroupBy?: View[ 'groupBy' ];\n\tlayout?: Record< string, unknown >;\n};\n\nexport interface ViewConfig {\n\t/**\n\t * Entity kind (e.g. postType, root).\n\t * Similar to core-data entity kinds.\n\t */\n\tkind: string;\n\n\t/**\n\t * Entity name (e.g. post, page, user, site).\n\t * Similar to core-data entity names.\n\t */\n\tname: string;\n\n\t/**\n\t * Identifier for the current view (all, published, mine, etc.)\n\t */\n\tslug: string;\n\n\t/**\n\t * Default view configuration\n\t */\n\tdefaultView: View;\n\n\t/**\n\t * View overrides applied on top of the persisted view but never persisted.\n\t * These represent tab-specific configuration (filters, sort) and\n\t * developer-defined view defaults that should override the persisted\n\t * view settings.\n\t */\n\tactiveViewOverrides?: ActiveViewOverrides;\n\n\t/**\n\t * Default layout configurations keyed by layout type.\n\t * Used to apply layout-type-specific defaults (e.g., table column styles)\n\t * that are merged as overrides based on the resolved view type.\n\t */\n\tdefaultLayouts?: SupportedLayouts;\n\n\t/**\n\t * Optional query parameters from URL (page, search)\n\t */\n\tqueryParams?: {\n\t\tpage?: number;\n\t\tsearch?: string;\n\t};\n\n\t/**\n\t * Callback for when URL query parameters should change\n\t */\n\tonChangeQueryParams?: ( params: {\n\t\tpage?: number;\n\t\tsearch?: string;\n\t} ) => void;\n}\n"],
5
5
  "mappings": ";;;;;;;;;;;;;;;;AAAA;AAAA;",
6
6
  "names": []
7
7
  }
@@ -0,0 +1,44 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // packages/views/src/use-view-config.ts
21
+ var use_view_config_exports = {};
22
+ __export(use_view_config_exports, {
23
+ useViewConfig: () => useViewConfig
24
+ });
25
+ module.exports = __toCommonJS(use_view_config_exports);
26
+ var import_data = require("@wordpress/data");
27
+ var import_core_data = require("@wordpress/core-data");
28
+ var import_lock_unlock = require("./lock-unlock.cjs");
29
+ function useViewConfig({
30
+ kind,
31
+ name
32
+ }) {
33
+ return (0, import_data.useSelect)(
34
+ (select) => {
35
+ return (0, import_lock_unlock.unlock)(select(import_core_data.store)).getViewConfig(kind, name);
36
+ },
37
+ [kind, name]
38
+ );
39
+ }
40
+ // Annotate the CommonJS export names for ESM import in node:
41
+ 0 && (module.exports = {
42
+ useViewConfig
43
+ });
44
+ //# sourceMappingURL=use-view-config.cjs.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/use-view-config.ts"],
4
+ "sourcesContent": ["/**\n * WordPress dependencies\n */\nimport { useSelect } from '@wordpress/data';\nimport { store as coreStore } from '@wordpress/core-data';\nimport type { View, SupportedLayouts, Form } from '@wordpress/dataviews';\n\n/**\n * Internal dependencies\n */\nimport { unlock } from './lock-unlock';\n\n/**\n * A hook that retrieves the view configuration for a given entity\n * from the core data store.\n *\n * @param {Object} params\n * @param {string} params.kind The kind of the entity.\n * @param {string} params.name The name of the entity.\n * @return {Object} An object containing the `default_view`, `default_layouts`, and `view_list` configuration for the entity.\n */\nexport function useViewConfig( {\n\tkind,\n\tname,\n}: {\n\tkind: string;\n\tname: string;\n} ): {\n\tdefault_view: View;\n\tdefault_layouts: SupportedLayouts;\n\tview_list: Array< any >;\n\tform: Form | undefined;\n} {\n\treturn useSelect(\n\t\t( select ) => {\n\t\t\treturn unlock( select( coreStore ) ).getViewConfig( kind, name );\n\t\t},\n\t\t[ kind, name ]\n\t);\n}\n"],
5
+ "mappings": ";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAGA,kBAA0B;AAC1B,uBAAmC;AAMnC,yBAAuB;AAWhB,SAAS,cAAe;AAAA,EAC9B;AAAA,EACA;AACD,GAQE;AACD,aAAO;AAAA,IACN,CAAE,WAAY;AACb,iBAAO,2BAAQ,OAAQ,iBAAAA,KAAU,CAAE,EAAE,cAAe,MAAM,IAAK;AAAA,IAChE;AAAA,IACA,CAAE,MAAM,IAAK;AAAA,EACd;AACD;",
6
+ "names": ["coreStore"]
7
+ }
@@ -57,9 +57,13 @@ function useView(config) {
57
57
  [preferenceKey]
58
58
  );
59
59
  const { set } = (0, import_data.useDispatch)(import_preferences.store);
60
- const baseView = persistedView ?? defaultView;
60
+ const baseView = persistedView ?? defaultView ?? {};
61
61
  const page = Number(queryParams?.page ?? baseView.page ?? 1);
62
62
  const search = queryParams?.search ?? baseView.search ?? "";
63
+ const combinedOverrides = (0, import_element.useMemo)(() => {
64
+ const layoutTypeDefaults = config.defaultLayouts?.[baseView.type] ?? {};
65
+ return { ...layoutTypeDefaults, ...activeViewOverrides };
66
+ }, [config.defaultLayouts, baseView.type, activeViewOverrides]);
63
67
  const view = (0, import_element.useMemo)(() => {
64
68
  return (0, import_filter_utils.mergeActiveViewOverrides)(
65
69
  {
@@ -67,10 +71,10 @@ function useView(config) {
67
71
  page,
68
72
  search
69
73
  },
70
- activeViewOverrides,
74
+ combinedOverrides,
71
75
  defaultView
72
76
  );
73
- }, [baseView, page, search, activeViewOverrides, defaultView]);
77
+ }, [baseView, page, search, combinedOverrides, defaultView]);
74
78
  const isModified = !!persistedView;
75
79
  const updateView = (0, import_element.useCallback)(
76
80
  (newView) => {
@@ -80,7 +84,7 @@ function useView(config) {
80
84
  };
81
85
  const preferenceView = (0, import_filter_utils.stripActiveViewOverrides)(
82
86
  omit(newView, ["page", "search"]),
83
- activeViewOverrides,
87
+ combinedOverrides,
84
88
  defaultView
85
89
  );
86
90
  if (onChangeQueryParams && !(0, import_dequal.dequal)(urlParams, { page, search })) {
@@ -88,12 +92,12 @@ function useView(config) {
88
92
  }
89
93
  const comparableBaseView = (0, import_filter_utils.stripActiveViewOverrides)(
90
94
  baseView,
91
- activeViewOverrides,
95
+ combinedOverrides,
92
96
  defaultView
93
97
  );
94
98
  const comparableDefaultView = (0, import_filter_utils.stripActiveViewOverrides)(
95
99
  defaultView,
96
- activeViewOverrides,
100
+ combinedOverrides,
97
101
  defaultView
98
102
  );
99
103
  if (!(0, import_dequal.dequal)(comparableBaseView, preferenceView)) {
@@ -110,7 +114,7 @@ function useView(config) {
110
114
  search,
111
115
  baseView,
112
116
  defaultView,
113
- activeViewOverrides,
117
+ combinedOverrides,
114
118
  set,
115
119
  preferenceKey
116
120
  ]
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../src/use-view.ts"],
4
- "sourcesContent": ["/**\n * External dependencies\n */\nimport { dequal } from 'dequal';\n\n/**\n * WordPress dependencies\n */\nimport { useCallback, useMemo } from '@wordpress/element';\nimport { useDispatch, useSelect } from '@wordpress/data';\nimport type { View } from '@wordpress/dataviews';\n// @ts-ignore - Preferences package is not typed\nimport { store as preferencesStore } from '@wordpress/preferences';\n\n/**\n * Internal dependencies\n */\nimport { generatePreferenceKey } from './preference-keys';\nimport {\n\tmergeActiveViewOverrides,\n\tstripActiveViewOverrides,\n} from './filter-utils';\nimport type { ViewConfig } from './types';\n\ninterface UseViewReturn {\n\tview: View;\n\tisModified: boolean;\n\tupdateView: ( newView: View ) => void;\n\tresetToDefault: () => void;\n}\n\nfunction omit< T extends object, K extends keyof T >(\n\tobj: T,\n\tkeys: K[]\n): Omit< T, K > {\n\tconst result = { ...obj };\n\tfor ( const key of keys ) {\n\t\tdelete result[ key ];\n\t}\n\treturn result;\n}\n\n/**\n * Hook for managing DataViews view state with local persistence.\n *\n * @param config Configuration object for loading the view.\n *\n * @return Object with current view, modification state, and update functions.\n */\nexport function useView( config: ViewConfig ): UseViewReturn {\n\tconst {\n\t\tkind,\n\t\tname,\n\t\tslug,\n\t\tdefaultView,\n\t\tactiveViewOverrides,\n\t\tqueryParams,\n\t\tonChangeQueryParams,\n\t} = config;\n\n\tconst preferenceKey = generatePreferenceKey( kind, name, slug );\n\tconst persistedView: View | undefined = useSelect(\n\t\t( select ) => {\n\t\t\treturn select( preferencesStore ).get(\n\t\t\t\t'core/views',\n\t\t\t\tpreferenceKey\n\t\t\t) as View | undefined;\n\t\t},\n\t\t[ preferenceKey ]\n\t);\n\tconst { set } = useDispatch( preferencesStore );\n\n\tconst baseView: View = persistedView ?? defaultView;\n\tconst page = Number( queryParams?.page ?? baseView.page ?? 1 );\n\tconst search = queryParams?.search ?? baseView.search ?? '';\n\n\t// Merge URL query parameters (page, search) and activeViewOverrides into the view\n\tconst view: View = useMemo( () => {\n\t\treturn mergeActiveViewOverrides(\n\t\t\t{\n\t\t\t\t...baseView,\n\t\t\t\tpage,\n\t\t\t\tsearch,\n\t\t\t},\n\t\t\tactiveViewOverrides,\n\t\t\tdefaultView\n\t\t);\n\t}, [ baseView, page, search, activeViewOverrides, defaultView ] );\n\n\tconst isModified = !! persistedView;\n\n\tconst updateView = useCallback(\n\t\t( newView: View ) => {\n\t\t\t// Extract URL params (page, search) from the new view\n\t\t\tconst urlParams: { page?: number; search?: string } = {\n\t\t\t\tpage: newView?.page,\n\t\t\t\tsearch: newView?.search,\n\t\t\t};\n\t\t\t// Strip activeViewOverrides and URL params before persisting\n\t\t\t// Cast is safe: omitting page/search doesn't change the discriminant (type field)\n\t\t\tconst preferenceView = stripActiveViewOverrides(\n\t\t\t\tomit( newView, [ 'page', 'search' ] ) as View,\n\t\t\t\tactiveViewOverrides,\n\t\t\t\tdefaultView\n\t\t\t);\n\n\t\t\t// If we have URL handling enabled, separate URL state from preference state\n\t\t\tif (\n\t\t\t\tonChangeQueryParams &&\n\t\t\t\t! dequal( urlParams, { page, search } )\n\t\t\t) {\n\t\t\t\tonChangeQueryParams( urlParams );\n\t\t\t}\n\n\t\t\t// Compare with baseView and defaultView after stripping activeViewOverrides\n\t\t\tconst comparableBaseView = stripActiveViewOverrides(\n\t\t\t\tbaseView,\n\t\t\t\tactiveViewOverrides,\n\t\t\t\tdefaultView\n\t\t\t);\n\t\t\tconst comparableDefaultView = stripActiveViewOverrides(\n\t\t\t\tdefaultView,\n\t\t\t\tactiveViewOverrides,\n\t\t\t\tdefaultView\n\t\t\t);\n\n\t\t\t// Only persist non-URL preferences if different from baseView\n\t\t\tif ( ! dequal( comparableBaseView, preferenceView ) ) {\n\t\t\t\tif ( dequal( preferenceView, comparableDefaultView ) ) {\n\t\t\t\t\tset( 'core/views', preferenceKey, undefined );\n\t\t\t\t} else {\n\t\t\t\t\tset( 'core/views', preferenceKey, preferenceView );\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\t[\n\t\t\tonChangeQueryParams,\n\t\t\tpage,\n\t\t\tsearch,\n\t\t\tbaseView,\n\t\t\tdefaultView,\n\t\t\tactiveViewOverrides,\n\t\t\tset,\n\t\t\tpreferenceKey,\n\t\t]\n\t);\n\n\tconst resetToDefault = useCallback( () => {\n\t\tset( 'core/views', preferenceKey, undefined );\n\t}, [ preferenceKey, set ] );\n\n\treturn {\n\t\tview,\n\t\tisModified,\n\t\tupdateView,\n\t\tresetToDefault,\n\t};\n}\n"],
5
- "mappings": ";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAGA,oBAAuB;AAKvB,qBAAqC;AACrC,kBAAuC;AAGvC,yBAA0C;AAK1C,6BAAsC;AACtC,0BAGO;AAUP,SAAS,KACR,KACA,MACe;AACf,QAAM,SAAS,EAAE,GAAG,IAAI;AACxB,aAAY,OAAO,MAAO;AACzB,WAAO,OAAQ,GAAI;AAAA,EACpB;AACA,SAAO;AACR;AASO,SAAS,QAAS,QAAoC;AAC5D,QAAM;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACD,IAAI;AAEJ,QAAM,oBAAgB,8CAAuB,MAAM,MAAM,IAAK;AAC9D,QAAM,oBAAkC;AAAA,IACvC,CAAE,WAAY;AACb,aAAO,OAAQ,mBAAAA,KAAiB,EAAE;AAAA,QACjC;AAAA,QACA;AAAA,MACD;AAAA,IACD;AAAA,IACA,CAAE,aAAc;AAAA,EACjB;AACA,QAAM,EAAE,IAAI,QAAI,yBAAa,mBAAAA,KAAiB;AAE9C,QAAM,WAAiB,iBAAiB;AACxC,QAAM,OAAO,OAAQ,aAAa,QAAQ,SAAS,QAAQ,CAAE;AAC7D,QAAM,SAAS,aAAa,UAAU,SAAS,UAAU;AAGzD,QAAM,WAAa,wBAAS,MAAM;AACjC,eAAO;AAAA,MACN;AAAA,QACC,GAAG;AAAA,QACH;AAAA,QACA;AAAA,MACD;AAAA,MACA;AAAA,MACA;AAAA,IACD;AAAA,EACD,GAAG,CAAE,UAAU,MAAM,QAAQ,qBAAqB,WAAY,CAAE;AAEhE,QAAM,aAAa,CAAC,CAAE;AAEtB,QAAM,iBAAa;AAAA,IAClB,CAAE,YAAmB;AAEpB,YAAM,YAAgD;AAAA,QACrD,MAAM,SAAS;AAAA,QACf,QAAQ,SAAS;AAAA,MAClB;AAGA,YAAM,qBAAiB;AAAA,QACtB,KAAM,SAAS,CAAE,QAAQ,QAAS,CAAE;AAAA,QACpC;AAAA,QACA;AAAA,MACD;AAGA,UACC,uBACA,KAAE,sBAAQ,WAAW,EAAE,MAAM,OAAO,CAAE,GACrC;AACD,4BAAqB,SAAU;AAAA,MAChC;AAGA,YAAM,yBAAqB;AAAA,QAC1B;AAAA,QACA;AAAA,QACA;AAAA,MACD;AACA,YAAM,4BAAwB;AAAA,QAC7B;AAAA,QACA;AAAA,QACA;AAAA,MACD;AAGA,UAAK,KAAE,sBAAQ,oBAAoB,cAAe,GAAI;AACrD,gBAAK,sBAAQ,gBAAgB,qBAAsB,GAAI;AACtD,cAAK,cAAc,eAAe,MAAU;AAAA,QAC7C,OAAO;AACN,cAAK,cAAc,eAAe,cAAe;AAAA,QAClD;AAAA,MACD;AAAA,IACD;AAAA,IACA;AAAA,MACC;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACD;AAAA,EACD;AAEA,QAAM,qBAAiB,4BAAa,MAAM;AACzC,QAAK,cAAc,eAAe,MAAU;AAAA,EAC7C,GAAG,CAAE,eAAe,GAAI,CAAE;AAE1B,SAAO;AAAA,IACN;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACD;AACD;",
4
+ "sourcesContent": ["/**\n * External dependencies\n */\nimport { dequal } from 'dequal';\n\n/**\n * WordPress dependencies\n */\nimport { useCallback, useMemo } from '@wordpress/element';\nimport { useDispatch, useSelect } from '@wordpress/data';\nimport type { View } from '@wordpress/dataviews';\n// @ts-ignore - Preferences package is not typed\nimport { store as preferencesStore } from '@wordpress/preferences';\n\n/**\n * Internal dependencies\n */\nimport { generatePreferenceKey } from './preference-keys';\nimport {\n\tmergeActiveViewOverrides,\n\tstripActiveViewOverrides,\n} from './filter-utils';\nimport type { ViewConfig } from './types';\n\ninterface UseViewReturn {\n\tview: View;\n\tisModified: boolean;\n\tupdateView: ( newView: View ) => void;\n\tresetToDefault: () => void;\n}\n\nfunction omit< T extends object, K extends keyof T >(\n\tobj: T,\n\tkeys: K[]\n): Omit< T, K > {\n\tconst result = { ...obj };\n\tfor ( const key of keys ) {\n\t\tdelete result[ key ];\n\t}\n\treturn result;\n}\n\n/**\n * Hook for managing DataViews view state with local persistence.\n *\n * @param config Configuration object for loading the view.\n *\n * @return Object with current view, modification state, and update functions.\n */\nexport function useView( config: ViewConfig ): UseViewReturn {\n\tconst {\n\t\tkind,\n\t\tname,\n\t\tslug,\n\t\tdefaultView,\n\t\tactiveViewOverrides,\n\t\tqueryParams,\n\t\tonChangeQueryParams,\n\t} = config;\n\n\tconst preferenceKey = generatePreferenceKey( kind, name, slug );\n\tconst persistedView: View | undefined = useSelect(\n\t\t( select ) => {\n\t\t\treturn select( preferencesStore ).get(\n\t\t\t\t'core/views',\n\t\t\t\tpreferenceKey\n\t\t\t) as View | undefined;\n\t\t},\n\t\t[ preferenceKey ]\n\t);\n\tconst { set } = useDispatch( preferencesStore );\n\n\tconst baseView: View = persistedView ?? defaultView ?? {};\n\tconst page = Number( queryParams?.page ?? baseView.page ?? 1 );\n\tconst search = queryParams?.search ?? baseView.search ?? '';\n\n\tconst combinedOverrides = useMemo( () => {\n\t\tconst layoutTypeDefaults =\n\t\t\tconfig.defaultLayouts?.[\n\t\t\t\tbaseView.type as keyof typeof config.defaultLayouts\n\t\t\t] ?? {};\n\t\treturn { ...layoutTypeDefaults, ...activeViewOverrides };\n\t}, [ config.defaultLayouts, baseView.type, activeViewOverrides ] );\n\n\t// Merge URL query parameters (page, search) and activeViewOverrides into the view\n\tconst view: View = useMemo( () => {\n\t\treturn mergeActiveViewOverrides(\n\t\t\t{\n\t\t\t\t...baseView,\n\t\t\t\tpage,\n\t\t\t\tsearch,\n\t\t\t},\n\t\t\tcombinedOverrides,\n\t\t\tdefaultView\n\t\t);\n\t}, [ baseView, page, search, combinedOverrides, defaultView ] );\n\n\tconst isModified = !! persistedView;\n\n\tconst updateView = useCallback(\n\t\t( newView: View ) => {\n\t\t\t// Extract URL params (page, search) from the new view\n\t\t\tconst urlParams: { page?: number; search?: string } = {\n\t\t\t\tpage: newView?.page,\n\t\t\t\tsearch: newView?.search,\n\t\t\t};\n\t\t\t// Strip activeViewOverrides and URL params before persisting\n\t\t\t// Cast is safe: omitting page/search doesn't change the discriminant (type field)\n\t\t\tconst preferenceView = stripActiveViewOverrides(\n\t\t\t\tomit( newView, [ 'page', 'search' ] ) as View,\n\t\t\t\tcombinedOverrides,\n\t\t\t\tdefaultView\n\t\t\t);\n\n\t\t\t// If we have URL handling enabled, separate URL state from preference state\n\t\t\tif (\n\t\t\t\tonChangeQueryParams &&\n\t\t\t\t! dequal( urlParams, { page, search } )\n\t\t\t) {\n\t\t\t\tonChangeQueryParams( urlParams );\n\t\t\t}\n\n\t\t\t// Compare with baseView and defaultView after stripping activeViewOverrides\n\t\t\tconst comparableBaseView = stripActiveViewOverrides(\n\t\t\t\tbaseView,\n\t\t\t\tcombinedOverrides,\n\t\t\t\tdefaultView\n\t\t\t);\n\t\t\tconst comparableDefaultView = stripActiveViewOverrides(\n\t\t\t\tdefaultView,\n\t\t\t\tcombinedOverrides,\n\t\t\t\tdefaultView\n\t\t\t);\n\n\t\t\t// Only persist non-URL preferences if different from baseView\n\t\t\tif ( ! dequal( comparableBaseView, preferenceView ) ) {\n\t\t\t\tif ( dequal( preferenceView, comparableDefaultView ) ) {\n\t\t\t\t\tset( 'core/views', preferenceKey, undefined );\n\t\t\t\t} else {\n\t\t\t\t\tset( 'core/views', preferenceKey, preferenceView );\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\t[\n\t\t\tonChangeQueryParams,\n\t\t\tpage,\n\t\t\tsearch,\n\t\t\tbaseView,\n\t\t\tdefaultView,\n\t\t\tcombinedOverrides,\n\t\t\tset,\n\t\t\tpreferenceKey,\n\t\t]\n\t);\n\n\tconst resetToDefault = useCallback( () => {\n\t\tset( 'core/views', preferenceKey, undefined );\n\t}, [ preferenceKey, set ] );\n\n\treturn {\n\t\tview,\n\t\tisModified,\n\t\tupdateView,\n\t\tresetToDefault,\n\t};\n}\n"],
5
+ "mappings": ";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAGA,oBAAuB;AAKvB,qBAAqC;AACrC,kBAAuC;AAGvC,yBAA0C;AAK1C,6BAAsC;AACtC,0BAGO;AAUP,SAAS,KACR,KACA,MACe;AACf,QAAM,SAAS,EAAE,GAAG,IAAI;AACxB,aAAY,OAAO,MAAO;AACzB,WAAO,OAAQ,GAAI;AAAA,EACpB;AACA,SAAO;AACR;AASO,SAAS,QAAS,QAAoC;AAC5D,QAAM;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACD,IAAI;AAEJ,QAAM,oBAAgB,8CAAuB,MAAM,MAAM,IAAK;AAC9D,QAAM,oBAAkC;AAAA,IACvC,CAAE,WAAY;AACb,aAAO,OAAQ,mBAAAA,KAAiB,EAAE;AAAA,QACjC;AAAA,QACA;AAAA,MACD;AAAA,IACD;AAAA,IACA,CAAE,aAAc;AAAA,EACjB;AACA,QAAM,EAAE,IAAI,QAAI,yBAAa,mBAAAA,KAAiB;AAE9C,QAAM,WAAiB,iBAAiB,eAAe,CAAC;AACxD,QAAM,OAAO,OAAQ,aAAa,QAAQ,SAAS,QAAQ,CAAE;AAC7D,QAAM,SAAS,aAAa,UAAU,SAAS,UAAU;AAEzD,QAAM,wBAAoB,wBAAS,MAAM;AACxC,UAAM,qBACL,OAAO,iBACN,SAAS,IACV,KAAK,CAAC;AACP,WAAO,EAAE,GAAG,oBAAoB,GAAG,oBAAoB;AAAA,EACxD,GAAG,CAAE,OAAO,gBAAgB,SAAS,MAAM,mBAAoB,CAAE;AAGjE,QAAM,WAAa,wBAAS,MAAM;AACjC,eAAO;AAAA,MACN;AAAA,QACC,GAAG;AAAA,QACH;AAAA,QACA;AAAA,MACD;AAAA,MACA;AAAA,MACA;AAAA,IACD;AAAA,EACD,GAAG,CAAE,UAAU,MAAM,QAAQ,mBAAmB,WAAY,CAAE;AAE9D,QAAM,aAAa,CAAC,CAAE;AAEtB,QAAM,iBAAa;AAAA,IAClB,CAAE,YAAmB;AAEpB,YAAM,YAAgD;AAAA,QACrD,MAAM,SAAS;AAAA,QACf,QAAQ,SAAS;AAAA,MAClB;AAGA,YAAM,qBAAiB;AAAA,QACtB,KAAM,SAAS,CAAE,QAAQ,QAAS,CAAE;AAAA,QACpC;AAAA,QACA;AAAA,MACD;AAGA,UACC,uBACA,KAAE,sBAAQ,WAAW,EAAE,MAAM,OAAO,CAAE,GACrC;AACD,4BAAqB,SAAU;AAAA,MAChC;AAGA,YAAM,yBAAqB;AAAA,QAC1B;AAAA,QACA;AAAA,QACA;AAAA,MACD;AACA,YAAM,4BAAwB;AAAA,QAC7B;AAAA,QACA;AAAA,QACA;AAAA,MACD;AAGA,UAAK,KAAE,sBAAQ,oBAAoB,cAAe,GAAI;AACrD,gBAAK,sBAAQ,gBAAgB,qBAAsB,GAAI;AACtD,cAAK,cAAc,eAAe,MAAU;AAAA,QAC7C,OAAO;AACN,cAAK,cAAc,eAAe,cAAe;AAAA,QAClD;AAAA,MACD;AAAA,IACD;AAAA,IACA;AAAA,MACC;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACD;AAAA,EACD;AAEA,QAAM,qBAAiB,4BAAa,MAAM;AACzC,QAAK,cAAc,eAAe,MAAU;AAAA,EAC7C,GAAG,CAAE,eAAe,GAAI,CAAE;AAE1B,SAAO;AAAA,IACN;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACD;AACD;",
6
6
  "names": ["preferencesStore"]
7
7
  }
@@ -1,8 +1,10 @@
1
1
  // packages/views/src/index.ts
2
2
  import { useView } from "./use-view.mjs";
3
3
  import { loadView } from "./load-view.mjs";
4
+ import { useViewConfig } from "./use-view-config.mjs";
4
5
  export {
5
6
  loadView,
6
- useView
7
+ useView,
8
+ useViewConfig
7
9
  };
8
10
  //# sourceMappingURL=index.mjs.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../src/index.ts"],
4
- "sourcesContent": ["export { useView } from './use-view';\nexport { loadView } from './load-view';\n"],
5
- "mappings": ";AAAA,SAAS,eAAe;AACxB,SAAS,gBAAgB;",
4
+ "sourcesContent": ["export { useView } from './use-view';\nexport { loadView } from './load-view';\nexport { useViewConfig } from './use-view-config';\n"],
5
+ "mappings": ";AAAA,SAAS,eAAe;AACxB,SAAS,gBAAgB;AACzB,SAAS,qBAAqB;",
6
6
  "names": []
7
7
  }
@@ -13,13 +13,15 @@ async function loadView(config) {
13
13
  const baseView = persistedView ?? defaultView;
14
14
  const page = queryParams?.page ?? 1;
15
15
  const search = queryParams?.search ?? "";
16
+ const layoutTypeDefaults = config.defaultLayouts?.[baseView?.type] ?? {};
17
+ const combinedOverrides = { ...layoutTypeDefaults, ...activeViewOverrides };
16
18
  return mergeActiveViewOverrides(
17
19
  {
18
20
  ...baseView,
19
21
  page,
20
22
  search
21
23
  },
22
- activeViewOverrides,
24
+ combinedOverrides,
23
25
  defaultView
24
26
  );
25
27
  }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../src/load-view.ts"],
4
- "sourcesContent": ["/**\n * WordPress dependencies\n */\nimport { select } from '@wordpress/data';\n// @ts-ignore - Preferences package is not typed\nimport { store as preferencesStore } from '@wordpress/preferences';\nimport type { View } from '@wordpress/dataviews';\n\n/**\n * Internal dependencies\n */\nimport { generatePreferenceKey } from './preference-keys';\nimport { mergeActiveViewOverrides } from './filter-utils';\nimport type { ViewConfig } from './types';\n\n/**\n * Async function for loading view state in route loaders.\n *\n * @param config Configuration object for loading the view.\n * @param config.kind Entity kind (e.g., 'postType', 'taxonomy', 'root').\n * @param config.name Specific entity name.\n * @param config.slug View identifier.\n * @param config.defaultView Default view configuration.\n * @param config.activeViewOverrides View overrides applied on top but never persisted.\n * @param config.queryParams Object with `page` and/or `search` from URL.\n * @return Promise resolving to the loaded view object.\n */\nexport async function loadView( config: ViewConfig ) {\n\tconst { kind, name, slug, defaultView, activeViewOverrides, queryParams } =\n\t\tconfig;\n\tconst preferenceKey = generatePreferenceKey( kind, name, slug );\n\tconst persistedView: View | undefined = select( preferencesStore ).get(\n\t\t'core/views',\n\t\tpreferenceKey\n\t) as View | undefined;\n\n\tconst baseView = persistedView ?? defaultView;\n\tconst page = queryParams?.page ?? 1;\n\tconst search = queryParams?.search ?? '';\n\n\treturn mergeActiveViewOverrides(\n\t\t{\n\t\t\t...baseView,\n\t\t\tpage,\n\t\t\tsearch,\n\t\t},\n\t\tactiveViewOverrides,\n\t\tdefaultView\n\t);\n}\n"],
5
- "mappings": ";AAGA,SAAS,cAAc;AAEvB,SAAS,SAAS,wBAAwB;AAM1C,SAAS,6BAA6B;AACtC,SAAS,gCAAgC;AAezC,eAAsB,SAAU,QAAqB;AACpD,QAAM,EAAE,MAAM,MAAM,MAAM,aAAa,qBAAqB,YAAY,IACvE;AACD,QAAM,gBAAgB,sBAAuB,MAAM,MAAM,IAAK;AAC9D,QAAM,gBAAkC,OAAQ,gBAAiB,EAAE;AAAA,IAClE;AAAA,IACA;AAAA,EACD;AAEA,QAAM,WAAW,iBAAiB;AAClC,QAAM,OAAO,aAAa,QAAQ;AAClC,QAAM,SAAS,aAAa,UAAU;AAEtC,SAAO;AAAA,IACN;AAAA,MACC,GAAG;AAAA,MACH;AAAA,MACA;AAAA,IACD;AAAA,IACA;AAAA,IACA;AAAA,EACD;AACD;",
4
+ "sourcesContent": ["/**\n * WordPress dependencies\n */\nimport { select } from '@wordpress/data';\n// @ts-ignore - Preferences package is not typed\nimport { store as preferencesStore } from '@wordpress/preferences';\nimport type { View } from '@wordpress/dataviews';\n\n/**\n * Internal dependencies\n */\nimport { generatePreferenceKey } from './preference-keys';\nimport { mergeActiveViewOverrides } from './filter-utils';\nimport type { ViewConfig } from './types';\n\n/**\n * Async function for loading view state in route loaders.\n *\n * @param config Configuration object for loading the view.\n * @param config.kind Entity kind (e.g., 'postType', 'taxonomy', 'root').\n * @param config.name Specific entity name.\n * @param config.slug View identifier.\n * @param config.defaultView Default view configuration.\n * @param config.activeViewOverrides View overrides applied on top but never persisted.\n * @param config.queryParams Object with `page` and/or `search` from URL.\n * @return Promise resolving to the loaded view object.\n */\nexport async function loadView( config: ViewConfig ) {\n\tconst { kind, name, slug, defaultView, activeViewOverrides, queryParams } =\n\t\tconfig;\n\tconst preferenceKey = generatePreferenceKey( kind, name, slug );\n\tconst persistedView: View | undefined = select( preferencesStore ).get(\n\t\t'core/views',\n\t\tpreferenceKey\n\t) as View | undefined;\n\n\tconst baseView = persistedView ?? defaultView;\n\tconst page = queryParams?.page ?? 1;\n\tconst search = queryParams?.search ?? '';\n\n\tconst layoutTypeDefaults =\n\t\tconfig.defaultLayouts?.[\n\t\t\tbaseView?.type as keyof typeof config.defaultLayouts\n\t\t] ?? {};\n\tconst combinedOverrides = { ...layoutTypeDefaults, ...activeViewOverrides };\n\n\treturn mergeActiveViewOverrides(\n\t\t{\n\t\t\t...baseView,\n\t\t\tpage,\n\t\t\tsearch,\n\t\t},\n\t\tcombinedOverrides,\n\t\tdefaultView\n\t);\n}\n"],
5
+ "mappings": ";AAGA,SAAS,cAAc;AAEvB,SAAS,SAAS,wBAAwB;AAM1C,SAAS,6BAA6B;AACtC,SAAS,gCAAgC;AAezC,eAAsB,SAAU,QAAqB;AACpD,QAAM,EAAE,MAAM,MAAM,MAAM,aAAa,qBAAqB,YAAY,IACvE;AACD,QAAM,gBAAgB,sBAAuB,MAAM,MAAM,IAAK;AAC9D,QAAM,gBAAkC,OAAQ,gBAAiB,EAAE;AAAA,IAClE;AAAA,IACA;AAAA,EACD;AAEA,QAAM,WAAW,iBAAiB;AAClC,QAAM,OAAO,aAAa,QAAQ;AAClC,QAAM,SAAS,aAAa,UAAU;AAEtC,QAAM,qBACL,OAAO,iBACN,UAAU,IACX,KAAK,CAAC;AACP,QAAM,oBAAoB,EAAE,GAAG,oBAAoB,GAAG,oBAAoB;AAE1E,SAAO;AAAA,IACN;AAAA,MACC,GAAG;AAAA,MACH;AAAA,MACA;AAAA,IACD;AAAA,IACA;AAAA,IACA;AAAA,EACD;AACD;",
6
6
  "names": []
7
7
  }
@@ -0,0 +1,11 @@
1
+ // packages/views/src/lock-unlock.ts
2
+ import { __dangerousOptInToUnstableAPIsOnlyForCoreModules } from "@wordpress/private-apis";
3
+ var { lock, unlock } = __dangerousOptInToUnstableAPIsOnlyForCoreModules(
4
+ "I acknowledge private features are not for use in themes or plugins and doing so will break in the next version of WordPress.",
5
+ "@wordpress/views"
6
+ );
7
+ export {
8
+ lock,
9
+ unlock
10
+ };
11
+ //# sourceMappingURL=lock-unlock.mjs.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/lock-unlock.ts"],
4
+ "sourcesContent": ["/**\n * WordPress dependencies\n */\nimport { __dangerousOptInToUnstableAPIsOnlyForCoreModules } from '@wordpress/private-apis';\n\nexport const { lock, unlock } =\n\t__dangerousOptInToUnstableAPIsOnlyForCoreModules(\n\t\t'I acknowledge private features are not for use in themes or plugins and doing so will break in the next version of WordPress.',\n\t\t'@wordpress/views'\n\t);\n"],
5
+ "mappings": ";AAGA,SAAS,wDAAwD;AAE1D,IAAM,EAAE,MAAM,OAAO,IAC3B;AAAA,EACC;AAAA,EACA;AACD;",
6
+ "names": []
7
+ }
@@ -0,0 +1,19 @@
1
+ // packages/views/src/use-view-config.ts
2
+ import { useSelect } from "@wordpress/data";
3
+ import { store as coreStore } from "@wordpress/core-data";
4
+ import { unlock } from "./lock-unlock.mjs";
5
+ function useViewConfig({
6
+ kind,
7
+ name
8
+ }) {
9
+ return useSelect(
10
+ (select) => {
11
+ return unlock(select(coreStore)).getViewConfig(kind, name);
12
+ },
13
+ [kind, name]
14
+ );
15
+ }
16
+ export {
17
+ useViewConfig
18
+ };
19
+ //# sourceMappingURL=use-view-config.mjs.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/use-view-config.ts"],
4
+ "sourcesContent": ["/**\n * WordPress dependencies\n */\nimport { useSelect } from '@wordpress/data';\nimport { store as coreStore } from '@wordpress/core-data';\nimport type { View, SupportedLayouts, Form } from '@wordpress/dataviews';\n\n/**\n * Internal dependencies\n */\nimport { unlock } from './lock-unlock';\n\n/**\n * A hook that retrieves the view configuration for a given entity\n * from the core data store.\n *\n * @param {Object} params\n * @param {string} params.kind The kind of the entity.\n * @param {string} params.name The name of the entity.\n * @return {Object} An object containing the `default_view`, `default_layouts`, and `view_list` configuration for the entity.\n */\nexport function useViewConfig( {\n\tkind,\n\tname,\n}: {\n\tkind: string;\n\tname: string;\n} ): {\n\tdefault_view: View;\n\tdefault_layouts: SupportedLayouts;\n\tview_list: Array< any >;\n\tform: Form | undefined;\n} {\n\treturn useSelect(\n\t\t( select ) => {\n\t\t\treturn unlock( select( coreStore ) ).getViewConfig( kind, name );\n\t\t},\n\t\t[ kind, name ]\n\t);\n}\n"],
5
+ "mappings": ";AAGA,SAAS,iBAAiB;AAC1B,SAAS,SAAS,iBAAiB;AAMnC,SAAS,cAAc;AAWhB,SAAS,cAAe;AAAA,EAC9B;AAAA,EACA;AACD,GAQE;AACD,SAAO;AAAA,IACN,CAAE,WAAY;AACb,aAAO,OAAQ,OAAQ,SAAU,CAAE,EAAE,cAAe,MAAM,IAAK;AAAA,IAChE;AAAA,IACA,CAAE,MAAM,IAAK;AAAA,EACd;AACD;",
6
+ "names": []
7
+ }
@@ -36,9 +36,13 @@ function useView(config) {
36
36
  [preferenceKey]
37
37
  );
38
38
  const { set } = useDispatch(preferencesStore);
39
- const baseView = persistedView ?? defaultView;
39
+ const baseView = persistedView ?? defaultView ?? {};
40
40
  const page = Number(queryParams?.page ?? baseView.page ?? 1);
41
41
  const search = queryParams?.search ?? baseView.search ?? "";
42
+ const combinedOverrides = useMemo(() => {
43
+ const layoutTypeDefaults = config.defaultLayouts?.[baseView.type] ?? {};
44
+ return { ...layoutTypeDefaults, ...activeViewOverrides };
45
+ }, [config.defaultLayouts, baseView.type, activeViewOverrides]);
42
46
  const view = useMemo(() => {
43
47
  return mergeActiveViewOverrides(
44
48
  {
@@ -46,10 +50,10 @@ function useView(config) {
46
50
  page,
47
51
  search
48
52
  },
49
- activeViewOverrides,
53
+ combinedOverrides,
50
54
  defaultView
51
55
  );
52
- }, [baseView, page, search, activeViewOverrides, defaultView]);
56
+ }, [baseView, page, search, combinedOverrides, defaultView]);
53
57
  const isModified = !!persistedView;
54
58
  const updateView = useCallback(
55
59
  (newView) => {
@@ -59,7 +63,7 @@ function useView(config) {
59
63
  };
60
64
  const preferenceView = stripActiveViewOverrides(
61
65
  omit(newView, ["page", "search"]),
62
- activeViewOverrides,
66
+ combinedOverrides,
63
67
  defaultView
64
68
  );
65
69
  if (onChangeQueryParams && !dequal(urlParams, { page, search })) {
@@ -67,12 +71,12 @@ function useView(config) {
67
71
  }
68
72
  const comparableBaseView = stripActiveViewOverrides(
69
73
  baseView,
70
- activeViewOverrides,
74
+ combinedOverrides,
71
75
  defaultView
72
76
  );
73
77
  const comparableDefaultView = stripActiveViewOverrides(
74
78
  defaultView,
75
- activeViewOverrides,
79
+ combinedOverrides,
76
80
  defaultView
77
81
  );
78
82
  if (!dequal(comparableBaseView, preferenceView)) {
@@ -89,7 +93,7 @@ function useView(config) {
89
93
  search,
90
94
  baseView,
91
95
  defaultView,
92
- activeViewOverrides,
96
+ combinedOverrides,
93
97
  set,
94
98
  preferenceKey
95
99
  ]
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../src/use-view.ts"],
4
- "sourcesContent": ["/**\n * External dependencies\n */\nimport { dequal } from 'dequal';\n\n/**\n * WordPress dependencies\n */\nimport { useCallback, useMemo } from '@wordpress/element';\nimport { useDispatch, useSelect } from '@wordpress/data';\nimport type { View } from '@wordpress/dataviews';\n// @ts-ignore - Preferences package is not typed\nimport { store as preferencesStore } from '@wordpress/preferences';\n\n/**\n * Internal dependencies\n */\nimport { generatePreferenceKey } from './preference-keys';\nimport {\n\tmergeActiveViewOverrides,\n\tstripActiveViewOverrides,\n} from './filter-utils';\nimport type { ViewConfig } from './types';\n\ninterface UseViewReturn {\n\tview: View;\n\tisModified: boolean;\n\tupdateView: ( newView: View ) => void;\n\tresetToDefault: () => void;\n}\n\nfunction omit< T extends object, K extends keyof T >(\n\tobj: T,\n\tkeys: K[]\n): Omit< T, K > {\n\tconst result = { ...obj };\n\tfor ( const key of keys ) {\n\t\tdelete result[ key ];\n\t}\n\treturn result;\n}\n\n/**\n * Hook for managing DataViews view state with local persistence.\n *\n * @param config Configuration object for loading the view.\n *\n * @return Object with current view, modification state, and update functions.\n */\nexport function useView( config: ViewConfig ): UseViewReturn {\n\tconst {\n\t\tkind,\n\t\tname,\n\t\tslug,\n\t\tdefaultView,\n\t\tactiveViewOverrides,\n\t\tqueryParams,\n\t\tonChangeQueryParams,\n\t} = config;\n\n\tconst preferenceKey = generatePreferenceKey( kind, name, slug );\n\tconst persistedView: View | undefined = useSelect(\n\t\t( select ) => {\n\t\t\treturn select( preferencesStore ).get(\n\t\t\t\t'core/views',\n\t\t\t\tpreferenceKey\n\t\t\t) as View | undefined;\n\t\t},\n\t\t[ preferenceKey ]\n\t);\n\tconst { set } = useDispatch( preferencesStore );\n\n\tconst baseView: View = persistedView ?? defaultView;\n\tconst page = Number( queryParams?.page ?? baseView.page ?? 1 );\n\tconst search = queryParams?.search ?? baseView.search ?? '';\n\n\t// Merge URL query parameters (page, search) and activeViewOverrides into the view\n\tconst view: View = useMemo( () => {\n\t\treturn mergeActiveViewOverrides(\n\t\t\t{\n\t\t\t\t...baseView,\n\t\t\t\tpage,\n\t\t\t\tsearch,\n\t\t\t},\n\t\t\tactiveViewOverrides,\n\t\t\tdefaultView\n\t\t);\n\t}, [ baseView, page, search, activeViewOverrides, defaultView ] );\n\n\tconst isModified = !! persistedView;\n\n\tconst updateView = useCallback(\n\t\t( newView: View ) => {\n\t\t\t// Extract URL params (page, search) from the new view\n\t\t\tconst urlParams: { page?: number; search?: string } = {\n\t\t\t\tpage: newView?.page,\n\t\t\t\tsearch: newView?.search,\n\t\t\t};\n\t\t\t// Strip activeViewOverrides and URL params before persisting\n\t\t\t// Cast is safe: omitting page/search doesn't change the discriminant (type field)\n\t\t\tconst preferenceView = stripActiveViewOverrides(\n\t\t\t\tomit( newView, [ 'page', 'search' ] ) as View,\n\t\t\t\tactiveViewOverrides,\n\t\t\t\tdefaultView\n\t\t\t);\n\n\t\t\t// If we have URL handling enabled, separate URL state from preference state\n\t\t\tif (\n\t\t\t\tonChangeQueryParams &&\n\t\t\t\t! dequal( urlParams, { page, search } )\n\t\t\t) {\n\t\t\t\tonChangeQueryParams( urlParams );\n\t\t\t}\n\n\t\t\t// Compare with baseView and defaultView after stripping activeViewOverrides\n\t\t\tconst comparableBaseView = stripActiveViewOverrides(\n\t\t\t\tbaseView,\n\t\t\t\tactiveViewOverrides,\n\t\t\t\tdefaultView\n\t\t\t);\n\t\t\tconst comparableDefaultView = stripActiveViewOverrides(\n\t\t\t\tdefaultView,\n\t\t\t\tactiveViewOverrides,\n\t\t\t\tdefaultView\n\t\t\t);\n\n\t\t\t// Only persist non-URL preferences if different from baseView\n\t\t\tif ( ! dequal( comparableBaseView, preferenceView ) ) {\n\t\t\t\tif ( dequal( preferenceView, comparableDefaultView ) ) {\n\t\t\t\t\tset( 'core/views', preferenceKey, undefined );\n\t\t\t\t} else {\n\t\t\t\t\tset( 'core/views', preferenceKey, preferenceView );\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\t[\n\t\t\tonChangeQueryParams,\n\t\t\tpage,\n\t\t\tsearch,\n\t\t\tbaseView,\n\t\t\tdefaultView,\n\t\t\tactiveViewOverrides,\n\t\t\tset,\n\t\t\tpreferenceKey,\n\t\t]\n\t);\n\n\tconst resetToDefault = useCallback( () => {\n\t\tset( 'core/views', preferenceKey, undefined );\n\t}, [ preferenceKey, set ] );\n\n\treturn {\n\t\tview,\n\t\tisModified,\n\t\tupdateView,\n\t\tresetToDefault,\n\t};\n}\n"],
5
- "mappings": ";AAGA,SAAS,cAAc;AAKvB,SAAS,aAAa,eAAe;AACrC,SAAS,aAAa,iBAAiB;AAGvC,SAAS,SAAS,wBAAwB;AAK1C,SAAS,6BAA6B;AACtC;AAAA,EACC;AAAA,EACA;AAAA,OACM;AAUP,SAAS,KACR,KACA,MACe;AACf,QAAM,SAAS,EAAE,GAAG,IAAI;AACxB,aAAY,OAAO,MAAO;AACzB,WAAO,OAAQ,GAAI;AAAA,EACpB;AACA,SAAO;AACR;AASO,SAAS,QAAS,QAAoC;AAC5D,QAAM;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACD,IAAI;AAEJ,QAAM,gBAAgB,sBAAuB,MAAM,MAAM,IAAK;AAC9D,QAAM,gBAAkC;AAAA,IACvC,CAAE,WAAY;AACb,aAAO,OAAQ,gBAAiB,EAAE;AAAA,QACjC;AAAA,QACA;AAAA,MACD;AAAA,IACD;AAAA,IACA,CAAE,aAAc;AAAA,EACjB;AACA,QAAM,EAAE,IAAI,IAAI,YAAa,gBAAiB;AAE9C,QAAM,WAAiB,iBAAiB;AACxC,QAAM,OAAO,OAAQ,aAAa,QAAQ,SAAS,QAAQ,CAAE;AAC7D,QAAM,SAAS,aAAa,UAAU,SAAS,UAAU;AAGzD,QAAM,OAAa,QAAS,MAAM;AACjC,WAAO;AAAA,MACN;AAAA,QACC,GAAG;AAAA,QACH;AAAA,QACA;AAAA,MACD;AAAA,MACA;AAAA,MACA;AAAA,IACD;AAAA,EACD,GAAG,CAAE,UAAU,MAAM,QAAQ,qBAAqB,WAAY,CAAE;AAEhE,QAAM,aAAa,CAAC,CAAE;AAEtB,QAAM,aAAa;AAAA,IAClB,CAAE,YAAmB;AAEpB,YAAM,YAAgD;AAAA,QACrD,MAAM,SAAS;AAAA,QACf,QAAQ,SAAS;AAAA,MAClB;AAGA,YAAM,iBAAiB;AAAA,QACtB,KAAM,SAAS,CAAE,QAAQ,QAAS,CAAE;AAAA,QACpC;AAAA,QACA;AAAA,MACD;AAGA,UACC,uBACA,CAAE,OAAQ,WAAW,EAAE,MAAM,OAAO,CAAE,GACrC;AACD,4BAAqB,SAAU;AAAA,MAChC;AAGA,YAAM,qBAAqB;AAAA,QAC1B;AAAA,QACA;AAAA,QACA;AAAA,MACD;AACA,YAAM,wBAAwB;AAAA,QAC7B;AAAA,QACA;AAAA,QACA;AAAA,MACD;AAGA,UAAK,CAAE,OAAQ,oBAAoB,cAAe,GAAI;AACrD,YAAK,OAAQ,gBAAgB,qBAAsB,GAAI;AACtD,cAAK,cAAc,eAAe,MAAU;AAAA,QAC7C,OAAO;AACN,cAAK,cAAc,eAAe,cAAe;AAAA,QAClD;AAAA,MACD;AAAA,IACD;AAAA,IACA;AAAA,MACC;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACD;AAAA,EACD;AAEA,QAAM,iBAAiB,YAAa,MAAM;AACzC,QAAK,cAAc,eAAe,MAAU;AAAA,EAC7C,GAAG,CAAE,eAAe,GAAI,CAAE;AAE1B,SAAO;AAAA,IACN;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACD;AACD;",
4
+ "sourcesContent": ["/**\n * External dependencies\n */\nimport { dequal } from 'dequal';\n\n/**\n * WordPress dependencies\n */\nimport { useCallback, useMemo } from '@wordpress/element';\nimport { useDispatch, useSelect } from '@wordpress/data';\nimport type { View } from '@wordpress/dataviews';\n// @ts-ignore - Preferences package is not typed\nimport { store as preferencesStore } from '@wordpress/preferences';\n\n/**\n * Internal dependencies\n */\nimport { generatePreferenceKey } from './preference-keys';\nimport {\n\tmergeActiveViewOverrides,\n\tstripActiveViewOverrides,\n} from './filter-utils';\nimport type { ViewConfig } from './types';\n\ninterface UseViewReturn {\n\tview: View;\n\tisModified: boolean;\n\tupdateView: ( newView: View ) => void;\n\tresetToDefault: () => void;\n}\n\nfunction omit< T extends object, K extends keyof T >(\n\tobj: T,\n\tkeys: K[]\n): Omit< T, K > {\n\tconst result = { ...obj };\n\tfor ( const key of keys ) {\n\t\tdelete result[ key ];\n\t}\n\treturn result;\n}\n\n/**\n * Hook for managing DataViews view state with local persistence.\n *\n * @param config Configuration object for loading the view.\n *\n * @return Object with current view, modification state, and update functions.\n */\nexport function useView( config: ViewConfig ): UseViewReturn {\n\tconst {\n\t\tkind,\n\t\tname,\n\t\tslug,\n\t\tdefaultView,\n\t\tactiveViewOverrides,\n\t\tqueryParams,\n\t\tonChangeQueryParams,\n\t} = config;\n\n\tconst preferenceKey = generatePreferenceKey( kind, name, slug );\n\tconst persistedView: View | undefined = useSelect(\n\t\t( select ) => {\n\t\t\treturn select( preferencesStore ).get(\n\t\t\t\t'core/views',\n\t\t\t\tpreferenceKey\n\t\t\t) as View | undefined;\n\t\t},\n\t\t[ preferenceKey ]\n\t);\n\tconst { set } = useDispatch( preferencesStore );\n\n\tconst baseView: View = persistedView ?? defaultView ?? {};\n\tconst page = Number( queryParams?.page ?? baseView.page ?? 1 );\n\tconst search = queryParams?.search ?? baseView.search ?? '';\n\n\tconst combinedOverrides = useMemo( () => {\n\t\tconst layoutTypeDefaults =\n\t\t\tconfig.defaultLayouts?.[\n\t\t\t\tbaseView.type as keyof typeof config.defaultLayouts\n\t\t\t] ?? {};\n\t\treturn { ...layoutTypeDefaults, ...activeViewOverrides };\n\t}, [ config.defaultLayouts, baseView.type, activeViewOverrides ] );\n\n\t// Merge URL query parameters (page, search) and activeViewOverrides into the view\n\tconst view: View = useMemo( () => {\n\t\treturn mergeActiveViewOverrides(\n\t\t\t{\n\t\t\t\t...baseView,\n\t\t\t\tpage,\n\t\t\t\tsearch,\n\t\t\t},\n\t\t\tcombinedOverrides,\n\t\t\tdefaultView\n\t\t);\n\t}, [ baseView, page, search, combinedOverrides, defaultView ] );\n\n\tconst isModified = !! persistedView;\n\n\tconst updateView = useCallback(\n\t\t( newView: View ) => {\n\t\t\t// Extract URL params (page, search) from the new view\n\t\t\tconst urlParams: { page?: number; search?: string } = {\n\t\t\t\tpage: newView?.page,\n\t\t\t\tsearch: newView?.search,\n\t\t\t};\n\t\t\t// Strip activeViewOverrides and URL params before persisting\n\t\t\t// Cast is safe: omitting page/search doesn't change the discriminant (type field)\n\t\t\tconst preferenceView = stripActiveViewOverrides(\n\t\t\t\tomit( newView, [ 'page', 'search' ] ) as View,\n\t\t\t\tcombinedOverrides,\n\t\t\t\tdefaultView\n\t\t\t);\n\n\t\t\t// If we have URL handling enabled, separate URL state from preference state\n\t\t\tif (\n\t\t\t\tonChangeQueryParams &&\n\t\t\t\t! dequal( urlParams, { page, search } )\n\t\t\t) {\n\t\t\t\tonChangeQueryParams( urlParams );\n\t\t\t}\n\n\t\t\t// Compare with baseView and defaultView after stripping activeViewOverrides\n\t\t\tconst comparableBaseView = stripActiveViewOverrides(\n\t\t\t\tbaseView,\n\t\t\t\tcombinedOverrides,\n\t\t\t\tdefaultView\n\t\t\t);\n\t\t\tconst comparableDefaultView = stripActiveViewOverrides(\n\t\t\t\tdefaultView,\n\t\t\t\tcombinedOverrides,\n\t\t\t\tdefaultView\n\t\t\t);\n\n\t\t\t// Only persist non-URL preferences if different from baseView\n\t\t\tif ( ! dequal( comparableBaseView, preferenceView ) ) {\n\t\t\t\tif ( dequal( preferenceView, comparableDefaultView ) ) {\n\t\t\t\t\tset( 'core/views', preferenceKey, undefined );\n\t\t\t\t} else {\n\t\t\t\t\tset( 'core/views', preferenceKey, preferenceView );\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\t[\n\t\t\tonChangeQueryParams,\n\t\t\tpage,\n\t\t\tsearch,\n\t\t\tbaseView,\n\t\t\tdefaultView,\n\t\t\tcombinedOverrides,\n\t\t\tset,\n\t\t\tpreferenceKey,\n\t\t]\n\t);\n\n\tconst resetToDefault = useCallback( () => {\n\t\tset( 'core/views', preferenceKey, undefined );\n\t}, [ preferenceKey, set ] );\n\n\treturn {\n\t\tview,\n\t\tisModified,\n\t\tupdateView,\n\t\tresetToDefault,\n\t};\n}\n"],
5
+ "mappings": ";AAGA,SAAS,cAAc;AAKvB,SAAS,aAAa,eAAe;AACrC,SAAS,aAAa,iBAAiB;AAGvC,SAAS,SAAS,wBAAwB;AAK1C,SAAS,6BAA6B;AACtC;AAAA,EACC;AAAA,EACA;AAAA,OACM;AAUP,SAAS,KACR,KACA,MACe;AACf,QAAM,SAAS,EAAE,GAAG,IAAI;AACxB,aAAY,OAAO,MAAO;AACzB,WAAO,OAAQ,GAAI;AAAA,EACpB;AACA,SAAO;AACR;AASO,SAAS,QAAS,QAAoC;AAC5D,QAAM;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACD,IAAI;AAEJ,QAAM,gBAAgB,sBAAuB,MAAM,MAAM,IAAK;AAC9D,QAAM,gBAAkC;AAAA,IACvC,CAAE,WAAY;AACb,aAAO,OAAQ,gBAAiB,EAAE;AAAA,QACjC;AAAA,QACA;AAAA,MACD;AAAA,IACD;AAAA,IACA,CAAE,aAAc;AAAA,EACjB;AACA,QAAM,EAAE,IAAI,IAAI,YAAa,gBAAiB;AAE9C,QAAM,WAAiB,iBAAiB,eAAe,CAAC;AACxD,QAAM,OAAO,OAAQ,aAAa,QAAQ,SAAS,QAAQ,CAAE;AAC7D,QAAM,SAAS,aAAa,UAAU,SAAS,UAAU;AAEzD,QAAM,oBAAoB,QAAS,MAAM;AACxC,UAAM,qBACL,OAAO,iBACN,SAAS,IACV,KAAK,CAAC;AACP,WAAO,EAAE,GAAG,oBAAoB,GAAG,oBAAoB;AAAA,EACxD,GAAG,CAAE,OAAO,gBAAgB,SAAS,MAAM,mBAAoB,CAAE;AAGjE,QAAM,OAAa,QAAS,MAAM;AACjC,WAAO;AAAA,MACN;AAAA,QACC,GAAG;AAAA,QACH;AAAA,QACA;AAAA,MACD;AAAA,MACA;AAAA,MACA;AAAA,IACD;AAAA,EACD,GAAG,CAAE,UAAU,MAAM,QAAQ,mBAAmB,WAAY,CAAE;AAE9D,QAAM,aAAa,CAAC,CAAE;AAEtB,QAAM,aAAa;AAAA,IAClB,CAAE,YAAmB;AAEpB,YAAM,YAAgD;AAAA,QACrD,MAAM,SAAS;AAAA,QACf,QAAQ,SAAS;AAAA,MAClB;AAGA,YAAM,iBAAiB;AAAA,QACtB,KAAM,SAAS,CAAE,QAAQ,QAAS,CAAE;AAAA,QACpC;AAAA,QACA;AAAA,MACD;AAGA,UACC,uBACA,CAAE,OAAQ,WAAW,EAAE,MAAM,OAAO,CAAE,GACrC;AACD,4BAAqB,SAAU;AAAA,MAChC;AAGA,YAAM,qBAAqB;AAAA,QAC1B;AAAA,QACA;AAAA,QACA;AAAA,MACD;AACA,YAAM,wBAAwB;AAAA,QAC7B;AAAA,QACA;AAAA,QACA;AAAA,MACD;AAGA,UAAK,CAAE,OAAQ,oBAAoB,cAAe,GAAI;AACrD,YAAK,OAAQ,gBAAgB,qBAAsB,GAAI;AACtD,cAAK,cAAc,eAAe,MAAU;AAAA,QAC7C,OAAO;AACN,cAAK,cAAc,eAAe,cAAe;AAAA,QAClD;AAAA,MACD;AAAA,IACD;AAAA,IACA;AAAA,MACC;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACD;AAAA,EACD;AAEA,QAAM,iBAAiB,YAAa,MAAM;AACzC,QAAK,cAAc,eAAe,MAAU;AAAA,EAC7C,GAAG,CAAE,eAAe,GAAI,CAAE;AAE1B,SAAO;AAAA,IACN;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACD;AACD;",
6
6
  "names": []
7
7
  }
@@ -1,3 +1,4 @@
1
1
  export { useView } from './use-view';
2
2
  export { loadView } from './load-view';
3
+ export { useViewConfig } from './use-view-config';
3
4
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AACrC,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AACrC,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AACvC,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"load-view.d.ts","sourceRoot":"","sources":["../src/load-view.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,sBAAsB,CAAC;AAOjD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAE1C;;;;;;;;;;;GAWG;AACH,wBAAsB,QAAQ,CAAE,MAAM,EAAE,UAAU,iBAsBjD"}
1
+ {"version":3,"file":"load-view.d.ts","sourceRoot":"","sources":["../src/load-view.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,sBAAsB,CAAC;AAOjD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAE1C;;;;;;;;;;;GAWG;AACH,wBAAsB,QAAQ,CAAE,MAAM,EAAE,UAAU,iBA4BjD"}
@@ -0,0 +1,2 @@
1
+ export declare const lock: (object: unknown, privateData: unknown) => void, unlock: <T = any>(object: unknown) => T;
2
+ //# sourceMappingURL=lock-unlock.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lock-unlock.d.ts","sourceRoot":"","sources":["../src/lock-unlock.ts"],"names":[],"mappings":"AAKA,eAAO,MAAQ,IAAI,mDAAE,MAAM,iCAIzB,CAAC"}
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * WordPress dependencies
3
3
  */
4
- import type { View } from '@wordpress/dataviews';
4
+ import type { View, SupportedLayouts } from '@wordpress/dataviews';
5
5
  export type ActiveViewOverrides = {
6
6
  titleField?: View['titleField'];
7
7
  showTitle?: View['showTitle'];
@@ -42,6 +42,12 @@ export interface ViewConfig {
42
42
  * view settings.
43
43
  */
44
44
  activeViewOverrides?: ActiveViewOverrides;
45
+ /**
46
+ * Default layout configurations keyed by layout type.
47
+ * Used to apply layout-type-specific defaults (e.g., table column styles)
48
+ * that are merged as overrides based on the resolved view type.
49
+ */
50
+ defaultLayouts?: SupportedLayouts;
45
51
  /**
46
52
  * Optional query parameters from URL (page, search)
47
53
  */
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,sBAAsB,CAAC;AAEjD,MAAM,MAAM,mBAAmB,GAAG;IAEjC,UAAU,CAAC,EAAE,IAAI,CAAE,YAAY,CAAE,CAAC;IAClC,SAAS,CAAC,EAAE,IAAI,CAAE,WAAW,CAAE,CAAC;IAChC,UAAU,CAAC,EAAE,IAAI,CAAE,YAAY,CAAE,CAAC;IAClC,SAAS,CAAC,EAAE,IAAI,CAAE,WAAW,CAAE,CAAC;IAChC,gBAAgB,CAAC,EAAE,IAAI,CAAE,kBAAkB,CAAE,CAAC;IAC9C,eAAe,CAAC,EAAE,IAAI,CAAE,iBAAiB,CAAE,CAAC;IAC5C,UAAU,CAAC,EAAE,IAAI,CAAE,YAAY,CAAE,CAAC;IAClC,qBAAqB,CAAC,EAAE,IAAI,CAAE,uBAAuB,CAAE,CAAC;IAExD,OAAO,CAAC,EAAE,IAAI,CAAE,SAAS,CAAE,CAAC;IAC5B,IAAI,CAAC,EAAE,IAAI,CAAE,MAAM,CAAE,CAAC;IACtB,OAAO,CAAC,EAAE,IAAI,CAAE,SAAS,CAAE,CAAC;IAC5B,MAAM,CAAC,EAAE,MAAM,CAAE,MAAM,EAAE,OAAO,CAAE,CAAC;CACnC,CAAC;AAEF,MAAM,WAAW,UAAU;IAC1B;;;OAGG;IACH,IAAI,EAAE,MAAM,CAAC;IAEb;;;OAGG;IACH,IAAI,EAAE,MAAM,CAAC;IAEb;;OAEG;IACH,IAAI,EAAE,MAAM,CAAC;IAEb;;OAEG;IACH,WAAW,EAAE,IAAI,CAAC;IAElB;;;;;OAKG;IACH,mBAAmB,CAAC,EAAE,mBAAmB,CAAC;IAE1C;;OAEG;IACH,WAAW,CAAC,EAAE;QACb,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,MAAM,CAAC,EAAE,MAAM,CAAC;KAChB,CAAC;IAEF;;OAEG;IACH,mBAAmB,CAAC,EAAE,CAAE,MAAM,EAAE;QAC/B,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,MAAM,CAAC,EAAE,MAAM,CAAC;KAChB,KAAM,IAAI,CAAC;CACZ"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,KAAK,EAAE,IAAI,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAEnE,MAAM,MAAM,mBAAmB,GAAG;IAEjC,UAAU,CAAC,EAAE,IAAI,CAAE,YAAY,CAAE,CAAC;IAClC,SAAS,CAAC,EAAE,IAAI,CAAE,WAAW,CAAE,CAAC;IAChC,UAAU,CAAC,EAAE,IAAI,CAAE,YAAY,CAAE,CAAC;IAClC,SAAS,CAAC,EAAE,IAAI,CAAE,WAAW,CAAE,CAAC;IAChC,gBAAgB,CAAC,EAAE,IAAI,CAAE,kBAAkB,CAAE,CAAC;IAC9C,eAAe,CAAC,EAAE,IAAI,CAAE,iBAAiB,CAAE,CAAC;IAC5C,UAAU,CAAC,EAAE,IAAI,CAAE,YAAY,CAAE,CAAC;IAClC,qBAAqB,CAAC,EAAE,IAAI,CAAE,uBAAuB,CAAE,CAAC;IAExD,OAAO,CAAC,EAAE,IAAI,CAAE,SAAS,CAAE,CAAC;IAC5B,IAAI,CAAC,EAAE,IAAI,CAAE,MAAM,CAAE,CAAC;IACtB,OAAO,CAAC,EAAE,IAAI,CAAE,SAAS,CAAE,CAAC;IAC5B,MAAM,CAAC,EAAE,MAAM,CAAE,MAAM,EAAE,OAAO,CAAE,CAAC;CACnC,CAAC;AAEF,MAAM,WAAW,UAAU;IAC1B;;;OAGG;IACH,IAAI,EAAE,MAAM,CAAC;IAEb;;;OAGG;IACH,IAAI,EAAE,MAAM,CAAC;IAEb;;OAEG;IACH,IAAI,EAAE,MAAM,CAAC;IAEb;;OAEG;IACH,WAAW,EAAE,IAAI,CAAC;IAElB;;;;;OAKG;IACH,mBAAmB,CAAC,EAAE,mBAAmB,CAAC;IAE1C;;;;OAIG;IACH,cAAc,CAAC,EAAE,gBAAgB,CAAC;IAElC;;OAEG;IACH,WAAW,CAAC,EAAE;QACb,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,MAAM,CAAC,EAAE,MAAM,CAAC;KAChB,CAAC;IAEF;;OAEG;IACH,mBAAmB,CAAC,EAAE,CAAE,MAAM,EAAE;QAC/B,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,MAAM,CAAC,EAAE,MAAM,CAAC;KAChB,KAAM,IAAI,CAAC;CACZ"}
@@ -0,0 +1,20 @@
1
+ import type { View, SupportedLayouts, Form } from '@wordpress/dataviews';
2
+ /**
3
+ * A hook that retrieves the view configuration for a given entity
4
+ * from the core data store.
5
+ *
6
+ * @param {Object} params
7
+ * @param {string} params.kind The kind of the entity.
8
+ * @param {string} params.name The name of the entity.
9
+ * @return {Object} An object containing the `default_view`, `default_layouts`, and `view_list` configuration for the entity.
10
+ */
11
+ export declare function useViewConfig({ kind, name, }: {
12
+ kind: string;
13
+ name: string;
14
+ }): {
15
+ default_view: View;
16
+ default_layouts: SupportedLayouts;
17
+ view_list: Array<any>;
18
+ form: Form | undefined;
19
+ };
20
+ //# sourceMappingURL=use-view-config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-view-config.d.ts","sourceRoot":"","sources":["../src/use-view-config.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,IAAI,EAAE,gBAAgB,EAAE,IAAI,EAAE,MAAM,sBAAsB,CAAC;AAOzE;;;;;;;;GAQG;AACH,wBAAgB,aAAa,CAAE,EAC9B,IAAI,EACJ,IAAI,GACJ,EAAE;IACF,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;CACb,GAAI;IACJ,YAAY,EAAE,IAAI,CAAC;IACnB,eAAe,EAAE,gBAAgB,CAAC;IAClC,SAAS,EAAE,KAAK,CAAE,GAAG,CAAE,CAAC;IACxB,IAAI,EAAE,IAAI,GAAG,SAAS,CAAC;CACvB,CAOA"}
@@ -1 +1 @@
1
- {"version":3,"file":"use-view.d.ts","sourceRoot":"","sources":["../src/use-view.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,sBAAsB,CAAC;AAYjD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAE1C,UAAU,aAAa;IACtB,IAAI,EAAE,IAAI,CAAC;IACX,UAAU,EAAE,OAAO,CAAC;IACpB,UAAU,EAAE,CAAE,OAAO,EAAE,IAAI,KAAM,IAAI,CAAC;IACtC,cAAc,EAAE,MAAM,IAAI,CAAC;CAC3B;AAaD;;;;;;GAMG;AACH,wBAAgB,OAAO,CAAE,MAAM,EAAE,UAAU,GAAI,aAAa,CA4G3D"}
1
+ {"version":3,"file":"use-view.d.ts","sourceRoot":"","sources":["../src/use-view.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,sBAAsB,CAAC;AAYjD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAE1C,UAAU,aAAa;IACtB,IAAI,EAAE,IAAI,CAAC;IACX,UAAU,EAAE,OAAO,CAAC;IACpB,UAAU,EAAE,CAAE,OAAO,EAAE,IAAI,KAAM,IAAI,CAAC;IACtC,cAAc,EAAE,MAAM,IAAI,CAAC;CAC3B;AAaD;;;;;;GAMG;AACH,wBAAgB,OAAO,CAAE,MAAM,EAAE,UAAU,GAAI,aAAa,CAoH3D"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wordpress/views",
3
- "version": "1.9.0",
3
+ "version": "1.10.0",
4
4
  "description": "View persistence and management for WordPress DataViews.",
5
5
  "author": "The WordPress Contributors",
6
6
  "license": "GPL-2.0-or-later",
@@ -41,14 +41,16 @@
41
41
  },
42
42
  "types": "build-types",
43
43
  "dependencies": {
44
- "@wordpress/data": "^10.42.0",
45
- "@wordpress/dataviews": "^13.1.0",
46
- "@wordpress/element": "^6.42.0",
47
- "@wordpress/preferences": "^4.42.0",
44
+ "@wordpress/core-data": "^7.43.0",
45
+ "@wordpress/data": "^10.43.0",
46
+ "@wordpress/dataviews": "^14.0.0",
47
+ "@wordpress/element": "^6.43.0",
48
+ "@wordpress/preferences": "^4.43.0",
49
+ "@wordpress/private-apis": "^1.43.0",
48
50
  "dequal": "^2.0.3"
49
51
  },
50
52
  "publishConfig": {
51
53
  "access": "public"
52
54
  },
53
- "gitHead": "c20787b1778ae64c2db65643b1c236309d68e6ba"
55
+ "gitHead": "2cea90674d11aa521ec3f71652fb3a6a4c383969"
54
56
  }
package/src/index.ts CHANGED
@@ -1,2 +1,3 @@
1
1
  export { useView } from './use-view';
2
2
  export { loadView } from './load-view';
3
+ export { useViewConfig } from './use-view-config';
package/src/load-view.ts CHANGED
@@ -38,13 +38,19 @@ export async function loadView( config: ViewConfig ) {
38
38
  const page = queryParams?.page ?? 1;
39
39
  const search = queryParams?.search ?? '';
40
40
 
41
+ const layoutTypeDefaults =
42
+ config.defaultLayouts?.[
43
+ baseView?.type as keyof typeof config.defaultLayouts
44
+ ] ?? {};
45
+ const combinedOverrides = { ...layoutTypeDefaults, ...activeViewOverrides };
46
+
41
47
  return mergeActiveViewOverrides(
42
48
  {
43
49
  ...baseView,
44
50
  page,
45
51
  search,
46
52
  },
47
- activeViewOverrides,
53
+ combinedOverrides,
48
54
  defaultView
49
55
  );
50
56
  }
@@ -0,0 +1,10 @@
1
+ /**
2
+ * WordPress dependencies
3
+ */
4
+ import { __dangerousOptInToUnstableAPIsOnlyForCoreModules } from '@wordpress/private-apis';
5
+
6
+ export const { lock, unlock } =
7
+ __dangerousOptInToUnstableAPIsOnlyForCoreModules(
8
+ 'I acknowledge private features are not for use in themes or plugins and doing so will break in the next version of WordPress.',
9
+ '@wordpress/views'
10
+ );
package/src/types.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * WordPress dependencies
3
3
  */
4
- import type { View } from '@wordpress/dataviews';
4
+ import type { View, SupportedLayouts } from '@wordpress/dataviews';
5
5
 
6
6
  export type ActiveViewOverrides = {
7
7
  // scalar values
@@ -51,6 +51,13 @@ export interface ViewConfig {
51
51
  */
52
52
  activeViewOverrides?: ActiveViewOverrides;
53
53
 
54
+ /**
55
+ * Default layout configurations keyed by layout type.
56
+ * Used to apply layout-type-specific defaults (e.g., table column styles)
57
+ * that are merged as overrides based on the resolved view type.
58
+ */
59
+ defaultLayouts?: SupportedLayouts;
60
+
54
61
  /**
55
62
  * Optional query parameters from URL (page, search)
56
63
  */
@@ -0,0 +1,40 @@
1
+ /**
2
+ * WordPress dependencies
3
+ */
4
+ import { useSelect } from '@wordpress/data';
5
+ import { store as coreStore } from '@wordpress/core-data';
6
+ import type { View, SupportedLayouts, Form } from '@wordpress/dataviews';
7
+
8
+ /**
9
+ * Internal dependencies
10
+ */
11
+ import { unlock } from './lock-unlock';
12
+
13
+ /**
14
+ * A hook that retrieves the view configuration for a given entity
15
+ * from the core data store.
16
+ *
17
+ * @param {Object} params
18
+ * @param {string} params.kind The kind of the entity.
19
+ * @param {string} params.name The name of the entity.
20
+ * @return {Object} An object containing the `default_view`, `default_layouts`, and `view_list` configuration for the entity.
21
+ */
22
+ export function useViewConfig( {
23
+ kind,
24
+ name,
25
+ }: {
26
+ kind: string;
27
+ name: string;
28
+ } ): {
29
+ default_view: View;
30
+ default_layouts: SupportedLayouts;
31
+ view_list: Array< any >;
32
+ form: Form | undefined;
33
+ } {
34
+ return useSelect(
35
+ ( select ) => {
36
+ return unlock( select( coreStore ) ).getViewConfig( kind, name );
37
+ },
38
+ [ kind, name ]
39
+ );
40
+ }
package/src/use-view.ts CHANGED
@@ -70,10 +70,18 @@ export function useView( config: ViewConfig ): UseViewReturn {
70
70
  );
71
71
  const { set } = useDispatch( preferencesStore );
72
72
 
73
- const baseView: View = persistedView ?? defaultView;
73
+ const baseView: View = persistedView ?? defaultView ?? {};
74
74
  const page = Number( queryParams?.page ?? baseView.page ?? 1 );
75
75
  const search = queryParams?.search ?? baseView.search ?? '';
76
76
 
77
+ const combinedOverrides = useMemo( () => {
78
+ const layoutTypeDefaults =
79
+ config.defaultLayouts?.[
80
+ baseView.type as keyof typeof config.defaultLayouts
81
+ ] ?? {};
82
+ return { ...layoutTypeDefaults, ...activeViewOverrides };
83
+ }, [ config.defaultLayouts, baseView.type, activeViewOverrides ] );
84
+
77
85
  // Merge URL query parameters (page, search) and activeViewOverrides into the view
78
86
  const view: View = useMemo( () => {
79
87
  return mergeActiveViewOverrides(
@@ -82,10 +90,10 @@ export function useView( config: ViewConfig ): UseViewReturn {
82
90
  page,
83
91
  search,
84
92
  },
85
- activeViewOverrides,
93
+ combinedOverrides,
86
94
  defaultView
87
95
  );
88
- }, [ baseView, page, search, activeViewOverrides, defaultView ] );
96
+ }, [ baseView, page, search, combinedOverrides, defaultView ] );
89
97
 
90
98
  const isModified = !! persistedView;
91
99
 
@@ -100,7 +108,7 @@ export function useView( config: ViewConfig ): UseViewReturn {
100
108
  // Cast is safe: omitting page/search doesn't change the discriminant (type field)
101
109
  const preferenceView = stripActiveViewOverrides(
102
110
  omit( newView, [ 'page', 'search' ] ) as View,
103
- activeViewOverrides,
111
+ combinedOverrides,
104
112
  defaultView
105
113
  );
106
114
 
@@ -115,12 +123,12 @@ export function useView( config: ViewConfig ): UseViewReturn {
115
123
  // Compare with baseView and defaultView after stripping activeViewOverrides
116
124
  const comparableBaseView = stripActiveViewOverrides(
117
125
  baseView,
118
- activeViewOverrides,
126
+ combinedOverrides,
119
127
  defaultView
120
128
  );
121
129
  const comparableDefaultView = stripActiveViewOverrides(
122
130
  defaultView,
123
- activeViewOverrides,
131
+ combinedOverrides,
124
132
  defaultView
125
133
  );
126
134
 
@@ -139,7 +147,7 @@ export function useView( config: ViewConfig ): UseViewReturn {
139
147
  search,
140
148
  baseView,
141
149
  defaultView,
142
- activeViewOverrides,
150
+ combinedOverrides,
143
151
  set,
144
152
  preferenceKey,
145
153
  ]