feat(layout): init @lowdefy/layout

This commit is contained in:
Gervwyk 2020-10-07 12:00:08 +02:00
parent 06939c6c77
commit 65612d4a5a
58 changed files with 15729 additions and 5 deletions

1
.gitignore vendored
View File

@ -3,5 +3,6 @@
.yarn/install-state.gz
**/dist/*
**/coverage/*
.DS_Store

View File

@ -1,13 +1,72 @@
packageExtensions:
"@apollo/client@*":
'@apollo/client@*':
dependencies:
graphql: "*"
"@apollographql/apollo-tools@*":
graphql: '*'
'@apollographql/apollo-tools@*':
dependencies:
graphql: "*"
graphql: '*'
'rc-animate@*':
dependencies:
'react-dom': '*'
'react': '*'
'rc-dialog@*':
dependencies:
'react-dom': '*'
'react': '*'
'rc-cascader@*':
dependencies:
'react-dom': '*'
'react': '*'
'rc-checkbox@*':
dependencies:
'react-dom': '*'
'react': '*'
'rc-collapse@*':
dependencies:
'react-dom': '*'
'react': '*'
'rc-input-number@*':
dependencies:
'react-dom': '*'
'react': '*'
'rc-menu@*':
dependencies:
'react-dom': '*'
'react': '*'
'rc-progress@*':
dependencies:
'react-dom': '*'
'react': '*'
'rc-rate@*':
dependencies:
'react-dom': '*'
'react': '*'
'rc-tabs@*':
dependencies:
'react-dom': '*'
'react': '*'
'rc-tooltip@*':
dependencies:
'react-dom': '*'
'react': '*'
'rc-trigger@*':
dependencies:
'react-dom': '*'
'react': '*'
'rc-upload@*':
dependencies:
'react-dom': '*'
'react': '*'
'rc-util@*':
dependencies:
'react-dom': '*'
'react': '*'
'react-dom@*':
dependencies:
'react': '*'
plugins:
- path: .yarn/plugins/@yarnpkg/plugin-interactive-tools.cjs
spec: "@yarnpkg/plugin-interactive-tools"
spec: '@yarnpkg/plugin-interactive-tools'
yarnPath: .yarn/releases/yarn-berry.cjs

14
packages/layout/.babelrc Normal file
View File

@ -0,0 +1,14 @@
{
"presets": [
[
"@babel/preset-env",
{
"targets": {
"node": "12",
"esmodules": true
}
}
],
"@babel/preset-react"
]
}

View File

@ -0,0 +1,124 @@
import React from 'react';
import type from '@lowdefy/type';
import { Input } from 'antd';
import { Area, BlockLayout, layoutParamsToArea } from '../src';
import Block from './blocks/Block';
import Box from './blocks/Box';
import Button from './blocks/Button';
import Page from './blocks/Page';
import Paragraph from './blocks/Paragraph';
import List from './blocks/List';
import Markdown from './blocks/Markdown';
import ErrorBoundary from './ErrorBoundary';
const Blocks = {
Block,
Button,
Input,
Paragraph,
Markdown,
};
const Containers = {
Box,
Page,
};
const Lists = {
List,
};
const Loading = ({ loading, children, showLoading = true }) =>
loading && showLoading ? <span>Loading</span> : <>{children}</>;
const AutoBlock = ({ block, makeCss, highlightBorders }) => {
const content = {};
let areas;
let Comp = Blocks[block.type];
let category = 'block';
if (!Comp) {
Comp = Containers[block.type];
category = 'container';
}
if (!Comp) {
Comp = Lists[block.type];
category = 'list';
}
switch (category) {
case 'container':
if (block.blocks) {
areas = { content: { blocks: block.blocks } };
}
if (block.areas) {
areas = block.areas;
}
Object.keys(areas || {}).forEach((areaKey) => {
content[areaKey] = (areaStyle) => (
<Area
area={layoutParamsToArea({
area: areas[areaKey] || {},
areaKey,
layout: block.layout || {},
})}
areaStyle={[areaStyle, type.isObject(areas[areaKey]) ? areas[areaKey].style : {}]}
highlightBorders={highlightBorders}
id={`${block.id}-${areaKey}`}
key={`${block.id}-${areaKey}`}
makeCss={makeCss}
>
{(areas[areaKey].blocks || []).map((bl, i) => (
<BindAutoBlock
key={`${bl.id}-${i}`}
block={bl}
makeCss={makeCss}
highlightBorders={highlightBorders}
/>
))}
</Area>
);
});
return (
<Comp
blockId={block.id}
content={content}
loading={block.loading}
makeCss={makeCss}
properties={block.properties}
/>
);
default:
return (
<Comp
blockId={block.id}
loading={block.loading}
makeCss={makeCss}
properties={block.properties}
/>
);
}
};
const BindAutoBlock = ({ block, state, makeCss, highlightBorders }) => {
return (
<ErrorBoundary>
<Loading id={`${block.id}-loading`} loading={block.loading} showLoading>
<BlockLayout
id={`bl-${block.id}`}
highlightBorders={highlightBorders}
layout={block.layout || {}}
blockStyle={block.style}
makeCss={makeCss}
>
<AutoBlock
block={block}
state={state}
makeCss={makeCss}
highlightBorders={highlightBorders}
/>
</BlockLayout>
</Loading>
</ErrorBoundary>
);
};
export default BindAutoBlock;

View File

@ -0,0 +1,32 @@
import React, { Component } from 'react';
class ErrorBoundary extends Component {
constructor(props) {
super(props);
this.state = {
hasError: false,
error: null,
};
}
static getDerivedStateFromError(error) {
return { hasError: true, error };
}
render() {
const { description, message, renderError, children } = this.props;
const { hasError, error } = this.state;
if (hasError) {
return (
<div>
ERROR: {renderError ? 'Error: ' : message} <br />
{renderError ? `${error.message}` : description} <br />
</div>
);
}
return children;
}
}
export default ErrorBoundary;

View File

@ -0,0 +1,20 @@
import React from 'react';
const Blank = ({ blockId, makeCss }) => (
<div
id={blockId}
className={makeCss([
{
background: '#269',
border: '2px solid #00aaee',
textAlign: 'center',
fontSize: 12,
color: '#fff',
},
])}
>
{blockId}
</div>
);
export default Blank;

View File

@ -0,0 +1,7 @@
import React from 'react';
const Box = ({ blockId, content }) => (
<div id={blockId}>{content.content && content.content()}</div>
);
export default Box;

View File

@ -0,0 +1,10 @@
import React from 'react';
import { Button } from 'antd';
const Blank = ({ blockId, properties }) => (
<Button id={blockId} {...properties}>
{blockId}
</Button>
);
export default Blank;

View File

@ -0,0 +1,20 @@
import React from 'react';
const Blank = ({ blockId, makeCss, children }) => (
<div
id={blockId}
className={makeCss([
{
background: '#900000',
border: '2px solid #f00',
textAlign: 'center',
fontSize: 12,
color: '#fff',
},
])}
>
{children}
</div>
);
export default Blank;

View File

@ -0,0 +1,483 @@
.markdown-body a:focus {
outline: none;
}
.markdown-body h1:hover a,
.markdown-body h2:hover a .markdown-body h3:hover a,
.markdown-body h4:hover a,
.markdown-body h5:hover a,
.markdown-body h6:hover a {
text-decoration: none;
}
.markdown-body {
-ms-text-size-adjust: 100%;
-webkit-text-size-adjust: 100%;
line-height: 1.55;
font-size: 16px;
word-wrap: break-word;
}
.markdown-body details {
display: block;
}
.markdown-body summary {
display: list-item;
}
.markdown-body a {
background-color: transparent;
}
.markdown-body a:active,
.markdown-body a:hover {
outline-width: 0;
}
.markdown-body strong {
font-weight: inherit;
font-weight: bolder;
}
.markdown-body h1 {
font-size: 2em;
margin: 0.67em 0;
}
.markdown-body img {
border-style: none;
}
.markdown-body code,
.markdown-body kbd,
.markdown-body pre {
font-family: monospace, monospace;
font-size: 1em;
}
.markdown-body hr {
box-sizing: content-box;
height: 0;
overflow: visible;
}
.markdown-body input {
font: inherit;
margin: 0;
}
.markdown-body input {
overflow: visible;
}
.markdown-body [type='checkbox'] {
box-sizing: border-box;
padding: 0;
}
.markdown-body * {
box-sizing: border-box;
}
.markdown-body input {
font-family: inherit;
font-size: inherit;
line-height: inherit;
}
.markdown-body a {
text-decoration: none;
}
.markdown-body a:hover {
text-decoration: underline;
}
.markdown-body strong {
font-weight: 600;
}
.markdown-body hr {
background: transparent;
border: 0;
border-bottom: 1px solid #dfe2e5;
height: 0;
margin: 15px 0;
overflow: hidden;
}
.markdown-body hr:before {
content: '';
display: table;
}
.markdown-body hr:after {
clear: both;
content: '';
display: table;
}
.markdown-body table {
border-collapse: collapse;
border-spacing: 0;
}
.markdown-body td,
.markdown-body th {
padding: 0;
}
.markdown-body details summary {
cursor: pointer;
}
.markdown-body h1,
.markdown-body h2,
.markdown-body h3,
.markdown-body h4,
.markdown-body h5,
.markdown-body h6 {
margin-bottom: 0;
margin-top: 0;
}
.markdown-body h1 {
font-size: 32px;
}
.markdown-body h1,
.markdown-body h2 {
font-weight: 600;
}
.markdown-body h2 {
font-size: 24px;
}
.markdown-body h3 {
font-size: 20px;
}
.markdown-body h3,
.markdown-body h4 {
font-weight: 600;
}
.markdown-body h4 {
font-size: 16px;
}
.markdown-body h5 {
font-size: 14px;
}
.markdown-body h5,
.markdown-body h6 {
font-weight: 600;
}
.markdown-body h6 {
font-size: 12px;
}
.markdown-body p {
margin-bottom: 10px;
margin-top: 0;
}
.markdown-body blockquote {
margin: 0;
}
.markdown-body ol,
.markdown-body ul {
margin-bottom: 0;
margin-top: 0;
padding-left: 0;
}
.markdown-body ol ol,
.markdown-body ul ol {
list-style-type: lower-roman;
}
.markdown-body ol ol ol,
.markdown-body ol ul ol,
.markdown-body ul ol ol,
.markdown-body ul ul ol {
list-style-type: lower-alpha;
}
.markdown-body dd {
margin-left: 0;
}
.markdown-body code,
.markdown-body pre {
font-family: SFMono-Regular, Consolas, Liberation Mono, Menlo, Courier, monospace;
font-size: 12px;
}
.markdown-body pre {
margin-bottom: 0;
margin-top: 0;
}
.markdown-body input::-webkit-inner-spin-button,
.markdown-body input::-webkit-outer-spin-button {
-webkit-appearance: none;
appearance: none;
margin: 0;
}
.markdown-body:before {
content: '';
display: table;
}
.markdown-body:after {
clear: both;
content: '';
display: table;
}
.markdown-body > :first-child {
margin-top: 0 !important;
}
.markdown-body > :last-child {
margin-bottom: 0 !important;
}
.markdown-body a:not([href]) {
color: inherit;
text-decoration: none;
}
.markdown-body blockquote,
.markdown-body dl,
.markdown-body ol,
.markdown-body p,
.markdown-body pre,
.markdown-body table,
.markdown-body ul {
margin-bottom: 16px;
margin-top: 0;
}
.markdown-body hr {
background-color: #e1e4e8;
border: 0;
height: 0.25em;
margin: 24px 0;
padding: 0;
}
.markdown-body blockquote {
border-left: 0.25em solid #dfe2e5;
color: #6a737d;
padding: 0 1em;
}
.markdown-body blockquote > :first-child {
margin-top: 0;
}
.markdown-body blockquote > :last-child {
margin-bottom: 0;
}
.markdown-body kbd {
background-color: #fafbfc;
border: 1px solid #c6cbd1;
border-bottom-color: #959da5;
border-radius: 3px;
box-shadow: inset 0 -1px 0 #959da5;
color: #444d56;
display: inline-block;
font-size: 11px;
line-height: 11px;
padding: 3px 5px;
vertical-align: middle;
}
.markdown-body h1,
.markdown-body h2,
.markdown-body h3,
.markdown-body h4,
.markdown-body h5,
.markdown-body h6 {
font-weight: 600;
line-height: 1.3;
margin-bottom: 16px;
margin-top: 24px;
}
.markdown-body h1 {
font-size: 2em;
}
.markdown-body h1,
.markdown-body h2 {
border-bottom: 1px solid #eaecef;
padding-bottom: 0.3em;
}
.markdown-body h2 {
font-size: 1.5em;
}
.markdown-body h3 {
font-size: 1.25em;
}
.markdown-body h4 {
font-size: 1em;
}
.markdown-body h5 {
font-size: 0.875em;
}
.markdown-body h6 {
color: #6a737d;
font-size: 0.85em;
}
.markdown-body ol,
.markdown-body ul {
padding-left: 2em;
}
.markdown-body ol ol,
.markdown-body ol ul,
.markdown-body ul ol,
.markdown-body ul ul {
margin-bottom: 0;
margin-top: 0;
}
.markdown-body li {
word-wrap: break-all;
}
.markdown-body li > p {
margin-top: 16px;
}
.markdown-body li + li {
margin-top: 0.25em;
}
.markdown-body dl {
padding: 0;
}
.markdown-body dl dt {
font-size: 1em;
font-style: italic;
font-weight: 600;
margin-top: 16px;
padding: 0;
}
.markdown-body dl dd {
margin-bottom: 16px;
padding: 0 16px;
}
.markdown-body table {
display: block;
overflow: auto;
width: 100%;
}
.markdown-body table th {
font-weight: 600;
}
.markdown-body table td,
.markdown-body table th {
border: 1px solid #dfe2e5;
padding: 6px 13px;
}
.markdown-body table tr {
background-color: #fff;
border-top: 1px solid #c6cbd1;
}
.markdown-body table tr:nth-child(2n) {
background-color: #f6f8fa;
}
.markdown-body img {
background-color: #fff;
box-sizing: content-box;
max-width: 100%;
}
.markdown-body img[align='right'] {
padding-left: 20px;
}
.markdown-body img[align='left'] {
padding-right: 20px;
}
.markdown-body code {
background-color: rgba(27, 31, 35, 0.05);
border-radius: 3px;
font-size: 85%;
margin: 0;
padding: 0.2em 0.4em;
}
.markdown-body pre {
word-wrap: normal;
background-color: rgba(27, 31, 35, 0.05);
border-radius: 3px;
font-size: 85%;
padding: 0.2em 0.4em;
}
.markdown-body pre > code {
background: transparent;
border: 0;
font-size: 100%;
margin: 0;
padding: 0;
white-space: pre;
word-break: normal;
}
.markdown-body pre code {
background-color: transparent;
border: 0;
display: inline;
line-height: inherit;
margin: 0;
max-width: auto;
overflow: visible;
padding: 0;
word-wrap: normal;
}
.markdown-body kbd {
background-color: #fafbfc;
border: 1px solid #d1d5da;
border-bottom-color: #c6cbd1;
border-radius: 3px;
box-shadow: inset 0 -1px 0 #c6cbd1;
color: #444d56;
display: inline-block;
font: 11px SFMono-Regular, Consolas, Liberation Mono, Menlo, Courier, monospace;
line-height: 11px;
padding: 3px 5px;
vertical-align: middle;
}
.markdown-body hr {
border-bottom-color: #eee;
}

View File

@ -0,0 +1,16 @@
import React from 'react';
import ReactMarkdown from 'react-markdown/with-html';
import './Markdown.css';
const Markdown = ({ blockId, properties }) => (
<div id={blockId}>
<ReactMarkdown
className="markdown-body"
source={properties.content}
escapeHtml={!properties.renderHtml}
/>
</div>
);
export default Markdown;

View File

@ -0,0 +1,50 @@
import React from 'react';
import { Layout, Breadcrumb } from 'antd';
const { Header, Content, Footer, Sider } = Layout;
class Page extends React.Component {
constructor(props) {
super(props);
this.state = {
collapsed: false,
};
this.onCollapse = this.onCollapse.bind(this);
}
onCollapse(collapsed) {
console.log(collapsed);
this.setState({ collapsed });
}
render() {
const { content } = this.props;
return (
<Layout style={{ minHeight: '100vh' }}>
<Sider collapsible collapsed={this.state.collapsed} onCollapse={this.onCollapse}>
<div className="logo" />
{content.sider && content.sider()}
</Sider>
<Layout className="site-layout">
<Header className="site-layout-background" style={{ padding: 0 }}>
{content.header && content.header()}
</Header>
<Content style={{ margin: '0 16px' }}>
<Breadcrumb style={{ margin: '16px 0' }}>
<Breadcrumb.Item>User</Breadcrumb.Item>
<Breadcrumb.Item>Bill</Breadcrumb.Item>
</Breadcrumb>
<div className="site-layout-background" style={{ padding: 24, minHeight: 360 }}>
{content.content && content.content()}
</div>
</Content>
{content.footer && (
<Footer style={{ textAlign: 'center' }}>{content.footer && content.footer()}</Footer>
)}
</Layout>
</Layout>
);
}
}
export default Page;

View File

@ -0,0 +1,5 @@
import React from 'react';
const Paragraph = ({ blockId, properties }) => <div id={blockId}>{properties.content}</div>;
export default Paragraph;

View File

@ -0,0 +1,62 @@
import YAML from 'js-yaml';
import basic from './examples/basic.yaml';
import grid from './examples/grid.yaml';
import kanban from './examples/kanban.yaml';
import complex from './examples/complex.yaml';
import row from './examples/row.yaml';
import col from './examples/col.yaml';
const dumpYaml = (data) => {
if (!data) {
return '';
}
return YAML.safeDump(data, {
// sortKeys: true,
noRefs: true,
});
};
const addBlocks = (acc, title, blocks) => {
acc.push({
id: 'grids',
type: 'Markdown',
properties: {
content: title,
},
});
(blocks || []).forEach((ex) => {
acc.push({
id: 'p',
type: 'Markdown',
properties: {
content: `\`\`\`\`yaml
${dumpYaml(ex)}
`,
},
});
acc.push(ex);
});
};
const getEx = () => {
const m = [];
addBlocks(m, ' # Basic Layouts', basic);
addBlocks(m, ' # Col Options', col);
addBlocks(m, ' # Row Options', row);
addBlocks(m, ' # Grid Layouts', grid);
addBlocks(m, ' # Kanban Layouts', kanban);
addBlocks(m, ' # Complex Layouts', complex);
return m;
};
const examples = {
id: 'page',
type: 'Page',
areas: {
content: {
blocks: [...getEx()],
},
},
};
export default examples;

View File

@ -0,0 +1,37 @@
- id: Paragraph style
type: Paragraph
style:
background: white
borderRadius: 20
properties:
content: >-
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod
tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,
quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse
cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat
non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
- id: Input
type: Input
- id: Button
type: Button
- id: 'Paragraph span: 12'
type: Paragraph
layout:
span: 12
properties:
content: >-
Loem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod
tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,
quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse
cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat
non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
- id: Input
type: Input
layout:
span: 4
- id: Disabled Col
type: Input
layout:
disabled: true

View File

@ -0,0 +1,319 @@
- id: 'span'
type: 'Box'
blocks:
- id: One
type: Paragraph
style:
background: '#40a0FF'
layout:
span: 4
properties:
content: |
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
- id: Two
type: Paragraph
layout:
span: 8
style:
background: '#FF4FaF'
properties:
content: |
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
- id: Three
type: Paragraph
layout:
span: 15
properties:
content: |
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
- id: 'center content'
type: Box
layout:
contentJustify: center
blocks:
- id: One
type: Paragraph
layout:
size: 800
style:
background: '#40a0FF'
properties:
content: |
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
- id: order
type: Box
blocks:
- id: One
type: Paragraph
layout:
order: 1
style:
background: '#40a0FF'
properties:
content: |
ONE Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,
- id: Two
type: Paragraph
layout:
order: 0
style:
background: '#FF4FaF'
properties:
content: |
TWO Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,
- id: offset
type: Box
blocks:
- id: One
type: Paragraph
layout:
offset: 4
style:
background: '#40a0FF'
properties:
content: |
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,
- id: Two
type: Paragraph
layout:
offset: 4
span: 10
style:
background: '#FF4FaF'
properties:
content: |
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,
- id: pull
type: Box
blocks:
- id: One
type: Paragraph
layout:
span: 10
style:
background: '#40a0FF'
properties:
content: |
ONE Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,
- id: Two
type: Paragraph
layout:
pull: 1
span: 10
style:
background: '#FF4FaF'
opacity: 0.5
properties:
content: |
TWO Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,
- id: push
type: Box
blocks:
- id: One
type: Paragraph
layout:
push: 1
span: 10
style:
background: '#40a0FF'
properties:
content: |
ONE Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,
- id: Two
type: Paragraph
layout:
span: 10
style:
background: '#FF4FaF'
opacity: 0.5
properties:
content: |
TWO Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,
- id: offset push pull span
type: Box
blocks:
- id: One
type: Paragraph
layout:
offset: 2
span: 6
style:
background: '#40AA55'
properties:
content: |
ONE Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod
- id: One
type: Paragraph
layout:
push: 1
span: 6
style:
background: '#40a0FF'
properties:
content: |
ONE Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod
- id: Two
type: Paragraph
layout:
pull: 1
span: 6
style:
background: '#FF4FaF'
opacity: 0.5
properties:
content: |
TWO Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod
- id: grow 1 1
type: Box
blocks:
- id: One
type: Paragraph
layout:
grow: 1
style:
background: '#40a0FF'
properties:
content: |
grow: 1 - ONE Lorem ipsum dolor
- id: Two
type: Paragraph
layout:
grow: 1
style:
background: '#FF4FaF'
properties:
content: |
grow: 1 - TWO Lorem ipsum dolor
- id: grow 1 0
type: Box
blocks:
- id: One
type: Paragraph
layout:
grow: 1
style:
background: '#40a0FF'
properties:
content: |
grow: 1 - ONE Lorem ipsum dolor
- id: Two
type: Paragraph
layout:
grow: 0
style:
background: '#FF4FaF'
properties:
content: |
grow: 0 - TWO Lorem ipsum dolor
- id: grow 0 1
type: Box
blocks:
- id: One
type: Paragraph
layout:
grow: 0
style:
background: '#40a0FF'
properties:
content: |
grow: 0 - ONE Lorem ipsum dolor
- id: Two
type: Paragraph
layout:
grow: 1
style:
background: '#FF4FaF'
properties:
content: |
grow: 1 - TWO Lorem ipsum dolor
- id: grow 0 0
type: Box
blocks:
- id: One
type: Paragraph
layout:
grow: 0
style:
background: '#40a0FF'
properties:
content: |
grow: 0 - ONE Lorem ipsum dolor
- id: Two
type: Paragraph
layout:
grow: 0
style:
background: '#FF4FaF'
properties:
content: |
grow: 0 - TWO Lorem ipsum dolor
- id: shrink 1 1
type: Box
blocks:
- id: One
type: Paragraph
layout:
shrink: 1
style:
background: '#40a0FF'
properties:
content: |
shrink: 1 - ONE Lorem ipsum dolor
- id: Two
type: Paragraph
layout:
shrink: 1
style:
background: '#FF4FaF'
properties:
content: |
shrink: 1 - TWO Lorem ipsum dolor
- id: size
type: Box
blocks:
- id: One
type: Paragraph
layout:
size: 200
style:
background: '#40a0FF'
properties:
content: |
size: 200 - ONE Lorem ipsum dolor
- id: Two
type: Paragraph
layout:
size: 400
style:
background: '#FF4FaF'
properties:
content: |
size: 400 - TWO Lorem ipsum dolor
- id: align
type: Box
areas:
content:
style:
height: 100
blocks:
- id: One
type: Button
layout:
align: top
span: 4
style:
background: '#40a0FF'
- id: Two
type: Button
layout:
align: middle
span: 4
style:
background: '#FF4FaF'
- id: Three
type: Button
layout:
align: bottom
span: 4
style:
background: '#40AA55'

View File

@ -0,0 +1,292 @@
- id: Complex Example
type: Box
blocks:
- id: header
type: Box
blocks:
- id: heading
type: Markdown
layout:
flex: 1 0 auto
properties:
content: |
# Issues
- id: feedback
type: Markdown
layout:
flex: 0 1 auto
align: center
properties:
content: |
Give Feedback
- id: tools
type: Box
blocks:
- id: search
type: Input
layout:
flex: 0 0 auto
- id: Assign
type: Button
layout:
flex: 0 0 auto
- id: Reporter
type: Button
layout:
flex: 0 0 auto
- id: Status
type: Button
layout:
flex: 0 0 auto
- id: Type
type: Button
layout:
flex: 1 0 auto
- id: advanced
type: Markdown
layout:
flex: 0 0 auto
properties:
content: |
Advanced Search
- id: main
type: Box
blocks:
- id: list_main
type: Box
layout:
flex: 0 1 300px
blocks:
- id: list_tools
type: Box
blocks:
- id: Created
type: Button
layout:
flex: 1 1 auto
- id: Fil
type: Button
layout:
flex: 0 1 auto
- id: Ref
type: Button
layout:
flex: 0 1 auto
- id: list
type: Box
blocks:
- id: item_0_1
type: Block
style:
height: 50
- id: item_0_2
type: Block
style:
height: 50
- id: item_0_3
type: Block
style:
height: 50
- id: item_0_4
type: Block
style:
height: 50
- id: main_content
type: Box
layout:
flex: 1 1 200px
# align: start
blocks:
- id: content
type: Markdown
properties:
content: |
## Validate still a heading
The below config will fail for both the field on root and the field in the object when the context is validated.
- id: comment
type: Box
blocks:
- id: avatar
type: Block
layout:
flex: 0 1 80px
- id: input_comment
layout:
flex: 1 1 80px
type: Input
- id: sider
type: Box
layout:
flex: 0 1 200px
blocks:
- id: content
type: Markdown
properties:
content: |
### One
- id: content
type: Markdown
properties:
content: |
Two
- id: content
type: Markdown
properties:
content: |
### three
- id: content
type: Markdown
properties:
content: |
Four
- id: Complex No Flex Field Example
type: Box
blocks:
- id: header
type: Box
blocks:
- id: heading
type: Markdown
layout:
grow: 1
properties:
content: |
# Issues
- id: feedback
type: Markdown
layout:
size: auto
align: center
properties:
content: |
Give Feedback
- id: tools
type: Box
blocks:
- id: search
type: Input
layout:
size: auto
- id: Assign
type: Button
layout:
flex: 0 1 auto
size: auto
- id: Reporter
type: Button
layout:
size: auto
- id: Status
type: Button
layout:
size: auto
- id: Type
type: Button
layout:
grow: 1
- id: advanced
type: Markdown
layout:
size: auto
properties:
content: |
Advanced Search
- id: main
type: Box
blocks:
- id: list_main
type: Box
layout:
size: 300
blocks:
- id: list_tools
type: Box
blocks:
- id: Created
type: Button
layout:
grow: 1
- id: Fil
type: Button
layout:
size: auto
- id: Ref
type: Button
layout:
size: auto
- id: list
type: Box
blocks:
- id: item_0_1
type: Block
style:
height: 50
- id: item_0_2
type: Block
style:
height: 50
- id: item_0_3
type: Block
style:
height: 50
- id: item_0_4
type: Block
style:
height: 50
- id: main_content
type: Box
layout:
size: 200
grow: 1
blocks:
- id: content
type: Markdown
properties:
content: |
## Validate still a heading
The below config will fail for both the field on root and the field in the object when the context is validated.
- id: comment
type: Box
blocks:
- id: avatar
type: Block
layout:
size: auto
- id: inputs_comment
layout:
grow: 1
type: Input
- id: sider
type: Box
layout:
size: 200
blocks:
- id: content
type: Markdown
properties:
content: |
### One
- id: content
type: Markdown
properties:
content: |
Two
- id: content
type: Markdown
properties:
content: |
### three
- id: content
type: Markdown
properties:
content: |
Four

View File

@ -0,0 +1,157 @@
- id: 4 sequential blocks
type: Box
blocks:
- id: tile_one
type: Block
- id: tile_two
type: Block
- id: tile_three
type: Block
- id: tile_four
type: Block
- id: 4 block grid
type: Box
blocks:
- id: tile_one
type: Block
layout:
span: 12
- id: tile_two
type: Block
layout:
span: 12
- id: tile_three
type: Block
layout:
span: 12
- id: tile_four
type: Block
layout:
span: 12
- id: 4 block grid with gutter
type: Box
areas:
content:
gutter: 50
blocks:
- id: tile_one
type: Block
layout:
span: 12
- id: tile_two
type: Block
layout:
span: 12
- id: tile_three
type: Block
layout:
span: 12
- id: tile_four
type: Block
layout:
span: 12
- id: 4 block grid with various heights
type: Box
areas:
content:
blocks:
- id: tile_one
type: Block
style:
height: 50
layout:
span: 12
- id: tile_two
type: Block
style:
height: 40
layout:
span: 12
- id: tile_three
type: Block
style:
height: 20
layout:
span: 12
- id: tile_four
type: Block
style:
height: 30
layout:
span: 12
- id: 2 column stacking
type: Box
blocks:
- id: b1
type: Box
layout:
span: 6
blocks:
- id: tile_one
type: Block
style:
height: 80
- id: b2
type: Box
layout:
span: 18
blocks:
- id: tile_two
type: Block
style:
height: 40
- id: tile_three
type: Block
style:
height: 20
layout:
span: 12
- id: tile_four
type: Block
style:
height: 30
layout:
span: 12
- id: typical dashboard
type: Box
layout:
contentGutter: 10
blocks:
- id: tile_one
type: Block
layout:
span: 8
style:
height: 80
- id: tile_two
type: Block
layout:
span: 8
style:
height: 80
- id: tile_three
type: Block
layout:
span: 8
style:
height: 80
- id: tile_four
type: Block
layout:
span: 12
style:
height: 80
- id: tile_five
type: Block
layout:
span: 12
style:
height: 80
- id: tile_six
type: Block
style:
height: 80

View File

@ -0,0 +1,124 @@
- id: basic kanban
type: Box
areas:
content:
style:
flexWrap: nowrap
overflow: scroll
height: 300
blocks:
- id: list_0
type: Box
layout:
flex: 0 0 400px
blocks:
- id: item_0_1
type: Block
style:
height: 50
- id: item_0_2
type: Block
style:
height: 50
- id: item_0_3
type: Block
style:
height: 50
- id: item_0_4
type: Block
style:
height: 50
- id: list_1
type: Box
layout:
flex: 0 0 200px
blocks:
- id: item_1_1
type: Block
style:
height: 50
- id: item_1_4
type: Block
style:
height: 50
- id: list_2
type: Box
layout:
flex: 0 0 400px
blocks:
- id: item_2_1
type: Block
style:
height: 50
- id: item_2_2
type: Block
style:
height: 50
- id: item_2_3
type: Block
style:
height: 50
- id: list_3
type: Box
layout:
flex: 0 0 400px
blocks:
- id: item_3_1
type: Block
style:
height: 150
- id: item_3_2
type: Block
style:
height: 50
- id: item_3_3
type: Block
style:
height: 250
- id: item_3_4
type: Block
style:
height: 50
- id: list_4
type: Box
layout:
flex: 0 0 400px
blocks:
- id: item_4_1
type: Block
style:
height: 50
- id: list_5
type: Box
layout:
flex: 0 0 400px
blocks:
- id: item_5_0
type: Block
style:
height: 50
- id: item_5_1
type: Block
style:
height: 50
- id: list_6
type: Box
layout:
flex: 0 0 400px
blocks:
- id: item_6_0
type: Block
style:
height: 50
- id: item_6_1
type: Block
style:
height: 50
- id: item_6_2
type: Block
style:
height: 50
- id: item_6_3
type: Block
style:
height: 50

View File

@ -0,0 +1,757 @@
- id: 'align top'
type: 'Box'
areas:
content:
align: top
style:
height: 200
blocks:
- id: One
type: Paragraph
layout:
span: 10
style:
background: '#40a0FF'
properties:
content: |
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
- id: Two
type: Paragraph
layout:
span: 10
style:
background: '#FF4FaF'
properties:
content: |
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
- id: 'align middle'
type: 'Box'
areas:
content:
align: middle
style:
height: 200
blocks:
- id: One
type: Paragraph
layout:
span: 10
style:
background: '#40a0FF'
properties:
content: |
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
- id: Two
type: Paragraph
layout:
span: 10
style:
background: '#FF4FaF'
properties:
content: |
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
- id: 'align bottom'
type: 'Box'
areas:
content:
align: bottom
style:
height: 200
blocks:
- id: One
type: Paragraph
layout:
span: 10
style:
background: '#40a0FF'
properties:
content: |
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
- id: Two
type: Paragraph
layout:
span: 10
style:
background: '#FF4FaF'
properties:
content: |
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
- id: 'align top wrap behavior'
type: 'Box'
areas:
content:
align: top
style:
height: 200
blocks:
- id: One
type: Paragraph
style:
background: '#40a0FF'
properties:
content: |
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
- id: Two
type: Paragraph
style:
background: '#FF4FaF'
properties:
content: |
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
- id: 'align middle wrap behavior'
type: 'Box'
areas:
content:
align: middle
style:
height: 200
blocks:
- id: One
type: Paragraph
style:
background: '#40a0FF'
properties:
content: |
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
- id: Two
type: Paragraph
style:
background: '#FF4FaF'
properties:
content: |
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
- id: 'align bottom wrap behavior'
type: 'Box'
areas:
content:
align: bottom
style:
height: 200
blocks:
- id: One
type: Paragraph
style:
background: '#40a0FF'
properties:
content: |
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
- id: Two
type: Paragraph
style:
background: '#FF4FaF'
properties:
content: |
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
- id: 'gutter as integer'
type: 'Box'
areas:
content:
gutter: 30
blocks:
- id: One
type: Paragraph
layout:
span: 12
style:
'& > *':
background: '#40a0FF'
properties:
content: |
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
- id: Two
type: Paragraph
layout:
span: 12
style:
'& > *':
background: '#FF4FaF'
properties:
content: |
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
- id: Three
type: Paragraph
layout:
span: 10
style:
'& > *':
background: '#FF4FaF'
properties:
content: |
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
- id: Four
type: Paragraph
layout:
span: 10
style:
'& > *':
background: '#40a0FF'
properties:
content: |
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
- id: 'gutter for col and row'
type: 'Box'
areas:
content:
gutter: [50, 20]
blocks:
- id: One
type: Paragraph
layout:
span: 12
style:
background: '#40a0FF'
properties:
content: |
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
- id: Two
type: Paragraph
layout:
span: 12
style:
background: '#FF4FaF'
properties:
content: |
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
- id: Three
type: Paragraph
layout:
span: 10
style:
background: '#FF4FaF'
properties:
content: |
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
- id: Four
type: Paragraph
layout:
span: 10
style:
background: '#40a0FF'
properties:
content: |
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
- id: 'gutter is object'
type: 'Box'
areas:
content:
gutter: { sm: 15, md: 30, lg: 60 }
blocks:
- id: One
type: Paragraph
layout:
span: 12
style:
background: '#40a0FF'
properties:
content: |
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
- id: Two
type: Paragraph
layout:
span: 12
style:
background: '#FF4FaF'
properties:
content: |
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
- id: Three
type: Paragraph
layout:
span: 10
style:
background: '#FF4FaF'
properties:
content: |
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
- id: Four
type: Paragraph
layout:
span: 10
style:
background: '#40a0FF'
properties:
content: |
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
- id: 'justify start'
type: 'Box'
areas:
content:
justify: start
blocks:
- id: One
type: Paragraph
layout:
span: 4
style:
background: '#40a0FF'
properties:
content: |
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
- id: Two
type: Paragraph
layout:
span: 4
style:
background: '#FF4FaF'
properties:
content: |
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
- id: Three
type: Paragraph
layout:
span: 4
style:
background: '#40AA55'
properties:
content: |
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
- id: 'justify center'
type: 'Box'
areas:
content:
justify: center
blocks:
- id: One
type: Paragraph
layout:
span: 4
style:
background: '#40a0FF'
properties:
content: |
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
- id: Two
type: Paragraph
layout:
span: 4
style:
background: '#FF4FaF'
properties:
content: |
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
- id: Three
type: Paragraph
layout:
span: 4
style:
background: '#40AA55'
properties:
content: |
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
- id: 'justify end'
type: 'Box'
areas:
content:
justify: end
blocks:
- id: One
type: Paragraph
layout:
span: 4
style:
background: '#40a0FF'
properties:
content: |
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
- id: Two
type: Paragraph
layout:
span: 4
style:
background: '#FF4FaF'
properties:
content: |
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
- id: Three
type: Paragraph
layout:
span: 4
style:
background: '#40AA55'
properties:
content: |
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
- id: 'justify space-between'
type: 'Box'
areas:
content:
justify: space-between
blocks:
- id: One
type: Paragraph
layout:
span: 4
style:
background: '#40a0FF'
properties:
content: |
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
- id: Two
type: Paragraph
layout:
span: 4
style:
background: '#FF4FaF'
properties:
content: |
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
- id: Three
type: Paragraph
layout:
span: 4
style:
background: '#40AA55'
properties:
content: |
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
- id: 'justify space-around'
type: 'Box'
areas:
content:
justify: space-around
blocks:
- id: One
type: Paragraph
layout:
span: 4
style:
background: '#40a0FF'
properties:
content: |
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
- id: Two
type: Paragraph
layout:
span: 4
style:
background: '#FF4FaF'
properties:
content: |
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
- id: Three
type: Paragraph
layout:
span: 4
style:
background: '#40AA55'
properties:
content: |
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
- id: 'direction row'
type: 'Box'
areas:
content:
direction: row
blocks:
- id: One
type: Paragraph
layout:
span: 4
style:
background: '#40a0FF'
properties:
content: |
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
- id: Two
type: Paragraph
layout:
span: 4
style:
background: '#FF4FaF'
properties:
content: |
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
- id: Three
type: Paragraph
layout:
span: 4
style:
background: '#40AA55'
properties:
content: |
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
- id: 'direction row-reverse'
type: 'Box'
areas:
content:
direction: row-reverse
blocks:
- id: One
type: Paragraph
layout:
span: 4
style:
background: '#40a0FF'
properties:
content: |
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
- id: Two
type: Paragraph
layout:
span: 4
style:
background: '#FF4FaF'
properties:
content: |
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
- id: Three
type: Paragraph
layout:
span: 4
style:
background: '#40AA55'
properties:
content: |
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
- id: 'direction column'
type: 'Box'
areas:
content:
direction: column
blocks:
- id: One
type: Paragraph
layout:
span: 8
style:
background: '#40a0FF'
properties:
content: |
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
- id: Two
type: Paragraph
layout:
span: 8
style:
background: '#FF4FaF'
properties:
content: |
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
- id: Three
type: Paragraph
layout:
span: 8
style:
background: '#40AA55'
properties:
content: |
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
- id: 'direction column-reverse'
type: 'Box'
areas:
content:
direction: column-reverse
blocks:
- id: One
type: Paragraph
layout:
span: 8
style:
background: '#40a0FF'
properties:
content: |
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
- id: Two
type: Paragraph
layout:
span: 8
style:
background: '#FF4FaF'
properties:
content: |
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
- id: Three
type: Paragraph
layout:
span: 8
style:
background: '#40AA55'
properties:
content: |
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
- id: 'wrap nowrap'
type: 'Box'
areas:
content:
wrap: nowrap
blocks:
- id: One
type: Paragraph
layout:
span: 10
style:
background: '#40a0FF'
properties:
content: |
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
- id: Two
type: Paragraph
layout:
span: 10
style:
background: '#FF4FaF'
properties:
content: |
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
- id: Three
type: Paragraph
layout:
span: 10
style:
background: '#40AA55'
properties:
content: |
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
- id: 'wrap wrap-reverse'
type: 'Box'
areas:
content:
wrap: wrap-reverse
blocks:
- id: One
type: Paragraph
layout:
span: 12
style:
background: '#40a0FF'
properties:
content: |
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
- id: Two
type: Paragraph
layout:
span: 8
style:
background: '#FF4FaF'
properties:
content: |
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
- id: Three
type: Paragraph
layout:
span: 15
style:
background: '#40AA55'
properties:
content: |
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
- id: 'overflow visible'
type: 'Box'
areas:
content:
wrap: nowrap
overflow: visible
blocks:
- id: One
type: Paragraph
layout:
span: 12
style:
background: '#40a0FF'
properties:
content: |
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
- id: Two
type: Paragraph
layout:
span: 8
style:
background: '#FF4FaF'
properties:
content: |
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
- id: Three
type: Paragraph
layout:
span: 15
style:
background: '#40AA55'
properties:
content: |
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
- id: 'overflow hidden'
type: 'Box'
areas:
content:
wrap: nowrap
overflow: hidden
blocks:
- id: One
type: Paragraph
layout:
span: 12
style:
background: '#40a0FF'
properties:
content: |
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
- id: Two
type: Paragraph
layout:
span: 8
style:
background: '#FF4FaF'
properties:
content: |
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
- id: Three
type: Paragraph
layout:
span: 15
style:
background: '#40AA55'
properties:
content: |
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
- id: 'overflow scroll'
type: 'Box'
areas:
content:
wrap: nowrap
overflow: scroll
blocks:
- id: One
type: Paragraph
layout:
span: 12
style:
background: '#40a0FF'
properties:
content: |
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
- id: Two
type: Paragraph
layout:
span: 8
style:
background: '#FF4FaF'
properties:
content: |
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
- id: Three
type: Paragraph
layout:
span: 15
style:
background: '#40AA55'
properties:
content: |
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo

View File

@ -0,0 +1,32 @@
import React from 'react';
import { render } from 'react-dom';
import AutoBlockSim from './AutoBlockSim';
import examples from './examples';
import { makeCss } from '../src';
// eslint-disable-next-line camelcase
const state = {
a: null,
b: null,
};
// eslint-disable-next-line no-undef
const documentCtx = document;
const Demo = () => (
<div id="page">
<div id="emotion" />
<AutoBlockSim
block={examples}
state={state}
areaKey="content"
makeCss={makeCss}
highlightBorders
/>
</div>
);
export default Demo;
render(<Demo />, documentCtx.querySelector('#root'));

View File

@ -0,0 +1,9 @@
{
"moduleFileExtensions": ["js", "json", "jsx", "ts", "tsx", "node", "yaml", "css"],
"transform": {
"\\.yaml$": "yaml-jest",
"\\.js?$": "babel-jest",
"\\.css$": "<rootDir>/tests/proxy.js"
},
"collectCoverageFrom": ["src/**/*.{js,jsx}", "!demo/*"]
}

View File

@ -0,0 +1,85 @@
{
"name": "@lowdefy/layout",
"version": "1.0.0",
"licence": "Apache-2.0",
"description": "",
"homepage": "https://lowdefy.com",
"bugs": {
"url": "https://github.com/lowdefy/lowdefy/issues"
},
"contributors": [
{
"name": "Sam Tolmay",
"url": "https://github.com/SamTolmay"
},
{
"name": "Gerrie van Wyk",
"url": "https://github.com/Gervwyk"
}
],
"repository": {
"type": "git",
"url": "https://github.com/lowdefy/lowdefy.git"
},
"main": "dist/index.js",
"files": [
"dist/*"
],
"scripts": {
"start": "webpack-dev-server",
"build": "babel src --out-dir dist",
"test": "jest --coverage --config jest.config.json --no-cache",
"prepare": "yarn build",
"prepublishOnly": "yarn build"
},
"dependencies": {
"@emotion/core": "10.0.35",
"@emotion/styled": "10.0.27",
"@lowdefy/delete": "1.0.0",
"@lowdefy/get": "1.0.0",
"@lowdefy/helpers": "1.0.0",
"@lowdefy/set": "1.0.0",
"@lowdefy/type": "1.0.0",
"antd": "4.4.2",
"classnames": "2.2.6",
"create-emotion": "10.0.27"
},
"devDependencies": {
"@babel/cli": "7.11.6",
"@babel/core": "7.11.6",
"@babel/preset-env": "7.11.5",
"@babel/preset-react": "7.10.4",
"babel-jest": "26.5.2",
"babel-loader": "8.1.0",
"babel-plugin-import": "1.13.0",
"buffer": "5.6.0",
"css-loader": "4.3.0",
"eslint": "6.8.0",
"eslint-config-airbnb": "18.2.0",
"eslint-config-prettier": "6.12.0",
"eslint-plugin-import": "2.22.1",
"eslint-plugin-jsx-a11y": "6.3.1",
"eslint-plugin-prettier": "3.1.4",
"eslint-plugin-react": "7.21.2",
"eslint-plugin-react-hooks": "4.1.2",
"html-webpack-plugin": "4.5.0",
"identity-obj-proxy": "3.0.0",
"jest": "26.5.2",
"js-yaml": "3.14.0",
"less": "3.12.2",
"less-loader": "7.0.1",
"path-browserify": "1.0.1",
"prettier": "2.1.2",
"react": "17.0.0-rc.2",
"react-dom": "17.0.0-rc.2",
"react-markdown": "4.3.1",
"react-syntax-highlight": "15.3.1",
"react-test-renderer": "17.0.0-rc.2",
"style-loader": "1.3.0",
"webpack": "5.0.0-rc.3",
"webpack-cli": "3.3.12",
"webpack-dev-server": "3.11.0",
"yaml-jest": "1.0.5",
"yaml-loader": "0.6.0"
}
}

View File

@ -0,0 +1,6 @@
<html>
<head> </head>
<body>
<div id="root"></div>
</body>
</html>

View File

@ -0,0 +1,24 @@
import React from 'react';
import { Row } from 'antd';
import gutterSetup from './gutterSetup.js';
const Area = ({ area, areaStyle, children, highlightBorders, id, makeCss }) => (
<Row
id={id}
align={area.align}
className={makeCss(areaStyle)}
gutter={gutterSetup(area.gutter)}
justify={area.justify}
style={{
// antd keeps bottom margin which can cause overflow issues.
flexDirection: area.direction,
flexWrap: area.wrap,
overflow: area.overflow,
border: highlightBorders && '1px dashed red',
}}
>
{children}
</Row>
);
export default Area;

View File

@ -0,0 +1,41 @@
import React from 'react';
import { Col } from 'antd';
import deriveLayout from './deriveLayout.js';
const alignSelf = (align) => {
if (align === 'bottom') {
return 'flex-end';
}
if (align === 'top') {
return 'flex-start';
}
if (align === 'middle') {
return 'center';
}
return align;
};
const BlockLayout = ({ id, blockStyle, children, highlightBorders, layout, makeCss }) => {
if (layout && layout.disabled) {
return (
<div id={id} className={makeCss(blockStyle)}>
{children}
</div>
);
}
return (
<Col
{...deriveLayout(layout)}
style={{
alignSelf: alignSelf(layout.align),
border: highlightBorders && '1px dashed #8eccf5',
}}
id={id}
className={makeCss(blockStyle)}
>
{children}
</Col>
);
};
export default BlockLayout;

View File

@ -0,0 +1,113 @@
import type from '@lowdefy/type';
const sanitizeGrow = (value) => {
if (value === 'unset' || value === 'inherit' || value === 'initial') {
return value;
}
if (type.isNumber(value) && value >= 0) {
return value;
}
if (value === true) {
return 1;
}
if (value === false) {
return 0;
}
return 0;
};
const sanitizeShrink = (value) => {
if (value === 'unset' || value === 'inherit' || value === 'initial') {
return value;
}
if (type.isNumber(value) && value >= 0) {
return value;
}
if (value === true) {
return 1;
}
if (value === false) {
return 0;
}
return 1;
};
const sanitizeSize = (value) => {
if (type.isNumber(value)) {
return `${value}px`;
}
if (type.isString(value)) {
return value;
}
return 'auto';
};
const deriveFlex = ({ flex, grow, shrink, size }) => {
if (type.isNone(flex) && type.isNone(grow) && type.isNone(shrink) && type.isNone(size)) {
return false;
}
if (flex) {
return flex === true ? '0 1 auto' : flex;
}
return `${sanitizeGrow(grow)} ${sanitizeShrink(shrink)} ${sanitizeSize(size)}`;
};
const diffOffsetAndSpan = (obj) => {
if (obj.offset && !obj.span) {
obj.span = 24 - obj.offset;
return obj;
}
if (!obj.span) {
obj.span = 24;
}
return obj;
};
const deriveLayout = ({
flex,
offset,
order,
pull,
push,
span,
grow,
shrink,
size,
xs,
sm,
md,
lg,
xl,
xxl,
}) => {
let colProps = {
xs: { span: 24 },
sm: { span: 24 },
md: diffOffsetAndSpan({ offset, order, pull, push, span }),
};
const flexValue = deriveFlex({ flex, grow, shrink, size });
if (flexValue) {
colProps = { flex: flexValue, order };
}
if (type.isObject(sm)) {
colProps.sm = { ...colProps.sm, ...diffOffsetAndSpan(sm) };
colProps.xs = { ...colProps.xs, ...diffOffsetAndSpan(sm) };
}
if (type.isObject(xs)) {
colProps.xs = { ...colProps.xs, ...diffOffsetAndSpan(xs) };
}
if (type.isObject(md)) {
colProps.md = { ...colProps.md, ...diffOffsetAndSpan(md) };
}
if (type.isObject(lg)) {
colProps.lg = diffOffsetAndSpan(lg);
}
if (type.isObject(xl)) {
colProps.xl = diffOffsetAndSpan(xl);
}
if (type.isObject(xxl)) {
colProps.xxl = diffOffsetAndSpan(xxl);
}
return colProps;
};
export default deriveLayout;

View File

@ -0,0 +1,33 @@
const getLabelCol = (value, inline) => {
if (inline) {
return { flex: '0 1 auto' };
}
const defaultVal = {
xs: { span: 24 },
sm: { span: 24 },
};
if (value.span) {
defaultVal.md = { span: value.span };
}
if (value.sm) {
defaultVal.sm = value.sm;
defaultVal.xs = value.sm;
}
if (value.xs) {
defaultVal.xs = value.xs;
}
if (value.md) {
defaultVal.md = value.md;
}
if (value.lg) {
defaultVal.lg = value.lg;
}
if (value.xl) {
defaultVal.xl = value.xl;
}
if (value.xxl) {
defaultVal.xxl = value.xxl;
}
return defaultVal;
};
export default getLabelCol;

View File

@ -0,0 +1,33 @@
const getWrapperCol = (value, inline) => {
if (inline) {
return { flex: '1 1 auto' };
}
const defaultVal = {
xs: { span: 24 },
sm: { span: 24 },
};
if (value.span) {
defaultVal.md = { span: 24 - value.span };
}
if (value.sm && value.sm.span) {
defaultVal.sm = { span: 24 - value.sm.span };
defaultVal.xs = { span: 24 - value.sm.span };
}
if (value.xs && value.xs.span) {
defaultVal.xs = { span: 24 - value.xs.span };
}
if (value.md && value.md.span) {
defaultVal.md = { span: 24 - value.md.span };
}
if (value.lg && value.lg.span) {
defaultVal.lg = { span: 24 - value.lg.span };
}
if (value.xl && value.xl.span) {
defaultVal.xl = { span: 24 - value.xl.span };
}
if (value.xxl && value.xxl.span) {
defaultVal.xxl = { span: 24 - value.xxl.span };
}
return defaultVal;
};
export default getWrapperCol;

View File

@ -0,0 +1,10 @@
import type from '@lowdefy/type';
const gutterSetup = (gutter) => {
if (type.isInt(gutter) || type.isObject(gutter)) {
return [gutter, gutter];
}
return gutter;
};
export default gutterSetup;

View File

@ -0,0 +1,8 @@
import Area from './Area.js';
import BlockLayout from './BlockLayout.js';
import labelLogic from './labelLogic.js';
import layoutParamsToArea from './layoutParamsToArea.js';
import makeCss from './makeCss.js';
import mediaToCssObject from './mediaToCssObject.js';
export { Area, BlockLayout, labelLogic, layoutParamsToArea, makeCss, mediaToCssObject };

View File

@ -0,0 +1,87 @@
import get from '@lowdefy/get';
import type from '@lowdefy/type';
import classNames from 'classnames';
import getWrapperCol from './getWrapperCol.js';
import getLabelCol from './getLabelCol.js';
const labelLogic = ({
blockId,
content,
methods,
properties = {},
required = false,
validate = [],
validated = false,
}) => {
const wrapperCol = getWrapperCol(properties, properties.inline);
const labelCol = getLabelCol(properties, properties.inline);
const validateStatus =
validated && validate.length === 0
? 'success'
: validate.length !== 0 && !get({ v: validate }, 'v.0.status')
? 'error'
: validate.length !== 0 &&
get({ v: validate }, 'v.0.status') &&
get({ v: validate }, 'v.0.status') !== 'info'
? get({ v: validate }, 'v.0.status')
: null;
// render label priority order: content.label area -> properties.title -> blockId and do not render an empty label
let label = content.label
? content.label()
: !type.isString(properties.title)
? blockId
: properties.title;
label = label === '' ? null : label;
// trim colon when colon is set, and the user inputs a colon, because antd class renders a colon
if (label && properties.colon && label.trim() !== '') {
label = label.replace(/[:|]\s*$/, '');
}
const rowClassName = classNames({
[`ant-form-item`]: true,
[`ant-form-item-with-help`]: false,
// Status
[`ant-form-item-has-feedback`]: validateStatus && properties.hasFeedback !== false,
[`ant-form-item-has-success`]: validateStatus === 'success',
[`ant-form-item-has-warning`]: validateStatus === 'warning',
[`ant-form-item-has-error`]: validateStatus === 'error',
[`ant-form-item-is-validating`]: validateStatus === 'validating',
[methods.makeCss({
flexWrap: properties.inline && 'inherit', // wrap extra content below input
})]: true,
});
const labelColClassName = classNames(
`ant-form-item-label`,
(properties.align === 'left' || !properties.align) && `ant-form-item-label-left` // default align left
);
const labelClassName = classNames({
[`ant-form-item-required`]: required,
[`ant-form-item-no-colon`]: properties.colon === false,
[methods.makeCss(properties.style)]: true,
});
const extraClassName = classNames(
'ant-form-item-extra',
methods.makeCss([
{
marginTop: properties.size === 'small' ? -4 : 0, // in size small reduce extra top margin
},
properties.extraStyle,
])
);
return {
extraClassName,
label: !properties.disabled && label,
labelClassName,
labelCol,
labelColClassName,
rowClassName,
validateStatus: properties.hasFeedback !== false && validateStatus,
wrapperCol,
};
};
export default labelLogic;

View File

@ -0,0 +1,16 @@
import type from '@lowdefy/type';
const layoutParamsToArea = ({ areaKey, area, layout }) => {
if (areaKey !== 'content') {
return area;
}
area.align = type.isNone(area.align) ? layout.contentAlign : area.align;
area.justify = type.isNone(area.justify) ? layout.contentJustify : area.justify;
area.direction = type.isNone(area.direction) ? layout.contentDirection : area.direction;
area.wrap = type.isNone(area.wrap) ? layout.contentWrap : area.wrap;
area.overflow = type.isNone(area.overflow) ? layout.contentOverflow : area.overflow;
area.gutter = type.isNone(area.gutter) ? layout.contentGutter : area.gutter;
return area;
};
export default layoutParamsToArea;

View File

@ -0,0 +1,14 @@
import createEmotion from 'create-emotion';
import { mergeObjects } from '@lowdefy/helpers';
import mediaToCssObject from './mediaToCssObject.js';
export const { css, injectGlobal } = createEmotion({
container: document.getElementById('emotion'),
});
const makeCss = (styles, options = {}) =>
options.styleObjectOnly
? mediaToCssObject(mergeObjects(styles), options)
: css(mediaToCssObject(mergeObjects(styles), options));
export default makeCss;

View File

@ -0,0 +1,81 @@
/* eslint-disable no-undef */
export const breakpoints = [576, 768, 992, 1200, 1600];
export const mq = [
{
name: 'xs',
breakpoints: breakpoints[0],
media: `@media screen and (max-width: ${breakpoints[0]}px)`,
mediaReact: `@media screen and (maxWidth: ${breakpoints[0]}px)`,
},
{
name: 'sm',
breakpoints: breakpoints[0],
media: `@media screen and (min-width: ${breakpoints[0]}px)`,
mediaReact: `@media screen and (minWidth: ${breakpoints[0]}px)`,
},
{
name: 'md',
breakpoints: breakpoints[1],
media: `@media screen and (min-width: ${breakpoints[1]}px)`,
mediaReact: `@media screen and (minWidth: ${breakpoints[1]}px)`,
},
{
name: 'lg',
breakpoints: breakpoints[2],
media: `@media screen and (min-width: ${breakpoints[2]}px)`,
mediaReact: `@media screen and (minWidth: ${breakpoints[2]}px)`,
},
{
name: 'xl',
breakpoints: breakpoints[3],
media: `@media screen and (min-width: ${breakpoints[3]}px)`,
mediaReact: `@media screen and (minWidth: ${breakpoints[3]}px)`,
},
{
name: 'xxl',
breakpoints: breakpoints[4],
media: `@media screen and (min-width: ${breakpoints[4]}px)`,
mediaReact: `@media screen and (minWidth: ${breakpoints[4]}px)`,
},
];
const mediaToCssObject = (obj = {}, options = {}) => {
// ES2015 key order matters.
const result = [];
const media = options.react ? 'mediaReact' : 'media';
Object.keys(obj).forEach((key) => {
switch (key) {
case 'xs':
result.push({ key: mq[0][media], value: obj.xs });
break;
case 'sm':
result.push({ key: mq[0][media], value: obj.sm });
break;
case 'md':
result.push({ key: mq[1][media], value: obj.md });
break;
case 'lg':
result.push({ key: mq[2][media], value: obj.lg });
break;
case 'xl':
result.push({ key: mq[3][media], value: obj.xl });
break;
case 'xxl':
result.push({ key: mq[4][media], value: obj.xxl });
break;
default:
result.push({ key, value: obj[key] });
break;
}
});
result.reverse();
const value = {};
result.forEach((item) => {
value[item.key] = item.value;
});
return value;
};
export default mediaToCssObject;

