├── .circleci └── config.yml ├── .editorconfig ├── .eslintignore ├── .eslintrc.json ├── .gitignore ├── .stylelintignore ├── .svnignore ├── .zipignore ├── LICENSE ├── README.txt ├── atomicblocks.php ├── bin └── phpcs-changed.sh ├── composer.json ├── config ├── paths.js ├── webpack.config.dev.js └── webpack.config.prod.js ├── dist ├── assets │ ├── fontawesome │ │ ├── css │ │ │ ├── all.css │ │ │ ├── all.min.css │ │ │ ├── brands.css │ │ │ ├── brands.min.css │ │ │ ├── regular.css │ │ │ ├── regular.min.css │ │ │ ├── solid.css │ │ │ ├── solid.min.css │ │ │ ├── svg-with-js.css │ │ │ ├── svg-with-js.min.css │ │ │ ├── v4-shims.css │ │ │ └── v4-shims.min.css │ │ └── webfonts │ │ │ ├── fa-brands-400.eot │ │ │ ├── fa-brands-400.svg │ │ │ ├── fa-brands-400.ttf │ │ │ ├── fa-brands-400.woff │ │ │ ├── fa-brands-400.woff2 │ │ │ ├── fa-regular-400.eot │ │ │ ├── fa-regular-400.svg │ │ │ ├── fa-regular-400.ttf │ │ │ ├── fa-regular-400.woff │ │ │ ├── fa-regular-400.woff2 │ │ │ ├── fa-solid-900.eot │ │ │ ├── fa-solid-900.svg │ │ │ ├── fa-solid-900.ttf │ │ │ ├── fa-solid-900.woff │ │ │ └── fa-solid-900.woff2 │ ├── genesis-font │ │ ├── genesis-icon.eot │ │ ├── genesis-icon.svg │ │ ├── genesis-icon.ttf │ │ └── genesis-icon.woff │ └── js │ │ ├── dismiss.js │ │ └── newsletter-block-functions.js ├── getting-started │ ├── getting-started.css │ ├── getting-started.js │ ├── getting-started.php │ ├── images │ │ ├── build-content.svg │ │ ├── cc115.svg │ │ ├── cc184.svg │ │ ├── cc26.svg │ │ ├── cc38.svg │ │ ├── cc4.svg │ │ ├── cc402.svg │ │ ├── cc41.svg │ │ ├── cc430.svg │ │ ├── cc45.svg │ │ ├── cc50.svg │ │ ├── cc94-f.svg │ │ ├── genesis-logo.svg │ │ ├── genesis-menu.png │ │ ├── genesis-pro-logo.svg │ │ ├── genesis-sample.jpg │ │ ├── geo.png │ │ ├── logo.png │ │ ├── monochrome.jpg │ │ └── revolution.jpg │ ├── pages │ │ ├── ab-getting-started.php │ │ ├── gpb-getting-started.php │ │ ├── settings-general.php │ │ └── settings-main.php │ ├── settings.js │ └── theme.jpg ├── init.php └── migration │ ├── admin.migration-notice.css │ ├── admin.migration-notice.js │ ├── class-install-genesis-blocks-api.php │ ├── class-notice.php │ ├── class-redirect.php │ └── migrate-page │ ├── ab-migrate.css │ ├── ab-migrate.js │ ├── ab-migrate.php │ ├── genesis_blocks_hero_Image.png │ └── migrate-page.php ├── includes ├── classes │ ├── class-atomicblocks-svg-icons.php │ └── class-mailchimp.php ├── compat.php ├── exceptions │ ├── class-api-error-exception.php │ └── class-mailchimp-api-error-exception.php ├── helpers │ └── svg-icons.php ├── interfaces │ └── newsletter-provider-interface.php ├── layout │ ├── class-component-registry.php │ ├── layout-endpoints.php │ ├── layout-functions.php │ └── register-layout-components.php ├── libraries │ └── drewm │ │ └── mailchimp-api │ │ └── MailChimp.php └── newsletter │ └── newsletter-functions.php ├── languages └── atomic-blocks.pot ├── loader.php ├── package-lock.json ├── package.json ├── phpcs.xml.dist ├── phpunit.xml.dist ├── scripts ├── build.js ├── start.js └── translate.js ├── src ├── blocks.js ├── blocks │ ├── block-accordion │ │ ├── components │ │ │ ├── accordion.js │ │ │ ├── edit.js │ │ │ ├── inspector.js │ │ │ └── save.js │ │ ├── deprecated │ │ │ ├── 2.0 │ │ │ │ └── components │ │ │ │ │ ├── accordion.js │ │ │ │ │ └── save.js │ │ │ └── deprecated.js │ │ ├── index.js │ │ └── styles │ │ │ ├── editor.scss │ │ │ └── style.scss │ ├── block-author-profile │ │ ├── components │ │ │ ├── avatar.js │ │ │ ├── edit.js │ │ │ ├── inspector.js │ │ │ ├── profile.js │ │ │ ├── save.js │ │ │ └── social.js │ │ ├── deprecated │ │ │ ├── 1.8.1 │ │ │ │ └── components │ │ │ │ │ └── save.js │ │ │ └── deprecated.js │ │ ├── index.js │ │ └── styles │ │ │ ├── editor.scss │ │ │ └── style.scss │ ├── block-button │ │ ├── components │ │ │ ├── button.js │ │ │ ├── icons.js │ │ │ └── inspector.js │ │ ├── index.js │ │ └── styles │ │ │ ├── editor.scss │ │ │ └── style.scss │ ├── block-column-inner │ │ ├── components │ │ │ ├── column.js │ │ │ ├── edit.js │ │ │ ├── inspector.js │ │ │ └── save.js │ │ ├── deprecated │ │ │ ├── 1.7.1 │ │ │ │ └── components │ │ │ │ │ ├── column.js │ │ │ │ │ └── save.js │ │ │ └── deprecated.js │ │ ├── index.js │ │ └── styles │ │ │ ├── editor.scss │ │ │ └── style.scss │ ├── block-column │ │ ├── components │ │ │ ├── column-layouts.js │ │ │ ├── column-wrap.js │ │ │ ├── edit.js │ │ │ ├── icons.js │ │ │ ├── inspector.js │ │ │ └── save.js │ │ └── index.js │ ├── block-container │ │ ├── components │ │ │ ├── container.js │ │ │ └── inspector.js │ │ ├── deprecated │ │ │ ├── 1.4.23 │ │ │ │ └── components │ │ │ │ │ └── container.js │ │ │ ├── 2.3.0 │ │ │ │ └── components │ │ │ │ │ └── container.js │ │ │ └── deprecated.js │ │ ├── index.js │ │ ├── index.php │ │ └── styles │ │ │ ├── editor.scss │ │ │ └── style.scss │ ├── block-cta │ │ ├── components │ │ │ ├── cta.js │ │ │ └── inspector.js │ │ ├── deprecated │ │ │ ├── 1.4.21 │ │ │ │ └── components │ │ │ │ │ └── cta.js │ │ │ ├── 1.4.22 │ │ │ │ └── components │ │ │ │ │ └── cta.js │ │ │ ├── 1.5.2 │ │ │ │ └── components │ │ │ │ │ └── cta.js │ │ │ └── deprecated.js │ │ ├── index.js │ │ └── styles │ │ │ ├── editor.scss │ │ │ └── style.scss │ ├── block-drop-cap │ │ ├── components │ │ │ ├── dropcap.js │ │ │ ├── icons.js │ │ │ └── inspector.js │ │ ├── index.js │ │ └── styles │ │ │ ├── editor.scss │ │ │ └── style.scss │ ├── block-layout │ │ ├── components │ │ │ ├── edit.js │ │ │ ├── layout │ │ │ │ ├── layout-library-item-card.js │ │ │ │ ├── layout-library-item-list.js │ │ │ │ ├── layout-library-item.js │ │ │ │ ├── layout-library.js │ │ │ │ └── layout-modal.js │ │ │ └── layouts-provider.js │ │ ├── index.js │ │ └── styles │ │ │ ├── editor.scss │ │ │ └── style.scss │ ├── block-newsletter │ │ ├── components │ │ │ ├── edit.js │ │ │ ├── inspector.js │ │ │ └── newsletter.js │ │ ├── index.js │ │ ├── index.php │ │ └── styles │ │ │ ├── editor.scss │ │ │ └── style.scss │ ├── block-notice │ │ ├── components │ │ │ ├── button.js │ │ │ ├── icons.js │ │ │ ├── inspector.js │ │ │ └── notice.js │ │ ├── index.js │ │ └── styles │ │ │ ├── editor.scss │ │ │ └── style.scss │ ├── block-post-grid │ │ ├── components │ │ │ ├── edit.js │ │ │ ├── image.js │ │ │ └── inspector.js │ │ ├── index.js │ │ ├── index.php │ │ └── styles │ │ │ ├── editor.scss │ │ │ └── style.scss │ ├── block-pricing-table-inner │ │ ├── components │ │ │ ├── button │ │ │ │ ├── edit.js │ │ │ │ ├── index.js │ │ │ │ └── inspector.js │ │ │ ├── description │ │ │ │ ├── edit.js │ │ │ │ ├── index.js │ │ │ │ └── inspector.js │ │ │ ├── global │ │ │ │ └── inspector.js │ │ │ ├── inspector.js │ │ │ ├── price │ │ │ │ ├── deprecated │ │ │ │ │ └── deprecated.js │ │ │ │ ├── edit.js │ │ │ │ ├── index.js │ │ │ │ └── inspector.js │ │ │ ├── subtitle │ │ │ │ ├── edit.js │ │ │ │ └── index.js │ │ │ └── title │ │ │ │ ├── edit.js │ │ │ │ └── index.js │ │ ├── index.js │ │ └── styles │ │ │ ├── editor.scss │ │ │ └── style.scss │ ├── block-pricing-table │ │ ├── components │ │ │ ├── inspector.js │ │ │ └── pricing.js │ │ └── index.js │ ├── block-sharing │ │ ├── components │ │ │ ├── edit.js │ │ │ ├── inspector.js │ │ │ └── sharing.js │ │ ├── index.js │ │ ├── index.php │ │ └── styles │ │ │ ├── editor.scss │ │ │ └── style.scss │ ├── block-spacer │ │ ├── components │ │ │ ├── icons.js │ │ │ ├── inspector.js │ │ │ └── spacer.js │ │ ├── index.js │ │ └── styles │ │ │ ├── editor.scss │ │ │ └── style.scss │ ├── block-testimonial │ │ ├── components │ │ │ ├── edit.js │ │ │ ├── inspector.js │ │ │ ├── save.js │ │ │ └── testimonial.js │ │ ├── index.js │ │ └── styles │ │ │ ├── editor.scss │ │ │ └── style.scss │ └── global-styles │ │ ├── index.js │ │ └── styles │ │ ├── editor.scss │ │ ├── style.scss │ │ ├── type.scss │ │ └── utility.scss ├── common.scss └── utils │ ├── components │ ├── background-image │ │ ├── attributes.js │ │ ├── classes.js │ │ ├── inspector.js │ │ ├── shared.js │ │ └── styles.js │ ├── data-providers │ │ └── currentUserData.js │ ├── icons │ │ └── index.js │ ├── margin.js │ ├── padding.js │ └── settings │ │ └── renderSettingControl.js │ ├── helper.js │ └── inspector │ ├── button.js │ ├── margin.js │ └── padding.js ├── tests ├── bootstrap.php ├── e2e │ ├── .babelrc │ ├── config │ │ └── setup-test-framework.js │ ├── jest.config.js │ └── specs │ │ └── add-blocks.js └── integration │ ├── layout-endpoints │ └── test-layout-endpoints.php │ ├── migration │ └── test-redirect.php │ └── newsletter │ └── test-newsletter-functions.php └── webpack.config.js /.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] 17 | indent_style = space 18 | indent_size = 2 19 | 20 | [*.md] 21 | trim_trailing_whitespace = false -------------------------------------------------------------------------------- /.eslintignore: -------------------------------------------------------------------------------- 1 | **/*.min.js 2 | **/*.build.js 3 | config/ 4 | node_modules/ 5 | scripts/ 6 | vendor/ 7 | -------------------------------------------------------------------------------- /.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": [ 3 | "plugin:@wordpress/eslint-plugin/recommended" 4 | ], 5 | "rules": { 6 | "prettier/prettier": "off", 7 | "no-useless-constructor": "off", 8 | "camelcase": "off", 9 | "@wordpress/no-unused-vars-before-return": "off", 10 | "no-unused-vars": "off", 11 | "no-undef": "off", 12 | "no-shadow": "off", 13 | "jsx-a11y/anchor-is-valid": "off", 14 | "no-console": "off", 15 | "jsx-a11y/click-events-have-key-events": "off", 16 | "jsx-a11y/interactive-supports-focus": "off", 17 | "no-unused-expressions": "off", 18 | "no-var": "off", 19 | "no-duplicate-imports": "off" 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Numerous always-ignore extensions 2 | *.diff 3 | *.err 4 | *.orig 5 | *.log 6 | *.rej 7 | *.swo 8 | *.swp 9 | *.vi 10 | *~ 11 | *.sass-cache 12 | 13 | # OS or Editor folders 14 | .DS_Store 15 | ._* 16 | .Spotlight-V100 17 | .Trashes 18 | Thumbs.db 19 | .cache 20 | .project 21 | .settings 22 | .tmproj 23 | *.esproj 24 | nbproject 25 | *.sublime-project 26 | *.sublime-workspace 27 | config.codekit 28 | 29 | # Komodo 30 | *.komodoproject 31 | .komodotools 32 | 33 | # Folders to ignore 34 | .hg 35 | .svn 36 | .CVS 37 | .idea 38 | node_modules/ 39 | vendor/ 40 | 41 | # Build files 42 | composer.lock 43 | Gruntfile.js 44 | dist/blocks.build.js 45 | dist/blocks.editor.build.css 46 | dist/blocks.style.build.css -------------------------------------------------------------------------------- /.stylelintignore: -------------------------------------------------------------------------------- 1 | **/*.build.css 2 | node_modules/ 3 | vendor/ 4 | -------------------------------------------------------------------------------- /.svnignore: -------------------------------------------------------------------------------- 1 | .circleci 2 | .DS_Store 3 | .editorconfig 4 | .eslintignore 5 | .eslintrc.json 6 | .git 7 | .gitignore 8 | .gitattributes 9 | .idea 10 | .stylelintignore 11 | .svnignore 12 | .zipignore 13 | bin 14 | config 15 | node_modules 16 | scripts 17 | specs 18 | vendor 19 | tests 20 | composer.lock 21 | package.json 22 | package-lock.json 23 | phpcs.xml.dist 24 | phpunit.xml.dist 25 | webpack.config.js 26 | -------------------------------------------------------------------------------- /.zipignore: -------------------------------------------------------------------------------- 1 | *.git* 2 | *.DS_Store* 3 | *.babelrc* 4 | *.eslintignore* 5 | *.eslintrc.json* 6 | *.circleci* 7 | *.sass-cache* 8 | *.editorconfig* 9 | *eslint* 10 | *stylelint* 11 | deploy.sh 12 | *Gruntfile.js* 13 | *package.json* 14 | *phpcs* 15 | *phpunit* 16 | *bin* 17 | *config* 18 | *grunt* 19 | *node_modules* 20 | *scripts* 21 | *specs* 22 | *tests* 23 | *vendor* 24 | *composer.json* 25 | *composer.lock* 26 | *package-lock.json* 27 | webpack.config.js 28 | -------------------------------------------------------------------------------- /atomicblocks.php: -------------------------------------------------------------------------------- 1 | path.resolve( pluginDir, relativePath ); 13 | 14 | // Config after eject: we're in ./config/ 15 | module.exports = { 16 | dotenv: resolvePlugin( '.env' ), 17 | pluginSrc: resolvePlugin( 'src' ), // Plugin src folder path. 18 | pluginBlocksJs: resolvePlugin( 'src/blocks.js' ), 19 | yarnLockFile: resolvePlugin( 'yarn.lock' ), 20 | pluginDist: resolvePlugin( '.' ) // We are in ./dist folder already so the path '.' resolves to ./dist/. 21 | }; 22 | -------------------------------------------------------------------------------- /dist/assets/fontawesome/css/brands.css: -------------------------------------------------------------------------------- 1 | /*! 2 | * Font Awesome Free 5.2.0 by @fontawesome - https://fontawesome.com 3 | * License - https://fontawesome.com/license (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) 4 | */ 5 | @font-face { 6 | font-family: 'Font Awesome 5 Brands'; 7 | font-style: normal; 8 | font-weight: normal; 9 | src: url("../webfonts/fa-brands-400.eot"); 10 | src: url("../webfonts/fa-brands-400.eot?#iefix") format("embedded-opentype"), url("../webfonts/fa-brands-400.woff2") format("woff2"), url("../webfonts/fa-brands-400.woff") format("woff"), url("../webfonts/fa-brands-400.ttf") format("truetype"), url("../webfonts/fa-brands-400.svg#fontawesome") format("svg"); } 11 | 12 | .fab { 13 | font-family: 'Font Awesome 5 Brands'; } 14 | -------------------------------------------------------------------------------- /dist/assets/fontawesome/css/brands.min.css: -------------------------------------------------------------------------------- 1 | /*! 2 | * Font Awesome Free 5.2.0 by @fontawesome - https://fontawesome.com 3 | * License - https://fontawesome.com/license (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) 4 | */ 5 | @font-face{font-family:"Font Awesome 5 Brands";font-style:normal;font-weight:normal;src:url(../webfonts/fa-brands-400.eot);src:url(../webfonts/fa-brands-400.eot?#iefix) format("embedded-opentype"),url(../webfonts/fa-brands-400.woff2) format("woff2"),url(../webfonts/fa-brands-400.woff) format("woff"),url(../webfonts/fa-brands-400.ttf) format("truetype"),url(../webfonts/fa-brands-400.svg#fontawesome) format("svg")}.fab{font-family:"Font Awesome 5 Brands"} -------------------------------------------------------------------------------- /dist/assets/fontawesome/css/regular.css: -------------------------------------------------------------------------------- 1 | /*! 2 | * Font Awesome Free 5.2.0 by @fontawesome - https://fontawesome.com 3 | * License - https://fontawesome.com/license (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) 4 | */ 5 | @font-face { 6 | font-family: 'Font Awesome 5 Free'; 7 | font-style: normal; 8 | font-weight: 400; 9 | src: url("../webfonts/fa-regular-400.eot"); 10 | src: url("../webfonts/fa-regular-400.eot?#iefix") format("embedded-opentype"), url("../webfonts/fa-regular-400.woff2") format("woff2"), url("../webfonts/fa-regular-400.woff") format("woff"), url("../webfonts/fa-regular-400.ttf") format("truetype"), url("../webfonts/fa-regular-400.svg#fontawesome") format("svg"); } 11 | 12 | .far { 13 | font-family: 'Font Awesome 5 Free'; 14 | font-weight: 400; } 15 | -------------------------------------------------------------------------------- /dist/assets/fontawesome/css/regular.min.css: -------------------------------------------------------------------------------- 1 | /*! 2 | * Font Awesome Free 5.2.0 by @fontawesome - https://fontawesome.com 3 | * License - https://fontawesome.com/license (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) 4 | */ 5 | @font-face{font-family:"Font Awesome 5 Free";font-style:normal;font-weight:400;src:url(../webfonts/fa-regular-400.eot);src:url(../webfonts/fa-regular-400.eot?#iefix) format("embedded-opentype"),url(../webfonts/fa-regular-400.woff2) format("woff2"),url(../webfonts/fa-regular-400.woff) format("woff"),url(../webfonts/fa-regular-400.ttf) format("truetype"),url(../webfonts/fa-regular-400.svg#fontawesome) format("svg")}.far{font-family:"Font Awesome 5 Free";font-weight:400} -------------------------------------------------------------------------------- /dist/assets/fontawesome/css/solid.css: -------------------------------------------------------------------------------- 1 | /*! 2 | * Font Awesome Free 5.2.0 by @fontawesome - https://fontawesome.com 3 | * License - https://fontawesome.com/license (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) 4 | */ 5 | @font-face { 6 | font-family: 'Font Awesome 5 Free'; 7 | font-style: normal; 8 | font-weight: 900; 9 | src: url("../webfonts/fa-solid-900.eot"); 10 | src: url("../webfonts/fa-solid-900.eot?#iefix") format("embedded-opentype"), url("../webfonts/fa-solid-900.woff2") format("woff2"), url("../webfonts/fa-solid-900.woff") format("woff"), url("../webfonts/fa-solid-900.ttf") format("truetype"), url("../webfonts/fa-solid-900.svg#fontawesome") format("svg"); } 11 | 12 | .fa, 13 | .fas { 14 | font-family: 'Font Awesome 5 Free'; 15 | font-weight: 900; } 16 | -------------------------------------------------------------------------------- /dist/assets/fontawesome/css/solid.min.css: -------------------------------------------------------------------------------- 1 | /*! 2 | * Font Awesome Free 5.2.0 by @fontawesome - https://fontawesome.com 3 | * License - https://fontawesome.com/license (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) 4 | */ 5 | @font-face{font-family:"Font Awesome 5 Free";font-style:normal;font-weight:900;src:url(../webfonts/fa-solid-900.eot);src:url(../webfonts/fa-solid-900.eot?#iefix) format("embedded-opentype"),url(../webfonts/fa-solid-900.woff2) format("woff2"),url(../webfonts/fa-solid-900.woff) format("woff"),url(../webfonts/fa-solid-900.ttf) format("truetype"),url(../webfonts/fa-solid-900.svg#fontawesome) format("svg")}.fa,.fas{font-family:"Font Awesome 5 Free";font-weight:900} -------------------------------------------------------------------------------- /dist/assets/fontawesome/webfonts/fa-brands-400.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/studiopress/atomic-blocks/70793261e92f98afca792faf1981bb2a02d59f84/dist/assets/fontawesome/webfonts/fa-brands-400.eot -------------------------------------------------------------------------------- /dist/assets/fontawesome/webfonts/fa-brands-400.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/studiopress/atomic-blocks/70793261e92f98afca792faf1981bb2a02d59f84/dist/assets/fontawesome/webfonts/fa-brands-400.ttf -------------------------------------------------------------------------------- /dist/assets/fontawesome/webfonts/fa-brands-400.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/studiopress/atomic-blocks/70793261e92f98afca792faf1981bb2a02d59f84/dist/assets/fontawesome/webfonts/fa-brands-400.woff -------------------------------------------------------------------------------- /dist/assets/fontawesome/webfonts/fa-brands-400.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/studiopress/atomic-blocks/70793261e92f98afca792faf1981bb2a02d59f84/dist/assets/fontawesome/webfonts/fa-brands-400.woff2 -------------------------------------------------------------------------------- /dist/assets/fontawesome/webfonts/fa-regular-400.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/studiopress/atomic-blocks/70793261e92f98afca792faf1981bb2a02d59f84/dist/assets/fontawesome/webfonts/fa-regular-400.eot -------------------------------------------------------------------------------- /dist/assets/fontawesome/webfonts/fa-regular-400.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/studiopress/atomic-blocks/70793261e92f98afca792faf1981bb2a02d59f84/dist/assets/fontawesome/webfonts/fa-regular-400.ttf -------------------------------------------------------------------------------- /dist/assets/fontawesome/webfonts/fa-regular-400.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/studiopress/atomic-blocks/70793261e92f98afca792faf1981bb2a02d59f84/dist/assets/fontawesome/webfonts/fa-regular-400.woff -------------------------------------------------------------------------------- /dist/assets/fontawesome/webfonts/fa-regular-400.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/studiopress/atomic-blocks/70793261e92f98afca792faf1981bb2a02d59f84/dist/assets/fontawesome/webfonts/fa-regular-400.woff2 -------------------------------------------------------------------------------- /dist/assets/fontawesome/webfonts/fa-solid-900.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/studiopress/atomic-blocks/70793261e92f98afca792faf1981bb2a02d59f84/dist/assets/fontawesome/webfonts/fa-solid-900.eot -------------------------------------------------------------------------------- /dist/assets/fontawesome/webfonts/fa-solid-900.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/studiopress/atomic-blocks/70793261e92f98afca792faf1981bb2a02d59f84/dist/assets/fontawesome/webfonts/fa-solid-900.ttf -------------------------------------------------------------------------------- /dist/assets/fontawesome/webfonts/fa-solid-900.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/studiopress/atomic-blocks/70793261e92f98afca792faf1981bb2a02d59f84/dist/assets/fontawesome/webfonts/fa-solid-900.woff -------------------------------------------------------------------------------- /dist/assets/fontawesome/webfonts/fa-solid-900.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/studiopress/atomic-blocks/70793261e92f98afca792faf1981bb2a02d59f84/dist/assets/fontawesome/webfonts/fa-solid-900.woff2 -------------------------------------------------------------------------------- /dist/assets/genesis-font/genesis-icon.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/studiopress/atomic-blocks/70793261e92f98afca792faf1981bb2a02d59f84/dist/assets/genesis-font/genesis-icon.eot -------------------------------------------------------------------------------- /dist/assets/genesis-font/genesis-icon.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /dist/assets/genesis-font/genesis-icon.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/studiopress/atomic-blocks/70793261e92f98afca792faf1981bb2a02d59f84/dist/assets/genesis-font/genesis-icon.ttf -------------------------------------------------------------------------------- /dist/assets/genesis-font/genesis-icon.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/studiopress/atomic-blocks/70793261e92f98afca792faf1981bb2a02d59f84/dist/assets/genesis-font/genesis-icon.woff -------------------------------------------------------------------------------- /dist/assets/js/dismiss.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Handles dismissible notices from the Notice block. 3 | */ 4 | 5 | /** 6 | * IE 11 polyfill for Nodelist.forEach. 7 | * 8 | * @see https://developer.mozilla.org/en-US/docs/Web/API/NodeList/forEach 9 | */ 10 | if ( window.NodeList && ! NodeList.prototype.forEach ) { 11 | NodeList.prototype.forEach = Array.prototype.forEach; 12 | } 13 | 14 | document.addEventListener( 'DOMContentLoaded', function() { 15 | var notices = document.querySelectorAll( 16 | '.ab-block-notice.ab-dismissable[data-id]' 17 | ); 18 | 19 | notices.forEach( function( element ) { 20 | var uid = element.getAttribute( 'data-id' ); 21 | 22 | var dismissible = element.querySelector( '.ab-notice-dismiss' ); 23 | 24 | if ( ! localStorage.getItem( 'notice-' + uid ) ) { 25 | element.style.display = 'block'; 26 | } 27 | 28 | if ( dismissible ) { 29 | dismissible.addEventListener( 'click', function( event ) { 30 | event.preventDefault(); 31 | localStorage.setItem( 'notice-' + uid, '1' ); 32 | element.style.display = ''; 33 | } ); 34 | } 35 | } ); 36 | } ); 37 | -------------------------------------------------------------------------------- /dist/getting-started/getting-started.js: -------------------------------------------------------------------------------- 1 | jQuery( document ).ready( function( $ ) { 2 | // Tabs 3 | $( '.inline-list' ).each( function() { 4 | $( this ) 5 | .find( 'li' ) 6 | .each( function( i ) { 7 | $( this ).click( function() { 8 | $( this ) 9 | .addClass( 'current' ) 10 | .siblings() 11 | .removeClass( 'current' ) 12 | .parents( '#wpbody' ) 13 | .find( 'div.panel-left' ) 14 | .removeClass( 'visible' ) 15 | .end() 16 | .find( 'div.panel-left:eq(' + i + ')' ) 17 | .addClass( 'visible' ); 18 | return false; 19 | } ); 20 | } ); 21 | } ); 22 | 23 | // Scroll to anchor 24 | $( '.anchor-nav a, .toc a' ).click( function( e ) { 25 | var href = $( this ).attr( 'href' ); 26 | e.preventDefault(); 27 | 28 | $( 'html, body' ).animate( 29 | { 30 | scrollTop: $( href ).offset().top, 31 | }, 32 | 'slow', 33 | 'swing' 34 | ); 35 | } ); 36 | 37 | // Back to top links 38 | $( '#help-panel h3' ).append( 39 | $( 40 | " Back to top" 41 | ) 42 | ); 43 | // Pro opt-in analytics handler 44 | $( '.ab-gs-feedback input[name="atomic-blocks-settings[analytics-opt-in]"]' ).on( 'click', function( event ) { 45 | $.ajax({ 46 | data: { 47 | action: 'atomic_blocks_pro_gs_analytics_toggle', 48 | 'ab-pro-analytics-toggle-value': event.target.value, 49 | 'atomic_blocks_pro_gs_analytics_toggle_nonce': $( '#atomic_blocks_pro_gs_analytics_toggle_nonce' ).val() 50 | }, 51 | type: 'post', 52 | url: ajaxurl 53 | }); 54 | }); 55 | }); 56 | -------------------------------------------------------------------------------- /dist/getting-started/images/cc430.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /dist/getting-started/images/genesis-menu.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/studiopress/atomic-blocks/70793261e92f98afca792faf1981bb2a02d59f84/dist/getting-started/images/genesis-menu.png -------------------------------------------------------------------------------- /dist/getting-started/images/genesis-sample.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/studiopress/atomic-blocks/70793261e92f98afca792faf1981bb2a02d59f84/dist/getting-started/images/genesis-sample.jpg -------------------------------------------------------------------------------- /dist/getting-started/images/geo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/studiopress/atomic-blocks/70793261e92f98afca792faf1981bb2a02d59f84/dist/getting-started/images/geo.png -------------------------------------------------------------------------------- /dist/getting-started/images/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/studiopress/atomic-blocks/70793261e92f98afca792faf1981bb2a02d59f84/dist/getting-started/images/logo.png -------------------------------------------------------------------------------- /dist/getting-started/images/monochrome.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/studiopress/atomic-blocks/70793261e92f98afca792faf1981bb2a02d59f84/dist/getting-started/images/monochrome.jpg -------------------------------------------------------------------------------- /dist/getting-started/images/revolution.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/studiopress/atomic-blocks/70793261e92f98afca792faf1981bb2a02d59f84/dist/getting-started/images/revolution.jpg -------------------------------------------------------------------------------- /dist/getting-started/pages/settings-general.php: -------------------------------------------------------------------------------- 1 | 10 |
11 | 12 | 13 | 14 | 19 | 30 | 31 | 32 |
15 | 18 | 20 | 21 | %2$s

