@wordpress/views 1.0.1-next.47f435fc9.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 (40) hide show
  1. package/LICENSE.md +788 -0
  2. package/README.md +72 -0
  3. package/build/index.js +32 -0
  4. package/build/index.js.map +7 -0
  5. package/build/load-view.js +47 -0
  6. package/build/load-view.js.map +7 -0
  7. package/build/preference-keys.js +31 -0
  8. package/build/preference-keys.js.map +7 -0
  9. package/build/types.js +17 -0
  10. package/build/types.js.map +7 -0
  11. package/build/use-view.js +102 -0
  12. package/build/use-view.js.map +7 -0
  13. package/build-module/index.js +7 -0
  14. package/build-module/index.js.map +7 -0
  15. package/build-module/load-view.js +23 -0
  16. package/build-module/load-view.js.map +7 -0
  17. package/build-module/preference-keys.js +7 -0
  18. package/build-module/preference-keys.js.map +7 -0
  19. package/build-module/types.js +1 -0
  20. package/build-module/types.js.map +7 -0
  21. package/build-module/use-view.js +78 -0
  22. package/build-module/use-view.js.map +7 -0
  23. package/build-types/index.d.ts +3 -0
  24. package/build-types/index.d.ts.map +1 -0
  25. package/build-types/load-view.d.ts +121 -0
  26. package/build-types/load-view.d.ts.map +1 -0
  27. package/build-types/preference-keys.d.ts +10 -0
  28. package/build-types/preference-keys.d.ts.map +1 -0
  29. package/build-types/types.d.ts +39 -0
  30. package/build-types/types.d.ts.map +1 -0
  31. package/build-types/use-view.d.ts +24 -0
  32. package/build-types/use-view.d.ts.map +1 -0
  33. package/package.json +47 -0
  34. package/src/index.ts +2 -0
  35. package/src/load-view.ts +57 -0
  36. package/src/preference-keys.ts +15 -0
  37. package/src/types.ts +44 -0
  38. package/src/use-view.ts +130 -0
  39. package/tsconfig.json +9 -0
  40. package/tsconfig.tsbuildinfo +1 -0
