Skip to content

Commit

Permalink
Merge branch 'master' into typescript-support-in-core
Browse files Browse the repository at this point in the history
* master:
  Add a marker in the props for `RenderBlocks` in case that we have a container (#4932)
  Update the 'version addded' information regarding the Grid block in docs
  Release 17.0.0-alpha.16
  Grid block in core + primitive Container block (#3180)
  Release 17.0.0-alpha.15
  Fix changelog message and docs for #4848 (#4927)
  Add Storybook story for useDetectClickOutside hook with several demos (#4923)
  Fix the experimental add new block button position, compensate the ic… (#4924)
  Use proper heading tag (depending on the headline) in default listing template (#4848)
  Fix Annontools storyBook (#4921)
  • Loading branch information
sneridagh committed Jun 30, 2023
2 parents 5df675e + a3b066b commit df15ce4
Show file tree
Hide file tree
Showing 68 changed files with 2,739 additions and 63 deletions.
25 changes: 25 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,31 @@

<!-- towncrier release notes start -->

## 17.0.0-alpha.16 (2023-06-28)

### Feature

- New block: Grid - A container of blocks, arranged in horizontal direction. @sneridagh
New primitive: Container - A primitive to build blocks containing other blocks. @sneridagh [#3180](https://github.com/plone/volto/issues/3180)


## 17.0.0-alpha.15 (2023-06-28)

### Breaking

- Use proper heading tag (depending on the headline) in default listing template @sneridagh [#4848](https://github.com/plone/volto/issues/4848)

### Bugfix

- Remove anonymous function calls. Remove default exports from. @sneridagh [#4917](https://github.com/plone/volto/issues/4917)
- Fix Annontools StoryBook @sneridagh [#4921](https://github.com/plone/volto/issues/4921)
- Fix the experimental add new block button position, compensate the icon width to center it correctly @sneridagh [#4924](https://github.com/plone/volto/issues/4924)

### Internal

- Add Storybook story for useDetectClickOutside hook with several demos @sneridagh [#4923](https://github.com/plone/volto/issues/4923)


## 17.0.0-alpha.14 (2023-06-23)

### Feature
Expand Down
18 changes: 18 additions & 0 deletions cypress/support/commands.js
Original file line number Diff line number Diff line change
Expand Up @@ -705,6 +705,20 @@ Cypress.Commands.add('getSlate', (createNewSlate = false) => {
return slate;
});

Cypress.Commands.add('getSlateSelector', (selector = SLATE_SELECTOR) => {
let slate;
cy.getIfExists(
selector,
() => {
slate = cy.get(selector).last();
},
() => {
slate = cy.get(selector, { timeout: 10000 }).last();
},
);
return slate;
});

Cypress.Commands.add('getSlateTitle', () => {
return cy.get(SLATE_TITLE_SELECTOR, {
timeout: 10000,
Expand Down Expand Up @@ -763,6 +777,10 @@ Cypress.Commands.add('getSlateEditorAndType', (type) => {
cy.getSlate().focus().click().type(type);
});

Cypress.Commands.add('getSlateEditorSelectorAndType', (selector, type) => {
cy.getSlateSelector(selector).focus().click().type(type);
});

Cypress.Commands.add('setSlateCursor', (subject, query, endQuery) => {
cy.get('.slate-editor.selected [contenteditable=true]')
.focus()
Expand Down
114 changes: 114 additions & 0 deletions cypress/tests/core/blocks/blocks-grid.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
context('Blocks Acceptance Tests', () => {
describe('Text Block Tests', () => {
beforeEach(() => {
cy.intercept('PATCH', '/**/document').as('edit');
cy.intercept('GET', '/**/document').as('content');
cy.intercept('GET', '/**/Document').as('schema');
// given a logged in editor and a page in edit mode
cy.visit('/');
cy.autologin();
cy.createContent({
contentType: 'Document',
contentId: 'document',
contentTitle: 'Test document',
});
cy.createContent({
contentType: 'Document',
contentId: 'my-page',
contentTitle: 'My Page',
path: '/document',
});
// Adding Image for Grid Image
cy.createContent({
contentType: 'Image',
contentId: 'my-image',
contentTitle: 'My Image',
path: '/document',
});
cy.visit('/document');
cy.navigate('/document/edit');
cy.wait('@schema');
});

it('As editor I can add a Grid', function () {
cy.getSlate().click();
cy.addNewBlock('grid');

cy.findByText('2 columns').click();

cy.get('button[aria-label="Add block in position 0"]').click();
cy.get('.blocks-chooser .mostUsed .button.image').click();
cy.get('.block.image .toolbar-inner .buttons:first-child').click();
cy.get('[aria-label="Select My Image"]').dblclick();
cy.findByText('my-image');

cy.get('button[aria-label="Add block in position 1"]').click();
cy.get('.blocks-chooser [aria-label="Unfold Text blocks"]').click();
cy.get('.blocks-chooser .text .button.slate').click();
cy.getSlateEditorSelectorAndType(
'.block.gridBlock.selected .slate-editor [contenteditable=true]',
'Colorless green ideas sleep furiously.',
);

cy.get('#toolbar-save').click();
cy.wait('@edit');
cy.wait('@content');

cy.findByText('Colorless green ideas sleep furiously.');

cy.navigate('/document/edit');
cy.wait('@schema');
cy.get('.block.inner.gridBlock').click();
cy.get('.block.inner.gridBlock .block-editor-slate').click();
cy.get('.block.inner.gridBlock [aria-label="Reset element 1"]').click();
cy.get('.block.inner.gridBlock [aria-label="Remove element 1"]').click();
cy.get(
'.block.inner.gridBlock .toolbar [aria-label="Add element to container"]',
).click();
cy.get('button[aria-label="Add block in position 1"]').click();
cy.get('.blocks-chooser .mostUsed .button.teaser').click();
cy.get(
'.objectbrowser-field[aria-labelledby="fieldset-default-field-label-href"] button[aria-label="Open object browser"]',
).click();
cy.get('[aria-label="Select My Page"]').dblclick();
cy.get('#toolbar-save').click();
cy.wait('@edit');
cy.wait('@content');

cy.get('.block.gridBlock').findByText('My Page');
});

it('As editor I can add a Grid with slate block on it', function () {
cy.getSlate().click();
cy.addNewBlock('grid');

cy.findByText('2 columns').click();

cy.get('button[aria-label="Add block in position 1"]').click();
cy.get('.blocks-chooser [aria-label="Unfold Text blocks"]').click();
cy.get('.blocks-chooser .text .button.slate').click();
cy.scrollTo('top');

cy.getSlateEditorSelectorAndType(
'.block.gridBlock.selected .slate-editor [contenteditable=true]',
'Colorless green ideas sleep furiously.',
).setSelection('furiously');
cy.scrollTo('top');
cy.wait(1000);
cy.scrollTo('top');
cy.get(
'.slate-inline-toolbar .ui.buttons .button-wrapper a[title="Add link"]',
).click();
cy.get('.link-form-container input').type('https://google.com{enter}');

cy.get('#toolbar-save').click();

cy.get('.block.gridBlock.two p').contains(
'Colorless green ideas sleep furiously.',
);
cy.get('.block.gridBlock.two p a')
.should('have.attr', 'href')
.and('include', 'https://google.com');
});
});
});
4 changes: 2 additions & 2 deletions cypress/tests/core/blocks/blocks-listing.js
Original file line number Diff line number Diff line change
Expand Up @@ -874,7 +874,7 @@ describe('Listing Block Tests', () => {
cy.get('#field-b_size-4-querystring').click().type('2');
cy.get('.ui.pagination.menu a[value="2"]').first().click();

cy.get('.listing-item h4').first().contains('My Folder 3');
cy.get('.listing-item h3').first().contains('My Folder 3');
});

it('Navigates in listing block pagination and url clears on logo click', () => {
Expand Down Expand Up @@ -1037,7 +1037,7 @@ describe('Listing Block Tests', () => {
cy.get('#field-b_size-4-querystring').click().type('2');
cy.get('.ui.pagination.menu a[value="2"]').first().click();

cy.get('.listing-item h4').first().contains('My Folder 3');
cy.get('.listing-item h3').first().contains('My Folder 3');
cy.get('#toolbar-save').click();
cy.wait('@save');
cy.wait('@content');
Expand Down
83 changes: 83 additions & 0 deletions docs/source/blocks/core/container.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
---
myst:
html_meta:
"description": "Volto container description and developer notes"
"property=og:description": "Volto container description and developer notes"
"property=og:title": "Volto container"
"keywords": "Volto, React, blocks, container, Plone"
---

(container-label)=

# Container

```{versionadded} Volto 17.0.0-alpha.10
```

A container in Volto is a core component that contains blocks.
A container consists of an Edit component that allows users to add, edit, or delete specific blocks inside the container.


## Building blocks using a container

When building a custom block that uses a container as its base, you must pass your block's properties into the container.


## Container props

The container component has particular properties:

`direction`
: The arrangement of blocks in the container, either `horizontal` or `vertical`.
The default value is `horizontal`.

`templateChooser`
: To complete the full customization of the template choice experience, you can customize the component that shows the choices as well.
You can enhance the default component located in {file}`src/components/manage/TemplateChooser/TemplateChooser.jsx` by providing your own component.
You might also need to provide your own custom `templates` function that is compatible with your component.

`editBlockWrapper`
: You can customize the container's `editBlockWrapper` by providing your own.
This will be passed to the `BlocksForm` component used by the container.
It is used to customize the block wrapper if the block that you are building needs to have a different one for the user experience of your block.

`containerToolbar`
: You can customize the container's control toolbar (the one on the top) by providing your own.

`maxLength`
: The maximum number of elements allowed inside the grid block.
The default value is four elements.

`allowedBlocks`
: Array of block types allowed in the grid block.
This can be extended to include any of the registered blocks.

`blocksConfig`
: It allows you to customize the blocks configuration available for the inner blocks.
You have to pass the whole existing Volto `blocksConfig` of the main configuration, then modify it given your needs, and pass it down.
You could add different variations, `schemaEnhancers`, and so on.
You could remove them as well, but only for blocks inside the grid block.

```js
config.blocks.blocksConfig.gridBlock.gridAllowedBlocks: ['teaser', 'image', 'slate'];
config.blocks.blocksConfig.gridBlock.blocksConfig: {
// You can customize the blocks inside the grid like this:
...config.blocks.blocksConfig,
teaser: {
...config.blocks.blocksConfig.teaser,
variations: [
{
id: 'default',
isDefault: true,
title: 'Default',
template: DefaultBody,
},
{
id: 'variation2',
title: 'variation #2',
template: DefaultBody2,
},
],
},
};
```
Loading

0 comments on commit df15ce4

Please sign in to comment.