Intro
This documentations is created by M1. studio
Our Missions
- Self Growth
- Team Growth
- Community Growth
This Page Objectives
- Unique Issue: only come across an error or bug ONCE, only ask question ONCE
- Clear: easy to read for new commmers.
Target Users
- M1 coders and designers
Contents
This will render
Hello M1.
class HelloM1 extends Cell {
cellRender(){
return <RoFill ro='cols 1600'>
<Label ca='w center 200' text='Hello M1.'/>
</RoFill>ß
}
}
- Definitions and Concepts
- Code guideline
- Design guideline
- Recruitments
Code Guideline
Guideline to source code
when see this.trigger means component has onActions
Cell converts props to state automatically for some fields
Guideline for adding fonts
Using Google Fonts
<html>
<head>
<link rel="stylesheet"
href="https://fonts.googleapis.com/css?family=Tangerine">
<style>
body {
font-family: 'Tangerine', serif;
font-size: 48px;
}
</style>
</head>
<body>
<div>Making the Web Beautiful!</div>
</body>
</html>
- Copy and paste the selected fonts into the
<head>of HTML. - Using CSS rules to specify font-family
Using @font-face
<html>
<head>
<style>
@font-face {
font-family: "SF Pro Text";
src: url("/fonts/SF-Pro-Text-Regular.woff") format('woff');
}
@font-face {
font-family: "SF Pro DisPlay Black";
src: url("/fonts/SF-Pro-Display-Black.woff") format('woff');
}
@font-face {
font-family: "SF Pro DisPlay Bold";
src: url("/fonts/SF-Pro-Display-Bold.woff") format('woff');
}
body {
font-family: 'SF Pro Text';
font-size: 48px;
}
</style>
</head>
<body>
<div>Making the Web Beautiful!</div>
</body>
</html>
- Download the font
- Use online fonts converter https://fonts.kaihag.com/ to convert font files to WOFF
- Add custom font files into the
<style>of HTML document (in html.index and template.js) by using@fontface
Guideline for using DialogManager
- import DialogManager by require it
const Dialog = require('core/DialogManager')()
// item_text.jsx
const DATA = (props, state, cell) => {
text: {
...labels_(`nav-button-${props.id}`),
...Dialog.events_trigger(`${list[props.id]}`)()
}
}
add events_trigger('event_key')() into the element which execute all handlers and behaviors attached to the matched elements for the given event
add add_display('event_key') into the element which listens given event
/// item_icon.jsx
const DATA = (props, state, cell) => {
icon: {
svg: props.icon,
selected: Dialog.add_display(list[props.id]),
}
}
const STYLES = (props, state, styles, cell) => {
return {
icon: {
style: (args) => {
const { selected } = args.state
const e = selected
return {
width: `calc(100vw/1280 * 44)`,
minWidth: `calc(100vw/1280 * 44)`,
height: `calc(100vw/1280 * 44)`,
fill: e ? '#1A1446' : '#C3C8DE',
}
}
}
}
}
Components
Components are big part of our framework. This section should describe all about
PrimaryComponents
ButtonLink
class PageHome extends Cell {
cellRender(){
const styles = {
button: {
width: '100%',
height: '100%',
fonSize: 16,
backgroundColor: 'pink',
}
}
return <RoAuto ro='cols 1600'>
<ButtonLink ca='left 10 top 0 w 200 h 40' style={{...styles.button}} href='/home'>
Click
</ButtonLink>
<RoAuto/>
}
}
| Props | Type | Meaning |
|---|---|---|
| href | string | Specifies the URL of the page the link goes to |
| target | string, default: _seft | Specifies where to open the linked document |
| style | object | Style of button |
| onActions.click | func | The callback func trigged on click |
| onActions.hover | func | The callback func trigged on hover |
| children | node | The content of button |
TextAuto
class PageHome extends Cell {
cellRender(){
const styles = {
text: {
fonSize: 16,
color: 'pink'
}
}
return <RoAuto ro='cols 1600'>
<TextAuto ca='left 10 top 0 w 200' style={{...styles.text}} flex={2} text='M1.studio' {...labels('unique string')}/>
<RoAuto/>
}
}
| Props | Type | Meaning |
|---|---|---|
| text (cms: ...labels('')) | string | The content of the component |
| style | object | The style of text |
| flex | num [1-9], default: 5 | The position of text in flex container |
| text_flex | string or int | Override flex if not null |
| onActions.click | func | The callback func trigged on click |
| onActions.hover | func | The callback func trigged on hover |
ImgObj
class PageHome extends Cell {
cellRender(){
return <RoAuto ro='cols 1600'>
<Img ca='left 10 w 200'
style={{width: '100%', objectFit: 'cover'}}
src="https://storage.googleapis.com/m1-public/NoImage.png">
</Img>
<RoAuto/>
}
}
| Props | Type | Meaning |
|---|---|---|
| src | string, drip | Specifies the URL of an image |
| src_path | string, drip | Specifies the URL of an image |
| url | string, drip | Specifies the URL of an image |
| use_original | bool | |
| raw | bool | |
| style | object | style of image |
ImgSvg
import svg_def from './svg_default.txt'
class PageHome extends Cell {
cellRender(){
return <RoAuto ro='cols 1600'>
<Svg ca='left 10 w 200 h 200'
svg={svg_def}>
</Svg>
<RoAuto/>
}
}
| Props | Type | Meaning |
|---|---|---|
| svg | string | Specifies the name of svg |
| zsvg | string | |
| onActions.click | func | The callback func trigged on click |
Video
class PageHome extends Cell {
player = null
cellRender(){
return <RoAuto ro='cols 1600'>
<Video ca='left 10 w 200 h 200'
src="https://archive.org/download/BigBuckBunny_124/Content/big_buck_bunny_720p_surround.mp4"
poster="https://peach.blender.org/wp-content/uploads/title_anouncement.jpg?x11217"
onActions={ action => e => {
if(action === 'ref') {
this.player = e.value
}
else if (action === 'play') {
this.sub.emit('button', false)
}
else if (action === 'pause') {
this.sub.emit('button', true)
}
}
}
/>
<ButtonText text={'Play'}
show={this.sub.drip('button')}
onActions={action => e => {
if (action === 'click') {
if (this.player) this.player.play()
}
}
style={args => {
const {show} = args.state
return {
...styles.button,
...(!show && {display: 'none'})
}
}}
/>
<RoAuto/>
}
| Props | Type | Meaning |
|---|---|---|
| src | string | Specifies the URL of the video |
| poster | string | Specifies an image to be shown until the user hits the play button |
| onActions.click | func | The callback func trigged on click |
Extended Components
ButtonIcon
class PageHome extends Cell {
cellRender(){
const styles = {
svg: {
container: {},
icon: {
width: '100%',
height: '100%',
objectFit: 'cover
}
}
}
return <RoAuto ro='cols 1600'>
<ButtonIcon ca='left 10 w 200'
svg={svg_def}
__key="unique string"
__level="s2"
style={styles.svg}
/>
<RoAuto/>
}
}
| Props | Type | Meaning |
|---|---|---|
| svg | Specifies the name of svg | |
| __key | string | The key cms |
| __level | string (global, s2, default :s1) | level of cms |
| style.container | object | Specific style for container wrap image in button |
| style.image | object | Specific style for image in button |
| onActions.click | func | The callback func trigged on click |
| onAcitons.hover | func | The callback func trigged on hover |
ButtonImage
class PageHome extends Cell {
cellRender(){
const styles = {
image: {
container: {},
image: {
width: '100%',
height: '100%',
objectFit: 'cover
}
}
}
return <RoAuto ro='cols 1600'>
<ButtonImage ca='left 10 w 200'
_key="unique string"
_level="s2"
style={styles.image}/>
<RoAuto/>
}
}
| Props | Type | Meaning |
|---|---|---|
| _key | string | The key cms |
| _level | string (global, s2, default :s1) | level of cms |
| style.container | object | Specific style for container wrap image in button |
| style.image | object | Specific style for image in button |
| onActions.click | func | The callback func trigged on click |
| onAcitons.hover | func | The callback func trigged on hover |
ButtonText
class PageHome extends Cell {
cellRender(){
const styles = {
button: {
container: {
display: 'flex',
alignItems: 'flex-end'
},
text: {
fontSize: 16,
color: 'pink'
}
}
}
return <RoAuto ro='cols 1600'>
<ButtonText ca='left 10 w 200' /// no cms
text='Click'
style={styles.button}
onActions={action => e => {
if(action === 'click'){
console.log('click')
}
}}/>
<ButtonText ca='left 10 w 200'
text='Click' /// cms and default text
_key="unique string"
_level="s2"
style={styles.button}/>
<RoAuto/>
}
}
| Props | Type | Meaning |
|---|---|---|
| text | string | The content of the component |
| _key | string | The key cms |
| _level | string (global, s2, default :s1) | level of cms |
| style.container | object | Specific style for container wrap text in button |
| style.text | object | Specific style for text in button text |
| onActions.click | func | The callback func trigged on click |
| onAcitons.hover | func | The callback func trigged on hover |
Slate
class Home extends Cell {
cellRender() {
const styles = {
container: {
fontSize: 'inherit',
minHeight: 300,
minWidth: 100,
color: "#434545",
fontFamily: "Helvetica Neue",
fontWeight: 400,
letterSpacing: 0.5,
lineHeight: "28px",
height: "100%",
width: "100%"
},
toolbar_wrap: {
width: '200px',
position: 'fixed',
bottom: 0,
right: 20,
boxSizing: "border-box",
padding: 15,
border: '1px solid #ededed',
background: '#FFFFFF',
zIndex: 9999,
},
slate: {
/// do not config this style ofter
/// example: change all text color to red
base: {
color: 'red',
fontSize: '18em',
lineHeight: 1.75,
},
/// specific styles to config
h1: {
fontSize: '32em',
fontWeight: 700,
lineHeight: 1.35,
marginBottom: '0.5em'
},
h2: {
fontSize: '24em',
fontWeight: 700,
lineHeight: 1.35,
boxSizing: 'border-box',
marginBottom: '0.5em'
},
h3: {
fontSize: '20em'
},
img: {
minHeight: 50,
}
}
}
return <RoAuto ro='cols 1600'>
<SlateRich ca='left 10 w 200'
style={styles}
{...slates_rich('unique_string')}/>
<RoAuto/>
}
}
| Props | Type | Meaning |
|---|---|---|
| slates_rich('') | string | The key cms |
style base vs specific style for block
Paging
| Props | Type | Meaning |
|---|---|---|
| number_of_pages | num | total pages |
| value | num | |
| styles.container | object | the style of container |
| styles.item | object | the style of items in container |
| onActions.click | func | The callback func trigged on click |
CaroComponents
RoFill
RoFill contain ro as prop
ro receive cols to calculate caro unit by using 100 ViewWidth/cols
Children of RoFill will receive prop as ca
Most used props in Ca
| Props in .ca | Meaning |
|---|---|
| left | left |
| w | width |
| top | top |
| h | height |
RoFill No Text Cases
RoFill is used to create website layouts. With specific layout validation, You can create parents first, all children need to follow Parent
Note:when using RoFill it is always necessary to identify the parent area display (top left w h or top left w)
return<RoFill ro={`cols 1280`} style={this.styles.container}>
<div ca='left 10 top 0 h 50 w 50' style={this.styles.ex00} />
<div ca='left 10 top 50 h 50 w 50' style={this.styles.ex00} />
<div ca='left 10 top 100 h 50 w 50' style={this.styles.ex00} />
<div ca='left 100 top 150 h 50 w 50' style={this.styles.ex00} />
</RoFill>

Rofill also has some special cases, determined by height, width
- default ca.w= fill (Fill all from start to end position)
- default ca.h = auto or ca.h = none (Height of RoFill depends on it's children)
- default ca.top = auto --> relative to last top + height last component, if last comp has h == auto, then just top using Flex to auto size section
cellRender() {
return <RoFill ro={`cols 1280`} style={this.styles.container}>
<RoFill ca='left 500 top 0 h 200 w 250' style={this.styles.ex02}>
<div ca='left 10 top 10 h 50 w 50' style={this.styles.ex00} />
<div ca='left 10 top auto h 50 w 50' style={this.styles.ex00} />
</RoFill>
</RoFill>
}

cellRender() {
return <RoFill ro={`cols 1280`} style={this.styles.container}>
{/* case 1: h : auto or h: '' */}
<RoFill ca='left 500 top 0 w 250' style={this.styles.ex02}>
<div ca='left 10 top 0 h 50 w 50' style={this.styles.ex00} />
<div ca='left 10 top 50 h 50 w 50' style={this.styles.ex00} />
<div ca='left 10 top 100 h 50 w 50' style={this.styles.ex00} />
<div ca='left 100 top 150 h 50 w 50' style={this.styles.ex00} />
</RoFill>
{/* case 2 : h : size */}
<RoFill ca='left 770 top 40 h 300 w 300' style={this.styles.ex02}>
<div ca='left 10 top 50 h 50 w 50' style={this.styles.ex00} />
<div ca='left 50 top 70 h 50 w 50' style={this.styles.ex00} />
<div ca='left 40 top 10 h 50 w 50' style={this.styles.ex00} />
<div ca='left 40 top 130 h 150 w 150' style={this.styles.ex00} />
</RoFill>
</RoFill>
</RoFill>
}
}

RoFill Text Cases
| Retangle | Values | Case |
|---|---|---|
| Pink | left 490 top 0 w 100 | h:none |
| Blue | left 150 top 0 w 150 h auto | h: auto |
| Green | left 320 top 0 w 150 h 100 | |
| Orange | left 0 top 0 w 100 h fill | h:fill |
| Lightblue | left 0 bottom 100 w 150 h 150 | bottom : 100 |
cellRender() {
return <RoFill ro={`cols 1280`} style={this.styles.container}>
<RoFill ca="left 500 top 10 w 600 h 100" style={this.styles.ex00}>
<div ca='left 0 top 0 w 100 h fill' style={this.styles.ex02}>test check Loren test test test hihihihihi</div>
<div ca='left 150 top 0 w 150 h auto' style={this.styles.ex03}>test test test test test testste dsnahjasd hihi hih ih ih i</div>
<div ca='left 490 top 0 w 100' style={this.styles.ex04}>test test test test test testste tetst tste tsetste</div>
<div ca='left 320 top 0 w 150 h 100' style={this.styles.ex05}>test test test test test testste</div>
</RoFill>
</RoFill>
cellRender(){
return <RoFill ca='left 0 top 0 w 300 h 300' ro={`cols 1280`} style={{backgroundColor:'blue'}}>
<div ca="left 0 bottom 100 w 150 h 150" style={{backgroundColor:'lightblue'}}>test Bottom</div>
</RoFill>
}

RoAuto
RoAuto contain ro as prop
ro receive cols to calculate caro unit by using 100 ViewWidth/cols
Children of RoAuto will receive prop as ca
Most used props in Ca
| Props in .ca | Meaning |
|---|---|
| left | left |
| w | width |
| top | top |
| h | height |
RoAuto General Cases
cellRender(){
return <RoAuto ro={'cols 1600'} style={style.container}>
<div ca='left 300 w 300 h 200' style={style.background2}></div>
<div ca='left 0 w 300 h 200' style={style.background3}></div>
<div ca='left 300 w 300 h 200' style={style.background4}></div>
<div ca='left 600 w 300 h 200' style={style.background1}></div>
<div ca='left 450 w 300 h 200 top -100' style={style.background3}></div>
<div ca='left 350 w 300 h 200 top -50' style={style.background4}></div>
</RoAuto>
}
RoAuto is used to create layouts for components. Height of RoAuto depends on it's children, the reason is RoAuto can elasticate flexibly when the height of it's children changes. As you can see in the picture below:
Background Grey of RoAuto is the biggest one which contains many other rectangles. Each retangle has their own Width and Height, it's Top will start from the bottom of above retangle (Top = 0 or No Top). If we want to overlap retangles with each other, changing the their Top to minus (the last 2 examples in code snippet). We change top of below retangle from 0 to -100, it will move up to half of above retangle's height (h 200), and so on ...

RoAuto Text Cases
cellRender(){
return <RoAuto ro={'cols 1600'} style={style.container}>
<div ca='left 300 w 300 h 100' style={style.background2}>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</div>
<div ca='left 0 w 300 top 20' style={style.background3}>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</div>
<div ca='left 300 w 300 top 50 h 100' style={style.background4}>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</div>
<div ca='left 600 w 300 ' style={style.background1}>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</div>
<div ca='left 600 w 300' style={style.background5}></div>
</RoAuto>
| Retangle | Values | Case |
|---|---|---|
| Pink | h 100 | no top |
| Blue | top 20 | no h |
| Green | top 50 h 100 | have top & h |
| Red | no top & h | |
| Yellow | no top & h and children in retangle |

As you can see in the picture:
| Props | Stand for |
|---|---|
| top | margin-top |
| h | padding-top |
Because height of parents will depends on inside children. So, if we set height for parents, they will not follow their children.
Take Pink & Green retangles as an example, we set h equal to 100, so height of parents can not be auto.
When ever the text of children is too long, they will get over the size of their parents.
On the other hand, in Blue and Red retangles, we do not set h for parent, so the long text can not influence to their parent's height.
Eventually, in Yellow retangle,there is no top, h and children, so the retangle can not display it's appearance.
ListComponents
ListGrid
Example:
const BLUEPRINT = () => {
return `root@: RoAuto ca(left 0 w 1360) ro(cols 1360){
list_basic@list_screen2:ListGrid ca(left 0 w 562 top -268)
}
}`
}
const DATA = (props, state, cell) => {
const { link_text, labels, svgs, images, links_ } = props._cms
return {
list: {
list_content: [
{ id: 'screen3_1', svg: table_svg1, title: 'Communication', text: 'Books, storytelling, language/ literacy games' },
{ id: 'screen3_2', svg: table_svg2, title: 'Music listening', text: 'Music and movement, singing' },
{ id: 'screen3_3', svg: table_svg3, title: ' Dramatic play', text: 'Family and dramatic play, dress ups and props' },
{ id: 'screen3_4', svg: table_svg4, title: 'Creative play', text: ' Play dough, clay, painting, art and collage' },
{ id: 'screen3_5', svg: table_svg5, title: 'Manipulative play', text: 'Blocks, puzzles, threading, construction sets' },
{ id: 'screen3_6', svg: table_svg6, title: 'Physical play', text: ' running, ball games, balancing and climbing equipment, sandpit' },
{ id: 'screen3_7', svg: table_svg7, title: ' Exploratory play', text: 'water, sand, science and nature, learning about the living world' },
{ id: 'screen3_8', svg: table_svg8, title: 'Constructive play', text: 'Carpentry and junk play' },
{ id: 'screen3_9', svg: table_svg9, title: 'Cognitive games', text: 'Maths games and computers for older age group' },
],
item: require('src/Des/Vinh/Components/_svg_activities').default,
col_space: 40,
col_num: 3,
cols: 1040,
row_space: 40,
row_height: 200
},
}
}
const STYLES = (props, state, styles) => {
return {
list_basic: {
style: {
container: {
width: '100%',
height: '100%'
},
item: {
width: '100%',
height: '100%',
}
}
},
}
}
export default class App extends Cell {
cellRender({ props, state, styles }) {
return <CellBlue
cascade={this.props}
injected_components={props._components}
components={{
ListGrid: require('list/ListGrid')
}}
blueprint={BLUEPRINT()}
data={DATA(props, state, this)}
styles={STYLES(props, state, styles, this)}
/>
}
}
ListGrid helps divide rows and columns of rectangles consistently. However, the width and height of each rectangle must be specific in order to make sure rectangles are similar to each other
In Components
import ListGrid first by require it
ListGrid: require('list/ListGrid')
In Styles
ListGrid contains 2 properties in it's style, they are container and item. In this case, container is root, and item is element that root contains.
In BluePrint
Call ListGrid as Component after import it, and pass it an array contain objects to resolve.
In Data
We have to pass 7 properties for ListGrid to use:
list_content:
data of each objectwill stand for what will be displayed in eachRectangleitem: pass a component that you have created before so that you can display it in
Gridcol_space: distance between each column
col_num: number of column that you want to devide.
cols: columns for ro(cols ...)
row_space: distance between each row
row_height: height of each rectangle
ListLazyLoad
// Create a component contains data
const BLUEPRINT = () => {
return `root@: RoAuto ro(cols 600){
string@: TextAuto ca(left 100 h 25 w 100)
}`
}
const DATA = (props, state, cell) => {
return {
string: {
text: state.index + 'hello'
}
}
}
const STYLES = (props, state, styles, cell) => {
return {
string: {
style: {
width: '100%',
height: '100%',
fontSize: 2,
color: 'red'
}
}
}
}
export default class App extends Cell {
cellRender({ props, state, styles }) {
return <CellBlue
cascade={this.props}
injected_components={props._components}
components={{
RoAuto: require('caro/RoAuto'),
RoFill: require('caro/RoFill'),
TextAuto: require('primary/TextAuto'),
}}
blueprint={BLUEPRINT()}
data={DATA(props, state, this)}
styles={STYLES(props, state, this, styles)}
/>
}
}
//----------------------------------------------------------------------------------------------------------------------------------------------------------------------
//Component uses ListLazyLoad
const BLUEPRINT = () => {
return `root@: RoAuto ro(cols 1200){
list@: ListLazyLoad ca(left 100 w 600 h 300) flex(2)
}`
}
const DATA = (props, state, cell) => {
return {
list: {
count: 1000,
current_page: 2,
paging_num: 5,
component: require('src/Des/Vinh/Test').default,
},
}
}
const STYLES = (props, state, styles, cell) => {
return {
list: {
style: {
width: '100%',
maxHeight: '100%',
border: 'solid 1px black',
}
},
}
}
export default class App extends Cell {
cellRender({ props, state, styles }) {
return <CellBlue
cascade={this.props}
injected_components={props._components}
components={{
RoAuto: require('caro/RoAuto'),
RoFill: require('caro/RoFill'),
TextAuto: require('primary/TextAuto'),
ListLazyLoad: require('src/components/ListComponents/ListLazyLoad'),
}}
blueprint={BLUEPRINT()}
data={DATA(props, state, this)}
styles={STYLES(props, state, this, styles)}
/>
}
}

ListLazyLoad helps add more the specific number of data everytime we scroll.
In Components
import ListLazyLoad first by require it.
ListLazyLoad: require('list/ListLazyLoad')
In Styles
the most important thing inListGrid is maxHeight, because we set max height to make the wrap can scroll.
In BluePrint
Call ListLazyLoad as Component after import it
In Data
We have to pass 4 properties for ListLazyLoad to use:
count: the
total number of datathat the list will containscurrent_page: current page that we are staying at. Notice that page num works following
index, that means if weset 0, we are moving topage 1.paging_num: specific number of data that we want to print out in each page. If we set
5, each page will contain5 elements.component: the component contains data that we have created before. In this case, the component is
class Testin the code snippet.
ListAutoColumn
Example:
const BLUEPRINT = () => {
return `root@: RoAuto ro(cols 1280){
list_auto_col@list:ListAutoColumn ca(left 100 w 500 h 300 top 0)
}
}`
}
const DATA = (props, state, cell) => {
return {
list: {
list_content: [
{ text: '11 11 11 11 11 11' },
{ text: '22 22 22 ' },
{ text: '33 33 33 33 33 33 ' },
{ text: '44 44 44 44 44 44' },
{ text: '55 55 55 55 55 55 ' },
{ text: '66 66 66 66 66 66' },
],
item: require('primary/TextAuto'),
},
}
}
const STYLES = (props) => {
return {
list_auto_col: {
style: {
container: {
width: '100%',
height: '100%',
},
column: {
width: `${100 / 5}%`,
},
item: {
width: '100%',
fontSize: 20,
}
}
},
}
}
export default class App extends Cell {
cellRender({ props, state, styles }) {
return <CellBlue
cascade={this.props}
components={{
RoAuto: require('caro/RoAuto'),
RoFill: require('caro/RoFill'),
ListAutoColumn: require('list/ListAutoColumn'),
}}
injected_components={props._components}
blueprint={BLUEPRINT()}
data={DATA(props, state, this)}
styles={STYLES(props, state, styles, this)}
/>
}
}

As you can see in the example above, in the first row, column number 2 has shortest content, so in the next row, column number 4 is the start of the row, it will be placed at the position below column number 2. Besides that, column number 1 apprears first as compared to column number 3, so that column number 5 will be placed below col number 1 and col number 6 will be placed below col number 3
In brief,ListAutoColumn works following the principle of automatically filling the next element below the shortest content of the previous elements in the previous row.
In Components
import ListGrid first by require it
ListAutoColumn: require('list/ListAutoColumn')
In Styles
ListAutoColumn contains 3 properties in it's style, they are container, item and column. In this case, container is root, and item is element that root contains, column is the width of column depending on how we devide.
In BluePrint
Call ListAutoColumn as Component after import it, and pass it an array contain objects to resolve.
In Data
We have to pass 2 properties for ListAutoColumn to use:
list_content:
data of each objectwill stand for what will be displayeditem: pass a component that you have created before so that you can use it for each object in the array
GalleryRow
import Item from './__item'
const BLUEPRINT = () => `root@: RoAuto ro(cols 375){
gallery@: GalleryRow ca(left 0 top 25 w 375 h 540)
} `
const DATA = (props, state, cell) => {
const { labels, images } = props._cms
const __api = state.__api || cell.__api
return {
gallery: {
ro: {
cols: 375,
positions_array: [0, 280, 560, 840, 1120],
main_index: 0,
delay: 0.3
},
data: [0, 1, 2, 3].map((index) => {
return {
img: images(`item-${index}-img`),
content: labels(`item-${index}-content`),
title: labels(`item-${index}-title`),
}
}),
render: ({ data, index }) => {
return <Item
_cms={cell.props._cms}
_components={cell.props._components}
key={index}
{...data}
/>
}
}
}
}
const STYLES = (props, state, styles, cell) => {
return {
root: {
style: {
fontSize: "calc(100vw/375)" //fontSize: "0.0625em",
}
}
}
}
class Gallery extends Cell {
__api = {}
cellRender({ styles, state, props }) {
return <CellBlue
cascade={this.props}
components={{
RoAuto: require('caro/RoAuto'),
GalleryRow: require('list/GalleryRow'),
}}
injected_components={props._components}
blueprint={BLUEPRINT(props, state)}
data={DATA(props, state, this)}
styles={STYLES(props, state, styles, this)}
/>
}
| Props | Type | Meaning |
|---|---|---|
| ro | object | create layout for GalleryRow. |
| render | func | render a component for GalleryRow |
| data | array | passing data to the component |
There are 4 properties of ro :
- cols: GalleryRow receive cols to calculate
caro unitby dividing the width of GallleryRow to cols - positions_array : array of spaced values from starting and ending points
- main_index: index of the component that is displayed first
- delay: Specifies how many seconds a transition effect takes to complete.
Popup Components
PopupFixed
class Home extends Cell {
constructor(){
this.sub = new Sub()
this.sub.add('popup')(null, {})
}
const style = args => {
const { show } = args.state
return {
container: {
...(!show && { display: 'none' }),
width: '100%',
height: '100%',
opacity: '0.8'
},
wrap: {
backgroundColor: 'orange'
}
}
}
cellRender() {
return (
<RoAuto ro='cols 1200'>
<PopupFixed ca='left 0 w 1200' modal={true}
style={style}
show={this.sub.drip('popup').as(i => i.show)}
onActions = { action => e => {
if (action === 'close') {
this.sub.emit('popup', { show: false })
}
}}>
<div>Title</div>
<div>content</div>
</PopupFixed>
<ButtonText ca='left 200 top 200 w 200 h 40' text='Open Popup'
onActions={action => e => {
if(action === 'click'){
this.sub.emit('popup', {show: true})
}
}}>
</ButtonText>
</RoAuto>
)
}
}
| Props | Type | Meaning |
|---|---|---|
| children | node | The content of the component. |
| modal | bool (default: false) | tell CaroComponents it'a a modal |
| show | drip | |
| onActions.close | func | The callback func trigged close popup |
| style.container | object | The style of the container |
| style. wrap | object | the style of the white part of container |
Form Components
Input
| Props | Type | Meaning |
|---|---|---|
| value | string | Specifies the value of an <input> element |
| disabled | drip | Specifies that an <input> element should be disabled |
| placeholder | drip | Specifies a short hint that describes the expected value of an <input> element |
| regex_error | regex | check the validity of the value |
| regex_input | regex | check the validity of the value |
| onActions.change | func | The callback func trigged on change |
| onActions.focus | func | The callback func trigged when the user sets focus on input |
| onActions.blur | func | The callback func trigged when input loses focus. |
Select
TextArea
When to use
When to use Caro
RoAuto
RoFill
When to use Text
Label
Slate
When to use Buttons
ButtonText
ButtonSvg
ButtonImage
When to use Img vs ButtonImg
Snippets
Made by M1
<ButtonText text='Published by M1.Studio with ♡' href='https://m1studio.co'/>
Snippets are short code lines that are often used in many projects
Met Issues
This sections contains all issues met during project
#1
date: 1.4.2019
Credits
This documentation page was created with Slate.