View File

@ -0,0 +1,174 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`Button 1`] = `
<div
className="ant-col {} ant-col-xs-24 ant-col-sm-24 ant-col-md-24"
id="bl-Button"
style={
Object {
"alignSelf": undefined,
"border": "1px dashed #8eccf5",
}
}
>
<button
className="ant-btn"
id="Button"
onClick={[Function]}
type="button"
>
<span>
Button
</span>
</button>
</div>
`;
exports[`Disabled Col 1`] = `
<div
className="{}"
id="bl-Disabled Col"
>
<input
blockId="Disabled Col"
className="ant-input"
makeCss={
[MockFunction] {
"calls": Array [
Array [
undefined,
],
],
"results": Array [
Object {
"type": "return",
"value": "{}",
},
],
}
}
onBlur={[Function]}
onChange={[Function]}
onFocus={[Function]}
onKeyDown={[Function]}
type="text"
value=""
/>
</div>
`;
exports[`Input 1`] = `
<div
className="ant-col {} ant-col-xs-24 ant-col-sm-24 ant-col-md-24"
id="bl-Input"
style={
Object {
"alignSelf": undefined,
"border": "1px dashed #8eccf5",
}
}
>
<input
blockId="Input"
className="ant-input"
makeCss={
[MockFunction] {
"calls": Array [
Array [
undefined,
],
],
"results": Array [
Object {
"type": "return",
"value": "{}",
},
],
}
}
onBlur={[Function]}
onChange={[Function]}
onFocus={[Function]}
onKeyDown={[Function]}
type="text"
value=""
/>
</div>
`;
exports[`Input 2`] = `
<div
className="ant-col {} ant-col-xs-24 ant-col-sm-24 ant-col-md-4"
id="bl-Input"
style={
Object {
"alignSelf": undefined,
"border": "1px dashed #8eccf5",
}
}
>
<input
blockId="Input"
className="ant-input"
makeCss={
[MockFunction] {
"calls": Array [
Array [
undefined,
],
],
"results": Array [
Object {
"type": "return",
"value": "{}",
},
],
}
}
onBlur={[Function]}
onChange={[Function]}
onFocus={[Function]}
onKeyDown={[Function]}
type="text"
value=""
/>
</div>
`;
exports[`Paragraph span: 12 1`] = `
<div
className="ant-col {} ant-col-xs-24 ant-col-sm-24 ant-col-md-12"
id="bl-Paragraph span: 12"
style={
Object {
"alignSelf": undefined,
"border": "1px dashed #8eccf5",
}
}
>
<div
id="Paragraph span: 12"
>
Loem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
</div>
</div>
`;
exports[`Paragraph style 1`] = `
<div
className="ant-col {\\"style\\":{\\"background\\":\\"white\\",\\"borderRadius\\":20}} ant-col-xs-24 ant-col-sm-24 ant-col-md-24"
id="bl-Paragraph style"
style={
Object {
"alignSelf": undefined,
"border": "1px dashed #8eccf5",
}
}
>
<div
id="Paragraph style"
>
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
</div>
</div>
`;

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,733 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`2 column stacking 1`] = `
<div
className="ant-col {} ant-col-xs-24 ant-col-sm-24 ant-col-md-24"
id="bl-2 column stacking"
style={
Object {
"alignSelf": undefined,
"border": "1px dashed #8eccf5",
}
}
>
<div
id="2 column stacking"
>
<div
className="ant-row {\\"style\\":[null,null]}"
id="2 column stacking-content"
style={
Object {
"border": "1px dashed red",
"flexDirection": undefined,
"flexWrap": undefined,
"overflow": undefined,
}
}
>
<div
className="ant-col {} ant-col-xs-24 ant-col-sm-24 ant-col-md-6"
id="bl-b1"
style={
Object {
"alignSelf": undefined,
"border": "1px dashed #8eccf5",
}
}
>
<div
id="b1"
>
<div
className="ant-row {\\"style\\":[null,null]}"
id="b1-content"
style={
Object {
"border": "1px dashed red",
"flexDirection": undefined,
"flexWrap": undefined,
"overflow": undefined,
}
}
>
<div
className="ant-col {\\"style\\":{\\"height\\":80}} ant-col-xs-24 ant-col-sm-24 ant-col-md-24"
id="bl-tile_one"
style={
Object {
"alignSelf": undefined,
"border": "1px dashed #8eccf5",
}
}
>
<div
className="{\\"style\\":[{\\"background\\":\\"#269\\",\\"border\\":\\"2px solid #00aaee\\",\\"textAlign\\":\\"center\\",\\"fontSize\\":12,\\"color\\":\\"#fff\\"}]}"
id="tile_one"
>
tile_one
</div>
</div>
</div>
</div>
</div>
<div
className="ant-col {} ant-col-xs-24 ant-col-sm-24 ant-col-md-18"
id="bl-b2"
style={
Object {
"alignSelf": undefined,
"border": "1px dashed #8eccf5",
}
}
>
<div
id="b2"
>
<div
className="ant-row {\\"style\\":[null,null]}"
id="b2-content"
style={
Object {
"border": "1px dashed red",
"flexDirection": undefined,
"flexWrap": undefined,
"overflow": undefined,
}
}
>
<div
className="ant-col {\\"style\\":{\\"height\\":40}} ant-col-xs-24 ant-col-sm-24 ant-col-md-24"
id="bl-tile_two"
style={
Object {
"alignSelf": undefined,
"border": "1px dashed #8eccf5",
}
}
>
<div
className="{\\"style\\":[{\\"background\\":\\"#269\\",\\"border\\":\\"2px solid #00aaee\\",\\"textAlign\\":\\"center\\",\\"fontSize\\":12,\\"color\\":\\"#fff\\"}]}"
id="tile_two"
>
tile_two
</div>
</div>
<div
className="ant-col {\\"style\\":{\\"height\\":20}} ant-col-xs-24 ant-col-sm-24 ant-col-md-12"
id="bl-tile_three"
style={
Object {
"alignSelf": undefined,
"border": "1px dashed #8eccf5",
}
}
>
<div
className="{\\"style\\":[{\\"background\\":\\"#269\\",\\"border\\":\\"2px solid #00aaee\\",\\"textAlign\\":\\"center\\",\\"fontSize\\":12,\\"color\\":\\"#fff\\"}]}"
id="tile_three"
>
tile_three
</div>
</div>
<div
className="ant-col {\\"style\\":{\\"height\\":30}} ant-col-xs-24 ant-col-sm-24 ant-col-md-12"
id="bl-tile_four"
style={
Object {
"alignSelf": undefined,
"border": "1px dashed #8eccf5",
}
}
>
<div
className="{\\"style\\":[{\\"background\\":\\"#269\\",\\"border\\":\\"2px solid #00aaee\\",\\"textAlign\\":\\"center\\",\\"fontSize\\":12,\\"color\\":\\"#fff\\"}]}"
id="tile_four"
>
tile_four
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
`;
exports[`4 block grid 1`] = `
<div
className="ant-col {} ant-col-xs-24 ant-col-sm-24 ant-col-md-24"
id="bl-4 block grid"
style={
Object {
"alignSelf": undefined,
"border": "1px dashed #8eccf5",
}
}
>
<div
id="4 block grid"
>
<div
className="ant-row {\\"style\\":[null,null]}"
id="4 block grid-content"
style={
Object {
"border": "1px dashed red",
"flexDirection": undefined,
"flexWrap": undefined,
"overflow": undefined,
}
}
>
<div
className="ant-col {} ant-col-xs-24 ant-col-sm-24 ant-col-md-12"
id="bl-tile_one"
style={
Object {
"alignSelf": undefined,
"border": "1px dashed #8eccf5",
}
}
>
<div
className="{\\"style\\":[{\\"background\\":\\"#269\\",\\"border\\":\\"2px solid #00aaee\\",\\"textAlign\\":\\"center\\",\\"fontSize\\":12,\\"color\\":\\"#fff\\"}]}"
id="tile_one"
>
tile_one
</div>
</div>
<div
className="ant-col {} ant-col-xs-24 ant-col-sm-24 ant-col-md-12"
id="bl-tile_two"
style={
Object {
"alignSelf": undefined,
"border": "1px dashed #8eccf5",
}
}
>
<div
className="{\\"style\\":[{\\"background\\":\\"#269\\",\\"border\\":\\"2px solid #00aaee\\",\\"textAlign\\":\\"center\\",\\"fontSize\\":12,\\"color\\":\\"#fff\\"}]}"
id="tile_two"
>
tile_two
</div>
</div>
<div
className="ant-col {} ant-col-xs-24 ant-col-sm-24 ant-col-md-12"
id="bl-tile_three"
style={
Object {
"alignSelf": undefined,
"border": "1px dashed #8eccf5",
}
}
>
<div
className="{\\"style\\":[{\\"background\\":\\"#269\\",\\"border\\":\\"2px solid #00aaee\\",\\"textAlign\\":\\"center\\",\\"fontSize\\":12,\\"color\\":\\"#fff\\"}]}"
id="tile_three"
>
tile_three
</div>
</div>
<div
className="ant-col {} ant-col-xs-24 ant-col-sm-24 ant-col-md-12"
id="bl-tile_four"
style={
Object {
"alignSelf": undefined,
"border": "1px dashed #8eccf5",
}
}
>
<div
className="{\\"style\\":[{\\"background\\":\\"#269\\",\\"border\\":\\"2px solid #00aaee\\",\\"textAlign\\":\\"center\\",\\"fontSize\\":12,\\"color\\":\\"#fff\\"}]}"
id="tile_four"
>
tile_four
</div>
</div>
</div>
</div>
</div>
`;
exports[`4 block grid with gutter 1`] = `
<div
className="ant-col {} ant-col-xs-24 ant-col-sm-24 ant-col-md-24"
id="bl-4 block grid with gutter"
style={
Object {
"alignSelf": undefined,
"border": "1px dashed #8eccf5",
}
}
>
<div
id="4 block grid with gutter"
>
<div
className="ant-row {\\"style\\":[null,null]}"
id="4 block grid with gutter-content"
style={
Object {
"border": "1px dashed red",
"flexDirection": undefined,
"flexWrap": undefined,
"marginBottom": 25,
"marginLeft": -25,
"marginRight": -25,
"marginTop": -25,
"overflow": undefined,
}
}
>
<div
className="ant-col {} ant-col-xs-24 ant-col-sm-24 ant-col-md-12"
id="bl-tile_one"
style={
Object {
"alignSelf": undefined,
"border": "1px dashed #8eccf5",
"paddingBottom": 25,
"paddingLeft": 25,
"paddingRight": 25,
"paddingTop": 25,
}
}
>
<div
className="{\\"style\\":[{\\"background\\":\\"#269\\",\\"border\\":\\"2px solid #00aaee\\",\\"textAlign\\":\\"center\\",\\"fontSize\\":12,\\"color\\":\\"#fff\\"}]}"
id="tile_one"
>
tile_one
</div>
</div>
<div
className="ant-col {} ant-col-xs-24 ant-col-sm-24 ant-col-md-12"
id="bl-tile_two"
style={
Object {
"alignSelf": undefined,
"border": "1px dashed #8eccf5",
"paddingBottom": 25,
"paddingLeft": 25,
"paddingRight": 25,
"paddingTop": 25,
}
}
>
<div
className="{\\"style\\":[{\\"background\\":\\"#269\\",\\"border\\":\\"2px solid #00aaee\\",\\"textAlign\\":\\"center\\",\\"fontSize\\":12,\\"color\\":\\"#fff\\"}]}"
id="tile_two"
>
tile_two
</div>
</div>
<div
className="ant-col {} ant-col-xs-24 ant-col-sm-24 ant-col-md-12"
id="bl-tile_three"
style={
Object {
"alignSelf": undefined,
"border": "1px dashed #8eccf5",
"paddingBottom": 25,
"paddingLeft": 25,
"paddingRight": 25,
"paddingTop": 25,
}
}
>
<div
className="{\\"style\\":[{\\"background\\":\\"#269\\",\\"border\\":\\"2px solid #00aaee\\",\\"textAlign\\":\\"center\\",\\"fontSize\\":12,\\"color\\":\\"#fff\\"}]}"
id="tile_three"
>
tile_three
</div>
</div>
<div
className="ant-col {} ant-col-xs-24 ant-col-sm-24 ant-col-md-12"
id="bl-tile_four"
style={
Object {
"alignSelf": undefined,
"border": "1px dashed #8eccf5",
"paddingBottom": 25,
"paddingLeft": 25,
"paddingRight": 25,
"paddingTop": 25,
}
}
>
<div
className="{\\"style\\":[{\\"background\\":\\"#269\\",\\"border\\":\\"2px solid #00aaee\\",\\"textAlign\\":\\"center\\",\\"fontSize\\":12,\\"color\\":\\"#fff\\"}]}"
id="tile_four"
>
tile_four
</div>
</div>
</div>
</div>
</div>
`;
exports[`4 block grid with various heights 1`] = `
<div
className="ant-col {} ant-col-xs-24 ant-col-sm-24 ant-col-md-24"
id="bl-4 block grid with various heights"
style={
Object {
"alignSelf": undefined,
"border": "1px dashed #8eccf5",
}
}
>
<div
id="4 block grid with various heights"
>
<div
className="ant-row {\\"style\\":[null,null]}"
id="4 block grid with various heights-content"
style={
Object {
"border": "1px dashed red",
"flexDirection": undefined,
"flexWrap": undefined,
"overflow": undefined,
}
}
>
<div
className="ant-col {\\"style\\":{\\"height\\":50}} ant-col-xs-24 ant-col-sm-24 ant-col-md-12"
id="bl-tile_one"
style={
Object {
"alignSelf": undefined,
"border": "1px dashed #8eccf5",
}
}
>
<div
className="{\\"style\\":[{\\"background\\":\\"#269\\",\\"border\\":\\"2px solid #00aaee\\",\\"textAlign\\":\\"center\\",\\"fontSize\\":12,\\"color\\":\\"#fff\\"}]}"
id="tile_one"
>
tile_one
</div>
</div>
<div
className="ant-col {\\"style\\":{\\"height\\":40}} ant-col-xs-24 ant-col-sm-24 ant-col-md-12"
id="bl-tile_two"
style={
Object {
"alignSelf": undefined,
"border": "1px dashed #8eccf5",
}
}
>
<div
className="{\\"style\\":[{\\"background\\":\\"#269\\",\\"border\\":\\"2px solid #00aaee\\",\\"textAlign\\":\\"center\\",\\"fontSize\\":12,\\"color\\":\\"#fff\\"}]}"
id="tile_two"
>
tile_two
</div>
</div>
<div
className="ant-col {\\"style\\":{\\"height\\":20}} ant-col-xs-24 ant-col-sm-24 ant-col-md-12"
id="bl-tile_three"
style={
Object {
"alignSelf": undefined,
"border": "1px dashed #8eccf5",
}
}
>
<div
className="{\\"style\\":[{\\"background\\":\\"#269\\",\\"border\\":\\"2px solid #00aaee\\",\\"textAlign\\":\\"center\\",\\"fontSize\\":12,\\"color\\":\\"#fff\\"}]}"
id="tile_three"
>
tile_three
</div>
</div>
<div
className="ant-col {\\"style\\":{\\"height\\":30}} ant-col-xs-24 ant-col-sm-24 ant-col-md-12"
id="bl-tile_four"
style={
Object {
"alignSelf": undefined,
"border": "1px dashed #8eccf5",
}
}
>
<div
className="{\\"style\\":[{\\"background\\":\\"#269\\",\\"border\\":\\"2px solid #00aaee\\",\\"textAlign\\":\\"center\\",\\"fontSize\\":12,\\"color\\":\\"#fff\\"}]}"
id="tile_four"
>
tile_four
</div>
</div>
</div>
</div>
</div>
`;
exports[`4 sequential blocks 1`] = `
<div
className="ant-col {} ant-col-xs-24 ant-col-sm-24 ant-col-md-24"
id="bl-4 sequential blocks"
style={
Object {
"alignSelf": undefined,
"border": "1px dashed #8eccf5",
}
}
>
<div
id="4 sequential blocks"
>
<div
className="ant-row {\\"style\\":[null,null]}"
id="4 sequential blocks-content"
style={
Object {
"border": "1px dashed red",
"flexDirection": undefined,
"flexWrap": undefined,
"overflow": undefined,
}
}
>
<div
className="ant-col {} ant-col-xs-24 ant-col-sm-24 ant-col-md-24"
id="bl-tile_one"
style={
Object {
"alignSelf": undefined,
"border": "1px dashed #8eccf5",
}
}
>
<div
className="{\\"style\\":[{\\"background\\":\\"#269\\",\\"border\\":\\"2px solid #00aaee\\",\\"textAlign\\":\\"center\\",\\"fontSize\\":12,\\"color\\":\\"#fff\\"}]}"
id="tile_one"
>
tile_one
</div>
</div>
<div
className="ant-col {} ant-col-xs-24 ant-col-sm-24 ant-col-md-24"
id="bl-tile_two"
style={
Object {
"alignSelf": undefined,
"border": "1px dashed #8eccf5",
}
}
>
<div
className="{\\"style\\":[{\\"background\\":\\"#269\\",\\"border\\":\\"2px solid #00aaee\\",\\"textAlign\\":\\"center\\",\\"fontSize\\":12,\\"color\\":\\"#fff\\"}]}"
id="tile_two"
>
tile_two
</div>
</div>
<div
className="ant-col {} ant-col-xs-24 ant-col-sm-24 ant-col-md-24"
id="bl-tile_three"
style={
Object {
"alignSelf": undefined,
"border": "1px dashed #8eccf5",
}
}
>
<div
className="{\\"style\\":[{\\"background\\":\\"#269\\",\\"border\\":\\"2px solid #00aaee\\",\\"textAlign\\":\\"center\\",\\"fontSize\\":12,\\"color\\":\\"#fff\\"}]}"
id="tile_three"
>
tile_three
</div>
</div>
<div
className="ant-col {} ant-col-xs-24 ant-col-sm-24 ant-col-md-24"
id="bl-tile_four"
style={
Object {
"alignSelf": undefined,
"border": "1px dashed #8eccf5",
}
}
>
<div
className="{\\"style\\":[{\\"background\\":\\"#269\\",\\"border\\":\\"2px solid #00aaee\\",\\"textAlign\\":\\"center\\",\\"fontSize\\":12,\\"color\\":\\"#fff\\"}]}"
id="tile_four"
>
tile_four
</div>
</div>
</div>
</div>
</div>
`;
exports[`typical dashboard 1`] = `
<div
className="ant-col {} ant-col-xs-24 ant-col-sm-24 ant-col-md-24"
id="bl-typical dashboard"
style={
Object {
"alignSelf": undefined,
"border": "1px dashed #8eccf5",
}
}
>
<div
id="typical dashboard"
>
<div
className="ant-row {\\"style\\":[null,null]}"
id="typical dashboard-content"
style={
Object {
"border": "1px dashed red",
"flexDirection": undefined,
"flexWrap": undefined,
"marginBottom": 5,
"marginLeft": -5,
"marginRight": -5,
"marginTop": -5,
"overflow": undefined,
}
}
>
<div
className="ant-col {\\"style\\":{\\"height\\":80}} ant-col-xs-24 ant-col-sm-24 ant-col-md-8"
id="bl-tile_one"
style={
Object {
"alignSelf": undefined,
"border": "1px dashed #8eccf5",
"paddingBottom": 5,
"paddingLeft": 5,
"paddingRight": 5,
"paddingTop": 5,
}
}
>
<div
className="{\\"style\\":[{\\"background\\":\\"#269\\",\\"border\\":\\"2px solid #00aaee\\",\\"textAlign\\":\\"center\\",\\"fontSize\\":12,\\"color\\":\\"#fff\\"}]}"
id="tile_one"
>
tile_one
</div>
</div>
<div
className="ant-col {\\"style\\":{\\"height\\":80}} ant-col-xs-24 ant-col-sm-24 ant-col-md-8"
id="bl-tile_two"
style={
Object {
"alignSelf": undefined,
"border": "1px dashed #8eccf5",
"paddingBottom": 5,
"paddingLeft": 5,
"paddingRight": 5,
"paddingTop": 5,
}
}
>
<div
className="{\\"style\\":[{\\"background\\":\\"#269\\",\\"border\\":\\"2px solid #00aaee\\",\\"textAlign\\":\\"center\\",\\"fontSize\\":12,\\"color\\":\\"#fff\\"}]}"
id="tile_two"
>
tile_two
</div>
</div>
<div
className="ant-col {\\"style\\":{\\"height\\":80}} ant-col-xs-24 ant-col-sm-24 ant-col-md-8"
id="bl-tile_three"
style={
Object {
"alignSelf": undefined,
"border": "1px dashed #8eccf5",
"paddingBottom": 5,
"paddingLeft": 5,
"paddingRight": 5,
"paddingTop": 5,
}
}
>
<div
className="{\\"style\\":[{\\"background\\":\\"#269\\",\\"border\\":\\"2px solid #00aaee\\",\\"textAlign\\":\\"center\\",\\"fontSize\\":12,\\"color\\":\\"#fff\\"}]}"
id="tile_three"
>
tile_three
</div>
</div>
<div
className="ant-col {\\"style\\":{\\"height\\":80}} ant-col-xs-24 ant-col-sm-24 ant-col-md-12"
id="bl-tile_four"
style={
Object {
"alignSelf": undefined,
"border": "1px dashed #8eccf5",
"paddingBottom": 5,
"paddingLeft": 5,
"paddingRight": 5,
"paddingTop": 5,
}
}
>
<div
className="{\\"style\\":[{\\"background\\":\\"#269\\",\\"border\\":\\"2px solid #00aaee\\",\\"textAlign\\":\\"center\\",\\"fontSize\\":12,\\"color\\":\\"#fff\\"}]}"
id="tile_four"
>
tile_four
</div>
</div>
<div
className="ant-col {\\"style\\":{\\"height\\":80}} ant-col-xs-24 ant-col-sm-24 ant-col-md-12"
id="bl-tile_five"
style={
Object {
"alignSelf": undefined,
"border": "1px dashed #8eccf5",
"paddingBottom": 5,
"paddingLeft": 5,
"paddingRight": 5,
"paddingTop": 5,
}
}
>
<div
className="{\\"style\\":[{\\"background\\":\\"#269\\",\\"border\\":\\"2px solid #00aaee\\",\\"textAlign\\":\\"center\\",\\"fontSize\\":12,\\"color\\":\\"#fff\\"}]}"
id="tile_five"
>
tile_five
</div>
</div>
<div
className="ant-col {\\"style\\":{\\"height\\":80}} ant-col-xs-24 ant-col-sm-24 ant-col-md-24"
id="bl-tile_six"
style={
Object {
"alignSelf": undefined,
"border": "1px dashed #8eccf5",
"paddingBottom": 5,
"paddingLeft": 5,
"paddingRight": 5,
"paddingTop": 5,
}
}
>
<div
className="{\\"style\\":[{\\"background\\":\\"#269\\",\\"border\\":\\"2px solid #00aaee\\",\\"textAlign\\":\\"center\\",\\"fontSize\\":12,\\"color\\":\\"#fff\\"}]}"
id="tile_six"
>
tile_six
</div>
</div>
</div>
</div>
</div>
`;

