├── .blockbook
├── index.js
└── themes
│ └── twenty-nineteen.css
├── .editorconfig
├── .eslintrc.js
├── .github
└── workflows
│ └── deploy-book.yml
├── .gitignore
├── .nvmrc
├── .prettierrc.js
├── .wp-env.json
├── README.md
├── babel.config.js
├── block-experiments.php
├── blocks
├── bauhaus-centenary
│ ├── editor.scss
│ ├── index.php
│ ├── src
│ │ ├── categories.js
│ │ ├── colors.js
│ │ ├── edit.js
│ │ ├── forms.js
│ │ ├── heights.js
│ │ ├── icon.js
│ │ ├── index.js
│ │ ├── radio-button-group.js
│ │ ├── ribbon.js
│ │ ├── save.js
│ │ └── year.js
│ └── style.scss
├── book
│ ├── editor.scss
│ ├── index.php
│ ├── src
│ │ ├── edit.js
│ │ ├── icon.js
│ │ ├── index.js
│ │ ├── prefixClasses.js
│ │ ├── rating.js
│ │ └── save.js
│ └── style.scss
├── duotone-filter
│ └── readme.md
├── event
│ ├── editor.scss
│ ├── index.php
│ ├── src
│ │ ├── date-select.js
│ │ ├── edit.js
│ │ ├── icons.js
│ │ ├── index.js
│ │ └── save.js
│ └── style.scss
├── image-compare
│ └── readme.md
├── layout-grid
│ ├── constants.scss
│ ├── editor.scss
│ ├── index.php
│ ├── src
│ │ ├── __tests__
│ │ │ ├── __image_snapshots__
│ │ │ │ ├── four-column-desktop-snap.png
│ │ │ │ ├── four-column-mobile-snap.png
│ │ │ │ ├── four-column-tablet-snap.png
│ │ │ │ ├── one-column-desktop-snap.png
│ │ │ │ ├── one-column-mobile-snap.png
│ │ │ │ ├── one-column-tablet-snap.png
│ │ │ │ ├── three-column-desktop-snap.png
│ │ │ │ ├── three-column-mobile-snap.png
│ │ │ │ ├── three-column-tablet-snap.png
│ │ │ │ ├── two-column-custom-background-desktop-snap.png
│ │ │ │ ├── two-column-custom-background-mobile-snap.png
│ │ │ │ ├── two-column-custom-background-tablet-snap.png
│ │ │ │ ├── two-column-desktop-snap.png
│ │ │ │ ├── two-column-mobile-snap.png
│ │ │ │ ├── two-column-no-gutters-desktop-snap.png
│ │ │ │ ├── two-column-no-gutters-mobile-snap.png
│ │ │ │ ├── two-column-no-gutters-tablet-snap.png
│ │ │ │ └── two-column-tablet-snap.png
│ │ │ ├── invalidations.js
│ │ │ ├── migrations.js
│ │ │ └── visual-test.js
│ │ ├── constants.js
│ │ ├── grid-column
│ │ │ ├── deprecated.js
│ │ │ ├── edit.js
│ │ │ ├── edit.native.js
│ │ │ ├── edit.native.scss
│ │ │ ├── hooks
│ │ │ │ └── with-update-alignment.js
│ │ │ └── save.js
│ │ ├── grid-overlay.scss
│ │ ├── grid-resize.scss
│ │ ├── grid.scss
│ │ ├── grid
│ │ │ ├── css-classname.js
│ │ │ ├── edit.js
│ │ │ ├── edit.native.js
│ │ │ ├── edit.native.scss
│ │ │ ├── grid-defaults.js
│ │ │ ├── higher-order.js
│ │ │ ├── layout-grid
│ │ │ │ └── index.js
│ │ │ ├── preview-device.js
│ │ │ ├── resize-grid
│ │ │ │ ├── index.js
│ │ │ │ ├── nearest.js
│ │ │ │ └── resize-handle.js
│ │ │ ├── save.js
│ │ │ ├── variation-control
│ │ │ │ ├── index.native.js
│ │ │ │ └── style.native.scss
│ │ │ └── variations.js
│ │ ├── icons.js
│ │ └── index.js
│ ├── style.scss
│ └── tests
│ │ ├── fixtures
│ │ ├── invalidation
│ │ │ ├── 1-1-padding-color.html
│ │ │ ├── 1.0-color.html
│ │ │ ├── 1.0-default.html
│ │ │ ├── 1.1-default.html
│ │ │ ├── 1.2-default.html
│ │ │ └── 1.2-padding-color.html
│ │ ├── migration
│ │ │ └── 1.3-custom-color.html
│ │ └── visual
│ │ │ ├── four-column.html
│ │ │ ├── one-column.html
│ │ │ ├── three-column.html
│ │ │ ├── two-column-custom-background.html
│ │ │ ├── two-column-no-gutters.html
│ │ │ └── two-column.html
│ │ └── tools
│ │ ├── block.js
│ │ ├── fixtures.js
│ │ └── style.css
├── model-viewer
│ ├── editor.scss
│ ├── index.json
│ ├── index.php
│ ├── model-viewer.min.js
│ ├── src
│ │ ├── edit.js
│ │ ├── icon.js
│ │ ├── index.js
│ │ ├── save.js
│ │ └── utils.js
│ └── style.scss
├── motion-background
│ └── README.md
├── rich-image
│ └── readme.md
├── sketch
│ ├── editor.scss
│ ├── index.php
│ ├── src
│ │ ├── controls.js
│ │ ├── edit.js
│ │ ├── example.json
│ │ ├── icons.js
│ │ ├── index.js
│ │ ├── lib.js
│ │ └── save.js
│ └── style.scss
├── starscape
│ ├── README.md
│ ├── editor.scss
│ ├── index.php
│ ├── src
│ │ ├── attributes.js
│ │ ├── constants.js
│ │ ├── deprecated
│ │ │ ├── index.js
│ │ │ ├── v1
│ │ │ │ ├── generated.json
│ │ │ │ ├── index.js
│ │ │ │ ├── save.js
│ │ │ │ └── starscape.js
│ │ │ └── v2
│ │ │ │ ├── attributes.js
│ │ │ │ ├── index.js
│ │ │ │ ├── save.js
│ │ │ │ ├── starscape.js
│ │ │ │ └── utils.js
│ │ ├── edit.js
│ │ ├── icon.js
│ │ ├── index.js
│ │ ├── save.js
│ │ ├── starscape.js
│ │ └── utils.js
│ └── style.scss
└── waves
│ ├── editor.scss
│ ├── index.json
│ ├── index.php
│ ├── src
│ ├── edit.js
│ ├── icon.js
│ ├── index.js
│ └── save.js
│ ├── style.scss
│ ├── twgl
│ ├── twgl-full.d.ts
│ ├── twgl-full.js
│ ├── twgl-full.js.map
│ ├── twgl-full.min.js
│ ├── twgl-full.module.js
│ ├── twgl.d.ts
│ ├── twgl.js
│ ├── twgl.js.map
│ └── twgl.min.js
│ └── waves.js
├── bundler
├── assets
│ └── jetpack-layout-grid
│ │ ├── banner-1544x500.png
│ │ ├── banner-772x250.png
│ │ ├── icon-128x128.png
│ │ ├── icon-256x256.jpg
│ │ ├── icon.svg
│ │ ├── screenshot-1.png
│ │ └── screenshot-2.png
├── build
│ ├── build-tools.mjs
│ ├── everything.sh
│ └── index.mjs
├── bundles
│ ├── bauhaus-centenary.json
│ ├── event.json
│ ├── layout-grid.json
│ ├── model-viewer.json
│ ├── sketch.json
│ ├── starscape.json
│ └── waves.json
├── resources
│ ├── a8c-bauhaus-centenary
│ │ ├── assets
│ │ │ ├── banner-1544x500.png
│ │ │ ├── banner-772x250.png
│ │ │ ├── icon-128x128.png
│ │ │ ├── icon-256x256.png
│ │ │ ├── icon.svg
│ │ │ ├── screenshot-1.png
│ │ │ ├── screenshot-2.png
│ │ │ ├── screenshot-3.png
│ │ │ └── screenshot-4.png
│ │ ├── block.json
│ │ └── readme.txt
│ ├── a8c-event
│ │ ├── assets
│ │ │ ├── banner-1544x500.png
│ │ │ ├── banner-772x250.png
│ │ │ ├── icon-128x128.png
│ │ │ ├── icon-256x256.png
│ │ │ ├── icon.svg
│ │ │ ├── screenshot-1.png
│ │ │ └── screenshot-2.gif
│ │ ├── block.json
│ │ └── readme.txt
│ ├── a8c-model-viewer
│ │ ├── block.json
│ │ └── readme.txt
│ ├── a8c-sketch
│ │ ├── assets
│ │ │ ├── banner-1544x500.png
│ │ │ ├── banner-772x250.png
│ │ │ ├── icon-128x128.png
│ │ │ ├── icon-256x256.png
│ │ │ ├── icon.svg
│ │ │ ├── screenshot-1.png
│ │ │ └── screenshot-2.png
│ │ ├── block.json
│ │ └── readme.txt
│ ├── a8c-starscape
│ │ ├── assets
│ │ │ ├── banner-1544x500.png
│ │ │ ├── banner-772x250.png
│ │ │ ├── icon-128x128.png
│ │ │ ├── icon-256x256.png
│ │ │ ├── icon.svg
│ │ │ ├── screenshot-1.png
│ │ │ ├── screenshot-2.png
│ │ │ ├── screenshot-3.png
│ │ │ └── screenshot-4.png
│ │ ├── block.json
│ │ └── readme.txt
│ ├── a8c-waves
│ │ ├── assets
│ │ │ ├── banner-1544-500.png
│ │ │ ├── banner-1544x500.png
│ │ │ ├── banner-772x250.png
│ │ │ ├── icon-128x128.png
│ │ │ ├── icon-256x256.png
│ │ │ ├── icon.svg
│ │ │ ├── screenshot-1.png
│ │ │ ├── screenshot-2.png
│ │ │ ├── screenshot-3.png
│ │ │ ├── screenshot-4.png
│ │ │ └── screenshot-5.gif
│ │ ├── block.json
│ │ └── readme.txt
│ ├── jetpack-layout-grid
│ │ ├── block.json
│ │ └── readme.txt
│ └── license.txt
├── template
│ ├── index.js
│ └── index.php
└── webpack.config.js
├── composer.json
├── composer.lock
├── config
└── jest-before.js
├── editor.scss
├── jest.config.js
├── lib
├── svg-dom-to-blob
│ └── index.js
└── upload-image
│ └── index.js
├── package.json
├── phpcs.xml.dist
├── src
├── block-icons.js
└── index.js
├── style.scss
├── webpack.config.js
└── yarn.lock
/.blockbook/index.js:
--------------------------------------------------------------------------------
1 | import { registerBlockType, registerTheme } from 'blockbook-api';
2 |
3 | // Register blocks
4 | import * as bauhausCentenaryBlock from '../blocks/bauhaus-centenary/src';
5 | import * as eventBlock from '../blocks/event/src';
6 | import * as starscapeBlock from '../blocks/starscape/src';
7 | import * as wavesBlock from '../blocks/waves/src';
8 | import * as ThreeDeeModelBlock from '../blocks/waves/src';
9 | import '../build/style.css';
10 | import '../build/editor.css';
11 |
12 | bauhausCentenaryBlock.registerBlock();
13 | eventBlock.registerBlock();
14 | starscapeBlock.registerBlock();
15 | wavesBlock.registerBlock();
16 | ThreeDeeModelBlock.registerBlock();
17 |
18 | registerBlockType( 'a8c/bauhaus-centenary' );
19 | registerBlockType( 'a8c/event' );
20 | registerBlockType( 'a8c/starscape' );
21 | registerBlockType( 'a8c/waves' );
22 | registerBlockType( 'a8c/model-viewer' );
23 |
24 | // Regiseter themes
25 | import twentyNineteenStyle from '!!raw-loader!./themes/twenty-nineteen.css';
26 | registerTheme( {
27 | name: 'twenty-nineteen',
28 | title: 'TwentyNineteen',
29 | editorStyles: twentyNineteenStyle,
30 | } );
31 |
--------------------------------------------------------------------------------
/.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
22 |
23 | [*.{gradle,java,kt}]
24 | indent_style = space
25 |
26 | [packages/react-native-*/**.xml]
27 | indent_style = space
28 |
--------------------------------------------------------------------------------
/.github/workflows/deploy-book.yml:
--------------------------------------------------------------------------------
1 | name: GitHub Pages
2 |
3 | on:
4 | push:
5 | branches:
6 | - master
7 |
8 | jobs:
9 | deploy:
10 | runs-on: ubuntu-latest
11 | steps:
12 | - name: Checkout
13 | uses: actions/checkout@v2
14 | with:
15 | ref: master
16 |
17 | - name: Setup Node
18 | uses: actions/setup-node@v1
19 | with:
20 | node-version: '12.x'
21 |
22 | - name: Install Dependencies
23 | run: yarn install
24 |
25 | - name: Build BlockBook
26 | run: yarn install && yarn blockbook:build -- --output-public-path=/block-experiments && cp dist/index.html dist/404.html
27 |
28 | - name: Deploy
29 | uses: peaceiris/actions-gh-pages@v3
30 | with:
31 | github_token: ${{ secrets.GITHUB_TOKEN }}
32 | publish_dir: ./dist
33 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 | /node_modules
3 | /plugin
4 | /bundles
5 | /vendor
6 | /dist
7 | /.idea
8 | yarn-error.log
9 | .DS_Store
10 |
--------------------------------------------------------------------------------
/.nvmrc:
--------------------------------------------------------------------------------
1 | 20
2 |
--------------------------------------------------------------------------------
/.prettierrc.js:
--------------------------------------------------------------------------------
1 | // Import the default config file and expose it in the project root.
2 | // Useful for editor integrations.
3 | module.exports = require( '@wordpress/prettier-config' );
4 |
--------------------------------------------------------------------------------
/.wp-env.json:
--------------------------------------------------------------------------------
1 | {
2 | "core": "WordPress/WordPress#master",
3 | "plugins": [ "." ],
4 | "config": {
5 | "SCRIPT_DEBUG": true
6 | }
7 | }
8 |
--------------------------------------------------------------------------------
/babel.config.js:
--------------------------------------------------------------------------------
1 | module.exports = ( api ) => {
2 | api.cache( true );
3 |
4 | return {
5 | presets: [ '@wordpress/babel-preset-default' ],
6 | plugins: [ '@emotion/babel-plugin', 'babel-plugin-inline-json-import' ],
7 | };
8 | };
9 |
--------------------------------------------------------------------------------
/block-experiments.php:
--------------------------------------------------------------------------------
1 | [],
27 | 'fill' => [],
28 | 'role' => [],
29 | 'aria-hidden' => [],
30 | 'focusable' => [],
31 | 'style' => [],
32 | 'height' => [],
33 | 'width' => [],
34 | 'viewbox' => [],
35 | 'preserveaspectratio' => [],
36 | ];
37 |
38 | $tags['path'] = [
39 | 'class' => [],
40 | 'd' => [],
41 | 'opacity' => [],
42 | 'fill' => [],
43 | 'fillrule' => [],
44 | 'fillopacity' => [],
45 | 'transform' => [],
46 | 'stroke' => [],
47 | ];
48 |
49 | $tags['rect'] = [
50 | 'd' => [],
51 | 'opacity' => [],
52 | 'fill' => [],
53 | 'fillrule' => [],
54 | 'transform' => [],
55 | 'width' => [],
56 | 'height' => [],
57 | 'y' => [],
58 | ];
59 |
60 | $tags['circle'] = [
61 | 'class' => [],
62 | 'cx' => [],
63 | 'cy' => [],
64 | 'r' => [],
65 | ];
66 |
67 | $tags['polygon'] = [
68 | 'points' => [],
69 | 'fill' => [],
70 | ];
71 |
72 | $tags['iframe'] = [
73 | 'title' => [],
74 | 'allowfullscreen' => [],
75 | 'frameborder' => [],
76 | 'width' => [],
77 | 'height' => [],
78 | 'src' => [],
79 | ];
80 |
81 | return $tags;
82 | }, 10, 2);
83 |
84 | $asset_file = plugin_dir_path( __FILE__ ) . 'build/index.asset.php';
85 | $asset = file_exists( $asset_file )
86 | ? require_once $asset_file
87 | : null;
88 | $dependencies = isset( $asset['dependencies'] ) ?
89 | $asset['dependencies'] :
90 | [];
91 | $version = isset( $asset['version'] ) ?
92 | $asset['version'] :
93 | filemtime( plugin_dir_path( __FILE__ ) . 'build/index.js' );
94 |
95 | // Block JS
96 | wp_register_script(
97 | 'block-experiments',
98 | plugins_url( 'build/index.js', __FILE__ ),
99 | $dependencies,
100 | $version,
101 | true
102 | );
103 |
104 | // Block front end style
105 | wp_register_style(
106 | 'block-experiments',
107 | plugins_url( 'build/style.css', __FILE__ ),
108 | [],
109 | filemtime( plugin_dir_path( __FILE__ ) . 'build/style.css' )
110 | );
111 |
112 | // Block editor style
113 | wp_register_style(
114 | 'block-experiments-editor',
115 | plugins_url( 'build/editor.css', __FILE__ ),
116 | [],
117 | filemtime( plugin_dir_path( __FILE__ ) . 'build/editor.css' )
118 | );
119 | } );
120 |
--------------------------------------------------------------------------------
/blocks/bauhaus-centenary/editor.scss:
--------------------------------------------------------------------------------
1 | // Editor-only styles
2 | .wp-block-a8c-bauhaus-centenary {
3 | .components-placeholder__label svg {
4 | margin-right: 0.75em;
5 | }
6 |
7 | .icon-button svg {
8 | // IE11 requires a fixed width & height for SVGs. Values are calculated
9 | // from what `height: 100%` and `width: auto` would have resulted in.
10 | height: 26px;
11 | width: 39px;
12 | }
13 | }
14 |
15 | .styles-panel {
16 | cursor: pointer;
17 | border-radius: 4px;
18 | padding: 4px;
19 | margin-bottom: 0.5em;
20 |
21 | &.is-selected {
22 | box-shadow: 0 0 0 2px #555d66;
23 | }
24 |
25 | &:focus {
26 | box-shadow: 0 0 0 2px #00a0d2;
27 | }
28 |
29 | &:hover {
30 | background-color: #f3f4f5;
31 | color: #191e23;
32 | }
33 |
34 | &__preview {
35 | border: 1px solid rgba( 25, 30, 35, 0.2 );
36 | border-radius: 4px;
37 | background-color: #fff;
38 | padding: 4px;
39 |
40 | svg {
41 | border-radius: 4px;
42 | display: block;
43 | width: 100%;
44 | height: auto;
45 | }
46 | }
47 |
48 | &__label {
49 | text-align: center;
50 | margin-bottom: 0;
51 | }
52 | }
53 |
54 | .components-button-group.is-radio-group {
55 | display: flex;
56 | margin-bottom: 0.5em;
57 |
58 | .components-button.is-button {
59 | display: inline-block;
60 | flex-grow: 1;
61 | }
62 | }
63 |
--------------------------------------------------------------------------------
/blocks/bauhaus-centenary/index.php:
--------------------------------------------------------------------------------
1 | 'block-experiments',
14 | 'style' => 'block-experiments',
15 | 'editor_style' => 'block-experiments-editor',
16 | ]
17 | );
18 |
19 | wp_set_script_translations( 'block-experiments', 'bauhaus-centenary' );
20 | } );
21 |
--------------------------------------------------------------------------------
/blocks/bauhaus-centenary/src/categories.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Internal dependencies
3 | */
4 | import forms from './forms';
5 | import year from './year';
6 | import ribbon from './ribbon';
7 |
8 | export default { forms, year, ribbon };
9 |
--------------------------------------------------------------------------------
/blocks/bauhaus-centenary/src/colors.js:
--------------------------------------------------------------------------------
1 | /**
2 | * WordPress dependencies
3 | */
4 | import { __ } from '@wordpress/i18n';
5 |
6 | export default [
7 | { name: __( 'Black', 'bauhaus-centenary' ), color: '#000000' },
8 | { name: __( 'Blue', 'bauhaus-centenary' ), color: '#051BF4' },
9 | { name: __( 'Red', 'bauhaus-centenary' ), color: '#D32121' },
10 | { name: __( 'Yellow', 'bauhaus-centenary' ), color: '#F7FC1C' },
11 | { name: __( 'White', 'bauhaus-centenary' ), color: '#FFFFFF' },
12 | ];
13 |
--------------------------------------------------------------------------------
/blocks/bauhaus-centenary/src/forms.js:
--------------------------------------------------------------------------------
1 | /**
2 | * External dependencies
3 | */
4 | import classnames from 'classnames';
5 |
6 | /**
7 | * WordPress dependencies
8 | */
9 | import { __ } from '@wordpress/i18n';
10 |
11 | /**
12 | * Internal dependencies
13 | */
14 | import * as Icon from './icon';
15 |
16 | const Forms = ( { className, attributes } ) => {
17 | return (
18 |
19 |
20 |
21 |
22 |
23 | );
24 | };
25 |
26 | const Content = Forms;
27 |
28 | export default Object.assign( Forms, {
29 | label: __( 'Forms', 'bauhaus-centenary' ),
30 | icon: ,
31 | preview: ,
32 | Content,
33 | } );
34 |
--------------------------------------------------------------------------------
/blocks/bauhaus-centenary/src/heights.js:
--------------------------------------------------------------------------------
1 | /**
2 | * WordPress dependencies
3 | */
4 | import { __ } from '@wordpress/i18n';
5 |
6 | export default [
7 | { label: __( 'Small', 'bauhaus-centenary' ), value: 64 },
8 | { label: __( 'Medium', 'bauhaus-centenary' ), value: 128 },
9 | { label: __( 'Large', 'bauhaus-centenary' ), value: 256 },
10 | ];
11 |
--------------------------------------------------------------------------------
/blocks/bauhaus-centenary/src/index.js:
--------------------------------------------------------------------------------
1 | /**
2 | * WordPress dependencies
3 | */
4 | import { registerBlockType } from '@wordpress/blocks';
5 | import { __ } from '@wordpress/i18n';
6 |
7 | /**
8 | * Internal dependencies
9 | */
10 | import Edit from './edit';
11 | import Save from './save';
12 | import { BauhausIcon } from './icon';
13 |
14 | export const registerBlock = () => {
15 | registerBlockType( 'a8c/bauhaus-centenary', {
16 | title: 'Bauhaus Centenary',
17 | description: __( 'Celebrate the centenary of the design school', 'bauhaus-centenary' ),
18 | icon: BauhausIcon,
19 | category: 'widgets',
20 | supports: {
21 | align: true,
22 | },
23 | attributes: {
24 | align: {
25 | type: 'string',
26 | default: 'center',
27 | },
28 | caption: {
29 | type: 'string',
30 | },
31 | height: {
32 | type: 'integer',
33 | default: 128,
34 | },
35 | category: {
36 | type: 'string',
37 | },
38 | backgroundColor: {
39 | type: 'string',
40 | },
41 | customBackgroundColor: {
42 | type: 'string',
43 | },
44 | fill1Color: {
45 | type: 'string',
46 | },
47 | fill2Color: {
48 | type: 'string',
49 | },
50 | fill3Color: {
51 | type: 'string',
52 | },
53 | year: {
54 | type: 'string',
55 | default: '1919',
56 | },
57 | },
58 | edit: ( props ) => ,
59 | save: ( props ) => ,
60 | } );
61 | };
62 |
--------------------------------------------------------------------------------
/blocks/bauhaus-centenary/src/radio-button-group.js:
--------------------------------------------------------------------------------
1 | /**
2 | * External dependencies
3 | */
4 | import classnames from 'classnames';
5 |
6 | /**
7 | * WordPress dependencies
8 | */
9 | import { Button } from '@wordpress/components';
10 |
11 | const RadioButtonGroup = ( { options, selected, onChange, className, ...props } ) => (
12 |
23 | { options.map( ( { label, value } ) => (
24 |
34 | ) ) }
35 |
36 | );
37 |
38 | export default RadioButtonGroup;
39 |
--------------------------------------------------------------------------------
/blocks/bauhaus-centenary/src/ribbon.js:
--------------------------------------------------------------------------------
1 | /**
2 | * WordPress dependencies
3 | */
4 | import { __ } from '@wordpress/i18n';
5 |
6 | /**
7 | * Internal dependencies
8 | */
9 | import * as Icon from './icon';
10 |
11 | const Ribbon = ( { attributes } ) => {
12 | const props = {
13 | style: { height: attributes.height },
14 | role: 'img',
15 | 'aria-hidden': true,
16 | };
17 |
18 | const iconProps = {
19 | fill1: attributes.fill1Color,
20 | fill2: attributes.fill2Color,
21 | fill3: attributes.fill3Color,
22 | };
23 |
24 | if ( attributes.align === 'full' ) {
25 | return (
26 |
27 |
28 |
29 |
30 |
31 | );
32 | }
33 |
34 | return (
35 |
36 |
37 |
38 |
39 | );
40 | };
41 |
42 | const Content = Ribbon;
43 |
44 | export default Object.assign( Ribbon, {
45 | label: __( 'Ribbon', 'bauhaus-centenary' ),
46 | icon: ,
47 | preview: ,
48 | Content,
49 | } );
50 |
--------------------------------------------------------------------------------
/blocks/bauhaus-centenary/src/save.js:
--------------------------------------------------------------------------------
1 | /**
2 | * External dependencies
3 | */
4 | import classnames from 'classnames';
5 |
6 | /**
7 | * WordPress dependencies
8 | */
9 | import { RichText, getColorClassName } from '@wordpress/block-editor';
10 |
11 | /**
12 | * Internal dependencies
13 | */
14 | import categories from './categories';
15 |
16 | const Save = ( { attributes, className } ) => {
17 | const Category = categories[ attributes.category ];
18 |
19 | const style = {
20 | backgroundColor: attributes.customBackgroundColor,
21 | };
22 |
23 | const classNames = classnames(
24 | className,
25 | { [ `align${ attributes.align }` ]: attributes.align },
26 | getColorClassName( 'background-color', attributes.backgroundColor ),
27 | );
28 |
29 | return (
30 |
31 |
32 | { ! RichText.isEmpty( attributes.caption ) && }
33 |
34 | );
35 | };
36 |
37 | export default Save;
38 |
--------------------------------------------------------------------------------
/blocks/bauhaus-centenary/src/year.js:
--------------------------------------------------------------------------------
1 | /**
2 | * WordPress dependencies
3 | */
4 | import { __ } from '@wordpress/i18n';
5 | import { SelectControl } from '@wordpress/components';
6 |
7 | /**
8 | * Internal dependencies
9 | */
10 | import * as Icon from './icon';
11 |
12 | const variations = {
13 | 1919: Icon.Year1919,
14 | 2019: Icon.Year2019,
15 | range: Icon.YearRange,
16 | };
17 |
18 | const Year = ( { attributes } ) => {
19 | const YearVariation = variations[ attributes.year ];
20 | return (
21 |
28 | );
29 | };
30 |
31 | const Content = Year;
32 |
33 | const ExtraStyles = ( { attributes, setAttributes } ) => (
34 | setAttributes( { year } ) }
42 | />
43 | );
44 |
45 | export default Object.assign( Year, {
46 | label: __( 'Year', 'bauhaus-centenary' ),
47 | icon: ,
48 | preview: ,
49 | Content,
50 | ExtraStyles,
51 | } );
52 |
--------------------------------------------------------------------------------
/blocks/bauhaus-centenary/style.scss:
--------------------------------------------------------------------------------
1 | // Editor and View styles
2 | .wp-block-a8c-bauhaus-centenary {
3 | padding: 2rem 0;
4 | display: flex;
5 | flex-direction: column;
6 | justify-content: center;
7 | text-align: center;
8 | border-radius: 4px;
9 |
10 | .forms,
11 | .year,
12 | .ribbon {
13 | padding: 0 2rem;
14 | }
15 |
16 | .forms {
17 | display: flex;
18 | justify-content: center;
19 | align-content: center;
20 |
21 | svg {
22 | width: auto;
23 | margin-right: 1rem;
24 | }
25 | }
26 |
27 | .ribbon {
28 | display: flex;
29 |
30 | svg {
31 | height: 100%;
32 | }
33 |
34 | svg:first-child {
35 | flex-grow: 0;
36 | }
37 |
38 | svg:last-child {
39 | flex-grow: 1;
40 | }
41 | }
42 |
43 | &.alignfull {
44 | border-radius: 0;
45 |
46 | .ribbon {
47 | padding: 0;
48 |
49 | svg:first-child {
50 | flex-grow: 1;
51 | }
52 |
53 | svg:last-child {
54 | flex-grow: 3;
55 | }
56 | }
57 | }
58 |
59 | }
--------------------------------------------------------------------------------
/blocks/book/editor.scss:
--------------------------------------------------------------------------------
1 | /**
2 | * The following styles get applied inside the editor only.
3 | *
4 | * Replace them with your own styles or remove the file completely.
5 | */
6 |
7 | // This selector should be revisited if/when we can leverage lightBlockWrapper.
8 | .wp-block-a8c-book {
9 | .wp-block-a8c-book__cover {
10 | // Ensure the correct aspect ratio of the cover image, even when the source image is way too big.
11 | height: 100% !important; // Needs high specificity to override an inline style. Would be nice if this could be output by the component itself instead.
12 |
13 | // Make the placeholder look like a book.
14 | .components-placeholder {
15 | box-shadow: none;
16 | height: 100%;
17 | }
18 | }
19 |
20 | .wp-block-a8c-book__cover-placeholder {
21 | // Default to 33% width.
22 | min-width: 140px;
23 | min-height: 230px;
24 | width: 33% !important;
25 | padding-top: 50%;
26 |
27 | .components-placeholder {
28 | position: absolute;
29 | top: 0;
30 | right: 0;
31 | bottom: 0;
32 | left: 0;
33 | }
34 |
35 | // Hide the resize handles on the placeholder.
36 | .components-resizable-box__handle {
37 | display: none;
38 | }
39 | }
40 | }
41 |
42 | .wp-block[data-align='center'] > .wp-block-a8c-book {
43 | display: flex;
44 | flex-direction: column;
45 | align-items: center;
46 | }
47 | .wp-block[data-align='left'] > .wp-block-a8c-book {
48 | margin-right: 1em;
49 | }
50 |
51 | .wp-block[data-align='right'] > .wp-block-a8c-book {
52 | margin-left: 1em;
53 | }
54 |
55 | .wp-block[data-align='left'],
56 | .wp-block[data-align='right'] {
57 | > .wp-block-a8c-book {
58 | margin-top: 0;
59 | margin-bottom: 0;
60 | }
61 | }
62 |
--------------------------------------------------------------------------------
/blocks/book/index.php:
--------------------------------------------------------------------------------
1 | 'wpcom-blocks',
6 | 'style' => 'wpcom-blocks',
7 | 'editor_style' => 'wpcom-blocks-editor',
8 | ] );
9 | } );
10 |
--------------------------------------------------------------------------------
/blocks/book/src/icon.js:
--------------------------------------------------------------------------------
1 | /**
2 | * WordPress depedencies
3 | */
4 |
5 | import { Path, SVG } from '@wordpress/components';
6 |
7 | export const BookIcon = () => (
8 |
14 | );
15 |
--------------------------------------------------------------------------------
/blocks/book/src/index.js:
--------------------------------------------------------------------------------
1 | /**
2 | * WordPress dependencies
3 | */
4 | import { registerBlockType } from '@wordpress/blocks';
5 | import { __ } from '@wordpress/i18n';
6 |
7 | /**
8 | * External dependencies
9 | */
10 | import { BookIcon } from './icon';
11 |
12 | /**
13 | * Internal dependencies
14 | */
15 | import Edit from './edit';
16 | import save from './save';
17 |
18 | /**
19 | * Every block starts by registering a new block type definition.
20 | *
21 | * @see https://developer.wordpress.org/block-editor/developers/block-api/#registering-a-block
22 | */
23 | export function registerBlock() {
24 | registerBlockType( 'a8c/book', {
25 | attributes: {
26 | author: {
27 | type: 'string',
28 | },
29 | height: {
30 | type: 'number',
31 | },
32 | imageId: {
33 | type: 'number',
34 | },
35 | imageUrl: {
36 | type: 'string',
37 | source: 'attribute',
38 | selector: 'img',
39 | attribute: 'src',
40 | },
41 | publisher: {
42 | type: 'string',
43 | },
44 | publicationDate: {
45 | type: 'string',
46 | },
47 | summary: {
48 | type: 'string',
49 | },
50 | title: {
51 | type: 'string',
52 | },
53 | width: {
54 | type: 'number',
55 | },
56 | },
57 |
58 | title: __( 'Book', 'a8c' ),
59 | description: __(
60 | 'Show a book with cover and metadata such as author and publisher.',
61 | 'a8c'
62 | ),
63 |
64 | category: 'widgets',
65 | icon: BookIcon,
66 |
67 | supports: {
68 | // Removes support for an HTML mode.
69 | html: false,
70 | align: [ 'left', 'center', 'right' ],
71 | lightBlockWrapper: true,
72 | },
73 |
74 | edit: Edit,
75 | save,
76 | } );
77 | }
78 |
--------------------------------------------------------------------------------
/blocks/book/src/prefixClasses.js:
--------------------------------------------------------------------------------
1 | /**
2 | * The name of the class which represents the base for all the styles
3 | * on this block.
4 | */
5 | const CSS_NAMESPACE = 'wp-block-a8c-book';
6 |
7 | /**
8 | * Function that prefixes the given classes with the CSS_NAMESPACE. The idea is to
9 | * avoid having to write the basename all the time, which is required by the BEM standard.
10 | *
11 | * @param {String} classes -- A string of classnames to be prefixed with the base name.
12 | */
13 | export default function prefixClasses( classes ) {
14 | return classes
15 | .split( ' ' )
16 | .map( ( name ) => `${ CSS_NAMESPACE }${ name }` )
17 | .join( ' ' );
18 | }
19 |
--------------------------------------------------------------------------------
/blocks/book/src/rating.js:
--------------------------------------------------------------------------------
1 | import { useState } from 'react';
2 | import { Icon, starFilled, starEmpty, starHalf } from '@wordpress/icons';
3 |
4 | function isPastHalf( { currentTarget, clientX } ) {
5 | const boundingClient = currentTarget.getBoundingClientRect();
6 | const mouseAt = Math.round( Math.abs( clientX - boundingClient.left ) );
7 |
8 | return mouseAt > boundingClient.width / 2;
9 | }
10 |
11 | export default function Rating( { isEditing = false, rating = 0, onRate } ) {
12 | const [ selectedRating, setSelectedRating ] = useState( rating );
13 | const [ hovering, setHovering ] = useState( false );
14 |
15 | const handleHover = ( index ) => ( event ) => {
16 | if ( ! isEditing ) {
17 | return;
18 | }
19 |
20 | setHovering( true );
21 |
22 | const selectedValue = index + 1;
23 | const newHoveredRating = isPastHalf( event )
24 | ? selectedValue
25 | : Math.max( selectedValue - 0.5, 1 );
26 |
27 | setSelectedRating( newHoveredRating );
28 | };
29 |
30 | const handleMouseOut = () => setHovering( false );
31 |
32 | const handleRating = () => {
33 | if ( onRate ) {
34 | onRate( selectedRating );
35 | }
36 | };
37 |
38 | const getStar = ( index ) => {
39 | const step = index + 1;
40 | const usedRating = hovering ? selectedRating : rating;
41 |
42 | // If we're on a step below or equal to the rating, the star should be filled.
43 | if ( step <= usedRating ) {
44 | return starFilled;
45 | }
46 |
47 | /**
48 | * If we're on a step over the rating rounded up to the closest integer,
49 | * the star should be empty.
50 | */
51 | if ( step > Math.ceil( usedRating ) ) {
52 | return starEmpty;
53 | }
54 |
55 | /**
56 | * Otherwise, we're in-between, which only happens if the rating is not
57 | * an integer, so we print a half star.
58 | */
59 | return starHalf;
60 | };
61 |
62 | return (
63 |
64 | { Array.from( { length: 5 } ).map( ( _, index ) => (
65 |
73 | ) ) }
74 |
75 | );
76 | }
77 |
--------------------------------------------------------------------------------
/blocks/book/src/save.js:
--------------------------------------------------------------------------------
1 | import { RichText } from '@wordpress/block-editor';
2 | /**
3 | * Retrieves the translation of text.
4 | *
5 | * @see https://developer.wordpress.org/block-editor/packages/packages-i18n/
6 | */
7 | import { __ } from '@wordpress/i18n';
8 |
9 | import classnames from 'classnames';
10 | import prefixClasses from './prefixClasses';
11 |
12 | /**
13 | * The save function defines the way in which the different attributes should
14 | * be combined into the final markup, which is then serialized by the block
15 | * editor into `post_content`.
16 | *
17 | * @see https://developer.wordpress.org/block-editor/developers/block-api/block-edit-save/#save
18 | *
19 | * @return {WPElement} Element to render.
20 | */
21 | export default function save( { className, attributes } ) {
22 | const {
23 | author,
24 | imageId,
25 | imageUrl,
26 | publicationDate,
27 | publisher,
28 | title,
29 | width,
30 | } = attributes;
31 | const hasMedia = !! imageId;
32 |
33 | const classes = classnames( 'wp-block-a8c-book', className );
34 |
35 | return (
36 |
37 | { hasMedia && (
38 |
42 |

43 |
44 | ) }
45 |
46 | { title && (
47 |
52 | ) }
53 | { author && (
54 |
59 | ) }
60 | { publisher && (
61 |
66 | ) }
67 | { publicationDate && (
68 |
73 | ) }
74 |
75 |
76 | );
77 | }
78 |
--------------------------------------------------------------------------------
/blocks/book/style.scss:
--------------------------------------------------------------------------------
1 | /**
2 | * The following styles get applied both on the front of your site
3 | * and in the editor.
4 | */
5 |
6 | .wp-block-a8c-book {
7 | width: auto;
8 |
9 | &.aligncenter {
10 | display: flex;
11 | flex-direction: column;
12 | align-items: center;
13 | }
14 |
15 | &.alignleft {
16 | margin-right: 1em;
17 | }
18 |
19 | &.alignright {
20 | margin-left: 1em;
21 | }
22 |
23 | &.alignleft,
24 | &.alignright {
25 | margin-top: 0;
26 | margin-right: 0;
27 | }
28 |
29 | .wp-block-a8c-book__meta {
30 | padding: 0.5em 0 1em 0;
31 | line-height: 1;
32 | .wp-block-a8c-book__title {
33 | font-weight: bold;
34 | }
35 | > p {
36 | padding: 0;
37 | margin: 0.5em 0;
38 | font-size: 0.8em;
39 | }
40 | }
41 |
42 | .wp-block-a8c-book__publication {
43 | span {
44 | margin-right: 0.5em;
45 | }
46 | }
47 |
48 | .wp-block-a8c-book__summary {
49 | width: auto;
50 | margin: 0;
51 | padding: 0;
52 | }
53 |
54 | .wp-block-a8c-book__container {
55 | display: flex;
56 | flex-direction: column;
57 | align-items: flex-start;
58 | justify-content: center;
59 | padding: 0;
60 | margin: 0 1em 1em 0;
61 | }
62 |
63 | .wp-block-a8c-book__cover {
64 | height: auto;
65 | max-width: 100%;
66 | img {
67 | display: block;
68 | width: 100%;
69 | height: 100%;
70 | }
71 | }
72 |
73 | // Show a shadow to emulate a book.
74 | .wp-block-a8c-book__cover {
75 | box-shadow: 0 1px 2px rgba( 0, 0, 0, 0.3 ),
76 | 0 2px 4px rgba( 0, 0, 0, 0.3 );
77 | }
78 |
79 | // 3D.
80 | @keyframes initAnimation {
81 | 0% {
82 | transform: rotateY( -3deg );
83 | }
84 | 100% {
85 | transform: rotateY( -16deg );
86 | }
87 | }
88 |
89 | .wp-block-a8c-book__cover {
90 | position: relative;
91 | transform-style: preserve-3d;
92 | }
93 |
94 | .wp-block-a8c-book__cover.is-3d:hover {
95 | transform: rotateY( -16deg );
96 | animation: 1s ease 0s 1 initAnimation;
97 | }
98 | }
99 |
--------------------------------------------------------------------------------
/blocks/duotone-filter/readme.md:
--------------------------------------------------------------------------------
1 | # Duotone Filter
2 |
3 | Duotone filter has been promoted to a WordPress core feature as part of block supports. 🎉
4 |
5 | The duotone block supports source is available in the Gutenberg repository under [block-editor](https://github.com/WordPress/gutenberg/tree/v10.6.0/packages/block-editor/src/hooks/duotone.js) and [lib](https://github.com/WordPress/gutenberg/blob/v10.6.0/lib/block-supports/duotone.php). It is included in WordPress 5.8.
6 |
--------------------------------------------------------------------------------
/blocks/event/editor.scss:
--------------------------------------------------------------------------------
1 | /* Editor styles */
2 | .wp-block-a8c-event {
3 | .event__date-select {
4 | display: inline;
5 |
6 | .components-button {
7 | height: auto;
8 | background: white;
9 | }
10 | }
11 |
12 | // Fixes for overriding editor styles
13 | .editor-styles-wrapper &,
14 | // Additional specificity needed for center aligned blocks
15 | .editor-styles-wrapper .wp-block[data-align="center"] > & {
16 | text-align: left;
17 |
18 | p {
19 | font-family: inherit;
20 | }
21 |
22 | .event__title {
23 | margin: 0 0 18px;
24 | font-weight: 800;
25 | line-height: 40px;
26 | }
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/blocks/event/index.php:
--------------------------------------------------------------------------------
1 | 'block-experiments',
6 | 'style' => 'block-experiments',
7 | 'editor_style' => 'block-experiments-editor',
8 | ] );
9 |
10 | wp_set_script_translations( 'block-experiments', 'event' );
11 | } );
12 |
--------------------------------------------------------------------------------
/blocks/event/src/date-select.js:
--------------------------------------------------------------------------------
1 | /**
2 | * WordPress dependencies
3 | */
4 | import { Button, DateTimePicker, Dropdown } from '@wordpress/components';
5 | import { dateI18n } from '@wordpress/date';
6 |
7 | const DateSelect = ( {
8 | placeholder,
9 | value,
10 | dateFormat,
11 | onChange,
12 | className,
13 | } ) => (
14 | (
20 |
28 | ) }
29 | renderContent={ () => (
30 |
31 | ) }
32 | />
33 | );
34 |
35 | DateSelect.Content = ( { value, dateFormat, className } ) =>
36 | value && (
37 |
40 | );
41 |
42 | export default DateSelect;
43 |
--------------------------------------------------------------------------------
/blocks/event/src/icons.js:
--------------------------------------------------------------------------------
1 | /**
2 | * WordPress dependencies
3 | */
4 | import { SVG, Rect, Path } from '@wordpress/components';
5 |
6 | export const Icon = () => (
7 |
15 | );
16 |
--------------------------------------------------------------------------------
/blocks/event/src/index.js:
--------------------------------------------------------------------------------
1 | /**
2 | * External dependencies
3 | */
4 |
5 | /**
6 | * WordPress dependencies
7 | */
8 | import { registerBlockType } from '@wordpress/blocks';
9 | import { __ } from '@wordpress/i18n';
10 |
11 | /**
12 | * Internal dependencies
13 | */
14 | import { Icon } from './icons';
15 | import Edit from './edit';
16 | import Save from './save';
17 |
18 | export function registerBlock() {
19 | registerBlockType( 'a8c/event', {
20 | title: __( 'Event', 'event' ),
21 | description: __( 'Show the time and location of an event.', 'event' ),
22 | icon: ,
23 | category: 'widgets',
24 | supports: {
25 | align: [ 'center', 'wide' ],
26 | },
27 | example: {
28 | attributes: {
29 | eventTitle: 'Digging for Treasure',
30 | eventLocation: 'Treasure Island',
31 | eventStart: '1783-11-14T12:00:00',
32 | eventImageId: 1,
33 | eventImageURL:
34 | 'https://upload.wikimedia.org/wikipedia/commons/thumb/0/03/TI-treasure.jpg/366px-TI-treasure.jpg',
35 | eventImageAlt: 'Treasure',
36 | focalPoint: {
37 | x: '0.30',
38 | y: '0.40',
39 | },
40 | customBackgroundColor: '#d4c5af',
41 | align: 'wide',
42 | },
43 | },
44 | attributes: {
45 | eventTitle: {
46 | type: 'string',
47 | },
48 | eventLocation: {
49 | type: 'string',
50 | },
51 | eventStart: {
52 | type: 'string',
53 | },
54 | eventImageId: {
55 | type: 'number',
56 | },
57 | eventImageURL: {
58 | type: 'string',
59 | },
60 | eventImageAlt: {
61 | type: 'string',
62 | default: '',
63 | },
64 | focalPoint: {
65 | type: 'object',
66 | },
67 | backgroundColor: {
68 | type: 'string',
69 | },
70 | customBackgroundColor: {
71 | type: 'string',
72 | },
73 | textColor: {
74 | type: 'string',
75 | },
76 | customTextColor: {
77 | type: 'string',
78 | },
79 | },
80 | edit: Edit,
81 | save: Save,
82 | } );
83 | }
84 |
--------------------------------------------------------------------------------
/blocks/event/src/save.js:
--------------------------------------------------------------------------------
1 | /**
2 | * External dependencies
3 | */
4 | import classnames from 'classnames';
5 |
6 | /**
7 | * WordPress dependencies
8 | */
9 | import {
10 | InnerBlocks,
11 | RichText,
12 | getColorClassName,
13 | } from '@wordpress/block-editor';
14 | import { getSettings, dateI18n } from '@wordpress/date';
15 | import { __ } from '@wordpress/i18n';
16 |
17 | /**
18 | * Internal dependencies
19 | */
20 | import DateSelect from './date-select';
21 |
22 | const Save = ( { attributes } ) => {
23 | const settings = getSettings();
24 |
25 | const classNames = [
26 | getColorClassName( 'color', attributes.textColor ),
27 | getColorClassName( 'background-color', attributes.backgroundColor ),
28 | ];
29 | const style = {
30 | color: attributes.customTextColor,
31 | backgroundColor: attributes.customBackgroundColor,
32 | };
33 | const imgStyle = {
34 | backgroundImage:
35 | attributes.eventImageURL && `url(${ attributes.eventImageURL })`,
36 | backgroundPosition:
37 | attributes.focalPoint &&
38 | `${ attributes.focalPoint.x * 100 }% ${ attributes.focalPoint.y *
39 | 100 }%`,
40 | backgroundSize: 'cover',
41 | };
42 |
43 | return (
44 |
48 |
49 | { attributes.eventStart && (
50 |
51 | { dateI18n( 'M', attributes.eventStart ) }
52 | { dateI18n( 'j', attributes.eventStart ) }
53 |
54 | ) }
55 |
60 | { attributes.eventStart && (
61 |
62 |
63 | { __( 'When:', 'event' ) }
64 |
65 |
70 |
71 | ) }
72 | { attributes.eventLocation && (
73 |
74 |
75 | { __( 'Where:', 'event' ) }
76 |
77 |
78 |
79 | ) }
80 |
81 |
82 |
83 |
84 | { attributes.eventImageURL && (
85 |
91 | ) }
92 |
93 | );
94 | };
95 |
96 | export default Save;
97 |
--------------------------------------------------------------------------------
/blocks/event/style.scss:
--------------------------------------------------------------------------------
1 | /* Front end styles */
2 | .wp-block-a8c-event {
3 | display: flex;
4 | flex-direction: row;
5 |
6 | padding: 18px;
7 | font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen-Sans, Ubuntu, Cantarell, 'Helvetica Neue', sans-serif;
8 | box-shadow: inset 0 0 0 4px rgba(0,0,0,.1);
9 |
10 | &.aligncenter {
11 | display: flex;
12 | text-align: left;
13 | }
14 |
15 | .event__datebox {
16 | float: left;
17 | width: 40px;
18 | height: 40px;
19 | background: black;
20 | color: white;
21 | margin: 0 18px 18px 0;
22 | padding: 4px;
23 | text-align: center;
24 |
25 | > span {
26 | display: block;
27 | margin: 0;
28 | line-height: 16px;
29 | }
30 |
31 | span:first-child {
32 | font-weight: bold;
33 | font-size: 12px;
34 | }
35 | }
36 |
37 | .event__title {
38 | font-weight: 800;
39 | line-height: 40px;
40 | clear: none;
41 | }
42 |
43 | .event__title,
44 | .event__time,
45 | .event__location {
46 | margin-top: 0;
47 | margin-bottom: 18px;
48 | hyphens: auto;
49 | overflow-wrap: break-word;
50 | }
51 |
52 | .event__description {
53 | margin-top: 18px;
54 | }
55 |
56 | .event__label {
57 | display: inline-block;
58 | min-width: 80px;
59 | opacity: 0.5;
60 | }
61 |
62 | .event__location {
63 | display: flex;
64 | }
65 |
66 | .event__details {
67 | flex: 2;
68 | }
69 |
70 | .event__image {
71 | flex: 1;
72 | margin-left: 18px;
73 | }
74 |
75 | .event__image--save {
76 | float: right;
77 | }
78 | }
79 |
--------------------------------------------------------------------------------
/blocks/image-compare/readme.md:
--------------------------------------------------------------------------------
1 | # Image Compare Block
2 |
3 | The Image Compare block has been promoted to a Jetpack block. 🎉
4 |
5 | The [block source is available here](https://github.com/Automattic/jetpack/tree/master/extensions/blocks/image-compare) or to simply use the block you can install Jetpack 8.6 or higher.
6 |
--------------------------------------------------------------------------------
/blocks/layout-grid/constants.scss:
--------------------------------------------------------------------------------
1 | $block-padding: 14px;
2 | $grid-desktop: repeat(12, 1fr); // Same as 12 instances of 1fr.
3 | $grid-tablet: repeat(8, 1fr);
4 | $grid-mobile: repeat(4, 1fr);
5 |
6 | $grid-gutter: 24px;
7 | $grid-gutter-none: 0px;
8 | $grid-gutter-small: 8px;
9 | $grid-gutter-medium: 16px;
10 | $grid-gutter-large: $grid-gutter;
11 | $grid-gutter-huge: 48px;
12 | $grid-gutter__background-offset: $grid-gutter / 2 + 1px;
13 |
14 | // These can be deprecated.
15 | $padding-none: $grid-gutter-none;
16 | $padding-small: $grid-gutter-small;
17 | $padding-medium: $grid-gutter-medium;
18 | $padding-large: $grid-gutter;
19 | $padding-huge: $grid-gutter-huge;
20 |
21 | // Standard Gutenberg Breakpoints
22 | $break-huge: 1440px;
23 | $break-wide: 1280px;
24 | $break-xlarge: 1080px;
25 | $break-large: 960px; // admin sidebar auto folds
26 | $break-medium: 782px; // adminbar goes big
27 | $break-small: 600px;
28 | $break-mobile: 480px;
29 | $break-zoomed-in: 280px;
30 |
--------------------------------------------------------------------------------
/blocks/layout-grid/index.php:
--------------------------------------------------------------------------------
1 | 'block-experiments',
7 | 'style' => 'block-experiments',
8 | 'editor_style' => 'block-experiments-editor',
9 | ] );
10 |
11 | register_block_type( 'jetpack/layout-grid-column', [
12 | 'editor_script' => 'block-experiments',
13 | 'style' => 'block-experiments',
14 | 'editor_style' => 'block-experiments-editor',
15 | ] );
16 |
17 | wp_set_script_translations( 'block-experiments', 'layout-grid' );
18 | } );
19 |
20 | add_filter(
21 | 'excerpt_allowed_wrapper_blocks',
22 | function( $allowed_wrapper_blocks ) {
23 | return array_merge( $allowed_wrapper_blocks, array( 'jetpack/layout-grid', 'jetpack/layout-grid-column' ) );
24 | }
25 | );
26 |
--------------------------------------------------------------------------------
/blocks/layout-grid/src/__tests__/__image_snapshots__/four-column-desktop-snap.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Automattic/block-experiments/cf30ce88838160d6b583fae41e96337ddc7318e6/blocks/layout-grid/src/__tests__/__image_snapshots__/four-column-desktop-snap.png
--------------------------------------------------------------------------------
/blocks/layout-grid/src/__tests__/__image_snapshots__/four-column-mobile-snap.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Automattic/block-experiments/cf30ce88838160d6b583fae41e96337ddc7318e6/blocks/layout-grid/src/__tests__/__image_snapshots__/four-column-mobile-snap.png
--------------------------------------------------------------------------------
/blocks/layout-grid/src/__tests__/__image_snapshots__/four-column-tablet-snap.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Automattic/block-experiments/cf30ce88838160d6b583fae41e96337ddc7318e6/blocks/layout-grid/src/__tests__/__image_snapshots__/four-column-tablet-snap.png
--------------------------------------------------------------------------------
/blocks/layout-grid/src/__tests__/__image_snapshots__/one-column-desktop-snap.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Automattic/block-experiments/cf30ce88838160d6b583fae41e96337ddc7318e6/blocks/layout-grid/src/__tests__/__image_snapshots__/one-column-desktop-snap.png
--------------------------------------------------------------------------------
/blocks/layout-grid/src/__tests__/__image_snapshots__/one-column-mobile-snap.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Automattic/block-experiments/cf30ce88838160d6b583fae41e96337ddc7318e6/blocks/layout-grid/src/__tests__/__image_snapshots__/one-column-mobile-snap.png
--------------------------------------------------------------------------------
/blocks/layout-grid/src/__tests__/__image_snapshots__/one-column-tablet-snap.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Automattic/block-experiments/cf30ce88838160d6b583fae41e96337ddc7318e6/blocks/layout-grid/src/__tests__/__image_snapshots__/one-column-tablet-snap.png
--------------------------------------------------------------------------------
/blocks/layout-grid/src/__tests__/__image_snapshots__/three-column-desktop-snap.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Automattic/block-experiments/cf30ce88838160d6b583fae41e96337ddc7318e6/blocks/layout-grid/src/__tests__/__image_snapshots__/three-column-desktop-snap.png
--------------------------------------------------------------------------------
/blocks/layout-grid/src/__tests__/__image_snapshots__/three-column-mobile-snap.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Automattic/block-experiments/cf30ce88838160d6b583fae41e96337ddc7318e6/blocks/layout-grid/src/__tests__/__image_snapshots__/three-column-mobile-snap.png
--------------------------------------------------------------------------------
/blocks/layout-grid/src/__tests__/__image_snapshots__/three-column-tablet-snap.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Automattic/block-experiments/cf30ce88838160d6b583fae41e96337ddc7318e6/blocks/layout-grid/src/__tests__/__image_snapshots__/three-column-tablet-snap.png
--------------------------------------------------------------------------------
/blocks/layout-grid/src/__tests__/__image_snapshots__/two-column-custom-background-desktop-snap.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Automattic/block-experiments/cf30ce88838160d6b583fae41e96337ddc7318e6/blocks/layout-grid/src/__tests__/__image_snapshots__/two-column-custom-background-desktop-snap.png
--------------------------------------------------------------------------------
/blocks/layout-grid/src/__tests__/__image_snapshots__/two-column-custom-background-mobile-snap.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Automattic/block-experiments/cf30ce88838160d6b583fae41e96337ddc7318e6/blocks/layout-grid/src/__tests__/__image_snapshots__/two-column-custom-background-mobile-snap.png
--------------------------------------------------------------------------------
/blocks/layout-grid/src/__tests__/__image_snapshots__/two-column-custom-background-tablet-snap.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Automattic/block-experiments/cf30ce88838160d6b583fae41e96337ddc7318e6/blocks/layout-grid/src/__tests__/__image_snapshots__/two-column-custom-background-tablet-snap.png
--------------------------------------------------------------------------------
/blocks/layout-grid/src/__tests__/__image_snapshots__/two-column-desktop-snap.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Automattic/block-experiments/cf30ce88838160d6b583fae41e96337ddc7318e6/blocks/layout-grid/src/__tests__/__image_snapshots__/two-column-desktop-snap.png
--------------------------------------------------------------------------------
/blocks/layout-grid/src/__tests__/__image_snapshots__/two-column-mobile-snap.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Automattic/block-experiments/cf30ce88838160d6b583fae41e96337ddc7318e6/blocks/layout-grid/src/__tests__/__image_snapshots__/two-column-mobile-snap.png
--------------------------------------------------------------------------------
/blocks/layout-grid/src/__tests__/__image_snapshots__/two-column-no-gutters-desktop-snap.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Automattic/block-experiments/cf30ce88838160d6b583fae41e96337ddc7318e6/blocks/layout-grid/src/__tests__/__image_snapshots__/two-column-no-gutters-desktop-snap.png
--------------------------------------------------------------------------------
/blocks/layout-grid/src/__tests__/__image_snapshots__/two-column-no-gutters-mobile-snap.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Automattic/block-experiments/cf30ce88838160d6b583fae41e96337ddc7318e6/blocks/layout-grid/src/__tests__/__image_snapshots__/two-column-no-gutters-mobile-snap.png
--------------------------------------------------------------------------------
/blocks/layout-grid/src/__tests__/__image_snapshots__/two-column-no-gutters-tablet-snap.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Automattic/block-experiments/cf30ce88838160d6b583fae41e96337ddc7318e6/blocks/layout-grid/src/__tests__/__image_snapshots__/two-column-no-gutters-tablet-snap.png
--------------------------------------------------------------------------------
/blocks/layout-grid/src/__tests__/__image_snapshots__/two-column-tablet-snap.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Automattic/block-experiments/cf30ce88838160d6b583fae41e96337ddc7318e6/blocks/layout-grid/src/__tests__/__image_snapshots__/two-column-tablet-snap.png
--------------------------------------------------------------------------------
/blocks/layout-grid/src/__tests__/invalidations.js:
--------------------------------------------------------------------------------
1 | /**
2 | * WordPress dependencies
3 | */
4 | import { parse } from '@wordpress/blocks';
5 |
6 | /**
7 | * Internal dependencies
8 | */
9 | import { registerBlock } from '../index';
10 | import { getFixtures, readFixture } from '../../tests/tools/fixtures';
11 | import { isValid } from '../../tests/tools/block';
12 |
13 | registerBlock();
14 |
15 | describe( 'Layout Grid Invalidations', () => {
16 | const fixtures = getFixtures( 'invalidation' );
17 |
18 | it.each( fixtures )(
19 | `does not invalidate grid blocks from fixture "%s"`,
20 | ( fixture ) => {
21 | const html = readFixture( fixture );
22 | const parsed = parse( html );
23 |
24 | // No warnings
25 | expect( console ).not.toHaveWarned();
26 |
27 | // Exactly 1 block
28 | expect( parsed.length ).toBe( 1 );
29 |
30 | // No validation issues
31 | expect( isValid( parsed[ 0 ] ) ).toBe( true );
32 |
33 | // It's a layout grid
34 | expect( parsed[ 0 ].name ).toBe( 'jetpack/layout-grid' );
35 | }
36 | );
37 | } );
38 |
--------------------------------------------------------------------------------
/blocks/layout-grid/src/__tests__/migrations.js:
--------------------------------------------------------------------------------
1 | /**
2 | * WordPress dependencies
3 | */
4 | import { parse, serialize, rawHandler } from '@wordpress/blocks';
5 | import { registerCoreBlocks } from '@wordpress/block-library';
6 |
7 | /**
8 | * Internal dependencies
9 | */
10 | import { registerBlock } from '../index';
11 | import { isValid } from '../../tests/tools/block';
12 | import { readFixture } from '../../tests/tools/fixtures';
13 |
14 | registerBlock();
15 |
16 | describe( 'Layout Grid Migrations', () => {
17 | beforeAll( () => {
18 | registerCoreBlocks();
19 | } );
20 |
21 | it( 'migrates missing is-background for custom colors', () => {
22 | const html = readFixture( 'migration/1.3-custom-color.html' );
23 | const parsed = parse( html );
24 |
25 | // No warnings
26 | expect( console ).toHaveInformed();
27 |
28 | // Exactly 1 block
29 | expect( parsed.length ).toBe( 1 );
30 |
31 | const gridBlock = parsed[ 0 ];
32 |
33 | // It's a layout grid
34 | expect( gridBlock.name ).toBe( 'jetpack/layout-grid' );
35 | expect( gridBlock.innerBlocks.length ).toBe( 3 );
36 |
37 | // No validation issues
38 | expect( isValid( gridBlock ) ).toBe( true );
39 |
40 | // Check attributes are correct
41 | const columnBlock = gridBlock.innerBlocks[ 1 ];
42 | const htmlBlock = serialize( columnBlock );
43 |
44 | // Custom background still exists
45 | expect( columnBlock.attributes.customBackgroundColor ).toBe(
46 | '#7c451f'
47 | );
48 |
49 | // has-background has been added to the block
50 | expect( htmlBlock.indexOf( 'has-background' ) !== -1 ).toBe( true );
51 |
52 | // The custom color is in the block
53 | expect( htmlBlock.indexOf( '7c451f' ) !== -1 ).toBe( true );
54 |
55 | // We still have our grid content
56 | expect( htmlBlock.indexOf( 'long established' ) !== -1 ).toBe( true );
57 | } );
58 | } );
59 |
--------------------------------------------------------------------------------
/blocks/layout-grid/src/__tests__/visual-test.js:
--------------------------------------------------------------------------------
1 | /**
2 | * External dependencies
3 | */
4 |
5 | import { generateImage } from 'jsdom-screenshot';
6 | import { render } from '@testing-library/react';
7 | import path from 'path';
8 |
9 | /**
10 | * Internal dependencies
11 | */
12 | import { registerBlock } from '../index';
13 | import { Block, Theme, dumpHTML } from '../../tests/tools/block';
14 | import { getFixtures, readFixture } from '../../tests/tools/fixtures';
15 |
16 | // Enable this to help with debugging
17 | const LOG_HTML = false;
18 |
19 | const VIEWPORTS = [
20 | {
21 | name: 'desktop',
22 | width: 1600,
23 | height: 1200,
24 | },
25 | {
26 | name: 'tablet',
27 | width: 600,
28 | height: 1200,
29 | },
30 | {
31 | name: 'mobile',
32 | width: 480,
33 | height: 1200,
34 | },
35 | ];
36 |
37 | function getSnapshotFilename( fixture ) {
38 | return fixture.replace( 'visual/', '' ).replace( '.html', '' );
39 | }
40 |
41 | describe( 'Grid Block visual regression', () => {
42 | beforeAll( () => {
43 | registerBlock();
44 | } );
45 |
46 | const fixtures = getFixtures( 'visual' );
47 |
48 | it.each( fixtures )(
49 | 'does not regress grid blocks from previous snapshot "%s"',
50 | async ( fixture ) => {
51 | const html = readFixture( fixture );
52 |
53 | render(
54 |
55 |
56 |
57 | );
58 |
59 | for ( let index = 0; index < VIEWPORTS.length; index++ ) {
60 | const { width, height, name } = VIEWPORTS[ index ];
61 |
62 | const screenshot = await generateImage( {
63 | viewport: { width, height },
64 | options: {
65 | fullPage: true,
66 | },
67 | targetSelector: '.entry-content',
68 | } );
69 |
70 | if ( LOG_HTML ) {
71 | dumpHTML(
72 | path.join(
73 | __dirname,
74 | getSnapshotFilename( fixture + '-' + name ) +
75 | '.html'
76 | )
77 | );
78 | }
79 |
80 | expect( screenshot ).toMatchImageSnapshot( {
81 | comparisonMethod: 'ssim',
82 | customSnapshotIdentifier: getSnapshotFilename(
83 | fixture + '-' + name
84 | ),
85 | } );
86 | }
87 | }
88 | );
89 | } );
90 |
--------------------------------------------------------------------------------
/blocks/layout-grid/src/constants.js:
--------------------------------------------------------------------------------
1 | /**
2 | * WordPress dependencies
3 | */
4 |
5 | import { __ } from '@wordpress/i18n';
6 | import { mobile, tablet, desktop } from '@wordpress/icons';
7 |
8 | function getSpacingValues() {
9 | return [
10 | { value: 'small', label: __( 'Small', 'layout-grid' ) },
11 | { value: 'medium', label: __( 'Medium', 'layout-grid' ) },
12 | { value: 'large', label: __( 'Large', 'layout-grid' ) },
13 | { value: 'huge', label: __( 'Huge', 'layout-grid' ) },
14 | ];
15 | }
16 |
17 | export const getPaddingValues = () =>
18 | [ { value: 'none', label: __( 'No padding', 'layout-grid' ) } ].concat(
19 | getSpacingValues()
20 | );
21 |
22 | export const getGutterValues = () =>
23 | [ { value: 'none', label: __( 'No gutter', 'layout-grid' ) } ].concat(
24 | getSpacingValues()
25 | );
26 |
27 | export const getColumns = () => [
28 | {
29 | label: __( '1 cols', 'layout-grid' ),
30 | value: 1,
31 | },
32 | {
33 | label: __( '2 cols', 'layout-grid' ),
34 | value: 2,
35 | },
36 | {
37 | label: __( '3 cols', 'layout-grid' ),
38 | value: 3,
39 | },
40 | {
41 | label: __( '4 cols', 'layout-grid' ),
42 | value: 4,
43 | },
44 | ];
45 |
46 | export const DEVICE_DESKTOP = 'Desktop';
47 | export const DEVICE_TABLET = 'Tablet';
48 | export const DEVICE_MOBILE = 'Mobile';
49 |
50 | export const getLayouts = () => [
51 | {
52 | value: DEVICE_DESKTOP,
53 | label: __( 'Desktop', 'layout-grid' ),
54 | icon: desktop,
55 | },
56 | {
57 | value: DEVICE_TABLET,
58 | label: __( 'Tablet', 'layout-grid' ),
59 | icon: tablet,
60 | },
61 | {
62 | value: DEVICE_MOBILE,
63 | label: __( 'Mobile', 'layout-grid' ),
64 | icon: mobile,
65 | },
66 | ];
67 |
68 | export const MAX_COLUMNS = 4;
69 |
70 | export const DEVICE_BREAKPOINTS = [
71 | DEVICE_DESKTOP,
72 | DEVICE_TABLET,
73 | DEVICE_MOBILE,
74 | ];
75 |
76 | export function getSpanForDevice( column, device ) {
77 | return `column${ column + 1 }${ device }Span`;
78 | }
79 |
80 | export function getOffsetForDevice( column, device ) {
81 | return `column${ column + 1 }${ device }Offset`;
82 | }
83 |
--------------------------------------------------------------------------------
/blocks/layout-grid/src/grid-column/deprecated.js:
--------------------------------------------------------------------------------
1 | /**
2 | * External dependencies
3 | */
4 |
5 | import classnames from 'classnames';
6 |
7 | /**
8 | * WordPress dependencies
9 | */
10 |
11 | import { InnerBlocks, getColorClassName } from '@wordpress/block-editor';
12 |
13 | // This is the old version of the save function, that doesn't add a `has-background` for custom colours
14 | const save = ( { attributes = {} } ) => {
15 | const {
16 | className,
17 | backgroundColor,
18 | customBackgroundColor,
19 | padding,
20 | verticalAlignment,
21 | } = attributes;
22 | const backgroundClass = getColorClassName(
23 | 'background-color',
24 | backgroundColor
25 | );
26 | const classes = classnames( className, {
27 | [ 'wp-block-jetpack-layout-grid__padding-' + padding ]: true,
28 | 'has-background': backgroundColor,
29 | [ backgroundClass ]: backgroundClass,
30 | [ `is-vertically-aligned-${ verticalAlignment }` ]: verticalAlignment,
31 | } );
32 | const style = {
33 | backgroundColor: backgroundClass ? undefined : customBackgroundColor,
34 | };
35 |
36 | return (
37 |
38 |
39 |
40 | );
41 | };
42 |
43 | const deprecated = [
44 | // Versions < 1.3.1 didn't save `is-background` for custom background colours. This is a deprecation that transforms the old to the new
45 | {
46 | attributes: {
47 | backgroundColor: {
48 | type: 'string',
49 | },
50 | customBackgroundColor: {
51 | type: 'string',
52 | },
53 | padding: {
54 | type: 'string',
55 | default: 'none',
56 | },
57 | verticalAlignment: {
58 | type: 'string',
59 | },
60 | },
61 | save,
62 | },
63 | ];
64 |
65 | export default deprecated;
66 |
--------------------------------------------------------------------------------
/blocks/layout-grid/src/grid-column/edit.native.scss:
--------------------------------------------------------------------------------
1 | .column__placeholder {
2 | flex: 1;
3 | padding: $block-selected-to-content;
4 | border: $border-width dashed $gray;
5 | border-radius: 4px;
6 | }
7 |
8 | .column__placeholder-dark {
9 | border: $border-width dashed $gray-70;
10 | }
11 |
12 | .column__placeholder-not-selected {
13 | padding: $block-selected-to-content;
14 | border: $border-width dashed $gray;
15 | }
16 |
17 | .column__appender {
18 | margin-left: $grid-unit-10;
19 | margin-right: $grid-unit-10;
20 | margin-bottom: -10px;
21 | }
22 |
23 | .column__appender-full-width {
24 | margin-left: $grid-unit * 2.5;
25 | margin-right: $grid-unit * 2.5;
26 | }
27 |
28 | .column__appender-full-width-has-children {
29 | margin-left: $grid-unit-15;
30 | margin-right: $grid-unit-15;
31 | margin-bottom: 5px;
32 | }
33 |
34 | .column__appender-not-full-width {
35 | margin-left: 0;
36 | margin-right: 0;
37 | margin-bottom: 5px;
38 | }
39 |
40 | .column__padding-none {
41 | padding: 0;
42 | }
43 | /* Add extra space to the bottom of the column block make sure that the there is enough space between column block and the settings cog. */
44 | .column__padding-none-is-selected {
45 | padding: 0 0 10px;
46 | }
47 |
48 | .column__padding-small {
49 | padding: 10px 8px 10px;
50 | }
51 | .column__padding-medium {
52 | padding: 16px;
53 | }
54 | .column__padding-large {
55 | padding: 24px;
56 | }
57 | .column__padding-huge {
58 | padding: 48px;
59 | }
60 |
--------------------------------------------------------------------------------
/blocks/layout-grid/src/grid-column/hooks/with-update-alignment.js:
--------------------------------------------------------------------------------
1 | /**
2 | * WordPress dependencies
3 | */
4 | import { withDispatch } from '@wordpress/data';
5 |
6 | export function withUpdateAlignment() {
7 | return withDispatch( ( dispatch, ownProps, registry ) => {
8 | return {
9 | updateAlignment( verticalAlignment ) {
10 | const { clientId, setAttributes } = ownProps;
11 | const { updateBlockAttributes } = dispatch(
12 | 'core/block-editor'
13 | );
14 | const { getBlockRootClientId } = registry.select(
15 | 'core/block-editor'
16 | );
17 |
18 | // Update own alignment.
19 | setAttributes( { verticalAlignment } );
20 |
21 | // Reset Parent Columns Block
22 | const rootClientId = getBlockRootClientId( clientId );
23 | updateBlockAttributes( rootClientId, {
24 | verticalAlignment: null,
25 | } );
26 | },
27 | };
28 | } );
29 | }
30 |
--------------------------------------------------------------------------------
/blocks/layout-grid/src/grid-column/save.js:
--------------------------------------------------------------------------------
1 | /**
2 | * External dependencies
3 | */
4 |
5 | import classnames from 'classnames';
6 |
7 | /**
8 | * WordPress dependencies
9 | */
10 |
11 | import { InnerBlocks, getColorClassName } from '@wordpress/block-editor';
12 |
13 | const save = ( { attributes = {} } ) => {
14 | const {
15 | className,
16 | backgroundColor,
17 | customBackgroundColor,
18 | padding,
19 | verticalAlignment,
20 | } = attributes;
21 | const backgroundClass = getColorClassName(
22 | 'background-color',
23 | backgroundColor
24 | );
25 | const classes = classnames( className, {
26 | [ 'wp-block-jetpack-layout-grid__padding-' + padding ]: true,
27 | 'has-background': backgroundColor || customBackgroundColor,
28 | [ backgroundClass ]: backgroundClass,
29 | [ `is-vertically-aligned-${ verticalAlignment }` ]: verticalAlignment,
30 | } );
31 | const style = {
32 | backgroundColor: backgroundClass ? undefined : customBackgroundColor,
33 | };
34 |
35 | return (
36 |
37 |
38 |
39 | );
40 | };
41 |
42 | export default save;
43 |
--------------------------------------------------------------------------------
/blocks/layout-grid/src/grid-resize.scss:
--------------------------------------------------------------------------------
1 | @import '../constants.scss';
2 |
3 | /**
4 | * Resize grid overlay
5 | */
6 |
7 | .wp-block-jetpack-layout-grid-editor .wpcom-resize-grid {
8 | user-select: none;
9 | position: absolute;
10 | top: 0;
11 | left: 0;
12 | width: 100%;
13 | height: 100%;
14 | touch-action: none;
15 |
16 | // Likely necessary to override bleed from themes.
17 | .wp-block {
18 | max-width: none;
19 | }
20 | }
21 |
22 | .wp-block-jetpack-layout-grid-editor.wp-block-jetpack-layout-gutter__none .wpcom-resize-grid:not(.wpcom-resize-grid__resizing) {
23 | grid-gap: $grid-gutter-none;
24 | }
25 |
26 | .wp-block-jetpack-layout-grid-editor.wp-block-jetpack-layout-gutter__small .wpcom-resize-grid:not(.wpcom-resize-grid__resizing) {
27 | grid-gap: $grid-gutter-small;
28 | }
29 |
30 | .wp-block-jetpack-layout-grid-editor.wp-block-jetpack-layout-gutter__medium .wpcom-resize-grid:not(.wpcom-resize-grid__resizing) {
31 | grid-gap: $grid-gutter-medium;
32 | }
33 |
34 | .wp-block-jetpack-layout-grid-editor.wp-block-jetpack-layout-gutter__huge .wpcom-resize-grid:not(.wpcom-resize-grid__resizing) {
35 | grid-gap: $grid-gutter-huge;
36 | }
37 |
38 | .wpcom-resize-grid__column-hidden {
39 | display: none;
40 | }
41 |
42 | .wpcom-resize-grid__resizing {
43 | user-select: none;
44 | z-index: 10000;
45 | touch-action: none;
46 | }
47 |
48 | // Elevate resize handle to be above column block hover & select layer.
49 | .wpcom-resize-grid__column .components-resizable-box__side-handle {
50 | z-index: 121;
51 | }
52 |
53 | body.is-resizing [data-type="jetpack/layout-grid"] {
54 | overflow: inherit;
55 | }
56 |
--------------------------------------------------------------------------------
/blocks/layout-grid/src/grid/edit.native.scss:
--------------------------------------------------------------------------------
1 | .grid-columns {
2 | padding-bottom: 8px;
3 | }
--------------------------------------------------------------------------------
/blocks/layout-grid/src/grid/grid-defaults.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Internal dependencies
3 | */
4 |
5 | import { DEVICE_MOBILE, DEVICE_TABLET } from '../constants';
6 |
7 | export const getGridWidth = device => {
8 | if ( device === DEVICE_TABLET ) {
9 | return 8;
10 | } else if ( device === DEVICE_MOBILE ) {
11 | return 4;
12 | }
13 |
14 | return 12;
15 | };
16 |
17 | export const getGridRows = device => {
18 | if ( device === DEVICE_TABLET ) {
19 | return 2;
20 | } else if ( device === DEVICE_MOBILE ) {
21 | return 4;
22 | }
23 |
24 | return 1;
25 | };
26 |
27 | export const getGridMax = ( device, columns ) => {
28 | if ( device === DEVICE_TABLET && columns > 2 ) {
29 | // 2x2 grid
30 | return getGridWidth( device ) * 2;
31 | }
32 |
33 | if ( device === DEVICE_MOBILE ) {
34 | return getGridWidth( device ) * columns;
35 | }
36 |
37 | return getGridWidth( device );
38 | };
39 |
40 | // Default spans to fill the device
41 | // 1 column: desktop=1x12x1 tablet=1x8x1 mobile=1x4x1
42 | // 2 column: desktop=2x6x1 tablet=2x4x1 mobile=1x4x2
43 | // 3 column: desktop=3x4x1 tablet=2x4x1 + 1x8x1 mobile=1x4x3
44 | // 4 column: desktop=4x3x1 tablet=2x4x2 mobile=1x4x4
45 | export function getDefaultSpan( device, columns, column ) {
46 | if ( device === DEVICE_TABLET ) {
47 | if ( columns === 3 && column === 2 ) {
48 | return getGridWidth( device );
49 | } else if ( columns > 1 ) {
50 | return getGridWidth( device ) / 2;
51 | }
52 |
53 | return getGridWidth( device );
54 | }
55 |
56 | if ( device === DEVICE_MOBILE ) {
57 | return getGridWidth( device );
58 | }
59 |
60 | return getGridWidth( device ) / columns;
61 | }
62 |
--------------------------------------------------------------------------------
/blocks/layout-grid/src/grid/preview-device.js:
--------------------------------------------------------------------------------
1 | /**
2 | * WordPress dependencies
3 | */
4 |
5 | import { useEffect } from '@wordpress/element';
6 | import { useViewportMatch, useResizeObserver } from '@wordpress/compose';
7 | import { useSelect, useDispatch } from '@wordpress/data';
8 | import {
9 | Button,
10 | ToolbarGroup,
11 | MenuGroup,
12 | MenuItemsChoice,
13 | Dropdown,
14 | } from '@wordpress/components';
15 | import { BlockControls } from '@wordpress/block-editor';
16 |
17 | /**
18 | * Internal dependencies
19 | */
20 |
21 | import { getLayouts } from '../constants';
22 |
23 | function getCurrentViewport( isMobile, isTablet ) {
24 | if ( isMobile ) {
25 | return 'Mobile';
26 | }
27 |
28 | if ( isTablet ) {
29 | return 'Tablet';
30 | }
31 |
32 | return 'Desktop';
33 | }
34 |
35 | function PreviewDevice( props ) {
36 | const { viewPort, updateViewport } = props;
37 | const {
38 | __experimentalSetPreviewDeviceType: setPreviewDevice,
39 | } = useDispatch( 'core/edit-post' ) || useDispatch( 'core/edit-site' );
40 | const previewDevice = useSelect(
41 | ( select ) =>
42 | ( select( 'core/edit-site' ) || select( 'core/edit-post' ) ).__experimentalGetPreviewDeviceType(),
43 | []
44 | );
45 | const [ resizeListener, sizes ] = useResizeObserver();
46 | const isTablet = useViewportMatch( 'medium', '<' );
47 | const isMobile = useViewportMatch( 'small', '<' );
48 |
49 | useEffect( () => {
50 | const newPort = getCurrentViewport( isMobile, isTablet );
51 |
52 | if ( newPort !== viewPort ) {
53 | updateViewport( newPort );
54 | }
55 | }, [ sizes ] );
56 |
57 | return (
58 | <>
59 | { resizeListener }
60 |
61 | { ! isMobile && (
62 |
63 | (
65 |
66 |
77 | ) }
78 | renderContent={ () => (
79 |
80 |
83 | setPreviewDevice( mode )
84 | }
85 | choices={ getLayouts() }
86 | />
87 |
88 | ) }
89 | />
90 |
91 | ) }
92 | >
93 | );
94 | }
95 |
96 | export default PreviewDevice;
97 |
--------------------------------------------------------------------------------
/blocks/layout-grid/src/grid/resize-grid/nearest.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Returns the 0-based column that the mouse is closest to
3 | */
4 | export default function findNearest( parent, xPos, direction, totalColumns ) {
5 | // Each column is 1/12th the width of the parent
6 | const { width, x } = parent.getBoundingClientRect();
7 | const colWidth = width / totalColumns;
8 | const mousePos = xPos - x;
9 |
10 | // Which column does mousePos fall into?
11 | const column = Math.floor( mousePos / colWidth );
12 | const offsetInColumn = mousePos % colWidth;
13 |
14 | // If we're going left then we need to be in the first half of a column
15 | if ( direction === 'left' ) {
16 | if ( offsetInColumn <= colWidth / 2 ) {
17 | // Matched this column
18 | return column;
19 | }
20 |
21 | // Not gone over the threshold - match the next column
22 | return column + 1;
23 | }
24 |
25 | // If going right we need to be in the second half
26 | if ( offsetInColumn < colWidth / 2 ) {
27 | // Matched this column
28 | return column;
29 | }
30 |
31 | return column + 1;
32 | }
33 |
--------------------------------------------------------------------------------
/blocks/layout-grid/src/grid/resize-grid/resize-handle.js:
--------------------------------------------------------------------------------
1 | /**
2 | * External dependencies
3 | */
4 |
5 | import classnames from 'classnames';
6 |
7 | const ResizeHandle = ( { direction, height, xPos, top, isSelected } ) => {
8 | const classes = classnames( 'wpcom-overlay-resize__handle', 'components-resizable-box__container', {
9 | 'is-selected': isSelected,
10 | } );
11 | const wrapStyle = {
12 | height: height + 'px',
13 | width: xPos + 'px',
14 | top: top + 'px',
15 | };
16 | const dragStyle = {
17 | left: xPos + 'px',
18 | };
19 |
20 |
21 | const handleClasses = classnames(
22 | 'components-resizable-box__handle',
23 | 'components-resizable-box__side-handle',
24 | {
25 | 'components-resizable-box__handle-left': direction === 'left',
26 | 'components-resizable-box__handle-right': direction === 'right',
27 | }
28 | );
29 |
30 | return (
31 |
36 | );
37 | };
38 |
39 | export default ResizeHandle;
40 |
--------------------------------------------------------------------------------
/blocks/layout-grid/src/grid/save.js:
--------------------------------------------------------------------------------
1 | /**
2 | * External dependencies
3 | */
4 |
5 | import classnames from 'classnames';
6 |
7 | /**
8 | * WordPress dependencies
9 | */
10 |
11 | import { InnerBlocks } from '@wordpress/block-editor';
12 |
13 | /**
14 | * Internal dependencies
15 | */
16 |
17 | import { getAsCSS, removeGridClasses, getGutterClasses } from './css-classname';
18 |
19 | const save = ( { attributes, innerBlocks } ) => {
20 | const {
21 | className,
22 | } = attributes;
23 | const extra = getAsCSS( innerBlocks.length, attributes );
24 | const classes = classnames(
25 | removeGridClasses( className ),
26 | extra,
27 | getGutterClasses( attributes ),
28 | );
29 |
30 | return (
31 |
32 |
33 |
34 | );
35 | };
36 |
37 | export default save;
38 |
--------------------------------------------------------------------------------
/blocks/layout-grid/src/grid/variation-control/style.native.scss:
--------------------------------------------------------------------------------
1 | .variation-control {
2 | padding-left: 0;
3 | padding-right: 0;
4 | }
5 |
6 | .variation-control__cancel-button {
7 | color: $blue-wordpress;
8 | font-size: 16px;
9 | padding-left: $grid-unit-20;
10 | padding-right: $grid-unit-20;
11 | }
12 | .variation-control__cancel-button-dark {
13 | color: $blue-30;
14 | }
15 |
16 | .variation-control__close-icon {
17 | color: $gray;
18 | margin-left: $grid-unit-10;
19 | padding-left: $grid-unit-20;
20 | padding-right: $grid-unit-20;
21 | }
22 |
23 | .variation-control__inner-shell {
24 | padding: 0 $grid-unit-20;
25 | }
26 |
27 | .variation-control-inner__scrollview-container {
28 | flex-direction: row;
29 | padding-left: 8px;
30 | padding-right: 0;
31 |
32 | }
33 |
34 | .variation-control-inner__scrollview {
35 | padding-top: $grid-unit-15;
36 | margin-left: -16px;
37 | margin-right: -16px;
38 | }
39 |
40 | .variation-control-inner__footer {
41 | padding-top: 21.5px;
42 | padding-bottom: 10.5px;
43 | font-size: 12px;
44 | color: $gray;
45 | flex: 1;
46 | }
47 |
48 | .variation-control-inner__footer-last {
49 | padding-top: 0px;
50 | }
51 |
52 | .variation-control-selected-button {
53 | width: 112px;
54 | height: 84px;
55 | }
56 |
57 | .variation-control-selected-button__item {
58 | border-width: $block-selected-border-width;
59 | border-radius: 8px;
60 | border-style: solid;
61 | border-color: $blue-50;
62 | background-color: $gray-light;
63 | }
64 | .variation-control-selected-button__item-dark {
65 | border-color: $blue-30;
66 | background-color: rgba( $white, 0.07 );
67 | }
68 |
69 | .variation-control-selected-button__label-icon {
70 | width: 48px;
71 | height: 32px;
72 | justify-content: center;
73 | align-items: center;
74 | fill: $gray-dark;
75 | }
76 |
77 | .variation-control-selected-button__label-icon-dark {
78 | fill: $white;
79 | }
80 |
81 | .variation-control-selected-button__label{
82 | background-color: transparent;
83 | padding-left: 2;
84 | padding-right: 2;
85 | padding-top: 4;
86 | padding-bottom: 0;
87 | justify-content: center;
88 | font-size: 12;
89 | color: $gray-dark;
90 | }
91 |
92 | .variation-control-selected-button__label-dark {
93 | color: $white;
94 | }
--------------------------------------------------------------------------------
/blocks/layout-grid/src/grid/variations.js:
--------------------------------------------------------------------------------
1 | /**
2 | * WordPress dependencies
3 | */
4 | import { __ } from '@wordpress/i18n';
5 |
6 | /** @typedef {import('@wordpress/blocks').WPBlockVariation} WPBlockVariation */
7 |
8 | /**
9 | * Internal dependencies
10 | */
11 | import ColumnIcon from './../icons';
12 | /**
13 | * Template option choices for predefined columns layouts.
14 | *
15 | * @type {WPBlockVariation[]}
16 | */
17 | const variations = [
18 | {
19 | name: 'one-column',
20 | title: __( 'One' ),
21 | description: __( 'One column', 'layout-grid' ),
22 | icon: ,
23 | isDefault: true,
24 | innerBlocks: [ [ 'jetpack/layout-grid-column' ] ],
25 | scope: [ 'block' ],
26 | },
27 | {
28 | name: 'two-columns',
29 | title: __( 'Two' ),
30 | description: __( 'Two columns', 'layout-grid' ),
31 | icon: ,
32 | innerBlocks: [
33 | [ 'jetpack/layout-grid-column' ],
34 | [ 'jetpack/layout-grid-column' ],
35 | ],
36 | scope: [ 'block' ],
37 | },
38 | {
39 | name: 'three-columns',
40 | title: __( 'Three' ),
41 | description: __( 'Three columns', 'layout-grid' ),
42 | icon: ,
43 | innerBlocks: [
44 | [ 'jetpack/layout-grid-column' ],
45 | [ 'jetpack/layout-grid-column' ],
46 | [ 'jetpack/layout-grid-column' ],
47 | ],
48 | scope: [ 'block' ],
49 | },
50 | {
51 | name: 'four-columns',
52 | title: __( 'Four' ),
53 | description: __( 'Four columns', 'layout-grid' ),
54 | icon: ,
55 | innerBlocks: [
56 | [ 'jetpack/layout-grid-column' ],
57 | [ 'jetpack/layout-grid-column' ],
58 | [ 'jetpack/layout-grid-column' ],
59 | [ 'jetpack/layout-grid-column' ],
60 | ],
61 | scope: [ 'block' ],
62 | },
63 | ];
64 |
65 | export default variations;
66 |
--------------------------------------------------------------------------------
/blocks/layout-grid/src/icons.js:
--------------------------------------------------------------------------------
1 | /**
2 | * WordPress dependencies
3 | */
4 |
5 | import { Path, SVG } from '@wordpress/components';
6 |
7 | export const GridIcon = ( props ) => {
8 | const iconProps = { ...props };
9 | if ( props.size ) {
10 | iconProps.width = props.size;
11 | iconProps.height = props.size;
12 | }
13 |
14 | return (
15 |
22 | );
23 | };
24 |
25 | export const GridColumnIcon = ( props ) => (
26 |
33 | );
34 |
35 | const ColSetup1 = ( props ) => (
36 |
43 | );
44 |
45 | const ColSetup2 = ( props ) => (
46 |
53 | );
54 |
55 | const ColSetup3 = ( props ) => (
56 |
63 | );
64 |
65 | const ColSetup4 = ( props ) => (
66 |
73 | );
74 |
75 | const ColumnIcon = ( { columns, ...props } ) => {
76 | if ( columns === 4 ) {
77 | return ;
78 | }
79 |
80 | if ( columns === 3 ) {
81 | return ;
82 | }
83 |
84 | if ( columns === 2 ) {
85 | return ;
86 | }
87 |
88 | return ;
89 | };
90 |
91 | export default ColumnIcon;
92 |
--------------------------------------------------------------------------------
/blocks/layout-grid/src/index.js:
--------------------------------------------------------------------------------
1 | /**
2 | * WordPress dependencies
3 | */
4 |
5 | import { registerBlockType } from '@wordpress/blocks';
6 | import { __ } from '@wordpress/i18n';
7 |
8 | /**
9 | * Internal dependencies
10 | */
11 |
12 | import editGrid from './grid/edit';
13 | import saveGrid from './grid/save';
14 | import editColumn from './grid-column/edit';
15 | import saveColumn from './grid-column/save';
16 | import { GridIcon, GridColumnIcon } from './icons';
17 | import {
18 | getSpanForDevice,
19 | getOffsetForDevice,
20 | DEVICE_BREAKPOINTS,
21 | MAX_COLUMNS,
22 | } from './constants';
23 | import deprecated from './grid-column/deprecated';
24 |
25 | function getColumnAttributes( total, breakpoints ) {
26 | const attributes = {};
27 |
28 | for ( let index = 0; index < total; index++ ) {
29 | breakpoints.map( ( breakpoint ) => {
30 | attributes[ getSpanForDevice( index, breakpoint ) ] = {
31 | type: 'number',
32 | };
33 | attributes[ getOffsetForDevice( index, breakpoint ) ] = {
34 | type: 'number',
35 | default: 0,
36 | };
37 | } );
38 | }
39 |
40 | return attributes;
41 | }
42 |
43 | export function registerBlock() {
44 | registerBlockType( 'jetpack/layout-grid', {
45 | title: __( 'Layout Grid', 'layout-grid' ),
46 | description: __(
47 | 'Align blocks to a global grid, with support for responsive breakpoints.',
48 | 'layout-grid'
49 | ),
50 | icon: GridIcon,
51 | category: 'design',
52 | supports: {
53 | align: [ 'full' ],
54 | html: false,
55 | },
56 | example: {
57 | attributes: {
58 | columns: 2,
59 | },
60 | innerBlocks: [
61 | {
62 | name: 'jetpack/layout-grid-column',
63 | innerBlocks: [
64 | {
65 | name: 'core/paragraph',
66 | attributes: {
67 | customFontSize: 32,
68 | content: __(
69 | 'Snow Patrol',
70 | 'layout-grid'
71 | ),
72 | align: 'center',
73 | },
74 | },
75 | ],
76 | },
77 | {
78 | name: 'jetpack/layout-grid-column',
79 | innerBlocks: [
80 | {
81 | name: 'core/image',
82 | attributes: {
83 | url:
84 | 'https://s.w.org/images/core/5.3/Windbuchencom.jpg',
85 | },
86 | },
87 | ],
88 | },
89 | ],
90 | },
91 | attributes: {
92 | gutterSize: {
93 | type: 'string',
94 | default: 'large',
95 | },
96 | addGutterEnds: {
97 | type: 'boolean',
98 | default: true,
99 | },
100 | verticalAlignment: {
101 | type: 'string',
102 | },
103 | ...getColumnAttributes( MAX_COLUMNS, DEVICE_BREAKPOINTS ),
104 | },
105 | edit: editGrid,
106 | save: saveGrid,
107 | } );
108 |
109 | registerBlockType( 'jetpack/layout-grid-column', {
110 | description: __(
111 | 'A column used inside a Layout Grid block.',
112 | 'layout-grid'
113 | ),
114 | title: __( 'Column', 'layout-grid' ),
115 | icon: GridColumnIcon,
116 | category: 'design',
117 | parent: [ 'jetpack/layout-grid' ],
118 | supports: {
119 | inserter: false,
120 | reusable: false,
121 | html: false,
122 | },
123 | attributes: {
124 | backgroundColor: {
125 | type: 'string',
126 | },
127 | customBackgroundColor: {
128 | type: 'string',
129 | },
130 | padding: {
131 | type: 'string',
132 | default: 'none',
133 | },
134 | verticalAlignment: {
135 | type: 'string',
136 | },
137 | },
138 | edit: editColumn,
139 | save: saveColumn,
140 | deprecated,
141 | } );
142 | }
143 |
--------------------------------------------------------------------------------
/blocks/layout-grid/tests/fixtures/invalidation/1-1-padding-color.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |

