Skip to content

Commit

Permalink
save extra stylus file
Browse files Browse the repository at this point in the history
  • Loading branch information
Javey committed Jul 30, 2019
1 parent caa6034 commit 0f33800
Show file tree
Hide file tree
Showing 13 changed files with 194 additions and 95 deletions.
65 changes: 45 additions & 20 deletions app/controllers/api.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,37 +8,39 @@ const fs = Fs.promises;
const {Utils} = Advanced;

module.exports = Advanced.Controller.extend({
getVariables() {
async getVariables() {
const {component} = this.req.query;

this._success({
'$btn-color': '$light-black',
'$btn-bg-color': '#fff',
});
const file = component ?
`${Utils.c('kpcStylus')}/${component}/variables.styl` :
Utils.c('kpcGlobalStylusFile');

const contents = await fs.readFile(file, 'utf-8');
const variables = contents.split('\n').reduce((acc, line) => {
if (line[0] === '$') {
const [name, value] = line.split(':=');
if (name && value) {
acc[name.trim()] = value.trim();
}
}
return acc;
}, {});

this._success(variables);
},

async save() {
const {variables, component, id} = this.req.body;
const {variables, code, component, globalVariables, globalCode, id} = this.req.body;

const {path: themePath, id: _id} = await this._initTemplateById(id);
const indexFile = `${themePath}/index.styl`;
const variablesFilename = `${component}.variables.styl`;
const variablesFile = `${themePath}/${variablesFilename}`;

const variablesContent = variables.reduce((acc, item) => {
if (item.name && item.value) {
acc.push(`${item.name} := ${item.value}`);
}
return acc;
}, []).join('\n');

if (!await fsExtra.pathExists(variablesFile)) {
// add @require in index.styl for creating variables file first time
await fs.writeFile(indexFile, `\n@require('./${variablesFilename}')`, {flag: 'a'});
}
const [content] = await Promise.all([
fs.readFile(Utils.c('stylus'), {encoding: 'utf-8'}),
fs.writeFile(variablesFile, variablesContent),
this._writeVariables(`${component}.variables.styl`, themePath, variables, indexFile),
this._writeVariables(`global.variables.styl`, themePath, globalVariables, indexFile),
this._writeExtraStylus(`reset.styl`, themePath, globalCode),
this._writeExtraStylus(`${component}.styl`, themePath, code),
]);

stylus(content, {
Expand All @@ -51,6 +53,29 @@ module.exports = Advanced.Controller.extend({
});
},

async _writeVariables(filename, themePath, variables, indexFile) {
const file = `${themePath}/${filename}`;

const contents = variables.reduce((acc, item) => {
if (item.name && item.value) {
acc.push(`${item.name} := ${item.value}`);
}
return acc;
}, []).join('\n');

if (!await fsExtra.pathExists(file)) {
// add @require in index.styl for creating variables file first time
await fs.writeFile(indexFile, `\n@require('./${filename}')`, {flag: 'a'});
}
await fs.writeFile(file, contents);
},

async _writeExtraStylus(filename, themePath, contents) {
if (contents) {
await fs.writeFile(`${themePath}/${filename}`, contents);
}
},

async _initTemplateById(id) {
const _id = id;

Expand Down
Empty file added button.variables.styl
Empty file.
3 changes: 3 additions & 0 deletions config/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,7 @@ module.exports = {
template: path.resolve(__dirname, '../templates'),
stylus: '{template}/theme.styl',
stylusTemplate: '{template}/theme',

kpcStylus: path.resolve(__dirname, '../node_modules/kpc/components'),
kpcGlobalStylusFile: path.resolve(__dirname, '../node_modules/kpc/styles/themes/default.styl'),
}
1 change: 1 addition & 0 deletions global.variables.styl
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
$primary-color := red
3 changes: 1 addition & 2 deletions src/app.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import App from 'kpc/components/app';
import router from './router';
import {createBrowserHistory} from 'history';
// import '@/all.styl';

const history = createBrowserHistory();
const app = new App({container: document.getElementById('app')});
Expand All @@ -12,7 +11,7 @@ function init(router) {

unlisten = history.listen(async ({hash}) => {
app.showLoading();
const {Page, data} = await router.resolve({pathname: hash.substring(1)});
const {Page, data} = await router.resolve({pathname: hash.substring(1) || '/'});
await app.load(Page, data);
});
history.replace(location);
Expand Down
28 changes: 28 additions & 0 deletions src/components/stylusEditor/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import Intact from 'intact';
import template from './index.vdt';

export default class StylusEditor extends Intact {
@Intact.template()
static template = template;

defaults() {
return {
collapseValue: ['$0', '$1'],
variables: [{}],
code: '',
availableVariables: [],
}
}

_addVariable(index) {
const variables = this.get('variables').slice(0);
variables.splice(index + 1, 0, {});
this.set({variables});
}

_removeVariable(index) {
const variables = this.get('variables').slice(0);
variables.splice(index, 1);
this.set({variables});
}
}
55 changes: 55 additions & 0 deletions src/components/stylusEditor/index.vdt
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import {Collapse, CollapseItem} from 'kpc/components/collapse';
import {Input} from 'kpc/components/input';
import {Form, FormItem} from 'kpc/components/form';
import {Select, Option} from 'kpc/components/select';
import Button from 'kpc/components/button';
import Icon from 'kpc/components/icon';
import Code from 'kpc/components/code';

<Collapse v-model="collapseValue" noBorder>
<CollapseItem title="Stylus 变量" class="variables-panel">
<Form labelWidth="200">
<FormItem fluid v-for={{ self.get('variables') }}>
<b:label>
<Select filterable fluid size="small"
v-model={{ `variables.${key}.name` }}
allowUnmatch
>
<Option
v-for={{
_.omit(
self.get('availableVariables'),
_.map(self.get('variables'), item => item.name)
)
}}
value={{ key }}
>
{{ key }}
</Option>
</Select>
</b:label>
<Input placeholder={{ self.get('availableVariables')[value.name] }}
fluid size="small"
v-model={{ `variables.${key}.value` }}
/>
<b:append>
<Button icon circle size="mini"
ev-click={{ self._addVariable.bind(self, key) }}
>
<Icon class="ion-ios-plus-empty" />
</Button>
<Button icon circle size="mini"
ev-click={{ self._removeVariable.bind(self, key) }}
disabled={{ self.get('variables').length === 1 }}
>
<Icon class="ion-ios-minus-empty" />
</Button>
</b:append>
</FormItem>
</Form>
</CollapseItem>
<CollapseItem title="附加样式" class="code-panel">
<Code v-model="code" height="300px" language="css" />
</CollapseItem>
</Collapse>

35 changes: 19 additions & 16 deletions src/pages/index/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@ export default class Index extends Intact {
lastSize: '500px',
collapseValue: ['$0', '$1'],
variables: [{}],
globalVariables: [{}],
component: 'button',
tab: 'component',
};
}

Expand All @@ -25,34 +28,34 @@ export default class Index extends Intact {
}, {});
this.set('id', qs.id);

return this._fetch();
this._watch();

return Promise.all([this._fetchGlobalVariables(), this._fetch()]);
}

_fetch() {
return api.getVariables({component: this.get('name')}).then(res => {
this.set('availableVariables', res.data);
_watch() {
this.on('$change:component', (c, v) => {
this._fetch();
});
}

_addVariable(index) {
const variables = this.get('variables').slice(0);
variables.splice(index + 1, 0, {});
this.set({variables});
_fetchGlobalVariables() {
return api.getVariables().then(res => {
this.set('globalAvailableVariables', res.data);
});
}

_removeVariable(index) {
const variables = this.get('variables').slice(0);
variables.splice(index, 1);
this.set({variables});
_fetch() {
return api.getVariables({component: this.get('component')}).then(res => {
this.set('availableVariables', res.data);
});
}

_save() {
const {variables, code, component, globalVariables, globalCode, id} = this.get();
return api.save({
variables: this.get('variables'),
component: this.get('name'),
id: this.get('id'),
variables, code, component, globalVariables, globalCode, id,
}).then(res => {
console.log(res.data.css);
const {id, css} = res.data;
if (id !== this.get('id')) {
history.pushState(null, null, `?id=${id}${location.hash}`);
Expand Down
2 changes: 2 additions & 0 deletions src/pages/index/index.styl
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,8 @@ html
padding-top 16px
border-top 1px solid $border-color
margin-top 16px
.k-tabs
margin-bottom 16px
.k-collapse
overflow-y auto
overflow-x hidden
Expand Down
71 changes: 24 additions & 47 deletions src/pages/index/index.vdt
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,13 @@ import {Breadcrumb, BreadcrumbItem} from 'kpc/components/breadcrumb';
import logo from '@/images/logo.png';
import {Split} from 'kpc/components/split';
import {Collapse, CollapseItem} from 'kpc/components/collapse';
import Code from 'kpc/components/code';
import Button from 'kpc/components/button';
import {Form, FormItem} from 'kpc/components/form';
import {Select, Option} from 'kpc/components/select';
import {Input} from 'kpc/components/input';
import {Tooltip} from 'kpc/components/tooltip';
import {Tabs, Tab} from 'kpc/components/tabs';
import StylusEditor from '@/components/stylusEditor';

<Layout class="layout">
<Header fixed>
Expand All @@ -21,12 +23,12 @@ import {Input} from 'kpc/components/input';
<Layout>
<Aside fixed>
<Menu
selectedKey={{ self.get('name') }}
selectedKey={{ self.get('component') }}
theme="light"
>
<MenuItem v-for={{ self.get('components') }}
key={{ value.name }}
to={{ `#/components/${value.name}` }}
ev-click={{ () => self.set('component', value.name) }}
>
{{ value.name }}
<span class="cn-name">{{ value.title }}</span>
Expand All @@ -36,52 +38,27 @@ import {Input} from 'kpc/components/input';
<Body>
<Split v-model:lastSize="lastSize">
<b:first>
<iframe src={{ `#/opera/${self.get('name')}` }}></iframe>
<iframe src={{ `#/opera/${self.get('component')}` }}></iframe>
</b:first>
<b:last>
<Collapse v-model="collapseValue" noBorder>
<CollapseItem title="Stylus 变量" class="variables-panel">
<Form labelWidth="200">
<FormItem fluid v-for={{ self.get('variables') }}>
<b:label>
<Select filterable fluid size="small"
v-model={{ `variables.${key}.name` }}
allowUnmatch
>
<Option
v-for={{
_.omit(
self.get('availableVariables'),
_.map(self.get('variables'), item => item.name)
)
}}
value={{ key }}
>{{ key }}</Option>
</Select>
</b:label>
<Input placeholder={{ self.get('availableVariables')[value.name] }}
fluid size="small"
v-model={{ `variables.${key}.value` }}
/>
<b:append>
<Button icon circle size="mini"
ev-click={{ self._addVariable.bind(self, key) }}
>
<Icon class="ion-ios-plus-empty" />
</Button>
<Button icon circle size="mini"
ev-click={{ self._removeVariable.bind(self, key) }}
>
<Icon class="ion-ios-minus-empty" />
</Button>
</b:append>
</FormItem>
</Form>
</CollapseItem>
<CollapseItem title="附加样式" class="code-panel">
<Code v-model="code" height="300px" language="css" />
</CollapseItem>
</Collapse>
<Tabs v-model="tab">
<Tab value="global">全局样式</Tab>
<Tab value="component">组件样式</Tab>
</Tabs>
<StylusEditor
v-model:variables="variables"
v-model:code="code"
availableVariables={{ self.get('availableVariables') }}
key="component"
v-if={{ self.get('tab') === 'component' }}
/>
<StylusEditor
v-model:variables="globalVariables"
v-model:code="globalCode"
availableVariables={{ self.get('globalAvailableVariables') }}
key="global"
v-else
/>
<div class="footer">
<Button type="primary" ev-click={{ self._save }}>保存</Button>
</div>
Expand Down
18 changes: 9 additions & 9 deletions src/router.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,15 @@ export default new Router([
return {Page: (await import('./pages/index')).default}
},
},
{
path: '/components/:name',
async action(context) {
return {
Page: (await import('./pages/index')).default,
data: context.params,
}
}
},
// {
// path: '/components/:name',
// async action(context) {
// return {
// Page: (await import('./pages/index')).default,
// data: context.params,
// }
// }
// },
{
path: '/opera/:name',
async action(context) {
Expand Down
Empty file.
Loading

0 comments on commit 0f33800

Please sign in to comment.