View File

@ -0,0 +1,575 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`basic kanban 1`] = `
<div
className="ant-col {} ant-col-xs-24 ant-col-sm-24 ant-col-md-24"
id="bl-basic kanban"
style={
Object {
"alignSelf": undefined,
"border": "1px dashed #8eccf5",
}
}
>
<div
id="basic kanban"
>
<div
className="ant-row {\\"style\\":[null,{\\"flexWrap\\":\\"nowrap\\",\\"overflow\\":\\"scroll\\",\\"height\\":300}]}"
id="basic kanban-content"
style={
Object {
"border": "1px dashed red",
"flexDirection": undefined,
"flexWrap": undefined,
"overflow": undefined,
}
}
>
<div
className="ant-col {}"
id="bl-list_0"
style={
Object {
"alignSelf": undefined,
"border": "1px dashed #8eccf5",
"flex": "0 0 400px",
}
}
>
<div
id="list_0"
>
<div
className="ant-row {\\"style\\":[null,null]}"
id="list_0-content"
style={
Object {
"border": "1px dashed red",
"flexDirection": undefined,
"flexWrap": undefined,
"overflow": undefined,
}
}
>
<div
className="ant-col {\\"style\\":{\\"height\\":50}} ant-col-xs-24 ant-col-sm-24 ant-col-md-24"
id="bl-item_0_1"
style={
Object {
"alignSelf": undefined,
"border": "1px dashed #8eccf5",
}
}
>
<div
className="{\\"style\\":[{\\"background\\":\\"#269\\",\\"border\\":\\"2px solid #00aaee\\",\\"textAlign\\":\\"center\\",\\"fontSize\\":12,\\"color\\":\\"#fff\\"}]}"
id="item_0_1"
>
item_0_1
</div>
</div>
<div
className="ant-col {\\"style\\":{\\"height\\":50}} ant-col-xs-24 ant-col-sm-24 ant-col-md-24"
id="bl-item_0_2"
style={
Object {
"alignSelf": undefined,
"border": "1px dashed #8eccf5",
}
}
>
<div
className="{\\"style\\":[{\\"background\\":\\"#269\\",\\"border\\":\\"2px solid #00aaee\\",\\"textAlign\\":\\"center\\",\\"fontSize\\":12,\\"color\\":\\"#fff\\"}]}"
id="item_0_2"
>
item_0_2
</div>
</div>
<div
className="ant-col {\\"style\\":{\\"height\\":50}} ant-col-xs-24 ant-col-sm-24 ant-col-md-24"
id="bl-item_0_3"
style={
Object {
"alignSelf": undefined,
"border": "1px dashed #8eccf5",
}
}
>
<div
className="{\\"style\\":[{\\"background\\":\\"#269\\",\\"border\\":\\"2px solid #00aaee\\",\\"textAlign\\":\\"center\\",\\"fontSize\\":12,\\"color\\":\\"#fff\\"}]}"
id="item_0_3"
>
item_0_3
</div>
</div>
<div
className="ant-col {\\"style\\":{\\"height\\":50}} ant-col-xs-24 ant-col-sm-24 ant-col-md-24"
id="bl-item_0_4"
style={
Object {
"alignSelf": undefined,
"border": "1px dashed #8eccf5",
}
}
>
<div
className="{\\"style\\":[{\\"background\\":\\"#269\\",\\"border\\":\\"2px solid #00aaee\\",\\"textAlign\\":\\"center\\",\\"fontSize\\":12,\\"color\\":\\"#fff\\"}]}"
id="item_0_4"
>
item_0_4
</div>
</div>
</div>
</div>
</div>
<div
className="ant-col {}"
id="bl-list_1"
style={
Object {
"alignSelf": undefined,
"border": "1px dashed #8eccf5",
"flex": "0 0 200px",
}
}
>
<div
id="list_1"
>
<div
className="ant-row {\\"style\\":[null,null]}"
id="list_1-content"
style={
Object {
"border": "1px dashed red",
"flexDirection": undefined,
"flexWrap": undefined,
"overflow": undefined,
}
}
>
<div
className="ant-col {\\"style\\":{\\"height\\":50}} ant-col-xs-24 ant-col-sm-24 ant-col-md-24"
id="bl-item_1_1"
style={
Object {
"alignSelf": undefined,
"border": "1px dashed #8eccf5",
}
}
>
<div
className="{\\"style\\":[{\\"background\\":\\"#269\\",\\"border\\":\\"2px solid #00aaee\\",\\"textAlign\\":\\"center\\",\\"fontSize\\":12,\\"color\\":\\"#fff\\"}]}"
id="item_1_1"
>
item_1_1
</div>
</div>
<div
className="ant-col {\\"style\\":{\\"height\\":50}} ant-col-xs-24 ant-col-sm-24 ant-col-md-24"
id="bl-item_1_4"
style={
Object {
"alignSelf": undefined,
"border": "1px dashed #8eccf5",
}
}
>
<div
className="{\\"style\\":[{\\"background\\":\\"#269\\",\\"border\\":\\"2px solid #00aaee\\",\\"textAlign\\":\\"center\\",\\"fontSize\\":12,\\"color\\":\\"#fff\\"}]}"
id="item_1_4"
>
item_1_4
</div>
</div>
</div>
</div>
</div>
<div
className="ant-col {}"
id="bl-list_2"
style={
Object {
"alignSelf": undefined,
"border": "1px dashed #8eccf5",
"flex": "0 0 400px",
}
}
>
<div
id="list_2"
>
<div
className="ant-row {\\"style\\":[null,null]}"
id="list_2-content"
style={
Object {
"border": "1px dashed red",
"flexDirection": undefined,
"flexWrap": undefined,
"overflow": undefined,
}
}
>
<div
className="ant-col {\\"style\\":{\\"height\\":50}} ant-col-xs-24 ant-col-sm-24 ant-col-md-24"
id="bl-item_2_1"
style={
Object {
"alignSelf": undefined,
"border": "1px dashed #8eccf5",
}
}
>
<div
className="{\\"style\\":[{\\"background\\":\\"#269\\",\\"border\\":\\"2px solid #00aaee\\",\\"textAlign\\":\\"center\\",\\"fontSize\\":12,\\"color\\":\\"#fff\\"}]}"
id="item_2_1"
>
item_2_1
</div>
</div>
<div
className="ant-col {\\"style\\":{\\"height\\":50}} ant-col-xs-24 ant-col-sm-24 ant-col-md-24"
id="bl-item_2_2"
style={
Object {
"alignSelf": undefined,
"border": "1px dashed #8eccf5",
}
}
>
<div
className="{\\"style\\":[{\\"background\\":\\"#269\\",\\"border\\":\\"2px solid #00aaee\\",\\"textAlign\\":\\"center\\",\\"fontSize\\":12,\\"color\\":\\"#fff\\"}]}"
id="item_2_2"
>
item_2_2
</div>
</div>
<div
className="ant-col {\\"style\\":{\\"height\\":50}} ant-col-xs-24 ant-col-sm-24 ant-col-md-24"
id="bl-item_2_3"
style={
Object {
"alignSelf": undefined,
"border": "1px dashed #8eccf5",
}
}
>
<div
className="{\\"style\\":[{\\"background\\":\\"#269\\",\\"border\\":\\"2px solid #00aaee\\",\\"textAlign\\":\\"center\\",\\"fontSize\\":12,\\"color\\":\\"#fff\\"}]}"
id="item_2_3"
>
item_2_3
</div>
</div>
</div>
</div>
</div>
<div
className="ant-col {}"
id="bl-list_3"
style={
Object {
"alignSelf": undefined,
"border": "1px dashed #8eccf5",
"flex": "0 0 400px",
}
}
>
<div
id="list_3"
>
<div
className="ant-row {\\"style\\":[null,null]}"
id="list_3-content"
style={
Object {
"border": "1px dashed red",
"flexDirection": undefined,
"flexWrap": undefined,
"overflow": undefined,
}
}
>
<div
className="ant-col {\\"style\\":{\\"height\\":150}} ant-col-xs-24 ant-col-sm-24 ant-col-md-24"
id="bl-item_3_1"
style={
Object {
"alignSelf": undefined,
"border": "1px dashed #8eccf5",
}
}
>
<div
className="{\\"style\\":[{\\"background\\":\\"#269\\",\\"border\\":\\"2px solid #00aaee\\",\\"textAlign\\":\\"center\\",\\"fontSize\\":12,\\"color\\":\\"#fff\\"}]}"
id="item_3_1"
>
item_3_1
</div>
</div>
<div
className="ant-col {\\"style\\":{\\"height\\":50}} ant-col-xs-24 ant-col-sm-24 ant-col-md-24"
id="bl-item_3_2"
style={
Object {
"alignSelf": undefined,
"border": "1px dashed #8eccf5",
}
}
>
<div
className="{\\"style\\":[{\\"background\\":\\"#269\\",\\"border\\":\\"2px solid #00aaee\\",\\"textAlign\\":\\"center\\",\\"fontSize\\":12,\\"color\\":\\"#fff\\"}]}"
id="item_3_2"
>
item_3_2
</div>
</div>
<div
className="ant-col {\\"style\\":{\\"height\\":250}} ant-col-xs-24 ant-col-sm-24 ant-col-md-24"
id="bl-item_3_3"
style={
Object {
"alignSelf": undefined,
"border": "1px dashed #8eccf5",
}
}
>
<div
className="{\\"style\\":[{\\"background\\":\\"#269\\",\\"border\\":\\"2px solid #00aaee\\",\\"textAlign\\":\\"center\\",\\"fontSize\\":12,\\"color\\":\\"#fff\\"}]}"
id="item_3_3"
>
item_3_3
</div>
</div>
<div
className="ant-col {\\"style\\":{\\"height\\":50}} ant-col-xs-24 ant-col-sm-24 ant-col-md-24"
id="bl-item_3_4"
style={
Object {
"alignSelf": undefined,
"border": "1px dashed #8eccf5",
}
}
>
<div
className="{\\"style\\":[{\\"background\\":\\"#269\\",\\"border\\":\\"2px solid #00aaee\\",\\"textAlign\\":\\"center\\",\\"fontSize\\":12,\\"color\\":\\"#fff\\"}]}"
id="item_3_4"
>
item_3_4
</div>
</div>
</div>
</div>
</div>
<div
className="ant-col {}"
id="bl-list_4"
style={
Object {
"alignSelf": undefined,
"border": "1px dashed #8eccf5",
"flex": "0 0 400px",
}
}
>
<div
id="list_4"
>
<div
className="ant-row {\\"style\\":[null,null]}"
id="list_4-content"
style={
Object {
"border": "1px dashed red",
"flexDirection": undefined,
"flexWrap": undefined,
"overflow": undefined,
}
}
>
<div
className="ant-col {\\"style\\":{\\"height\\":50}} ant-col-xs-24 ant-col-sm-24 ant-col-md-24"
id="bl-item_4_1"
style={
Object {
"alignSelf": undefined,
"border": "1px dashed #8eccf5",
}
}
>
<div
className="{\\"style\\":[{\\"background\\":\\"#269\\",\\"border\\":\\"2px solid #00aaee\\",\\"textAlign\\":\\"center\\",\\"fontSize\\":12,\\"color\\":\\"#fff\\"}]}"
id="item_4_1"
>
item_4_1
</div>
</div>
</div>
</div>
</div>
<div
className="ant-col {}"
id="bl-list_5"
style={
Object {
"alignSelf": undefined,
"border": "1px dashed #8eccf5",
"flex": "0 0 400px",
}
}
>
<div
id="list_5"
>
<div
className="ant-row {\\"style\\":[null,null]}"
id="list_5-content"
style={
Object {
"border": "1px dashed red",
"flexDirection": undefined,
"flexWrap": undefined,
"overflow": undefined,
}
}
>
<div
className="ant-col {\\"style\\":{\\"height\\":50}} ant-col-xs-24 ant-col-sm-24 ant-col-md-24"
id="bl-item_5_0"
style={
Object {
"alignSelf": undefined,
"border": "1px dashed #8eccf5",
}
}
>
<div
className="{\\"style\\":[{\\"background\\":\\"#269\\",\\"border\\":\\"2px solid #00aaee\\",\\"textAlign\\":\\"center\\",\\"fontSize\\":12,\\"color\\":\\"#fff\\"}]}"
id="item_5_0"
>
item_5_0
</div>
</div>
<div
className="ant-col {\\"style\\":{\\"height\\":50}} ant-col-xs-24 ant-col-sm-24 ant-col-md-24"
id="bl-item_5_1"
style={
Object {
"alignSelf": undefined,
"border": "1px dashed #8eccf5",
}
}
>
<div
className="{\\"style\\":[{\\"background\\":\\"#269\\",\\"border\\":\\"2px solid #00aaee\\",\\"textAlign\\":\\"center\\",\\"fontSize\\":12,\\"color\\":\\"#fff\\"}]}"
id="item_5_1"
>
item_5_1
</div>
</div>
</div>
</div>
</div>
<div
className="ant-col {}"
id="bl-list_6"
style={
Object {
"alignSelf": undefined,
"border": "1px dashed #8eccf5",
"flex": "0 0 400px",
}
}
>
<div
id="list_6"
>
<div
className="ant-row {\\"style\\":[null,null]}"
id="list_6-content"
style={
Object {
"border": "1px dashed red",
"flexDirection": undefined,
"flexWrap": undefined,
"overflow": undefined,
}
}
>
<div
className="ant-col {\\"style\\":{\\"height\\":50}} ant-col-xs-24 ant-col-sm-24 ant-col-md-24"
id="bl-item_6_0"
style={
Object {
"alignSelf": undefined,
"border": "1px dashed #8eccf5",
}
}
>
<div
className="{\\"style\\":[{\\"background\\":\\"#269\\",\\"border\\":\\"2px solid #00aaee\\",\\"textAlign\\":\\"center\\",\\"fontSize\\":12,\\"color\\":\\"#fff\\"}]}"
id="item_6_0"
>
item_6_0
</div>
</div>
<div
className="ant-col {\\"style\\":{\\"height\\":50}} ant-col-xs-24 ant-col-sm-24 ant-col-md-24"
id="bl-item_6_1"
style={
Object {
"alignSelf": undefined,
"border": "1px dashed #8eccf5",
}
}
>
<div
className="{\\"style\\":[{\\"background\\":\\"#269\\",\\"border\\":\\"2px solid #00aaee\\",\\"textAlign\\":\\"center\\",\\"fontSize\\":12,\\"color\\":\\"#fff\\"}]}"
id="item_6_1"
>
item_6_1
</div>
</div>
<div
className="ant-col {\\"style\\":{\\"height\\":50}} ant-col-xs-24 ant-col-sm-24 ant-col-md-24"
id="bl-item_6_2"
style={
Object {
"alignSelf": undefined,
"border": "1px dashed #8eccf5",
}
}
>
<div
className="{\\"style\\":[{\\"background\\":\\"#269\\",\\"border\\":\\"2px solid #00aaee\\",\\"textAlign\\":\\"center\\",\\"fontSize\\":12,\\"color\\":\\"#fff\\"}]}"
id="item_6_2"
>
item_6_2
</div>
</div>
<div
className="ant-col {\\"style\\":{\\"height\\":50}} ant-col-xs-24 ant-col-sm-24 ant-col-md-24"
id="bl-item_6_3"
style={
Object {
"alignSelf": undefined,
"border": "1px dashed #8eccf5",
}
}
>
<div
className="{\\"style\\":[{\\"background\\":\\"#269\\",\\"border\\":\\"2px solid #00aaee\\",\\"textAlign\\":\\"center\\",\\"fontSize\\":12,\\"color\\":\\"#fff\\"}]}"
id="item_6_3"
>
item_6_3
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
`;

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,4 @@
import basic from '../demo/examples/basic.yaml';
import runExampleTests from './runExampleTests';
runExampleTests(basic);