5 |
6 |
7 |
8 |
9 |
10 |
It is a long established fact that a reader will be distracted by the readable content of a page when looking at its layout. The point of using Lorem Ipsum is that it has a more-or-less normal distribution of letters, as opposed to using 'Content here, content here', making it look like readable English. Many desktop publishing packages and web page editors now use Lorem Ipsum as their default model text, and a search for 'lorem ipsum' will uncover many web sites still in their infancy. Various versions have evolved over the years, sometimes by accident, sometimes on purpose (injected humour and the like).
11 |
12 |
13 |
14 |
15 |
16 |

17 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/blocks/layout-grid/tests/fixtures/invalidation/1.0-color.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |

5 |
6 |
7 |
8 |
9 |
10 |
It is a long established fact that a reader will be distracted by the readable content of a page when looking at its layout. The point of using Lorem Ipsum is that it has a more-or-less normal distribution of letters, as opposed to using 'Content here, content here', making it look like readable English. Many desktop publishing packages and web page editors now use Lorem Ipsum as their default model text, and a search for 'lorem ipsum' will uncover many web sites still in their infancy. Various versions have evolved over the years, sometimes by accident, sometimes on purpose (injected humour and the like).
11 |
12 |
13 |
14 |
15 |
16 |

17 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/blocks/layout-grid/tests/fixtures/invalidation/1.0-default.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |

