mirror of
https://github.com/frappe/books.git
synced 2024-09-20 11:29:00 +00:00
Tree as Web Component
This commit is contained in:
parent
f7db1206b0
commit
2909cd74b7
@ -4,7 +4,6 @@
|
|||||||
@import "node_modules/flatpickr/dist/themes/airbnb";
|
@import "node_modules/flatpickr/dist/themes/airbnb";
|
||||||
@import "node_modules/codemirror/lib/codemirror";
|
@import "node_modules/codemirror/lib/codemirror";
|
||||||
@import "node_modules/frappe-datatable/dist/frappe-datatable";
|
@import "node_modules/frappe-datatable/dist/frappe-datatable";
|
||||||
// @import "node_modules/octicons/build/build.css";
|
|
||||||
|
|
||||||
@import "./variables.scss";
|
@import "./variables.scss";
|
||||||
@import "./indicators.scss";
|
@import "./indicators.scss";
|
||||||
|
@ -1,111 +1,123 @@
|
|||||||
@import "./variables.scss";
|
@import "./variables.scss";
|
||||||
|
|
||||||
.tree {
|
.tree-body {
|
||||||
padding: $spacer-3 $spacer-4;
|
padding: $spacer-3 $spacer-4;
|
||||||
}
|
}
|
||||||
|
|
||||||
.tree li {
|
f-tree, f-tree-node {
|
||||||
list-style: none;
|
display: block;
|
||||||
}
|
}
|
||||||
|
|
||||||
ul.tree-children {
|
f-tree-node:hover {
|
||||||
padding-left: $spacer-4;
|
|
||||||
}
|
|
||||||
|
|
||||||
.tree-link {
|
|
||||||
cursor: pointer;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.tree-link:hover {
|
|
||||||
background-color: $gray-100;
|
background-color: $gray-100;
|
||||||
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
.tree-link .node-parent {
|
// .tree {
|
||||||
color: $gray-600;
|
// padding: $spacer-3 $spacer-4;
|
||||||
width: 24px;
|
// }
|
||||||
height: 24px;
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.tree-link .node-leaf {
|
// .tree li {
|
||||||
color: $gray-400;
|
// list-style: none;
|
||||||
}
|
// }
|
||||||
|
|
||||||
.tree-link .node-parent, .tree-link .node-leaf {
|
// ul.tree-children {
|
||||||
padding: $spacer-2;
|
// padding-left: $spacer-4;
|
||||||
}
|
// }
|
||||||
|
|
||||||
.tree-link.active {
|
// .tree-link {
|
||||||
a {
|
// cursor: pointer;
|
||||||
color: $gray-600;
|
// display: flex;
|
||||||
}
|
// align-items: center;
|
||||||
}
|
// width: 100%;
|
||||||
|
// }
|
||||||
|
|
||||||
.tree-hover {
|
// .tree-link:hover {
|
||||||
background-color: $gray-200;
|
// background-color: $gray-100;
|
||||||
min-height: 20px;
|
// }
|
||||||
border: 1px solid $gray-600;
|
|
||||||
}
|
|
||||||
|
|
||||||
.tree-node-toolbar {
|
// .tree-link .node-parent {
|
||||||
display: inline-block;
|
// color: $gray-200;
|
||||||
padding: 0px 5px;
|
// width: 24px;
|
||||||
margin-left: 15px;
|
// height: 24px;
|
||||||
margin-bottom: -4px;
|
// }
|
||||||
margin-top: -8px;
|
|
||||||
}
|
|
||||||
|
|
||||||
// @media (max-width: @screen-xs) {
|
// .tree-link .node-leaf {
|
||||||
// ul.tree-children {
|
// color: $gray-400;
|
||||||
// padding-left: 10px;
|
// }
|
||||||
|
|
||||||
|
// .tree-link .node-parent, .tree-link .node-leaf {
|
||||||
|
// padding: $spacer-2;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// .tree-link.active {
|
||||||
|
// a {
|
||||||
|
// color: $gray-600;
|
||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
|
|
||||||
// decoration
|
// .tree-hover {
|
||||||
// .tree, .tree-node {
|
// background-color: $gray-200;
|
||||||
.tree.with-skeleton, .tree.with-skeleton .tree-node {
|
// min-height: 20px;
|
||||||
position: relative;
|
// border: 1px solid $gray-600;
|
||||||
|
// }
|
||||||
|
|
||||||
&.opened::before, &:last-child::after {
|
// .tree-node-toolbar {
|
||||||
content: '';
|
// display: inline-block;
|
||||||
position: absolute;
|
// padding: 0px 5px;
|
||||||
top: 12px;
|
// margin-left: 15px;
|
||||||
left: 7px;
|
// margin-bottom: -4px;
|
||||||
height: calc(100% - 23px);
|
// margin-top: -8px;
|
||||||
width: 1px;
|
// }
|
||||||
background: $gray-400;
|
|
||||||
z-index: -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
&:last-child::after {
|
// // @media (max-width: @screen-xs) {
|
||||||
top: 11px;
|
// // ul.tree-children {
|
||||||
left: -13px;
|
// // padding-left: 10px;
|
||||||
height: calc(100% - 15px);
|
// // }
|
||||||
width: 3px;
|
// // }
|
||||||
background: #fff;
|
|
||||||
}
|
|
||||||
|
|
||||||
&.opened > .tree-children > .tree-node > .tree-link::before {
|
// // decoration
|
||||||
content: '';
|
// // .tree, .tree-node {
|
||||||
position: absolute;
|
// .tree.with-skeleton, .tree.with-skeleton .tree-node {
|
||||||
width: 18px;
|
// position: relative;
|
||||||
height: 1px;
|
|
||||||
top: 10px;
|
|
||||||
left: -12px;
|
|
||||||
z-index: -1;
|
|
||||||
background: $gray-400;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.tree.with-skeleton.opened::before {
|
// &.opened::before, &:last-child::after {
|
||||||
left: 22px;
|
// content: '';
|
||||||
top: 33px;
|
// position: absolute;
|
||||||
height: calc(100% - 67px);
|
// top: 12px;
|
||||||
}
|
// left: 7px;
|
||||||
|
// height: calc(100% - 23px);
|
||||||
|
// width: 1px;
|
||||||
|
// background: $gray-400;
|
||||||
|
// z-index: -1;
|
||||||
|
// }
|
||||||
|
|
||||||
.tree-link.active ~ .balance-area {
|
// &:last-child::after {
|
||||||
color: $gray-600 !important;
|
// top: 11px;
|
||||||
}
|
// left: -13px;
|
||||||
|
// height: calc(100% - 15px);
|
||||||
|
// width: 3px;
|
||||||
|
// background: #fff;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// &.opened > .tree-children > .tree-node > .tree-link::before {
|
||||||
|
// content: '';
|
||||||
|
// position: absolute;
|
||||||
|
// width: 18px;
|
||||||
|
// height: 1px;
|
||||||
|
// top: 10px;
|
||||||
|
// left: -12px;
|
||||||
|
// z-index: -1;
|
||||||
|
// background: $gray-400;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// .tree.with-skeleton.opened::before {
|
||||||
|
// left: 22px;
|
||||||
|
// top: 33px;
|
||||||
|
// height: calc(100% - 67px);
|
||||||
|
// }
|
||||||
|
|
||||||
|
// .tree-link.active ~ .balance-area {
|
||||||
|
// color: $gray-600 !important;
|
||||||
|
// }
|
||||||
|
@ -64,6 +64,35 @@ module.exports = {
|
|||||||
element.parentNode.removeChild(element);
|
element.parentNode.removeChild(element);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
on(element, event, selector, handler) {
|
||||||
|
if (!handler) {
|
||||||
|
handler = selector;
|
||||||
|
this.bind(element, event, handler);
|
||||||
|
} else {
|
||||||
|
this.delegate(element, event, selector, handler);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
off(element, event, handler) {
|
||||||
|
element.removeEventListener(event, handler);
|
||||||
|
},
|
||||||
|
|
||||||
|
bind(element, event, callback) {
|
||||||
|
event.split(/\s+/).forEach(function (event) {
|
||||||
|
element.addEventListener(event, callback);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
delegate(element, event, selector, callback) {
|
||||||
|
element.addEventListener(event, function (e) {
|
||||||
|
const delegatedTarget = e.target.closest(selector);
|
||||||
|
if (delegatedTarget) {
|
||||||
|
e.delegatedTarget = delegatedTarget;
|
||||||
|
callback.call(this, e, delegatedTarget);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
empty(element) {
|
empty(element) {
|
||||||
while (element.firstChild) {
|
while (element.firstChild) {
|
||||||
element.removeChild(element.firstChild);
|
element.removeChild(element.firstChild);
|
||||||
|
@ -2,15 +2,106 @@ const frappe = require('frappejs');
|
|||||||
const octicons = require('octicons');
|
const octicons = require('octicons');
|
||||||
const utils = require('frappejs/client/ui/utils');
|
const utils = require('frappejs/client/ui/utils');
|
||||||
|
|
||||||
class Tree {
|
const iconSet = {
|
||||||
constructor({parent, label, iconSet, withSkeleton, method}) {
|
open: octicons["triangle-down"].toSVG({ width: "12", height: "12", "class": "tree-icon-open" }),
|
||||||
|
close: octicons["triangle-right"].toSVG({ width: "12", height: "12", "class": "tree-icon-closed" })
|
||||||
|
};
|
||||||
|
|
||||||
|
let TreeTemplate = document.createElement('template');
|
||||||
|
TreeTemplate.innerHTML = `
|
||||||
|
<div class="tree">
|
||||||
|
<slot></slot>
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
|
||||||
|
class Tree extends HTMLElement {
|
||||||
|
constructor() {
|
||||||
|
super();
|
||||||
|
|
||||||
|
this.attachShadow({ mode: 'open' })
|
||||||
|
.appendChild(TreeTemplate.content.cloneNode(true));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
window.customElements.define('f-tree', Tree);
|
||||||
|
|
||||||
|
let TreeNodeTemplate = document.createElement('template');
|
||||||
|
TreeNodeTemplate.innerHTML = `
|
||||||
|
<style>
|
||||||
|
.tree-node-content {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tree-node-icon {
|
||||||
|
width: 2rem;
|
||||||
|
height: 2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tree-node-icon svg {
|
||||||
|
padding: 0.5rem;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<div class="tree-node-content">
|
||||||
|
<div class="tree-node-icon"></div>
|
||||||
|
<div class="tree-node-label"></div>
|
||||||
|
<div class="tree-node-actions"></div>
|
||||||
|
</div>
|
||||||
|
<slot></slot>
|
||||||
|
`;
|
||||||
|
|
||||||
|
|
||||||
|
class TreeNode extends HTMLElement {
|
||||||
|
static get observedAttributes() {
|
||||||
|
return ['label', 'expanded']
|
||||||
|
}
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
super();
|
||||||
|
|
||||||
|
let shadowRoot = this.attachShadow({ mode: 'open' });
|
||||||
|
shadowRoot.appendChild(TreeNodeTemplate.content.cloneNode(true));
|
||||||
|
this.iconEl = shadowRoot.querySelector('.tree-node-icon');
|
||||||
|
this.labelEl = shadowRoot.querySelector('.tree-node-label');
|
||||||
|
this.actionsEl = shadowRoot.querySelector('.tree-node-actions');
|
||||||
|
}
|
||||||
|
|
||||||
|
attributeChangedCallback(name, oldValue, newValue) {
|
||||||
|
console.log(name, oldValue, newValue);
|
||||||
|
|
||||||
|
switch(name) {
|
||||||
|
case 'label': {
|
||||||
|
this.labelEl.innerHTML = newValue || '';
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case 'expanded': {
|
||||||
|
this.expanded = this.hasAttribute('expanded');
|
||||||
|
|
||||||
|
if (this.expanded) {
|
||||||
|
this.iconEl.innerHTML = iconSet.open;
|
||||||
|
} else {
|
||||||
|
this.iconEl.innerHTML = iconSet.close;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
default: break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
window.customElements.define('f-tree-node', TreeNode);
|
||||||
|
|
||||||
|
class TreeOld {
|
||||||
|
constructor({ parent, label, iconSet, withSkeleton, method }) {
|
||||||
Object.assign(this, arguments[0]);
|
Object.assign(this, arguments[0]);
|
||||||
this.nodes = {};
|
this.nodes = {};
|
||||||
if(!iconSet) {
|
if (!iconSet) {
|
||||||
this.iconSet = {
|
this.iconSet = {
|
||||||
open: octicons["triangle-down"].toSVG({ "width": 10, "class": "node-parent"}),
|
open: octicons["triangle-down"].toSVG({ "width": 10, "class": "node-parent" }),
|
||||||
closed: octicons["triangle-right"].toSVG({ "width": 5, "class": "node-parent"}),
|
closed: octicons["triangle-right"].toSVG({ "width": 5, "class": "node-parent" }),
|
||||||
leaf: octicons["primitive-dot"].toSVG({ "width": 7, "class": "node-leaf"})
|
leaf: octicons["primitive-dot"].toSVG({ "width": 7, "class": "node-leaf" })
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
this.make();
|
this.make();
|
||||||
@ -31,7 +122,7 @@ class Tree {
|
|||||||
// this.loadChildren(this.selectedNode.parentNode, true);
|
// this.loadChildren(this.selectedNode.parentNode, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
async loadChildren(node, deep=false) {
|
async loadChildren(node, deep = false) {
|
||||||
let children = !deep ? await this.method(node) : await this.getAllNodes(node);
|
let children = !deep ? await this.method(node) : await this.getAllNodes(node);
|
||||||
this.renderNodeChildren(node, children);
|
this.renderNodeChildren(node, children);
|
||||||
}
|
}
|
||||||
@ -40,7 +131,7 @@ class Tree {
|
|||||||
dataList.map(d => { this.renderNodeChildren(this.nodes[d.parent], d.data); });
|
dataList.map(d => { this.renderNodeChildren(this.nodes[d.parent], d.data); });
|
||||||
}
|
}
|
||||||
|
|
||||||
renderNodeChildren(node, dataSet=[]) {
|
renderNodeChildren(node, dataSet = []) {
|
||||||
frappe.ui.empty(node.childrenList);
|
frappe.ui.empty(node.childrenList);
|
||||||
|
|
||||||
dataSet.forEach(data => {
|
dataSet.forEach(data => {
|
||||||
@ -67,7 +158,7 @@ class Tree {
|
|||||||
expandable: expandable,
|
expandable: expandable,
|
||||||
};
|
};
|
||||||
|
|
||||||
if(parentNode){
|
if (parentNode) {
|
||||||
node.parentNode = parentNode;
|
node.parentNode = parentNode;
|
||||||
node.parent = parentNode.childrenList;
|
node.parent = parentNode.childrenList;
|
||||||
node.isRoot = 0;
|
node.isRoot = 0;
|
||||||
@ -90,8 +181,8 @@ class Tree {
|
|||||||
});
|
});
|
||||||
|
|
||||||
let iconHtml = '';
|
let iconHtml = '';
|
||||||
if(this.iconSet) {
|
if (this.iconSet) {
|
||||||
iconHtml = node.expandable ? this.iconSet.closed : this.iconSet.leaf;
|
iconHtml = node.expandable ? this.iconSet.closed : '';
|
||||||
}
|
}
|
||||||
let labelEl = `<span class="tree-label"> ${node.label}</span>`;
|
let labelEl = `<span class="tree-label"> ${node.label}</span>`;
|
||||||
|
|
||||||
@ -118,17 +209,17 @@ class Tree {
|
|||||||
|
|
||||||
async onNodeClick(node, click = true) {
|
async onNodeClick(node, click = true) {
|
||||||
this.setSelectedNode(node);
|
this.setSelectedNode(node);
|
||||||
if(click) {
|
if (click) {
|
||||||
this.onClick && this.onClick(node);
|
this.onClick && this.onClick(node);
|
||||||
}
|
}
|
||||||
await this.expandNode(node);
|
await this.expandNode(node);
|
||||||
// select link
|
// select link
|
||||||
utils.activate(this.tree, node.treeLink, 'tree-link', 'active');
|
utils.activate(this.tree, node.treeLink, 'tree-link', 'active');
|
||||||
if(node.toolbar) this.showToolbar(node);
|
if (node.toolbar) this.showToolbar(node);
|
||||||
}
|
}
|
||||||
|
|
||||||
async expandNode(node) {
|
async expandNode(node) {
|
||||||
if(node.expandable) {
|
if (node.expandable) {
|
||||||
await this.toggleNode(node);
|
await this.toggleNode(node);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -139,11 +230,11 @@ class Tree {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async toggleNode(node) {
|
async toggleNode(node) {
|
||||||
if(!node.loaded) await this.loadChildren(node);
|
if (!node.loaded) await this.loadChildren(node);
|
||||||
|
|
||||||
// expand children
|
// expand children
|
||||||
if(node.childrenList) {
|
if (node.childrenList) {
|
||||||
if(node.childrenList.innerHTML.length) {
|
if (node.childrenList.innerHTML.length) {
|
||||||
if (node.expanded) {
|
if (node.expanded) {
|
||||||
node.childrenList.classList.add('hide');
|
node.childrenList.classList.add('hide');
|
||||||
} else {
|
} else {
|
||||||
@ -152,7 +243,7 @@ class Tree {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// open close icon
|
// open close icon
|
||||||
if(this.iconSet) {
|
if (this.iconSet) {
|
||||||
const oldIcon = node.treeLink.querySelector('svg');
|
const oldIcon = node.treeLink.querySelector('svg');
|
||||||
const newIconKey = node.expanded ? 'closed' : 'open';
|
const newIconKey = node.expanded ? 'closed' : 'open';
|
||||||
const newIcon = frappe.ui.create(this.iconSet[newIconKey]);
|
const newIcon = frappe.ui.create(this.iconSet[newIconKey]);
|
||||||
|
@ -56,18 +56,83 @@ module.exports = class BaseTree extends BaseList {
|
|||||||
}
|
}
|
||||||
|
|
||||||
renderTree(rootLabel) {
|
renderTree(rootLabel) {
|
||||||
this.tree = new Tree({
|
// const tree = new Tree();
|
||||||
|
// tree.getChildNodes = async node => {
|
||||||
|
// const children = await this.getData(node) || [];
|
||||||
|
// return children.map(d => ({
|
||||||
|
// label: d.name,
|
||||||
|
// value: d.name,
|
||||||
|
// expandable: d.isGroup
|
||||||
|
// }));
|
||||||
|
// }
|
||||||
|
// tree.rootNode = {
|
||||||
|
// label: rootLabel,
|
||||||
|
// value: rootLabel,
|
||||||
|
// isRoot: 1,
|
||||||
|
// expandable: 1
|
||||||
|
// }
|
||||||
|
// this.body.appendChild(tree);
|
||||||
|
|
||||||
|
this.rootNode = {
|
||||||
label: rootLabel,
|
label: rootLabel,
|
||||||
parent: this.body,
|
value: rootLabel,
|
||||||
method: async node => {
|
isRoot: true,
|
||||||
const children = await this.getData(node) || [];
|
expanded: true,
|
||||||
return children.map(d => ({
|
children: []
|
||||||
label: d.name,
|
}
|
||||||
value: d.name,
|
|
||||||
expandable: d.isGroup
|
const getNodeHTML = node =>
|
||||||
}));
|
`<f-tree-node
|
||||||
}
|
label="${node.label}"
|
||||||
|
value="${node.value}"
|
||||||
|
${node.expanded ? 'expanded' : ''}
|
||||||
|
${node.isRoot ? 'is-root' : ''}>
|
||||||
|
</f-tree-node>`;
|
||||||
|
|
||||||
|
this.treeWrapper = frappe.ui.create('f-tree');
|
||||||
|
|
||||||
|
this.rootNode.el = frappe.ui.create(getNodeHTML(this.rootNode), {
|
||||||
|
inside: this.treeWrapper
|
||||||
});
|
});
|
||||||
|
|
||||||
|
this.treeWrapper = frappe.ui.create(`
|
||||||
|
<f-tree>
|
||||||
|
${getNodeHTML(this.rootNode)}
|
||||||
|
</f-tree>
|
||||||
|
`);
|
||||||
|
|
||||||
|
this.body.appendChild(this.treeWrapper);
|
||||||
|
|
||||||
|
frappe.ui.on(this.treeWrapper, 'click', 'f-tree-node', async (e, treeNode) => {
|
||||||
|
if (treeNode.expanded) {
|
||||||
|
treeNode.removeAttribute('expanded');
|
||||||
|
} else {
|
||||||
|
treeNode.setAttribute('expanded', '');
|
||||||
|
}
|
||||||
|
|
||||||
|
let node = null;
|
||||||
|
// if (treeNode.hasAttribute('is-root')) {
|
||||||
|
// node = this.rootNode;
|
||||||
|
// } else {
|
||||||
|
|
||||||
|
// }
|
||||||
|
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
// this.tree = new Tree({
|
||||||
|
// label: rootLabel,
|
||||||
|
// parent: this.body,
|
||||||
|
// method: async node => {
|
||||||
|
// const children = await this.getData(node) || [];
|
||||||
|
// return children.map(d => ({
|
||||||
|
// label: d.name,
|
||||||
|
// value: d.name,
|
||||||
|
// expandable: d.isGroup
|
||||||
|
// }));
|
||||||
|
// }
|
||||||
|
// });
|
||||||
}
|
}
|
||||||
|
|
||||||
async getData(node) {
|
async getData(node) {
|
||||||
@ -119,7 +184,7 @@ module.exports = class BaseTree extends BaseList {
|
|||||||
});
|
});
|
||||||
|
|
||||||
this.page.body.addEventListener('click', (event) => {
|
this.page.body.addEventListener('click', (event) => {
|
||||||
if(event.target.classList.contains('checkbox')) {
|
if (event.target.classList.contains('checkbox')) {
|
||||||
this.trigger('state-change');
|
this.trigger('state-change');
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@ -138,7 +203,7 @@ module.exports = class BaseTree extends BaseList {
|
|||||||
|
|
||||||
this.searchInput = this.toolbar.querySelector('input');
|
this.searchInput = this.toolbar.querySelector('input');
|
||||||
this.searchInput.addEventListener('keypress', (event) => {
|
this.searchInput.addEventListener('keypress', (event) => {
|
||||||
if (event.keyCode===13) {
|
if (event.keyCode === 13) {
|
||||||
this.refresh();
|
this.refresh();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -5,7 +5,6 @@ module.exports = {
|
|||||||
format: 'cjs'
|
format: 'cjs'
|
||||||
},
|
},
|
||||||
plugins: [
|
plugins: [
|
||||||
require('rollup-plugin-sass')(),
|
|
||||||
require('rollup-plugin-postcss')({
|
require('rollup-plugin-postcss')({
|
||||||
extract: true,
|
extract: true,
|
||||||
plugins: [
|
plugins: [
|
||||||
|
Loading…
Reference in New Issue
Block a user