View File

@ -0,0 +1,5 @@
import col from '../demo/examples/col.yaml';
import runExampleTests from './runExampleTests';
runExampleTests(col);
runExampleTests(col, { highlightBorders: false });

View File

@ -0,0 +1,4 @@
import complex from '../demo/examples/complex.yaml';
import runExampleTests from './runExampleTests';
runExampleTests(complex);

View File

@ -0,0 +1,353 @@
import deriveLayout from '../src/deriveLayout';
const defaultValue = {
xs: {
span: 24,
},
sm: {
span: 24,
},
md: {
span: 24,
},
};
test('layout is empty', () => {
const layout = {};
expect(deriveLayout(layout)).toEqual(defaultValue);
});
test('set properties', () => {
const layout = {
offset: 1,
order: 2,
pull: 3,
push: 4,
span: 5,
};
expect(deriveLayout(layout)).toEqual({ ...defaultValue, md: layout });
});
test('set sm properties', () => {
const layout = {
sm: {
offset: 1,
order: 2,
pull: 3,
push: 4,
span: 5,
},
};
expect(deriveLayout(layout)).toEqual({ ...defaultValue, sm: layout.sm, xs: layout.sm });
});
test('set xs properties', () => {
const layout = {
xs: {
offset: 1,
order: 2,
pull: 3,
push: 4,
span: 5,
},
};
expect(deriveLayout(layout)).toEqual({ ...defaultValue, xs: layout.xs });
});
test('set xs and md properties', () => {
const layout = {
xs: {
offset: 1,
order: 2,
pull: 3,
push: 4,
span: 5,
},
md: {
offset: 11,
order: 22,
pull: 33,
push: 44,
span: 55,
},
};
expect(deriveLayout(layout)).toEqual({ ...defaultValue, xs: layout.xs, md: layout.md });
});
test('set xs and sm properties', () => {
const layout = {
xs: {
offset: 1,
order: 2,
pull: 3,
push: 4,
span: 5,
},
sm: {
offset: 11,
order: 22,
pull: 33,
push: 44,
span: 55,
},
};
expect(deriveLayout(layout)).toEqual({ ...defaultValue, xs: layout.xs, sm: layout.sm });
});
test('set lg property', () => {
const layout = {
lg: {
order: 2,
},
};
expect(deriveLayout(layout)).toEqual({ ...defaultValue, lg: layout.lg });
});
test('set xl property', () => {
const layout = {
xl: {
order: 2,
},
};
expect(deriveLayout(layout)).toEqual({ ...defaultValue, xl: layout.xl });
});
test('set xxl property', () => {
const layout = {
xxl: {
order: 2,
},
};
expect(deriveLayout(layout)).toEqual({ ...defaultValue, xxl: layout.xxl });
});
test('set flex number', () => {
const layout = { flex: 1 };
expect(deriveLayout(layout)).toEqual({ flex: 1 });
});
test('set flex string', () => {
const layout = { flex: '1 1' };
expect(deriveLayout(layout)).toEqual({ flex: '1 1' });
});
test('set flex true sets default', () => {
const layout = { flex: true };
expect(deriveLayout(layout)).toEqual({ flex: '0 1 auto' });
});
test('set grow 1 sets flex 1 1 auto', () => {
const layout = { grow: 1 };
expect(deriveLayout(layout)).toEqual({ flex: '1 1 auto' });
});
test('set grow true sets flex 1 1 auto', () => {
const layout = { grow: true };
expect(deriveLayout(layout)).toEqual({ flex: '1 1 auto' });
});
test('set grow false sets flex 0 1 auto', () => {
const layout = { grow: false };
expect(deriveLayout(layout)).toEqual({ flex: '0 1 auto' });
});
test('set grow 3 sets flex 3 1 auto', () => {
const layout = { grow: 3 };
expect(deriveLayout(layout)).toEqual({ flex: '3 1 auto' });
});
test('set grow "unset" sets flex unset 1 auto', () => {
const layout = { grow: 'unset' };
expect(deriveLayout(layout)).toEqual({ flex: 'unset 1 auto' });
});
test('set grow "inherit" sets flex unset 1 auto', () => {
const layout = { grow: 'inherit' };
expect(deriveLayout(layout)).toEqual({ flex: 'inherit 1 auto' });
});
test('set grow "initial" sets flex unset 1 auto', () => {
const layout = { grow: 'initial' };
expect(deriveLayout(layout)).toEqual({ flex: 'initial 1 auto' });
});
test('set grow string sets flex 0 1 auto default', () => {
const layout = { grow: 'aaa' };
expect(deriveLayout(layout)).toEqual({ flex: '0 1 auto' });
});
test('set shrink 0 sets flex 0 0 auto', () => {
const layout = { shrink: 0 };
expect(deriveLayout(layout)).toEqual({ flex: '0 0 auto' });
});
test('set shrink true sets flex 0 1 auto', () => {
const layout = { shrink: true };
expect(deriveLayout(layout)).toEqual({ flex: '0 1 auto' });
});
test('set shrink false sets flex 0 0 auto', () => {
const layout = { shrink: false };
expect(deriveLayout(layout)).toEqual({ flex: '0 0 auto' });
});
test('set shrink 3 sets flex 0 3 auto', () => {
const layout = { shrink: 3 };
expect(deriveLayout(layout)).toEqual({ flex: '0 3 auto' });
});
test('set shrink "unset" sets flex unset 1 auto', () => {
const layout = { shrink: 'unset' };
expect(deriveLayout(layout)).toEqual({ flex: '0 unset auto' });
});
test('set shrink "inherit" sets flex unset 1 auto', () => {
const layout = { shrink: 'inherit' };
expect(deriveLayout(layout)).toEqual({ flex: '0 inherit auto' });
});
test('set shrink "initial" sets flex unset 1 auto', () => {
const layout = { shrink: 'initial' };
expect(deriveLayout(layout)).toEqual({ flex: '0 initial auto' });
});
test('set shrink string sets flex 0 1 auto default', () => {
const layout = { shrink: 'aaa' };
expect(deriveLayout(layout)).toEqual({ flex: '0 1 auto' });
});
test('set size to number set flex to px', () => {
const layout = { size: 100 };
expect(deriveLayout(layout)).toEqual({ flex: '0 1 100px' });
});
test('set size to string set flex to string', () => {
const layout = { size: '100' };
expect(deriveLayout(layout)).toEqual({ flex: '0 1 100' });
});
test('set size to bool set flex to default', () => {
const layout = { size: true };
expect(deriveLayout(layout)).toEqual({ flex: '0 1 auto' });
});
test('set offset will reduce span', () => {
const layout = { offset: 4 };
expect(deriveLayout(layout)).toEqual({
md: {
offset: 4,
span: 20,
},
sm: {
span: 24,
},
xs: {
span: 24,
},
});
});
test('set offset will reduce span md', () => {
const layout = { md: { offset: 4 } };
expect(deriveLayout(layout)).toEqual({
md: {
offset: 4,
span: 20,
},
sm: {
span: 24,
},
xs: {
span: 24,
},
});
});
test('set offset will reduce span xs', () => {
const layout = { xs: { offset: 4 } };
expect(deriveLayout(layout)).toEqual({
md: {
span: 24,
},
sm: {
span: 24,
},
xs: {
span: 20,
offset: 4,
},
});
});
test('set offset will reduce span sm', () => {
const layout = { sm: { offset: 4 } };
expect(deriveLayout(layout)).toEqual({
md: {
span: 24,
},
sm: {
span: 20,
offset: 4,
},
xs: {
span: 20,
offset: 4,
},
});
});
test('set offset will reduce span lg', () => {
const layout = { lg: { offset: 4 } };
expect(deriveLayout(layout)).toEqual({
lg: {
span: 20,
offset: 4,
},
md: {
span: 24,
},
sm: {
span: 24,
},
xs: {
span: 24,
},
});
});
test('set offset will reduce span xl', () => {
const layout = { xl: { offset: 4 } };
expect(deriveLayout(layout)).toEqual({
xl: {
span: 20,
offset: 4,
},
md: {
span: 24,
},
sm: {
span: 24,
},
xs: {
span: 24,
},
});
});
test('set offset will reduce span xxl', () => {
const layout = { xxl: { offset: 4 } };
expect(deriveLayout(layout)).toEqual({
xxl: {
span: 20,
offset: 4,
},
md: {
span: 24,
},
sm: {
span: 24,
},
xs: {
span: 24,
},
});
});

