├── .editorconfig ├── .gitignore ├── .prettierrc ├── .stylelintrc.json ├── .vscode └── settings.json ├── .wp-env.json ├── build ├── index.asset.php ├── index.js ├── index.js.map ├── style-index.css └── style-index.css.map ├── example-wp-settings.php ├── inc └── class-example-wp-settings.php ├── package-lock.json ├── package.json ├── readme.md ├── readme.txt └── src ├── components ├── Panel.js └── SettingsPage.js ├── index.js └── style.scss /.editorconfig: -------------------------------------------------------------------------------- 1 | # This file is for unifying the coding style for different editors and IDEs 2 | # editorconfig.org 3 | 4 | # WordPress Coding Standards 5 | # https://make.wordpress.org/core/handbook/coding-standards/ 6 | 7 | root = true 8 | 9 | [*] 10 | charset = utf-8 11 | end_of_line = lf 12 | insert_final_newline = true 13 | trim_trailing_whitespace = true 14 | indent_style = tab 15 | 16 | [*.{yml,yaml}] 17 | indent_style = space 18 | indent_size = 2 19 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | 8 | # Coverage directory used by tools like istanbul 9 | coverage 10 | 11 | # Compiled binary addons (https://nodejs.org/api/addons.html) 12 | build/Release 13 | 14 | # Dependency directories 15 | node_modules/ 16 | 17 | # Optional npm cache directory 18 | .npm 19 | 20 | # Optional eslint cache 21 | .eslintcache 22 | 23 | # Output of `npm pack` 24 | *.tgz 25 | 26 | # Output of `wp-scripts plugin-zip` 27 | *.zip 28 | 29 | # dotenv environment variables file 30 | .env 31 | -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | "@wordpress/prettier-config" 2 | -------------------------------------------------------------------------------- /.stylelintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@wordpress/stylelint-config/scss", 3 | "rules": { 4 | "at-rule-empty-line-before": null, 5 | "at-rule-no-unknown": null, 6 | "comment-empty-line-before": null, 7 | "font-weight-notation": null, 8 | "max-line-length": null, 9 | "no-descending-specificity": null, 10 | "rule-empty-line-before": null, 11 | "selector-class-pattern": null, 12 | "value-keyword-case": null, 13 | "scss/operator-no-unspaced": null, 14 | "scss/selector-no-redundant-nesting-selector": null, 15 | "scss/at-import-partial-extension": null, 16 | "scss/no-global-function-names": null, 17 | "scss/comment-no-empty": null, 18 | "scss/at-extend-no-missing-placeholder": null, 19 | "scss/operator-no-newline-after": null, 20 | "scss/at-if-closing-brace-newline-after": null, 21 | "scss/at-else-empty-line-before": null, 22 | "scss/at-if-closing-brace-space-after": null, 23 | "no-invalid-position-at-import-rule": null 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "[scss]": { 3 | "editor.defaultFormatter": "esbenp.prettier-vscode", 4 | "editor.formatOnSave": true 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /.wp-env.json: -------------------------------------------------------------------------------- 1 | { 2 | "plugins": ["."] 3 | } 4 | -------------------------------------------------------------------------------- /build/index.asset.php: -------------------------------------------------------------------------------- 1 | array('react', 'wp-components', 'wp-core-data', 'wp-data', 'wp-element', 'wp-i18n'), 'version' => '5b8b0d640a2f4c312c43'); 2 | -------------------------------------------------------------------------------- /build/index.js: -------------------------------------------------------------------------------- 1 | /******/ (() => { // webpackBootstrap 2 | /******/ "use strict"; 3 | /******/ var __webpack_modules__ = ({ 4 | 5 | /***/ "./src/components/Panel.js": 6 | /*!*********************************!*\ 7 | !*** ./src/components/Panel.js ***! 8 | \*********************************/ 9 | /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { 10 | 11 | __webpack_require__.r(__webpack_exports__); 12 | /* harmony export */ __webpack_require__.d(__webpack_exports__, { 13 | /* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__) 14 | /* harmony export */ }); 15 | /* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! react */ "react"); 16 | /* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_0__); 17 | /* harmony import */ var _wordpress_i18n__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @wordpress/i18n */ "@wordpress/i18n"); 18 | /* harmony import */ var _wordpress_i18n__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_wordpress_i18n__WEBPACK_IMPORTED_MODULE_1__); 19 | /* harmony import */ var _wordpress_components__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! @wordpress/components */ "@wordpress/components"); 20 | /* harmony import */ var _wordpress_components__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(_wordpress_components__WEBPACK_IMPORTED_MODULE_2__); 21 | /* harmony import */ var _wordpress_data__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! @wordpress/data */ "@wordpress/data"); 22 | /* harmony import */ var _wordpress_data__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(_wordpress_data__WEBPACK_IMPORTED_MODULE_3__); 23 | /* harmony import */ var _wordpress_core_data__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! @wordpress/core-data */ "@wordpress/core-data"); 24 | /* harmony import */ var _wordpress_core_data__WEBPACK_IMPORTED_MODULE_4___default = /*#__PURE__*/__webpack_require__.n(_wordpress_core_data__WEBPACK_IMPORTED_MODULE_4__); 25 | 26 | 27 | 28 | 29 | 30 | function Panel() { 31 | // Get the settings from the store. 32 | const { 33 | record: settings, 34 | hasResolved 35 | } = (0,_wordpress_data__WEBPACK_IMPORTED_MODULE_3__.useSelect)(select => { 36 | return { 37 | record: select(_wordpress_core_data__WEBPACK_IMPORTED_MODULE_4__.store).getEditedEntityRecord('root', 'site'), 38 | hasResolved: select(_wordpress_core_data__WEBPACK_IMPORTED_MODULE_4__.store).hasFinishedResolution('getEditedEntityRecord', ['root', 'site']) 39 | }; 40 | }); 41 | 42 | // We'll use these functions to save the settings to the store. 43 | const { 44 | editEntityRecord 45 | } = (0,_wordpress_data__WEBPACK_IMPORTED_MODULE_3__.useDispatch)(_wordpress_core_data__WEBPACK_IMPORTED_MODULE_4__.store); 46 | if (!hasResolved) { 47 | return null; 48 | } 49 | 50 | // This will save settings the settings to the local state only. 51 | const updateOptions = (key, value) => { 52 | editEntityRecord('root', 'site', undefined, { 53 | wpdev_account_settings: { 54 | ...settings.wpdev_account_settings, 55 | [key]: value 56 | } 57 | }); 58 | }; 59 | return (0,react__WEBPACK_IMPORTED_MODULE_0__.createElement)(_wordpress_components__WEBPACK_IMPORTED_MODULE_2__.Flex, { 60 | direction: "column", 61 | gap: "4", 62 | className: "example-wp-settings-field-group" 63 | }, (0,react__WEBPACK_IMPORTED_MODULE_0__.createElement)(_wordpress_components__WEBPACK_IMPORTED_MODULE_2__.FlexItem, null, (0,react__WEBPACK_IMPORTED_MODULE_0__.createElement)(_wordpress_components__WEBPACK_IMPORTED_MODULE_2__.TextControl, { 64 | label: (0,_wordpress_i18n__WEBPACK_IMPORTED_MODULE_1__.__)('Acount Number'), 65 | value: settings.wpdev_account_settings?.account_number, 66 | type: 'text', 67 | onChange: value => { 68 | updateOptions('account_number', value); 69 | } 70 | })), (0,react__WEBPACK_IMPORTED_MODULE_0__.createElement)(_wordpress_components__WEBPACK_IMPORTED_MODULE_2__.FlexItem, null, (0,react__WEBPACK_IMPORTED_MODULE_0__.createElement)(_wordpress_components__WEBPACK_IMPORTED_MODULE_2__.TextControl, { 71 | label: (0,_wordpress_i18n__WEBPACK_IMPORTED_MODULE_1__.__)('Account Key'), 72 | value: settings.wpdev_account_settings?.account_key, 73 | type: 'password', 74 | onChange: value => { 75 | updateOptions('account_key', value); 76 | } 77 | }))); 78 | } 79 | /* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (Panel); 80 | 81 | /***/ }), 82 | 83 | /***/ "./src/components/SettingsPage.js": 84 | /*!****************************************!*\ 85 | !*** ./src/components/SettingsPage.js ***! 86 | \****************************************/ 87 | /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { 88 | 89 | __webpack_require__.r(__webpack_exports__); 90 | /* harmony export */ __webpack_require__.d(__webpack_exports__, { 91 | /* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__) 92 | /* harmony export */ }); 93 | /* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! react */ "react"); 94 | /* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_0__); 95 | /* harmony import */ var _wordpress_i18n__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @wordpress/i18n */ "@wordpress/i18n"); 96 | /* harmony import */ var _wordpress_i18n__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_wordpress_i18n__WEBPACK_IMPORTED_MODULE_1__); 97 | /* harmony import */ var _wordpress_element__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! @wordpress/element */ "@wordpress/element"); 98 | /* harmony import */ var _wordpress_element__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(_wordpress_element__WEBPACK_IMPORTED_MODULE_2__); 99 | /* harmony import */ var _wordpress_components__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! @wordpress/components */ "@wordpress/components"); 100 | /* harmony import */ var _wordpress_components__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(_wordpress_components__WEBPACK_IMPORTED_MODULE_3__); 101 | /* harmony import */ var _wordpress_data__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! @wordpress/data */ "@wordpress/data"); 102 | /* harmony import */ var _wordpress_data__WEBPACK_IMPORTED_MODULE_4___default = /*#__PURE__*/__webpack_require__.n(_wordpress_data__WEBPACK_IMPORTED_MODULE_4__); 103 | /* harmony import */ var _wordpress_core_data__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! @wordpress/core-data */ "@wordpress/core-data"); 104 | /* harmony import */ var _wordpress_core_data__WEBPACK_IMPORTED_MODULE_5___default = /*#__PURE__*/__webpack_require__.n(_wordpress_core_data__WEBPACK_IMPORTED_MODULE_5__); 105 | /* harmony import */ var _Panel__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./Panel */ "./src/components/Panel.js"); 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | function SettingsPage() { 114 | // Get the settings from the store. 115 | const { 116 | record: settings, 117 | hasResolved 118 | } = (0,_wordpress_data__WEBPACK_IMPORTED_MODULE_4__.useSelect)(select => { 119 | return { 120 | record: select(_wordpress_core_data__WEBPACK_IMPORTED_MODULE_5__.store).getEditedEntityRecord('root', 'site'), 121 | hasResolved: select(_wordpress_core_data__WEBPACK_IMPORTED_MODULE_5__.store).hasFinishedResolution('getEditedEntityRecord', ['root', 'site']) 122 | }; 123 | }); 124 | 125 | // We'll use these functions to save the settings to the store. 126 | const { 127 | saveEntityRecord 128 | } = (0,_wordpress_data__WEBPACK_IMPORTED_MODULE_4__.useDispatch)(_wordpress_core_data__WEBPACK_IMPORTED_MODULE_5__.store); 129 | 130 | // State to show a success message when the settings are saved. 131 | const [success, setSuccess] = (0,_wordpress_element__WEBPACK_IMPORTED_MODULE_2__.useState)(false); 132 | 133 | // State to keep track of which tab is active. 134 | const [activeTab, setActiveTab] = (0,_wordpress_element__WEBPACK_IMPORTED_MODULE_2__.useState)('panel'); 135 | 136 | // If the settings haven't been loaded yet, we'll return null. 137 | // This needs to happen after all the hooks are called. 138 | if (!hasResolved) { 139 | return null; 140 | } 141 | // In the block editor, saving to the database happens automatically when you publish or update a post. 142 | // In the our settings page, you would need to add a separate button to save the settings. 143 | const saveOptions = event => { 144 | event.preventDefault(); 145 | saveEntityRecord('root', 'site', { 146 | wpdev_account_settings: settings.wpdev_account_settings 147 | }).then(response => { 148 | setSuccess(true); 149 | console.log(response); 150 | }); 151 | }; 152 | return (0,react__WEBPACK_IMPORTED_MODULE_0__.createElement)("form", { 153 | className: "example-wp-settings", 154 | onSubmit: saveOptions 155 | }, (0,react__WEBPACK_IMPORTED_MODULE_0__.createElement)(_wordpress_components__WEBPACK_IMPORTED_MODULE_3__.Card, null, (0,react__WEBPACK_IMPORTED_MODULE_0__.createElement)(_wordpress_components__WEBPACK_IMPORTED_MODULE_3__.CardBody, null, (0,react__WEBPACK_IMPORTED_MODULE_0__.createElement)("h1", null, (0,_wordpress_i18n__WEBPACK_IMPORTED_MODULE_1__.__)('Example WP Settings Settings')), (0,react__WEBPACK_IMPORTED_MODULE_0__.createElement)(_wordpress_components__WEBPACK_IMPORTED_MODULE_3__.TabPanel, { 156 | className: "example-wp-settings-tab-panel", 157 | onSelect: tabName => { 158 | setActiveTab(tabName); 159 | }, 160 | initialTabName: activeTab, 161 | tabs: [{ 162 | name: 'panel', 163 | title: 'Example Panel', 164 | content: (0,react__WEBPACK_IMPORTED_MODULE_0__.createElement)(_Panel__WEBPACK_IMPORTED_MODULE_6__["default"], null) 165 | }] 166 | }, tab => (0,react__WEBPACK_IMPORTED_MODULE_0__.createElement)(react__WEBPACK_IMPORTED_MODULE_0__.Fragment, null, tab.content))), (0,react__WEBPACK_IMPORTED_MODULE_0__.createElement)(_wordpress_components__WEBPACK_IMPORTED_MODULE_3__.CardDivider, null), (0,react__WEBPACK_IMPORTED_MODULE_0__.createElement)(_wordpress_components__WEBPACK_IMPORTED_MODULE_3__.CardBody, null, (0,react__WEBPACK_IMPORTED_MODULE_0__.createElement)(_wordpress_components__WEBPACK_IMPORTED_MODULE_3__.Flex, null, (0,react__WEBPACK_IMPORTED_MODULE_0__.createElement)(_wordpress_components__WEBPACK_IMPORTED_MODULE_3__.FlexItem, null, (0,react__WEBPACK_IMPORTED_MODULE_0__.createElement)(_wordpress_components__WEBPACK_IMPORTED_MODULE_3__.Button, { 167 | variant: "primary", 168 | type: "submit" 169 | }, "Save Changes")), (0,react__WEBPACK_IMPORTED_MODULE_0__.createElement)(_wordpress_components__WEBPACK_IMPORTED_MODULE_3__.FlexItem, null, success && (0,react__WEBPACK_IMPORTED_MODULE_0__.createElement)(_wordpress_components__WEBPACK_IMPORTED_MODULE_3__.Snackbar, { 170 | status: 'success', 171 | onDismiss: function noRefCheck() { 172 | setSuccess(false); 173 | }, 174 | onRemove: function noRefCheck() {} 175 | }, "Saved")))))); 176 | } 177 | /* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (SettingsPage); 178 | 179 | /***/ }), 180 | 181 | /***/ "./src/index.js": 182 | /*!**********************!*\ 183 | !*** ./src/index.js ***! 184 | \**********************/ 185 | /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { 186 | 187 | __webpack_require__.r(__webpack_exports__); 188 | /* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! react */ "react"); 189 | /* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_0__); 190 | /* harmony import */ var _wordpress_element__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @wordpress/element */ "@wordpress/element"); 191 | /* harmony import */ var _wordpress_element__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_wordpress_element__WEBPACK_IMPORTED_MODULE_1__); 192 | /* harmony import */ var _components_SettingsPage__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./components/SettingsPage */ "./src/components/SettingsPage.js"); 193 | /* harmony import */ var _style_scss__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./style.scss */ "./src/style.scss"); 194 | 195 | 196 | 197 | 198 | let root = (0,_wordpress_element__WEBPACK_IMPORTED_MODULE_1__.createRoot)(document.getElementById('root')); 199 | root.render((0,react__WEBPACK_IMPORTED_MODULE_0__.createElement)(_components_SettingsPage__WEBPACK_IMPORTED_MODULE_2__["default"], null)); 200 | 201 | /***/ }), 202 | 203 | /***/ "./src/style.scss": 204 | /*!************************!*\ 205 | !*** ./src/style.scss ***! 206 | \************************/ 207 | /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { 208 | 209 | __webpack_require__.r(__webpack_exports__); 210 | // extracted by mini-css-extract-plugin 211 | 212 | 213 | /***/ }), 214 | 215 | /***/ "react": 216 | /*!************************!*\ 217 | !*** external "React" ***! 218 | \************************/ 219 | /***/ ((module) => { 220 | 221 | module.exports = window["React"]; 222 | 223 | /***/ }), 224 | 225 | /***/ "@wordpress/components": 226 | /*!************************************!*\ 227 | !*** external ["wp","components"] ***! 228 | \************************************/ 229 | /***/ ((module) => { 230 | 231 | module.exports = window["wp"]["components"]; 232 | 233 | /***/ }), 234 | 235 | /***/ "@wordpress/core-data": 236 | /*!**********************************!*\ 237 | !*** external ["wp","coreData"] ***! 238 | \**********************************/ 239 | /***/ ((module) => { 240 | 241 | module.exports = window["wp"]["coreData"]; 242 | 243 | /***/ }), 244 | 245 | /***/ "@wordpress/data": 246 | /*!******************************!*\ 247 | !*** external ["wp","data"] ***! 248 | \******************************/ 249 | /***/ ((module) => { 250 | 251 | module.exports = window["wp"]["data"]; 252 | 253 | /***/ }), 254 | 255 | /***/ "@wordpress/element": 256 | /*!*********************************!*\ 257 | !*** external ["wp","element"] ***! 258 | \*********************************/ 259 | /***/ ((module) => { 260 | 261 | module.exports = window["wp"]["element"]; 262 | 263 | /***/ }), 264 | 265 | /***/ "@wordpress/i18n": 266 | /*!******************************!*\ 267 | !*** external ["wp","i18n"] ***! 268 | \******************************/ 269 | /***/ ((module) => { 270 | 271 | module.exports = window["wp"]["i18n"]; 272 | 273 | /***/ }) 274 | 275 | /******/ }); 276 | /************************************************************************/ 277 | /******/ // The module cache 278 | /******/ var __webpack_module_cache__ = {}; 279 | /******/ 280 | /******/ // The require function 281 | /******/ function __webpack_require__(moduleId) { 282 | /******/ // Check if module is in cache 283 | /******/ var cachedModule = __webpack_module_cache__[moduleId]; 284 | /******/ if (cachedModule !== undefined) { 285 | /******/ return cachedModule.exports; 286 | /******/ } 287 | /******/ // Create a new module (and put it into the cache) 288 | /******/ var module = __webpack_module_cache__[moduleId] = { 289 | /******/ // no module.id needed 290 | /******/ // no module.loaded needed 291 | /******/ exports: {} 292 | /******/ }; 293 | /******/ 294 | /******/ // Execute the module function 295 | /******/ __webpack_modules__[moduleId](module, module.exports, __webpack_require__); 296 | /******/ 297 | /******/ // Return the exports of the module 298 | /******/ return module.exports; 299 | /******/ } 300 | /******/ 301 | /******/ // expose the modules object (__webpack_modules__) 302 | /******/ __webpack_require__.m = __webpack_modules__; 303 | /******/ 304 | /************************************************************************/ 305 | /******/ /* webpack/runtime/chunk loaded */ 306 | /******/ (() => { 307 | /******/ var deferred = []; 308 | /******/ __webpack_require__.O = (result, chunkIds, fn, priority) => { 309 | /******/ if(chunkIds) { 310 | /******/ priority = priority || 0; 311 | /******/ for(var i = deferred.length; i > 0 && deferred[i - 1][2] > priority; i--) deferred[i] = deferred[i - 1]; 312 | /******/ deferred[i] = [chunkIds, fn, priority]; 313 | /******/ return; 314 | /******/ } 315 | /******/ var notFulfilled = Infinity; 316 | /******/ for (var i = 0; i < deferred.length; i++) { 317 | /******/ var [chunkIds, fn, priority] = deferred[i]; 318 | /******/ var fulfilled = true; 319 | /******/ for (var j = 0; j < chunkIds.length; j++) { 320 | /******/ if ((priority & 1 === 0 || notFulfilled >= priority) && Object.keys(__webpack_require__.O).every((key) => (__webpack_require__.O[key](chunkIds[j])))) { 321 | /******/ chunkIds.splice(j--, 1); 322 | /******/ } else { 323 | /******/ fulfilled = false; 324 | /******/ if(priority < notFulfilled) notFulfilled = priority; 325 | /******/ } 326 | /******/ } 327 | /******/ if(fulfilled) { 328 | /******/ deferred.splice(i--, 1) 329 | /******/ var r = fn(); 330 | /******/ if (r !== undefined) result = r; 331 | /******/ } 332 | /******/ } 333 | /******/ return result; 334 | /******/ }; 335 | /******/ })(); 336 | /******/ 337 | /******/ /* webpack/runtime/compat get default export */ 338 | /******/ (() => { 339 | /******/ // getDefaultExport function for compatibility with non-harmony modules 340 | /******/ __webpack_require__.n = (module) => { 341 | /******/ var getter = module && module.__esModule ? 342 | /******/ () => (module['default']) : 343 | /******/ () => (module); 344 | /******/ __webpack_require__.d(getter, { a: getter }); 345 | /******/ return getter; 346 | /******/ }; 347 | /******/ })(); 348 | /******/ 349 | /******/ /* webpack/runtime/define property getters */ 350 | /******/ (() => { 351 | /******/ // define getter functions for harmony exports 352 | /******/ __webpack_require__.d = (exports, definition) => { 353 | /******/ for(var key in definition) { 354 | /******/ if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) { 355 | /******/ Object.defineProperty(exports, key, { enumerable: true, get: definition[key] }); 356 | /******/ } 357 | /******/ } 358 | /******/ }; 359 | /******/ })(); 360 | /******/ 361 | /******/ /* webpack/runtime/hasOwnProperty shorthand */ 362 | /******/ (() => { 363 | /******/ __webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop)) 364 | /******/ })(); 365 | /******/ 366 | /******/ /* webpack/runtime/make namespace object */ 367 | /******/ (() => { 368 | /******/ // define __esModule on exports 369 | /******/ __webpack_require__.r = (exports) => { 370 | /******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) { 371 | /******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' }); 372 | /******/ } 373 | /******/ Object.defineProperty(exports, '__esModule', { value: true }); 374 | /******/ }; 375 | /******/ })(); 376 | /******/ 377 | /******/ /* webpack/runtime/jsonp chunk loading */ 378 | /******/ (() => { 379 | /******/ // no baseURI 380 | /******/ 381 | /******/ // object to store loaded and loading chunks 382 | /******/ // undefined = chunk not loaded, null = chunk preloaded/prefetched 383 | /******/ // [resolve, reject, Promise] = chunk loading, 0 = chunk loaded 384 | /******/ var installedChunks = { 385 | /******/ "index": 0, 386 | /******/ "./style-index": 0 387 | /******/ }; 388 | /******/ 389 | /******/ // no chunk on demand loading 390 | /******/ 391 | /******/ // no prefetching 392 | /******/ 393 | /******/ // no preloaded 394 | /******/ 395 | /******/ // no HMR 396 | /******/ 397 | /******/ // no HMR manifest 398 | /******/ 399 | /******/ __webpack_require__.O.j = (chunkId) => (installedChunks[chunkId] === 0); 400 | /******/ 401 | /******/ // install a JSONP callback for chunk loading 402 | /******/ var webpackJsonpCallback = (parentChunkLoadingFunction, data) => { 403 | /******/ var [chunkIds, moreModules, runtime] = data; 404 | /******/ // add "moreModules" to the modules object, 405 | /******/ // then flag all "chunkIds" as loaded and fire callback 406 | /******/ var moduleId, chunkId, i = 0; 407 | /******/ if(chunkIds.some((id) => (installedChunks[id] !== 0))) { 408 | /******/ for(moduleId in moreModules) { 409 | /******/ if(__webpack_require__.o(moreModules, moduleId)) { 410 | /******/ __webpack_require__.m[moduleId] = moreModules[moduleId]; 411 | /******/ } 412 | /******/ } 413 | /******/ if(runtime) var result = runtime(__webpack_require__); 414 | /******/ } 415 | /******/ if(parentChunkLoadingFunction) parentChunkLoadingFunction(data); 416 | /******/ for(;i < chunkIds.length; i++) { 417 | /******/ chunkId = chunkIds[i]; 418 | /******/ if(__webpack_require__.o(installedChunks, chunkId) && installedChunks[chunkId]) { 419 | /******/ installedChunks[chunkId][0](); 420 | /******/ } 421 | /******/ installedChunks[chunkId] = 0; 422 | /******/ } 423 | /******/ return __webpack_require__.O(result); 424 | /******/ } 425 | /******/ 426 | /******/ var chunkLoadingGlobal = globalThis["webpackChunkexample_wp_settings"] = globalThis["webpackChunkexample_wp_settings"] || []; 427 | /******/ chunkLoadingGlobal.forEach(webpackJsonpCallback.bind(null, 0)); 428 | /******/ chunkLoadingGlobal.push = webpackJsonpCallback.bind(null, chunkLoadingGlobal.push.bind(chunkLoadingGlobal)); 429 | /******/ })(); 430 | /******/ 431 | /************************************************************************/ 432 | /******/ 433 | /******/ // startup 434 | /******/ // Load entry module and return exports 435 | /******/ // This entry module depends on other loaded chunks and execution need to be delayed 436 | /******/ var __webpack_exports__ = __webpack_require__.O(undefined, ["./style-index"], () => (__webpack_require__("./src/index.js"))) 437 | /******/ __webpack_exports__ = __webpack_require__.O(__webpack_exports__); 438 | /******/ 439 | /******/ })() 440 | ; 441 | //# sourceMappingURL=index.js.map -------------------------------------------------------------------------------- /build/index.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"index.js","mappings":";;;;;;;;;;;;;;;;;;;;;;;;;AAAqC;AAC+B;AAEX;AACC;AAE1D,SAASQ,KAAKA,CAAA,EAAG;EAChB;EACA,MAAM;IAAEC,MAAM,EAAEC,QAAQ;IAAEC;EAAY,CAAC,GAAGN,0DAAS,CAAIO,MAAM,IAAM;IAClE,OAAO;MACNH,MAAM,EAAEG,MAAM,CAAEL,uDAAU,CAAC,CAACM,qBAAqB,CAAE,MAAM,EAAE,MAAO,CAAC;MACnEF,WAAW,EAAEC,MAAM,CAAEL,uDAAU,CAAC,CAACO,qBAAqB,CACrD,uBAAuB,EACvB,CAAE,MAAM,EAAE,MAAM,CACjB;IACD,CAAC;EACF,CAAE,CAAC;;EAEH;EACA,MAAM;IAAEC;EAAiB,CAAC,GAAGX,4DAAW,CAAEG,uDAAU,CAAC;EAErD,IAAK,CAAEI,WAAW,EAAG;IACpB,OAAO,IAAI;EACZ;;EAEA;EACA,MAAMK,aAAa,GAAGA,CAAEC,GAAG,EAAEC,KAAK,KAAM;IACvCH,gBAAgB,CAAE,MAAM,EAAE,MAAM,EAAEI,SAAS,EAAE;MAC5CC,sBAAsB,EAAE;QACvB,GAAGV,QAAQ,CAACU,sBAAsB;QAClC,CAAEH,GAAG,GAAIC;MACV;IACD,CAAE,CAAC;EACJ,CAAC;EAED,OACCG,oDAAA,CAACpB,uDAAI;IACJqB,SAAS,EAAC,QAAQ;IAClBC,GAAG,EAAC,GAAG;IACPC,SAAS,EAAC;EAAiC,GAE3CH,oDAAA,CAACnB,2DAAQ,QACRmB,oDAAA,CAAClB,8DAAW;IACXsB,KAAK,EAAGzB,mDAAE,CAAE,eAAgB,CAAG;IAC/BkB,KAAK,EAAGR,QAAQ,CAACU,sBAAsB,EAAEM,cAAgB;IACzDC,IAAI,EAAG,MAAQ;IACfC,QAAQ,EAAKV,KAAK,IAAM;MACvBF,aAAa,CAAE,gBAAgB,EAAEE,KAAM,CAAC;IACzC;EAAG,CACH,CACQ,CAAC,EACXG,oDAAA,CAACnB,2DAAQ,QACRmB,oDAAA,CAAClB,8DAAW;IACXsB,KAAK,EAAGzB,mDAAE,CAAE,aAAc,CAAG;IAC7BkB,KAAK,EAAGR,QAAQ,CAACU,sBAAsB,EAAES,WAAa;IACtDF,IAAI,EAAG,UAAY;IACnBC,QAAQ,EAAKV,KAAK,IAAM;MACvBF,aAAa,CAAE,aAAa,EAAEE,KAAM,CAAC;IACtC;EAAG,CACH,CACQ,CACL,CAAC;AAET;AAEA,iEAAeV,KAAK;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACjEiB;AACoB;AAU1B;AAE0B;AACC;AAE9B;AAE5B,SAAS8B,YAAYA,CAAA,EAAG;EACvB;EACA,MAAM;IAAE7B,MAAM,EAAEC,QAAQ;IAAEC;EAAY,CAAC,GAAGN,0DAAS,CAAIO,MAAM,IAAM;IAClE,OAAO;MACNH,MAAM,EAAEG,MAAM,CAAEL,uDAAU,CAAC,CAACM,qBAAqB,CAAE,MAAM,EAAE,MAAO,CAAC;MACnEF,WAAW,EAAEC,MAAM,CAAEL,uDAAU,CAAC,CAACO,qBAAqB,CACrD,uBAAuB,EACvB,CAAE,MAAM,EAAE,MAAM,CACjB;IACD,CAAC;EACF,CAAE,CAAC;;EAEH;EACA,MAAM;IAAEyB;EAAiB,CAAC,GAAGnC,4DAAW,CAAEG,uDAAU,CAAC;;EAErD;EACA,MAAM,CAAEiC,OAAO,EAAEC,UAAU,CAAE,GAAGX,4DAAQ,CAAE,KAAM,CAAC;;EAEjD;EACA,MAAM,CAAEY,SAAS,EAAEC,YAAY,CAAE,GAAGb,4DAAQ,CAAE,OAAQ,CAAC;;EAEvD;EACA;EACA,IAAK,CAAEnB,WAAW,EAAG;IACpB,OAAO,IAAI;EACZ;EACA;EACA;EACA,MAAMiC,WAAW,GAAKC,KAAK,IAAM;IAChCA,KAAK,CAACC,cAAc,CAAC,CAAC;IACtBP,gBAAgB,CAAE,MAAM,EAAE,MAAM,EAAE;MACjCnB,sBAAsB,EAAEV,QAAQ,CAACU;IAClC,CAAE,CAAC,CAAC2B,IAAI,CAAIC,QAAQ,IAAM;MACzBP,UAAU,CAAE,IAAK,CAAC;MAClBQ,OAAO,CAACC,GAAG,CAAEF,QAAS,CAAC;IACxB,CAAE,CAAC;EACJ,CAAC;EAED,OACC3B,oDAAA;IAAMG,SAAS,EAAC,qBAAqB;IAAC2B,QAAQ,EAAGP;EAAa,GAC7DvB,oDAAA,CAACW,uDAAI,QACJX,oDAAA,CAACY,2DAAQ,QACRZ,oDAAA,aAAMrB,mDAAE,CAAE,8BAA+B,CAAO,CAAC,EACjDqB,oDAAA,CAACgB,2DAAQ;IACRb,SAAS,EAAC,+BAA+B;IACzC4B,QAAQ,EAAKC,OAAO,IAAM;MACzBV,YAAY,CAAEU,OAAQ,CAAC;IACxB,CAAG;IACHC,cAAc,EAAGZ,SAAW;IAC5Ba,IAAI,EAAG,CACN;MACCC,IAAI,EAAE,OAAO;MACbC,KAAK,EAAE,eAAe;MACtBC,OAAO,EAAErC,oDAAA,CAACb,8CAAK,MAAE;IAClB,CAAC;EACC,GAECmD,GAAG,IAAMtC,oDAAA,CAAAuC,2CAAA,QAAID,GAAG,CAACD,OAAW,CACvB,CACD,CAAC,EACXrC,oDAAA,CAACa,8DAAW,MAAE,CAAC,EACfb,oDAAA,CAACY,2DAAQ,QACRZ,oDAAA,CAACpB,uDAAI,QACJoB,oDAAA,CAACnB,2DAAQ,QACRmB,oDAAA,CAACc,yDAAM;IAAC0B,OAAO,EAAC,SAAS;IAAClC,IAAI,EAAC;EAAQ,GAAC,cAEhC,CACC,CAAC,EACXN,oDAAA,CAACnB,2DAAQ,QACNsC,OAAO,IACRnB,oDAAA,CAACe,2DAAQ;IACR0B,MAAM,EAAG,SAAW;IACpBC,SAAS,EAAG,SAASC,UAAUA,CAAA,EAAG;MACjCvB,UAAU,CAAE,KAAM,CAAC;IACpB,CAAG;IACHwB,QAAQ,EAAG,SAASD,UAAUA,CAAA,EAAG,CAAC;EAAG,GACrC,OAES,CAEF,CACL,CACG,CACL,CACD,CAAC;AAET;AAEA,iEAAe1B,YAAY;;;;;;;;;;;;;;;;;;AC1GqB;AACK;AAE/B;AAEtB,IAAI6B,IAAI,GAAGD,8DAAU,CAAEE,QAAQ,CAACC,cAAc,CAAE,MAAO,CAAE,CAAC;AAC1DF,IAAI,CAACG,MAAM,CAAEjD,oDAAA,CAACiB,gEAAY,MAAE,CAAE,CAAC;;;;;;;;;;;ACN/B;;;;;;;;;;;ACAA;;;;;;;;;;ACAA;;;;;;;;;;ACAA;;;;;;;;;;ACAA;;;;;;;;;;ACAA;;;;;;;;;;ACAA;;;;;;UCAA;UACA;;UAEA;UACA;UACA;UACA;UACA;UACA;UACA;UACA;UACA;UACA;UACA;UACA;UACA;;UAEA;UACA;;UAEA;UACA;UACA;;UAEA;UACA;;;;;WCzBA;WACA;WACA;WACA;WACA,+BAA+B,wCAAwC;WACvE;WACA;WACA;WACA;WACA,iBAAiB,qBAAqB;WACtC;WACA;WACA,kBAAkB,qBAAqB;WACvC;WACA;WACA,KAAK;WACL;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;;;;;WC3BA;WACA;WACA;WACA;WACA;WACA,iCAAiC,WAAW;WAC5C;WACA;;;;;WCPA;WACA;WACA;WACA;WACA,yCAAyC,wCAAwC;WACjF;WACA;WACA;;;;;WCPA;;;;;WCAA;WACA;WACA;WACA,uDAAuD,iBAAiB;WACxE;WACA,gDAAgD,aAAa;WAC7D;;;;;WCNA;;WAEA;WACA;WACA;WACA;WACA;WACA;WACA;;WAEA;;WAEA;;WAEA;;WAEA;;WAEA;;WAEA;;WAEA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA,MAAM,qBAAqB;WAC3B;WACA;WACA;WACA;WACA;WACA;WACA;WACA;;WAEA;WACA;WACA;;;;;UEjDA;UACA;UACA;UACA;UACA","sources":["webpack://example-wp-settings/./src/components/Panel.js","webpack://example-wp-settings/./src/components/SettingsPage.js","webpack://example-wp-settings/./src/index.js","webpack://example-wp-settings/./src/style.scss?75bd","webpack://example-wp-settings/external window \"React\"","webpack://example-wp-settings/external window [\"wp\",\"components\"]","webpack://example-wp-settings/external window [\"wp\",\"coreData\"]","webpack://example-wp-settings/external window [\"wp\",\"data\"]","webpack://example-wp-settings/external window [\"wp\",\"element\"]","webpack://example-wp-settings/external window [\"wp\",\"i18n\"]","webpack://example-wp-settings/webpack/bootstrap","webpack://example-wp-settings/webpack/runtime/chunk loaded","webpack://example-wp-settings/webpack/runtime/compat get default export","webpack://example-wp-settings/webpack/runtime/define property getters","webpack://example-wp-settings/webpack/runtime/hasOwnProperty shorthand","webpack://example-wp-settings/webpack/runtime/make namespace object","webpack://example-wp-settings/webpack/runtime/jsonp chunk loading","webpack://example-wp-settings/webpack/before-startup","webpack://example-wp-settings/webpack/startup","webpack://example-wp-settings/webpack/after-startup"],"sourcesContent":["import { __ } from '@wordpress/i18n';\nimport { Flex, FlexItem, TextControl } from '@wordpress/components';\n\nimport { useDispatch, useSelect } from '@wordpress/data';\nimport { store as coreStore } from '@wordpress/core-data';\n\nfunction Panel() {\n\t// Get the settings from the store.\n\tconst { record: settings, hasResolved } = useSelect( ( select ) => {\n\t\treturn {\n\t\t\trecord: select( coreStore ).getEditedEntityRecord( 'root', 'site' ),\n\t\t\thasResolved: select( coreStore ).hasFinishedResolution(\n\t\t\t\t'getEditedEntityRecord',\n\t\t\t\t[ 'root', 'site' ]\n\t\t\t),\n\t\t};\n\t} );\n\n\t// We'll use these functions to save the settings to the store.\n\tconst { editEntityRecord } = useDispatch( coreStore );\n\n\tif ( ! hasResolved ) {\n\t\treturn null;\n\t}\n\n\t// This will save settings the settings to the local state only.\n\tconst updateOptions = ( key, value ) => {\n\t\teditEntityRecord( 'root', 'site', undefined, {\n\t\t\twpdev_account_settings: {\n\t\t\t\t...settings.wpdev_account_settings,\n\t\t\t\t[ key ]: value,\n\t\t\t},\n\t\t} );\n\t};\n\n\treturn (\n\t\t\n\t\t\t\n\t\t\t\t {\n\t\t\t\t\t\tupdateOptions( 'account_number', value );\n\t\t\t\t\t} }\n\t\t\t\t/>\n\t\t\t\n\t\t\t\n\t\t\t\t {\n\t\t\t\t\t\tupdateOptions( 'account_key', value );\n\t\t\t\t\t} }\n\t\t\t\t/>\n\t\t\t\n\t\t\n\t);\n}\n\nexport default Panel;\n","import { __ } from '@wordpress/i18n';\nimport { useState, useEffect } from '@wordpress/element';\nimport {\n\tCard,\n\tCardBody,\n\tCardDivider,\n\tFlex,\n\tFlexItem,\n\tButton,\n\tSnackbar,\n\tTabPanel,\n} from '@wordpress/components';\n\nimport { useDispatch, useSelect } from '@wordpress/data';\nimport { store as coreStore } from '@wordpress/core-data';\n\nimport Panel from './Panel';\n\nfunction SettingsPage() {\n\t// Get the settings from the store.\n\tconst { record: settings, hasResolved } = useSelect( ( select ) => {\n\t\treturn {\n\t\t\trecord: select( coreStore ).getEditedEntityRecord( 'root', 'site' ),\n\t\t\thasResolved: select( coreStore ).hasFinishedResolution(\n\t\t\t\t'getEditedEntityRecord',\n\t\t\t\t[ 'root', 'site' ]\n\t\t\t),\n\t\t};\n\t} );\n\n\t// We'll use these functions to save the settings to the store.\n\tconst { saveEntityRecord } = useDispatch( coreStore );\n\n\t// State to show a success message when the settings are saved.\n\tconst [ success, setSuccess ] = useState( false );\n\n\t// State to keep track of which tab is active.\n\tconst [ activeTab, setActiveTab ] = useState( 'panel' );\n\n\t// If the settings haven't been loaded yet, we'll return null.\n\t// This needs to happen after all the hooks are called.\n\tif ( ! hasResolved ) {\n\t\treturn null;\n\t}\n\t// In the block editor, saving to the database happens automatically when you publish or update a post.\n\t// In the our settings page, you would need to add a separate button to save the settings.\n\tconst saveOptions = ( event ) => {\n\t\tevent.preventDefault();\n\t\tsaveEntityRecord( 'root', 'site', {\n\t\t\twpdev_account_settings: settings.wpdev_account_settings,\n\t\t} ).then( ( response ) => {\n\t\t\tsetSuccess( true );\n\t\t\tconsole.log( response );\n\t\t} );\n\t};\n\n\treturn (\n\t\t
\n\t\t\t\n\t\t\t\t\n\t\t\t\t\t