5 |
6 |
7 |
8 |
9 |
10 |
It is a long established fact that a reader will be distracted by the readable content of a page when looking at its layout. The point of using Lorem Ipsum is that it has a more-or-less normal distribution of letters, as opposed to using 'Content here, content here', making it look like readable English. Many desktop publishing packages and web page editors now use Lorem Ipsum as their default model text, and a search for 'lorem ipsum' will uncover many web sites still in their infancy. Various versions have evolved over the years, sometimes by accident, sometimes on purpose (injected humour and the like).
11 |
12 |
13 |
14 |
15 |
16 |

17 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/blocks/layout-grid/tests/fixtures/invalidation/1.1-default.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |

5 |
6 |
7 |
8 |
9 |
10 |
It is a long established fact that a reader will be distracted by the readable content of a page when looking at its layout. The point of using Lorem Ipsum is that it has a more-or-less normal distribution of letters, as opposed to using 'Content here, content here', making it look like readable English. Many desktop publishing packages and web page editors now use Lorem Ipsum as their default model text, and a search for 'lorem ipsum' will uncover many web sites still in their infancy. Various versions have evolved over the years, sometimes by accident, sometimes on purpose (injected humour and the like).
11 |
12 |
13 |
14 |
15 |
16 |

17 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/blocks/layout-grid/tests/fixtures/invalidation/1.2-default.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |

5 |
6 |
7 |
8 |
9 |
10 |
It is a long established fact that a reader will be distracted by the readable content of a page when looking at its layout. The point of using Lorem Ipsum is that it has a more-or-less normal distribution of letters, as opposed to using 'Content here, content here', making it look like readable English. Many desktop publishing packages and web page editors now use Lorem Ipsum as their default model text, and a search for 'lorem ipsum' will uncover many web sites still in their infancy. Various versions have evolved over the years, sometimes by accident, sometimes on purpose (injected humour and the like).
11 |
12 |
13 |
14 |
15 |
16 |

17 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/blocks/layout-grid/tests/fixtures/invalidation/1.2-padding-color.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |

5 |
6 |
7 |
8 |
9 |
10 |
It is a long established fact that a reader will be distracted by the readable content of a page when looking at its layout. The point of using Lorem Ipsum is that it has a more-or-less normal distribution of letters, as opposed to using 'Content here, content here', making it look like readable English. Many desktop publishing packages and web page editors now use Lorem Ipsum as their default model text, and a search for 'lorem ipsum' will uncover many web sites still in their infancy. Various versions have evolved over the years, sometimes by accident, sometimes on purpose (injected humour and the like).
11 |
12 |
13 |
14 |
15 |
16 |

17 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/blocks/layout-grid/tests/fixtures/migration/1.3-custom-color.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |

5 |
6 |
7 |
8 |
9 |
10 |
It is a long established fact that a reader will be distracted by the readable content of a page when looking at its layout. The point of using Lorem Ipsum is that it has a more-or-less normal distribution of letters, as opposed to using 'Content here, content here', making it look like readable English. Many desktop publishing packages and web page editors now use Lorem Ipsum as their default model text, and a search for 'lorem ipsum' will uncover many web sites still in their infancy. Various versions have evolved over the years, sometimes by accident, sometimes on purpose (injected humour and the like).
11 |
12 |
13 |
14 |
15 |
16 |

17 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/blocks/layout-grid/tests/fixtures/visual/four-column.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |

5 |
6 |
7 |
8 |
9 |
10 |
It is a long established fact that a reader will be distracted by the readable content of a page when looking at its layout. The point of using Lorem Ipsum is that it has a more-or-less normal distribution of letters, as opposed to using 'Content here, content here', making it look like readable English. Many desktop publishing packages and web page editors now use Lorem Ipsum as their default model text, and a search for 'lorem ipsum' will uncover many web sites still in their infancy. Various versions have evolved over the years, sometimes by accident, sometimes on purpose (injected humour and the like).
11 |
12 |
13 |
14 |
15 |
16 |

17 |
18 |
19 |
20 |
21 |
22 |
It is a long established fact that a reader will be distracted by the readable content of a page when looking at its layout. The point of using Lorem Ipsum is that it has a more-or-less normal distribution of letters, as opposed to using 'Content here, content here', making it look like readable English. Many desktop publishing packages and web page editors now use Lorem Ipsum as their default model text, and a search for 'lorem ipsum' will uncover many web sites still in their infancy. Various versions have evolved over the years, sometimes by accident, sometimes on purpose (injected humour and the like).
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/blocks/layout-grid/tests/fixtures/visual/one-column.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |

5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/blocks/layout-grid/tests/fixtures/visual/three-column.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |

6 |
7 |
8 |
9 |
10 |
11 |
It is a long established fact that a reader will be distracted by the readable content of a page when looking at its layout. The point of using Lorem Ipsum is that it has a more-or-less normal distribution of letters, as opposed to using 'Content here, content here', making it look like readable English. Many desktop publishing packages and web page editors now use Lorem Ipsum as their default model text, and a search for 'lorem ipsum' will uncover many web sites still in their infancy. Various versions have evolved over the years, sometimes by accident, sometimes on purpose (injected humour and the like).
12 |
13 |
14 |
15 |
16 |
17 |

18 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/blocks/layout-grid/tests/fixtures/visual/two-column-custom-background.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |

5 |
6 |
7 |
8 |
9 |
10 |
It is a long established fact that a reader will be distracted by the readable content of a page when looking at its layout. The point of using Lorem Ipsum is that it has a more-or-less normal distribution of letters, as opposed to using 'Content here, content here', making it look like readable English. Many desktop publishing packages and web page editors now use Lorem Ipsum as their default model text, and a search for 'lorem ipsum' will uncover many web sites still in their infancy. Various versions have evolved over the years, sometimes by accident, sometimes on purpose (injected humour and the like).
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/blocks/layout-grid/tests/fixtures/visual/two-column-no-gutters.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |

5 |
6 |
7 |
8 |
9 |
10 |
It is a long established fact that a reader will be distracted by the readable content of a page when looking at its layout. The point of using Lorem Ipsum is that it has a more-or-less normal distribution of letters, as opposed to using 'Content here, content here', making it look like readable English. Many desktop publishing packages and web page editors now use Lorem Ipsum as their default model text, and a search for 'lorem ipsum' will uncover many web sites still in their infancy. Various versions have evolved over the years, sometimes by accident, sometimes on purpose (injected humour and the like).
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/blocks/layout-grid/tests/fixtures/visual/two-column.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |

5 |
6 |
7 |
8 |
9 |
10 |
It is a long established fact that a reader will be distracted by the readable content of a page when looking at its layout. The point of using Lorem Ipsum is that it has a more-or-less normal distribution of letters, as opposed to using 'Content here, content here', making it look like readable English. Many desktop publishing packages and web page editors now use Lorem Ipsum as their default model text, and a search for 'lorem ipsum' will uncover many web sites still in their infancy. Various versions have evolved over the years, sometimes by accident, sometimes on purpose (injected humour and the like).
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/blocks/layout-grid/tests/tools/block.js:
--------------------------------------------------------------------------------
1 | /**
2 | * External dependencies
3 | */
4 |
5 | import fs from 'fs';
6 |
7 | /**
8 | * Internal dependencies
9 | */
10 | import './style.css';
11 |
12 | // TODO: it would be better if we could generate scss => css directly here
13 |
14 | /**
15 | * List of themes with their CSS file
16 | */
17 | const THEMES = {
18 | twentytwenty: 'https://themes.svn.wordpress.org/twentytwenty/1.4/style.css',
19 | };
20 |
21 | /**
22 | * Get a theme URL from a theme name
23 | *
24 | * @param {string} theme - Theme name
25 | * @return {string} Theme URL
26 | */
27 | function getTheme( theme ) {
28 | if ( THEMES[ theme ] ) {
29 | return THEMES[ theme ];
30 | }
31 |
32 | return THEMES.twentytwenty;
33 | }
34 |
35 | /**
36 | * Return a block embedded within a WP post.
37 | *
38 | * @param {Object} props - Component props
39 | * @param {string} props.blockHTML - The block HTML
40 | */
41 | export function Block( props ) {
42 | const { blockHTML } = props;
43 |
44 | return (
45 |
49 | );
50 | }
51 |
52 | /**
53 | * Render content within a fake WP themes
54 | *
55 | * @param {Object} props - Component props
56 | * @param {Object} props.children - The content to render in the theme
57 | * @param {string} props.theme - Theme name
58 | */
59 | export function Theme( props ) {
60 | const { children, theme } = props;
61 |
62 | return (
63 | <>
64 |
65 |
66 |
67 |
68 | { children }
69 |
70 |
71 | >
72 | );
73 | }
74 |
75 | /**
76 | * Utility function to dump the content of the psuedo browser to a file, to help with debugging.
77 | *
78 | * @param {string} filename - Target file name
79 | */
80 | export function dumpHTML( filename ) {
81 | fs.writeFileSync( filename, document.documentElement.outerHTML );
82 | }
83 |
84 | export function isValid( block ) {
85 | return (
86 | block.isValid &&
87 | ( block.innerBlocks
88 | ? block.innerBlocks.filter( ( filt ) => ! filt.isValid ).length ===
89 | 0
90 | : true )
91 | );
92 | }
93 |
--------------------------------------------------------------------------------
/blocks/layout-grid/tests/tools/fixtures.js:
--------------------------------------------------------------------------------
1 | /**
2 | * External dependencies
3 | */
4 |
5 | import { uniq } from 'lodash';
6 | import path from 'path';
7 | import fs from 'fs';
8 |
9 | const FIXTURES_DIR = path.join( __dirname, '..', 'fixtures' );
10 |
11 | export function readFixture( filename ) {
12 | try {
13 | return fs.readFileSync( path.join( FIXTURES_DIR, filename ), 'utf8' );
14 | } catch ( err ) {
15 | return null;
16 | }
17 | }
18 |
19 | export function getFixtures( groupName ) {
20 | return uniq(
21 | fs
22 | .readdirSync( path.join( FIXTURES_DIR, groupName ) )
23 | .filter( ( f ) => /(\.html|\.json)$/.test( f ) )
24 | ).map( ( filename ) => path.join( groupName, filename ) );
25 | }
26 |
--------------------------------------------------------------------------------
/blocks/model-viewer/editor.scss:
--------------------------------------------------------------------------------
1 | /**
2 | * The following styles get applied inside the editor only.
3 | */
4 |
--------------------------------------------------------------------------------
/blocks/model-viewer/index.json:
--------------------------------------------------------------------------------
1 | [ "model-viewer.min.js" ]
2 |
--------------------------------------------------------------------------------
/blocks/model-viewer/index.php:
--------------------------------------------------------------------------------
1 | 'google-model-viewer',
16 | 'editor_script' => 'block-experiments',
17 | 'style' => 'block-experiments',
18 | 'editor_style' => 'block-experiments-editor',
19 | ] );
20 |
21 | wp_register_script(
22 | 'google-model-viewer',
23 | plugins_url( 'model-viewer.min.js', __FILE__ ),
24 | [ 'wp-dom-ready' ],
25 | filemtime( plugin_dir_path( __FILE__ ) . 'model-viewer.min.js' ),
26 | true,
27 | );
28 |
29 | wp_set_script_translations( 'block-experiments', 'model-viewer' );
30 | }
31 | add_action( 'init', '\Automattic\A8c\Plugins\Blocks\ModelViewer\create_block_3d_model_block_block_init' );
32 |
33 |
34 | function allow_media_uploads( array $types ): array {
35 | // @todo: figure out why content-type is being changed to
36 | // application/octet-stream on upload, instead of remaining as
37 | // model/gltf+json and model/gltf-binary.
38 | $types['gltf'] = 'application/octet-stream';
39 | $types['glb'] = 'application/octet-stream';
40 |
41 | return $types;
42 | }
43 |
44 | function add_script_type_attribute($tag, $handle, $src) {
45 | if ( 'google-model-viewer' !== $handle ) {
46 | return $tag;
47 | }
48 |
49 | $dom = new \DOMDocument();
50 | $dom->loadHTML( $tag );
51 |
52 | /** @var \DOMElement $script */
53 | $script = $dom->getElementsByTagName( 'script' )[0];
54 | $script->removeAttribute( 'async' );
55 | $script->removeAttribute( 'defer' );
56 | $script->setAttribute( 'type', 'module' );
57 |
58 | return $dom->saveHTML( $script );
59 | }
60 |
61 | function remove_upload_size_limit() {
62 | return 0;
63 | }
64 |
65 | add_filter( 'script_loader_tag', '\Automattic\A8c\Plugins\Blocks\ModelViewer\add_script_type_attribute' , 10, 3 );
66 | add_filter( 'upload_mimes', '\Automattic\A8c\Plugins\Blocks\ModelViewer\allow_media_uploads', 10, 1 );
67 | add_filter( 'upload_size_limit', '\Automattic\A8c\Plugins\Blocks\ModelViewer\remove_upload_size_limit', 10, 0 );
68 |
--------------------------------------------------------------------------------
/blocks/model-viewer/src/icon.js:
--------------------------------------------------------------------------------
1 | /**
2 | * WordPress depedencies
3 | */
4 |
5 | import { Path, SVG } from '@wordpress/components';
6 |
7 | export const icon = () => (
8 |
20 | );
21 |
--------------------------------------------------------------------------------
/blocks/model-viewer/src/index.js:
--------------------------------------------------------------------------------
1 | /**
2 | * WordPress dependencies
3 | */
4 | import { registerBlockType } from '@wordpress/blocks';
5 | import { __ } from '@wordpress/i18n';
6 |
7 | /**
8 | * Internal dependencies
9 | */
10 | import { icon } from './icon';
11 | import Edit from './edit';
12 | import Save from './save';
13 |
14 | export const registerBlock = () => {
15 | registerBlockType( 'a8c/model-viewer', {
16 | title: '3D Model',
17 | description: __(
18 | 'Show 3D models in an interactive viewer. Add files in .gltf or .glb formats.'
19 | ),
20 | category: 'widgets',
21 | icon,
22 | attributes: {
23 | id: {
24 | type: 'number',
25 | },
26 | src: {
27 | type: 'string',
28 | source: 'attribute',
29 | selector: 'model-viewer',
30 | attribute: 'src',
31 | },
32 | alt: {
33 | type: 'string',
34 | source: 'attribute',
35 | selector: 'model-viewer',
36 | attribute: 'alt',
37 | default: '',
38 | },
39 | autoRotate: {
40 | type: 'boolean',
41 | default: false,
42 | },
43 | width: {
44 | type: 'number',
45 | },
46 | widthUnit: {
47 | type: 'string',
48 | },
49 | height: {
50 | type: 'number',
51 | },
52 | heightUnit: {
53 | type: 'string',
54 | },
55 | cameraOrbit: {
56 | type: 'string',
57 | },
58 | fieldOfView: {
59 | type: 'number',
60 | },
61 | },
62 | supports: {
63 | align: true,
64 | },
65 | edit: ( props ) => ,
66 | save: ( props ) => ,
67 | } );
68 | };
69 |
--------------------------------------------------------------------------------
/blocks/model-viewer/src/save.js:
--------------------------------------------------------------------------------
1 | import { __ } from '@wordpress/i18n';
2 | import { useBlockProps } from '@wordpress/block-editor';
3 |
4 | import { DEFAULT_HEIGHT, DEFAULT_WIDTH } from './utils.js';
5 |
6 | export default function save( { attributes } ) {
7 | const {
8 | src,
9 | alt,
10 | width,
11 | height,
12 | widthUnit,
13 | heightUnit,
14 | cameraOrbit,
15 | fieldOfView,
16 | autoRotate,
17 | } = attributes;
18 |
19 | // React stringifies custom properties, so use object destructuring to disable auto-rotate.
20 | // See https://github.com/facebook/react/issues/9230
21 | // Gutenberg won't save the value when true is a boolean.
22 | const autoRotateAttr = autoRotate ? { 'auto-rotate': 'true' } : {};
23 |
24 | return (
25 |
26 |
50 |
51 | );
52 | }
53 |
--------------------------------------------------------------------------------
/blocks/model-viewer/src/utils.js:
--------------------------------------------------------------------------------
1 | export const PC_WIDTH_DEFAULT = 50;
2 | export const PX_WIDTH_DEFAULT = 350;
3 | export const PC_HEIGHT_DEFAULT = 50;
4 | export const PX_HEIGHT_DEFAULT = 350;
5 | export const DEFAULT_WIDTH = '100%';
6 | export const DEFAULT_HEIGHT = '240px';
7 | export const MIN_WIDTH = 220;
8 | export const MIN_WIDTH_UNIT = 'px';
9 | export const MIN_HEIGHT = 220;
10 | export const MIN_HEIGHT_UNIT = 'px';
11 |
--------------------------------------------------------------------------------
/blocks/model-viewer/style.scss:
--------------------------------------------------------------------------------
1 | /**
2 | * Frontend styles.
3 | */
4 |
5 | .wp-block-a8c-model-viewer {
6 | // Clear out default margins on figure.
7 | margin-left: 0;
8 | margin-right: 0;
9 | }
10 |
11 | .wp-block-a8c-model-viewer__component {
12 | width: inherit;
13 | height: inherit;
14 | }
15 |
--------------------------------------------------------------------------------
/blocks/motion-background/README.md:
--------------------------------------------------------------------------------
1 | # Motion Background Block
2 |
3 | The motion background block was an experiment in providing a wrapper WebGL context for blocks because each browser implementation has a fixed number of WebGL contexts available.
4 |
5 | It proved a bit more difficult than was worth continuing to explore since it was unlikely to have more than 8 of these blocks on a single page. So the idea was discarded and development continued in the [`a8c/waves` block](/blocks/waves) using a single WebGL context for each block.
6 |
--------------------------------------------------------------------------------
/blocks/rich-image/readme.md:
--------------------------------------------------------------------------------
1 | # Rich Image Block
2 |
3 | The Rich Image block has been promoted to a WordPress core feature as part of the Image block. 🎉
4 |
5 | The [Image block source is available in the Gutenberg repository](https://github.com/WordPress/gutenberg/tree/v8.4.0/packages/block-library/src/image) and the [associated REST API is in WordPress core](https://github.com/WordPress/wordpress-develop/commit/e51a554f5da556804e05e0bb498f59473de8ce7d). It is included in WordPress 5.5.
6 |
--------------------------------------------------------------------------------
/blocks/sketch/editor.scss:
--------------------------------------------------------------------------------
1 | .wp-block-a8c-sketch {
2 | &__brush-style-popover {
3 | /**
4 | * Take care of default width for popover content.
5 | */
6 | .components-popover__content {
7 | min-width: initial;
8 | }
9 | }
10 | &__color-palette-popover {
11 | /**
12 | * Take care of default width for popover content.
13 | */
14 | .components-popover__content {
15 | padding: 16px;
16 | }
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/blocks/sketch/index.php:
--------------------------------------------------------------------------------
1 | %s', esc_html( $title ) ) : '';
12 | $supports_attributes = get_block_wrapper_attributes();
13 |
14 | if ( ! isset( $attributes['strokes'] ) || '' === $attributes['strokes'] ) {
15 | return '';
16 | }
17 |
18 | $paths = array_map(
19 | function( $stroke ) {
20 | if ( ! isset( $stroke['stroke'] ) || '' === $stroke['stroke'] ||
21 | ! isset( $stroke['color'] ) || '' === $stroke['color'] ) {
22 | return '';
23 | }
24 | return sprintf(
25 | '',
26 | esc_attr( $stroke['color'] ),
27 | esc_attr( get_svg_path_from_stroke( $stroke['stroke'] ) )
28 | );
29 | },
30 | $strokes
31 | );
32 |
33 | $style = sprintf( 'style="height: %dpx;"', esc_attr( $height ) );
34 |
35 | $html =
36 | sprintf( '', $supports_attributes, $style ) .
37 | '' .
41 | '';
42 | return $html;
43 | }
44 |
45 | function set_render_callback() {
46 | // Note that 'block-experiments' gets replaced with 'a8c-sketch' when bundling
47 | register_block_type(
48 | 'a8c/sketch',
49 | [
50 | 'editor_script' => 'block-experiments',
51 | 'style' => 'block-experiments',
52 | 'editor_style' => 'block-experiments-editor',
53 | 'render_callback' => __NAMESPACE__ . '\a8c_sketch_render',
54 | 'supports' => array(
55 | 'align' => true,
56 | )
57 | ]
58 | );
59 | }
60 |
61 | function get_svg_path_from_stroke( $stroke ) {
62 | if ( count( $stroke ) === 0 ) {
63 | return '';
64 | }
65 |
66 | $d = [];
67 |
68 | $p0 = $stroke[0];
69 | $p1 = $stroke[1];
70 |
71 | $d = array_merge( $d, [ 'M', $p0[0], $p0[1], 'Q' ] );
72 |
73 | $n_marks = count( $stroke );
74 |
75 | for ( $i = 1; $i < $n_marks; $i++ ) {
76 |
77 | $d = array_merge(
78 | $d,
79 | [
80 | $p0[0],
81 | $p0[1],
82 | ( $p0[0] + $p1[0] ) / 2,
83 | ( $p0[1] + $p1[1] ) / 2,
84 | ]
85 | );
86 | $p0 = $p1;
87 | $p1 = $stroke[ $i ];
88 | }
89 |
90 | $d[] = 'Z';
91 |
92 | return implode( ' ', $d );
93 | }
94 |
95 | add_action( 'init', __NAMESPACE__ . '\set_render_callback' );
96 |
97 |
--------------------------------------------------------------------------------
/blocks/sketch/src/icons.js:
--------------------------------------------------------------------------------
1 | /**
2 | * WordPress dependencies
3 | */
4 | import { Circle, Path, Rect, SVG } from '@wordpress/components';
5 |
6 | export const BlockIcon = () => (
7 |
19 | );
20 |
21 | export const ColorControlIcon = ( { color } ) => (
22 |
31 | );
32 |
33 | export const BrushSizeControlIcon = () => (
34 |
39 | );
40 |
41 | export const BrushSizeIcon = ( { radius = 8 } ) => (
42 |
45 | );
46 |
--------------------------------------------------------------------------------
/blocks/sketch/src/index.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Internal dependencies
3 | */
4 | import edit from './edit';
5 | import save from './save';
6 | import { BlockIcon as icon } from './icons';
7 | import example from './example';
8 |
9 | /**
10 | * WordPress dependencies
11 | */
12 | import { __, _x } from '@wordpress/i18n';
13 | import { registerBlockType } from '@wordpress/blocks';
14 |
15 | export const name = 'a8c/sketch';
16 |
17 | const block = {
18 | apiVersion: 2,
19 | icon,
20 | attributes: {
21 | strokes: { type: 'array', default: [] },
22 | height: { type: 'number', default: 450 },
23 | title: { type: 'string', default: '' },
24 | },
25 | supports: {
26 | align: true,
27 | },
28 | title: __( 'Sketch', 'a8c-sketch' ),
29 | category: 'widgets',
30 | description: _x(
31 | '“Not a day without a line drawn.” — Apelles of Kos',
32 | 'Block description, based on a quote',
33 | 'a8c-sketch'
34 | ),
35 | keywords: [ __( 'Draw', 'a8c-sketch' ) ],
36 | edit,
37 | save,
38 | example,
39 | };
40 | export function registerBlock() {
41 | registerBlockType( name, block );
42 | }
43 |
--------------------------------------------------------------------------------
/blocks/sketch/src/lib.js:
--------------------------------------------------------------------------------
1 | export const presets = [
2 | {
3 | size: 3,
4 | thinning: 0.3,
5 | smoothing: 0.83,
6 | streamline: 0.45,
7 | },
8 | {
9 | size: 14,
10 | thinning: 0.6,
11 | smoothing: 0.5,
12 | streamline: 0.75,
13 | },
14 | {
15 | size: 25,
16 | thinning: 0.5,
17 | smoothing: 0.5,
18 | streamline: 0.6,
19 | },
20 | ];
21 |
22 | const average = (a, b) => (a + b) / 2
23 |
24 |
25 | // Create SVG path data using the strokes from perfect-freehand.
26 | export function getSvgPathFromStroke( points, closed = true ) {
27 | const len = points.length
28 |
29 | if (len < 4) {
30 | return ``
31 | }
32 |
33 | let a = points[0]
34 | let b = points[1]
35 | const c = points[2]
36 |
37 | let result = `M${a[0].toFixed(2)},${a[1].toFixed(2)} Q${b[0].toFixed(2)},${b[1].toFixed(
38 | 2
39 | )} ${average(b[0], c[0]).toFixed(2)},${average(b[1], c[1]).toFixed(2)} T`
40 |
41 | for (let i = 2, max = len - 1; i < max; i++) {
42 | a = points[i]
43 | b = points[i + 1]
44 | result += `${average(a[0], b[0]).toFixed(2)},${average(a[1], b[1]).toFixed(2)} `
45 | }
46 |
47 | if (closed) {
48 | result += 'Z'
49 | }
50 |
51 | return result
52 | }
53 |
--------------------------------------------------------------------------------
/blocks/sketch/src/save.js:
--------------------------------------------------------------------------------
1 | /**
2 | * WordPress dependencies
3 | */
4 | import { __ } from '@wordpress/i18n';
5 | import { useBlockProps } from '@wordpress/block-editor';
6 |
7 | const Save = () => {
8 | const blockProps = useBlockProps.save();
9 |
10 | return ;
11 | };
12 |
13 | export default Save;
14 |
--------------------------------------------------------------------------------
/blocks/sketch/style.scss:
--------------------------------------------------------------------------------
1 | .wp-block-a8c-sketch {
2 | height: 100%;
3 | position: relative;
4 |
5 | svg {
6 | position: absolute;
7 | top: 0;
8 | left: 0;
9 | width: 100%;
10 | height: 100%;
11 | touch-action: none;
12 | overflow: hidden;
13 |
14 | path {
15 | user-select: none;
16 | -webkit-user-select: none;
17 | }
18 | }
19 |
20 | }
21 |
--------------------------------------------------------------------------------
/blocks/starscape/README.md:
--------------------------------------------------------------------------------
1 | # Starscape Block
2 |
3 | 
4 |
5 | An experiment in saving dynamically generated styles. This block creates a dynamic animated starfield using CSS `box-shadow`.
6 |
7 | Everything was made of collapsing stars, we are all made of star stuff. Now we also can create content in WordPress with stars in motion.
8 |
9 | ## Screenshots
10 |
11 | 
12 | 
13 | 
14 | 
15 |
--------------------------------------------------------------------------------
/blocks/starscape/editor.scss:
--------------------------------------------------------------------------------
1 | .wp-block-a8c-starscape__advanced {
2 | margin-bottom: 24px;
3 |
4 | & > p {
5 | grid-column: span 2;
6 | margin-bottom: 0;
7 | }
8 |
9 | & > .components-base-control {
10 | margin-bottom: 0;
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/blocks/starscape/index.php:
--------------------------------------------------------------------------------
1 | 'block-experiments',
19 | 'style' => 'block-experiments',
20 | 'editor_style' => 'block-experiments-editor',
21 | ] );
22 |
23 | wp_set_script_translations( 'block-experiments', 'starscape' );
24 | }
25 | add_action( 'init', __NAMESPACE__ . '\register_block' );
26 |
--------------------------------------------------------------------------------
/blocks/starscape/src/attributes.js:
--------------------------------------------------------------------------------
1 | export default {
2 | align: {
3 | type: 'string',
4 | default: 'full',
5 | },
6 | color: {
7 | type: 'string',
8 | default: '#fff',
9 | },
10 | background: {
11 | type: 'string',
12 | // Default #000 in style.scss.
13 | },
14 | intensity: {
15 | type: 'number',
16 | default: 80,
17 | },
18 | density: {
19 | type: 'number',
20 | default: 20,
21 | },
22 | speed: {
23 | type: 'number',
24 | default: 20,
25 | },
26 | areaWidth: {
27 | type: 'integer',
28 | default: 1920,
29 | },
30 | areaHeight: {
31 | type: 'integer',
32 | default: 1080,
33 | },
34 | minHeight: {
35 | type: 'string',
36 | // Default 430px in style.scss.
37 | },
38 | layout: {
39 | type: 'object',
40 | default: {
41 | type: 'constrained',
42 | },
43 | },
44 | tagName: {
45 | type: 'string',
46 | default: 'div',
47 | },
48 | templateLock: {
49 | type: [ 'string', 'boolean' ],
50 | enum: [ 'all', 'insert', 'contentOnly', false ],
51 | },
52 | allowedBlocks: {
53 | type: 'array',
54 | },
55 | };
56 |
--------------------------------------------------------------------------------
/blocks/starscape/src/deprecated/index.js:
--------------------------------------------------------------------------------
1 | import v1 from './v1';
2 | import v2 from './v2';
3 |
4 | // Deprecations should run in reverse chronological order. Most probable
5 | // deprecations to run are the most recent. This ordering makes the process
6 | // a little more performant.
7 | export default [ v2, v1 ];
8 |
--------------------------------------------------------------------------------
/blocks/starscape/src/deprecated/v1/save.js:
--------------------------------------------------------------------------------
1 | /**
2 | * External dependencies
3 | */
4 | import classnames from 'classnames';
5 |
6 | /**
7 | * WordPress dependencies
8 | */
9 | import { RichText, getColorClassName } from '@wordpress/block-editor';
10 |
11 | /**
12 | * Internal dependencies
13 | */
14 | import Starscape from './starscape';
15 |
16 | const Save = ( { attributes, className } ) => {
17 | const textColorClass = getColorClassName( 'color', attributes.textColor );
18 |
19 | return (
20 |
26 |
43 |
44 | );
45 | };
46 |
47 | export default Save;
48 |
--------------------------------------------------------------------------------
/blocks/starscape/src/deprecated/v1/starscape.js:
--------------------------------------------------------------------------------
1 | /**
2 | * External dependencies
3 | */
4 | import classnames from 'classnames';
5 |
6 | const Starscape = ( {
7 | starStyles,
8 | animationStyles,
9 | children,
10 | className,
11 | background,
12 | } ) => {
13 | return (
14 |
18 |
25 |
32 |
39 | { children }
40 |
41 | );
42 | };
43 |
44 | export default Starscape;
45 |
--------------------------------------------------------------------------------
/blocks/starscape/src/deprecated/v2/attributes.js:
--------------------------------------------------------------------------------
1 | export default {
2 | align: {
3 | type: 'string',
4 | default: 'full',
5 | },
6 | color: {
7 | type: 'string',
8 | default: '#fff',
9 | },
10 | background: {
11 | type: 'string',
12 | // Default #000 in style.scss.
13 | },
14 | intensity: {
15 | type: 'number',
16 | default: 80,
17 | },
18 | density: {
19 | type: 'number',
20 | default: 20,
21 | },
22 | speed: {
23 | type: 'number',
24 | default: 20,
25 | },
26 | areaWidth: {
27 | type: 'integer',
28 | default: 1920,
29 | },
30 | areaHeight: {
31 | type: 'integer',
32 | default: 1080,
33 | },
34 | minHeight: {
35 | type: 'string',
36 | // Default 430px in style.scss.
37 | },
38 | layout: {
39 | type: 'object',
40 | default: {
41 | type: 'constrained',
42 | },
43 | },
44 | tagName: {
45 | type: 'string',
46 | default: 'div',
47 | },
48 | templateLock: {
49 | type: [ 'string', 'boolean' ],
50 | enum: [ 'all', 'insert', 'contentOnly', false ],
51 | },
52 | allowedBlocks: {
53 | type: 'array',
54 | },
55 | };
56 |
--------------------------------------------------------------------------------
/blocks/starscape/src/deprecated/v2/index.js:
--------------------------------------------------------------------------------
1 | /**
2 | * WordPress dependencies
3 | */
4 | import { __ } from '@wordpress/i18n';
5 |
6 | /**
7 | * Internal dependencies
8 | */
9 | import attributes from './attributes';
10 | import save from './save';
11 |
12 | export default {
13 | supports: {
14 | className: true,
15 | align: [ 'wide', 'full' ],
16 | color: {
17 | heading: true,
18 | text: true,
19 | link: true,
20 | background: false,
21 | gradients: false,
22 | },
23 | html: false,
24 | layout: {
25 | allowJustification: false,
26 | },
27 | spacing: {
28 | padding: true,
29 | margin: [ 'top', 'bottom' ],
30 | blockGap: true,
31 | __experimentalDefaultControls: {
32 | padding: true,
33 | blockGap: true,
34 | },
35 | },
36 | },
37 | attributes,
38 | save,
39 | };
40 |
--------------------------------------------------------------------------------
/blocks/starscape/src/deprecated/v2/save.js:
--------------------------------------------------------------------------------
1 | /**
2 | * WordPress dependencies
3 | */
4 | import { useBlockProps, useInnerBlocksProps } from '@wordpress/block-editor';
5 |
6 | /**
7 | * Internal dependencies
8 | */
9 | import Starscape from './starscape';
10 | import { genStars, genAnimations } from './utils';
11 |
12 | function StarscapeSave( { attributes } ) {
13 | const {
14 | background,
15 | color,
16 | intensity,
17 | density,
18 | speed,
19 | minHeight,
20 | areaWidth,
21 | areaHeight,
22 | tagName,
23 | } = attributes;
24 |
25 | const starStyles = genStars( { color, density, areaWidth, areaHeight } );
26 | const animationStyles = genAnimations( { speed } );
27 |
28 | const blockProps = useBlockProps.save( {
29 | style: { background, minHeight },
30 | } );
31 |
32 | const innerBlocksProps = useInnerBlocksProps.save( {
33 | className: 'wp-block-a8c-starscape__inner',
34 | } );
35 |
36 | return (
37 |
44 |
45 |
46 | );
47 | }
48 |
49 | export default StarscapeSave;
50 |
--------------------------------------------------------------------------------
/blocks/starscape/src/deprecated/v2/starscape.js:
--------------------------------------------------------------------------------
1 | /**
2 | * WordPress dependencies
3 | */
4 | import { forwardRef } from '@wordpress/element';
5 |
6 | /**
7 | * @typedef {Object} StarscapeProps
8 | * @property {string} [as] HTML tag name.
9 | * @property {Object} starStyles Styles for the stars.
10 | * @property {Object} animationStyles Styles for the animation.
11 | * @property {number} intensity Intensity of the stars.
12 | * @property {WPElement} [children] Children of the component.
13 | */
14 |
15 | /**
16 | * Starscape background effect component.
17 | *
18 | * @param {StarscapeProps} props Starscape props
19 | * @param {Ref} ref React ref
20 | *
21 | * @returns {WPElement} Starscape component
22 | */
23 | const Starscape = (
24 | {
25 | as: Component = 'div',
26 | starStyles,
27 | animationStyles,
28 | intensity,
29 | children,
30 | ...props
31 | },
32 | ref
33 | ) => {
34 | return (
35 |
36 | { [ 0, 1, 2 ].map( ( i ) => (
37 |
46 | ) ) }
47 | { children }
48 |
49 | );
50 | };
51 |
52 | export default forwardRef( Starscape );
53 |
--------------------------------------------------------------------------------
/blocks/starscape/src/icon.js:
--------------------------------------------------------------------------------
1 | /**
2 | * WordPress dependencies
3 | */
4 | import { Path, SVG } from '@wordpress/components';
5 |
6 | const StarsIcon = ( props ) => {
7 | return (
8 |
15 | );
16 | };
17 |
18 | export default StarsIcon;
19 |
--------------------------------------------------------------------------------
/blocks/starscape/src/index.js:
--------------------------------------------------------------------------------
1 | /**
2 | * WordPress dependencies
3 | */
4 | import { registerBlockType } from '@wordpress/blocks';
5 | import { __ } from '@wordpress/i18n';
6 |
7 | /**
8 | * Internal dependencies
9 | */
10 | import StarsIcon from './icon';
11 | import attributes from './attributes';
12 | import edit from './edit';
13 | import save from './save';
14 | import deprecated from './deprecated';
15 |
16 | export function registerBlock() {
17 | registerBlockType( 'a8c/starscape', {
18 | apiVersion: 3,
19 | title: __( 'Starscape', 'starscape' ),
20 | description: __( 'Create content with stars in motion.', 'starscape' ),
21 | icon: ,
22 | category: 'widgets',
23 | supports: {
24 | className: true,
25 | align: [ 'wide', 'full' ],
26 | color: {
27 | heading: true,
28 | text: true,
29 | link: true,
30 | background: false,
31 | gradients: false,
32 | },
33 | html: false,
34 | layout: {
35 | allowJustification: false,
36 | },
37 | spacing: {
38 | padding: true,
39 | margin: [ 'top', 'bottom' ],
40 | blockGap: true,
41 | __experimentalDefaultControls: {
42 | padding: true,
43 | blockGap: true,
44 | },
45 | },
46 | },
47 | attributes,
48 | edit,
49 | save,
50 | deprecated,
51 | } );
52 | }
53 |
--------------------------------------------------------------------------------
/blocks/starscape/src/save.js:
--------------------------------------------------------------------------------
1 | /**
2 | * WordPress dependencies
3 | */
4 | import { useBlockProps, useInnerBlocksProps } from '@wordpress/block-editor';
5 |
6 | /**
7 | * Internal dependencies
8 | */
9 | import Starscape from './starscape';
10 | import { genStars, genAnimations } from './utils';
11 |
12 | function StarscapeSave( { attributes } ) {
13 | const {
14 | background,
15 | color,
16 | intensity,
17 | density,
18 | speed,
19 | minHeight,
20 | areaWidth,
21 | areaHeight,
22 | tagName,
23 | } = attributes;
24 |
25 | const starStyles = genStars( { color, density, areaWidth, areaHeight } );
26 | const animationStyles = genAnimations( { speed } );
27 |
28 | const blockProps = useBlockProps.save( {
29 | style: { background, minHeight, overflow: 'hidden' },
30 | } );
31 |
32 | const innerBlocksProps = useInnerBlocksProps.save( {
33 | className: 'wp-block-a8c-starscape__inner',
34 | } );
35 |
36 | return (
37 |
44 |
45 |
46 | );
47 | }
48 |
49 | export default StarscapeSave;
50 |
--------------------------------------------------------------------------------
/blocks/starscape/src/starscape.js:
--------------------------------------------------------------------------------
1 | /**
2 | * WordPress dependencies
3 | */
4 | import { forwardRef } from '@wordpress/element';
5 |
6 | /**
7 | * @typedef {Object} StarscapeProps
8 | * @property {string} [as] HTML tag name.
9 | * @property {Object} starStyles Styles for the stars.
10 | * @property {Object} animationStyles Styles for the animation.
11 | * @property {number} intensity Intensity of the stars.
12 | * @property {WPElement} [children] Children of the component.
13 | */
14 |
15 | /**
16 | * Starscape background effect component.
17 | *
18 | * @param {StarscapeProps} props Starscape props
19 | * @param {Ref} ref React ref
20 | *
21 | * @returns {WPElement} Starscape component
22 | */
23 | const Starscape = (
24 | {
25 | as: Component = 'div',
26 | starStyles,
27 | animationStyles,
28 | intensity,
29 | children,
30 | ...props
31 | },
32 | ref
33 | ) => {
34 | return (
35 |
36 | { [ 0, 1, 2 ].map( ( i ) => (
37 |
46 | ) ) }
47 | { children }
48 |
49 | );
50 | };
51 |
52 | export default forwardRef( Starscape );
53 |
--------------------------------------------------------------------------------
/blocks/starscape/style.scss:
--------------------------------------------------------------------------------
1 | .wp-block-a8c-starscape {
2 | position: relative;
3 | min-height: 430px;
4 | display: flex;
5 | justify-content: center;
6 | align-items: center;
7 | padding: 1em;
8 | overflow: hidden;
9 | overflow: clip;
10 | box-sizing: border-box;
11 | background: #000;
12 |
13 | &__inner {
14 | width: 100%;
15 | }
16 |
17 | &__stars {
18 | position: absolute;
19 | top: 100%;
20 | left: 50%;
21 | transform: translateZ( 0 );
22 | }
23 |
24 | /*
25 | * v1 block styles.
26 | */
27 |
28 | &:has( > &__heading ) {
29 | justify-content: initial;
30 | padding: 0 40px;
31 | }
32 |
33 | &__heading {
34 | z-index: 1;
35 | width: 100%;
36 | font-size: 84px;
37 | line-height: 1.3;
38 | }
39 | }
40 |
41 | @keyframes wp-block-a8c-starscape-animation-rotate {
42 | from {
43 | transform: rotateZ( 0deg );
44 | }
45 | to {
46 | transform: rotateZ( 360deg );
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/blocks/waves/editor.scss:
--------------------------------------------------------------------------------
1 | /* Editor styles */
2 |
3 | .wp-block-a8c-waves {
4 | &__inner-container
5 | > .block-editor-inner-blocks
6 | > .block-editor-block-list__layout {
7 | margin-left: 0;
8 | margin-right: 0;
9 | }
10 |
11 | &__resize-container:not( .is-resizing ) {
12 | // Important is used to have higher specificity than the inline style set by re-resizable library.
13 | height: auto !important;
14 | }
15 |
16 | [data-align='left'] > &,
17 | [data-align='right'] > & {
18 | max-width: 290px;
19 | width: 100%;
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/blocks/waves/index.json:
--------------------------------------------------------------------------------
1 | [ "twgl/twgl.js", "waves.js" ]
2 |
--------------------------------------------------------------------------------
/blocks/waves/index.php:
--------------------------------------------------------------------------------
1 | 'a8c-waves-js',
6 | 'editor_script' => 'block-experiments',
7 | 'style' => 'block-experiments',
8 | 'editor_style' => 'block-experiments-editor',
9 | ] );
10 | wp_register_script(
11 | 'a8c-twgl-js',
12 | plugins_url( 'twgl/twgl.js', __FILE__ ),
13 | [], // no dependencies
14 | filemtime( plugin_dir_path( __FILE__ ) . 'twgl/twgl.js' ),
15 | true // in footer
16 | );
17 | wp_register_script(
18 | 'a8c-waves-js',
19 | plugins_url( 'waves.js', __FILE__ ),
20 | [ 'a8c-twgl-js', 'wp-dom-ready' ],
21 | filemtime( plugin_dir_path( __FILE__ ) . 'waves.js' ),
22 | true // in footer
23 | );
24 | wp_set_script_translations( 'block-experiments', 'waves' );
25 | } );
26 |
27 | add_filter( 'should_load_separate_core_block_assets', '__return_true' );
28 |
--------------------------------------------------------------------------------
/blocks/waves/src/icon.js:
--------------------------------------------------------------------------------
1 | /**
2 | * WordPress dependencies
3 | */
4 | import { Path, SVG } from '@wordpress/components';
5 |
6 | const WavesIcon = ( props ) => {
7 | return (
8 |
19 | );
20 | };
21 |
22 | export default WavesIcon;
23 |
--------------------------------------------------------------------------------
/blocks/waves/src/index.js:
--------------------------------------------------------------------------------
1 | /**
2 | * WordPress dependencies
3 | */
4 | import { registerBlockType } from '@wordpress/blocks';
5 | import { __ } from '@wordpress/i18n';
6 |
7 | /**
8 | * Internal dependencies
9 | */
10 | import WavesIcon from './icon';
11 | import Edit from './edit';
12 | import Save from './save';
13 |
14 | export const registerBlock = () => {
15 | registerBlockType( 'a8c/waves', {
16 | title: __( 'Waves', 'waves' ),
17 | description: __( 'Create content with waves in motion.', 'waves' ),
18 | icon: ,
19 | category: 'widgets',
20 | supports: {
21 | align: true,
22 | html: false,
23 | },
24 | attributes: {
25 | complexity: {
26 | type: 'integer',
27 | default: 2,
28 | },
29 | mouseSpeed: {
30 | type: 'integer',
31 | default: 20,
32 | },
33 | fluidSpeed: {
34 | type: 'integer',
35 | default: 20,
36 | },
37 | color1: {
38 | type: 'string',
39 | },
40 | color2: {
41 | type: 'string',
42 | },
43 | color3: {
44 | type: 'string',
45 | },
46 | color4: {
47 | type: 'string',
48 | },
49 | minHeight: {
50 | type: 'number',
51 | },
52 | minHeightUnit: {
53 | type: 'string',
54 | },
55 | previewImage: {
56 | type: 'string',
57 | },
58 | },
59 | edit: Edit,
60 | save: Save,
61 | } );
62 | };
63 |
--------------------------------------------------------------------------------
/blocks/waves/src/save.js:
--------------------------------------------------------------------------------
1 | /**
2 | * WordPress dependencies
3 | */
4 | import { InnerBlocks } from '@wordpress/block-editor';
5 |
6 | const Save = ( { attributes } ) => {
7 | const minHeightWithUnit = attributes.minHeightUnit
8 | ? `${ attributes.minHeight }${ attributes.minHeightUnit }`
9 | : attributes.minHeight;
10 | const style = {
11 | minHeight: minHeightWithUnit || undefined,
12 | backgroundImage: `url( "${ attributes.previewImage }" )`,
13 | };
14 | return (
15 |
29 | );
30 | };
31 |
32 | export default Save;
33 |
--------------------------------------------------------------------------------
/blocks/waves/style.scss:
--------------------------------------------------------------------------------
1 | /* Editor styles */
2 |
3 | .wp-block-a8c-waves {
4 | position: relative;
5 | min-height: 430px;
6 | height: 100%;
7 | width: 100%;
8 | display: flex;
9 | justify-content: center;
10 | align-items: center;
11 | overflow: hidden;
12 |
13 | // Bottom left is consistent with how the WebGL behaves, so this will be the most similar to what is shown in the editor.
14 | background: bottom left / cover no-repeat;
15 |
16 | // Using flexbox without an assigned height property breaks vertical center alignment in IE11.
17 | // Appending an empty ::after element tricks IE11 into giving the cover image an implicit height, which sidesteps this issue.
18 | &::after {
19 | display: block;
20 | content: '';
21 | font-size: 0;
22 | min-height: inherit;
23 |
24 | // IE doesn't support flex so omit that.
25 | @supports ( position: sticky ) {
26 | content: none;
27 | }
28 | }
29 |
30 | &__inner-container {
31 | width: calc( 100% - 70px );
32 | padding: 2rem 0;
33 | z-index: 1;
34 | }
35 |
36 | // Apply max-width to floated items that have no intrinsic width
37 | &.alignleft,
38 | &.alignright {
39 | max-width: 290px;
40 | width: 100%;
41 | }
42 |
43 | // Aligned cover blocks should not use our global alignment rules
44 | &.aligncenter,
45 | &.alignleft,
46 | &.alignright {
47 | display: flex;
48 | }
49 |
50 | canvas {
51 | position: absolute;
52 | width: 100%;
53 | height: 100%;
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/bundler/assets/jetpack-layout-grid/banner-1544x500.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Automattic/block-experiments/cf30ce88838160d6b583fae41e96337ddc7318e6/bundler/assets/jetpack-layout-grid/banner-1544x500.png
--------------------------------------------------------------------------------
/bundler/assets/jetpack-layout-grid/banner-772x250.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Automattic/block-experiments/cf30ce88838160d6b583fae41e96337ddc7318e6/bundler/assets/jetpack-layout-grid/banner-772x250.png
--------------------------------------------------------------------------------
/bundler/assets/jetpack-layout-grid/icon-128x128.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Automattic/block-experiments/cf30ce88838160d6b583fae41e96337ddc7318e6/bundler/assets/jetpack-layout-grid/icon-128x128.png
--------------------------------------------------------------------------------
/bundler/assets/jetpack-layout-grid/icon-256x256.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Automattic/block-experiments/cf30ce88838160d6b583fae41e96337ddc7318e6/bundler/assets/jetpack-layout-grid/icon-256x256.jpg
--------------------------------------------------------------------------------
/bundler/assets/jetpack-layout-grid/icon.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/bundler/assets/jetpack-layout-grid/screenshot-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Automattic/block-experiments/cf30ce88838160d6b583fae41e96337ddc7318e6/bundler/assets/jetpack-layout-grid/screenshot-1.png
--------------------------------------------------------------------------------
/bundler/assets/jetpack-layout-grid/screenshot-2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Automattic/block-experiments/cf30ce88838160d6b583fae41e96337ddc7318e6/bundler/assets/jetpack-layout-grid/screenshot-2.png
--------------------------------------------------------------------------------
/bundler/build/everything.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | rm -rf bundles
4 | mkdir -p bundles
5 |
6 | for file in ./bundler/bundles/*.json
7 | do
8 | yarn plugin $(basename $file)
9 | yarn bundle
10 | done
11 |
--------------------------------------------------------------------------------
/bundler/build/index.mjs:
--------------------------------------------------------------------------------
1 | import fs from 'fs';
2 | import path from 'path';
3 | import {
4 | storeFile,
5 | buildStyle,
6 | buildIndexJs,
7 | buildIndexPhp,
8 | copyBlocks,
9 | packageBundle,
10 | } from './build-tools.mjs';
11 |
12 | const commandLine = process.argv.slice( 2 );
13 | const configFile =
14 | commandLine.length > 0
15 | ? path.join(
16 | 'bundler',
17 | 'bundles',
18 | commandLine[ 0 ].replace( '.json', '' ) + '.json'
19 | )
20 | : null;
21 |
22 | if ( ! configFile || ! fs.existsSync( configFile ) ) {
23 | console.error( 'node build.js ' );
24 | process.exit( 1 );
25 | }
26 |
27 | const json = JSON.parse( fs.readFileSync( configFile, 'utf8' ) );
28 |
29 | const PLUGIN_DIR = `plugin/${ json.resource }`;
30 | const BUILD_DIR = 'build';
31 |
32 | // Check values exist before proceeding
33 | const required = [ 'blocks', 'version', 'name', 'description', 'resource' ];
34 | required.forEach( ( key ) => {
35 | if ( json[ key ] === undefined ) {
36 | console.error( 'Missing key in JSON file: ' + key );
37 | process.exit( 1 );
38 | }
39 | } );
40 |
41 | console.log( 'Building plugin with config: ' + configFile );
42 |
43 | // Build index.php
44 | const indexPhp = buildIndexPhp( json );
45 |
46 | // Make index.js
47 | const indexJs = buildIndexJs( json.blocks, json.labs ? json.labs : false );
48 |
49 | // Make style.scss
50 | const styleScss = buildStyle(
51 | json.blocks,
52 | 'Import front end styles for blocks',
53 | 'style'
54 | );
55 |
56 | // Make editor.scss
57 | const editorScss = buildStyle(
58 | json.blocks,
59 | 'Import editor styles for blocks',
60 | 'editor'
61 | );
62 |
63 | // Dump all files to disk
64 | storeFile( indexPhp, path.join( PLUGIN_DIR, 'index.php' ) );
65 | storeFile( indexJs, path.join( BUILD_DIR, 'src', 'index.js' ) );
66 | storeFile( styleScss, path.join( BUILD_DIR, 'style.scss' ) );
67 | storeFile( editorScss, path.join( BUILD_DIR, 'editor.scss' ) );
68 |
69 | // Copy block PHP files
70 | copyBlocks( json, PLUGIN_DIR );
71 |
72 | // And finally package it all up
73 | packageBundle( json );
74 |
--------------------------------------------------------------------------------
/bundler/bundles/bauhaus-centenary.json:
--------------------------------------------------------------------------------
1 | {
2 | "blocks": [ "bauhaus-centenary" ],
3 | "version": "1.0.3",
4 | "name": "Bauhaus Centenary",
5 | "description": "Celebrate the centenary of the design school",
6 | "resource": "a8c-bauhaus-centenary"
7 | }
8 |
--------------------------------------------------------------------------------
/bundler/bundles/event.json:
--------------------------------------------------------------------------------
1 | {
2 | "blocks": [ "event" ],
3 | "version": "1.0.2",
4 | "name": "Event",
5 | "description": "Show the time and location of an event",
6 | "resource": "a8c-event"
7 | }
8 |
--------------------------------------------------------------------------------
/bundler/bundles/layout-grid.json:
--------------------------------------------------------------------------------
1 | {
2 | "blocks": [
3 | "layout-grid"
4 | ],
5 | "version": "1.8.5",
6 | "name": "Layout Grid",
7 | "description": "Let any blocks align to a global grid",
8 | "resource": "jetpack-layout-grid",
9 | "locale": "layout-grid"
10 | }
11 |
--------------------------------------------------------------------------------
/bundler/bundles/model-viewer.json:
--------------------------------------------------------------------------------
1 | {
2 | "blocks": [ "model-viewer" ],
3 | "version": "1.0.0",
4 | "labs": true,
5 | "name": "A8C 3D Model Viewer",
6 | "description": "Show 3D models in an interactive viewer. Add files in .gltf or .glb formats.",
7 | "resource": "a8c-model-viewer"
8 | }
9 |
--------------------------------------------------------------------------------
/bundler/bundles/sketch.json:
--------------------------------------------------------------------------------
1 | {
2 | "blocks": [ "sketch" ],
3 | "version": "1.3.0",
4 | "name": "Sketch",
5 | "description": "Draw and write freely on a canvas. The block offers color selection, different brush sizes, and with its transparent background can be layered on top of any container block, like groups or covers.",
6 | "resource": "a8c-sketch"
7 | }
8 |
--------------------------------------------------------------------------------
/bundler/bundles/starscape.json:
--------------------------------------------------------------------------------
1 | {
2 | "blocks": [ "starscape" ],
3 | "version": "2.0.0",
4 | "name": "Starscape Block",
5 | "description": "Stars in motion",
6 | "resource": "a8c-starscape"
7 | }
8 |
--------------------------------------------------------------------------------
/bundler/bundles/waves.json:
--------------------------------------------------------------------------------
1 | {
2 | "blocks": [ "waves" ],
3 | "version": "1.0.3",
4 | "name": "Waves Block",
5 | "description": "Blocks can now be sinuous and soothing with the Waves Block.",
6 | "resource": "a8c-waves"
7 | }
8 |
--------------------------------------------------------------------------------
/bundler/resources/a8c-bauhaus-centenary/assets/banner-1544x500.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Automattic/block-experiments/cf30ce88838160d6b583fae41e96337ddc7318e6/bundler/resources/a8c-bauhaus-centenary/assets/banner-1544x500.png
--------------------------------------------------------------------------------
/bundler/resources/a8c-bauhaus-centenary/assets/banner-772x250.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Automattic/block-experiments/cf30ce88838160d6b583fae41e96337ddc7318e6/bundler/resources/a8c-bauhaus-centenary/assets/banner-772x250.png
--------------------------------------------------------------------------------
/bundler/resources/a8c-bauhaus-centenary/assets/icon-128x128.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Automattic/block-experiments/cf30ce88838160d6b583fae41e96337ddc7318e6/bundler/resources/a8c-bauhaus-centenary/assets/icon-128x128.png
--------------------------------------------------------------------------------
/bundler/resources/a8c-bauhaus-centenary/assets/icon-256x256.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Automattic/block-experiments/cf30ce88838160d6b583fae41e96337ddc7318e6/bundler/resources/a8c-bauhaus-centenary/assets/icon-256x256.png
--------------------------------------------------------------------------------
/bundler/resources/a8c-bauhaus-centenary/assets/icon.svg:
--------------------------------------------------------------------------------
1 |
21 |
--------------------------------------------------------------------------------
/bundler/resources/a8c-bauhaus-centenary/assets/screenshot-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Automattic/block-experiments/cf30ce88838160d6b583fae41e96337ddc7318e6/bundler/resources/a8c-bauhaus-centenary/assets/screenshot-1.png
--------------------------------------------------------------------------------
/bundler/resources/a8c-bauhaus-centenary/assets/screenshot-2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Automattic/block-experiments/cf30ce88838160d6b583fae41e96337ddc7318e6/bundler/resources/a8c-bauhaus-centenary/assets/screenshot-2.png
--------------------------------------------------------------------------------
/bundler/resources/a8c-bauhaus-centenary/assets/screenshot-3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Automattic/block-experiments/cf30ce88838160d6b583fae41e96337ddc7318e6/bundler/resources/a8c-bauhaus-centenary/assets/screenshot-3.png
--------------------------------------------------------------------------------
/bundler/resources/a8c-bauhaus-centenary/assets/screenshot-4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Automattic/block-experiments/cf30ce88838160d6b583fae41e96337ddc7318e6/bundler/resources/a8c-bauhaus-centenary/assets/screenshot-4.png
--------------------------------------------------------------------------------
/bundler/resources/a8c-bauhaus-centenary/block.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "a8c/bauhaus-centenary",
3 | "title": "Bauhaus Centenary",
4 | "description": "Celebrate the centenary of the design school.",
5 | "category": "widgets",
6 | "editorScript": "file:./index.js",
7 | "editorStyle": "file:./editor.css",
8 | "style": "file:./style.css"
9 | }
10 |
--------------------------------------------------------------------------------
/bundler/resources/a8c-bauhaus-centenary/readme.txt:
--------------------------------------------------------------------------------
1 | === Bauhaus Centenary Block ===
2 | Contributors: automattic, ajlende, pablohoneyhoney
3 | Stable tag: 1.0.3
4 | Tested up to: 6.0
5 | Requires at least: 5.3
6 | License: GPLv2 or later
7 | License URI: https://www.gnu.org/licenses/gpl-2.0.html
8 | Tags: block, blocks, bauhaus
9 |
10 | Celebrate the centenary of the design school
11 |
12 | == Description ==
13 |
14 | 2019 marks the 100th anniversary of the Bauhaus design school. Choose from three different styles—forms, year, and ribbon—each paying homage to Bauhaus design.
15 |
16 | ## Requirements
17 |
18 | As this is part of a series of block experiments, the latest version of the Gutenberg Plugin is required.
19 |
20 | ## Source and Support
21 |
22 | You can follow development, file an issue, suggest features, and view the source at the Github repo: https://github.com/Automattic/block-experiments
23 |
24 | == Screenshots ==
25 |
26 | 1. Bauhaus styles selector
27 | 2. Forms style
28 | 3. Year style
29 | 4. Ribbon style
30 |
31 | == Changelog ==
32 |
33 | = 1.0.3 - 1st July 2021 =
34 | * Improve compatibility with block directory
35 |
36 | = 1.0.2 - 6th March 2020 =
37 | * Fix button style in IE
38 |
39 | = 1.0.1 - 6th March 2020 =
40 | * Fix button styling and deprecation warnings in Gutenberg v6.7.0
41 | * Fix missing text domains for translations
42 |
43 | = 1.0.0 - 16th December 2019 =
44 | * Initial release
45 |
--------------------------------------------------------------------------------
/bundler/resources/a8c-event/assets/banner-1544x500.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Automattic/block-experiments/cf30ce88838160d6b583fae41e96337ddc7318e6/bundler/resources/a8c-event/assets/banner-1544x500.png
--------------------------------------------------------------------------------
/bundler/resources/a8c-event/assets/banner-772x250.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Automattic/block-experiments/cf30ce88838160d6b583fae41e96337ddc7318e6/bundler/resources/a8c-event/assets/banner-772x250.png
--------------------------------------------------------------------------------
/bundler/resources/a8c-event/assets/icon-128x128.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Automattic/block-experiments/cf30ce88838160d6b583fae41e96337ddc7318e6/bundler/resources/a8c-event/assets/icon-128x128.png
--------------------------------------------------------------------------------
/bundler/resources/a8c-event/assets/icon-256x256.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Automattic/block-experiments/cf30ce88838160d6b583fae41e96337ddc7318e6/bundler/resources/a8c-event/assets/icon-256x256.png
--------------------------------------------------------------------------------
/bundler/resources/a8c-event/assets/icon.svg:
--------------------------------------------------------------------------------
1 |
16 |
--------------------------------------------------------------------------------
/bundler/resources/a8c-event/assets/screenshot-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Automattic/block-experiments/cf30ce88838160d6b583fae41e96337ddc7318e6/bundler/resources/a8c-event/assets/screenshot-1.png
--------------------------------------------------------------------------------
/bundler/resources/a8c-event/assets/screenshot-2.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Automattic/block-experiments/cf30ce88838160d6b583fae41e96337ddc7318e6/bundler/resources/a8c-event/assets/screenshot-2.gif
--------------------------------------------------------------------------------
/bundler/resources/a8c-event/block.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "a8c/event",
3 | "title": "Event",
4 | "description": "Let everyone know about the events going on. Whether you're hosting or attending, the event block will feature your event including the time and location.",
5 | "category": "widgets",
6 | "editorScript": "file:./index.js",
7 | "editorStyle": "file:./editor.css",
8 | "style": "file:./style.css"
9 | }
10 |
--------------------------------------------------------------------------------
/bundler/resources/a8c-event/readme.txt:
--------------------------------------------------------------------------------
1 | === Event Block ===
2 | Contributors: automattic, ajlende, jasmussen
3 | Stable tag: 1.0.3
4 | Tested up to: 6.4
5 | Requires at least: 6.1
6 | License: GPLv2 or later
7 | License URI: https://www.gnu.org/licenses/gpl-2.0.html
8 | Tags: block, event, card
9 |
10 | Quickly create simple event cards and invitations
11 |
12 | == Description ==
13 |
14 | Let everyone know about the events going on. Whether you're hosting or attending, the event block will feature your event including the time and location.
15 |
16 | ## Source and Support
17 |
18 | This block is no longer under active development. Bug reports will be fixed, but no new features will be added.
19 |
20 | Full source is available at the Github repo: https://github.com/Automattic/block-experiments
21 |
22 | == Screenshots ==
23 |
24 | 1. Event Block
25 | 2. Customizing the Event Block
26 |
27 | == Changelog ==
28 |
29 | = 1.0.3 - 6th November 2023 =
30 | * Update to use stabilized APIs.
31 | * Fix console warnings in the editor.
32 |
33 | = 1.0.2 - 22nd July 2021 =
34 | * Improve compatibility with block directory
35 | * Fix center aligned styling
36 |
37 | = 1.0.1 - 3rd August 2020 =
38 | * Fix 'Event Description' placeholder internationalization
39 |
40 | = 1.0.0 - 24th April 2020 =
41 | * Initial release
42 |
--------------------------------------------------------------------------------
/bundler/resources/a8c-model-viewer/block.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "a8c/model-viewer",
3 | "title": "3D Model",
4 | "description": "Show 3D models in an interactive viewer. Add files in .gltf or .glb formats.",
5 | "category": "widgets",
6 | "editorScript": "file:./index.js",
7 | "editorStyle": "file:./editor.css",
8 | "style": "file:./style.css"
9 | }
10 |
--------------------------------------------------------------------------------
/bundler/resources/a8c-model-viewer/readme.txt:
--------------------------------------------------------------------------------
1 | === A8C 3D Model Viewer Block ===
2 | Contributors: automattic
3 | Stable tag: 1.0.0
4 | Tested up to: 6.0
5 | Requires at least: 6.0
6 | License: GPLv2 or later
7 | License URI: https://www.gnu.org/licenses/gpl-2.0.html
8 | Tags: block, blocks, model, 3d
9 |
10 | View 3D models
11 |
12 | == Description ==
13 |
14 | View 3D models
15 |
16 | ## Requirements
17 |
18 | As this is part of a series of block experiments, the latest version of the Gutenberg Plugin is required.
19 |
20 | ## Source and Support
21 |
22 | You can follow development, file an issue, suggest features, and view the source at the Github repo: https://github.com/Automattic/block-experiments
23 |
24 | == Screenshots ==
25 |
26 | == Changelog ==
27 |
28 | = 1.0.0 - 26th April 2022 =
29 | * Initial release
30 |
--------------------------------------------------------------------------------
/bundler/resources/a8c-sketch/assets/banner-1544x500.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Automattic/block-experiments/cf30ce88838160d6b583fae41e96337ddc7318e6/bundler/resources/a8c-sketch/assets/banner-1544x500.png
--------------------------------------------------------------------------------
/bundler/resources/a8c-sketch/assets/banner-772x250.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Automattic/block-experiments/cf30ce88838160d6b583fae41e96337ddc7318e6/bundler/resources/a8c-sketch/assets/banner-772x250.png
--------------------------------------------------------------------------------
/bundler/resources/a8c-sketch/assets/icon-128x128.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Automattic/block-experiments/cf30ce88838160d6b583fae41e96337ddc7318e6/bundler/resources/a8c-sketch/assets/icon-128x128.png
--------------------------------------------------------------------------------
/bundler/resources/a8c-sketch/assets/icon-256x256.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Automattic/block-experiments/cf30ce88838160d6b583fae41e96337ddc7318e6/bundler/resources/a8c-sketch/assets/icon-256x256.png
--------------------------------------------------------------------------------
/bundler/resources/a8c-sketch/assets/icon.svg:
--------------------------------------------------------------------------------
1 |
5 |
--------------------------------------------------------------------------------
/bundler/resources/a8c-sketch/assets/screenshot-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Automattic/block-experiments/cf30ce88838160d6b583fae41e96337ddc7318e6/bundler/resources/a8c-sketch/assets/screenshot-1.png
--------------------------------------------------------------------------------
/bundler/resources/a8c-sketch/assets/screenshot-2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Automattic/block-experiments/cf30ce88838160d6b583fae41e96337ddc7318e6/bundler/resources/a8c-sketch/assets/screenshot-2.png
--------------------------------------------------------------------------------
/bundler/resources/a8c-sketch/block.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "a8c/sketch",
3 | "title": "Sketch",
4 | "description": "Draw and write freely on a canvas. The block offers color selection, different brush sizes, and with its transparent background can be layered on top of any container block, like groups or covers.",
5 | "category": "widgets",
6 | "editorScript": "file:./index.js",
7 | "editorStyle": "file:./editor.css",
8 | "style": "file:./style.css"
9 | }
10 |
--------------------------------------------------------------------------------
/bundler/resources/a8c-sketch/readme.txt:
--------------------------------------------------------------------------------
1 | === Sketch Block ===
2 | Contributors: automattic, matveb, oskosk, pablohoneyhoney
3 | Stable tag: 1.3.0
4 | Tested up to: 6.1.1
5 | Requires at least: 5.9
6 | License: GPLv2 or later
7 | License URI: https://www.gnu.org/licenses/gpl-2.0.html
8 | Tags: block, blocks, sketch, freehand, drawing
9 |
10 | Sketch and draw freely on a canvas with brush strokes that feel natural.
11 |
12 | == Description ==
13 |
14 | Sketch and draw freely on a canvas with brush strokes that feel natural. Pick among three different brush sizes and the color palette of the site. The block has a transparent background so it can be layered on top of any container block, like groups or background images to achieve different effects.
15 |
16 | ## Credits
17 |
18 | The block is powered by the awesome perfect-freehand library.
19 |
20 | ## Source and Support
21 |
22 | You can follow development, file an issue, suggest features, and view the source at the Github repo: https://github.com/Automattic/block-experiments
23 |
24 | == Screenshots ==
25 |
26 | 1. Sketch Block by Automattic.
27 | 2. Draw and write freely on a canvas.
28 |
29 | == Changelog ==
30 |
31 | = 1.3.0 - 3nd March 2023 =
32 | * Added default and custom color palettes to Color control.
33 | * Fixed selected color marked in the Color control
34 |
35 | = 1.2.0 - 2nd March 2023 =
36 | * Updated the Clear control to not reset the height of the sketch.
37 | * Removed minimum height restriction for resizer.
38 | * Fixed full width block alignment support.
39 | * Updated Upload control label to "Upload as image".
40 | * Updated alternative text control copy.
41 | * Updated dependency on perfect-freehand to its version 1.2.0.
42 |
43 | = 1.1.0 - 2nd October 2022 =
44 | * Updated to reflect compatibility with WordPess 6.0.
45 | * Added toolbar control for uploading an image to the media library generated from the sketch drawing.
46 |
47 | = 1.0.10 - 14th July 2021 =
48 | * Prevent default pointer behavior on move, which could cause unintended window scrolling with some devices and browsers.
49 |
50 | = 1.0.9 - 8th July 2021 =
51 | * Improved accessibility by using title and role on the SVG element
52 |
53 | = 1.0.8 - 2nd July 2021 =
54 | * Address crashing issues when the underlying library detects duplicate strokes
55 |
56 | = 1.0.7 - 1st July 2021 =
57 | * Add example for the block inserter preview
58 | * Categorize the block under widgets
59 |
60 | = 1.0.6 - 1st July 2021 =
61 | * Improve compatibility with block directory
62 |
63 | = 1.0.0 - 1st July 2021 =
64 | * Initial release
65 |
66 |
--------------------------------------------------------------------------------
/bundler/resources/a8c-starscape/assets/banner-1544x500.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Automattic/block-experiments/cf30ce88838160d6b583fae41e96337ddc7318e6/bundler/resources/a8c-starscape/assets/banner-1544x500.png
--------------------------------------------------------------------------------
/bundler/resources/a8c-starscape/assets/banner-772x250.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Automattic/block-experiments/cf30ce88838160d6b583fae41e96337ddc7318e6/bundler/resources/a8c-starscape/assets/banner-772x250.png
--------------------------------------------------------------------------------
/bundler/resources/a8c-starscape/assets/icon-128x128.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Automattic/block-experiments/cf30ce88838160d6b583fae41e96337ddc7318e6/bundler/resources/a8c-starscape/assets/icon-128x128.png
--------------------------------------------------------------------------------
/bundler/resources/a8c-starscape/assets/icon-256x256.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Automattic/block-experiments/cf30ce88838160d6b583fae41e96337ddc7318e6/bundler/resources/a8c-starscape/assets/icon-256x256.png
--------------------------------------------------------------------------------
/bundler/resources/a8c-starscape/assets/icon.svg:
--------------------------------------------------------------------------------
1 |
14 |
--------------------------------------------------------------------------------
/bundler/resources/a8c-starscape/assets/screenshot-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Automattic/block-experiments/cf30ce88838160d6b583fae41e96337ddc7318e6/bundler/resources/a8c-starscape/assets/screenshot-1.png
--------------------------------------------------------------------------------
/bundler/resources/a8c-starscape/assets/screenshot-2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Automattic/block-experiments/cf30ce88838160d6b583fae41e96337ddc7318e6/bundler/resources/a8c-starscape/assets/screenshot-2.png
--------------------------------------------------------------------------------
/bundler/resources/a8c-starscape/assets/screenshot-3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Automattic/block-experiments/cf30ce88838160d6b583fae41e96337ddc7318e6/bundler/resources/a8c-starscape/assets/screenshot-3.png
--------------------------------------------------------------------------------
/bundler/resources/a8c-starscape/assets/screenshot-4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Automattic/block-experiments/cf30ce88838160d6b583fae41e96337ddc7318e6/bundler/resources/a8c-starscape/assets/screenshot-4.png
--------------------------------------------------------------------------------
/bundler/resources/a8c-starscape/block.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "a8c/starscape",
3 | "title": "Starscape",
4 | "description": "Everything was made of collapsing stars, we are all made of star stuff. Now we also can create content in WordPress with stars in motion.",
5 | "category": "widgets",
6 | "editorScript": "file:./index.js",
7 | "editorStyle": "file:./editor.css",
8 | "style": "file:./style.css"
9 | }
10 |
--------------------------------------------------------------------------------
/bundler/resources/a8c-starscape/readme.txt:
--------------------------------------------------------------------------------
1 | === Starscape Block ===
2 | Contributors: automattic, ajlende, pablohoneyhoney
3 | Stable tag: 2.0.0
4 | Tested up to: 6.3
5 | Requires at least: 6.3
6 | License: GPLv2 or later
7 | License URI: https://www.gnu.org/licenses/gpl-2.0.html
8 | Tags: block, blocks
9 |
10 | Stars in motion
11 |
12 | == Description ==
13 |
14 | Everything was made of collapsing stars, we are all made of star stuff. Now we also can create content in WordPress with stars in motion.
15 |
16 | ## Requirements
17 |
18 | As this is part of a series of block experiments, the latest version of the Gutenberg Plugin is required.
19 |
20 | ## Source and Support
21 |
22 | You can follow development, file an issue, suggest features, and view the source at the Github repo: https://github.com/Automattic/block-experiments
23 |
24 | == Screenshots ==
25 |
26 | 1. Starscape Block by Automattic.
27 | 2. Create content with stars in motion.
28 | 3. Choose from a number of sky backgrounds.
29 | 4. Control the quantity of stars and speed of rotation.
30 |
31 | == Changelog ==
32 |
33 | = 2.0.0 - 29th July 2023 =
34 | * Add inner blocks support
35 | * Add star color support
36 | * Add star intensity support
37 | * Add link color support
38 | * Add theme gradient background support
39 | * Add spacing support
40 | * Add minimum block height support
41 | * Add block tag name support
42 | * Add template lock and allowed block support for theme developers
43 | * Modernize block implementation
44 | * Performance improvements
45 |
46 | = 1.0.3 - 1st July 2021 =
47 | * Improve compatibility with block directory
48 |
49 | = 1.0.2 - 6th March 2020 =
50 | * Fix missing text domains for translations
51 |
52 | = 1.0.1 - 24th January 2020 =
53 | * Fix custom gradients for Gutenberg 7.3.0
54 |
55 | = 1.0.0 - 23rd January 2020 =
56 | * Initial release
57 |
--------------------------------------------------------------------------------
/bundler/resources/a8c-waves/assets/banner-1544-500.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Automattic/block-experiments/cf30ce88838160d6b583fae41e96337ddc7318e6/bundler/resources/a8c-waves/assets/banner-1544-500.png
--------------------------------------------------------------------------------
/bundler/resources/a8c-waves/assets/banner-1544x500.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Automattic/block-experiments/cf30ce88838160d6b583fae41e96337ddc7318e6/bundler/resources/a8c-waves/assets/banner-1544x500.png
--------------------------------------------------------------------------------
/bundler/resources/a8c-waves/assets/banner-772x250.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Automattic/block-experiments/cf30ce88838160d6b583fae41e96337ddc7318e6/bundler/resources/a8c-waves/assets/banner-772x250.png
--------------------------------------------------------------------------------
/bundler/resources/a8c-waves/assets/icon-128x128.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Automattic/block-experiments/cf30ce88838160d6b583fae41e96337ddc7318e6/bundler/resources/a8c-waves/assets/icon-128x128.png
--------------------------------------------------------------------------------
/bundler/resources/a8c-waves/assets/icon-256x256.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Automattic/block-experiments/cf30ce88838160d6b583fae41e96337ddc7318e6/bundler/resources/a8c-waves/assets/icon-256x256.png
--------------------------------------------------------------------------------
/bundler/resources/a8c-waves/assets/icon.svg:
--------------------------------------------------------------------------------
1 |
14 |
--------------------------------------------------------------------------------
/bundler/resources/a8c-waves/assets/screenshot-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Automattic/block-experiments/cf30ce88838160d6b583fae41e96337ddc7318e6/bundler/resources/a8c-waves/assets/screenshot-1.png
--------------------------------------------------------------------------------
/bundler/resources/a8c-waves/assets/screenshot-2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Automattic/block-experiments/cf30ce88838160d6b583fae41e96337ddc7318e6/bundler/resources/a8c-waves/assets/screenshot-2.png
--------------------------------------------------------------------------------
/bundler/resources/a8c-waves/assets/screenshot-3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Automattic/block-experiments/cf30ce88838160d6b583fae41e96337ddc7318e6/bundler/resources/a8c-waves/assets/screenshot-3.png
--------------------------------------------------------------------------------
/bundler/resources/a8c-waves/assets/screenshot-4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Automattic/block-experiments/cf30ce88838160d6b583fae41e96337ddc7318e6/bundler/resources/a8c-waves/assets/screenshot-4.png
--------------------------------------------------------------------------------
/bundler/resources/a8c-waves/assets/screenshot-5.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Automattic/block-experiments/cf30ce88838160d6b583fae41e96337ddc7318e6/bundler/resources/a8c-waves/assets/screenshot-5.gif
--------------------------------------------------------------------------------
/bundler/resources/a8c-waves/block.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "a8c/waves",
3 | "title": "Waves",
4 | "description": "Blocks can now be sinuous and soothing with the Waves Block.",
5 | "category": "widgets",
6 | "editorScript": "file:./index.js",
7 | "editorStyle": "file:./editor.css",
8 | "script": "file:./blocks/waves.js",
9 | "style": "file:./style.css"
10 | }
11 |
--------------------------------------------------------------------------------
/bundler/resources/a8c-waves/readme.txt:
--------------------------------------------------------------------------------
1 | === Waves Block ===
2 | Contributors: automattic, ajlende, pablohoneyhoney
3 | Stable tag: 1.0.3
4 | Tested up to: 6.0
5 | Requires at least: 5.4
6 | License: GPLv2 or later
7 | License URI: https://www.gnu.org/licenses/gpl-2.0.html
8 | Tags: block, blocks, waves
9 |
10 | Gradients in motion.
11 |
12 | == Description ==
13 |
14 | Blocks can now be sinuous and soothing with the Waves Block.
15 |
16 | ## Requirements
17 |
18 | As this is part of a series of block experiments, the latest version of the Gutenberg Plugin is required.
19 |
20 | ## Source and Support
21 |
22 | You can follow development, file an issue, suggest features, and view the source at the Github repo: https://github.com/Automattic/block-experiments
23 |
24 | == Screenshots ==
25 |
26 | 1. Waves Block by Automattic.
27 | 2. Gradients in motion.
28 | 3. Use the colors from your theme.
29 | 4. Adjust the complexity of the waves.
30 | 5. Enjoy the soothing animation.
31 |
32 | == Changelog ==
33 |
34 | = 1.0.3 - 22nd July 2021 =
35 | * Use `should_load_separate_core_block_assets` for loading assets
36 | * Load script translations
37 |
38 | = 1.0.2 - 1st July 2021 =
39 | * Improve compatibility with block directory
40 |
41 | = 1.0.1 - 3rd August 2020 =
42 | * Fix error when double selecting a color
43 | * Minor performance improvements
44 |
45 | = 1.0.0 - 22nd May 2020 =
46 | * Initial release
47 |
--------------------------------------------------------------------------------
/bundler/resources/jetpack-layout-grid/block.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "jetpack/layout-grid",
3 | "title": "Layout Grid",
4 | "description": "A Gutenberg container block to let you align items consistently across a global grid.",
5 | "category": "design",
6 | "editorScript": "file:./index.js",
7 | "editorStyle": "file:./editor.css",
8 | "style": "file:./style.css"
9 | }
10 |
--------------------------------------------------------------------------------
/bundler/template/index.js:
--------------------------------------------------------------------------------
1 | /**
2 | * External dependencies
3 | */
4 |
5 | /**
6 | * Load blocks
7 | */
8 |
--------------------------------------------------------------------------------
/bundler/template/index.php:
--------------------------------------------------------------------------------
1 | /config/jest-before.js' ],
8 | transformIgnorePatterns: [ 'node_modules/(?!(@wordpress|parsel-js)/)' ],
9 | };
10 |
--------------------------------------------------------------------------------
/lib/svg-dom-to-blob/index.js:
--------------------------------------------------------------------------------
1 |
2 | export default function svgDomToBlob( svgNode, fn ) {
3 | if ( ! svgNode ) {
4 | return;
5 | }
6 |
7 | // Get SVG Blob.
8 | svgNode.setAttribute("viewBox", `0 0 ${svgNode.getBoundingClientRect().width} ${svgNode.getBoundingClientRect().height}`);
9 | const svgString = new XMLSerializer().serializeToString( svgNode );
10 | const DOMURL = self.URL || self.webkitURL || self;
11 | const svgBlob = new Blob( [ svgString ], { type: "image/svg+xml;charset=utf-8" } );
12 |
13 | // Start to convert SVG string to base64.
14 | const canvas = document.createElement( 'canvas' );
15 | const ctx = canvas.getContext( "2d" );
16 | ctx.canvas.width = svgNode.width.baseVal.value;
17 | ctx.canvas.height = svgNode.height.baseVal.value;
18 |
19 | // Create an image based on the SVG string.
20 | const img = new Image();
21 | const url = DOMURL.createObjectURL( svgBlob );
22 | img.onload = function() {
23 | // Draw the image on the canvas.
24 | ctx.drawImage( img, 0, 0 );
25 | DOMURL.revokeObjectURL( canvas.toDataURL( 'image/png' ) );
26 | canvas.toBlob( fn );
27 | };
28 | img.src = url;
29 | };
30 |
--------------------------------------------------------------------------------
/lib/upload-image/index.js:
--------------------------------------------------------------------------------
1 | /**
2 | * WordPress dependencies
3 | */
4 | import { store as blockEditorStore } from '@wordpress/block-editor';
5 | import { select } from '@wordpress/data';
6 | import { __ } from '@wordpress/i18n';
7 |
8 | export default function uploadBlobToMediaLibrary(
9 | imageBlob,
10 | {
11 | title = __( 'Image generated via Sketch block', 'a8c-sketch' ),
12 | caption = '',
13 | description = '',
14 | },
15 | fn
16 | ) {
17 | const { getSettings } = select( blockEditorStore );
18 | const mediaUpload = getSettings().mediaUpload;
19 |
20 | if ( ! imageBlob ) {
21 | return fn( __( 'No valid image', 'a8c-sketch' ) );
22 | }
23 |
24 | const reader = new window.FileReader();
25 | reader.readAsDataURL( imageBlob );
26 | reader.onloadend = () => {
27 | mediaUpload( {
28 | additionalData: {
29 | title,
30 | caption,
31 | description,
32 | },
33 | allowedTypes: [ 'image' ],
34 | filesList: [ imageBlob ],
35 | onFileChange: ( images ) => {
36 | if ( ! images?.length ) {
37 | return;
38 | }
39 |
40 | const image = images[ 0 ];
41 | if ( ! image?.id ) {
42 | return;
43 | }
44 | fn( null, image );
45 | },
46 | onError: fn,
47 | } );
48 | };
49 | }
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "block-experiments",
3 | "version": "1.0.0",
4 | "description": "A monorepo for blocks",
5 | "main": "src/index.js",
6 | "author": "Automattic",
7 | "license": "GPL-2.0-or-later",
8 | "scripts": {
9 | "env": "wp-env",
10 | "start": "yarn build-css & wp-scripts start & node-sass --watch editor.scss -o build & node-sass --watch style.scss -o build",
11 | "build": "wp-scripts build && yarn build-css",
12 | "build-css": "node-sass ./editor.scss -o build | postcss build/editor.css -u autoprefixer -b 'last 2 versions' -r --no-map && node-sass ./style.scss -o build | postcss build/style.css -u autoprefixer -b 'last 2 versions' -r --no-map",
13 | "plugin": "yarn clean && node ./bundler/build/index.mjs",
14 | "everything": "./bundler/build/everything.sh",
15 | "bundle": "./build/bundle.sh",
16 | "all": "node ./bundler/all.js",
17 | "clean": "rm -rf ./build ./plugin",
18 | "lint": "npm run lint-js & npm run lint-php",
19 | "lint-js": "wp-scripts lint-js blocks",
20 | "lint-php": "composer run lint",
21 | "blockbook:start": "npm run build-css && blockbook start",
22 | "blockbook:build": "npm run build-css && blockbook build"
23 | },
24 | "devDependencies": {
25 | "@babel/core": "^7.26.9",
26 | "@babel/plugin-proposal-class-properties": "^7.18.6",
27 | "@babel/plugin-transform-modules-commonjs": "^7.26.3",
28 | "@babel/preset-env": "^7.26.9",
29 | "@testing-library/dom": "^10.4.0",
30 | "@testing-library/jest-dom": "^6.6.3",
31 | "@testing-library/react": "^16.2.0",
32 | "@types/jest": "^29.5.14",
33 | "@types/mocha": "^10.0.10",
34 | "@wordpress/babel-preset-default": "^8.20.0",
35 | "@wordpress/block-library": "^9.20.0",
36 | "@wordpress/env": "^10.18.0",
37 | "@wordpress/icons": "^10.18.0",
38 | "@wordpress/jest-preset-default": "^12.18.0",
39 | "@wordpress/prettier-config": "^4.18.0",
40 | "@wordpress/scripts": "^30.11.0",
41 | "autoprefixer": "^10.4.20",
42 | "babel-plugin-inline-json-import": "^0.3.2",
43 | "blockbook-cli": "^0.7.1",
44 | "eslint": "^9.21.0",
45 | "eslint-config-wpcalypso": "^6.1.0",
46 | "eslint-plugin-eslint-comments": "^3.2.0",
47 | "eslint-plugin-import": "^2.31.0",
48 | "eslint-plugin-jest": "^28.11.0",
49 | "eslint-plugin-jsx-a11y": "^6.10.2",
50 | "eslint-plugin-react": "^7.37.4",
51 | "eslint-plugin-wpcalypso": "^8.0.0",
52 | "fs-extra": "^11.3.0",
53 | "jest-image-snapshot": "^6.4.0",
54 | "jest-puppeteer": "^11.0.0",
55 | "jest-transform-css": "^6.0.2",
56 | "jest-transform-file": "^1.1.1",
57 | "jsdom-screenshot": "^4.0.0",
58 | "node-sass": "^9.0.0",
59 | "postcss": "^8.5.3",
60 | "postcss-cli": "^11.0.0",
61 | "puppeteer": "^24.3.0",
62 | "replace-in-file": "^8.3.0",
63 | "stringcase": "^4.3.1"
64 | },
65 | "dependencies": {
66 | "@google/model-viewer": "^4.0.0",
67 | "@wordpress/block-editor": "^14.13.0",
68 | "@wordpress/blocks": "^14.7.0",
69 | "classnames": "^2.5.1",
70 | "colord": "^2.9.3",
71 | "fast-average-color": "^9.4.0",
72 | "perfect-freehand": "1.2.2",
73 | "tinycolor2": "^1.6.0"
74 | }
75 | }
76 |
--------------------------------------------------------------------------------
/phpcs.xml.dist:
--------------------------------------------------------------------------------
1 |
2 |
3 | Sniffs for WordPress plugins, with minor modifications for Gutenberg
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
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 | ./index.php
52 | ./rest-api.php
53 | ./blocks
54 |
55 |
56 |
57 |
58 |
--------------------------------------------------------------------------------
/src/block-icons.js:
--------------------------------------------------------------------------------
1 | /**
2 | * WordPress depedencies
3 | */
4 |
5 | import { Path, SVG } from '@wordpress/components';
6 |
7 | export const BlockIcon = () => (
8 |
11 | );
12 |
13 | export const TinkerBlocksLogo = () => (
14 |
17 | );
18 |
--------------------------------------------------------------------------------
/src/index.js:
--------------------------------------------------------------------------------
1 | /**
2 | * WordPress dependencies
3 | */
4 |
5 | import { getCategories, setCategories } from '@wordpress/blocks';
6 |
7 | /**
8 | * Internal dependencies
9 | */
10 |
11 | import { TinkerBlocksLogo } from './block-icons';
12 |
13 | setCategories( [
14 | {
15 | slug: 'block-experiments',
16 | title: 'Block Experiments',
17 | icon: ,
18 | },
19 | ...getCategories(),
20 | ] );
21 |
22 | /**
23 | * Load all our blocks
24 | */
25 | import * as bauhausCentenaryBlock from '../blocks/bauhaus-centenary/src';
26 | import * as eventBlock from '../blocks/event/src';
27 | import * as layoutGridBlock from '../blocks/layout-grid/src';
28 | import * as sketchBlock from '../blocks/sketch/src';
29 | import * as starscapeBlock from '../blocks/starscape/src';
30 | import * as wavesBlock from '../blocks/waves/src';
31 | import * as bookBlock from '../blocks/book/src';
32 | import * as modelViewerBlock from '../blocks/model-viewer/src';
33 |
34 | // Instantiate the blocks, adding them to our block category
35 | bauhausCentenaryBlock.registerBlock();
36 | eventBlock.registerBlock();
37 | layoutGridBlock.registerBlock();
38 | sketchBlock.registerBlock();
39 | starscapeBlock.registerBlock();
40 | wavesBlock.registerBlock();
41 | bookBlock.registerBlock();
42 | modelViewerBlock.registerBlock();
43 |
--------------------------------------------------------------------------------
/style.scss:
--------------------------------------------------------------------------------
1 | /* Import front end styles for blocks */
2 | @import './blocks/bauhaus-centenary/style.scss';
3 | @import './blocks/event/style.scss';
4 | @import './blocks/layout-grid/style.scss';
5 | @import './blocks/sketch/style.scss';
6 | @import './blocks/starscape/style.scss';
7 | @import './blocks/waves/style.scss';
8 | @import './blocks/book/style.scss';
9 | @import './blocks/model-viewer/style.scss';
10 |
--------------------------------------------------------------------------------
/webpack.config.js:
--------------------------------------------------------------------------------
1 | /**
2 | * External dependencies
3 | */
4 | const { CleanWebpackPlugin } = require( 'clean-webpack-plugin' );
5 |
6 | /**
7 | * WordPress dependencies
8 | */
9 | const defaultConfig = require( '@wordpress/scripts/config/webpack.config' );
10 |
11 | module.exports = {
12 | ...defaultConfig,
13 |
14 | // Disable the clean plugin as it kills our CSS
15 | plugins: defaultConfig.plugins.filter(
16 | ( plugin ) => ! ( plugin instanceof CleanWebpackPlugin )
17 | ),
18 | };
19 |
--------------------------------------------------------------------------------