View File

@ -0,0 +1,109 @@
import getLabelCol from '../src/getLabelCol';
test('with inline', () => {
expect(getLabelCol({}, true)).toEqual({ flex: '0 1 auto' });
});
test('with no span value', () => {
expect(getLabelCol({}, false)).toEqual({
xs: { span: 24 },
sm: { span: 24 },
});
});
test('with a span value', () => {
expect(getLabelCol({ span: 3 }, false)).toEqual({
xs: { span: 24 },
sm: { span: 24 },
md: { span: 3 },
});
});
test('with a xs span value', () => {
expect(getLabelCol({ xs: { span: 3 } }, false)).toEqual({
xs: { span: 3 },
sm: { span: 24 },
});
});
test('with a sm span value', () => {
expect(getLabelCol({ sm: { span: 3 } }, false)).toEqual({
xs: { span: 3 },
sm: { span: 3 },
});
});
test('with a md span value', () => {
expect(getLabelCol({ md: { span: 3 } }, false)).toEqual({
xs: { span: 24 },
sm: { span: 24 },
md: { span: 3 },
});
});
test('with a lg span value', () => {
expect(getLabelCol({ lg: { span: 3 } }, false)).toEqual({
xs: { span: 24 },
sm: { span: 24 },
lg: { span: 3 },
});
});
test('with a xl span value', () => {
expect(getLabelCol({ xl: { span: 3 } }, false)).toEqual({
xs: { span: 24 },
sm: { span: 24 },
xl: { span: 3 },
});
});
test('with a xxl span value', () => {
expect(getLabelCol({ xxl: { span: 3 } }, false)).toEqual({
xs: { span: 24 },
sm: { span: 24 },
xxl: { span: 3 },
});
});
test('with all desktop span values', () => {
expect(
getLabelCol({ md: { span: 1 }, lg: { span: 2 }, xl: { span: 3 }, xxl: { span: 4 } }, false)
).toEqual({
xs: { span: 24 },
sm: { span: 24 },
md: { span: 1 },
lg: { span: 2 },
xl: { span: 3 },
xxl: { span: 4 },
});
});
test('with all mobile span values', () => {
expect(getLabelCol({ xs: { span: 1 }, sm: { span: 2 } }, false)).toEqual({
xs: { span: 1 },
sm: { span: 2 },
});
});
test('with all span values', () => {
expect(
getLabelCol(
{
xs: { span: 11 },
sm: { span: 22 },
md: { span: 1 },
lg: { span: 2 },
xl: { span: 3 },
xxl: { span: 4 },
},
false
)
).toEqual({
xs: { span: 11 },
sm: { span: 22 },
md: { span: 1 },
lg: { span: 2 },
xl: { span: 3 },
xxl: { span: 4 },
});
});