', 24 | 'https://mailchimp.com/help/about-api-keys/', 25 | esc_html__( 'Find your Mailchimp API key.', 'atomic-blocks' ) 26 | ); 27 | echo wp_kses_post( $atomic_blocks_mailchimp_api_key_link ); 28 | ?> 29 |
33 |
34 | -------------------------------------------------------------------------------- /dist/getting-started/settings.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | window.addEventListener( 'DOMContentLoaded', function() { 3 | var AtomicBlocksSettings = { 4 | init() { 5 | this.addListeners(); 6 | this.setUpDefaultStates(); 7 | }, 8 | 9 | // Sets up default state for settings tabs and settings visibility. 10 | setUpDefaultStates() { 11 | var tab = 'general'; 12 | 13 | var saved_tab = this.getActiveTabState(); 14 | 15 | if ( saved_tab ) { 16 | tab = saved_tab.substring( 1 ); 17 | } 18 | 19 | if ( window.location.hash ) { 20 | tab = window.location.hash.substring( 1 ); 21 | } else { 22 | window.location.hash = tab; 23 | } 24 | 25 | jQuery( 'div[class^="atomic-blocks-settings-"], div[class^="genesis-page-builder-settings-"]' ).hide(); 26 | jQuery( '#atomic-blocks-settings .tab-content' ).hide(); 27 | jQuery( '.inline-list' ) 28 | .find( 'li' ) 29 | .removeClass( 'current' ); 30 | jQuery( '.atomic-blocks-settings-tab-' + tab + ', .genesis-page-builder-settings-tab-' + tab ) 31 | .addClass( 'current' ) 32 | .blur(); 33 | jQuery( '#atomic-blocks-settings' ) 34 | .find( '.atomic-blocks-settings-' + tab + ', .genesis-page-builder-settings-' + tab ) 35 | .show(); 36 | }, 37 | 38 | // Adds event listeners. 39 | addListeners() { 40 | jQuery( '.inline-list a' ).on( 'click', function( event ) { 41 | event.preventDefault(); 42 | jQuery( 'div[class^="atomic-blocks-settings-"], div[class^="genesis-page-builder-settings-"]' ).hide(); 43 | AtomicBlocksSettings.switchTab( 44 | jQuery( this ), 45 | event.target.hash 46 | ); 47 | AtomicBlocksSettings.saveActiveTabState( event.target.hash ); 48 | } ); 49 | }, 50 | 51 | // Handles tab switching functionality. 52 | switchTab( target, hash ) { 53 | var tab = target.data( 'tab' ); 54 | window.location.hash = hash; 55 | target 56 | .parent() 57 | .siblings() 58 | .removeClass( 'current' ); 59 | target 60 | .parent() 61 | .addClass( 'current' ) 62 | .blur(); 63 | jQuery( '#atomic-blocks-settings .tab-content' ).hide(); 64 | jQuery( '#atomic-blocks-settings' ) 65 | .find( '.atomic-blocks-settings-' + tab +', .genesis-page-builder-settings-' + tab ) 66 | .show(); 67 | }, 68 | 69 | // Returns the active tab stored in session storage. 70 | getActiveTabState() { 71 | if ( 'undefined' === typeof sessionStorage ) { 72 | return; 73 | } 74 | 75 | return sessionStorage.getItem( 76 | 'atomic_blocks_settings_active_tab' 77 | ); 78 | }, 79 | 80 | // Saves the active tab in session storage. 81 | saveActiveTabState( tab ) { 82 | if ( 'undefined' === typeof sessionStorage ) { 83 | return; 84 | } 85 | 86 | sessionStorage.setItem( 'atomic_blocks_settings_active_tab', tab ); 87 | }, 88 | }; 89 | 90 | // Bootstrap the settings page. 91 | AtomicBlocksSettings.init(); 92 | } ); 93 | -------------------------------------------------------------------------------- /dist/getting-started/theme.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/studiopress/atomic-blocks/70793261e92f98afca792faf1981bb2a02d59f84/dist/getting-started/theme.jpg -------------------------------------------------------------------------------- /dist/migration/admin.migration-notice.css: -------------------------------------------------------------------------------- 1 | .ab-notice-migration { 2 | display: flex; 3 | } 4 | 5 | .ab-notice-migration .ab-migration-copy { 6 | margin-right: auto; 7 | } 8 | 9 | .ab-notice-migration__learn-more { 10 | display: block; 11 | } 12 | 13 | .ab-notice-migration .ab-notice-option { 14 | margin: auto 0.2rem; 15 | } 16 | 17 | .ab-notice-migration.ab-hidden { 18 | display: none; 19 | } 20 | 21 | #ab-notice-not-now { 22 | margin-left: 16px; 23 | } 24 | .ab-notice-migration.notice-info{ 25 | border-left-color: #5d45c9; 26 | } -------------------------------------------------------------------------------- /dist/migration/admin.migration-notice.js: -------------------------------------------------------------------------------- 1 | /* global XMLHttpRequest, FormData, ajaxurl */ 2 | 3 | document.addEventListener( 'DOMContentLoaded', function() { 4 | const hiddenClass = 'ab-hidden'; 5 | 6 | // In the main migration notice, on clicking 'Not Now', 7 | // make an AJAX request to store the user meta to not display the notice again. 8 | // Also, remove this notice and display another. 9 | document.querySelector( '#ab-notice-not-now' ).addEventListener( 'click', function() { 10 | const request = new XMLHttpRequest(); 11 | const data = new FormData(); 12 | data.append( 'action', 'ab_dismiss_migration_notice' ); 13 | data.append( 'ab-migration-nonce-name', document.querySelector( '#ab-migration-nonce-name' ).value ); 14 | 15 | request.open( 'POST', ajaxurl, true ); 16 | request.send( data ); 17 | 18 | // Remove this notice. 19 | const notice = document.querySelector( '#ab-migration-notice' ); 20 | notice.parentNode.removeChild( notice ); 21 | 22 | // Display the 'Not Now' notice. 23 | document.querySelector( '#ab-not-now-notice' ).classList.remove( hiddenClass ); 24 | } ); 25 | 26 | // In the 'Not Now' notice, on clicking 'OK', hide the notice. 27 | document.querySelector( '#ab-notice-ok' ).addEventListener( 'click', function() { 28 | document.querySelector( '#ab-not-now-notice' ).classList.add( hiddenClass ); 29 | } ); 30 | } ); 31 | -------------------------------------------------------------------------------- /dist/migration/class-redirect.php: -------------------------------------------------------------------------------- 1 | get_rest_url( null, 'atomicblocks/v1/install-activate-gb/' ), 26 | 'install_gb_nonce' => wp_create_nonce( 'wp_rest' ), 27 | 'success_redirect_url' => admin_url( 'admin.php?page=genesis-blocks-migrate' ), 28 | ) 29 | ); 30 | 31 | // Migrate Page styles. 32 | wp_register_style( 'atomic-blocks-migrate', plugins_url( '/migrate-page/ab-migrate.css', dirname( __FILE__ ) ), false, '1.0.0' ); 33 | wp_enqueue_style( 'atomic-blocks-migrate' ); 34 | 35 | wp_enqueue_style( 'common-css' ); 36 | } 37 | add_action( 'admin_enqueue_scripts', 'atomic_blocks_migrate_load_admin_scripts' ); 38 | 39 | /** 40 | * Adds a submenu item for the Migrate Page under the Atomic Blocks top level menu. 41 | * 42 | * @since 1.0.0 43 | */ 44 | function atomic_blocks_migrate_menu() { 45 | 46 | add_submenu_page( 47 | 'atomic-blocks', 48 | esc_html__( 'Migrate', 'atomic-blocks' ), 49 | esc_html__( 'Migrate', 'atomic-blocks' ), 50 | 'install_plugins', 51 | 'atomic-blocks-migrate-page', 52 | 'atomic_blocks_migrate_page' 53 | ); 54 | 55 | } 56 | add_action( 'admin_menu', 'atomic_blocks_migrate_menu', 11 ); 57 | 58 | /** 59 | * Outputs the markup used on the Migrate Page 60 | * 61 | * @since 1.0.0 62 | */ 63 | function atomic_blocks_migrate_page() { 64 | 65 | $this_dir = trailingslashit( dirname( __FILE__ ) ); 66 | 67 | include $this_dir . 'ab-migrate.php'; 68 | 69 | } 70 | -------------------------------------------------------------------------------- /includes/compat.php: -------------------------------------------------------------------------------- 1 | 22 | 30 | array( 38 | 'class' => true, 39 | 'xmlns' => true, 40 | 'width' => true, 41 | 'height' => true, 42 | 'viewbox' => true, 43 | 'aria-hidden' => true, 44 | 'role' => true, 45 | 'focusable' => true, 46 | ), 47 | 'path' => array( 48 | 'fill' => true, 49 | 'fill-rule' => true, 50 | 'd' => true, 51 | 'transform' => true, 52 | ), 53 | 'polygon' => array( 54 | 'fill' => true, 55 | 'fill-rule' => true, 56 | 'points' => true, 57 | 'transform' => true, 58 | 'focusable' => true, 59 | ), 60 | ) 61 | ); 62 | 63 | if ( ! $svg ) { 64 | return false; 65 | } 66 | return $svg; 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /includes/interfaces/newsletter-provider-interface.php: -------------------------------------------------------------------------------- 1 | getMessage() ) ); 27 | } 28 | } 29 | 30 | /** 31 | * Unregisters the specified layout component from the Component Registry 32 | * for use in the Layouts block. 33 | * 34 | * @return mixed Boolean true if component unregistered. WP_Error object if an error occurs. 35 | * @param string $type The component type to be unregistered. 36 | * @param string $key The unique layout key to be unregistered. 37 | */ 38 | function atomic_blocks_unregister_layout_component( $type, $key ) { 39 | $registry = Component_Registry::instance(); 40 | try { 41 | $registry::remove( $type, $key ); 42 | return true; 43 | } catch ( Exception $exception ) { 44 | return new WP_Error( esc_html( $exception->getMessage() ) ); 45 | } 46 | } 47 | 48 | /** 49 | * Retrieves the specified layout component. 50 | * 51 | * @param string $type The layout component type. 52 | * @param string $key The layout component's unique key. 53 | * 54 | * @return mixed|WP_Error 55 | */ 56 | function atomic_blocks_get_layout_component( $type, $key ) { 57 | 58 | if ( empty( $type ) ) { 59 | return new WP_Error( esc_html__( 'You must supply a type to retrieve a layout component.', 'atomic-blocks' ) ); 60 | } 61 | 62 | if ( empty( $key ) ) { 63 | return new WP_Error( esc_html__( 'You must supply a key to retrieve a layout component.', 'atomic-blocks' ) ); 64 | } 65 | 66 | $type = sanitize_key( $type ); 67 | 68 | $key = sanitize_key( $key ); 69 | 70 | $registry = Component_Registry::instance(); 71 | 72 | try { 73 | return $registry::get( $type, $key ); 74 | } catch ( Exception $exception ) { 75 | return new WP_Error( esc_html( $exception->getMessage() ) ); 76 | } 77 | } 78 | 79 | /** 80 | * Gets the registered layouts. 81 | * 82 | * @return array Array of registered layouts. 83 | */ 84 | function atomic_blocks_get_layouts() { 85 | $registry = Component_Registry::instance(); 86 | return $registry::layouts(); 87 | } 88 | 89 | /** 90 | * Gets the registered sections. 91 | * 92 | * @return array Array of registered sections. 93 | */ 94 | function atomic_blocks_get_sections() { 95 | $registry = Component_Registry::instance(); 96 | return $registry::sections(); 97 | } 98 | -------------------------------------------------------------------------------- /phpcs.xml.dist: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | Atomic Blocks ruleset for phpcs. 7 | 8 | 9 | . 10 | 11 | 12 | *.min.js 13 | /languages/ 14 | /node_modules/ 15 | /vendor/ 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | tests 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | -------------------------------------------------------------------------------- /phpunit.xml.dist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 13 | 14 | 15 | tests 16 | 17 | 18 | 19 | 20 | 21 | . 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /src/blocks.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Import blocks. 3 | */ 4 | import './blocks/block-testimonial/index.js'; 5 | import './blocks/block-author-profile/index.js'; 6 | import './blocks/block-notice/index.js'; 7 | import './blocks/block-drop-cap/index.js'; 8 | import './blocks/block-button/index.js'; 9 | import './blocks/block-spacer/index.js'; 10 | import './blocks/block-accordion/index.js'; 11 | import './blocks/block-cta/index.js'; 12 | import './blocks/block-sharing/index.js'; 13 | import './blocks/block-post-grid/index.js'; 14 | import './blocks/block-container/index.js'; 15 | 16 | /** 17 | * Pricing Table block. 18 | */ 19 | import './blocks/block-pricing-table/index.js'; 20 | import './blocks/block-pricing-table-inner/index.js'; 21 | import './blocks/block-pricing-table-inner/components/price/index.js'; 22 | import './blocks/block-pricing-table-inner/components/description/index.js'; 23 | import './blocks/block-pricing-table-inner/components/title/index.js'; 24 | import './blocks/block-pricing-table-inner/components/subtitle/index.js'; 25 | import './blocks/block-pricing-table-inner/components/button/index.js'; 26 | 27 | /** 28 | * Newsletter block. 29 | */ 30 | import './blocks/block-newsletter/index'; 31 | 32 | /** 33 | * Advanced Column block. 34 | */ 35 | import './blocks/block-column/index.js'; 36 | import './blocks/block-column-inner/index.js'; 37 | 38 | /** 39 | * Section and Layout block. 40 | */ 41 | import './blocks/block-layout/index.js'; 42 | 43 | /** 44 | * Global styles. 45 | */ 46 | import './blocks/global-styles/index.js'; 47 | -------------------------------------------------------------------------------- /src/blocks/block-accordion/components/accordion.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Accordion Wrapper 3 | */ 4 | 5 | // Setup the block 6 | const { Component } = wp.element; 7 | 8 | // Import block dependencies and components 9 | import classnames from 'classnames'; 10 | 11 | /** 12 | * Create a Accordion wrapper Component 13 | */ 14 | export default class Accordion extends Component { 15 | constructor( props ) { 16 | super( ...arguments ); 17 | } 18 | 19 | render() { 20 | return ( 21 |
34 | { this.props.children } 35 |
36 | ); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/blocks/block-accordion/components/edit.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Internal dependencies 3 | */ 4 | import Inspector from './inspector'; 5 | import Accordion from './accordion'; 6 | 7 | /** 8 | * WordPress dependencies 9 | */ 10 | const { __ } = wp.i18n; 11 | const { Component } = wp.element; 12 | const { 13 | RichText, 14 | AlignmentToolbar, 15 | BlockControls, 16 | InnerBlocks, 17 | } = wp.blockEditor; 18 | 19 | export default class Edit extends Component { 20 | constructor() { 21 | super( ...arguments ); 22 | } 23 | 24 | render() { 25 | return [ 26 | // Show the block alignment controls on focus 27 | 28 | 31 | this.props.setAttributes( { 32 | accordionAlignment: value, 33 | } ) 34 | } 35 | /> 36 | , 37 | 38 | // Show the block controls on focus 39 | , 40 | 41 | // Show the button markup in the editor 42 | 43 | 49 | this.props.setAttributes( { accordionTitle: value } ) 50 | } 51 | /> 52 | 53 |
54 | 55 |
56 |
, 57 | ]; 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /src/blocks/block-accordion/components/inspector.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Inspector Controls. 3 | */ 4 | 5 | /** 6 | * Internal dependencies. 7 | */ 8 | import RenderSettingControl from '../../../utils/components/settings/renderSettingControl'; 9 | 10 | /** 11 | * Setup the block. 12 | */ 13 | const { __ } = wp.i18n; 14 | const { Component } = wp.element; 15 | 16 | /** 17 | * Import block dependencies. 18 | */ 19 | const { InspectorControls } = wp.blockEditor; 20 | 21 | /** 22 | * Import Inspector components. 23 | */ 24 | const { PanelBody, RangeControl, ToggleControl } = wp.components; 25 | 26 | /** 27 | * Create an Inspector Controls wrapper Component. 28 | */ 29 | export default class Inspector extends Component { 30 | constructor( props ) { 31 | super( ...arguments ); 32 | } 33 | 34 | render() { 35 | return ( 36 | 37 | 38 | 39 | 43 | this.props.setAttributes( { 44 | accordionFontSize: value, 45 | } ) 46 | } 47 | min={ 14 } 48 | max={ 24 } 49 | step={ 1 } 50 | /> 51 | 52 | 53 | 54 | 58 | this.props.setAttributes( { 59 | accordionOpen: ! this.props.attributes 60 | .accordionOpen, 61 | } ) 62 | } 63 | /> 64 | 65 | 66 | 67 | ); 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /src/blocks/block-accordion/components/save.js: -------------------------------------------------------------------------------- 1 | // Import block dependencies and components 2 | import Accordion from './accordion'; 3 | 4 | /** 5 | * WordPress dependencies 6 | */ 7 | const { Component } = wp.element; 8 | const { RichText, InnerBlocks } = wp.blockEditor; 9 | 10 | export default class Save extends Component { 11 | constructor() { 12 | super( ...arguments ); 13 | } 14 | 15 | render() { 16 | return ( 17 | 18 |
19 | 20 | 23 | 24 |
25 | 26 |
27 |
28 |
29 | ); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/blocks/block-accordion/deprecated/2.0/components/accordion.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Accordion Wrapper 3 | */ 4 | 5 | // Setup the block 6 | const { Component } = wp.element; 7 | 8 | // Import block dependencies and components 9 | import classnames from 'classnames'; 10 | 11 | /** 12 | * Create a Accordion wrapper Component 13 | */ 14 | export default class Accordion_2_0 extends Component { 15 | constructor( props ) { 16 | super( ...arguments ); 17 | } 18 | 19 | render() { 20 | // Setup the attributes 21 | const { accordionAlignment, accordionFontSize } = this.props.attributes; 22 | 23 | return ( 24 |
33 | { this.props.children } 34 |
35 | ); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/blocks/block-accordion/deprecated/2.0/components/save.js: -------------------------------------------------------------------------------- 1 | // Import block dependencies and components 2 | import Accordion_2_0 from './accordion'; 3 | 4 | /** 5 | * WordPress dependencies 6 | */ 7 | const { Component } = wp.element; 8 | const { RichText, InnerBlocks } = wp.blockEditor; 9 | 10 | export default class Save_2_0 extends Component { 11 | constructor() { 12 | super( ...arguments ); 13 | } 14 | 15 | render() { 16 | return ( 17 | 18 |
19 | 20 | 23 | 24 |
25 | 26 |
27 |
28 |
29 | ); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/blocks/block-accordion/deprecated/deprecated.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Component deprecations. 3 | */ 4 | 5 | /** 6 | * Version 2.0. 7 | */ 8 | import Save_2_0 from './2.0/components/save'; 9 | 10 | export const Accordion_2_0_save = ( props ) => { 11 | return ; 12 | }; 13 | 14 | export const Accordion_2_0_attributes = { 15 | accordionTitle: { 16 | type: 'array', 17 | selector: '.ab-accordion-title', 18 | source: 'children', 19 | }, 20 | accordionText: { 21 | type: 'array', 22 | selector: '.ab-accordion-text', 23 | source: 'children', 24 | }, 25 | accordionAlignment: { 26 | type: 'string', 27 | }, 28 | accordionFontSize: { 29 | type: 'number', 30 | default: 18, 31 | }, 32 | accordionOpen: { 33 | type: 'boolean', 34 | default: false, 35 | }, 36 | }; 37 | 38 | const Deprecated = [ 39 | /* Version 2.0. */ 40 | { 41 | attributes: Accordion_2_0_attributes, 42 | save: Accordion_2_0_save, 43 | }, 44 | ]; 45 | 46 | export default Deprecated; 47 | -------------------------------------------------------------------------------- /src/blocks/block-accordion/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * BLOCK: Atomic Blocks Accordion Block 3 | */ 4 | 5 | // Import block dependencies and components 6 | import Edit from './components/edit'; 7 | import Save from './components/save'; 8 | import Deprecated from './deprecated/deprecated'; 9 | 10 | // Import CSS 11 | import './styles/style.scss'; 12 | import './styles/editor.scss'; 13 | 14 | // Components 15 | const { __ } = wp.i18n; 16 | 17 | // Extend component 18 | const { Component } = wp.element; 19 | 20 | // Register block 21 | const { registerBlockType } = wp.blocks; 22 | 23 | const blockAttributes = { 24 | accordionTitle: { 25 | type: 'array', 26 | selector: '.ab-accordion-title', 27 | source: 'children', 28 | }, 29 | accordionText: { 30 | type: 'array', 31 | selector: '.ab-accordion-text', 32 | source: 'children', 33 | }, 34 | accordionAlignment: { 35 | type: 'string', 36 | }, 37 | accordionFontSize: { 38 | type: 'number', 39 | default: undefined, 40 | }, 41 | accordionOpen: { 42 | type: 'boolean', 43 | default: false, 44 | }, 45 | }; 46 | 47 | // Register the block 48 | registerBlockType( 'atomic-blocks/ab-accordion', { 49 | title: __( 'Accordion', 'atomic-blocks' ), 50 | description: __( 51 | 'Add accordion block with a title and text.', 52 | 'atomic-blocks' 53 | ), 54 | icon: 'editor-ul', 55 | category: 'atomic-blocks', 56 | keywords: [ 57 | __( 'accordion', 'atomic-blocks' ), 58 | __( 'list', 'atomic-blocks' ), 59 | __( 'atomic', 'atomic-blocks' ), 60 | ], 61 | attributes: blockAttributes, 62 | 63 | ab_settings_data: { 64 | ab_accordion_accordionFontSize: { 65 | title: __( 'Title Font Size', 'atomic-blocks' ), 66 | }, 67 | ab_accordion_accordionOpen: { 68 | title: __( 'Open by default', 'atomic-blocks' ), 69 | }, 70 | }, 71 | 72 | // Render the block components 73 | edit: ( props ) => { 74 | return ; 75 | }, 76 | 77 | // Save the attributes and markup 78 | save: ( props ) => { 79 | return ; 80 | }, 81 | 82 | deprecated: Deprecated, 83 | } ); 84 | -------------------------------------------------------------------------------- /src/blocks/block-accordion/styles/editor.scss: -------------------------------------------------------------------------------- 1 | /** 2 | * Editor styles for the admin 3 | */ 4 | 5 | .ab-block-accordion { 6 | margin-bottom: 0; 7 | } 8 | -------------------------------------------------------------------------------- /src/blocks/block-accordion/styles/style.scss: -------------------------------------------------------------------------------- 1 | /** 2 | * Accordion styles 3 | * Loads on front end and back end 4 | */ 5 | 6 | .ab-block-accordion { 7 | margin-bottom: 1.2em; 8 | 9 | .ab-accordion-title { 10 | background: #f2f2f2; 11 | padding: 10px 15px; 12 | 13 | p { 14 | display: inline; 15 | } 16 | } 17 | 18 | .ab-accordion-text { 19 | padding: 10px 15px; 20 | } 21 | 22 | .editor-rich-text .editor-rich-text__inline-toolbar { 23 | display: block; 24 | left: 40%; 25 | } 26 | } 27 | 28 | .ab-block-accordion + .ab-block-accordion { 29 | margin-top: -.6em; 30 | } 31 | 32 | /* Font size styles */ 33 | @media only screen and (min-width: 600px) { 34 | 35 | .ab-font-size-14 .ab-accordion-title { 36 | font-size: 14px; 37 | } 38 | 39 | .ab-font-size-15 .ab-accordion-title { 40 | font-size: 15px; 41 | } 42 | 43 | .ab-font-size-16 .ab-accordion-title { 44 | font-size: 16px; 45 | } 46 | 47 | .ab-font-size-17 .ab-accordion-title { 48 | font-size: 17px; 49 | } 50 | 51 | .ab-font-size-18 .ab-accordion-title { 52 | font-size: 18px; 53 | } 54 | 55 | .ab-font-size-19 .ab-accordion-title { 56 | font-size: 19px; 57 | } 58 | 59 | .ab-font-size-20 .ab-accordion-title { 60 | font-size: 20px; 61 | } 62 | 63 | .ab-font-size-21 .ab-accordion-title { 64 | font-size: 21px; 65 | } 66 | 67 | .ab-font-size-22 .ab-accordion-title { 68 | font-size: 22px; 69 | } 70 | 71 | .ab-font-size-23 .ab-accordion-title { 72 | font-size: 23px; 73 | } 74 | 75 | .ab-font-size-24 .ab-accordion-title { 76 | font-size: 24px; 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /src/blocks/block-author-profile/components/avatar.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Avatar Column Wrapper 3 | */ 4 | 5 | /* Setup the block */ 6 | const { Component } = wp.element; 7 | 8 | /* Create an SocialIcons wrapper Component */ 9 | export default class AvatarColumn extends Component { 10 | constructor( props ) { 11 | super( ...arguments ); 12 | } 13 | 14 | render() { 15 | return ( 16 |
17 |
18 | { this.props.children } 19 |
20 |
21 | ); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/blocks/block-author-profile/components/profile.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Profile Box Wrapper 3 | */ 4 | 5 | /* Setup the block */ 6 | const { Component } = wp.element; 7 | 8 | /* Import block dependencies and components */ 9 | import classnames from 'classnames'; 10 | 11 | /* Create a profile box wrapper Component */ 12 | export default class ProfileBox extends Component { 13 | constructor( props ) { 14 | super( ...arguments ); 15 | } 16 | 17 | render() { 18 | /* Setup the attributes */ 19 | const { 20 | profileAlignment, 21 | profileImgURL, 22 | profileFontSize, 23 | profileBackgroundColor, 24 | profileTextColor, 25 | profileAvatarShape, 26 | } = this.props.attributes; 27 | 28 | return ( 29 |
44 | { this.props.children } 45 |
46 | ); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/blocks/block-author-profile/components/save.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Internal dependencies 3 | */ 4 | import classnames from 'classnames'; 5 | import ProfileBox from './profile'; 6 | import SocialIcons from './social'; 7 | import AvatarColumn from './avatar'; 8 | 9 | /** 10 | * WordPress dependencies 11 | */ 12 | const { Component } = wp.element; 13 | const { RichText } = wp.blockEditor; 14 | 15 | export default class Save extends Component { 16 | constructor() { 17 | super( ...arguments ); 18 | } 19 | 20 | render() { 21 | const { 22 | profileName, 23 | profileTitle, 24 | profileContent, 25 | profileImgURL, 26 | profileImgAlt, 27 | profileImgID, 28 | profileTextColor, 29 | } = this.props.attributes; 30 | 31 | return ( 32 | /* Save the block markup for the front end */ 33 | 34 | { profileImgURL && ( 35 | 36 |
37 | { 45 |
46 |
47 | ) } 48 | 49 |
54 | { profileName && ( 55 | 63 | ) } 64 | 65 | { profileTitle && ( 66 | 74 | ) } 75 | 76 | { profileContent && ( 77 | 82 | ) } 83 | 84 | 85 |
86 |
87 | ); 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /src/blocks/block-author-profile/deprecated/1.8.1/components/save.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Internal dependencies 3 | */ 4 | import classnames from 'classnames'; 5 | import ProfileBox from '../../../components/profile'; 6 | import SocialIcons from '../../../components/social'; 7 | import AvatarColumn from '../../../components/avatar'; 8 | 9 | /** 10 | * WordPress dependencies 11 | */ 12 | const { Component } = wp.element; 13 | const { RichText } = wp.blockEditor; 14 | 15 | export default class Save_1_8_1 extends Component { 16 | constructor() { 17 | super( ...arguments ); 18 | } 19 | 20 | render() { 21 | const { 22 | profileName, 23 | profileTitle, 24 | profileContent, 25 | profileImgURL, 26 | profileTextColor, 27 | } = this.props.attributes; 28 | 29 | return ( 30 | /* Save the block markup for the front end */ 31 | 32 | { profileImgURL && ( 33 | 34 |
35 | avatar 40 |
41 |
42 | ) } 43 | 44 |
49 | { profileName && ( 50 | 58 | ) } 59 | 60 | { profileTitle && ( 61 | 69 | ) } 70 | 71 | { profileContent && ( 72 | 77 | ) } 78 | 79 | 80 |
81 |
82 | ); 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /src/blocks/block-author-profile/deprecated/deprecated.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Component deprecations. 3 | */ 4 | 5 | /** 6 | * Version 1.8.1. 7 | */ 8 | import Save_1_8_1 from './1.8.1/components/save'; 9 | 10 | export const Author_Profile_1_8_1_attributes = { 11 | profileName: { 12 | type: 'array', 13 | source: 'children', 14 | selector: '.ab-profile-name', 15 | }, 16 | profileTitle: { 17 | type: 'array', 18 | source: 'children', 19 | selector: '.ab-profile-title', 20 | }, 21 | profileContent: { 22 | type: 'array', 23 | selector: '.ab-profile-text', 24 | source: 'children', 25 | }, 26 | profileAlignment: { 27 | type: 'string', 28 | }, 29 | profileImgURL: { 30 | type: 'string', 31 | source: 'attribute', 32 | attribute: 'src', 33 | selector: 'img', 34 | }, 35 | profileImgID: { 36 | type: 'number', 37 | }, 38 | profileBackgroundColor: { 39 | type: 'string', 40 | default: '#f2f2f2', 41 | }, 42 | profileTextColor: { 43 | type: 'string', 44 | default: '#32373c', 45 | }, 46 | profileLinkColor: { 47 | type: 'string', 48 | default: '#392f43', 49 | }, 50 | profileFontSize: { 51 | type: 'number', 52 | default: 18, 53 | }, 54 | profileAvatarShape: { 55 | type: 'string', 56 | default: 'square', 57 | }, 58 | twitter: { 59 | type: 'url', 60 | }, 61 | facebook: { 62 | type: 'url', 63 | }, 64 | instagram: { 65 | type: 'url', 66 | }, 67 | pinterest: { 68 | type: 'url', 69 | }, 70 | google: { 71 | type: 'url', 72 | }, 73 | youtube: { 74 | type: 'url', 75 | }, 76 | github: { 77 | type: 'url', 78 | }, 79 | linkedin: { 80 | type: 'url', 81 | }, 82 | email: { 83 | type: 'url', 84 | }, 85 | website: { 86 | type: 'url', 87 | }, 88 | }; 89 | 90 | export const Author_Profile_1_8_1_save = ( props ) => { 91 | return ; 92 | }; 93 | 94 | const Deprecated = [ 95 | /* Version 1.8.1. */ 96 | { 97 | attributes: Author_Profile_1_8_1_attributes, 98 | save: Author_Profile_1_8_1_save, 99 | }, 100 | ]; 101 | 102 | export default Deprecated; 103 | -------------------------------------------------------------------------------- /src/blocks/block-author-profile/styles/editor.scss: -------------------------------------------------------------------------------- 1 | /** 2 | * Editor styles for the admin 3 | */ 4 | 5 | .ab-block-profile { 6 | margin-bottom: 0; 7 | } 8 | 9 | .block-editor-block-list__layout [data-type="atomic-blocks/ab-profile-box"] { 10 | margin-bottom: 1.2em; 11 | } 12 | 13 | .ab-profile-image-wrap { 14 | svg { 15 | pointer-events: none; 16 | margin: auto; 17 | } 18 | 19 | .components-button:not(:disabled):not([aria-disabled=true]):focus { 20 | background: none; 21 | box-shadow: none; 22 | } 23 | } 24 | 25 | .ab-profile-content-wrap { 26 | h2.editor-rich-text__tinymce { 27 | line-height: 1.2; 28 | } 29 | 30 | p.editor-rich-text__tinymce { 31 | line-height: 1.6; 32 | } 33 | } 34 | 35 | #editor .wp-block-atomic-blocks-ab-profile-box.square .ab-remove-image { 36 | top: 5px; 37 | right: 5px; 38 | } 39 | 40 | #editor .ab-has-avatar { 41 | 42 | .ab-profile-image-square { 43 | button { 44 | top: 0; 45 | left: 0; 46 | height: 100%; 47 | } 48 | 49 | .ab-change-image { 50 | transition: .2s ease; 51 | 52 | &:hover { 53 | opacity: .7; 54 | } 55 | } 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /src/blocks/block-author-profile/styles/style.scss: -------------------------------------------------------------------------------- 1 | /** 2 | * Profile styles 3 | * Loads on front end and back end 4 | */ 5 | 6 | .ab-block-profile { 7 | background: #f2f2f2; 8 | color: #293038; 9 | margin: 0 auto; 10 | padding: 3%; 11 | border-radius: 5px; 12 | margin-bottom: 1.2em; 13 | display: flex; 14 | flex-flow: row wrap; 15 | justify-content: space-around; 16 | width: 100%; 17 | 18 | .ab-profile-column { 19 | display: block; 20 | padding: 15px; 21 | flex: 3 0 0; 22 | 23 | @media only screen and (max-width: 600px) { 24 | flex: auto; 25 | } 26 | } 27 | 28 | .ab-profile-avatar-wrap { 29 | position: relative; 30 | z-index: 0; 31 | flex: 1 0 0; 32 | 33 | @media only screen and (max-width: 600px) { 34 | flex: auto; 35 | max-width: 210px; 36 | margin: 0 auto; 37 | } 38 | } 39 | 40 | .ab-profile-content-wrap { 41 | @media only screen and (max-width: 600px) { 42 | text-align: center; 43 | } 44 | } 45 | 46 | .ab-profile-text { 47 | font-size: 18px; 48 | padding-top: 1em; 49 | 50 | a { 51 | color: inherit; 52 | box-shadow: 0 -1px 0 inset; 53 | text-decoration: none; 54 | 55 | &:hover { 56 | color: inherit; 57 | box-shadow: 0 -2px 0 inset; 58 | } 59 | } 60 | 61 | p { 62 | line-height: 1.6; 63 | 64 | &:last-child { 65 | margin-bottom: 0; 66 | } 67 | } 68 | } 69 | 70 | .ab-profile-name { 71 | font-size: 1.4em; 72 | font-weight: bold; 73 | line-height: 1.2; 74 | margin: 0; 75 | } 76 | 77 | .ab-profile-title { 78 | opacity: .8; 79 | padding-top: 5px; 80 | margin-bottom: 0; 81 | } 82 | 83 | .ab-profile-image-square { 84 | position: absolute; 85 | top: 0; 86 | left: 0; 87 | height: 100%; 88 | width: 100%; 89 | z-index: 5; 90 | margin: 0; 91 | } 92 | 93 | .ab-profile-text:empty, 94 | .ab-profile-title:empty, 95 | .ab-profile-name:empty { 96 | display: none; 97 | } 98 | 99 | .ab-profile-image-wrap { 100 | width: 100%; 101 | background: #ddd; 102 | position: relative; 103 | width: 100%; 104 | 105 | &:before { 106 | content: ''; 107 | display: inline-block; 108 | padding-top: 100%; 109 | } 110 | 111 | button { 112 | position: absolute; 113 | left: 0; 114 | z-index: 50; 115 | padding: 0; 116 | height: 100%; 117 | width: 100%; 118 | } 119 | 120 | button:focus { 121 | background: none; 122 | border: none; 123 | outline: none; 124 | box-shadow: none; 125 | } 126 | 127 | img { 128 | object-fit: cover; 129 | height: 100%; 130 | width: 100%; 131 | position: relative; 132 | z-index: 5; 133 | } 134 | } 135 | 136 | .ab-social-links { 137 | list-style: none; 138 | margin: 0 0 0 0; 139 | padding: 5% 0 0 0; 140 | font-size: 0; 141 | 142 | &:empty { 143 | display: none; 144 | } 145 | 146 | li { 147 | display: inline-block; 148 | margin: 0 8px 0 0; 149 | padding: 0; 150 | 151 | a { 152 | border: none; 153 | 154 | &:hover { 155 | opacity: .9; 156 | } 157 | } 158 | 159 | i { 160 | font-size: 18px; 161 | background: #0393e3; 162 | color: #fff; 163 | padding: 10px; 164 | border-radius: 100px; 165 | height: 38px; 166 | width: 38px; 167 | text-align: center; 168 | } 169 | } 170 | } 171 | } 172 | 173 | .right .ab-profile-avatar-wrap { 174 | order: 2; 175 | } 176 | 177 | .round .ab-profile-image-wrap { 178 | border-radius: 500px; 179 | 180 | &:before { 181 | content: ''; 182 | display: inline-block; 183 | padding-top: 92%; 184 | } 185 | 186 | img { 187 | border-radius: 500px; 188 | } 189 | } 190 | -------------------------------------------------------------------------------- /src/blocks/block-button/components/button.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Button Wrapper 3 | */ 4 | 5 | // Setup the block 6 | const { Component } = wp.element; 7 | 8 | // Import block dependencies and components 9 | import classnames from 'classnames'; 10 | 11 | /** 12 | * Create a Button wrapper Component 13 | */ 14 | export default class customButton extends Component { 15 | constructor( props ) { 16 | super( ...arguments ); 17 | } 18 | 19 | render() { 20 | return ( 21 |
30 | { this.props.children } 31 |
32 | ); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/blocks/block-button/components/icons.js: -------------------------------------------------------------------------------- 1 | const icons = {}; 2 | 3 | icons.upload = ( 4 | 10 | 11 | 12 | 13 | 14 | 15 | ); 16 | 17 | icons.dismiss = ( 18 | 25 | 26 | 27 | ); 28 | 29 | export default icons; 30 | -------------------------------------------------------------------------------- /src/blocks/block-button/components/inspector.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Inspector Controls 3 | */ 4 | 5 | // Import Inspector settings 6 | import ButtonSettings from './../../../utils/inspector/button'; 7 | 8 | // Setup the block 9 | const { __ } = wp.i18n; 10 | const { Component } = wp.element; 11 | 12 | // Import block components 13 | const { InspectorControls } = wp.blockEditor; 14 | 15 | // Import Inspector components 16 | const { PanelBody } = wp.components; 17 | 18 | /** 19 | * Create an Inspector Controls wrapper Component 20 | */ 21 | export default class Inspector extends Component { 22 | constructor( props ) { 23 | super( ...arguments ); 24 | } 25 | 26 | render() { 27 | // Setup the attributes 28 | const { 29 | buttonBackgroundColor, 30 | buttonTextColor, 31 | buttonSize, 32 | buttonShape, 33 | buttonTarget, 34 | } = this.props.attributes; 35 | const { setAttributes } = this.props; 36 | 37 | return ( 38 | 39 | 40 | 44 | setAttributes( { buttonTarget: ! buttonTarget } ) 45 | } 46 | // Button Size 47 | buttonSize={ buttonSize } 48 | onChangeButtonSize={ ( buttonSize ) => 49 | setAttributes( { buttonSize } ) 50 | } 51 | // Button Shape 52 | buttonShape={ buttonShape } 53 | onChangeButtonShape={ ( buttonShape ) => 54 | setAttributes( { buttonShape } ) 55 | } 56 | // Button color 57 | buttonBackgroundColor={ buttonBackgroundColor } 58 | onChangeButtonColor={ ( buttonBackgroundColor ) => 59 | setAttributes( { buttonBackgroundColor } ) 60 | } 61 | // Button text color 62 | buttonTextColor={ buttonTextColor } 63 | onChangeButtonTextColor={ ( buttonTextColor ) => 64 | setAttributes( { buttonTextColor } ) 65 | } 66 | /> 67 | 68 | 69 | ); 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /src/blocks/block-button/styles/editor.scss: -------------------------------------------------------------------------------- 1 | /** 2 | * Editor styles for the admin 3 | */ 4 | 5 | .ab-block-button { 6 | &+ .blocks-button__inline-link .editor-url-input, 7 | &+ .blocks-button__inline-link .block-editor-url-input { 8 | display: inline-block; 9 | width: auto; 10 | } 11 | 12 | &+ .blocks-button__inline-link .components-button { 13 | display: inline-block; 14 | padding: 8px; 15 | } 16 | 17 | &+ .blocks-button__inline-link svg { 18 | vertical-align: middle; 19 | margin-right: 8px; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/blocks/block-button/styles/style.scss: -------------------------------------------------------------------------------- 1 | /** 2 | * Button styles 3 | * Loads on front end and back end 4 | */ 5 | 6 | .ab-block-button { 7 | margin: 0 0 1.2em 0; 8 | position: relative; 9 | 10 | .blocks-rich-text { 11 | display: inline-flex; 12 | } 13 | 14 | .components-autocomplete { 15 | display: inline-block; 16 | width: auto; 17 | margin: 0 auto; 18 | position: relative; 19 | } 20 | } 21 | 22 | .ab-button { 23 | text-align: center; 24 | font-size: 18px; 25 | line-height: 1 !important; 26 | background-color: #32373c; 27 | border: none; 28 | border-radius: 50px; 29 | box-shadow: none; 30 | color: #fff; 31 | cursor: pointer; 32 | padding: .6em 1em; 33 | text-decoration: none; 34 | word-break: break-word; 35 | transition: .3s ease; 36 | display: inline-block; 37 | 38 | &:hover { 39 | box-shadow: inset 0 0 200px rgba(255, 255, 255, 0.15); 40 | } 41 | } 42 | 43 | .ab-button-shape-square, 44 | input[type="submit"].ab-button-shape-square { 45 | border-radius: 0; 46 | } 47 | 48 | .ab-button-shape-rounded, 49 | input[type="submit"].ab-button-shape-rounded { 50 | border-radius: 5px; 51 | } 52 | 53 | .ab-button-shape-circular, 54 | input[type="submit"].ab-button-shape-circular { 55 | border-radius: 100px; 56 | } 57 | 58 | .ab-button-size-small, 59 | input[type="submit"].ab-button-size-small { 60 | font-size: 14px; 61 | } 62 | 63 | .ab-button-size-medium, 64 | input[type="submit"].ab-button-size-medium { 65 | font-size: 20px; 66 | } 67 | 68 | .ab-button-size-large, 69 | input[type="submit"].ab-button-size-large { 70 | font-size: 26px; 71 | padding: .8em 1.2em; 72 | } 73 | 74 | .ab-button-size-extralarge, 75 | input[type="submit"].ab-button-size-extralarge { 76 | font-size: 34px; 77 | padding: .8em 1.2em; 78 | } 79 | 80 | .ab-button-right { 81 | transform: translateX(-100%); 82 | left: 100%; 83 | position: relative; 84 | } 85 | 86 | .ab-button-center { 87 | margin: 0 auto; 88 | } 89 | -------------------------------------------------------------------------------- /src/blocks/block-column-inner/components/edit.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Internal dependencies 3 | */ 4 | import Inspector from './inspector'; 5 | import Column from './column'; 6 | import classnames from 'classnames'; 7 | 8 | /** 9 | * WordPress dependencies 10 | */ 11 | const { __ } = wp.i18n; 12 | const { compose } = wp.compose; 13 | const { Component } = wp.element; 14 | const { Toolbar } = wp.components; 15 | const { 16 | AlignmentToolbar, 17 | BlockControls, 18 | InnerBlocks, 19 | withColors, 20 | } = wp.blockEditor; 21 | 22 | class Edit extends Component { 23 | constructor() { 24 | super( ...arguments ); 25 | } 26 | 27 | render() { 28 | const { attributes, setAttributes } = this.props; 29 | 30 | const toolbarControls = [ 31 | { 32 | icon: 'arrow-up-alt2', 33 | title: __( 'Vertical Align Top', 'atomic-blocks' ), 34 | isActive: 'top' === attributes.columnVerticalAlignment, 35 | onClick: () => 36 | setAttributes( { columnVerticalAlignment: 'top' } ), 37 | }, 38 | { 39 | icon: 'minus', 40 | title: __( 'Vertical Align Middle', 'atomic-blocks' ), 41 | isActive: 'center' === attributes.columnVerticalAlignment, 42 | onClick: () => 43 | setAttributes( { columnVerticalAlignment: 'center' } ), 44 | }, 45 | { 46 | icon: 'arrow-down-alt2', 47 | title: __( 'Vertical Align Bottom', 'atomic-blocks' ), 48 | isActive: 'bottom' === attributes.columnVerticalAlignment, 49 | onClick: () => 50 | setAttributes( { columnVerticalAlignment: 'bottom' } ), 51 | }, 52 | ]; 53 | 54 | return [ 55 | 56 | { 59 | setAttributes( { textAlign: value } ); 60 | } } 61 | /> 62 | 63 | , 64 | , 65 | 72 | 77 | , 78 | ]; 79 | } 80 | } 81 | 82 | export default compose( [ 83 | withColors( 'backgroundColor', { textColor: 'color' } ), 84 | ] )( Edit ); 85 | -------------------------------------------------------------------------------- /src/blocks/block-column-inner/components/save.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Internal dependencies. 3 | */ 4 | import Column from './column'; 5 | 6 | /** 7 | * WordPress dependencies. 8 | */ 9 | const { Component } = wp.element; 10 | const { InnerBlocks } = wp.blockEditor; 11 | 12 | export default class Save extends Component { 13 | render() { 14 | const { attributes } = this.props; 15 | 16 | return ( 17 | 29 | 30 | 31 | ); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/blocks/block-column-inner/deprecated/1.7.1/components/save.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Internal dependencies. 3 | */ 4 | import Column_1_7_1 from './column'; 5 | 6 | /** 7 | * WordPress dependencies. 8 | */ 9 | const { Component } = wp.element; 10 | const { InnerBlocks } = wp.blockEditor; 11 | 12 | export default class Save_1_7_1 extends Component { 13 | render() { 14 | const { attributes } = this.props; 15 | 16 | return ( 17 | 29 | 30 | 31 | ); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/blocks/block-column-inner/deprecated/deprecated.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Column component deprecations. 3 | */ 4 | 5 | import Save_1_7_1 from './1.7.1/components/save'; 6 | 7 | export const Column_Inner_1_7_1_attributes = { 8 | backgroundColor: { 9 | type: 'string', 10 | }, 11 | customBackgroundColor: { 12 | type: 'string', 13 | }, 14 | textColor: { 15 | type: 'string', 16 | }, 17 | customTextColor: { 18 | type: 'string', 19 | }, 20 | textAlign: { 21 | type: 'string', 22 | }, 23 | marginSync: { 24 | type: 'boolean', 25 | default: false, 26 | }, 27 | marginUnit: { 28 | type: 'string', 29 | default: 'px', 30 | }, 31 | margin: { 32 | type: 'number', 33 | default: 0, 34 | }, 35 | marginTop: { 36 | type: 'number', 37 | default: 0, 38 | }, 39 | marginBottom: { 40 | type: 'number', 41 | default: 0, 42 | }, 43 | paddingSync: { 44 | type: 'boolean', 45 | default: false, 46 | }, 47 | paddingUnit: { 48 | type: 'string', 49 | default: 'px', 50 | }, 51 | padding: { 52 | type: 'number', 53 | default: 0, 54 | }, 55 | paddingTop: { 56 | type: 'number', 57 | default: 0, 58 | }, 59 | paddingRight: { 60 | type: 'number', 61 | default: 0, 62 | }, 63 | paddingBottom: { 64 | type: 'number', 65 | default: 0, 66 | }, 67 | paddingLeft: { 68 | type: 'number', 69 | default: 0, 70 | }, 71 | columnVerticalAlignment: { 72 | type: 'string', 73 | }, 74 | }; 75 | 76 | export const Column_Inner_1_7_1_save = ( props ) => { 77 | return ; 78 | }; 79 | 80 | const deprecated = [ 81 | // Version 1.7.1 82 | { 83 | attributes: Column_Inner_1_7_1_attributes, 84 | save: Column_Inner_1_7_1_save, 85 | }, 86 | ]; 87 | 88 | export default deprecated; 89 | -------------------------------------------------------------------------------- /src/blocks/block-column/components/column-layouts.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Column layouts available for each column option. 3 | */ 4 | 5 | import icons from './icons'; 6 | 7 | const { __ } = wp.i18n; 8 | 9 | const columnLayouts = { 10 | /* 1 column layout. */ 11 | 1: [ 12 | { 13 | name: __( '1 Column', 'atomic-blocks' ), 14 | key: 'ab-1-col-equal', 15 | col: 1, 16 | icon: icons.oneEqual, 17 | }, 18 | ], 19 | 20 | /* 2 column layouts. */ 21 | 2: [ 22 | { 23 | name: __( '2 Columns - 50/50', 'atomic-blocks' ), 24 | key: 'ab-2-col-equal', 25 | col: 2, 26 | icon: icons.twoEqual, 27 | }, 28 | { 29 | name: __( '2 Columns - 75/25', 'atomic-blocks' ), 30 | key: 'ab-2-col-wideleft', 31 | col: 2, 32 | icon: icons.twoLeftWide, 33 | }, 34 | { 35 | name: __( '2 Columns - 25/75', 'atomic-blocks' ), 36 | key: 'ab-2-col-wideright', 37 | col: 2, 38 | icon: icons.twoRightWide, 39 | }, 40 | ], 41 | 42 | /* 3 column layouts. */ 43 | 3: [ 44 | { 45 | name: __( '3 Columns - 33/33/33', 'atomic-blocks' ), 46 | key: 'ab-3-col-equal', 47 | col: 3, 48 | icon: icons.threeEqual, 49 | }, 50 | { 51 | name: __( '3 Columns - 25/50/25', 'atomic-blocks' ), 52 | key: 'ab-3-col-widecenter', 53 | col: 3, 54 | icon: icons.threeWideCenter, 55 | }, 56 | { 57 | name: __( '3 Columns - 50/25/25', 'atomic-blocks' ), 58 | key: 'ab-3-col-wideleft', 59 | col: 3, 60 | icon: icons.threeWideLeft, 61 | }, 62 | { 63 | name: __( '3 Columns - 25/25/50', 'atomic-blocks' ), 64 | key: 'ab-3-col-wideright', 65 | col: 3, 66 | icon: icons.threeWideRight, 67 | }, 68 | ], 69 | 70 | /* 4 column layouts. */ 71 | 4: [ 72 | { 73 | name: __( '4 Columns - 25/25/25/25', 'atomic-blocks' ), 74 | key: 'ab-4-col-equal', 75 | col: 4, 76 | icon: icons.fourEqual, 77 | }, 78 | { 79 | name: __( '4 Columns - 40/20/20/20', 'atomic-blocks' ), 80 | key: 'ab-4-col-wideleft', 81 | col: 4, 82 | icon: icons.fourLeft, 83 | }, 84 | { 85 | name: __( '4 Columns - 20/20/20/40', 'atomic-blocks' ), 86 | key: 'ab-4-col-wideright', 87 | col: 4, 88 | icon: icons.fourRight, 89 | }, 90 | ], 91 | 92 | /* 5 column layouts. */ 93 | 5: [ 94 | { 95 | name: __( '5 Columns', 'atomic-blocks' ), 96 | key: 'ab-5-col-equal', 97 | col: 5, 98 | icon: icons.fiveEqual, 99 | }, 100 | ], 101 | 102 | /* 6 column layouts. */ 103 | 6: [ 104 | { 105 | name: __( '6 Columns', 'atomic-blocks' ), 106 | key: 'ab-6-col-equal', 107 | col: 6, 108 | icon: icons.sixEqual, 109 | }, 110 | ], 111 | }; 112 | 113 | export default columnLayouts; 114 | -------------------------------------------------------------------------------- /src/blocks/block-column/components/save.js: -------------------------------------------------------------------------------- 1 | /** 2 | * External dependencies. 3 | */ 4 | import classnames from 'classnames'; 5 | import Columns from './column-wrap'; 6 | 7 | /** 8 | * WordPress dependencies. 9 | */ 10 | const { Component } = wp.element; 11 | const { InnerBlocks } = wp.blockEditor; 12 | 13 | export default class Save extends Component { 14 | render() { 15 | const { attributes } = this.props; 16 | 17 | const className = classnames( [ 18 | 'ab-layout-column-wrap', 19 | 'ab-block-layout-column-gap-' + attributes.columnsGap, 20 | attributes.responsiveToggle ? 'ab-is-responsive-column' : null, 21 | ] ); 22 | 23 | return ( 24 | 36 |
44 | 45 |
46 |
47 | ); 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/blocks/block-container/components/container.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Container wrapper 3 | */ 4 | 5 | // Setup the block 6 | const { Component } = wp.element; 7 | 8 | // Import block dependencies and components 9 | import classnames from 'classnames'; 10 | 11 | /** 12 | * Create a Button wrapper Component 13 | */ 14 | export default class Container extends Component { 15 | constructor( props ) { 16 | super( ...arguments ); 17 | } 18 | 19 | render() { 20 | // Setup the attributes 21 | const { 22 | attributes: { 23 | containerBackgroundColor, 24 | containerAlignment, 25 | containerPaddingTop, 26 | containerPaddingRight, 27 | containerPaddingBottom, 28 | containerPaddingLeft, 29 | containerMarginTop, 30 | containerMarginBottom, 31 | containerWidth, 32 | containerMaxWidth, 33 | containerImgURL, 34 | containerImgAlt, 35 | containerDimRatio, 36 | }, 37 | } = this.props; 38 | 39 | const styles = { 40 | backgroundColor: containerBackgroundColor 41 | ? containerBackgroundColor 42 | : undefined, 43 | textAlign: containerAlignment ? containerAlignment : undefined, 44 | paddingLeft: containerPaddingLeft 45 | ? `${ containerPaddingLeft }%` 46 | : undefined, 47 | paddingRight: containerPaddingRight 48 | ? `${ containerPaddingRight }%` 49 | : undefined, 50 | paddingBottom: containerPaddingBottom 51 | ? `${ containerPaddingBottom }%` 52 | : undefined, 53 | paddingTop: containerPaddingTop 54 | ? `${ containerPaddingTop }%` 55 | : undefined, 56 | marginTop: containerMarginTop 57 | ? `${ containerMarginTop }%` 58 | : undefined, 59 | marginBottom: containerMarginBottom 60 | ? `${ containerMarginBottom }%` 61 | : undefined, 62 | }; 63 | 64 | const className = classnames( 65 | [ this.props.className, 'ab-block-container' ], 66 | { 67 | [ 'align' + containerWidth ]: containerWidth, 68 | } 69 | ); 70 | 71 | return ( 72 |
76 |
77 | { containerImgURL && !! containerImgURL.length && ( 78 |
79 | { 91 |
92 | ) } 93 | 94 |
102 | { this.props.children } 103 |
104 |
105 |
106 | ); 107 | } 108 | } 109 | 110 | function dimRatioToClass( ratio ) { 111 | return 0 === ratio || 50 === ratio 112 | ? null 113 | : 'has-background-dim-' + 10 * Math.round( ratio / 10 ); 114 | } 115 | -------------------------------------------------------------------------------- /src/blocks/block-container/deprecated/1.4.23/components/container.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Container wrapper 3 | */ 4 | 5 | // Setup the block 6 | const { Component } = wp.element; 7 | 8 | // Import block dependencies and components 9 | import classnames from 'classnames'; 10 | 11 | /** 12 | * Create a Button wrapper Component 13 | */ 14 | export default class Container_1_4_23 extends Component { 15 | constructor( props ) { 16 | super( ...arguments ); 17 | } 18 | 19 | render() { 20 | // Setup the attributes 21 | const { 22 | attributes: { 23 | containerBackgroundColor, 24 | containerAlignment, 25 | containerPaddingTop, 26 | containerPaddingRight, 27 | containerPaddingBottom, 28 | containerPaddingLeft, 29 | containerMarginTop, 30 | containerMarginBottom, 31 | containerWidth, 32 | containerMaxWidth, 33 | }, 34 | } = this.props; 35 | 36 | const className = classnames( 37 | [ this.props.className, 'ab-block-container' ], 38 | { 39 | [ 'align' + containerWidth ]: containerWidth, 40 | } 41 | ); 42 | 43 | return ( 44 |
57 | { this.props.children } 58 |
59 | ); 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /src/blocks/block-container/deprecated/2.3.0/components/container.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Container wrapper 3 | */ 4 | 5 | // Setup the block 6 | const { Component } = wp.element; 7 | 8 | // Import block dependencies and components 9 | import classnames from 'classnames'; 10 | 11 | /** 12 | * Create a Button wrapper Component 13 | */ 14 | export default class Container_2_3_0 extends Component { 15 | constructor( props ) { 16 | super( ...arguments ); 17 | } 18 | 19 | render() { 20 | // Setup the attributes 21 | const { 22 | attributes: { 23 | containerBackgroundColor, 24 | containerAlignment, 25 | containerPaddingTop, 26 | containerPaddingRight, 27 | containerPaddingBottom, 28 | containerPaddingLeft, 29 | containerMarginTop, 30 | containerMarginBottom, 31 | containerWidth, 32 | containerMaxWidth, 33 | containerImgURL, 34 | containerImgAlt, 35 | containerDimRatio, 36 | }, 37 | } = this.props; 38 | 39 | const styles = { 40 | backgroundColor: containerBackgroundColor 41 | ? containerBackgroundColor 42 | : undefined, 43 | textAlign: containerAlignment ? containerAlignment : undefined, 44 | paddingLeft: containerPaddingLeft 45 | ? `${ containerPaddingLeft }%` 46 | : undefined, 47 | paddingRight: containerPaddingRight 48 | ? `${ containerPaddingRight }%` 49 | : undefined, 50 | paddingBottom: containerPaddingBottom 51 | ? `${ containerPaddingBottom }%` 52 | : undefined, 53 | paddingTop: containerPaddingTop 54 | ? `${ containerPaddingTop }%` 55 | : undefined, 56 | marginTop: containerMarginTop 57 | ? `${ containerMarginTop }%` 58 | : undefined, 59 | marginBottom: containerMarginBottom 60 | ? `${ containerMarginBottom }%` 61 | : undefined, 62 | }; 63 | 64 | const className = classnames( 65 | [ this.props.className, 'ab-block-container' ], 66 | { 67 | [ 'align' + containerWidth ]: containerWidth, 68 | } 69 | ); 70 | 71 | return ( 72 |
76 |
77 | { containerImgURL && !! containerImgURL.length && ( 78 |
79 | { 91 |
92 | ) } 93 | 94 |
100 | { this.props.children } 101 |
102 |
103 |
104 | ); 105 | } 106 | } 107 | 108 | function dimRatioToClass( ratio ) { 109 | return 0 === ratio || 50 === ratio 110 | ? null 111 | : 'has-background-dim-' + 10 * Math.round( ratio / 10 ); 112 | } 113 | -------------------------------------------------------------------------------- /src/blocks/block-container/index.php: -------------------------------------------------------------------------------- 1 | 61 | { this.props.children } 62 | 63 | ); 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /src/blocks/block-cta/deprecated/1.4.21/components/cta.js: -------------------------------------------------------------------------------- 1 | /** 2 | * CTA Wrapper 3 | */ 4 | 5 | // Setup the block 6 | const { Component } = wp.element; 7 | 8 | // Import block dependencies and components 9 | import classnames from 'classnames'; 10 | 11 | /** 12 | * Create a CallToAction wrapper Component 13 | */ 14 | export default class CallToAction_1_4_21 extends Component { 15 | constructor( props ) { 16 | super( ...arguments ); 17 | } 18 | 19 | render() { 20 | // Setup the attributes 21 | const { 22 | attributes: { 23 | buttonText, 24 | buttonUrl, 25 | buttonAlignment, 26 | buttonBackgroundColor, 27 | buttonTextColor, 28 | buttonSize, 29 | buttonShape, 30 | buttonTarget, 31 | ctaTitle, 32 | ctaText, 33 | ctaTitleFontSize, 34 | ctaTextFontSize, 35 | ctaWidth, 36 | ctaBackgroundColor, 37 | ctaTextColor, 38 | }, 39 | } = this.props; 40 | 41 | return ( 42 |
54 | { this.props.children } 55 |
56 | ); 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /src/blocks/block-cta/deprecated/1.4.22/components/cta.js: -------------------------------------------------------------------------------- 1 | /** 2 | * CTA Wrapper 3 | */ 4 | 5 | // Setup the block 6 | const { Component } = wp.element; 7 | 8 | // Import block dependencies and components 9 | import classnames from 'classnames'; 10 | 11 | /** 12 | * Create a CallToAction wrapper Component 13 | */ 14 | export default class CallToAction_1_4_22 extends Component { 15 | constructor( props ) { 16 | super( ...arguments ); 17 | } 18 | 19 | render() { 20 | // Setup the attributes 21 | const { 22 | attributes: { 23 | buttonText, 24 | buttonUrl, 25 | buttonAlignment, 26 | buttonBackgroundColor, 27 | buttonTextColor, 28 | buttonSize, 29 | buttonShape, 30 | buttonTarget, 31 | ctaTitle, 32 | ctaText, 33 | ctaTitleFontSize, 34 | ctaTextFontSize, 35 | ctaWidth, 36 | ctaBackgroundColor, 37 | ctaTextColor, 38 | }, 39 | } = this.props; 40 | 41 | const className = classnames( 42 | [ this.props.className, 'ab-block-cta' ], 43 | { 44 | [ 'ab-font-size-' + ctaTextFontSize ]: ctaTextFontSize, 45 | } 46 | ); 47 | 48 | const styles = { 49 | backgroundColor: ctaBackgroundColor 50 | ? ctaBackgroundColor 51 | : undefined, 52 | textAlign: buttonAlignment ? buttonAlignment : undefined, 53 | }; 54 | 55 | return ( 56 |
60 | { this.props.children } 61 |
62 | ); 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /src/blocks/block-cta/deprecated/1.5.2/components/cta.js: -------------------------------------------------------------------------------- 1 | /** 2 | * CTA Wrapper 3 | */ 4 | 5 | // Setup the block 6 | const { Component } = wp.element; 7 | 8 | // Import block dependencies and components 9 | import classnames from 'classnames'; 10 | 11 | /** 12 | * Create a CallToAction wrapper Component 13 | */ 14 | export default class CallToAction_1_5_2 extends Component { 15 | constructor( props ) { 16 | super( ...arguments ); 17 | } 18 | 19 | render() { 20 | // Setup the attributes 21 | const { 22 | attributes: { 23 | buttonText, 24 | buttonUrl, 25 | buttonAlignment, 26 | buttonBackgroundColor, 27 | buttonTextColor, 28 | buttonSize, 29 | buttonShape, 30 | buttonTarget, 31 | ctaTitle, 32 | ctaText, 33 | ctaTitleFontSize, 34 | ctaTextFontSize, 35 | ctaWidth, 36 | ctaBackgroundColor, 37 | ctaTextColor, 38 | }, 39 | } = this.props; 40 | 41 | const className = classnames( 42 | [ this.props.className, 'ab-block-cta' ], 43 | { 44 | [ 'ab-font-size-' + ctaTextFontSize ]: ctaTextFontSize, 45 | [ 'align' + ctaWidth ]: ctaWidth, 46 | } 47 | ); 48 | 49 | const styles = { 50 | backgroundColor: ctaBackgroundColor 51 | ? ctaBackgroundColor 52 | : undefined, 53 | textAlign: buttonAlignment ? buttonAlignment : undefined, 54 | }; 55 | 56 | return ( 57 |
61 | { this.props.children } 62 |
63 | ); 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /src/blocks/block-cta/styles/editor.scss: -------------------------------------------------------------------------------- 1 | /** 2 | * Editor styles for the admin 3 | */ 4 | 5 | .ab-block-cta { 6 | margin-bottom: 0; 7 | } 8 | 9 | .block-editor-block-list__layout [data-type="atomic-blocks/ab-cta"] { 10 | margin-bottom: 1.2em; 11 | } 12 | 13 | .ab-cta-button { 14 | .blocks-button__inline-link .editor-url-input { 15 | display: inline-block; 16 | width: auto; 17 | } 18 | 19 | .blocks-button__inline-link .components-button { 20 | display: inline-block; 21 | padding: 8px; 22 | } 23 | 24 | .blocks-button__inline-link svg { 25 | vertical-align: middle; 26 | margin-right: 8px; 27 | } 28 | } 29 | 30 | .ab-block-cta h2.editor-rich-text__tinymce.mce-content-body { 31 | line-height: 1.2; 32 | } 33 | 34 | .ab-cta-inspector-media.components-button { 35 | padding: 8px; 36 | } 37 | -------------------------------------------------------------------------------- /src/blocks/block-drop-cap/components/dropcap.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Testimonial Block Wrapper 3 | */ 4 | 5 | // Setup the block 6 | const { Component } = wp.element; 7 | 8 | // Import block dependencies and components 9 | import classnames from 'classnames'; 10 | 11 | /** 12 | * Create a drop cap wrapper Component 13 | */ 14 | export default class DropCap extends Component { 15 | constructor( props ) { 16 | super( ...arguments ); 17 | } 18 | 19 | render() { 20 | // Setup the attributes 21 | const { 22 | dropCapAlignment, 23 | dropCapTextColor, 24 | dropCapFontSize, 25 | dropCapStyle, 26 | } = this.props.attributes; 27 | 28 | return ( 29 |
41 | { this.props.children } 42 |
43 | ); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/blocks/block-drop-cap/components/icons.js: -------------------------------------------------------------------------------- 1 | const icons = {}; 2 | 3 | icons.upload = ( 4 | 10 | 11 | 12 | 13 | 14 | 15 | ); 16 | 17 | export default icons; 18 | -------------------------------------------------------------------------------- /src/blocks/block-drop-cap/components/inspector.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Inspector Controls 3 | */ 4 | 5 | /** 6 | * Internal dependencies. 7 | */ 8 | import RenderSettingControl from '../../../utils/components/settings/renderSettingControl'; 9 | 10 | // Setup the block 11 | const { __ } = wp.i18n; 12 | const { Component } = wp.element; 13 | 14 | // Import block components 15 | const { InspectorControls } = wp.blockEditor; 16 | 17 | // Import Inspector components 18 | const { RangeControl, SelectControl, PanelBody } = wp.components; 19 | 20 | /** 21 | * Create an Inspector Controls wrapper Component 22 | */ 23 | export default class Inspector extends Component { 24 | constructor( props ) { 25 | super( ...arguments ); 26 | } 27 | 28 | render() { 29 | // Setup the attributes 30 | const { dropCapFontSize, dropCapStyle } = this.props.attributes; 31 | 32 | // Drop cap style options 33 | const dropCapOptions = [ 34 | { value: 'ab-drop-cap-letter', label: __( 'Letter' ) }, 35 | { value: 'ab-drop-cap-square', label: __( 'Square' ) }, 36 | { value: 'ab-drop-cap-border', label: __( 'Border' ) }, 37 | ]; 38 | 39 | return ( 40 | 41 | 42 | 43 | 47 | this.props.setAttributes( { 48 | dropCapFontSize: value, 49 | } ) 50 | } 51 | min={ 1 } 52 | max={ 6 } 53 | step={ 1 } 54 | /> 55 | 56 | 57 | 58 | 66 | this.props.setAttributes( { 67 | dropCapStyle: value, 68 | } ) 69 | } 70 | /> 71 | 72 | 73 | 74 | ); 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /src/blocks/block-drop-cap/styles/editor.scss: -------------------------------------------------------------------------------- 1 | /** 2 | * Editor styles for the admin 3 | */ 4 | 5 | .ab-block-drop-cap { 6 | .ab-drop-cap-text:not( :focus ):first-letter { 7 | float: left; 8 | font-size: 75px; 9 | line-height: .7em; 10 | margin-top: .15em; 11 | margin-right: 25px; 12 | margin-bottom: 25px; 13 | font-weight: bold; 14 | text-transform: uppercase; 15 | } 16 | 17 | &.ab-drop-cap-square .ab-drop-cap-text:not( :focus ):first-letter { 18 | background: #32373c; 19 | color: #fff; 20 | padding: .2em; 21 | } 22 | 23 | &.ab-drop-cap-border .ab-drop-cap-text:not( :focus ):first-letter { 24 | color: #32373c; 25 | padding: .2em; 26 | border: solid 4px; 27 | } 28 | 29 | /* Font size styles */ 30 | @media only screen and (min-width: 600px) { 31 | .ab-font-size-1.ab-drop-cap-text:not( :focus ):first-letter { 32 | font-size: 75px; 33 | } 34 | 35 | .ab-font-size-2.ab-drop-cap-text:not( :focus ):first-letter { 36 | font-size: 85px; 37 | } 38 | 39 | .ab-font-size-3.ab-drop-cap-text:not( :focus ):first-letter { 40 | font-size: 95px; 41 | } 42 | 43 | .ab-font-size-4.ab-drop-cap-text:not( :focus ):first-letter { 44 | font-size: 105px; 45 | } 46 | 47 | .ab-font-size-5.ab-drop-cap-text:not( :focus ):first-letter { 48 | font-size: 115px; 49 | } 50 | 51 | .ab-font-size-6.ab-drop-cap-text:not( :focus ):first-letter { 52 | font-size: 125px; 53 | } 54 | } 55 | } -------------------------------------------------------------------------------- /src/blocks/block-drop-cap/styles/style.scss: -------------------------------------------------------------------------------- 1 | /** 2 | * Drop cap styles 3 | * Loads on front end and back end 4 | */ 5 | 6 | .entry-content .ab-block-drop-cap { 7 | .ab-drop-cap-text p:first-letter { 8 | float: left; 9 | font-size: 75px; 10 | line-height: .7em; 11 | margin-top: .15em; 12 | margin-right: 25px; 13 | margin-bottom: 25px; 14 | font-weight: bold; 15 | text-transform: uppercase; 16 | } 17 | 18 | &.ab-drop-cap-square .ab-drop-cap-text p:first-letter { 19 | background: #32373c; 20 | color: #fff; 21 | padding: .2em; 22 | } 23 | 24 | &.ab-drop-cap-border .ab-drop-cap-text p:first-letter { 25 | color: #32373c; 26 | padding: .2em; 27 | border: solid 4px; 28 | } 29 | 30 | /* Font size styles */ 31 | @media only screen and (min-width: 600px) { 32 | &.ab-font-size-1 .ab-drop-cap-text:first-letter { 33 | font-size: 75px; 34 | } 35 | 36 | &.ab-font-size-2 .ab-drop-cap-text:first-letter { 37 | font-size: 85px; 38 | } 39 | 40 | &.ab-font-size-3 .ab-drop-cap-text:first-letter { 41 | font-size: 95px; 42 | } 43 | 44 | &.ab-font-size-4 .ab-drop-cap-text:first-letter { 45 | font-size: 105px; 46 | } 47 | 48 | &.ab-font-size-5 .ab-drop-cap-text:first-letter { 49 | font-size: 115px; 50 | } 51 | 52 | &.ab-font-size-6 .ab-drop-cap-text p:first-letter { 53 | font-size: 125px; 54 | } 55 | } 56 | } 57 | 58 | .ab-block-drop-cap { 59 | &:before, 60 | &:after { 61 | content: ''; 62 | display: table; 63 | } 64 | 65 | &:after { 66 | clear: both; 67 | } 68 | 69 | a { 70 | color: inherit; 71 | box-shadow: 0 -1px 0 inset; 72 | text-decoration: none; 73 | 74 | &:hover { 75 | color: inherit; 76 | box-shadow: 0 -2px 0 inset; 77 | } 78 | } 79 | } -------------------------------------------------------------------------------- /src/blocks/block-layout/components/edit.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Edit component. 3 | */ 4 | 5 | /** 6 | * Import dependencies. 7 | */ 8 | import LayoutModal from './layout/layout-modal'; 9 | import { LayoutsContext } from './layouts-provider'; 10 | 11 | /** 12 | * WordPress dependencies. 13 | */ 14 | const { __ } = wp.i18n; 15 | const { Placeholder } = wp.components; 16 | const { Component, Fragment } = wp.element; 17 | const { BlockControls, BlockAlignmentToolbar } = wp.blockEditor; 18 | 19 | export default class Edit extends Component { 20 | constructor( props ) { 21 | super( ...arguments ); 22 | } 23 | 24 | render() { 25 | const { attributes, setAttributes, clientId } = this.props; 26 | 27 | /* Placeholder with layout modal */ 28 | return [ 29 | 30 | 31 | setAttributes( { align } ) } 34 | controls={ [] } 35 | /> 36 | 37 | 47 | 52 | { ( context ) => ( 53 | 57 | ) } 58 | 59 | 60 | , 61 | ]; 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /src/blocks/block-layout/components/layout/layout-library-item-card.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Layout Library Card Item. 3 | */ 4 | 5 | /** 6 | * Dependencies. 7 | */ 8 | import classnames from 'classnames'; 9 | 10 | /** 11 | * WordPress dependencies. 12 | */ 13 | const { __ } = wp.i18n; 14 | const { Component, Fragment } = wp.element; 15 | const { Button, Dashicon, Tooltip } = wp.components; 16 | 17 | export default class LayoutLibraryItemCard extends Component { 18 | constructor() { 19 | super( ...arguments ); 20 | } 21 | 22 | render() { 23 | return ( 24 | 25 |
29 |
30 |
31 | 44 | 45 |
46 |
47 | { this.props.name } 48 | { 49 | 64 | 85 | 86 | } 87 |
88 |
89 |
90 |
91 |
92 |
93 | ); 94 | } 95 | } 96 | -------------------------------------------------------------------------------- /src/blocks/block-layout/components/layout/layout-library-item-list.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Layout Library Card Item. 3 | */ 4 | 5 | /** 6 | * Dependencies. 7 | */ 8 | 9 | /** 10 | * WordPress dependencies. 11 | */ 12 | const { __ } = wp.i18n; 13 | const { addQueryArgs } = wp.url; 14 | const { Component, Fragment } = wp.element; 15 | 16 | export default class LayoutLibraryItemList extends Component { 17 | constructor() { 18 | super( ...arguments ); 19 | } 20 | 21 | render() { 22 | const postIdString = this.props.itemKey.match( /\d+/g ); 23 | const postID = postIdString[ 0 ]; 24 | 25 | return ( 26 | 27 | 56 | 57 | ); 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /src/blocks/block-layout/components/layout/layout-library-item.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Layout Library Section and Layout Item. 3 | */ 4 | 5 | /** 6 | * Dependencies. 7 | */ 8 | import LayoutLibraryItemCard from './layout-library-item-card'; 9 | import LayoutLibraryItemList from './layout-library-item-list'; 10 | 11 | /** 12 | * WordPress dependencies. 13 | */ 14 | const { compose } = wp.compose; 15 | const { rawHandler } = wp.blocks; 16 | const { withSelect, withDispatch } = wp.data; 17 | const { Component, Fragment } = wp.element; 18 | 19 | class LayoutLibraryItem extends Component { 20 | constructor() { 21 | super( ...arguments ); 22 | } 23 | 24 | render() { 25 | return ( 26 | 27 | { /* Insert the selected layout. */ } 28 | { 'ab-layout-tab-reusable-blocks' !== this.props.currentTab ? ( 29 | 30 | ) : ( 31 | 32 | ) } 33 | 34 | ); 35 | } 36 | } 37 | 38 | export default compose( 39 | /** 40 | * Use rawHandler to parse html layouts to blocks 41 | * See https://git.io/fjqGc for details 42 | */ 43 | withSelect( ( select, { clientId } ) => { 44 | const { getBlock } = select( 'core/block-editor' ); 45 | const { canUserUseUnfilteredHTML } = select( 'core/editor' ); 46 | const block = getBlock( clientId ); 47 | return { 48 | block, 49 | canUserUseUnfilteredHTML: canUserUseUnfilteredHTML(), 50 | }; 51 | } ), 52 | withDispatch( ( dispatch, { block, canUserUseUnfilteredHTML } ) => ( { 53 | import: ( blockLayout ) => 54 | dispatch( 'core/block-editor' ).replaceBlocks( 55 | block.clientId, 56 | rawHandler( { 57 | HTML: blockLayout, 58 | mode: 'BLOCKS', 59 | canUserUseUnfilteredHTML, 60 | } ) 61 | ), 62 | } ) ) 63 | )( LayoutLibraryItem ); 64 | -------------------------------------------------------------------------------- /src/blocks/block-layout/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * BLOCK: Atomic Blocks Layout 3 | */ 4 | 5 | /** 6 | * Import dependencies. 7 | */ 8 | import Edit from './components/edit'; 9 | import LayoutsProvider from './components/layouts-provider'; 10 | import './styles/style.scss'; 11 | import './styles/editor.scss'; 12 | 13 | /** 14 | * WordPress dependencies. 15 | */ 16 | const { __ } = wp.i18n; 17 | const { registerBlockType } = wp.blocks; 18 | 19 | /** 20 | * Register the Layout block 21 | */ 22 | registerBlockType( 'atomic-blocks/ab-layouts', { 23 | title: __( 'Layouts', 'atomic-blocks' ), 24 | description: __( 25 | 'Add a pre-defined section or layout to posts and pages.', 26 | 'atomic-blocks' 27 | ), 28 | icon: 'layout', 29 | category: 'atomic-blocks', 30 | keywords: [ 31 | __( 'layout', 'atomic-blocks' ), 32 | __( 'column', 'atomic-blocks' ), 33 | __( 'section', 'atomic-blocks' ), 34 | ], 35 | 36 | /* Render the block components. */ 37 | edit: ( props ) => { 38 | return ( 39 | 40 | 41 | 42 | ); 43 | }, 44 | 45 | /* Save the block markup. */ 46 | save: () => { 47 | return null; 48 | }, 49 | } ); 50 | 51 | /** 52 | * Add a AB Layout button to the toolbar. 53 | */ 54 | document.addEventListener( 'DOMContentLoaded', appendImportButton ); 55 | 56 | /** 57 | * Build the layout inserter button. 58 | */ 59 | function appendImportButton() { 60 | const toolbar = document.querySelector( '.edit-post-header-toolbar' ); 61 | if ( ! toolbar ) { 62 | return; 63 | } 64 | const buttonDiv = document.createElement( 'div' ); 65 | let html = '
'; 66 | html += ``; 73 | html += '
'; 74 | buttonDiv.innerHTML = html; 75 | toolbar.appendChild( buttonDiv ); 76 | document 77 | .getElementById( 'abLayoutInsertButton' ) 78 | .addEventListener( 'click', abInsertLayout ); 79 | } 80 | 81 | /** 82 | * Add the AB Layout block on click. 83 | */ 84 | function abInsertLayout() { 85 | const block = wp.blocks.createBlock( 'atomic-blocks/ab-layouts' ); 86 | wp.data.dispatch( 'core/block-editor' ).insertBlocks( block ); 87 | } 88 | -------------------------------------------------------------------------------- /src/blocks/block-layout/styles/style.scss: -------------------------------------------------------------------------------- 1 | /** 2 | * Layout styles 3 | * Loads on front end and back end 4 | */ 5 | 6 | .ab-layout-column-button .ab-block-button { 7 | margin-bottom: 0; 8 | } 9 | 10 | .ab-layout-selector-group { 11 | margin-top: 10px; 12 | } 13 | 14 | .ab-layout-selector { 15 | display: inline-block; 16 | margin: 0 5px; 17 | 18 | button.ab-layout-selector-button { 19 | padding: 15px; 20 | height: auto; 21 | border-radius: 5px; 22 | background: #fff; 23 | 24 | &:hover { 25 | background: #fff; 26 | } 27 | } 28 | 29 | button.components-button.is-button:last-child { 30 | border-radius: 5px; 31 | } 32 | } 33 | 34 | .ab-toolbar-insert-layout-button { 35 | margin-right: 3px; 36 | } 37 | 38 | /** 39 | * Layout style modifications 40 | * This probably belongs in a theme! 41 | */ 42 | 43 | .ab-layout-team-1 { 44 | .ab-profile-column { 45 | flex: 100%; 46 | } 47 | .ab-social-links { 48 | padding-top: 25px; 49 | } 50 | } 51 | 52 | .ab-layout-hero-cover { 53 | .wp-block-cover__inner-container { 54 | max-width: 800px; 55 | } 56 | 57 | h2, h3, h4 { 58 | max-width: 100%; 59 | } 60 | } 61 | 62 | .ab-white-text, 63 | .editor-styles-wrapper [data-type="core/heading"] .ab-white-text { 64 | color: #fff; 65 | } 66 | 67 | .ab-layout-landing-2 { 68 | .ab-block-profile { 69 | padding: 0; 70 | text-align: center; 71 | } 72 | .ab-block-profile .ab-profile-avatar-wrap, 73 | .ab-block-profile .ab-profile-column { 74 | flex: 0 0 100%; 75 | } 76 | .round .ab-profile-image-wrap { 77 | max-width: 220px; 78 | margin: 0 auto; 79 | } 80 | .ab-block-cta { 81 | .ab-cta-content { 82 | max-width: 700px; 83 | margin: 0 auto; 84 | } 85 | 86 | .ab-button { 87 | font-weight: normal; 88 | } 89 | } 90 | } 91 | 92 | .ab-layout-landing-3 { 93 | .ab-layout-landing-3-cover { 94 | h2, h3, h4, h5, h6 { 95 | margin-left: auto; 96 | margin-right: auto; 97 | 98 | @media only screen and (min-width: 600px) { 99 | font-size: 42px; 100 | } 101 | } 102 | } 103 | 104 | @media only screen and (min-width: 600px) { 105 | .ab-block-post-grid header .ab-block-post-grid-title { 106 | font-size: 24px; 107 | } 108 | } 109 | } 110 | 111 | /** 112 | * Twenty Twenty theme styles 113 | * Let's look at loading these conditionally if the theme is active 114 | */ 115 | 116 | div[class*="ab-section-"].alignfull, 117 | div[class*="ab-layout-"].alignfull { 118 | margin-top: auto; 119 | margin-bottom: auto; 120 | } 121 | -------------------------------------------------------------------------------- /src/blocks/block-newsletter/components/newsletter.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Newsletter Wrapper 3 | */ 4 | 5 | /** 6 | * WordPress dependencies 7 | */ 8 | const { Component } = wp.element; 9 | const { getColorClassName } = wp.blockEditor; 10 | 11 | /** 12 | * External dependencies 13 | */ 14 | import classnames from 'classnames'; 15 | 16 | /** 17 | * Newsletter Container class 18 | */ 19 | export default class NewsletterContainer extends Component { 20 | constructor( props ) { 21 | super( ...arguments ); 22 | } 23 | 24 | render() { 25 | const { attributes, backgroundColor, textColor } = this.props; 26 | 27 | /* Setup button background color class */ 28 | let backgroundColorClass; 29 | 30 | if ( attributes.customBackgroundColor ) { 31 | backgroundColorClass = 'ab-has-custom-background-color'; 32 | } else { 33 | backgroundColorClass = attributes.backgroundColor 34 | ? 'has-' + attributes.backgroundColor + '-background-color' 35 | : null; 36 | } 37 | 38 | /* Setup button text color class */ 39 | let textColorClass; 40 | 41 | if ( attributes.customTextColor ) { 42 | textColorClass = 'ab-has-custom-text-color'; 43 | } else { 44 | textColorClass = attributes.textColor 45 | ? 'has-' + attributes.textColor + '-color' 46 | : null; 47 | } 48 | 49 | return ( 50 |
74 | { this.props.children } 75 |
76 | ); 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /src/blocks/block-newsletter/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * WordPress dependencies 3 | */ 4 | const { __ } = wp.i18n; 5 | const { registerBlockType } = wp.blocks; 6 | 7 | /** 8 | * Internal dependencies 9 | */ 10 | import Edit from './components/edit'; 11 | import './styles/style.scss'; 12 | import './styles/editor.scss'; 13 | 14 | registerBlockType( 'atomic-blocks/newsletter', { 15 | title: __( 'Email newsletter', 'atomic-blocks' ), 16 | description: __( 'Add an email newsletter sign-up form.', 'atomic-blocks' ), 17 | category: 'atomic-blocks', 18 | icon: 'email-alt', 19 | keywords: [ 20 | __( 'Mailchimp', 'atomic-blocks' ), 21 | __( 'Subscribe', 'atomic-blocks' ), 22 | __( 'Newsletter', 'atomic-blocks' ), 23 | ], 24 | edit: Edit, 25 | ab_settings_data: { 26 | ab_newsletter_mailingList: { 27 | title: __( 'Mailing List', 'atomic-blocks' ), 28 | }, 29 | ab_newsletter_successMessage: { 30 | title: __( 'Success Message', 'atomic-blocks' ), 31 | }, 32 | ab_newsletter_doubleOptIn: { 33 | title: __( 'Enable Double Opt-In', 'atomic-blocks' ), 34 | }, 35 | ab_newsletter_containerPadding: { 36 | title: __( 'Form Padding', 'atomic-blocks' ), 37 | }, 38 | ab_newsletter_containerMargin: { 39 | title: __( 'Form Margin', 'atomic-blocks' ), 40 | }, 41 | ab_newsletter_colorOptions: { 42 | title: __( 'Color Options', 'atomic-blocks' ), 43 | }, 44 | }, 45 | save: () => { 46 | return null; 47 | }, 48 | } ); 49 | -------------------------------------------------------------------------------- /src/blocks/block-newsletter/styles/editor.scss: -------------------------------------------------------------------------------- 1 | /** 2 | * Editor styles 3 | */ 4 | 5 | .ab-block-newsletter { 6 | .ab-newsletter-title.mce-content-body { 7 | margin-top: 0; 8 | line-height: 1.3; 9 | } 10 | } 11 | 12 | .ab-form-styles { 13 | label { 14 | margin-bottom: 8px; 15 | width: 100%; 16 | display: block; 17 | } 18 | input { 19 | width: 100%; 20 | height: auto; 21 | border: solid 1px #ccc; 22 | min-height: 45px; 23 | margin-bottom: 15px; 24 | padding: 15px; 25 | font-size: 16px; 26 | } 27 | } 28 | 29 | .ab-newsletter-double-opt-in-setting-wrapper { 30 | margin-bottom: 24px; 31 | 32 | .description { 33 | margin-bottom: 5px; 34 | } 35 | } 36 | .ab-newsletter-double-opt-in-toggle { 37 | margin-right: 5px; 38 | } 39 | -------------------------------------------------------------------------------- /src/blocks/block-newsletter/styles/style.scss: -------------------------------------------------------------------------------- 1 | /** 2 | * Front end and back end styles 3 | */ 4 | 5 | .ab-block-newsletter { 6 | .ab-newsletter-title { 7 | margin-top: 0; 8 | line-height: 1.3; 9 | } 10 | 11 | .ab-block-button { 12 | margin-bottom: 0; 13 | } 14 | } 15 | 16 | .ab-block-newsletter-label { 17 | font-size: 16px; 18 | } 19 | 20 | .ab-form-styles { 21 | label { 22 | margin-bottom: 8px; 23 | width: 100%; 24 | display: block; 25 | } 26 | input:not(.ab-newsletter-submit) { 27 | width: 100%; 28 | height: auto; 29 | min-height: 45px; 30 | margin-bottom: 15px; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/blocks/block-notice/components/button.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Notice Box Dismiss Button 3 | */ 4 | 5 | // Setup the block 6 | const { Component } = wp.element; 7 | 8 | /** 9 | * Create a button wrapper Component 10 | */ 11 | export default class DismissButton extends Component { 12 | constructor( props ) { 13 | super( ...arguments ); 14 | } 15 | 16 | render() { 17 | // Setup the attributes 18 | const { 19 | attributes: { noticeTitleColor }, 20 | } = this.props; 21 | 22 | return ( 23 |
30 | { this.props.children } 31 |
32 | ); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/blocks/block-notice/components/icons.js: -------------------------------------------------------------------------------- 1 | const icons = {}; 2 | 3 | icons.upload = ( 4 | 10 | 11 | 12 | 13 | 14 | 15 | ); 16 | 17 | icons.dismiss = ( 18 | 25 | 26 | 27 | ); 28 | 29 | export default icons; 30 | -------------------------------------------------------------------------------- /src/blocks/block-notice/components/notice.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Notice Box Wrapper 3 | */ 4 | 5 | // Setup the block 6 | const { Component } = wp.element; 7 | 8 | // Import block dependencies and components 9 | import classnames from 'classnames'; 10 | import * as uniqueID from './../../../utils/helper'; 11 | 12 | /** 13 | * Create a Notice wrapper Component 14 | */ 15 | export default class NoticeBox extends Component { 16 | constructor( props ) { 17 | super( ...arguments ); 18 | } 19 | 20 | render() { 21 | // Setup the attributes 22 | const { 23 | attributes: { 24 | noticeTitle, 25 | noticeAlignment, 26 | noticeBackgroundColor, 27 | noticeTextColor, 28 | noticeFontSize, 29 | noticeDismiss, 30 | }, 31 | } = this.props; 32 | 33 | // Generate a unique ID for the dismissible notice 34 | const blockID = uniqueID.generateUniqueID( 35 | noticeDismiss + noticeTitle 36 | ); 37 | 38 | return ( 39 |
53 | { this.props.children } 54 |
55 | ); 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /src/blocks/block-notice/styles/editor.scss: -------------------------------------------------------------------------------- 1 | /** 2 | * Editor styles for the admin 3 | */ 4 | 5 | .ab-block-notice { 6 | margin-bottom: 0; 7 | } 8 | 9 | .block-editor-block-list__layout [data-type="atomic-blocks/ab-notice"] { 10 | margin-bottom: 1.2em; 11 | } 12 | -------------------------------------------------------------------------------- /src/blocks/block-notice/styles/style.scss: -------------------------------------------------------------------------------- 1 | /** 2 | * Notice styles 3 | * Loads on front end and back end 4 | */ 5 | 6 | .ab-block-notice { 7 | border-radius: 5px; 8 | position: relative; 9 | margin-bottom: 1.2em; 10 | 11 | .ab-notice-dismiss { 12 | position: absolute; 13 | top: 13px; 14 | right: 13px; 15 | opacity: .8; 16 | padding: 0; 17 | background: none; 18 | transition: .3s ease; 19 | 20 | &:hover { 21 | opacity: 1; 22 | cursor: pointer; 23 | box-shadow: none; 24 | } 25 | } 26 | 27 | .ab-notice-title { 28 | font-weight: bold; 29 | padding: .5em 1em; 30 | margin: 0; 31 | color: #fff; 32 | border-top-right-radius: 5px; 33 | border-top-left-radius: 5px; 34 | width: 100%; 35 | display: inline-block; 36 | 37 | p { 38 | margin-bottom: 0; 39 | } 40 | 41 | &:empty { 42 | display: none; 43 | } 44 | } 45 | 46 | .ab-notice-text { 47 | padding: 1em; 48 | border: solid 2px #333; 49 | border-radius: 5px; 50 | background: #fff; 51 | 52 | p:last-child { 53 | margin-bottom: 0; 54 | } 55 | } 56 | 57 | .ab-notice-title:not(:empty) + .notice-text, 58 | .blocks-rich-text + .blocks-rich-text .ab-notice-text { 59 | border-top-right-radius: 0; 60 | border-top-left-radius: 0; 61 | border-bottom-right-radius: 5px; 62 | border-bottom-left-radius: 5px; 63 | } 64 | } 65 | 66 | body:not(.wp-admin) .ab-block-notice.ab-dismissable { 67 | display: none; 68 | } 69 | -------------------------------------------------------------------------------- /src/blocks/block-post-grid/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * BLOCK: Atomic Blocks Post and Page Grid 3 | */ 4 | 5 | // Import block dependencies and components 6 | import edit from './components/edit'; 7 | 8 | // Import CSS 9 | import './styles/style.scss'; 10 | import './styles/editor.scss'; 11 | 12 | // Components 13 | const { __ } = wp.i18n; 14 | 15 | // Register block controls 16 | const { registerBlockType } = wp.blocks; 17 | 18 | // Register alignments 19 | const validAlignments = [ 'center', 'wide', 'full' ]; 20 | 21 | // Register the block 22 | registerBlockType( 'atomic-blocks/ab-post-grid', { 23 | title: __( 'Post and Page Grid', 'atomic-blocks' ), 24 | description: __( 25 | 'Add a grid or list of customizable posts or pages.', 26 | 'atomic-blocks' 27 | ), 28 | icon: 'grid-view', 29 | category: 'atomic-blocks', 30 | keywords: [ 31 | __( 'post', 'atomic-blocks' ), 32 | __( 'page', 'atomic-blocks' ), 33 | __( 'grid', 'atomic-blocks' ), 34 | ], 35 | 36 | getEditWrapperProps( attributes ) { 37 | const { align } = attributes; 38 | if ( -1 !== validAlignments.indexOf( align ) ) { 39 | return { 'data-align': align }; 40 | } 41 | }, 42 | 43 | edit, 44 | 45 | ab_settings_data: { 46 | ab_postgrid_postType: { 47 | title: __( 'Content Type', 'atomic-blocks' ), 48 | }, 49 | ab_postgrid_queryControls: { 50 | title: __( 'Query Controls', 'atomic-blocks' ), 51 | }, 52 | ab_postgrid_offset: { 53 | title: __( 'Post Offset', 'atomic-blocks' ), 54 | }, 55 | ab_postgrid_columns: { 56 | title: __( 'Columns', 'atomic-blocks' ), 57 | }, 58 | ab_postgrid_displaySectionTitle: { 59 | title: __( 'Display Section Title', 'atomic-blocks' ), 60 | }, 61 | ab_postgrid_sectionTitle: { 62 | title: __( 'Section Title', 'atomic-blocks' ), 63 | }, 64 | ab_postgrid_displayPostImage: { 65 | title: __( 'Display Featured Image', 'atomic-blocks' ), 66 | }, 67 | ab_postgrid_imageSizeValue: { 68 | title: __( 'Image Size', 'atomic-blocks' ), 69 | }, 70 | ab_postgrid_displayPostTitle: { 71 | title: __( 'Display Post Title', 'atomic-blocks' ), 72 | }, 73 | ab_postgrid_displayPostAuthor: { 74 | title: __( 'Display Post Author', 'atomic-blocks' ), 75 | }, 76 | ab_postgrid_displayPostDate: { 77 | title: __( 'Display Post Date', 'atomic-blocks' ), 78 | }, 79 | ab_postgrid_displayPostExcerpt: { 80 | title: __( 'Display Post Excerpt', 'atomic-blocks' ), 81 | }, 82 | ab_postgrid_excerptLength: { 83 | title: __( 'Excerpt Length', 'atomic-blocks' ), 84 | }, 85 | ab_postgrid_displayPostLink: { 86 | title: __( 'Display Continue Reading Link', 'atomic-blocks' ), 87 | }, 88 | ab_postgrid_readMoreText: { 89 | title: __( 'Read More Text', 'atomic-blocks' ), 90 | }, 91 | ab_postgrid_sectionTag: { 92 | title: __( 'Post Grid Section Tag', 'atomic-blocks' ), 93 | }, 94 | ab_postgrid_sectionTitleTag: { 95 | title: __( 'Section Title Heading Tag', 'atomic-blocks' ), 96 | }, 97 | ab_postgrid_postTitleTag: { 98 | title: __( 'Post Title Heading Tag', 'atomic-blocks' ), 99 | }, 100 | }, 101 | 102 | // Render via PHP 103 | save() { 104 | return null; 105 | }, 106 | } ); 107 | -------------------------------------------------------------------------------- /src/blocks/block-post-grid/styles/editor.scss: -------------------------------------------------------------------------------- 1 | /** 2 | * Editor styles for the admin 3 | */ 4 | 5 | .ab-block-post-grid { 6 | .ab-block-post-grid-title a { 7 | text-decoration: none; 8 | } 9 | } 10 | 11 | .ab-block-post-grid-markup-settings { 12 | .components-base-control__help { 13 | margin-top: 8px; 14 | } 15 | } 16 | 17 | .block-editor__container .block-editor-block-list__block .ab-block-post-grid a { 18 | color: inherit; 19 | } 20 | 21 | .ab-block-post-grid-image { 22 | position: relative; 23 | 24 | &:hover { 25 | .ab-post-grid-no-image-placeholder { 26 | opacity: 1; 27 | z-index: 1; 28 | } 29 | } 30 | } 31 | 32 | .ab-post-grid-no-image-placeholder { 33 | padding: 40px; 34 | position: absolute; 35 | top: 0; 36 | left: 0; 37 | width: 100%; 38 | height: 100%; 39 | opacity: 0; 40 | background: #f3f3f4; 41 | transition: .2s ease; 42 | 43 | svg { 44 | margin-bottom: 10px; 45 | } 46 | } 47 | 48 | .ab-post-grid-no-image-icon { 49 | position: absolute; 50 | top: 10px; 51 | background: #ffe606; 52 | right: 10px; 53 | padding: 6px; 54 | line-height: 1; 55 | height: 32px; 56 | transition: .2s ease; 57 | border-radius: 5px; 58 | z-index: 1; 59 | } 60 | 61 | .block-editor__container .components-placeholder__fieldset .ab-post-grid-image-help { 62 | display: inline-block; 63 | font-weight: bold; 64 | 65 | a { 66 | color: #0073aa; 67 | text-decoration: underline; 68 | 69 | &:hover { 70 | color: #00a0d2; 71 | } 72 | } 73 | } 74 | 75 | [data-type="atomic-blocks/ab-post-grid"] .components-placeholder { 76 | align-items: center; 77 | 78 | .components-placeholder__fieldset { 79 | width: auto; 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /src/blocks/block-pricing-table-inner/components/description/edit.js: -------------------------------------------------------------------------------- 1 | // Import block dependencies and components 2 | import classnames from 'classnames'; 3 | import Inspector from './inspector'; 4 | 5 | const { __ } = wp.i18n; 6 | const { registerBlockType } = wp.blocks; 7 | const { compose } = wp.compose; 8 | const { Component, Fragment } = wp.element; 9 | 10 | const { RichText, withFontSizes, withColors } = wp.blockEditor; 11 | 12 | class Edit extends Component { 13 | constructor() { 14 | super( ...arguments ); 15 | } 16 | 17 | render() { 18 | // Setup the attributes 19 | const { 20 | attributes: { 21 | features, 22 | borderStyle, 23 | borderColor, 24 | borderWidth, 25 | paddingTop, 26 | paddingRight, 27 | paddingBottom, 28 | paddingLeft, 29 | }, 30 | isSelected, 31 | className, 32 | setAttributes, 33 | fallbackFontSize, 34 | fontSize, 35 | backgroundColor, 36 | textColor, 37 | } = this.props; 38 | 39 | // Setup class names 40 | const editClassName = classnames( { 41 | 'ab-pricing-table-features': true, 42 | [ fontSize.class ]: fontSize.class, 43 | 'has-text-color': textColor.color, 44 | 'has-background': backgroundColor.color, 45 | [ backgroundColor.class ]: backgroundColor.class, 46 | [ textColor.class ]: textColor.class, 47 | [ borderStyle ]: borderStyle, 48 | [ 'ab-list-border-width-' + borderWidth ]: borderWidth, 49 | } ); 50 | 51 | // Setup styles 52 | const editStyles = { 53 | fontSize: fontSize.size ? fontSize.size + 'px' : undefined, 54 | backgroundColor: backgroundColor.color, 55 | color: textColor.color, 56 | borderColor: borderColor ? borderColor : undefined, 57 | paddingTop: paddingTop ? paddingTop + 'px' : undefined, 58 | paddingRight: paddingRight ? paddingRight + 'px' : undefined, 59 | paddingBottom: paddingBottom ? paddingBottom + 'px' : undefined, 60 | paddingLeft: paddingLeft ? paddingLeft + 'px' : undefined, 61 | }; 62 | 63 | return [ 64 | 65 | 66 | 77 | setAttributes( { features: value } ) 78 | } 79 | style={ editStyles } 80 | className={ editClassName ? editClassName : undefined } 81 | /> 82 | , 83 | ]; 84 | } 85 | } 86 | 87 | export default compose( [ 88 | withFontSizes( 'fontSize' ), 89 | withColors( 'backgroundColor', { textColor: 'color' } ), 90 | ] )( Edit ); 91 | -------------------------------------------------------------------------------- /src/blocks/block-pricing-table-inner/components/subtitle/edit.js: -------------------------------------------------------------------------------- 1 | // Import block dependencies and components 2 | import classnames from 'classnames'; 3 | import Inspector from '../global/inspector'; 4 | 5 | const { __ } = wp.i18n; 6 | const { registerBlockType } = wp.blocks; 7 | const { compose } = wp.compose; 8 | const { Component, Fragment } = wp.element; 9 | 10 | const { RichText, withFontSizes, withColors } = wp.blockEditor; 11 | 12 | class Edit extends Component { 13 | constructor() { 14 | super( ...arguments ); 15 | } 16 | 17 | render() { 18 | // Setup the attributes 19 | const { 20 | attributes: { 21 | subtitle, 22 | paddingTop, 23 | paddingRight, 24 | paddingBottom, 25 | paddingLeft, 26 | }, 27 | isSelected, 28 | className, 29 | setAttributes, 30 | fallbackFontSize, 31 | fontSize, 32 | backgroundColor, 33 | textColor, 34 | } = this.props; 35 | 36 | // Setup class names 37 | const editClassName = classnames( { 38 | 'ab-pricing-table-subtitle': true, 39 | [ fontSize.class ]: fontSize.class, 40 | 'has-text-color': textColor.color, 41 | 'has-background': backgroundColor.color, 42 | [ backgroundColor.class ]: backgroundColor.class, 43 | [ textColor.class ]: textColor.class, 44 | } ); 45 | 46 | // Setup styles 47 | const editStyles = { 48 | fontSize: fontSize.size ? fontSize.size + 'px' : undefined, 49 | backgroundColor: backgroundColor.color, 50 | color: textColor.color, 51 | paddingTop: paddingTop ? paddingTop + 'px' : undefined, 52 | paddingRight: paddingRight ? paddingRight + 'px' : undefined, 53 | paddingBottom: paddingBottom ? paddingBottom + 'px' : undefined, 54 | paddingLeft: paddingLeft ? paddingLeft + 'px' : undefined, 55 | }; 56 | 57 | return [ 58 | 59 | 60 | 66 | setAttributes( { subtitle: value } ) 67 | } 68 | style={ editStyles } 69 | className={ editClassName ? editClassName : undefined } 70 | /> 71 | , 72 | ]; 73 | } 74 | } 75 | 76 | export default compose( [ 77 | withFontSizes( 'fontSize' ), 78 | withColors( 'backgroundColor', { textColor: 'color' } ), 79 | ] )( Edit ); 80 | -------------------------------------------------------------------------------- /src/blocks/block-pricing-table-inner/components/title/edit.js: -------------------------------------------------------------------------------- 1 | // Import block dependencies and components 2 | import classnames from 'classnames'; 3 | import Inspector from '../global/inspector'; 4 | 5 | const { __ } = wp.i18n; 6 | const { registerBlockType } = wp.blocks; 7 | const { compose } = wp.compose; 8 | const { Component, Fragment } = wp.element; 9 | 10 | const { RichText, withFontSizes, withColors } = wp.blockEditor; 11 | 12 | class Edit extends Component { 13 | constructor() { 14 | super( ...arguments ); 15 | } 16 | 17 | render() { 18 | // Setup the attributes 19 | const { 20 | attributes: { 21 | title, 22 | paddingTop, 23 | paddingRight, 24 | paddingBottom, 25 | paddingLeft, 26 | }, 27 | isSelected, 28 | className, 29 | setAttributes, 30 | fallbackFontSize, 31 | fontSize, 32 | backgroundColor, 33 | textColor, 34 | } = this.props; 35 | 36 | // Setup class names 37 | const editClassName = classnames( { 38 | 'ab-pricing-table-title': true, 39 | [ fontSize.class ]: fontSize.class, 40 | 'has-text-color': textColor.color, 41 | 'has-background': backgroundColor.color, 42 | [ backgroundColor.class ]: backgroundColor.class, 43 | [ textColor.class ]: textColor.class, 44 | } ); 45 | 46 | // Setup styles 47 | const editStyles = { 48 | fontSize: fontSize.size ? fontSize.size + 'px' : undefined, 49 | backgroundColor: backgroundColor.color, 50 | color: textColor.color, 51 | paddingTop: paddingTop ? paddingTop + 'px' : undefined, 52 | paddingRight: paddingRight ? paddingRight + 'px' : undefined, 53 | paddingBottom: paddingBottom ? paddingBottom + 'px' : undefined, 54 | paddingLeft: paddingLeft ? paddingLeft + 'px' : undefined, 55 | }; 56 | 57 | return [ 58 | 59 | 60 | setAttributes( { title: value } ) } 67 | style={ editStyles } 68 | className={ editClassName ? editClassName : undefined } 69 | /> 70 | , 71 | ]; 72 | } 73 | } 74 | 75 | export default compose( [ 76 | withFontSizes( 'fontSize' ), 77 | withColors( 'backgroundColor', { textColor: 'color' } ), 78 | ] )( Edit ); 79 | -------------------------------------------------------------------------------- /src/blocks/block-pricing-table/components/inspector.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Inspector Controls 3 | */ 4 | 5 | import RenderSettingControl from '../../../utils/components/settings/renderSettingControl'; 6 | 7 | // Setup the block 8 | const { __ } = wp.i18n; 9 | const { Component } = wp.element; 10 | 11 | // Import block components 12 | const { InspectorControls } = wp.blockEditor; 13 | 14 | // Import Inspector components 15 | const { PanelBody, RangeControl } = wp.components; 16 | 17 | /** 18 | * Create an Inspector Controls wrapper Component 19 | */ 20 | export default class Inspector extends Component { 21 | constructor( props ) { 22 | super( ...arguments ); 23 | } 24 | 25 | render() { 26 | // Setup the attributes 27 | const { 28 | attributes: { columns, columnsGap }, 29 | } = this.props; 30 | 31 | return ( 32 | 33 | 34 | 35 | 39 | this.props.setAttributes( { columns: value } ) 40 | } 41 | min={ 1 } 42 | max={ 4 } 43 | /> 44 | 45 | 46 | 53 | this.props.setAttributes( { 54 | columnsGap: value, 55 | } ) 56 | } 57 | min={ 0 } 58 | max={ 5 } 59 | step={ 1 } 60 | /> 61 | 62 | 63 | 64 | ); 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /src/blocks/block-pricing-table/components/pricing.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Pricing Block Wrapper 3 | */ 4 | 5 | // Setup the block 6 | const { Component } = wp.element; 7 | 8 | // Import block dependencies and components 9 | import classnames from 'classnames'; 10 | 11 | /** 12 | * Create a Pricing wrapper Component 13 | */ 14 | export default class Pricing extends Component { 15 | constructor( props ) { 16 | super( ...arguments ); 17 | } 18 | 19 | render() { 20 | // Setup the attributes 21 | const { 22 | attributes: { columns, align }, 23 | } = this.props; 24 | 25 | const className = classnames( 26 | [ this.props.className, 'ab-pricing-columns-' + columns ], 27 | { 28 | [ 'align' + align ]: align, 29 | } 30 | ); 31 | 32 | return ( 33 |
34 | { this.props.children } 35 |
36 | ); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/blocks/block-sharing/components/edit.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Internal dependencies 3 | */ 4 | import Inspector from './inspector'; 5 | import ShareLinks from './sharing'; 6 | 7 | /** 8 | * WordPress dependencies 9 | */ 10 | const { __ } = wp.i18n; 11 | const { Component } = wp.element; 12 | const { AlignmentToolbar, BlockControls } = wp.blockEditor; 13 | 14 | export default class Edit extends Component { 15 | render() { 16 | return [ 17 | // Show the alignment toolbar on focus 18 | 19 | 22 | this.props.setAttributes( { shareAlignment: value } ) 23 | } 24 | /> 25 | , 26 | 27 | // Show the block controls on focus 28 | , 29 | 30 | // Show the button markup in the editor 31 | 32 | 111 | , 112 | ]; 113 | } 114 | } 115 | -------------------------------------------------------------------------------- /src/blocks/block-sharing/components/sharing.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Sharing Wrapper 3 | */ 4 | 5 | // Setup the block 6 | const { Component } = wp.element; 7 | 8 | // Import block dependencies and components 9 | import classnames from 'classnames'; 10 | 11 | /** 12 | * Create a ShareLinks wrapper Component 13 | */ 14 | export default class ShareLinks extends Component { 15 | render() { 16 | return ( 17 |
30 | { this.props.children } 31 |
32 | ); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/blocks/block-sharing/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * BLOCK: Atomic Blocks Sharing 3 | */ 4 | 5 | // Import 6 | import Edit from './components/edit'; 7 | import './styles/style.scss'; 8 | import './styles/editor.scss'; 9 | 10 | // Components 11 | const { __ } = wp.i18n; 12 | 13 | // Register block 14 | const { registerBlockType } = wp.blocks; 15 | 16 | // Register the block 17 | registerBlockType( 'atomic-blocks/ab-sharing', { 18 | title: __( 'Sharing', 'atomic-blocks' ), 19 | description: __( 20 | 'Add sharing buttons to your posts and pages.', 21 | 'atomic-blocks' 22 | ), 23 | icon: 'admin-links', 24 | category: 'atomic-blocks', 25 | keywords: [ 26 | __( 'sharing', 'atomic-blocks' ), 27 | __( 'social', 'atomic-blocks' ), 28 | __( 'atomic', 'atomic-blocks' ), 29 | ], 30 | 31 | ab_settings_data: { 32 | ab_sharing_links: { 33 | title: __( 'Sharing Links', 'atomic-blocks' ), 34 | }, 35 | ab_sharing_shareButtonStyle: { 36 | title: __( 'Button Style', 'atomic-blocks' ), 37 | }, 38 | ab_sharing_shareButtonShape: { 39 | title: __( 'Button Shape', 'atomic-blocks' ), 40 | }, 41 | ab_sharing_shareButtonSize: { 42 | title: __( 'Button Size', 'atomic-blocks' ), 43 | }, 44 | ab_sharing_shareButtonColor: { 45 | title: __( 'Button Color', 'atomic-blocks' ), 46 | }, 47 | }, 48 | 49 | // Render the block components 50 | edit: ( props ) => { 51 | return ; 52 | }, 53 | 54 | // Render via PHP 55 | save() { 56 | return null; 57 | }, 58 | } ); 59 | -------------------------------------------------------------------------------- /src/blocks/block-sharing/styles/editor.scss: -------------------------------------------------------------------------------- 1 | /** 2 | * Editor styles for the admin 3 | */ 4 | 5 | .ab-block-sharing { 6 | margin-bottom: 0; 7 | } -------------------------------------------------------------------------------- /src/blocks/block-sharing/styles/style.scss: -------------------------------------------------------------------------------- 1 | /** 2 | * Sharing styles 3 | * Loads on front end and back end 4 | */ 5 | 6 | .ab-block-sharing { 7 | margin: 0 0 1.2em 0; 8 | position: relative; 9 | 10 | .blocks-rich-text { 11 | display: inline-flex; 12 | } 13 | 14 | .ab-share-list { 15 | margin: 0; 16 | padding: 0; 17 | 18 | li { 19 | list-style: none; 20 | display: inline-block; 21 | margin: 0 5px 5px 0; 22 | } 23 | 24 | a { 25 | background: #272c30; 26 | color: #fff; 27 | padding: 10px 15px; 28 | text-align: center; 29 | display: block; 30 | line-height: 1; 31 | font-size: 16px; 32 | transition: .3s ease; 33 | 34 | &:hover { 35 | box-shadow: inset 0 0 200px rgba(255, 255, 255, 0.15); 36 | } 37 | } 38 | } 39 | 40 | &.ab-share-icon-text { 41 | i { 42 | margin-right: 5px; 43 | } 44 | } 45 | 46 | &.ab-share-icon-only { 47 | a { 48 | padding: 10px 11px; 49 | min-width: 37px; 50 | } 51 | 52 | .ab-social-text { 53 | border: 0; 54 | clip: rect(1px, 1px, 1px, 1px); 55 | clip-path: inset(50%); 56 | height: 1px; 57 | margin: -1px; 58 | overflow: hidden; 59 | padding: 0; 60 | position: absolute !important; 61 | width: 1px; 62 | word-wrap: normal !important; 63 | } 64 | } 65 | 66 | &.ab-share-text-only { 67 | i { 68 | display: none; 69 | } 70 | } 71 | 72 | &.ab-share-shape-square { 73 | a { 74 | border-radius: 0; 75 | } 76 | } 77 | 78 | &.ab-share-shape-rounded { 79 | a { 80 | border-radius: 5px; 81 | } 82 | } 83 | 84 | &.ab-share-shape-circular { 85 | a { 86 | border-radius: 100px; 87 | } 88 | } 89 | 90 | &.ab-share-size-small { 91 | a { 92 | font-size: 13px; 93 | } 94 | } 95 | 96 | &.ab-share-size-small.ab-share-icon-only { 97 | a { 98 | padding: 7px 6px; 99 | min-width: 28px; 100 | } 101 | } 102 | 103 | &.ab-share-size-medium { 104 | a { 105 | font-size: 16px; 106 | } 107 | } 108 | 109 | &.ab-share-size-large { 110 | a { 111 | font-size: 20px; 112 | } 113 | } 114 | 115 | &.ab-share-size-large.ab-share-icon-only { 116 | a { 117 | font-size: 26px; 118 | min-width: 48px; 119 | } 120 | } 121 | 122 | &.ab-share-size-large.ab-share-icon-text { 123 | i { 124 | margin-right: 10px; 125 | } 126 | } 127 | 128 | &.ab-share-color-social { 129 | a { 130 | color: #fff; 131 | } 132 | 133 | .ab-share-twitter { 134 | background: #1ca1f3; 135 | } 136 | 137 | .ab-share-facebook { 138 | background: #3b5999; 139 | } 140 | 141 | .ab-share-google { 142 | background: #dc4b45; 143 | } 144 | 145 | .ab-share-pinterest { 146 | background: #bd091c; 147 | } 148 | 149 | .ab-share-linkedin { 150 | background: #0077b5; 151 | } 152 | 153 | .ab-share-reddit { 154 | background: #ff4500; 155 | } 156 | } 157 | } 158 | 159 | .ab-button-right { 160 | transform: translateX(-100%); 161 | left: 100%; 162 | position: relative; 163 | } 164 | 165 | .ab-button-center { 166 | margin: 0 auto; 167 | } -------------------------------------------------------------------------------- /src/blocks/block-spacer/components/icons.js: -------------------------------------------------------------------------------- 1 | const icons = {}; 2 | 3 | icons.upload = ( 4 | 10 | 11 | 12 | 13 | 14 | 15 | ); 16 | 17 | icons.dismiss = ( 18 | 25 | 26 | 27 | ); 28 | 29 | export default icons; 30 | -------------------------------------------------------------------------------- /src/blocks/block-spacer/components/spacer.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Button Wrapper 3 | */ 4 | 5 | // Setup the block 6 | const { Component } = wp.element; 7 | 8 | // Import block dependencies and components 9 | import classnames from 'classnames'; 10 | 11 | /** 12 | * Create a Button wrapper Component 13 | */ 14 | export default class Spacer extends Component { 15 | render() { 16 | // Setup the attributes 17 | const { 18 | spacerDivider, 19 | spacerDividerStyle, 20 | spacerDividerColor, 21 | spacerDividerHeight, 22 | } = this.props.attributes; 23 | 24 | return ( 25 |
37 | { this.props.children } 38 |
39 | ); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/blocks/block-spacer/styles/editor.scss: -------------------------------------------------------------------------------- 1 | /** 2 | * Editor styles for the admin 3 | */ 4 | 5 | .block-editor-block-list__layout [data-type="atomic-blocks/ab-spacer"] { 6 | margin-bottom: 1.2em; 7 | } 8 | 9 | .ab-block-spacer { 10 | border: dashed 1px #ddd; 11 | margin-bottom: 0; 12 | 13 | .ab-spacer-handle { 14 | margin-bottom: 0; 15 | } 16 | 17 | &.is-selected::before { 18 | outline: none; 19 | } 20 | 21 | .block-editor-block-list__block-edit { 22 | outline: 1px dashed #ddd; 23 | } 24 | 25 | &.is-selected .block-editor-block-list__block-edit, 26 | &.is-hovered .block-editor-block-list__block-edit { 27 | outline: 1px dotted #ddd; 28 | } 29 | 30 | &.is-selected .block-editor-block-list__block-edit { 31 | outline: 1px solid #ddd; 32 | } 33 | } 34 | 35 | .ab-spacer-control__resize-handle { 36 | background: none; 37 | background: none; 38 | border-radius: 0; 39 | bottom: -15px !important; 40 | cursor: row-resize !important; 41 | display: none; 42 | height: 32px !important; 43 | left: 0 !important; 44 | width: 100% !important; 45 | z-index: 999; 46 | 47 | .block-editor-block-list__block[data-type="atomic-blocks/ab-spacer"].is-selected &, 48 | .block-editor-block-list__block[data-type="atomic-blocks/ab-spacer"].is-hovered & { 49 | display: block; 50 | } 51 | 52 | &:after { 53 | background-color: #32373c; 54 | border-radius: 50px; 55 | border: 2px solid #fff; 56 | content: ''; 57 | display: block; 58 | height: 12px; 59 | left: 50%; 60 | margin-left: -8px; 61 | margin-top: -6px; 62 | position: absolute; 63 | top: 50%; 64 | width: 12px; 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /src/blocks/block-spacer/styles/style.scss: -------------------------------------------------------------------------------- 1 | /** 2 | * Spacer styles 3 | * Loads on front end and back end 4 | */ 5 | 6 | .ab-block-spacer { 7 | margin: 0 0 1.2em 0; 8 | position: relative; 9 | 10 | hr { 11 | border: none; 12 | margin: 0; 13 | background: none; 14 | } 15 | 16 | &.ab-spacer-divider:after { 17 | content: " "; 18 | width: 100%; 19 | height: 1px; 20 | border-top: solid 1px; 21 | position: absolute; 22 | top: 50%; 23 | left: 0; 24 | } 25 | 26 | &.ab-divider-solid.ab-spacer-divider:after { 27 | border-top-style: solid; 28 | } 29 | 30 | &.ab-divider-dotted.ab-spacer-divider:after { 31 | border-top-style: dotted; 32 | } 33 | 34 | &.ab-divider-dashed.ab-spacer-divider:after { 35 | border-top-style: dashed; 36 | } 37 | 38 | &.ab-divider-size-1.ab-spacer-divider:after { 39 | border-top-width: 1px; 40 | } 41 | 42 | &.ab-divider-size-2.ab-spacer-divider:after { 43 | border-top-width: 2px; 44 | } 45 | 46 | &.ab-divider-size-3.ab-spacer-divider:after { 47 | border-top-width: 3px; 48 | } 49 | 50 | &.ab-divider-size-4.ab-spacer-divider:after { 51 | border-top-width: 4px; 52 | } 53 | 54 | &.ab-divider-size-5.ab-spacer-divider:after { 55 | border-top-width: 5px; 56 | } 57 | } 58 | 59 | .entry-content .ab-block-spacer { 60 | hr { 61 | border: none; 62 | margin: 0; 63 | background: none; 64 | &:before, 65 | &:after { 66 | display: none; 67 | } 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /src/blocks/block-testimonial/components/inspector.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Inspector Controls 3 | */ 4 | 5 | import RenderSettingControl from '../../../utils/components/settings/renderSettingControl'; 6 | 7 | // Setup the block 8 | const { __ } = wp.i18n; 9 | const { Component } = wp.element; 10 | 11 | // Import block components 12 | const { InspectorControls, PanelColorSettings } = wp.blockEditor; 13 | 14 | // Import Inspector components 15 | const { PanelBody, RangeControl, SelectControl } = wp.components; 16 | 17 | /** 18 | * Create an Inspector Controls wrapper Component 19 | */ 20 | export default class Inspector extends Component { 21 | render() { 22 | // Cite Alignment Options 23 | const citeAlignOptions = [ 24 | { 25 | value: 'left-aligned', 26 | label: __( 'Left Aligned', 'atomic-blocks' ), 27 | }, 28 | { 29 | value: 'right-aligned', 30 | label: __( 'Right Aligned', 'atomic-blocks' ), 31 | }, 32 | ]; 33 | 34 | // Setup the attributes 35 | const { 36 | attributes: { 37 | testimonialBackgroundColor, 38 | testimonialTextColor, 39 | testimonialFontSize, 40 | testimonialCiteAlign, 41 | }, 42 | setAttributes, 43 | } = this.props; 44 | 45 | // Update color values 46 | const onChangeBackgroundColor = ( value ) => 47 | setAttributes( { testimonialBackgroundColor: value } ); 48 | const onChangeTextColor = ( value ) => 49 | setAttributes( { testimonialTextColor: value } ); 50 | 51 | return ( 52 | 53 | 54 | 55 | 59 | this.props.setAttributes( { 60 | testimonialFontSize: value, 61 | } ) 62 | } 63 | min={ 14 } 64 | max={ 24 } 65 | step={ 1 } 66 | /> 67 | 68 | 69 | 78 | this.props.setAttributes( { 79 | testimonialCiteAlign: value, 80 | } ) 81 | } 82 | /> 83 | 84 | 85 | 86 | 100 | 101 | 102 | 103 | 114 | 115 | 116 | ); 117 | } 118 | } 119 | -------------------------------------------------------------------------------- /src/blocks/block-testimonial/components/save.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Internal dependencies 3 | */ 4 | import Testimonial from './testimonial'; 5 | 6 | /** 7 | * WordPress dependencies 8 | */ 9 | const { Component } = wp.element; 10 | const { RichText } = wp.blockEditor; 11 | 12 | export default class Save extends Component { 13 | render() { 14 | const { 15 | testimonialName, 16 | testimonialTitle, 17 | testimonialContent, 18 | testimonialAlignment, 19 | testimonialImgURL, 20 | testimonialTextColor, 21 | } = this.props.attributes; 22 | 23 | return ( 24 | 25 | 33 | 34 |
35 | { testimonialImgURL && ( 36 |
37 |
38 | avatar 43 |
44 |
45 | ) } 46 | 47 | { testimonialName && ( 48 | 58 | ) } 59 | 60 | { testimonialTitle && ( 61 | 71 | ) } 72 |
73 |
74 | ); 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /src/blocks/block-testimonial/components/testimonial.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Testimonial Block Wrapper 3 | */ 4 | 5 | // Setup the block 6 | const { Component } = wp.element; 7 | 8 | // Import block dependencies and components 9 | import classnames from 'classnames'; 10 | 11 | /** 12 | * Create a Testimonial wrapper Component 13 | */ 14 | export default class Testimonial extends Component { 15 | render() { 16 | // Setup the attributes 17 | const { 18 | attributes: { 19 | testimonialImgURL, 20 | testimonialBackgroundColor, 21 | testimonialTextColor, 22 | testimonialFontSize, 23 | testimonialCiteAlign, 24 | }, 25 | } = this.props; 26 | 27 | return ( 28 |
45 | { this.props.children } 46 |
47 | ); 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/blocks/block-testimonial/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * BLOCK: Atomic Blocks Testimonial 3 | */ 4 | 5 | // Import block dependencies and components 6 | import Edit from './components/edit'; 7 | import Save from './components/save'; 8 | 9 | // Import CSS 10 | import './styles/style.scss'; 11 | import './styles/editor.scss'; 12 | 13 | // Internationalization 14 | const { __ } = wp.i18n; 15 | 16 | // Register block 17 | const { registerBlockType } = wp.blocks; 18 | 19 | // Register the block 20 | registerBlockType( 'atomic-blocks/ab-testimonial', { 21 | title: __( 'Testimonial', 'atomic-blocks' ), 22 | description: __( 23 | 'Add a user testimonial with a name and title.', 24 | 'atomic-blocks' 25 | ), 26 | icon: 'format-quote', 27 | category: 'atomic-blocks', 28 | keywords: [ 29 | __( 'testimonial', 'atomic-blocks' ), 30 | __( 'quote', 'atomic-blocks' ), 31 | __( 'atomic', 'atomic-blocks' ), 32 | ], 33 | attributes: { 34 | testimonialName: { 35 | type: 'array', 36 | selector: '.ab-testimonial-name', 37 | source: 'children', 38 | }, 39 | testimonialTitle: { 40 | type: 'array', 41 | selector: '.ab-testimonial-title', 42 | source: 'children', 43 | }, 44 | testimonialContent: { 45 | type: 'array', 46 | selector: '.ab-testimonial-text', 47 | source: 'children', 48 | }, 49 | testimonialAlignment: { 50 | type: 'string', 51 | }, 52 | testimonialImgURL: { 53 | type: 'string', 54 | source: 'attribute', 55 | attribute: 'src', 56 | selector: 'img', 57 | }, 58 | testimonialImgID: { 59 | type: 'number', 60 | }, 61 | testimonialBackgroundColor: { 62 | type: 'string', 63 | default: '#f2f2f2', 64 | }, 65 | testimonialTextColor: { 66 | type: 'string', 67 | default: '#32373c', 68 | }, 69 | testimonialFontSize: { 70 | type: 'number', 71 | default: 18, 72 | }, 73 | testimonialCiteAlign: { 74 | type: 'string', 75 | default: 'left-aligned', 76 | }, 77 | }, 78 | ab_settings_data: { 79 | ab_testimonial_testimonialFontSize: { 80 | title: __( 'Font Size', 'atomic-blocks' ), 81 | }, 82 | ab_testimonial_testimonialCiteAlign: { 83 | title: __( 'Cite Alignment', 'atomic-blocks' ), 84 | }, 85 | ab_testimonial_testimonialBackgroundColor: { 86 | title: __( 'Background Color', 'atomic-blocks' ), 87 | }, 88 | ab_testimonial_testimonialTextColor: { 89 | title: __( 'Text Color', 'atomic-blocks' ), 90 | }, 91 | }, 92 | 93 | /* Render the block in the editor. */ 94 | edit: ( props ) => { 95 | return ; 96 | }, 97 | 98 | /* Save the block markup. */ 99 | save: ( props ) => { 100 | return ; 101 | }, 102 | } ); 103 | -------------------------------------------------------------------------------- /src/blocks/block-testimonial/styles/editor.scss: -------------------------------------------------------------------------------- 1 | /** 2 | * Editor styles for the admin 3 | */ 4 | 5 | .ab-block-testimonial { 6 | margin-bottom: 0; 7 | 8 | .components-button:not(:disabled):not([aria-disabled=true]):focus { 9 | background: none; 10 | box-shadow: none; 11 | } 12 | } 13 | 14 | .block-editor-block-list__layout [data-type="atomic-blocks/ab-testimonial"] { 15 | margin-bottom: 1.2em; 16 | } 17 | 18 | .ab-testimonial-info { 19 | h2.editor-rich-text__tinymce { 20 | line-height: 1.2; 21 | } 22 | 23 | p.editor-rich-text__tinymce { 24 | line-height: 1.6; 25 | } 26 | 27 | .ab-testimonial-title + .ab-testimonial-title { 28 | line-height: 1.8; 29 | } 30 | } 31 | 32 | #editor div[class^="wp-block-atomic-blocks-"].ab-block-testimonial .ab-add-image svg { 33 | height: 20px; 34 | width: 20px; 35 | } 36 | -------------------------------------------------------------------------------- /src/blocks/block-testimonial/styles/style.scss: -------------------------------------------------------------------------------- 1 | /** 2 | * Testimonial styles 3 | * Loads on front end and back end 4 | */ 5 | 6 | .ab-block-testimonial { 7 | background: #f2f2f2; 8 | color: #293038; 9 | margin: 0 auto; 10 | padding: 5%; 11 | border-radius: 5px; 12 | margin-bottom: 1.2em; 13 | 14 | .ab-testimonial-info { 15 | position: relative; 16 | display: inline-block; 17 | width: 100%; 18 | margin-top: 15px; 19 | min-height: 55px; 20 | padding-top: 5px; 21 | line-height: 1.4; 22 | } 23 | 24 | .ab-testimonial-info { 25 | .blocks-editable { 26 | padding-left: 0; 27 | } 28 | 29 | .ab-testimonial-avatar-wrap { 30 | position: absolute; 31 | left: 0; 32 | top: 0; 33 | } 34 | } 35 | 36 | .ab-testimonial-avatar-wrap + .ab-testimonial-name, 37 | .ab-testimonial-avatar-wrap + .ab-testimonial-name + .ab-testimonial-title, 38 | .ab-testimonial-avatar-wrap + .ab-testimonial-title, 39 | .ab-testimonial-avatar-wrap + .editor-rich-text, 40 | .ab-testimonial-avatar-wrap + .editor-rich-text + .editor-rich-text { 41 | margin-left: 70px; 42 | padding-left: 0; 43 | } 44 | 45 | .ab-testimonial-text { 46 | p { 47 | line-height: 1.6; 48 | } 49 | 50 | a { 51 | color: inherit; 52 | box-shadow: 0 -1px 0 inset; 53 | text-decoration: none; 54 | 55 | &:hover { 56 | color: inherit; 57 | box-shadow: 0 -2px 0 inset; 58 | } 59 | } 60 | } 61 | 62 | .ab-testimonial-name { 63 | font-size: 1em; 64 | font-weight: bold; 65 | line-height: 1.2; 66 | margin: 0; 67 | padding: 0; 68 | } 69 | 70 | .ab-testimonial-title { 71 | opacity: .8; 72 | } 73 | 74 | .ab-testimonial-avatar { 75 | border-radius: 200px; 76 | max-width: 100px; 77 | } 78 | 79 | .ab-testimonial-image-wrap { 80 | height: 55px; 81 | width: 55px; 82 | background: #ddd; 83 | border-radius: 200px; 84 | position: relative; 85 | 86 | img { 87 | object-fit: cover; 88 | height: 100%; 89 | width: 100%; 90 | position: relative; 91 | z-index: 10; 92 | border-radius: 40px; 93 | z-index: 5; 94 | } 95 | } 96 | } 97 | 98 | .right-aligned { 99 | .ab-testimonial-info { 100 | text-align: right; 101 | 102 | h2 { 103 | left: 0; 104 | } 105 | 106 | .ab-testimonial-name, 107 | .ab-testimonial-title { 108 | margin-right: 70px; 109 | margin-left: 0; 110 | } 111 | 112 | .ab-testimonial-avatar-wrap { 113 | left: auto; 114 | right: 0; 115 | } 116 | } 117 | } 118 | -------------------------------------------------------------------------------- /src/blocks/global-styles/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Import global styles. 3 | */ 4 | import './styles/style.scss'; 5 | import './styles/editor.scss'; 6 | -------------------------------------------------------------------------------- /src/blocks/global-styles/styles/editor.scss: -------------------------------------------------------------------------------- 1 | #editor div[class^="wp-block-atomic-blocks-"] { 2 | .ab-change-image { 3 | position: absolute; 4 | z-index: 50; 5 | padding: 0; 6 | top: 0; 7 | left: 0; 8 | opacity: 1; 9 | height: 100%; 10 | 11 | img { 12 | transition: .2s ease; 13 | } 14 | 15 | &:hover { 16 | img { 17 | opacity: .7 18 | } 19 | } 20 | } 21 | 22 | .ab-change-image:focus { 23 | background: none; 24 | border: none; 25 | outline: none; 26 | box-shadow: none; 27 | } 28 | 29 | .ab-add-image { 30 | position: absolute; 31 | left: 0; 32 | top: 0; 33 | z-index: 50; 34 | padding: 0; 35 | width: 100%; 36 | height: 100%; 37 | 38 | svg { 39 | position: absolute; 40 | top: 17px; 41 | left: 19px; 42 | } 43 | } 44 | 45 | .ab-remove-image { 46 | color: #ec3939; 47 | position: absolute; 48 | right: 0; 49 | top: 0; 50 | height: auto; 51 | width: 20px; 52 | left: auto; 53 | z-index: 60; 54 | margin: 0; 55 | padding: 0; 56 | background: #fff; 57 | border-radius: 50px; 58 | 59 | &:active, 60 | &:focus { 61 | color: #ec3939; 62 | background: #fff; 63 | } 64 | } 65 | 66 | .ab-remove-image:not(:disabled):not([aria-disabled=true]):focus { 67 | background: #fff; 68 | } 69 | } 70 | 71 | .ab-inspector-help-text { 72 | .components-base-control__help { 73 | margin-top: 0; 74 | } 75 | } 76 | 77 | @import 'type.scss'; 78 | 79 | .wp-block *[class*="gpb-fluid"], 80 | .editor-styles-wrapper *[class*="gpb-fluid"] { 81 | margin: 0 0 1rem 0; 82 | line-height: 1.1; 83 | font-weight: normal; 84 | } 85 | 86 | .editor-styles-wrapper .gpb-fluid-1 { 87 | @include fluid-font-size(20px, 26px, $vp-small, $vp-large); 88 | } 89 | 90 | .editor-styles-wrapper .gpb-fluid-2 { 91 | @include fluid-font-size(22px, 30px, $vp-small, $vp-large); 92 | } 93 | 94 | .editor-styles-wrapper .gpb-fluid-3 { 95 | @include fluid-font-size(24px, 38px, $vp-small, $vp-large); 96 | } 97 | 98 | .editor-styles-wrapper .gpb-fluid-4 { 99 | @include fluid-font-size(28px, 44px, $vp-small, $vp-large); 100 | } 101 | 102 | .editor-styles-wrapper .gpb-fluid-5 { 103 | @include fluid-font-size(32px, 52px, $vp-small, $vp-large); 104 | } 105 | 106 | .editor-styles-wrapper .gpb-fluid-6 { 107 | @include fluid-font-size(36px, 60px, $vp-small, $vp-large); 108 | } 109 | -------------------------------------------------------------------------------- /src/blocks/global-styles/styles/type.scss: -------------------------------------------------------------------------------- 1 | /** 2 | * Fluid Type 3 | * Provide a flexible type override for block typography 4 | */ 5 | 6 | /* Breakpoints */ 7 | $vp-small: 600px; 8 | $vp-large: 1024px; 9 | 10 | /* Fluid type mixin */ 11 | @mixin fluid-font-size($minFontSize: 16px, $maxFontSize: 20px, $minViewport: 600px, $maxViewport: 1200px) { 12 | $slope: ($minFontSize - $maxFontSize) / ($minViewport - $maxViewport); 13 | $base: $maxFontSize - $slope * $maxViewport; 14 | 15 | font-size: $minFontSize; 16 | 17 | @media (min-width: $minViewport) { 18 | font-size: calc(#{$base} + 100vw * #{$slope}); 19 | } 20 | 21 | @media (min-width: $maxViewport) { 22 | font-size: $maxFontSize; 23 | } 24 | } 25 | 26 | 27 | -------------------------------------------------------------------------------- /src/blocks/global-styles/styles/utility.scss: -------------------------------------------------------------------------------- 1 | /** 2 | * Utility classes 3 | * Provide a way to modify layouts with sprinkled in classes 4 | */ 5 | 6 | /* Overflow */ 7 | 8 | .gpb-overflow-hidden { 9 | overflow: hidden; 10 | } 11 | 12 | /* Grid Enhancements */ 13 | 14 | .gpb-grid-mobile-space .ab-is-responsive-column { 15 | grid-row-gap: 1em; 16 | } 17 | 18 | /* Border Radius */ 19 | 20 | .gpb-rounded-grid { 21 | .ab-block-layout-column-inner { 22 | border-radius: 10px; 23 | } 24 | } 25 | 26 | .gpb-rounded-sm, 27 | .gpb-rounded-sm img { 28 | border-radius: 5px; 29 | } 30 | 31 | .gpb-rounded-md, 32 | .gpb-rounded-md img { 33 | border-radius: 10px; 34 | } 35 | 36 | .gpb-rounded-lg, 37 | .gpb-rounded-lg img { 38 | border-radius: 20px; 39 | } 40 | 41 | .gpb-rounded-xl, 42 | .gpb-rounded-xl img { 43 | border-radius: 30px; 44 | } 45 | 46 | .gpb-rounded-full, 47 | .gpb-rounded-full img { 48 | border-radius: 500px; 49 | } 50 | 51 | /* Alignment */ 52 | 53 | .gpb-mobile-align-reset { 54 | @media only screen and (max-width: 600px) { 55 | float: none; 56 | text-align: left; 57 | margin-left: 0 !important; 58 | margin-right: 0; 59 | } 60 | } 61 | 62 | /* Grid */ 63 | 64 | .gpb-grid-mobile-reorder .ab-is-responsive-column { 65 | @media only screen and (max-width: 600px) { 66 | .ab-block-layout-column:nth-of-type(1){ 67 | grid-area: col2; 68 | } 69 | 70 | .ab-block-layout-column:nth-of-type(2){ 71 | grid-area: col1; 72 | } 73 | } 74 | } 75 | 76 | /* Margin */ 77 | 78 | .gpb-mb-1 { 79 | margin-bottom: 1rem; 80 | } 81 | -------------------------------------------------------------------------------- /src/common.scss: -------------------------------------------------------------------------------- 1 | /** 2 | * Variables for use in blocks. 3 | */ 4 | 5 | // Variables 6 | $black: #293038; 7 | $accent: #5a3fd6; 8 | $lightgray: #626e81; 9 | -------------------------------------------------------------------------------- /src/utils/components/background-image/attributes.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Background image attributes. 3 | */ 4 | 5 | const BackgroundAttributes = { 6 | backgroundImgURL: { 7 | type: 'string', 8 | }, 9 | backgroundDimRatio: { 10 | type: 'number', 11 | default: 100, 12 | }, 13 | backgroundRepeat: { 14 | type: 'string', 15 | default: 'no-repeat', 16 | }, 17 | backgroundSize: { 18 | type: 'string', 19 | default: 'cover', 20 | }, 21 | hasParallax: { 22 | type: 'boolean', 23 | default: false, 24 | }, 25 | focalPoint: { 26 | type: 'object', 27 | }, 28 | }; 29 | 30 | export default BackgroundAttributes; 31 | -------------------------------------------------------------------------------- /src/utils/components/background-image/classes.js: -------------------------------------------------------------------------------- 1 | import { dimRatioToClass } from './shared'; 2 | 3 | /** 4 | * Background image classes. 5 | * 6 | * @param {Object} attributes 7 | */ 8 | function BackgroundImageClasses( attributes ) { 9 | return [ 10 | attributes.backgroundDimRatio !== undefined && 11 | 100 !== attributes.backgroundDimRatio 12 | ? 'ab-has-background-dim' 13 | : null, 14 | dimRatioToClass( attributes.backgroundDimRatio ), 15 | attributes.backgroundImgURL && 16 | attributes.backgroundSize && 17 | 'no-repeat' === attributes.backgroundRepeat 18 | ? 'ab-background-' + attributes.backgroundSize 19 | : null, 20 | attributes.backgroundImgURL && attributes.backgroundRepeat 21 | ? 'ab-background-' + attributes.backgroundRepeat 22 | : null, 23 | attributes.hasParallax ? 'ab-has-parallax' : null, 24 | ]; 25 | } 26 | 27 | export default BackgroundImageClasses; 28 | -------------------------------------------------------------------------------- /src/utils/components/background-image/shared.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Shared background image functions 3 | */ 4 | 5 | export function dimRatioToClass( ratio ) { 6 | return 100 > ratio 7 | ? 'ab-has-background-dim-' + 10 * Math.round( ratio / 10 ) 8 | : null; 9 | } 10 | -------------------------------------------------------------------------------- /src/utils/components/background-image/styles.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Background image styles. 3 | */ 4 | 5 | const BackgroundImageStyles = ( attributes ) => { 6 | const styles = { 7 | backgroundImage: attributes.backgroundImgURL 8 | ? `url(${ attributes.backgroundImgURL })` 9 | : undefined, 10 | backgroundPosition: attributes.focalPoint 11 | ? `${ attributes.focalPoint.x * 100 }% ${ attributes.focalPoint.y * 12 | 100 }%` 13 | : undefined, 14 | }; 15 | 16 | return styles; 17 | }; 18 | 19 | export default BackgroundImageStyles; 20 | -------------------------------------------------------------------------------- /src/utils/components/data-providers/currentUserData.js: -------------------------------------------------------------------------------- 1 | export default function getCurrentUserData() { 2 | return atomic_globals.user_data; 3 | } 4 | -------------------------------------------------------------------------------- /src/utils/components/icons/index.js: -------------------------------------------------------------------------------- 1 | const icons = {}; 2 | 3 | icons.upload = ( 4 | 10 | 11 | 12 | 13 | 14 | 15 | ); 16 | 17 | export default icons; 18 | -------------------------------------------------------------------------------- /src/utils/components/margin.js: -------------------------------------------------------------------------------- 1 | const { __ } = wp.i18n; 2 | const { Fragment } = wp.element; 3 | const { RangeControl } = wp.components; 4 | 5 | export default function Margin( props ) { 6 | const { 7 | // Margin top props 8 | marginTop, 9 | marginTopLabel, 10 | marginTopMin, 11 | marginTopMax, 12 | marginEnableTop, 13 | onChangeMarginTop = () => {}, 14 | 15 | // Margin right props 16 | marginRight, 17 | marginRightLabel, 18 | marginRightMin, 19 | marginRightMax, 20 | marginEnableRight, 21 | onChangeMarginRight = () => {}, 22 | 23 | // Margin bottom props 24 | marginBottom, 25 | marginBottomLabel, 26 | marginBottomMin, 27 | marginBottomMax, 28 | marginEnableBottom, 29 | onChangeMarginBottom = () => {}, 30 | 31 | // Margin left props 32 | marginLeft, 33 | marginLeftLabel, 34 | marginLeftMin, 35 | marginLeftMax, 36 | marginEnableLeft, 37 | onChangeMarginLeft = () => {}, 38 | 39 | // Margin vertical props 40 | marginVertical, 41 | marginVerticalLabel, 42 | marginEnableVertical, 43 | marginVerticalMin, 44 | marginVerticalMax, 45 | onChangeMarginVertical = () => {}, 46 | 47 | // Margin horizontal props 48 | marginHorizontal, 49 | marginHorizontalLabel, 50 | marginEnableHorizontal, 51 | marginHorizontalMin, 52 | marginHorizontalMax, 53 | onChangeMarginHorizontal = () => {}, 54 | } = props; 55 | 56 | return ( 57 | 58 | { marginEnableTop && ( 59 | 70 | ) } 71 | { marginEnableRight && ( 72 | 83 | ) } 84 | { marginEnableBottom && ( 85 | 96 | ) } 97 | { marginEnableLeft && ( 98 | 109 | ) } 110 | { marginEnableVertical && ( 111 | 122 | ) } 123 | { marginEnableHorizontal && ( 124 | 135 | ) } 136 | 137 | ); 138 | } 139 | -------------------------------------------------------------------------------- /src/utils/components/padding.js: -------------------------------------------------------------------------------- 1 | const { __ } = wp.i18n; 2 | const { Fragment } = wp.element; 3 | const { RangeControl } = wp.components; 4 | 5 | export default function Padding( props ) { 6 | const { 7 | // Padding props 8 | padding, 9 | paddingTitle, 10 | paddingHelp, 11 | paddingMin, 12 | paddingMax, 13 | paddingEnable, 14 | onChangePadding = () => {}, 15 | 16 | // Padding top props 17 | paddingTop, 18 | paddingTopMin, 19 | paddingTopMax, 20 | paddingEnableTop, 21 | onChangePaddingTop = () => {}, 22 | 23 | // Padding right props 24 | paddingRight, 25 | paddingRightMin, 26 | paddingRightMax, 27 | paddingEnableRight, 28 | onChangePaddingRight = () => {}, 29 | 30 | // Padding bottom props 31 | paddingBottom, 32 | paddingBottomMin, 33 | paddingBottomMax, 34 | paddingEnableBottom, 35 | onChangePaddingBottom = () => {}, 36 | 37 | // Padding left props 38 | paddingLeft, 39 | paddingLeftMin, 40 | paddingLeftMax, 41 | paddingEnableLeft, 42 | onChangePaddingLeft = () => {}, 43 | 44 | // Padding vertical props 45 | paddingVertical, 46 | paddingEnableVertical, 47 | paddingVerticalMin, 48 | paddingVerticalMax, 49 | onChangePaddingVertical = () => {}, 50 | 51 | // Padding horizontal props 52 | paddingHorizontal, 53 | paddingEnableHorizontal, 54 | paddingHorizontalMin, 55 | paddingHorizontalMax, 56 | onChangePaddingHorizontal = () => {}, 57 | } = props; 58 | 59 | return ( 60 | 61 | { paddingEnable && ( 62 | 74 | ) } 75 | { paddingEnableTop && ( 76 | 83 | ) } 84 | { paddingEnableRight && ( 85 | 92 | ) } 93 | { paddingEnableBottom && ( 94 | 101 | ) } 102 | { paddingEnableLeft && ( 103 | 110 | ) } 111 | { paddingEnableVertical && ( 112 | 119 | ) } 120 | { paddingEnableHorizontal && ( 121 | 128 | ) } 129 | 130 | ); 131 | } 132 | -------------------------------------------------------------------------------- /src/utils/components/settings/renderSettingControl.js: -------------------------------------------------------------------------------- 1 | const { Component } = wp.element; 2 | const { applyFilters } = wp.hooks; 3 | 4 | import getCurrentUserData from './../data-providers/currentUserData'; 5 | 6 | /** 7 | * A wrapper that contains user data for making decisions when rendering block setting controls. 8 | */ 9 | export default class RenderSettingControl extends Component { 10 | render() { 11 | if ( 'undefined' === typeof this.props.children ) { 12 | return null; 13 | } 14 | 15 | /** 16 | * Let the temporary hacks begin. 17 | * Get the block name this setting is associated with. 18 | */ 19 | let fallback = false; 20 | 21 | if ( 22 | 'undefined' === typeof this.props.children.props || 23 | 'undefined' === typeof this.props.children.props.name 24 | ) { 25 | fallback = true; 26 | } 27 | 28 | if ( 29 | fallback && 30 | ( 'undefined' === typeof this.props.children._owner || 31 | 'undefined' === 32 | typeof this.props.children._owner.memoizedProps || 33 | 'undefined' === 34 | typeof this.props.children._owner.memoizedProps.name ) 35 | ) { 36 | return this.props.children; 37 | } 38 | 39 | const blockName = fallback 40 | ? this.props.children._owner.memoizedProps.name 41 | : this.props.children.props.name; 42 | 43 | /** 44 | * A filter for determining whether or not a setting should be rendered. 45 | * 46 | * @param {boolean} Whether or not the setting control should be rendered. Default true. 47 | * @param {string} The block name. 48 | * @param {string} The setting control's ID. 49 | * @param {Object} The current user's data. 50 | */ 51 | if ( 52 | applyFilters( 53 | 'ab_should_render_block_setting', 54 | true, 55 | blockName, 56 | this.props.id, 57 | getCurrentUserData() 58 | ) 59 | ) { 60 | return this.props.children; 61 | } 62 | 63 | return null; 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /src/utils/helper.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Helper Functions 3 | */ 4 | 5 | // Import helper dependencies 6 | import md5 from 'md5'; 7 | 8 | // Calculate the font size 9 | export function fontRatioToClass( ratio ) { 10 | return 0 === ratio || 50 === ratio 11 | ? null 12 | : 'font-size-' + 1 * Math.round( ratio / 1 ); 13 | } 14 | 15 | // Generate a unique ID for the notice block 16 | export function generateUniqueID( input ) { 17 | return md5( input ).substr( 0, 6 ); 18 | } 19 | -------------------------------------------------------------------------------- /src/utils/inspector/margin.js: -------------------------------------------------------------------------------- 1 | const { __ } = wp.i18n; 2 | const { Fragment } = wp.element; 3 | const { RangeControl } = wp.components; 4 | 5 | export default function MarginSettings( props ) { 6 | const { 7 | // Margin top props 8 | marginTop, 9 | marginTopLabel, 10 | marginTopMin, 11 | marginTopMax, 12 | marginEnableTop, 13 | onChangeMarginTop = () => {}, 14 | 15 | // Margin right props 16 | marginRight, 17 | marginRightLabel, 18 | marginRightMin, 19 | marginRightMax, 20 | marginEnableRight, 21 | onChangeMarginRight = () => {}, 22 | 23 | // Margin bottom props 24 | marginBottom, 25 | marginBottomLabel, 26 | marginBottomMin, 27 | marginBottomMax, 28 | marginEnableBottom, 29 | onChangeMarginBottom = () => {}, 30 | 31 | // Margin left props 32 | marginLeft, 33 | marginLeftLabel, 34 | marginLeftMin, 35 | marginLeftMax, 36 | marginEnableLeft, 37 | onChangeMarginLeft = () => {}, 38 | 39 | // Margin vertical props 40 | marginVertical, 41 | marginVerticalLabel, 42 | marginEnableVertical, 43 | marginVerticalMin, 44 | marginVerticalMax, 45 | onChangeMarginVertical = () => {}, 46 | 47 | // Margin horizontal props 48 | marginHorizontal, 49 | marginHorizontalLabel, 50 | marginEnableHorizontal, 51 | marginHorizontalMin, 52 | marginHorizontalMax, 53 | onChangeMarginHorizontal = () => {}, 54 | } = props; 55 | 56 | return ( 57 | 58 | { marginEnableTop && ( 59 | 70 | ) } 71 | { marginEnableRight && ( 72 | 83 | ) } 84 | { marginEnableBottom && ( 85 | 96 | ) } 97 | { marginEnableLeft && ( 98 | 109 | ) } 110 | { marginEnableVertical && ( 111 | 122 | ) } 123 | { marginEnableHorizontal && ( 124 | 135 | ) } 136 | 137 | ); 138 | } 139 | -------------------------------------------------------------------------------- /src/utils/inspector/padding.js: -------------------------------------------------------------------------------- 1 | const { __ } = wp.i18n; 2 | const { Fragment } = wp.element; 3 | const { RangeControl } = wp.components; 4 | 5 | export default function Padding( props ) { 6 | const { 7 | // Padding props 8 | padding, 9 | paddingTitle, 10 | paddingHelp, 11 | paddingMin, 12 | paddingMax, 13 | paddingEnable, 14 | onChangePadding = () => {}, 15 | 16 | // Padding top props 17 | paddingTop, 18 | paddingTopMin, 19 | paddingTopMax, 20 | paddingEnableTop, 21 | onChangePaddingTop = () => {}, 22 | 23 | // Padding right props 24 | paddingRight, 25 | paddingRightMin, 26 | paddingRightMax, 27 | paddingEnableRight, 28 | onChangePaddingRight = () => {}, 29 | 30 | // Padding bottom props 31 | paddingBottom, 32 | paddingBottomMin, 33 | paddingBottomMax, 34 | paddingEnableBottom, 35 | onChangePaddingBottom = () => {}, 36 | 37 | // Padding left props 38 | paddingLeft, 39 | paddingLeftMin, 40 | paddingLeftMax, 41 | paddingEnableLeft, 42 | onChangePaddingLeft = () => {}, 43 | 44 | // Padding vertical props 45 | paddingVertical, 46 | paddingEnableVertical, 47 | paddingVerticalMin, 48 | paddingVerticalMax, 49 | onChangePaddingVertical = () => {}, 50 | 51 | // Padding horizontal props 52 | paddingHorizontal, 53 | paddingEnableHorizontal, 54 | paddingHorizontalMin, 55 | paddingHorizontalMax, 56 | onChangePaddingHorizontal = () => {}, 57 | } = props; 58 | 59 | return ( 60 | 61 | { paddingEnable && ( 62 | 74 | ) } 75 | { paddingEnableTop && ( 76 | 83 | ) } 84 | { paddingEnableRight && ( 85 | 92 | ) } 93 | { paddingEnableBottom && ( 94 | 101 | ) } 102 | { paddingEnableLeft && ( 103 | 110 | ) } 111 | { paddingEnableVertical && ( 112 | 119 | ) } 120 | { paddingEnableHorizontal && ( 121 | 128 | ) } 129 | 130 | ); 131 | } 132 | -------------------------------------------------------------------------------- /tests/bootstrap.php: -------------------------------------------------------------------------------- 1 | /config/setup-test-framework.js', 6 | '@wordpress/jest-console', 7 | 'expect-puppeteer', 8 | ], 9 | }; 10 | -------------------------------------------------------------------------------- /tests/e2e/specs/add-blocks.js: -------------------------------------------------------------------------------- 1 | /** 2 | * WordPress dependencies 3 | */ 4 | import { 5 | createNewPost, 6 | insertBlock, 7 | saveDraft, 8 | } from '@wordpress/e2e-test-utils'; 9 | 10 | describe( 'Add Blocks', () => { 11 | it( 'inserts blocks with the inserter', async () => { 12 | await createNewPost(); 13 | 14 | await insertBlock( 'Accordion' ); 15 | await insertBlock( 'Advanced Columns' ); 16 | await insertBlock( 'Button' ); 17 | await insertBlock( 'Container' ); 18 | await insertBlock( 'Call To Action' ); 19 | await insertBlock( 'Drop Cap' ); 20 | await insertBlock( 'Email newsletter' ); 21 | await insertBlock( 'Notice' ); 22 | await insertBlock( 'Post and Page Grid' ); 23 | await insertBlock( 'Pricing' ); 24 | await insertBlock( 'Profile Box' ); 25 | await insertBlock( 'Sharing' ); 26 | await insertBlock( 'Spacer' ); 27 | await insertBlock( 'Testimonial' ); 28 | await insertBlock( 'Layouts' ); 29 | } ); 30 | 31 | it( 'saves the entered value in the Call To Action block', async () => { 32 | await createNewPost(); 33 | 34 | await insertBlock( 'Call To Action' ); 35 | await page.focus( '.block-editor-block-list__block [role="textbox"]' ); 36 | const ctaTitle = 'This is an example CTA title'; 37 | await page.keyboard.type( ctaTitle ); 38 | 39 | await expect( page ).toMatch( ctaTitle ); 40 | } ); 41 | } ); 42 | -------------------------------------------------------------------------------- /tests/integration/migration/test-redirect.php: -------------------------------------------------------------------------------- 1 | instance = new Redirect(); 40 | } 41 | 42 | /** 43 | * Tears down after each test. 44 | */ 45 | public function tearDown() { 46 | delete_option( self::REDIRECT_OPTION_NAME ); 47 | parent::tearDown(); 48 | } 49 | 50 | /** 51 | * Test redirect_after_upgrade. 52 | */ 53 | public function test_redirect_after_upgrade_wrong_user() { 54 | $this->instance->redirect_after_upgrade( new stdClass(), [] ); 55 | $this->assertFalse( get_option( self::REDIRECT_OPTION_NAME ) ); 56 | } 57 | 58 | /** 59 | * Test redirect_after_upgrade. 60 | */ 61 | public function test_redirect_after_upgrade_correct_user_wrong_plugin() { 62 | wp_set_current_user( $this->factory()->user->create( [ 'role' => 'administrator' ] ) ); 63 | $this->instance->redirect_after_upgrade( new stdClass(), [ 'plugins' => [ 'foo/foo.php' ] ] ); 64 | 65 | $this->assertFalse( get_option( self::REDIRECT_OPTION_NAME ) ); 66 | } 67 | 68 | /** 69 | * Test redirect_after_upgrade. 70 | */ 71 | public function test_redirect_after_upgrade_correct_user_correct_plugin() { 72 | wp_set_current_user( $this->factory()->user->create( [ 'role' => 'administrator' ] ) ); 73 | $this->instance->redirect_after_upgrade( new stdClass(), [ 'plugins' => [ 'atomic-blocks/atomicblocks.php' ] ] ); 74 | 75 | $this->assertTrue( get_option( self::REDIRECT_OPTION_NAME ) ); 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /tests/integration/newsletter/test-newsletter-functions.php: -------------------------------------------------------------------------------- 1 | assertWPError( $response ); 34 | $this->assertSame( $response->get_error_code(), 'invalid_email' ); 35 | } 36 | 37 | /** 38 | * Tests newsletter form submission processing. 39 | * 40 | * @covers ::process_submission 41 | */ 42 | public function test_process_submission_with_invalid_provider() { 43 | $response = process_submission( 'test@example.com', false, [] ); 44 | $this->assertWPError( $response ); 45 | $this->assertSame( $response->get_error_code(), 'invalid_provider' ); 46 | } 47 | 48 | /** 49 | * Tests newsletter form submission processing. 50 | * 51 | * @covers ::process_submission 52 | */ 53 | public function test_process_submission_with_invalid_list_id() { 54 | $response = process_submission( 'test@example.com', 'mailchimp', [] ); 55 | $this->assertWPError( $response ); 56 | $this->assertSame( $response->get_error_code(), 'invalid_list_id' ); 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /webpack.config.js: -------------------------------------------------------------------------------- 1 | const ExtractText = require( 'extract-text-webpack-plugin' ); 2 | const path = require('path'); 3 | 4 | const devMode = process.env.NODE_ENV !== 'production'; 5 | 6 | const editorStyles = new ExtractText( { 7 | filename: './blocks.editor.build.css', 8 | } ); 9 | 10 | const frontendStyles = new ExtractText( { 11 | filename: './blocks.style.build.css', 12 | } ); 13 | 14 | const plugins = [ editorStyles, frontendStyles ]; 15 | 16 | const scssConfig = { 17 | use: [ 18 | { 19 | loader: 'css-loader', 20 | }, 21 | { 22 | loader: 'sass-loader', 23 | options: { 24 | prependData: '@import "./src/common.scss";\n', 25 | }, 26 | }, 27 | ], 28 | }; 29 | 30 | module.exports = { 31 | context: __dirname, 32 | devtool: devMode ? 'inline-sourcemap' : false, 33 | mode: devMode ? 'development' : 'production', 34 | entry: { 35 | blocks: './src/blocks.js', 36 | }, 37 | output: { 38 | path: __dirname + '/dist/', 39 | filename: '[name].build.js', 40 | }, 41 | module: { 42 | rules: [ 43 | { 44 | test: /\.js$/, 45 | exclude: [ 46 | path.resolve( __dirname, 'node_modules' ), 47 | path.resolve( __dirname, 'build' ), 48 | path.resolve( __dirname, 'vendor' ), 49 | ], 50 | use: [ 51 | { 52 | loader: 'babel-loader', 53 | options: { 54 | presets: [ '@babel/preset-react' ], 55 | }, 56 | }, 57 | ], 58 | }, 59 | { 60 | test: /editor\.scss$/, 61 | exclude: [ 62 | path.resolve( __dirname, 'node_modules' ), 63 | path.resolve( __dirname, 'build' ), 64 | path.resolve( __dirname, 'vendor' ), 65 | ], 66 | use: editorStyles.extract( scssConfig ), 67 | }, 68 | { 69 | test: /style\.scss$/, 70 | exclude: [ 71 | path.resolve( __dirname, 'node_modules' ), 72 | path.resolve( __dirname, 'build' ), 73 | path.resolve( __dirname, 'vendor' ), 74 | ], 75 | use: frontendStyles.extract( scssConfig ), 76 | }, 77 | ], 78 | }, 79 | plugins, 80 | }; 81 | --------------------------------------------------------------------------------