feat(blockBasic): Add Img block.

This commit is contained in:
Gervwyk 2021-05-26 10:32:36 +02:00
parent e9b2950ef6
commit c850cb3206
12 changed files with 449 additions and 10 deletions

View File

@ -8,7 +8,7 @@
- id: properties.style
type: Html
properties:
style:
style:
background: yellow
padding: 10
html: |
@ -16,7 +16,7 @@
- id: properties.html-styled
type: Html
properties:
style:
style:
background: yellow
padding: 10
html: |
@ -49,4 +49,4 @@
</div>
<script>
alert('script tag');
</script>
</script>

View File

@ -0,0 +1,60 @@
- id: default
type: Img
- id: src
type: Img
properties:
src: https://docs.lowdefy.com/public/logo-light-theme.png
- id: srcset
type: Img
properties:
src: https://docs.lowdefy.com/public/logo-light-theme.png
srcset: https://docs.lowdefy.com/public/logo-dark-theme.png
- id: alt
type: Img
properties:
src: https://docs.lowdefy.com/public/logo-light-theme.png
alt: This is the alt
- id: alt
type: Img
properties:
src: https://docs.lowdefy.com/public/logo-light-theme.png
crossorigin: anonymous
- id: decoding
type: Img
properties:
src: https://docs.lowdefy.com/public/logo-light-theme.png
decoding: sync
- id: height
type: Img
properties:
src: https://docs.lowdefy.com/public/logo-light-theme.png
height: 30
- id: loading
type: Img
properties:
src: https://docs.lowdefy.com/public/logo-light-theme.png
loading: lazy
- id: sizes
type: Img
properties:
src: https://docs.lowdefy.com/public/logo-light-theme.png
sizes: 20px
- id: style
type: Img
properties:
src: https://docs.lowdefy.com/public/logo-light-theme.png
style:
border: 1px solid red
- id: width
type: Img
properties:
src: https://docs.lowdefy.com/public/logo-light-theme.png
height: 10
- id: onClick
type: Img
properties:
src: https://docs.lowdefy.com/public/logo-light-theme.png
events:
onClick:
- id: testAction
type: Text

View File