View File

@ -0,0 +1,109 @@
import getWrapperCol from '../src/getWrapperCol';
test('with inline', () => {
expect(getWrapperCol({}, true)).toEqual({ flex: '1 1 auto' });
});
test('with no span value', () => {
expect(getWrapperCol({}, false)).toEqual({
xs: { span: 24 },
sm: { span: 24 },
});
});
test('with a span value', () => {
expect(getWrapperCol({ span: 3 }, false)).toEqual({
xs: { span: 24 },
sm: { span: 24 },
md: { span: 21 },
});
});
test('with a xs span value', () => {
expect(getWrapperCol({ xs: { span: 3 } }, false)).toEqual({
xs: { span: 21 },
sm: { span: 24 },
});
});
test('with a sm span value', () => {
expect(getWrapperCol({ sm: { span: 3 } }, false)).toEqual({
xs: { span: 21 },
sm: { span: 21 },
});
});
test('with a md span value', () => {
expect(getWrapperCol({ md: { span: 3 } }, false)).toEqual({
xs: { span: 24 },
sm: { span: 24 },
md: { span: 21 },
});
});
test('with a lg span value', () => {
expect(getWrapperCol({ lg: { span: 3 } }, false)).toEqual({
xs: { span: 24 },
sm: { span: 24 },
lg: { span: 21 },
});
});
test('with a xl span value', () => {
expect(getWrapperCol({ xl: { span: 3 } }, false)).toEqual({
xs: { span: 24 },
sm: { span: 24 },
xl: { span: 21 },
});
});
test('with a xxl span value', () => {
expect(getWrapperCol({ xxl: { span: 3 } }, false)).toEqual({
xs: { span: 24 },
sm: { span: 24 },
xxl: { span: 21 },
});
});
test('with all desktop span values', () => {
expect(
getWrapperCol({ md: { span: 1 }, lg: { span: 2 }, xl: { span: 3 }, xxl: { span: 4 } }, false)
).toEqual({
xs: { span: 24 },
sm: { span: 24 },
md: { span: 23 },
lg: { span: 22 },
xl: { span: 21 },
xxl: { span: 20 },
});
});
test('with all mobile span values', () => {
expect(getWrapperCol({ xs: { span: 1 }, sm: { span: 2 } }, false)).toEqual({
xs: { span: 23 },
sm: { span: 22 },
});
});
test('with all span values', () => {
expect(
getWrapperCol(
{
xs: { span: 11 },
sm: { span: 22 },
md: { span: 1 },
lg: { span: 2 },
xl: { span: 3 },
xxl: { span: 4 },
},
false
)
).toEqual({
xs: { span: 13 },
sm: { span: 2 },
md: { span: 23 },
lg: { span: 22 },
xl: { span: 21 },
xxl: { span: 20 },
});
});

View File

@ -0,0 +1,4 @@
import grid from '../demo/examples/grid.yaml';
import runExampleTests from './runExampleTests';
runExampleTests(grid);

View File

@ -0,0 +1,24 @@
import gutterSetup from '../src/gutterSetup';
test('no gutter specified', () => {
expect(gutterSetup(undefined)).toEqual(undefined);
});
test('gutter is int', () => {
expect(gutterSetup(10)).toEqual([10, 10]);
});
test('gutter is 0', () => {
expect(gutterSetup(0)).toEqual([0, 0]);
});
test('gutter is array', () => {
expect(gutterSetup([10, 20])).toEqual([10, 20]);
});
test('gutter is object', () => {
expect(gutterSetup({ sm: 10, md: 20 }, null)).toEqual([
{ sm: 10, md: 20 },
{ sm: 10, md: 20 },
]);
});

View File

@ -0,0 +1,4 @@
import kanban from '../demo/examples/kanban.yaml';
import runExampleTests from './runExampleTests';
runExampleTests(kanban);

View File