{ __( 'Example WP Settings Settings' ) }

\n\t\t\t\t\t {\n\t\t\t\t\t\t\tsetActiveTab( tabName );\n\t\t\t\t\t\t} }\n\t\t\t\t\t\tinitialTabName={ activeTab }\n\t\t\t\t\t\ttabs={ [\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tname: 'panel',\n\t\t\t\t\t\t\t\ttitle: 'Example Panel',\n\t\t\t\t\t\t\t\tcontent: ,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t] }\n\t\t\t\t\t>\n\t\t\t\t\t\t{ ( tab ) => <>{ tab.content } }\n\t\t\t\t\t\n\t\t\t\t
\n\t\t\t\t\n\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\n\t\t\t\t\t\t\n\t\t\t\t\t\t\t{ success && (\n\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\tSaved\n\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t) }\n\t\t\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t\n\t\t\t
\n\t\t
\n\t);\n}\n\nexport default SettingsPage;\n","import { createRoot } from '@wordpress/element';\nimport SettingsPage from './components/SettingsPage';\n\nimport './style.scss';\n\nlet root = createRoot( document.getElementById( 'root' ) );\nroot.render( );\n","// extracted by mini-css-extract-plugin\nexport {};","module.exports = window[\"React\"];","module.exports = window[\"wp\"][\"components\"];","module.exports = window[\"wp\"][\"coreData\"];","module.exports = window[\"wp\"][\"data\"];","module.exports = window[\"wp\"][\"element\"];","module.exports = window[\"wp\"][\"i18n\"];","// The module cache\nvar __webpack_module_cache__ = {};\n\n// The require function\nfunction __webpack_require__(moduleId) {\n\t// Check if module is in cache\n\tvar cachedModule = __webpack_module_cache__[moduleId];\n\tif (cachedModule !== undefined) {\n\t\treturn cachedModule.exports;\n\t}\n\t// Create a new module (and put it into the cache)\n\tvar module = __webpack_module_cache__[moduleId] = {\n\t\t// no module.id needed\n\t\t// no module.loaded needed\n\t\texports: {}\n\t};\n\n\t// Execute the module function\n\t__webpack_modules__[moduleId](module, module.exports, __webpack_require__);\n\n\t// Return the exports of the module\n\treturn module.exports;\n}\n\n// expose the modules object (__webpack_modules__)\n__webpack_require__.m = __webpack_modules__;\n\n","var deferred = [];\n__webpack_require__.O = (result, chunkIds, fn, priority) => {\n\tif(chunkIds) {\n\t\tpriority = priority || 0;\n\t\tfor(var i = deferred.length; i > 0 && deferred[i - 1][2] > priority; i--) deferred[i] = deferred[i - 1];\n\t\tdeferred[i] = [chunkIds, fn, priority];\n\t\treturn;\n\t}\n\tvar notFulfilled = Infinity;\n\tfor (var i = 0; i < deferred.length; i++) {\n\t\tvar [chunkIds, fn, priority] = deferred[i];\n\t\tvar fulfilled = true;\n\t\tfor (var j = 0; j < chunkIds.length; j++) {\n\t\t\tif ((priority & 1 === 0 || notFulfilled >= priority) && Object.keys(__webpack_require__.O).every((key) => (__webpack_require__.O[key](chunkIds[j])))) {\n\t\t\t\tchunkIds.splice(j--, 1);\n\t\t\t} else {\n\t\t\t\tfulfilled = false;\n\t\t\t\tif(priority < notFulfilled) notFulfilled = priority;\n\t\t\t}\n\t\t}\n\t\tif(fulfilled) {\n\t\t\tdeferred.splice(i--, 1)\n\t\t\tvar r = fn();\n\t\t\tif (r !== undefined) result = r;\n\t\t}\n\t}\n\treturn result;\n};","// getDefaultExport function for compatibility with non-harmony modules\n__webpack_require__.n = (module) => {\n\tvar getter = module && module.__esModule ?\n\t\t() => (module['default']) :\n\t\t() => (module);\n\t__webpack_require__.d(getter, { a: getter });\n\treturn getter;\n};","// define getter functions for harmony exports\n__webpack_require__.d = (exports, definition) => {\n\tfor(var key in definition) {\n\t\tif(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n\t\t\tObject.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n\t\t}\n\t}\n};","__webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))","// define __esModule on exports\n__webpack_require__.r = (exports) => {\n\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n\t}\n\tObject.defineProperty(exports, '__esModule', { value: true });\n};","// no baseURI\n\n// object to store loaded and loading chunks\n// undefined = chunk not loaded, null = chunk preloaded/prefetched\n// [resolve, reject, Promise] = chunk loading, 0 = chunk loaded\nvar installedChunks = {\n\t\"index\": 0,\n\t\"./style-index\": 0\n};\n\n// no chunk on demand loading\n\n// no prefetching\n\n// no preloaded\n\n// no HMR\n\n// no HMR manifest\n\n__webpack_require__.O.j = (chunkId) => (installedChunks[chunkId] === 0);\n\n// install a JSONP callback for chunk loading\nvar webpackJsonpCallback = (parentChunkLoadingFunction, data) => {\n\tvar [chunkIds, moreModules, runtime] = data;\n\t// add \"moreModules\" to the modules object,\n\t// then flag all \"chunkIds\" as loaded and fire callback\n\tvar moduleId, chunkId, i = 0;\n\tif(chunkIds.some((id) => (installedChunks[id] !== 0))) {\n\t\tfor(moduleId in moreModules) {\n\t\t\tif(__webpack_require__.o(moreModules, moduleId)) {\n\t\t\t\t__webpack_require__.m[moduleId] = moreModules[moduleId];\n\t\t\t}\n\t\t}\n\t\tif(runtime) var result = runtime(__webpack_require__);\n\t}\n\tif(parentChunkLoadingFunction) parentChunkLoadingFunction(data);\n\tfor(;i < chunkIds.length; i++) {\n\t\tchunkId = chunkIds[i];\n\t\tif(__webpack_require__.o(installedChunks, chunkId) && installedChunks[chunkId]) {\n\t\t\tinstalledChunks[chunkId][0]();\n\t\t}\n\t\tinstalledChunks[chunkId] = 0;\n\t}\n\treturn __webpack_require__.O(result);\n}\n\nvar chunkLoadingGlobal = globalThis[\"webpackChunkexample_wp_settings\"] = globalThis[\"webpackChunkexample_wp_settings\"] || [];\nchunkLoadingGlobal.forEach(webpackJsonpCallback.bind(null, 0));\nchunkLoadingGlobal.push = webpackJsonpCallback.bind(null, chunkLoadingGlobal.push.bind(chunkLoadingGlobal));","","// startup\n// Load entry module and return exports\n// This entry module depends on other loaded chunks and execution need to be delayed\nvar __webpack_exports__ = __webpack_require__.O(undefined, [\"./style-index\"], () => (__webpack_require__(\"./src/index.js\")))\n__webpack_exports__ = __webpack_require__.O(__webpack_exports__);\n",""],"names":["__","Flex","FlexItem","TextControl","useDispatch","useSelect","store","coreStore","Panel","record","settings","hasResolved","select","getEditedEntityRecord","hasFinishedResolution","editEntityRecord","updateOptions","key","value","undefined","wpdev_account_settings","createElement","direction","gap","className","label","account_number","type","onChange","account_key","useState","useEffect","Card","CardBody","CardDivider","Button","Snackbar","TabPanel","SettingsPage","saveEntityRecord","success","setSuccess","activeTab","setActiveTab","saveOptions","event","preventDefault","then","response","console","log","onSubmit","onSelect","tabName","initialTabName","tabs","name","title","content","tab","Fragment","variant","status","onDismiss","noRefCheck","onRemove","createRoot","root","document","getElementById","render"],"sourceRoot":""} -------------------------------------------------------------------------------- /build/style-index.css: -------------------------------------------------------------------------------- 1 | /*!***************************************************************************************************************************************************************************************************************************************!*\ 2 | !*** css ./node_modules/css-loader/dist/cjs.js??ruleSet[1].rules[4].use[1]!./node_modules/postcss-loader/dist/cjs.js??ruleSet[1].rules[4].use[2]!./node_modules/sass-loader/dist/cjs.js??ruleSet[1].rules[4].use[3]!./src/style.scss ***! 3 | \***************************************************************************************************************************************************************************************************************************************/ 4 | .example-wp-settings { 5 | max-width: 780px; 6 | } 7 | .example-wp-settings h1 { 8 | text-align: center; 9 | } 10 | .example-wp-settings .example-wp-settings-tab-panel .components-tab-panel__tabs { 11 | justify-content: center; 12 | border-bottom: 1px solid #ddd; 13 | } 14 | .example-wp-settings .example-wp-settings-field-group { 15 | margin-top: 2rem; 16 | } 17 | 18 | /*# sourceMappingURL=style-index.css.map*/ -------------------------------------------------------------------------------- /build/style-index.css.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"./style-index.css","mappings":";;;AAAA;EACC;AACD;AAAC;EACC;AAEF;AACE;EACC;EACA;AACH;AAGC;EACC;AADF,C","sources":["webpack://example-wp-settings/./src/style.scss"],"sourcesContent":[".example-wp-settings {\n\tmax-width: 780px;\n\th1 {\n\t\ttext-align: center;\n\t}\n\t.example-wp-settings-tab-panel {\n\t\t.components-tab-panel__tabs {\n\t\t\tjustify-content: center;\n\t\t\tborder-bottom: 1px solid #ddd;\n\t\t}\n\t}\n\n\t.example-wp-settings-field-group {\n\t\tmargin-top: 2rem;\n\t}\n}\n"],"names":[],"sourceRoot":""} -------------------------------------------------------------------------------- /example-wp-settings.php: -------------------------------------------------------------------------------- 1 | 59 |
60 |
61 |
62 | id ) { 77 | return; 78 | } 79 | 80 | // Enqueue the styles for the core components library. 81 | wp_enqueue_style( 'global' ); 82 | wp_enqueue_style( 'wp-edit-post' ); 83 | 84 | // Our build processs generates a `index.asset.php` file for each entry point. 85 | $asset_file = include EXAMPLE_WP_SETTINGS_PATH . '/build/index.asset.php'; 86 | 87 | // Enqueue the admin page script and its dependencies. 88 | wp_enqueue_script( 'example-wp-settings-admin-page', EXAMPLE_WP_SETTINGS_URL . '/build/index.js', $asset_file['dependencies'], $asset_file['version'], true ); 89 | 90 | // Enqueue the admin page styles. 91 | wp_enqueue_style( 'example-wp-settings-admin-page', EXAMPLE_WP_SETTINGS_URL . '/build/style-index.css', array(), $asset_file['version'] ); 92 | } 93 | 94 | 95 | 96 | 97 | 98 | /** 99 | * Register our custom settings handler. 100 | * 101 | * @return void 102 | */ 103 | public static function register_custom_settings() { 104 | 105 | // Register our custom setting. 106 | register_setting( 107 | 'wpdev', 108 | 'wpdev_account_settings', 109 | array( 110 | 'type' => 'object', // Our setting is an object that could contain multiple values. 111 | 'description' => 'Account Settings for our API.', 112 | 'sanitize_callback' => array( get_class(), 'sanitize_callback' ), 113 | 'default' => array( // Default values for our setting. 114 | 'account_number' => '', 115 | 'account_key' => '', 116 | ), 117 | 'show_in_rest' => array( 118 | 'schema' => array( 119 | 'type' => 'object', 120 | 'properties' => array( 121 | 'account_number' => array( // Schema for our 'account_number'. 122 | 'type' => 'string', 123 | ), 124 | 'account_key' => array( // Schema for our 'account_key'. 125 | 'type' => 'string', 126 | ), 127 | ), 128 | ), 129 | ), 130 | ) 131 | ); 132 | } 133 | 134 | 135 | /** 136 | * Sanitize our settings. 137 | * 138 | * @param array $settings The settings to sanitize. 139 | * @return array 140 | */ 141 | public static function sanitize_callback( $settings ) { 142 | // Sanitize our 'account_number'. 143 | $settings['account_number'] = sanitize_text_field( $settings['account_number'] ); 144 | // Sanitize our 'account_key'. 145 | $settings['account_key'] = sanitize_text_field( $settings['account_key'] ); 146 | return $settings; 147 | } 148 | } 149 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "example-wp-settings", 3 | "version": "0.1.0", 4 | "description": "Example WordPress settings page.", 5 | "author": "The WordPress Contributors", 6 | "license": "GPL-2.0-or-later", 7 | "main": "build/index.js", 8 | "scripts": { 9 | "build": "wp-scripts build", 10 | "format": "wp-scripts format", 11 | "lint:css": "wp-scripts lint-style", 12 | "lint:js": "wp-scripts lint-js", 13 | "packages-update": "wp-scripts packages-update", 14 | "plugin-zip": "wp-scripts plugin-zip", 15 | "start": "wp-scripts start", 16 | "env": "wp-env" 17 | }, 18 | "devDependencies": { 19 | "@wordpress/scripts": "^26.17.0" 20 | }, 21 | "dependencies": { 22 | "@wordpress/env": "^8.12.0" 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | # Example WP Settings Page 2 | 3 | This is an example of a WordPress settings page. It uses the WordPress [Settings API](https://codex.wordpress.org/Settings_API), [REST API](https://developer.wordpress.org/rest-api/), and [Gutenberg Component Library](https://developer.wordpress.org/block-editor/components/) to create a JavaScript-powered settings page with a tabbed interface. 4 | 5 | Xnapper-2024-05-25-07 26 22 6 | 7 | 8 | ## Development 9 | 10 | This plugin was scaffolded with [@wordpress/create-block](https://developer.wordpress.org/block-editor/reference-guides/packages/packages-create-block/). If you'd like to develop from this repository, first install all of the dependencies: 11 | 12 | `npm install` 13 | 14 | Then run the build process in a watch mode: 15 | 16 | `npm start` 17 | 18 | ## Running Locally 19 | 20 | To use the included local environment, make sure Docker is running and then run the following command: 21 | 22 | `npm run env start` 23 | 24 | and visit [http://localhost:8888/wp-admin](http://localhost:8888/wp-admin). 25 | 26 | You should be able to log in with Username: `admin` and Password: `password`. 27 | 28 | [Learn more about wp-env](https://developer.wordpress.org/block-editor/reference-guides/packages/packages-env/). 29 | -------------------------------------------------------------------------------- /readme.txt: -------------------------------------------------------------------------------- 1 | === Example WP Settings === 2 | Contributors: bacoords 3 | Tags: block 4 | Tested up to: 6.1 5 | Stable tag: 0.1.0 6 | License: GPL-2.0-or-later 7 | License URI: https://www.gnu.org/licenses/gpl-2.0.html 8 | 9 | Example settings page scaffolded with Create Block tool. 10 | -------------------------------------------------------------------------------- /src/components/Panel.js: -------------------------------------------------------------------------------- 1 | import { __ } from '@wordpress/i18n'; 2 | import { Flex, FlexItem, TextControl } from '@wordpress/components'; 3 | 4 | import { useDispatch, useSelect } from '@wordpress/data'; 5 | import { store as coreStore } from '@wordpress/core-data'; 6 | 7 | function Panel() { 8 | // Get the settings from the store. 9 | const { record: settings, hasResolved } = useSelect( ( select ) => { 10 | return { 11 | record: select( coreStore ).getEditedEntityRecord( 'root', 'site' ), 12 | hasResolved: select( coreStore ).hasFinishedResolution( 13 | 'getEditedEntityRecord', 14 | [ 'root', 'site' ] 15 | ), 16 | }; 17 | } ); 18 | 19 | // We'll use these functions to save the settings to the store. 20 | const { editEntityRecord } = useDispatch( coreStore ); 21 | 22 | if ( ! hasResolved ) { 23 | return null; 24 | } 25 | 26 | // This will save settings the settings to the local state only. 27 | const updateOptions = ( key, value ) => { 28 | editEntityRecord( 'root', 'site', undefined, { 29 | wpdev_account_settings: { 30 | ...settings.wpdev_account_settings, 31 | [ key ]: value, 32 | }, 33 | } ); 34 | }; 35 | 36 | return ( 37 | 42 | 43 | { 48 | updateOptions( 'account_number', value ); 49 | } } 50 | /> 51 | 52 | 53 | { 58 | updateOptions( 'account_key', value ); 59 | } } 60 | /> 61 | 62 | 63 | ); 64 | } 65 | 66 | export default Panel; 67 | -------------------------------------------------------------------------------- /src/components/SettingsPage.js: -------------------------------------------------------------------------------- 1 | import { __ } from '@wordpress/i18n'; 2 | import { useState, useEffect } from '@wordpress/element'; 3 | import { 4 | Card, 5 | CardBody, 6 | CardDivider, 7 | Flex, 8 | FlexItem, 9 | Button, 10 | Snackbar, 11 | TabPanel, 12 | } from '@wordpress/components'; 13 | 14 | import { useDispatch, useSelect } from '@wordpress/data'; 15 | import { store as coreStore } from '@wordpress/core-data'; 16 | 17 | import Panel from './Panel'; 18 | 19 | function SettingsPage() { 20 | // Get the settings from the store. 21 | const { record: settings, hasResolved } = useSelect( ( select ) => { 22 | return { 23 | record: select( coreStore ).getEditedEntityRecord( 'root', 'site' ), 24 | hasResolved: select( coreStore ).hasFinishedResolution( 25 | 'getEditedEntityRecord', 26 | [ 'root', 'site' ] 27 | ), 28 | }; 29 | } ); 30 | 31 | // We'll use these functions to save the settings to the store. 32 | const { saveEntityRecord } = useDispatch( coreStore ); 33 | 34 | // State to show a success message when the settings are saved. 35 | const [ success, setSuccess ] = useState( false ); 36 | 37 | // State to keep track of which tab is active. 38 | const [ activeTab, setActiveTab ] = useState( 'panel' ); 39 | 40 | // If the settings haven't been loaded yet, we'll return null. 41 | // This needs to happen after all the hooks are called. 42 | if ( ! hasResolved ) { 43 | return null; 44 | } 45 | // In the block editor, saving to the database happens automatically when you publish or update a post. 46 | // In the our settings page, you would need to add a separate button to save the settings. 47 | const saveOptions = ( event ) => { 48 | event.preventDefault(); 49 | saveEntityRecord( 'root', 'site', { 50 | wpdev_account_settings: settings.wpdev_account_settings, 51 | } ).then( ( response ) => { 52 | setSuccess( true ); 53 | console.log( response ); 54 | } ); 55 | }; 56 | 57 | return ( 58 |
59 | 60 | 61 |

