mirror of
https://github.com/lowdefy/lowdefy.git
synced 2025-01-24 13:45:07 +08:00
feat: init @lowdefy/block-tools
This commit is contained in:
parent
ee5ecdd724
commit
e9854a7a29
@ -30,15 +30,19 @@ class ErrorBoundary extends Component {
|
||||
}
|
||||
|
||||
render() {
|
||||
const { description, message, renderError, children } = this.props;
|
||||
const { description, message, renderError, fallback, children } = this.props;
|
||||
const { hasError, error } = this.state;
|
||||
if (hasError) {
|
||||
return (
|
||||
if (fallback) {
|
||||
return fallback;
|
||||
}
|
||||
if (renderError) {
|
||||
<div>
|
||||
{renderError ? 'Error: ' : message}
|
||||
{renderError ? `${error.message}` : description} <br />
|
||||
</div>
|
||||
);
|
||||
{'Error: ' + (message || error.message) + (description && '<br />' + description)}
|
||||
</div>;
|
||||
}
|
||||
// Throw to console but fail silently to user?
|
||||
return '';
|
||||
}
|
||||
|
||||
return children;
|
||||
|
55
packages/blockTools/src/connectBlock.js
Normal file
55
packages/blockTools/src/connectBlock.js
Normal file
@ -0,0 +1,55 @@
|
||||
/*
|
||||
Copyright 2020 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';
|
||||
|
||||
const defaultMethods = (methods) => ({
|
||||
callAction: methods.callAction || (() => undefined),
|
||||
makeCss: methods.makeCss || (() => undefined),
|
||||
registerAction: methods.registerAction || (() => undefined),
|
||||
registerMethod: methods.registerMethod || (() => undefined),
|
||||
...methods,
|
||||
});
|
||||
|
||||
const connectBlock = (Comp) => {
|
||||
return ({
|
||||
actions,
|
||||
blockId,
|
||||
Components,
|
||||
content,
|
||||
methods,
|
||||
menus,
|
||||
properties,
|
||||
user,
|
||||
validate,
|
||||
...props
|
||||
}) => (
|
||||
<Comp
|
||||
{...props}
|
||||
actions={actions || {}}
|
||||
blockId={blockId || `blockId_${Math.floor(Math.random() * 16777215).toString(16)}`}
|
||||
methods={defaultMethods(methods || {})}
|
||||
Components={Components || {}}
|
||||
content={content || {}}
|
||||
menus={menus || []}
|
||||
properties={properties || {}}
|
||||
user={user || {}}
|
||||
validate={validate || []}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
export default connectBlock;
|
@ -14,9 +14,11 @@
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
import makeCss from './makeCss.js';
|
||||
import mediaToCssObject from './mediaToCssObject.js';
|
||||
import connectBlock from './connectBlock';
|
||||
import emotion from './emotion';
|
||||
import ErrorBoundary from './ErrorBoundary';
|
||||
import makeCssClass from './makeCssClass.js';
|
||||
import mediaToCssObject from './mediaToCssObject.js';
|
||||
import useRunAfterUpdate from './useRunAfterUpdate';
|
||||
|
||||
export { ErrorBoundary, emotion, makeCss, mediaToCssObject };
|
||||
export { connectBlock, emotion, ErrorBoundary, makeCssClass, mediaToCssObject, useRunAfterUpdate };
|
||||
|
@ -18,9 +18,9 @@ import { mergeObjects } from '@lowdefy/helpers';
|
||||
import mediaToCssObject from './mediaToCssObject';
|
||||
import emotion from './emotion';
|
||||
|
||||
const makeCss = (styles, options = {}) =>
|
||||
const makeCssClass = (styles, options = {}) =>
|
||||
options.styleObjectOnly
|
||||
? mediaToCssObject(mergeObjects(styles), options)
|
||||
: emotion.css(mediaToCssObject(mergeObjects(styles), options));
|
||||
|
||||
export default makeCss;
|
||||
export default makeCssClass;
|
32
packages/blockTools/src/useRunAfterUpdate.js
Normal file
32
packages/blockTools/src/useRunAfterUpdate.js
Normal file
@ -0,0 +1,32 @@
|
||||
/*
|
||||
Copyright 2020 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';
|
||||
|
||||
const useRunAfterUpdate = () => {
|
||||
const afterPaintRef = React.useRef(null);
|
||||
React.useLayoutEffect(() => {
|
||||
if (afterPaintRef.current) {
|
||||
afterPaintRef.current();
|
||||
afterPaintRef.current = null;
|
||||
}
|
||||
});
|
||||
return (fn) => {
|
||||
afterPaintRef.current = fn;
|
||||
};
|
||||
};
|
||||
|
||||
export default useRunAfterUpdate;
|
@ -1,4 +1,20 @@
|
||||
import makeCss from '../src/makeCss';
|
||||
/*
|
||||
Copyright 2020 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 makeCssClass from '../src/makeCssClass';
|
||||
|
||||
const mockCss = jest.fn();
|
||||
const mockCssImp = (obj) => ({
|
||||
@ -20,7 +36,7 @@ test('object with no media', () => {
|
||||
b: 1,
|
||||
c: { a: 'b' },
|
||||
};
|
||||
expect(makeCss(obj)).toMatchInlineSnapshot(`
|
||||
expect(makeCssClass(obj)).toMatchInlineSnapshot(`
|
||||
Object {
|
||||
"emotionClassFor": Object {
|
||||
"a": "a",
|
||||
@ -42,7 +58,7 @@ test('objects with no media', () => {
|
||||
const obj2 = {
|
||||
c: { a: 'c' },
|
||||
};
|
||||
expect(makeCss([obj1, obj2])).toMatchInlineSnapshot(`
|
||||
expect(makeCssClass([obj1, obj2])).toMatchInlineSnapshot(`
|
||||
Object {
|
||||
"emotionClassFor": Object {
|
||||
"a": "a",
|
||||
@ -64,7 +80,7 @@ test('objects with media', () => {
|
||||
lg: { a: 'lg' },
|
||||
xl: { a: 'xl' },
|
||||
};
|
||||
expect(makeCss(obj)).toMatchInlineSnapshot(`
|
||||
expect(makeCssClass(obj)).toMatchInlineSnapshot(`
|
||||
Object {
|
||||
"emotionClassFor": Object {
|
||||
"@media screen and (max-width: 576px)": Object {
|
||||
@ -102,7 +118,7 @@ test('objects with media', () => {
|
||||
lg: { a: 'lg', c: { sm: { a: '1' } } },
|
||||
xl: { a: 'xl' },
|
||||
};
|
||||
expect(makeCss([obj1, obj2])).toMatchInlineSnapshot(`
|
||||
expect(makeCssClass([obj1, obj2])).toMatchInlineSnapshot(`
|
||||
Object {
|
||||
"emotionClassFor": Object {
|
||||
"@media screen and (max-width: 576px)": Object {
|
||||
@ -136,7 +152,7 @@ test('object with no media, react', () => {
|
||||
b: 1,
|
||||
c: { a: 'b' },
|
||||
};
|
||||
expect(makeCss(obj, { react: true })).toMatchInlineSnapshot(`
|
||||
expect(makeCssClass(obj, { react: true })).toMatchInlineSnapshot(`
|
||||
Object {
|
||||
"emotionClassFor": Object {
|
||||
"a": "a",
|
||||
@ -158,7 +174,7 @@ test('objects with no media, react', () => {
|
||||
const obj2 = {
|
||||
c: { a: 'c' },
|
||||
};
|
||||
expect(makeCss([obj1, obj2], { react: true })).toMatchInlineSnapshot(`
|
||||
expect(makeCssClass([obj1, obj2], { react: true })).toMatchInlineSnapshot(`
|
||||
Object {
|
||||
"emotionClassFor": Object {
|
||||
"a": "a",
|
||||
@ -180,7 +196,7 @@ test('objects with media, react', () => {
|
||||
lg: { a: 'lg' },
|
||||
xl: { a: 'xl' },
|
||||
};
|
||||
expect(makeCss(obj, { react: true })).toMatchInlineSnapshot(`
|
||||
expect(makeCssClass(obj, { react: true })).toMatchInlineSnapshot(`
|
||||
Object {
|
||||
"emotionClassFor": Object {
|
||||
"@media screen and (maxWidth: 576px)": Object {
|
||||
@ -218,7 +234,7 @@ test('objects with media, react', () => {
|
||||
lg: { a: 'lg', c: { sm: { a: '1' } } },
|
||||
xl: { a: 'xl' },
|
||||
};
|
||||
expect(makeCss([obj1, obj2], { react: true })).toMatchInlineSnapshot(`
|
||||
expect(makeCssClass([obj1, obj2], { react: true })).toMatchInlineSnapshot(`
|
||||
Object {
|
||||
"emotionClassFor": Object {
|
||||
"@media screen and (maxWidth: 576px)": Object {
|
||||
@ -252,7 +268,7 @@ test('object with no media, styleObjectOnly', () => {
|
||||
b: 1,
|
||||
c: { a: 'b' },
|
||||
};
|
||||
expect(makeCss(obj, { styleObjectOnly: true })).toMatchInlineSnapshot(`
|
||||
expect(makeCssClass(obj, { styleObjectOnly: true })).toMatchInlineSnapshot(`
|
||||
Object {
|
||||
"a": "a",
|
||||
"b": 1,
|
||||
@ -272,7 +288,7 @@ test('objects with no media, styleObjectOnly', () => {
|
||||
const obj2 = {
|
||||
c: { a: 'c' },
|
||||
};
|
||||
expect(makeCss([obj1, obj2], { styleObjectOnly: true })).toMatchInlineSnapshot(`
|
||||
expect(makeCssClass([obj1, obj2], { styleObjectOnly: true })).toMatchInlineSnapshot(`
|
||||
Object {
|
||||
"a": "a",
|
||||
"c": Object {
|
||||
@ -292,7 +308,7 @@ test('objects with media, styleObjectOnly', () => {
|
||||
lg: { a: 'lg' },
|
||||
xl: { a: 'xl' },
|
||||
};
|
||||
expect(makeCss(obj, { styleObjectOnly: true })).toMatchInlineSnapshot(`
|
||||
expect(makeCssClass(obj, { styleObjectOnly: true })).toMatchInlineSnapshot(`
|
||||
Object {
|
||||
"@media screen and (max-width: 576px)": Object {
|
||||
"a": "sm",
|
||||
@ -328,7 +344,7 @@ test('objects with media, styleObjectOnly', () => {
|
||||
lg: { a: 'lg', c: { sm: { a: '1' } } },
|
||||
xl: { a: 'xl' },
|
||||
};
|
||||
expect(makeCss([obj1, obj2], { styleObjectOnly: true })).toMatchInlineSnapshot(`
|
||||
expect(makeCssClass([obj1, obj2], { styleObjectOnly: true })).toMatchInlineSnapshot(`
|
||||
Object {
|
||||
"@media screen and (max-width: 576px)": Object {
|
||||
"a": "smsm",
|
@ -1,3 +1,19 @@
|
||||
/*
|
||||
Copyright 2020 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 mediaToCssObject from '../src/mediaToCssObject';
|
||||
|
||||
test('no object', () => {
|
||||
|
Loading…
Reference in New Issue
Block a user