@ -0,0 +1,825 @@
import labelLogic from '../src/labelLogic';
const makeCss = jest.fn();
const makeCssImp = (style, op) => JSON.stringify({ style, options: op });
beforeEach(() => {
makeCss.mockReset();
makeCss.mockImplementation(makeCssImp);
Object.defineProperty(window, 'matchMedia', {
writable: true,
value: jest.fn().mockImplementation((query) => ({
matches: false,
media: query,
onchange: null,
addListener: jest.fn(), // deprecated
removeListener: jest.fn(), // deprecated
addEventListener: jest.fn(),
removeEventListener: jest.fn(),
dispatchEvent: jest.fn(),
})),
});
});
const defaultInput = {
blockId: 'label_1',
content: {},
methods: { makeCss },
};
test('label default logic', () => {
expect(labelLogic(defaultInput)).toEqual({
extraClassName: 'ant-form-item-extra {"style":[{"marginTop":0},null]}',
label: 'label_1',
labelClassName: '{}',
labelCol: {
sm: {
span: 24,
},
xs: {
span: 24,
},
},
labelColClassName: 'ant-form-item-label ant-form-item-label-left',
rowClassName: 'ant-form-item {"style":{}}',
validateStatus: null,
wrapperCol: {
sm: {
span: 24,
},
xs: {
span: 24,
},
},
});
});
test('label default logic with required', () => {
expect(labelLogic({ ...defaultInput, required: true })).toEqual({
extraClassName: 'ant-form-item-extra {"style":[{"marginTop":0},null]}',
label: 'label_1',
labelClassName: 'ant-form-item-required {}',
labelCol: {
sm: {
span: 24,
},
xs: {
span: 24,
},
},
labelColClassName: 'ant-form-item-label ant-form-item-label-left',
rowClassName: 'ant-form-item {"style":{}}',
validateStatus: null,
wrapperCol: {
sm: {
span: 24,
},
xs: {
span: 24,
},
},
});
});
test('label default logic with required and validated', () => {
expect(labelLogic({ ...defaultInput, required: true, validated: true })).toEqual({
extraClassName: 'ant-form-item-extra {"style":[{"marginTop":0},null]}',
label: 'label_1',
labelClassName: 'ant-form-item-required {}',
labelCol: {
sm: {
span: 24,
},
xs: {
span: 24,
},
},
labelColClassName: 'ant-form-item-label ant-form-item-label-left',
rowClassName: 'ant-form-item ant-form-item-has-feedback ant-form-item-has-success {"style":{}}',
validateStatus: 'success',
wrapperCol: {
sm: {
span: 24,
},
xs: {
span: 24,
},
},
});
});
test('label default logic with required, validated and validate', () => {
expect(
labelLogic({
...defaultInput,
required: true,
validated: true,
validate: [{ message: 'fail' }],
})
).toEqual({
extraClassName: 'ant-form-item-extra {"style":[{"marginTop":0},null]}',
label: 'label_1',
labelClassName: 'ant-form-item-required {}',
labelCol: {
sm: {
span: 24,
},
xs: {
span: 24,
},
},
labelColClassName: 'ant-form-item-label ant-form-item-label-left',
rowClassName: 'ant-form-item ant-form-item-has-feedback ant-form-item-has-error {"style":{}}',
validateStatus: 'error',
wrapperCol: {
sm: {
span: 24,
},
xs: {
span: 24,
},
},
});
});
test('label default logic properties.align = right', () => {
expect(labelLogic({ ...defaultInput, properties: { align: 'right' } })).toEqual({
extraClassName: 'ant-form-item-extra {"style":[{"marginTop":0},null]}',
label: 'label_1',
labelClassName: '{}',
labelCol: {
sm: {
span: 24,
},
xs: {
span: 24,
},
},
labelColClassName: 'ant-form-item-label',
rowClassName: 'ant-form-item {"style":{}}',
validateStatus: null,
wrapperCol: {
sm: {
span: 24,
},
xs: {
span: 24,
},
},
});
});
test('label default logic properties.align = left', () => {
expect(labelLogic({ ...defaultInput, properties: { align: 'left' } })).toEqual({
extraClassName: 'ant-form-item-extra {"style":[{"marginTop":0},null]}',
label: 'label_1',
labelClassName: '{}',
labelCol: {
sm: {
span: 24,
},
xs: {
span: 24,
},
},
labelColClassName: 'ant-form-item-label ant-form-item-label-left',
rowClassName: 'ant-form-item {"style":{}}',
validateStatus: null,
wrapperCol: {
sm: {
span: 24,
},
xs: {
span: 24,
},
},
});
});
test('label default logic properties.inline = true', () => {
expect(labelLogic({ ...defaultInput, properties: { inline: true } })).toEqual({
extraClassName: 'ant-form-item-extra {"style":[{"marginTop":0},null]}',
label: 'label_1',
labelClassName: '{}',
labelCol: { flex: '0 1 auto' },
labelColClassName: 'ant-form-item-label ant-form-item-label-left',
rowClassName: 'ant-form-item {"style":{"flexWrap":"inherit"}}',
validateStatus: null,
wrapperCol: { flex: '1 1 auto' },
});
let reponse = labelLogic({ ...defaultInput, properties: { inline: true }, required: true });
expect(reponse.labelClassName).toEqual('ant-form-item-required {}');
reponse = labelLogic({
...defaultInput,
properties: { inline: true },
required: true,
validated: true,
});
expect(reponse.labelClassName).toEqual('ant-form-item-required {}');
expect(reponse.validateStatus).toEqual('success');
expect(reponse.rowClassName).toEqual(
'ant-form-item ant-form-item-has-feedback ant-form-item-has-success {"style":{"flexWrap":"inherit"}}'
);
expect(
labelLogic({
...defaultInput,
properties: { inline: true },
required: true,
validated: true,
validate: [{ status: 'error', message: 'fail' }],
})
).toEqual({
extraClassName: 'ant-form-item-extra {"style":[{"marginTop":0},null]}',
label: 'label_1',
labelClassName: 'ant-form-item-required {}',
labelCol: { flex: '0 1 auto' },
labelColClassName: 'ant-form-item-label ant-form-item-label-left',
rowClassName:
'ant-form-item ant-form-item-has-feedback ant-form-item-has-error {"style":{"flexWrap":"inherit"}}',
validateStatus: 'error',
wrapperCol: { flex: '1 1 auto' },
});
});
test('label default logic properties.colon = true', () => {
expect(labelLogic({ ...defaultInput, properties: { colon: true } })).toEqual({
extraClassName: 'ant-form-item-extra {"style":[{"marginTop":0},null]}',
label: 'label_1',
labelClassName: '{}',
labelCol: {
sm: {
span: 24,
},
xs: {
span: 24,
},
},
labelColClassName: 'ant-form-item-label ant-form-item-label-left',
rowClassName: 'ant-form-item {"style":{}}',
validateStatus: null,
wrapperCol: {
sm: {
span: 24,
},
xs: {
span: 24,
},
},
});
let reponse = labelLogic({ ...defaultInput, properties: { colon: true }, required: true });
expect(reponse.labelClassName).toEqual('ant-form-item-required {}');
reponse = labelLogic({
...defaultInput,
properties: { colon: true },
required: true,
validated: true,
});
expect(reponse.labelClassName).toEqual('ant-form-item-required {}');
expect(reponse.validateStatus).toEqual('success');
expect(reponse.rowClassName).toEqual(
'ant-form-item ant-form-item-has-feedback ant-form-item-has-success {"style":{}}'
);
expect(
labelLogic({
...defaultInput,
properties: { colon: true },
required: true,
validated: true,
validate: [{ status: 'error', message: 'fail' }],
})
).toEqual({
extraClassName: 'ant-form-item-extra {"style":[{"marginTop":0},null]}',
label: 'label_1',
labelClassName: 'ant-form-item-required {}',
labelCol: {
sm: {
span: 24,
},
xs: {
span: 24,
},
},
labelColClassName: 'ant-form-item-label ant-form-item-label-left',
rowClassName: 'ant-form-item ant-form-item-has-feedback ant-form-item-has-error {"style":{}}',
validateStatus: 'error',
wrapperCol: {
sm: {
span: 24,
},
xs: {
span: 24,
},
},
});
});
test('label default logic properties.title = title_1', () => {
expect(labelLogic({ ...defaultInput, properties: { title: 'title_1' } })).toEqual({
extraClassName: 'ant-form-item-extra {"style":[{"marginTop":0},null]}',
label: 'title_1',
labelClassName: '{}',
labelCol: {
sm: {
span: 24,
},
xs: {
span: 24,
},
},
labelColClassName: 'ant-form-item-label ant-form-item-label-left',
rowClassName: 'ant-form-item {"style":{}}',
validateStatus: null,
wrapperCol: {
sm: {
span: 24,
},
xs: {
span: 24,
},
},
});
let reponse = labelLogic({ ...defaultInput, properties: { colon: true }, required: true });
expect(reponse.labelClassName).toEqual('ant-form-item-required {}');
reponse = labelLogic({
...defaultInput,
properties: { title: 'title_1' },
required: true,
validated: true,
});
expect(reponse.labelClassName).toEqual('ant-form-item-required {}');
expect(reponse.validateStatus).toEqual('success');
expect(reponse.rowClassName).toEqual(
'ant-form-item ant-form-item-has-feedback ant-form-item-has-success {"style":{}}'
);
expect(
labelLogic({
...defaultInput,
properties: { title: 'title_1' },
required: true,
validated: true,
validate: [{ status: 'error', message: 'fail' }],
})
).toEqual({
extraClassName: 'ant-form-item-extra {"style":[{"marginTop":0},null]}',
label: 'title_1',
labelClassName: 'ant-form-item-required {}',
labelCol: {
sm: {
span: 24,
},
xs: {
span: 24,
},
},
labelColClassName: 'ant-form-item-label ant-form-item-label-left',
rowClassName: 'ant-form-item ant-form-item-has-feedback ant-form-item-has-error {"style":{}}',
validateStatus: 'error',
wrapperCol: {
sm: {
span: 24,
},
xs: {
span: 24,
},
},
});
});
test('label default logic properties.hasFeedback = false', () => {
expect(labelLogic({ ...defaultInput, properties: { hasFeedback: false } })).toEqual({
extraClassName: 'ant-form-item-extra {"style":[{"marginTop":0},null]}',
label: 'label_1',
labelClassName: '{}',
labelCol: {
sm: {
span: 24,
},
xs: {
span: 24,
},
},
labelColClassName: 'ant-form-item-label ant-form-item-label-left',
rowClassName: 'ant-form-item {"style":{}}',
validateStatus: false,
wrapperCol: {
sm: {
span: 24,
},
xs: {
span: 24,
},
},
});
let reponse = labelLogic({ ...defaultInput, properties: { hasFeedback: false }, required: true });
expect(reponse.labelClassName).toEqual('ant-form-item-required {}');
reponse = labelLogic({
...defaultInput,
properties: { hasFeedback: false },
required: true,
validated: true,
});
expect(reponse.labelClassName).toEqual('ant-form-item-required {}');
expect(reponse.validateStatus).toEqual(false);
expect(reponse.rowClassName).toEqual('ant-form-item ant-form-item-has-success {"style":{}}');
expect(
labelLogic({
...defaultInput,
properties: { hasFeedback: false },
required: true,
validated: true,
validate: [{ status: 'error', message: 'fail' }],
})
).toEqual({
extraClassName: 'ant-form-item-extra {"style":[{"marginTop":0},null]}',
label: 'label_1',
labelClassName: 'ant-form-item-required {}',
labelCol: {
sm: {
span: 24,
},
xs: {
span: 24,
},
},
labelColClassName: 'ant-form-item-label ant-form-item-label-left',
rowClassName: 'ant-form-item ant-form-item-has-error {"style":{}}',
validateStatus: false,
wrapperCol: {
sm: {
span: 24,
},
xs: {
span: 24,
},
},
});
});
test('label default logic properties.size = small', () => {
expect(labelLogic({ ...defaultInput, properties: { size: 'small' } })).toEqual({
extraClassName: 'ant-form-item-extra {"style":[{"marginTop":-4},null]}',
label: 'label_1',
labelClassName: '{}',
labelCol: {
sm: {
span: 24,
},
xs: {
span: 24,
},
},
labelColClassName: 'ant-form-item-label ant-form-item-label-left',
rowClassName: 'ant-form-item {"style":{}}',
validateStatus: null,
wrapperCol: {
sm: {
span: 24,
},
xs: {
span: 24,
},
},
});
let reponse = labelLogic({ ...defaultInput, properties: { size: 'small' }, required: true });
expect(reponse.labelClassName).toEqual('ant-form-item-required {}');
reponse = labelLogic({
...defaultInput,
properties: { colon: true },
required: true,
validated: true,
});
expect(reponse.labelClassName).toEqual('ant-form-item-required {}');
expect(reponse.validateStatus).toEqual('success');
expect(reponse.rowClassName).toEqual(
'ant-form-item ant-form-item-has-feedback ant-form-item-has-success {"style":{}}'
);
expect(
labelLogic({
...defaultInput,
properties: { size: 'small' },
required: true,
validated: true,
validate: [{ status: 'error', message: 'fail' }],
})
).toEqual({
extraClassName: 'ant-form-item-extra {"style":[{"marginTop":-4},null]}',
label: 'label_1',
labelClassName: 'ant-form-item-required {}',
labelCol: {
sm: {
span: 24,
},
xs: {
span: 24,
},
},
labelColClassName: 'ant-form-item-label ant-form-item-label-left',
rowClassName: 'ant-form-item ant-form-item-has-feedback ant-form-item-has-error {"style":{}}',
validateStatus: 'error',
wrapperCol: {
sm: {
span: 24,
},
xs: {
span: 24,
},
},
});
});
test('label default logic properties.disabled = true', () => {
expect(labelLogic({ ...defaultInput, properties: { disabled: true } })).toEqual({
extraClassName: 'ant-form-item-extra {"style":[{"marginTop":0},null]}',
label: false,
labelClassName: '{}',
labelCol: {
sm: {
span: 24,
},
xs: {
span: 24,
},
},
labelColClassName: 'ant-form-item-label ant-form-item-label-left',
rowClassName: 'ant-form-item {"style":{}}',
validateStatus: null,
wrapperCol: {
sm: {
span: 24,
},
xs: {
span: 24,
},
},
});
let reponse = labelLogic({ ...defaultInput, properties: { disabled: true }, required: true });
expect(reponse.labelClassName).toEqual('ant-form-item-required {}');
reponse = labelLogic({
...defaultInput,
properties: { hasFeedback: false },
required: true,
validated: true,
});
expect(reponse.labelClassName).toEqual('ant-form-item-required {}');
expect(reponse.validateStatus).toEqual(false);
expect(reponse.rowClassName).toEqual('ant-form-item ant-form-item-has-success {"style":{}}');
expect(
labelLogic({
...defaultInput,
properties: { disabled: true },
required: true,
validated: true,
validate: [{ status: 'error', message: 'fail' }],
})
).toEqual({
extraClassName: 'ant-form-item-extra {"style":[{"marginTop":0},null]}',
label: false,
labelClassName: 'ant-form-item-required {}',
labelCol: {
sm: {
span: 24,
},
xs: {
span: 24,
},
},
labelColClassName: 'ant-form-item-label ant-form-item-label-left',
rowClassName: 'ant-form-item ant-form-item-has-feedback ant-form-item-has-error {"style":{}}',
validateStatus: 'error',
wrapperCol: {
sm: {
span: 24,
},
xs: {
span: 24,
},
},
});
});
test('label default logic properties.style && properties.extraStyle', () => {
expect(
labelLogic({ ...defaultInput, properties: { style: { b: 2 }, extraStyle: { a: 1 } } })
).toEqual({
extraClassName: 'ant-form-item-extra {"style":[{"marginTop":0},{"a":1}]}',
label: 'label_1',
labelClassName: '{"style":{"b":2}}',
labelCol: {
sm: {
span: 24,
},
xs: {
span: 24,
},
},
labelColClassName: 'ant-form-item-label ant-form-item-label-left',
rowClassName: 'ant-form-item {"style":{}}',
validateStatus: null,
wrapperCol: {
sm: {
span: 24,
},
xs: {
span: 24,
},
},
});
let reponse = labelLogic({ ...defaultInput, properties: { disabled: true }, required: true });
expect(reponse.labelClassName).toEqual('ant-form-item-required {}');
reponse = labelLogic({
...defaultInput,
properties: { style: { b: 2 }, extraStyle: { a: 1 } },
required: true,
validated: true,
});
expect(reponse.labelClassName).toEqual('ant-form-item-required {"style":{"b":2}}');
expect(reponse.validateStatus).toEqual('success');
expect(reponse.rowClassName).toEqual(
'ant-form-item ant-form-item-has-feedback ant-form-item-has-success {"style":{}}'
);
expect(
labelLogic({
...defaultInput,
properties: { style: { b: 2 }, extraStyle: { a: 1 } },
required: true,
validated: true,
validate: [{ status: 'error', message: 'fail' }],
})
).toEqual({
extraClassName: 'ant-form-item-extra {"style":[{"marginTop":0},{"a":1}]}',
label: 'label_1',
labelClassName: 'ant-form-item-required {"style":{"b":2}}',
labelCol: {
sm: {
span: 24,
},
xs: {
span: 24,
},
},
labelColClassName: 'ant-form-item-label ant-form-item-label-left',
rowClassName: 'ant-form-item ant-form-item-has-feedback ant-form-item-has-error {"style":{}}',
validateStatus: 'error',
wrapperCol: {
sm: {
span: 24,
},
xs: {
span: 24,
},
},
});
});
test('label default logic content.label = () => one', () => {
expect(labelLogic({ ...defaultInput, content: { label: () => 'one' } })).toEqual({
extraClassName: 'ant-form-item-extra {"style":[{"marginTop":0},null]}',
label: 'one',
labelClassName: '{}',
labelCol: {
sm: {
span: 24,
},
xs: {
span: 24,
},
},
labelColClassName: 'ant-form-item-label ant-form-item-label-left',
rowClassName: 'ant-form-item {"style":{}}',
validateStatus: null,
wrapperCol: {
sm: {
span: 24,
},
xs: {
span: 24,
},
},
});
let reponse = labelLogic({ ...defaultInput, properties: { colon: true }, required: true });
expect(reponse.labelClassName).toEqual('ant-form-item-required {}');
reponse = labelLogic({
...defaultInput,
content: { label: () => 'one' },
required: true,
validated: true,
});
expect(reponse.labelClassName).toEqual('ant-form-item-required {}');
expect(reponse.validateStatus).toEqual('success');
expect(reponse.rowClassName).toEqual(
'ant-form-item ant-form-item-has-feedback ant-form-item-has-success {"style":{}}'
);
expect(
labelLogic({
...defaultInput,
content: { label: () => 'one' },
required: true,
validated: true,
validate: [{ status: 'error', message: 'fail' }],
})
).toEqual({
extraClassName: 'ant-form-item-extra {"style":[{"marginTop":0},null]}',
label: 'one',
labelClassName: 'ant-form-item-required {}',
labelCol: {
sm: {
span: 24,
},
xs: {
span: 24,
},
},
labelColClassName: 'ant-form-item-label ant-form-item-label-left',
rowClassName: 'ant-form-item ant-form-item-has-feedback ant-form-item-has-error {"style":{}}',
validateStatus: 'error',
wrapperCol: {
sm: {
span: 24,
},
xs: {
span: 24,
},
},
});
});
test('label default logic label === "" ', () => {
expect(labelLogic({ ...defaultInput, content: { label: () => '' } })).toEqual({
extraClassName: 'ant-form-item-extra {"style":[{"marginTop":0},null]}',
label: null,
labelClassName: '{}',
labelCol: {
sm: {
span: 24,
},
xs: {
span: 24,
},
},
labelColClassName: 'ant-form-item-label ant-form-item-label-left',
rowClassName: 'ant-form-item {"style":{}}',
validateStatus: null,
wrapperCol: {
sm: {
span: 24,
},
xs: {
span: 24,
},
},
});
let reponse = labelLogic({ ...defaultInput, properties: { colon: true }, required: true });
expect(reponse.labelClassName).toEqual('ant-form-item-required {}');
reponse = labelLogic({
...defaultInput,
content: { label: () => '' },
required: true,
validated: true,
});
expect(reponse.labelClassName).toEqual('ant-form-item-required {}');
expect(reponse.validateStatus).toEqual('success');
expect(reponse.rowClassName).toEqual(
'ant-form-item ant-form-item-has-feedback ant-form-item-has-success {"style":{}}'
);
expect(
labelLogic({
...defaultInput,
content: { label: () => '' },
required: true,
validated: true,
validate: [{ status: 'error', message: 'fail' }],
})
).toEqual({
extraClassName: 'ant-form-item-extra {"style":[{"marginTop":0},null]}',
label: null,
labelClassName: 'ant-form-item-required {}',
labelCol: {
sm: {
span: 24,
},
xs: {
span: 24,
},
},
labelColClassName: 'ant-form-item-label ant-form-item-label-left',
rowClassName: 'ant-form-item ant-form-item-has-feedback ant-form-item-has-error {"style":{}}',
validateStatus: 'error',
wrapperCol: {
sm: {
span: 24,
},
xs: {
span: 24,
},
},
});
});