package/README.md ADDED
@@ -0,0 +1,72 @@
1
+ # @wordpress/views
2
+
3
+ A lightweight package for managing DataViews view state with persistence using WordPress preferences.
4
+
5
+ The `@wordpress/views` package provides:
6
+
7
+ - **Persistence**: Automatically saves and restores DataViews state using `@wordpress/preferences`
8
+ - **View Modification Detection**: Tracks when views differ from their default state
9
+ - **Reset Functionality**: Simple reset to default view capability
10
+ - **Clean Integration**: Drop-in replacement for manual view state management
11
+
12
+ ## Installation
13
+
14
+ Install the module
15
+
16
+ ```bash
17
+ npm install @wordpress/views --save
18
+ ```
19
+
20
+ ## API Reference
21
+
22
+ <!-- START TOKEN(Autogenerated API docs) -->
23
+
24
+ ### loadView
25
+
26
+ Async function for loading view state in route loaders with optional URL parameters.
27
+
28
+ _Usage_
29
+
30
+ ```typescript
31
+ // In route loader
32
+ const view = await loadView( {
33
+ kind: 'taxonomy',
34
+ name: 'category',
35
+ slug: 'all',
36
+ defaultView,
37
+ queryParams: { page: search.page, search: search.search },
38
+ } );
39
+ ```
40
+
41
+ _Parameters_
42
+
43
+ - _config_ `ViewConfig`: Configuration object for loading the view.
44
+ - _config.kind_ `ViewConfig`: Entity kind (e.g., 'postType', 'taxonomy', 'root').
45
+ - _config.name_ `ViewConfig`: Specific entity name.
46
+ - _config.slug_ `ViewConfig`: View identifier.
47
+ - _config.defaultView_ `ViewConfig`: Default view configuration.
48
+ - _config.queryParams_ `ViewConfig`: Object with `page` and/or `search` from URL.
49
+
50
+ _Returns_
51
+
52
+ - Promise resolving to the loaded view object.
53
+
54
+ ### useView
55
+
56
+ Hook for managing DataViews view state with local persistence.
57
+
58
+ _Parameters_
59
+
60
+ - _config_ `ViewConfig`: Configuration object for loading the view.
61
+ - _config.kind_ `ViewConfig`: Entity kind (e.g., 'postType', 'taxonomy', 'root').
62
+ - _config.name_ `ViewConfig`: Specific entity name.
63
+ - _config.slug_ `ViewConfig`: View identifier.
64
+ - _config.defaultView_ `ViewConfig`: Default view configuration.
65
+ - _config.queryParams_ `ViewConfig`: Object with `page` and/or `search` from URL.
66
+ - _config.onChangeQueryParams_ `ViewConfig`: Optional callback to update URL parameters.
67
+
68
+ _Returns_
69
+
70
+ - `UseViewReturn`: Object with current view, modification state, and update functions.
71
+
72
+ <!-- END TOKEN(Autogenerated API docs) -->
package/build/index.js ADDED
@@ -0,0 +1,32 @@
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
+ var index_exports = {};
20
+ __export(index_exports, {
21
+ loadView: () => import_load_view.loadView,
22
+ useView: () => import_use_view.useView
23
+ });
24
+ module.exports = __toCommonJS(index_exports);
25
+ var import_use_view = require("./use-view");
26
+ var import_load_view = require("./load-view");
27
+ // Annotate the CommonJS export names for ESM import in node:
28
+ 0 && (module.exports = {
29
+ loadView,
30
+ useView
31
+ });
32
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 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;",
6
+ "names": []
7
+ }
@@ -0,0 +1,47 @@
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
+ var load_view_exports = {};
20
+ __export(load_view_exports, {
21
+ loadView: () => loadView
22
+ });
23
+ module.exports = __toCommonJS(load_view_exports);
24
+ var import_data = require("@wordpress/data");
25
+ var import_preferences = require("@wordpress/preferences");
26
+ var import_preference_keys = require("./preference-keys");
27
+ async function loadView(config) {
28
+ const { kind, name, slug, defaultView, queryParams } = config;
29
+ const preferenceKey = (0, import_preference_keys.generatePreferenceKey)(kind, name, slug);
30
+ const persistedView = (0, import_data.select)(import_preferences.store).get(
31
+ "core/views",
32
+ preferenceKey
33
+ );
34
+ const baseView = persistedView ?? defaultView;
35
+ const page = queryParams?.page ?? 1;
36
+ const search = queryParams?.search ?? "";
37
+ return {
38
+ ...baseView,
39
+ page,
40
+ search
41
+ };
42
+ }
43
+ // Annotate the CommonJS export names for ESM import in node:
44
+ 0 && (module.exports = {
45
+ loadView
46
+ });
47
+ //# sourceMappingURL=load-view.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 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 type { ViewConfig } from './types';\n\n/**\n * Async function for loading view state in route loaders with optional URL parameters.\n *\n * @example\n *\n * ```typescript\n * // In route loader\n * const view = await loadView( {\n * \tkind: 'taxonomy',\n * \tname: 'category',\n * \tslug: 'all',\n * \tdefaultView,\n * \tqueryParams: { page: search.page, search: search.search },\n * } );\n * ```\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.queryParams Object with `page` and/or `search` from URL.\n *\n * @return Promise resolving to the loaded view object.\n */\nexport async function loadView( config: ViewConfig ) {\n\tconst { kind, name, slug, defaultView, queryParams } = config;\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 {\n\t\t...baseView,\n\t\tpage,\n\t\tsearch,\n\t};\n}\n"],
5
+ "mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAGA,kBAAuB;AAEvB,yBAA0C;AAM1C,6BAAsC;AA4BtC,eAAsB,SAAU,QAAqB;AACpD,QAAM,EAAE,MAAM,MAAM,MAAM,aAAa,YAAY,IAAI;AACvD,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,SAAO;AAAA,IACN,GAAG;AAAA,IACH;AAAA,IACA;AAAA,EACD;AACD;",
6
+ "names": ["preferencesStore"]
7
+ }
@@ -0,0 +1,31 @@
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
+ var preference_keys_exports = {};
20
+ __export(preference_keys_exports, {
21
+ generatePreferenceKey: () => generatePreferenceKey
22
+ });
23
+ module.exports = __toCommonJS(preference_keys_exports);
24
+ function generatePreferenceKey(kind, name, slug) {
25
+ return `dataviews-${kind}-${name}-${slug}`;
26
+ }
27
+ // Annotate the CommonJS export names for ESM import in node:
28
+ 0 && (module.exports = {
29
+ generatePreferenceKey
30
+ });
31
+ //# sourceMappingURL=preference-keys.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/preference-keys.ts"],
4
+ "sourcesContent": ["/**\n * Generates a unique preference key for a DataViews view.\n *\n * @param kind The entity kind (e.g., 'postType', 'root')\n * @param name The specific entity name (e.g., 'post', 'user', 'site')\n * @param slug The specific entity slug (e.g., 'category', 'post', 'all')\n * @return The preference key string\n */\nexport function generatePreferenceKey(\n\tkind: string,\n\tname: string,\n\tslug: string\n): string {\n\treturn `dataviews-${ kind }-${ name }-${ slug }`;\n}\n"],
5
+ "mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAQO,SAAS,sBACf,MACA,MACA,MACS;AACT,SAAO,aAAc,IAAK,IAAK,IAAK,IAAK,IAAK;AAC/C;",
6
+ "names": []
7
+ }
package/build/types.js ADDED
@@ -0,0 +1,17 @@
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 __copyProps = (to, from, except, desc) => {
7
+ if (from && typeof from === "object" || typeof from === "function") {
8
+ for (let key of __getOwnPropNames(from))
9
+ if (!__hasOwnProp.call(to, key) && key !== except)
10
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
11
+ }
12
+ return to;
13
+ };
14
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
15
+ var types_exports = {};
16
+ module.exports = __toCommonJS(types_exports);
17
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/types.ts"],
4
+ "sourcesContent": ["/**\n * WordPress dependencies\n */\nimport type { View } from '@wordpress/dataviews';\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 * 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
+ "mappings": ";;;;;;;;;;;;;;AAAA;AAAA;",
6
+ "names": []
7
+ }
@@ -0,0 +1,102 @@
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
+ var use_view_exports = {};
20
+ __export(use_view_exports, {
21
+ useView: () => useView
22
+ });
23
+ module.exports = __toCommonJS(use_view_exports);
24
+ var import_dequal = require("dequal");
25
+ var import_preference_keys = require("./preference-keys");
26
+ var import_element = require("@wordpress/element");
27
+ var import_data = require("@wordpress/data");
28
+ var import_preferences = require("@wordpress/preferences");
29
+ function omit(obj, keys) {
30
+ const result = { ...obj };
31
+ for (const key of keys) {
32
+ delete result[key];
33
+ }
34
+ return result;
35
+ }
36
+ function useView(config) {
37
+ const { kind, name, slug, defaultView, queryParams, onChangeQueryParams } = config;
38
+ const preferenceKey = (0, import_preference_keys.generatePreferenceKey)(kind, name, slug);
39
+ const persistedView = (0, import_data.useSelect)(
40
+ (select) => {
41
+ return select(import_preferences.store).get(
42
+ "core/views",
43
+ preferenceKey
44
+ );
45
+ },
46
+ [preferenceKey]
47
+ );
48
+ const { set } = (0, import_data.useDispatch)(import_preferences.store);
49
+ const baseView = persistedView ?? defaultView;
50
+ const page = queryParams?.page ?? baseView.page ?? 1;
51
+ const search = queryParams?.search ?? baseView.search ?? "";
52
+ const view = (0, import_element.useMemo)(() => {
53
+ return {
54
+ ...baseView,
55
+ page,
56
+ search
57
+ };
58
+ }, [baseView, page, search]);
59
+ const isModified = !!persistedView;
60
+ const updateView = (0, import_element.useCallback)(
61
+ (newView) => {
62
+ const urlParams = {
63
+ page: newView?.page,
64
+ search: newView?.search
65
+ };
66
+ const preferenceView = omit(newView, ["page", "search"]);
67
+ if (onChangeQueryParams && !(0, import_dequal.dequal)(urlParams, { page, search })) {
68
+ onChangeQueryParams(urlParams);
69
+ }
70
+ if (!(0, import_dequal.dequal)(baseView, preferenceView)) {
71
+ if ((0, import_dequal.dequal)(preferenceView, defaultView)) {
72
+ set("core/views", preferenceKey, void 0);
73
+ } else {
74
+ set("core/views", preferenceKey, preferenceView);
75
+ }
76
+ }
77
+ },
78
+ [
79
+ onChangeQueryParams,
80
+ page,
81
+ search,
82
+ baseView,
83
+ defaultView,
84
+ set,
85
+ preferenceKey
86
+ ]
87
+ );
88
+ const resetToDefault = (0, import_element.useCallback)(() => {
89
+ set("core/views", preferenceKey, void 0);
90
+ }, [preferenceKey, set]);
91
+ return {
92
+ view,
93
+ isModified,
94
+ updateView,
95
+ resetToDefault
96
+ };
97
+ }
98
+ // Annotate the CommonJS export names for ESM import in node:
99
+ 0 && (module.exports = {
100
+ useView
101
+ });
102
+ //# sourceMappingURL=use-view.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/use-view.ts"],
4
+ "sourcesContent": ["/**\n * External dependencies\n */\nimport { dequal } from 'dequal';\n\n/**\n * Internal dependencies\n */\nimport { generatePreferenceKey } from './preference-keys';\nimport type { ViewConfig } from './types';\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\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 * @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.queryParams Object with `page` and/or `search` from URL.\n * @param config.onChangeQueryParams Optional callback to update URL parameters.\n *\n * @return Object with current view, modification state, and update functions.\n */\nexport function useView( config: ViewConfig ): UseViewReturn {\n\tconst { kind, name, slug, defaultView, queryParams, onChangeQueryParams } =\n\t\tconfig;\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 = queryParams?.page ?? baseView.page ?? 1;\n\tconst search = queryParams?.search ?? baseView.search ?? '';\n\n\t// Merge URL query parameters (page, search) into the view\n\tconst view: View = useMemo( () => {\n\t\treturn {\n\t\t\t...baseView,\n\t\t\tpage,\n\t\t\tsearch,\n\t\t};\n\t}, [ baseView, page, search ] );\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\tconst preferenceView = omit( newView, [ 'page', 'search' ] );\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// Only persist non-URL preferences if different from baseView\n\t\t\tif ( ! dequal( baseView, preferenceView ) ) {\n\t\t\t\tif ( dequal( preferenceView, defaultView ) ) {\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\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,6BAAsC;AAMtC,qBAAqC;AACrC,kBAAuC;AAGvC,yBAA0C;AAS1C,SAAS,KACR,KACA,MACe;AACf,QAAM,SAAS,EAAE,GAAG,IAAI;AACxB,aAAY,OAAO,MAAO;AACzB,WAAO,OAAQ,GAAI;AAAA,EACpB;AACA,SAAO;AACR;AAeO,SAAS,QAAS,QAAoC;AAC5D,QAAM,EAAE,MAAM,MAAM,MAAM,aAAa,aAAa,oBAAoB,IACvE;AAED,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,aAAa,QAAQ,SAAS,QAAQ;AACnD,QAAM,SAAS,aAAa,UAAU,SAAS,UAAU;AAGzD,QAAM,WAAa,wBAAS,MAAM;AACjC,WAAO;AAAA,MACN,GAAG;AAAA,MACH;AAAA,MACA;AAAA,IACD;AAAA,EACD,GAAG,CAAE,UAAU,MAAM,MAAO,CAAE;AAE9B,QAAM,aAAa,CAAC,CAAE;AAEtB,QAAM,iBAAa;AAAA,IAClB,CAAE,YAAmB;AAEpB,YAAM,YAAgD;AAAA,QACrD,MAAM,SAAS;AAAA,QACf,QAAQ,SAAS;AAAA,MAClB;AACA,YAAM,iBAAiB,KAAM,SAAS,CAAE,QAAQ,QAAS,CAAE;AAG3D,UACC,uBACA,KAAE,sBAAQ,WAAW,EAAE,MAAM,OAAO,CAAE,GACrC;AACD,4BAAqB,SAAU;AAAA,MAChC;AAGA,UAAK,KAAE,sBAAQ,UAAU,cAAe,GAAI;AAC3C,gBAAK,sBAAQ,gBAAgB,WAAY,GAAI;AAC5C,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,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
+ "names": ["preferencesStore"]
7
+ }
@@ -0,0 +1,7 @@
1
+ import { useView } from "./use-view";
2
+ import { loadView } from "./load-view";
3
+ export {
4
+ loadView,
5
+ useView
6
+ };
7
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 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;",
6
+ "names": []
7
+ }
@@ -0,0 +1,23 @@
1
+ import { select } from "@wordpress/data";
2
+ import { store as preferencesStore } from "@wordpress/preferences";
3
+ import { generatePreferenceKey } from "./preference-keys";
4
+ async function loadView(config) {
5
+ const { kind, name, slug, defaultView, queryParams } = config;
6
+ const preferenceKey = generatePreferenceKey(kind, name, slug);
7
+ const persistedView = select(preferencesStore).get(
8
+ "core/views",
9
+ preferenceKey
10
+ );
11
+ const baseView = persistedView ?? defaultView;
12
+ const page = queryParams?.page ?? 1;
13
+ const search = queryParams?.search ?? "";
14
+ return {
15
+ ...baseView,
16
+ page,
17
+ search
18
+ };
19
+ }
20
+ export {
21
+ loadView
22
+ };
23
+ //# sourceMappingURL=load-view.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 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 type { ViewConfig } from './types';\n\n/**\n * Async function for loading view state in route loaders with optional URL parameters.\n *\n * @example\n *\n * ```typescript\n * // In route loader\n * const view = await loadView( {\n * \tkind: 'taxonomy',\n * \tname: 'category',\n * \tslug: 'all',\n * \tdefaultView,\n * \tqueryParams: { page: search.page, search: search.search },\n * } );\n * ```\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.queryParams Object with `page` and/or `search` from URL.\n *\n * @return Promise resolving to the loaded view object.\n */\nexport async function loadView( config: ViewConfig ) {\n\tconst { kind, name, slug, defaultView, queryParams } = config;\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 {\n\t\t...baseView,\n\t\tpage,\n\t\tsearch,\n\t};\n}\n"],
5
+ "mappings": "AAGA,SAAS,cAAc;AAEvB,SAAS,SAAS,wBAAwB;AAM1C,SAAS,6BAA6B;AA4BtC,eAAsB,SAAU,QAAqB;AACpD,QAAM,EAAE,MAAM,MAAM,MAAM,aAAa,YAAY,IAAI;AACvD,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,GAAG;AAAA,IACH;AAAA,IACA;AAAA,EACD;AACD;",
6
+ "names": []
7
+ }
@@ -0,0 +1,7 @@
1
+ function generatePreferenceKey(kind, name, slug) {
2
+ return `dataviews-${kind}-${name}-${slug}`;
3
+ }
4
+ export {
5
+ generatePreferenceKey
6
+ };
7
+ //# sourceMappingURL=preference-keys.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/preference-keys.ts"],
4
+ "sourcesContent": ["/**\n * Generates a unique preference key for a DataViews view.\n *\n * @param kind The entity kind (e.g., 'postType', 'root')\n * @param name The specific entity name (e.g., 'post', 'user', 'site')\n * @param slug The specific entity slug (e.g., 'category', 'post', 'all')\n * @return The preference key string\n */\nexport function generatePreferenceKey(\n\tkind: string,\n\tname: string,\n\tslug: string\n): string {\n\treturn `dataviews-${ kind }-${ name }-${ slug }`;\n}\n"],
5
+ "mappings": "AAQO,SAAS,sBACf,MACA,MACA,MACS;AACT,SAAO,aAAc,IAAK,IAAK,IAAK,IAAK,IAAK;AAC/C;",
6
+ "names": []
7
+ }
@@ -0,0 +1 @@
1
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": [],
4
+ "sourcesContent": [],
5
+ "mappings": "",
6
+ "names": []
7
+ }
@@ -0,0 +1,78 @@
1
+ import { dequal } from "dequal";
2
+ import { generatePreferenceKey } from "./preference-keys";
3
+ import { useCallback, useMemo } from "@wordpress/element";
4
+ import { useDispatch, useSelect } from "@wordpress/data";
5
+ import { store as preferencesStore } from "@wordpress/preferences";
6
+ function omit(obj, keys) {
7
+ const result = { ...obj };
8
+ for (const key of keys) {
9
+ delete result[key];
10
+ }
11
+ return result;
12
+ }
13
+ function useView(config) {
14
+ const { kind, name, slug, defaultView, queryParams, onChangeQueryParams } = config;
15
+ const preferenceKey = generatePreferenceKey(kind, name, slug);
16
+ const persistedView = useSelect(
17
+ (select) => {
18
+ return select(preferencesStore).get(
19
+ "core/views",
20
+ preferenceKey
21
+ );
22
+ },
23
+ [preferenceKey]
24
+ );
25
+ const { set } = useDispatch(preferencesStore);
26
+ const baseView = persistedView ?? defaultView;
27
+ const page = queryParams?.page ?? baseView.page ?? 1;
28
+ const search = queryParams?.search ?? baseView.search ?? "";
29
+ const view = useMemo(() => {
30
+ return {
31
+ ...baseView,
32
+ page,
33
+ search
34
+ };
35
+ }, [baseView, page, search]);
36
+ const isModified = !!persistedView;
37
+ const updateView = useCallback(
38
+ (newView) => {
39
+ const urlParams = {
40
+ page: newView?.page,
41
+ search: newView?.search
42
+ };
43
+ const preferenceView = omit(newView, ["page", "search"]);
44
+ if (onChangeQueryParams && !dequal(urlParams, { page, search })) {
45
+ onChangeQueryParams(urlParams);
46
+ }
47
+ if (!dequal(baseView, preferenceView)) {
48
+ if (dequal(preferenceView, defaultView)) {
49
+ set("core/views", preferenceKey, void 0);
50
+ } else {
51
+ set("core/views", preferenceKey, preferenceView);
52
+ }
53
+ }
54
+ },
55
+ [
56
+ onChangeQueryParams,
57
+ page,
58
+ search,
59
+ baseView,
60
+ defaultView,
61
+ set,
62
+ preferenceKey
63
+ ]
64
+ );
65
+ const resetToDefault = useCallback(() => {
66
+ set("core/views", preferenceKey, void 0);
67
+ }, [preferenceKey, set]);
68
+ return {
69
+ view,
70
+ isModified,
71
+ updateView,
72
+ resetToDefault
73
+ };
74
+ }
75
+ export {
76
+ useView
77
+ };
78
+ //# sourceMappingURL=use-view.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/use-view.ts"],
4
+ "sourcesContent": ["/**\n * External dependencies\n */\nimport { dequal } from 'dequal';\n\n/**\n * Internal dependencies\n */\nimport { generatePreferenceKey } from './preference-keys';\nimport type { ViewConfig } from './types';\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\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 * @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.queryParams Object with `page` and/or `search` from URL.\n * @param config.onChangeQueryParams Optional callback to update URL parameters.\n *\n * @return Object with current view, modification state, and update functions.\n */\nexport function useView( config: ViewConfig ): UseViewReturn {\n\tconst { kind, name, slug, defaultView, queryParams, onChangeQueryParams } =\n\t\tconfig;\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 = queryParams?.page ?? baseView.page ?? 1;\n\tconst search = queryParams?.search ?? baseView.search ?? '';\n\n\t// Merge URL query parameters (page, search) into the view\n\tconst view: View = useMemo( () => {\n\t\treturn {\n\t\t\t...baseView,\n\t\t\tpage,\n\t\t\tsearch,\n\t\t};\n\t}, [ baseView, page, search ] );\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\tconst preferenceView = omit( newView, [ 'page', 'search' ] );\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// Only persist non-URL preferences if different from baseView\n\t\t\tif ( ! dequal( baseView, preferenceView ) ) {\n\t\t\t\tif ( dequal( preferenceView, defaultView ) ) {\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\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,6BAA6B;AAMtC,SAAS,aAAa,eAAe;AACrC,SAAS,aAAa,iBAAiB;AAGvC,SAAS,SAAS,wBAAwB;AAS1C,SAAS,KACR,KACA,MACe;AACf,QAAM,SAAS,EAAE,GAAG,IAAI;AACxB,aAAY,OAAO,MAAO;AACzB,WAAO,OAAQ,GAAI;AAAA,EACpB;AACA,SAAO;AACR;AAeO,SAAS,QAAS,QAAoC;AAC5D,QAAM,EAAE,MAAM,MAAM,MAAM,aAAa,aAAa,oBAAoB,IACvE;AAED,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,aAAa,QAAQ,SAAS,QAAQ;AACnD,QAAM,SAAS,aAAa,UAAU,SAAS,UAAU;AAGzD,QAAM,OAAa,QAAS,MAAM;AACjC,WAAO;AAAA,MACN,GAAG;AAAA,MACH;AAAA,MACA;AAAA,IACD;AAAA,EACD,GAAG,CAAE,UAAU,MAAM,MAAO,CAAE;AAE9B,QAAM,aAAa,CAAC,CAAE;AAEtB,QAAM,aAAa;AAAA,IAClB,CAAE,YAAmB;AAEpB,YAAM,YAAgD;AAAA,QACrD,MAAM,SAAS;AAAA,QACf,QAAQ,SAAS;AAAA,MAClB;AACA,YAAM,iBAAiB,KAAM,SAAS,CAAE,QAAQ,QAAS,CAAE;AAG3D,UACC,uBACA,CAAE,OAAQ,WAAW,EAAE,MAAM,OAAO,CAAE,GACrC;AACD,4BAAqB,SAAU;AAAA,MAChC;AAGA,UAAK,CAAE,OAAQ,UAAU,cAAe,GAAI;AAC3C,YAAK,OAAQ,gBAAgB,WAAY,GAAI;AAC5C,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,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
+ "names": []
7
+ }
@@ -0,0 +1,3 @@
1
+ export { useView } from './use-view';
2
+ export { loadView } from './load-view';
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +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"}