@ -0,0 +1,38 @@
/*
Copyright 2020-2021 Lowdefy, Inc
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
import React from 'react';
import { blockDefaultProps } from '@lowdefy/block-tools';
const ImgBlock = ({ blockId, events, properties, methods }) => {
const { style, ...allProps } = properties;
return (
<img
{...allProps}
id={blockId}
data-testid={blockId}
onClick={() => methods.triggerEvent({ name: 'onClick' })}
className={methods.makeCssClass([
{ outline: 'none', cursor: events.onClick && 'pointer' },
properties.style,
])}
/>
);
};
ImgBlock.defaultProps = blockDefaultProps;
export default ImgBlock;

View File

@ -0,0 +1,62 @@
{
"category": "display",
"loading": false,
"schema": {
"properties": {
"type": "object",
"additionalProperties": false,
"required": ["src"],
"properties": {
"src": {
"type": "string",
"description": "The image URL."
},
"alt": {
"type": "string",
"description": "Alternative text description of the image."
},
"crossorigin": {
"type": "string",
"enum": ["anonymous", "use-credentials"],
"description": "Indicates if the fetching of the image must be done using a CORS request."
},
"decoding": {
"type": "string",
"enum": ["sync", "async", "auto"],
"description": "An image decoding hint to the browser. Sync for atomic presentation with other content, async, to reduce delay in presenting other content and auto leave to browser to decide."
},
"height": {
"type": "number",
"description": "Height of the image."
},
"loading": {
"type": "string",
"enum": ["eager", "lazy"],
"description": "How the browser should load the image. Eager loads the image immediately, lazy, defers loading until the image it reaches a calculated distance from the viewport, as defined by the browser."
},
"sizes": {
"type": "string",
"description": "Indicating a set of source sizes of strings separated by commas."
},
"srcset": {
"type": "string",
"description": "Possible image sources for the user agent to use, strings separated by commas.",
"docs": {
"displayType": "text-area"
}
},
"style": {
"type": "object",
"description": "Css style object to applied to the image.",
"docs": {
"displayType": "yaml"
}
},
"width": {
"type": "number",
"description": "Width of the image."
}
}
}
}
}

View File

@ -18,8 +18,9 @@ import Box from './blocks/Box/Box';
import Context from './blocks/Context/Context';
import DangerousHtml from './blocks/DangerousHtml/DangerousHtml';
import Html from './blocks/Html/Html';
import Img from './blocks/Img/Img';
import List from './blocks/List/List';
import Span from './blocks/Span/Span';
export { Box, Context, DangerousHtml, Html, Span, List };
export default { Box, Context, DangerousHtml, Html, Span, List };
export { Box, Context, DangerousHtml, Html, Img, List, Span };
export default { Box, Context, DangerousHtml, Html, Img, List, Span };

View File

@ -0,0 +1,56 @@
/*
Copyright 2020-2021 Lowdefy, Inc
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
import React from 'react';
import { mockBlock, runBlockSchemaTests, runRenderTests } from '@lowdefy/block-tools';
import { configure, mount } from 'enzyme';
import Adapter from '@wojtekmaj/enzyme-adapter-react-17';
configure({ adapter: new Adapter() });
import { Img } from '../src';
import examples from '../demo/examples/Img.yaml';
import meta from '../src/blocks/Img/Img.json';
jest.mock('@lowdefy/block-tools', () => {
const originalModule = jest.requireActual('@lowdefy/block-tools');
return {
...originalModule,
blockDefaultProps: {
...originalModule.blockDefaultProps,
methods: {
...originalModule.blockDefaultProps.methods,
makeCssClass: jest.fn((style, op) => JSON.stringify({ style, options: op })),
},
},
};
});
runRenderTests({ examples, Block: Img, meta });
runBlockSchemaTests({ examples, meta });
const { before, methods, getProps } = mockBlock({ meta });
beforeEach(before);
test('triggerEvent onClick', () => {
const block = {
id: 'one',
type: 'Img',
};
const Shell = () => <Img {...getProps(block)} methods={methods} />;
const wrapper = mount(<Shell />);
wrapper.find('[data-testid="one"]').simulate('click');
expect(methods.triggerEvent).toHaveBeenCalledWith({ name: 'onClick' });
});

View File

@ -0,0 +1,176 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`Render alt - value[0] 1`] = `
<img
alt="This is the alt"
className="{\\"style\\":[{\\"outline\\":\\"none\\"},null]}"
data-testid="alt"
id="alt"
onClick={[Function]}
src="https://docs.lowdefy.com/public/logo-light-theme.png"
/>
`;
exports[`Render alt - value[0] 2`] = `
<img
className="{\\"style\\":[{\\"outline\\":\\"none\\"},null]}"
crossorigin="anonymous"
data-testid="alt"
id="alt"
onClick={[Function]}
src="https://docs.lowdefy.com/public/logo-light-theme.png"
/>
`;
exports[`Render decoding - value[0] 1`] = `
<img
className="{\\"style\\":[{\\"outline\\":\\"none\\"},null]}"
data-testid="decoding"
decoding="sync"
id="decoding"
onClick={[Function]}
src="https://docs.lowdefy.com/public/logo-light-theme.png"
/>
`;
exports[`Render default - value[0] 1`] = `
<img
className="{\\"style\\":[{\\"outline\\":\\"none\\"},null]}"
data-testid="default"
id="default"
onClick={[Function]}
/>
`;
exports[`Render height - value[0] 1`] = `
<img
className="{\\"style\\":[{\\"outline\\":\\"none\\"},null]}"
data-testid="height"
height={30}
id="height"
onClick={[Function]}
src="https://docs.lowdefy.com/public/logo-light-theme.png"
/>
`;
exports[`Render loading - value[0] 1`] = `
<img
className="{\\"style\\":[{\\"outline\\":\\"none\\"},null]}"
data-testid="loading"
id="loading"
loading="lazy"
onClick={[Function]}
src="https://docs.lowdefy.com/public/logo-light-theme.png"
/>
`;
exports[`Render onClick - value[0] 1`] = `
<img
className="{\\"style\\":[{\\"outline\\":\\"none\\",\\"cursor\\":\\"pointer\\"},null]}"
data-testid="onClick"
id="onClick"
onClick={[Function]}
src="https://docs.lowdefy.com/public/logo-light-theme.png"
/>
`;
exports[`Render sizes - value[0] 1`] = `
<img
className="{\\"style\\":[{\\"outline\\":\\"none\\"},null]}"
data-testid="sizes"
id="sizes"
onClick={[Function]}
sizes="20px"
src="https://docs.lowdefy.com/public/logo-light-theme.png"
/>
`;
exports[`Render src - value[0] 1`] = `
<img
className="{\\"style\\":[{\\"outline\\":\\"none\\"},null]}"
data-testid="src"
id="src"
onClick={[Function]}
src="https://docs.lowdefy.com/public/logo-light-theme.png"
/>
`;
exports[`Render srcset - value[0] 1`] = `
<img
className="{\\"style\\":[{\\"outline\\":\\"none\\"},null]}"
data-testid="srcset"
id="srcset"
onClick={[Function]}
src="https://docs.lowdefy.com/public/logo-light-theme.png"
srcset="https://docs.lowdefy.com/public/logo-dark-theme.png"
/>
`;
exports[`Render style - value[0] 1`] = `
<img
className="{\\"style\\":[{\\"outline\\":\\"none\\"},{\\"border\\":\\"1px solid red\\"}]}"
data-testid="style"
id="style"
onClick={[Function]}
src="https://docs.lowdefy.com/public/logo-light-theme.png"
/>
`;
exports[`Render width - value[0] 1`] = `
<img
className="{\\"style\\":[{\\"outline\\":\\"none\\"},null]}"
data-testid="width"
height={10}
id="width"
onClick={[Function]}
src="https://docs.lowdefy.com/public/logo-light-theme.png"
/>
`;
exports[`Test Schema alt 1`] = `true`;
exports[`Test Schema alt 2`] = `null`;
exports[`Test Schema alt 3`] = `true`;
exports[`Test Schema alt 4`] = `null`;
exports[`Test Schema decoding 1`] = `true`;
exports[`Test Schema decoding 2`] = `null`;
exports[`Test Schema default 1`] = `true`;
exports[`Test Schema default 2`] = `null`;
exports[`Test Schema height 1`] = `true`;
exports[`Test Schema height 2`] = `null`;
exports[`Test Schema loading 1`] = `true`;
exports[`Test Schema loading 2`] = `null`;
exports[`Test Schema onClick 1`] = `true`;
exports[`Test Schema onClick 2`] = `null`;
exports[`Test Schema sizes 1`] = `true`;
exports[`Test Schema sizes 2`] = `null`;
exports[`Test Schema src 1`] = `true`;
exports[`Test Schema src 2`] = `null`;
exports[`Test Schema srcset 1`] = `true`;
exports[`Test Schema srcset 2`] = `null`;
exports[`Test Schema style 1`] = `true`;
exports[`Test Schema style 2`] = `null`;
exports[`Test Schema width 1`] = `true`;
exports[`Test Schema width 2`] = `null`;

View File

@ -23,7 +23,7 @@ _ref:
html: <a href="https://lowdefy.com">Lowdefy Website</a>
description_content: |
A block to render HTML.
> The Html block sanitizes HTML using [DOMPurify's](https://github.com/cure53/DOMPurify) default configuration. This comes with some security considerations, please consider [DOMPurify's Security Goals and Threat Model](https://github.com/cure53/DOMPurify/wiki/Security-Goals-&-Threat-Model) for more details regarding the security impact of using the Html block. In short, it is strongly advised to never render any user input Html content, only render hardcoded or trusted HTML content.
examples:
@ -31,21 +31,20 @@ _ref:
block:
id: basic_example
type: Html
properties:
properties:
html: |
<div style="background: #123456; padding: 10px;"><h1 style="color: white;">A simple white title box</h1></div>
- title: DangerousHtml with iframes sanitized
block:
id: sanitized_iframes_example
type: Html
properties:
properties:
html: |
The iframe was removed: <iframe style="max-width: 512px;" width="100%" src="https://www.youtube.com/embed/7N7GWdlQJlU" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe> - title: DangerousHtml with iframes enabled
- title: DangerousHtml basic sanitization
block:
id: sanitized_example
type: Html
properties:
properties:
html: |
<div style="color: red; border: 2px dashed blue; padding: 10px;"><script>alert("hello world")</script><img src=x onerror=alert("img") />A little bit of bad html sanitized.</div>

View File

@ -0,0 +1,40 @@
# Copyright 2020-2021 Lowdefy, Inc
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
# http://www.apache.org/licenses/LICENSE-2.0
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
_ref:
path: templates/blocks/template.yaml.njk
vars:
block_type: Img
category: display
schema: ../blocks/blocksBasic/src/blocks/Img/Img.json
filePath: blocks/display/Img.yaml
init_property_values:
src: 'https://docs.lowdefy.com/public/logo-light-theme.png'
description_content: |
A block to render a HTML [`<img/>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/img) element.
examples:
- title: Basic Img
block:
id: basic_example
type: Img
properties:
src: https://docs.lowdefy.com/public/logo-light-theme.png
- title: srcset Img
block:
id: srcset_example
type: Img
properties:
src: https://docs.lowdefy.com/public/logo-light-theme.png
srcset: https://docs.lowdefy.com/public/logo-square-light-theme.png 40w, https://docs.lowdefy.com/public/logo-light-theme.png 577w
sizes: '(max-width: 576px) 40px, 577px'

View File

@ -16,6 +16,9 @@ name: '@lowdefy/docs'
lowdefy: '3.15.0'
licence: Apache-2.0
types:
Img:
url: http://localhost:3002/meta/Img.json
global:
all_icons:
_ref: blocks/all_icons.yaml

View File

@ -293,6 +293,9 @@
- id: Icon
type: MenuLink
pageId: Icon
- id: Img
type: MenuLink
pageId: Img
- id: Markdown
type: MenuLink
pageId: Markdown

View File

@ -74,6 +74,7 @@
- _ref: blocks/display/EChart.yaml
- _ref: blocks/display/Html.yaml
- _ref: blocks/display/Icon.yaml
- _ref: blocks/display/Img.yaml
- _ref: blocks/display/Markdown.yaml
- _ref: blocks/display/MarkdownWithCode.yaml
- _ref: blocks/display/Menu.yaml