View File

@ -0,0 +1,149 @@
import layoutParamsToArea from '../src/layoutParamsToArea';
test('empty area and layout', () => {
const layout = {};
const area = {};
const areaKey = 'content';
expect(layoutParamsToArea({ areaKey, area, layout })).toEqual(area);
});
test('layout fields', () => {
const layout = {
contentAlign: 1,
contentJustify: 2,
contentDirection: 3,
contentWrap: 4,
contentOverflow: 5,
contentGutter: 6,
};
const area = {};
const areaKey = 'content';
expect(layoutParamsToArea({ areaKey, area, layout })).toEqual({
align: 1,
justify: 2,
direction: 3,
wrap: 4,
overflow: 5,
gutter: 6,
});
});
test('area fields', () => {
const layout = {};
const area = {
align: 1,
justify: 2,
direction: 3,
wrap: 4,
overflow: 5,
gutter: 6,
};
const areaKey = 'content';
expect(layoutParamsToArea({ areaKey, area, layout })).toEqual({
align: 1,
justify: 2,
direction: 3,
wrap: 4,
overflow: 5,
gutter: 6,
});
});
test('area and layout', () => {
const layout = {
contentAlign: 11,
contentJustify: 22,
contentDirection: 33,
contentWrap: 44,
contentOverflow: 55,
contentGutter: 66,
};
const area = {
align: 1,
justify: 2,
direction: 3,
wrap: 4,
overflow: 5,
gutter: 6,
};
const areaKey = 'content';
expect(layoutParamsToArea({ areaKey, area, layout })).toEqual({
align: 1,
justify: 2,
direction: 3,
wrap: 4,
overflow: 5,
gutter: 6,
});
});
test('some area and layout', () => {
const layout = {
contentAlign: 11,
contentJustify: 22,
contentDirection: 33,
contentWrap: 44,
contentOverflow: 55,
contentGutter: 66,
};
const area = {
align: 1,
justify: 2,
direction: 3,
};
const areaKey = 'content';
expect(layoutParamsToArea({ areaKey, area, layout })).toEqual({
align: 1,
justify: 2,
direction: 3,
wrap: 44,
overflow: 55,
gutter: 66,
});
});
test('some area and layout with 0', () => {
const layout = {
contentAlign: 11,
contentJustify: 22,
contentDirection: 33,
contentWrap: 44,
contentOverflow: 55,
contentGutter: 66,
};
const area = {
align: 0,
justify: 0,
direction: 0,
wrap: 0,
overflow: 0,
gutter: 0,
};
const areaKey = 'content';
expect(layoutParamsToArea({ areaKey, area, layout })).toEqual({
align: 0,
justify: 0,
direction: 0,
wrap: 0,
overflow: 0,
gutter: 0,
});
});
test('area and layout not content', () => {
const layout = {
contentAlign: 11,
contentJustify: 22,
contentDirection: 33,
contentWrap: 44,
contentOverflow: 55,
contentGutter: 66,
};
const area = {
align: 1,
};
const areaKey = 'none';
expect(layoutParamsToArea({ areaKey, area, layout })).toEqual({
align: 1,
});
});

View File

@ -0,0 +1,355 @@
import makeCss from '../src/makeCss';
const mockCss = jest.fn();
const mockCssImp = (obj) => ({
emotionClassFor: obj,
});
jest.mock('create-emotion', () => () => ({
css: (obj) => mockCss(obj),
}));
beforeEach(() => {
mockCss.mockReset();
mockCss.mockImplementation(mockCssImp);
});
test('object with no media', () => {
const obj = {
a: 'a',
b: 1,
c: { a: 'b' },
};
expect(makeCss(obj)).toMatchInlineSnapshot(`
Object {
"emotionClassFor": Object {
"a": "a",
"b": 1,
"c": Object {
"a": "b",
},
},
}
`);
expect(mockCss).toHaveBeenCalled();
});
test('objects with no media', () => {
const obj1 = {
a: 'a',
c: { a: 'b', d: 1 },
};
const obj2 = {
c: { a: 'c' },
};
expect(makeCss([obj1, obj2])).toMatchInlineSnapshot(`
Object {
"emotionClassFor": Object {
"a": "a",
"c": Object {
"a": "c",
"d": 1,
},
},
}
`);
expect(mockCss).toHaveBeenCalled();
});
test('objects with media', () => {
const obj = {
a: 'a',
sm: { a: 'sm', c: 1 },
md: { a: 'md' },
lg: { a: 'lg' },
xl: { a: 'xl' },
};
expect(makeCss(obj)).toMatchInlineSnapshot(`
Object {
"emotionClassFor": Object {
"@media screen and (max-width: 576px)": Object {
"a": "sm",
"c": 1,
},
"@media screen and (min-width: 576px)": Object {
"a": "md",
},
"@media screen and (min-width: 768px)": Object {
"a": "lg",
},
"@media screen and (min-width: 992px)": Object {
"a": "xl",
},
"a": "a",
},
}
`);
expect(mockCss).toHaveBeenCalled();
});
test('objects with media', () => {
const obj1 = {
a: 'a',
sm: { a: 'sm', c: 1 },
md: { a: 'md' },
lg: { a: 'lg' },
xl: { a: 'xl' },
};
const obj2 = {
a: 'x',
sm: { a: 'smsm' },
md: { a: 'md' },
lg: { a: 'lg', c: { sm: { a: '1' } } },
xl: { a: 'xl' },
};
expect(makeCss([obj1, obj2])).toMatchInlineSnapshot(`
Object {
"emotionClassFor": Object {
"@media screen and (max-width: 576px)": Object {
"a": "smsm",
"c": 1,
},
"@media screen and (min-width: 576px)": Object {
"a": "md",
},
"@media screen and (min-width: 768px)": Object {
"a": "lg",
"c": Object {
"sm": Object {
"a": "1",
},
},
},
"@media screen and (min-width: 992px)": Object {
"a": "xl",
},
"a": "x",
},
}
`);
expect(mockCss).toHaveBeenCalled();
});
test('object with no media, react', () => {
const obj = {
a: 'a',
b: 1,
c: { a: 'b' },
};
expect(makeCss(obj, { react: true })).toMatchInlineSnapshot(`
Object {
"emotionClassFor": Object {
"a": "a",
"b": 1,
"c": Object {
"a": "b",
},
},
}
`);
expect(mockCss).toHaveBeenCalled();
});
test('objects with no media, react', () => {
const obj1 = {
a: 'a',
c: { a: 'b', d: 1 },
};
const obj2 = {
c: { a: 'c' },
};
expect(makeCss([obj1, obj2], { react: true })).toMatchInlineSnapshot(`
Object {
"emotionClassFor": Object {
"a": "a",
"c": Object {
"a": "c",
"d": 1,
},
},
}
`);
expect(mockCss).toHaveBeenCalled();
});
test('objects with media, react', () => {
const obj = {
a: 'a',
sm: { a: 'sm', c: 1 },
md: { a: 'md' },
lg: { a: 'lg' },
xl: { a: 'xl' },
};
expect(makeCss(obj, { react: true })).toMatchInlineSnapshot(`
Object {
"emotionClassFor": Object {
"@media screen and (maxWidth: 576px)": Object {
"a": "sm",
"c": 1,
},
"@media screen and (minWidth: 576px)": Object {
"a": "md",
},
"@media screen and (minWidth: 768px)": Object {
"a": "lg",
},
"@media screen and (minWidth: 992px)": Object {
"a": "xl",
},
"a": "a",
},
}
`);
expect(mockCss).toHaveBeenCalled();
});
test('objects with media, react', () => {
const obj1 = {
a: 'a',
sm: { a: 'sm', c: 1 },
md: { a: 'md' },
lg: { a: 'lg' },
xl: { a: 'xl' },
};
const obj2 = {
a: 'x',
sm: { a: 'smsm' },
md: { a: 'md' },
lg: { a: 'lg', c: { sm: { a: '1' } } },
xl: { a: 'xl' },
};
expect(makeCss([obj1, obj2], { react: true })).toMatchInlineSnapshot(`
Object {
"emotionClassFor": Object {
"@media screen and (maxWidth: 576px)": Object {
"a": "smsm",
"c": 1,
},
"@media screen and (minWidth: 576px)": Object {
"a": "md",
},
"@media screen and (minWidth: 768px)": Object {
"a": "lg",
"c": Object {
"sm": Object {
"a": "1",
},
},
},
"@media screen and (minWidth: 992px)": Object {
"a": "xl",
},
"a": "x",
},
}
`);
expect(mockCss).toHaveBeenCalled();
});
test('object with no media, styleObjectOnly', () => {
const obj = {
a: 'a',
b: 1,
c: { a: 'b' },
};
expect(makeCss(obj, { styleObjectOnly: true })).toMatchInlineSnapshot(`
Object {
"a": "a",
"b": 1,
"c": Object {
"a": "b",
},
}
`);
expect(mockCss).not.toHaveBeenCalled();
});
test('objects with no media, styleObjectOnly', () => {
const obj1 = {
a: 'a',
c: { a: 'b', d: 1 },
};
const obj2 = {
c: { a: 'c' },
};
expect(makeCss([obj1, obj2], { styleObjectOnly: true })).toMatchInlineSnapshot(`
Object {
"a": "a",
"c": Object {
"a": "c",
"d": 1,
},
}
`);
expect(mockCss).not.toHaveBeenCalled();
});
test('objects with media, styleObjectOnly', () => {
const obj = {
a: 'a',
sm: { a: 'sm', c: 1 },
md: { a: 'md' },
lg: { a: 'lg' },
xl: { a: 'xl' },
};
expect(makeCss(obj, { styleObjectOnly: true })).toMatchInlineSnapshot(`
Object {
"@media screen and (max-width: 576px)": Object {
"a": "sm",
"c": 1,
},
"@media screen and (min-width: 576px)": Object {
"a": "md",
},
"@media screen and (min-width: 768px)": Object {
"a": "lg",
},
"@media screen and (min-width: 992px)": Object {
"a": "xl",
},
"a": "a",
}
`);
expect(mockCss).not.toHaveBeenCalled();
});
test('objects with media, styleObjectOnly', () => {
const obj1 = {
a: 'a',
sm: { a: 'sm', c: 1 },
md: { a: 'md' },
lg: { a: 'lg' },
xl: { a: 'xl' },
};
const obj2 = {
a: 'x',
sm: { a: 'smsm' },
md: { a: 'md' },
lg: { a: 'lg', c: { sm: { a: '1' } } },
xl: { a: 'xl' },
};
expect(makeCss([obj1, obj2], { styleObjectOnly: true })).toMatchInlineSnapshot(`
Object {
"@media screen and (max-width: 576px)": Object {
"a": "smsm",
"c": 1,
},
"@media screen and (min-width: 576px)": Object {
"a": "md",
},
"@media screen and (min-width: 768px)": Object {
"a": "lg",
"c": Object {
"sm": Object {
"a": "1",
},
},
},
"@media screen and (min-width: 992px)": Object {
"a": "xl",
},
"a": "x",
}
`);
expect(mockCss).not.toHaveBeenCalled();
});

View File

@ -0,0 +1,78 @@
import mediaToCssObject from '../src/mediaToCssObject';
test('no object', () => {
expect(mediaToCssObject()).toEqual({});
});
test('object with no media unchanged', () => {
const obj = {
a: 'a',
b: 1,
c: { a: 'b' },
};
expect(mediaToCssObject(obj)).toEqual(obj);
});
test('object with all media', () => {
const obj = {
a: 'a',
xs: { a: 'xs' },
sm: { a: 'sm' },
md: { a: 'md' },
lg: { a: 'lg' },
xl: { a: 'xl' },
xxl: { a: 'xxl' },
};
expect(mediaToCssObject(obj)).toMatchInlineSnapshot(`
Object {
"@media screen and (max-width: 576px)": Object {
"a": "xs",
},
"@media screen and (min-width: 1200px)": Object {
"a": "xxl",
},
"@media screen and (min-width: 576px)": Object {
"a": "md",
},
"@media screen and (min-width: 768px)": Object {
"a": "lg",
},
"@media screen and (min-width: 992px)": Object {
"a": "xl",
},
"a": "a",
}
`);
});
test('object with all media with react option', () => {
const obj = {
a: 'a',
xs: { a: 'xs' },
sm: { a: 'sm' },
md: { a: 'md' },
lg: { a: 'lg' },
xl: { a: 'xl' },
xxl: { a: 'xxl' },
};
expect(mediaToCssObject(obj, { react: true })).toMatchInlineSnapshot(`
Object {
"@media screen and (maxWidth: 576px)": Object {
"a": "xs",
},
"@media screen and (minWidth: 1200px)": Object {
"a": "xxl",
},
"@media screen and (minWidth: 576px)": Object {
"a": "md",
},
"@media screen and (minWidth: 768px)": Object {
"a": "lg",
},
"@media screen and (minWidth: 992px)": Object {
"a": "xl",
},
"a": "a",
}
`);
});

View File

@ -0,0 +1,17 @@
const fs = require('fs');
// Read the identity-obj-proxy as text. NOTE This only works because the entire module is inside one file
const identityObjProxySrc = fs.readFileSync(require.resolve('identity-obj-proxy'), 'utf-8');
/**
* The jest config option "moduleNameMapper" does not resolve to absolute paths, which
* can cause conflicts with similar file names. In this case, "style.less" and "style.js" are
* both mocked with the identity-obj-proxy. This causes compiling of @material-ui to fail.
* Instead use the "transforms" option to accomplish stubbing CSS/LESS files with identityObjProxy
*/
module.exports = {
process() {
return identityObjProxySrc;
},
};

View File

@ -0,0 +1,5 @@
import row from '../demo/examples/row.yaml';
import runExampleTests from './runExampleTests';
runExampleTests(row);
runExampleTests(row, { highlightBorders: false });

View File

@ -0,0 +1,44 @@
import React from 'react';
import renderer from 'react-test-renderer';
import AutoBlockSim from '../demo/AutoBlockSim';
const runExampleTests = (examples, options = { highlightBorders: true }) => {
const makeCss = jest.fn();
const makeCssImp = (style, op) => JSON.stringify({ style, options: op });
beforeEach(() => {
makeCss.mockReset();
makeCss.mockImplementation(makeCssImp);
Object.defineProperty(window, 'matchMedia', {
writable: true,
value: jest.fn().mockImplementation((query) => ({
matches: false,
media: query,
onchange: null,
addListener: jest.fn(), // deprecated
removeListener: jest.fn(), // deprecated
addEventListener: jest.fn(),
removeEventListener: jest.fn(),
dispatchEvent: jest.fn(),
})),
});
});
examples.forEach((ex) => {
test(ex.id, () => {
const component = renderer.create(
<AutoBlockSim
block={ex}
state={{}}
areaKey="content"
makeCss={makeCss}
highlightBorders={options.highlightBorders}
/>
);
const tree = component.toJSON();
expect(tree).toMatchSnapshot();
});
});
};
export default runExampleTests;

View File

@ -0,0 +1,77 @@
const HtmlWebpackPlugin = require('html-webpack-plugin');
const path = require('path');
module.exports = {
entry: './demo/index',
mode: 'development',
devServer: {
contentBase: path.join(__dirname, 'dist'),
port: 3001,
},
// webpack 5 support polyfills
resolve: { fallback: { path: 'path-browserify', buffer: 'buffer' } },
module: {
rules: [
{
test: /\.m?jsx?$/,
loader: 'babel-loader',
// TODO: FIXME: do NOT webpack 5 support with this
// x-ref: https://github.com/webpack/webpack/issues/11467
// waiting for babel fix: https://github.com/vercel/next.js/pull/17095#issuecomment-692435147
resolve: {
fullySpecified: false,
},
options: {
presets: ['@babel/preset-react'],
},
},
{
test: /\.ya?ml$/,
type: 'json',
use: 'yaml-loader',
},
{
test: /\.css$/,
use: [
{
loader: 'style-loader',
},
{
loader: 'css-loader', // translates CSS into CommonJS
},
],
},
{
test: /\.less$/,
use: [
{
loader: 'style-loader',
},
{
loader: 'css-loader', // translates CSS into CommonJS
},
{
loader: 'less-loader', // compiles Less to CSS
options: {
lessOptions: {
modifyVars: {
'@primary-color': '#697a8c',
'@link-color': '#1890ff',
'@layout-header-background': '#30383f',
'@layout-sider-background': '#30383f',
'@menu-dark-submenu-bg': '#21262b',
},
javascriptEnabled: true,
},
},
},
],
},
],
},
plugins: [
new HtmlWebpackPlugin({
template: './public/index.html',
}),
],
};