{ __( 'Example WP Settings Settings' ) }

62 | { 65 | setActiveTab( tabName ); 66 | } } 67 | initialTabName={ activeTab } 68 | tabs={ [ 69 | { 70 | name: 'panel', 71 | title: 'Example Panel', 72 | content: , 73 | }, 74 | ] } 75 | > 76 | { ( tab ) => <>{ tab.content } } 77 | 78 |
79 | 80 | 81 | 82 | 83 | 86 | 87 | 88 | { success && ( 89 | 96 | Saved 97 | 98 | ) } 99 | 100 | 101 | 102 |
103 |
104 | ); 105 | } 106 | 107 | export default SettingsPage; 108 | -------------------------------------------------------------------------------- /src/index.js: -------------------------------------------------------------------------------- 1 | import { createRoot } from '@wordpress/element'; 2 | import SettingsPage from './components/SettingsPage'; 3 | 4 | import './style.scss'; 5 | 6 | let root = createRoot( document.getElementById( 'root' ) ); 7 | root.render( ); 8 | -------------------------------------------------------------------------------- /src/style.scss: -------------------------------------------------------------------------------- 1 | .example-wp-settings { 2 | max-width: 780px; 3 | h1 { 4 | text-align: center; 5 | } 6 | .example-wp-settings-tab-panel { 7 | .components-tab-panel__tabs { 8 | justify-content: center; 9 | border-bottom: 1px solid #ddd; 10 | } 11 | } 12 | 13 | .example-wp-settings-field-group { 14 | margin-top: 2rem; 15 | } 16 | } 17 | --------------------------------------------------------------------------------