How To Use
**INSTALL WITH NPM or YARN **
npm install @joloh/jspattern
or
yarn add @joloh/jspattern
*** With auto-reload. Thanks to design patterns**
HTML Components
- Figure
- Form
- Header
- Table
- Canvas
- TableHeader
- TableBody
- TableFooter
- TableHead
- TableRow
- DataCell
- Icon
- Image
- Input
- Paragraph
- Section
- Article
- List
- ListItem
- Mark
- Span
- Button
- DefinitionList
- DefinitionListTerme
- DefinitionListDescription
- Grid
- Main
- IconButton
Each class has a component that use it. EX : Form component uses FormClass and Each Input uses InputClass
Start in 5 steps.
1 - Create an index.html file
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<main id="root"></main>
<script type="module" src="index.js"></script>
</body>
</html>
2 - create the index.js file
import {App} from "@joloh/jspattern";
import {Home} from "./views";
new App({
home: Home,
});
3 - Create your first page. It should look like this**.
import {Header, Paragraph, Section} from "@joloh/jspattern";
export const Home = (params) => {
return Section({
children: [
Header({textContent: "Home"}),
Section({
children: [
Paragraph({text : " Lorem ipsum dolor sit amet."}),
]
})
]
})
}
4 - please add google font link in your index.html file or use another library
<link href="https://fonts.googleapis.com/css?family=Material+Icons|Material+Icons+Outlined|Material+Icons+Two+Tone|Material+Icons+Round|Material+Icons+Sharp" rel="stylesheet">
5 - To build the project I use PARCEL. PAGE Once you're done. create a symbolic link for PARCEL or just run this command in the terminal from the root of your project :
node_modules/.bin/parcel index.html
You will have the project running on http://localhost:1234
PAGE EXEMPLE
import {
Article,
Button, DefinitionList, DefinitionListDescription, DefinitionListTerme,
Figure,
Form,
Grid,
Header,
Icon,
List,
ListItem,
Paragraph,
Section, Image
} from "@joloh/jspattern";
import {_console} from "@joloh/jspattern";
// ASSUMING YOU HAVE AN EXPORTABLE CONST CALLED actionsTypes somewhere
import {actionsTypes} from "../redux/redux";
// ASSUMING YOU HAVE AN IMAGE CALLED img.png somewhere
import * as img from "../assets/img.png"
// ASSUMING YOU HAVE A PAGE CALLED Contact somewhere
import {Contact} from "./Contact";
export const Home = (params) => {
const {stateObserver, useState, navigation, useReduxProvider, updateDom} = params({
text: "text",
image: null
});
const setText = useState("text");
const setImage = useState('image');
const [store, dispatch] = useReduxProvider();
const formItems = {
fields: [
{name: "name", tagName: "input", attributes: {placeholder: "Name", type: "text", className: "input", style: {background: "aliceblue"}, onkeydown: okKeydown}},
{name: "placeholder", tagName: "input", attributes: {placeholder: "Placeholder", type: "text", className: "input", style: {background: "aliceblue"}, onkeydown: okKeydown}},
{name: "type",tagName: "input", attributes: {placeholder: "Type", type: "text", className: "input", style: {background: "aliceblue"}, onkeydown: okKeydown}},
{name: "content", tagName: "input", attributes: {placeholder: "Content", type: "text", className: "input", style: {background: "aliceblue"}, onkeydown: okKeydown}},
],
}
return Section({
style: {margin: "1rem 2rem"},
children: [
Section({children: [
Header({textContent: "Custom Form"}),
Form({className: "custom-table-form", items: formItems.fields}),
]
}),
Section({
className: "custom-table-form__icon",
style: {marginTop: "10px"},
children: [
Icon({
className: "custom-table-form__icon",
textContent: "remove_circle_outline",
onclick: function (e) {
_console("remove_circle_outline click", e);
}
}),
Icon({
className: "custom-table-form__icon",
textContent: "add_circle_outline",
id: "abcd",
onclick: function (e) {
_console("add_circle_outline click", e);
const prods = store.products || [];
// demo
[{id: 1, name: "iphone",},
{id: 2, name: "samsung",},
{id: 3, name: "huawei",},
].forEach(p => prods.push(p));
dispatch({
type: actionsTypes.PRODUCTS,
products: prods
});
updateDom({element: e.target, data: {style: {backgroundColor: "red"}}});
_console("add_circle_outline store", store);
}
})
]
}),
Figure({className: "home-image-easy", style: { position: "relative" }, children: [
Image({src : img, style: {width: "10%", objectFit: "cover"}}),
]}),
Article({className: "home-image-easy", style: { position: "relative" }, children: [
Article({textContent: "HELLO"}),
]}),
Grid({
gtc: "1fr 1fr",
children: [
Section({
children: [
Paragraph({textContent: "Shamamal"})
]
}),
Section({
children: [
Paragraph({textContent: "Lorem ipsum dolor sit amet, consectetur adipisicing elit. Quis, voluptates"}),
Paragraph({textContent: "Lorem ipsum dolor sit"})
]
}),
]
}),
Section({
children: [
List({
children: [
ListItem({textContent: "Hey"}),
ListItem({textContent: "Ho"}),
ListItem({textContent: "Hu"}),
ListItem({textContent: "Ha"}),
]
}),
Button({
textContent: "Contact Us",
onclick: function (e) {
console.log(e);
navigation.goToUrl({url: "/contact", title: "Contact", stateObserver, useState, navigation, nextPage: Contact});
}
}),
DefinitionList({
children : [
DefinitionListTerme({textContent: "Denim (semigloss finish"}),
DefinitionListDescription({textContent: "Ceiling"}),
DefinitionListTerme({textContent: "Denim (eggshell finish)"}),
DefinitionListTerme({textContent: "Evening Sky (eggshell finish)"}),
DefinitionListDescription({textContent: "Layered on the walls"})
]
})
]
}),
]
});
};
TABLE
Table({
children: [
TableHeader({
children: [
TableRow({
children: [
DataCell({textContent: "ID"}),
DataCell({textContent: "Email"}),
DataCell({textContent: "Full name"}),
]
}),
]
}),
TableBody({
children: [
TableRow({
children: [
DataCell({textContent: "1"}),
DataCell({textContent: "buzz@foo.com"}),
DataCell({textContent: "Fuz Buzz"}),
]
}),
]
}),
TableFooter({
children: [
TableRow({
children: [
DataCell({textContent: "Nice table"}),
]
}),
]
}),
]
})
BUTTONS
IconButton({
textContent: 'perception',
icon: "content_copy",
attributes: {
icon: {},
text: {style: {color: "red"}},
}
})
IconButton({
children: [
Span({textContent: "easy"}),
Icon({textContent: "person"}),
],
})
Button({textContent: "GitLab"})
Google Font Icons
Icon({textContent: "person"})
Headings Default is H1 is no tagName specified. Check your browser inspecter tool to see.
Section({
children: [
Header({tagName: "h1", textContent: "Heading"}),
Header({tagName: "h2", textContent: "Heading"}),
Header({tagName: "h3", textContent: "Heading"}),
Header({tagName: "h4", textContent: "Heading"}),
Header({tagName: "h5", textContent: "Heading"}),
Header({tagName: "h6", textContent: "Heading"}),
]
})
Override html tag name
If you want to use another tag name and override the one given by the class. Just add property tagName ex: tagName: "span" HTML Attributes you can set html attributes using attributes object like so
Button({textContent: "Save", attributes: {style: {background: "purple",color: "white"}, type: "submit"}})
Use Context Provider Create a single file a paste this inside as a starter.
export const initialState = {
products: [],
};
export const actionsTypes = {
PRODUCTS: "PRODUCTS",
};
const reducer = (state = {}, action = {}) => {
switch (action.type) {
case actionsTypes.PRODUCTS:
return {
...state,
products: action.products,
};
default:
return state;
}
};
Then provide arguments from entrypoint App
return new App(routes, initialState, reducer);
useContextProvider, useState, useArgs, Arg, ArgList...and more to come
const CustomPage = (params) => {
const {stateObserver, useState, navigation, useReduxProvider, updateDom, componentArgs} = params({
text: "text",
image: null
});
const setText = useState("text");
const setImage = useState('image');
const [store, dispatch] = useReduxProvider();
const [args, setArgs, addElement] = useArgs();
setArgs("tableItems", [
{ id: 1, name: "ok", title: "jack", unit_price: 25, price: 125, qty: 1 },
{ id: 2, name: "tomate", title: "same", unit_price: 25, total: 25, qty: 1 },
{ id: 3, name: "oeuf", title: "jaune", unit_price: 12, total: 25, qty: 1 },
]);
setArgs("momto", [
{ id: 1, name: "ok", title: "jack", unit_price: 25, price: 125, qty: 1 },
{ id: 2, name: "tomate", title: "same", unit_price: 25, total: 25, qty: 1 },
{ id: 3, name: "oeuf", title: "jaune", unit_price: 12, total: 25, qty: 1 },
]);
addElement("tableItems", { id: 1, name: "ok", title: "jack", unit_price: 25, price: 125, qty: 1 });
Arg("userId", "2");
Arg("quatre", 4);
Arg("douze", 2);
Arg("cent", 100);
Arg("dix", 10);
Arg("quarante5", 45);
ArgList("products", [
{ id: 2, name: "tomate", title: "same", unit_price: 25, total: 25, qty: 1 },
{ id: 2, name: "tomate", title: "same", unit_price: 25, total: 25, qty: 1 },
{ id: 2, name: "tomate", title: "same", unit_price: 25, total: 25, qty: 1 },
{ id: 2, name: "tomate", title: "same", unit_price: 25, total: 25, qty: 1 },
]);
console.log(args);
}
Update dom element on click
1 - Element
Header({
id: "hide-me",
textContent: "Lorem ipsum"
})
2 - The button
Button({
textContent: "GitLab", className: ["button", "fw-600"],
onclick: (e) => {
setArgs("isOn", !args.isOn);
updateDom({element: "hide-me", show: !args.isOn, data: {style: {background: "blue", borderRadius: "30px"}}});
updateDom({element: e.target, data: {style: {background: "blue", borderRadius: "30px"}}});
}
})