Skip to content

Commit d35c3ec

Browse files
authored
Merge pull request #4 from peakchen90/dev
Dev
2 parents 67fcfe3 + 7612dff commit d35c3ec

File tree

6 files changed

+131
-34
lines changed

6 files changed

+131
-34
lines changed

CHANGELOG.md

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,34 @@
11
# CHANGELOG
22

3+
## v1.1.0
4+
2019-12-01
5+
6+
- **Feature**: Added `x-class` directive for conditionally joining classNames together.
7+
- **Optimization**: Split the runtime into multiple independent files to reduce runtime bundle size.
8+
39
## v1.0.2
410
2019-11-23
511

6-
- Fix bug: When `x-if` is nested under `x-else` and `x-else-if`, an error is reported.
12+
- **Bug**: fix bug that when `x-if` is nested under `x-else` and `x-else-if`, an error is reported.
713

814
## v1.0.0
915
2019-10-20
1016

11-
- Added `x-model-hook` directive for **useState hook function**, and the `x-model` can only be used in **class component** now
12-
- In some cases use the runtime instead of the AST code
13-
- Fix some problem of `x-model`
14-
- Improved stability
17+
- **Feature**: Added `x-model-hook` directive for **useState hook function**, and the `x-model` can only be used in **class component** now
18+
- **Optimization**: In some cases use the runtime instead of the AST code
19+
- **Optimization**: Fix some problem of `x-model`
20+
- **Optimization**: Improved stability
1521

1622
## v0.1.1
1723
2019-10-17
1824

19-
- Update some documents
25+
- **Optimization**: Update some documents
2026

2127

2228
## v0.1.0
2329
2019-10-07
2430

25-
- Features: Support for `x-if` and `x-else-if` and `x-else`
26-
- Features: Support for `x-show`
27-
- Features: Support for `x-for`
28-
- Features: Support for `x-model`
31+
- **Feature**: Support for `x-if` and `x-else-if` and `x-else`
32+
- **Feature**: Support for `x-show`
33+
- **Feature**: Support for `x-for`
34+
- **Feature**: Support for `x-model`

README.ZH-CN.md

Lines changed: 54 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
- [x-for](#toc-directives-x-for)
2222
- [x-model](#toc-directives-x-model)
2323
- [x-model-hook](#toc-directives-x-model-hook)
24+
- [x-class](#toc-directives-x-class)
2425
- [相关资源](#toc-related-packages)
2526
- [已知问题](#toc-known-issues)
2627
- [更新日志](#toc-changeloog)
@@ -136,7 +137,7 @@ const foo = (
136137
)
137138
```
138139

139-
当然,它也会通过调用 [runtime function](./lib/runtime.js) 合并其他 `style`,例如:
140+
当然,它也会通过调用 [mergeProps 方法](./runtime/merge-props.js) 合并其他 `style` props,例如:
140141
```jsx harmony
141142
const foo = (
142143
<div
@@ -154,7 +155,7 @@ const foo = (
154155
<div
155156
{...extraProps}
156157
style={{
157-
...require("babel-plugin-react-directives/lib/runtime").mergeProps.call(this, "style", [
158+
...mergeProps.call(this, "style", [
158159
{ style: { color: 'red' } },
159160
extraProps
160161
]),
@@ -225,7 +226,7 @@ const foo = (
225226

226227
### <span id="toc-directives-x-model">x-model</span>
227228
`x-model` 是类似于 vue `v-model` 的语法糖,使用时绑定一个值到表单元素的 `value` prop 上,在表单元素更新时自动更新状态。
228-
通过调用 [runtime function](./lib/runtime.js) 获取更新的值(如果第一个参数 `arg` 不为空,且 `arg.target` 是一个对象,返回 `arg.target.value`,否则返回 `arg`
229+
通过调用 [resolveValue 方法](./runtime/resolve-value.js) 获取更新的值(如果第一个参数 `arg` 不为空,且 `arg.target` 是一个对象,返回 `arg.target.value`,否则返回 `arg`
229230

230231
**例子:**
231232
```jsx harmony
@@ -252,7 +253,7 @@ class Foo extends React.Component {
252253
render() {
253254
return (
254255
<input value={this.state.data} onChange={(..._args) => {
255-
let _value = require("babel-plugin-react-directives/lib/runtime").resolveValue(_args);
256+
let _value = resolveValue(_args);
256257

257258
this.setState(_prevState => {
258259
return { data: _value };
@@ -263,7 +264,7 @@ class Foo extends React.Component {
263264
}
264265
```
265266

266-
当存在其他 `onChange` prop 时,将通过调用 [runtime function](./lib/runtime.js) 合并其他 `onChange` 方法:
267+
当存在其他 `onChange` prop 时,将通过调用 [invokeOnchange 方法](./runtime/invoke-onchange.js) 合并其他 `onChange` 方法:
267268
```jsx harmony
268269
class Foo extends React.Component {
269270
constructor(props) {
@@ -305,13 +306,13 @@ class Foo extends React.Component {
305306
{...this.props}
306307
value={this.state.data}
307308
onChange={(..._args) => {
308-
let _value = require("babel-plugin-react-directives/lib/runtime").resolveValue(_args);
309+
let _value = resolveValue(_args);
309310

310311
this.setState(_prevState => {
311312
return { data: _value };
312313
});
313314

314-
require("babel-plugin-react-directives/lib/runtime").invokeExtraOnChange.call(this, _args, [
315+
invokeOnchange.call(this, _args, [
315316
{ onChange: this.onChange.bind(this) },
316317
this.props
317318
]);
@@ -356,7 +357,7 @@ class Foo extends React.Component {
356357
<input
357358
value={data.text}
358359
onChange={(..._args) => {
359-
let _value = require("babel-plugin-react-directives/lib/runtime").resolveValue(_args);
360+
let _value = resolveValue(_args);
360361

361362
this.setState(_prevState => {
362363
let _val = {
@@ -391,7 +392,7 @@ function Foo() {
391392
<input
392393
value={data}
393394
onChange={(..._args) => {
394-
let _value = require("babel-plugin-react-directives/lib/runtime").resolveValue(_args);
395+
let _value = resolveValue(_args);
395396

396397
setData(_value);
397398
}}
@@ -402,6 +403,50 @@ function Foo() {
402403

403404
**提示**: 如果你在项目中使用了 [**ESLint**](https://eslint.org),也许会提示你 `setData` 是一个从未使用的变量,请安装 [**eslint-plugin-react-directives**](https://github.com/peakchen90/eslint-plugin-react-directives) 来解决这个问题
404405

406+
### <span id="toc-directives-x-class">x-class</span>
407+
408+
> *1.1.0版本新增*
409+
410+
`x-class` 通过 [classnames](https://github.com/JedWatson/classnames) 有条件的生成 className, 这对于动态生成 className 非常有用。
411+
用法与 [classnames](https://github.com/JedWatson/classnames) 相同,绑定值将作为参数传给 [`classNames`](https://github.com/JedWatson/classnames#usage) 方法。
412+
413+
**例子:**
414+
```jsx harmony
415+
const foo = <div x-class={{ abc: true, def: false }}>
416+
```
417+
418+
**转换成:**
419+
```jsx harmony
420+
const foo = <div className={classNames({ abc: true, def: false })}>
421+
// className="abc"
422+
```
423+
**提示**: `classNames` 方法引用于 [runtime/classnames.js](./runtime/classnames.js).
424+
425+
当然,它也将合并其他的 `className` props, 例如:
426+
```jsx harmony
427+
const foo = <div x-class={{ abc: true, def: false }} className="xyz">
428+
```
429+
430+
将被转换成:
431+
```jsx harmony
432+
const foo = <div className={classNames(["xyz", { abc: true, def: false }])}>
433+
// className="xyz abc"
434+
```
435+
436+
`x-class` 也可以与 [css-modules](https://github.com/css-modules/css-modules) 一起使用,例如:
437+
```jsx harmony
438+
import styles from './style.css';
439+
440+
const foo = (
441+
<div
442+
className={styles.foo}
443+
x-class={{
444+
[styles.bar]: true,
445+
[styles.qux]: false
446+
}}
447+
/>
448+
)
449+
```
405450

406451
## <span id="toc-related-packages">相关资源</span>
407452
- [eslint-plugin-react-directives](https://github.com/peakchen90/eslint-plugin-react-directives)

README.md

Lines changed: 56 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ A babel plugin that provides some directives for react(any JSX), similar to dire
88
[![npm](https://img.shields.io/npm/v/babel-plugin-react-directives.svg)](https://www.npmjs.com/package/babel-plugin-react-directives)
99
[![GitHub](https://img.shields.io/github/license/mashape/apistatus.svg)](https://github.com/peakchen90/babel-plugin-react-directives/blob/master/LICENSE)
1010

11-
> 🇨🇳 [**中文文档**](./README.ZH-CN.md)
11+
> [**中文文档**](./README.ZH-CN.md)
1212
1313
## Table of Contents
1414
- [Usage](#toc-usage)
@@ -22,6 +22,7 @@ A babel plugin that provides some directives for react(any JSX), similar to dire
2222
- [x-for](#toc-directives-x-for)
2323
- [x-model](#toc-directives-x-model)
2424
- [x-model-hook](#toc-directives-x-model-hook)
25+
- [x-class](#toc-directives-x-class)
2526
- [Related Packages](#toc-related-packages)
2627
- [Known Issues](#toc-known-issues)
2728
- [CHANGELOG](#toc-changeloog)
@@ -137,7 +138,7 @@ const foo = (
137138
)
138139
```
139140

140-
Of course, it will also merge other `style` by calling the [runtime function](./lib/runtime.js), for example:
141+
Of course, it will also merge other `style` props by calling the [mergeProps method](./runtime/merge-props.js), for example:
141142
```jsx harmony
142143
const foo = (
143144
<div
@@ -155,7 +156,7 @@ const foo = (
155156
<div
156157
{...extraProps}
157158
style={{
158-
...require("babel-plugin-react-directives/lib/runtime").mergeProps.call(this, "style", [
159+
...mergeProps.call(this, "style", [
159160
{ style: { color: 'red' } },
160161
extraProps
161162
]),
@@ -228,7 +229,7 @@ const foo = (
228229

229230
### <span id="toc-directives-x-model">x-model</span>
230231
The `x-model` is a syntax sugar similar to vue `v-model`, which binds a state to the `value` prop of the **form element** and automatically updates the state when the element is updated.
231-
It resolves the updated value by calling the [runtime function](./lib/runtime.js) (If the first argument `arg` is non-empty, and `arg.target` is an object, return `arg.target.value`, otherwise return `arg`).
232+
It resolves the updated value by calling the [resolveValue method](./runtime/resolve-value.js) (If the first argument `arg` is non-empty, and `arg.target` is an object, return `arg.target.value`, otherwise return `arg`).
232233

233234
**Example:**
234235
```jsx harmony
@@ -255,7 +256,7 @@ class Foo extends React.Component {
255256
render() {
256257
return (
257258
<input value={this.state.data} onChange={(..._args) => {
258-
let _value = require("babel-plugin-react-directives/lib/runtime").resolveValue(_args);
259+
let _value = resolveValue(_args);
259260

260261
this.setState(_prevState => {
261262
return { data: _value };
@@ -266,7 +267,7 @@ class Foo extends React.Component {
266267
}
267268
```
268269

269-
When there are other `onChange` props, merge them by calling the [runtime function](./lib/runtime.js):
270+
When there are other `onChange` props, merge them by calling the [invokeOnchange method](./runtime/invoke-onchange.js):
270271
```jsx harmony
271272
class Foo extends React.Component {
272273
constructor(props) {
@@ -308,13 +309,13 @@ class Foo extends React.Component {
308309
{...this.props}
309310
value={this.state.data}
310311
onChange={(..._args) => {
311-
let _value = require("babel-plugin-react-directives/lib/runtime").resolveValue(_args);
312+
let _value = resolveValue(_args);
312313

313314
this.setState(_prevState => {
314315
return { data: _value };
315316
});
316317

317-
require("babel-plugin-react-directives/lib/runtime").invokeExtraOnChange.call(this, _args, [
318+
invokeOnchange.call(this, _args, [
318319
{ onChange: this.onChange.bind(this) },
319320
this.props
320321
]);
@@ -359,7 +360,7 @@ class Foo extends React.Component {
359360
<input
360361
value={data.text}
361362
onChange={(..._args) => {
362-
let _value = require("babel-plugin-react-directives/lib/runtime").resolveValue(_args);
363+
let _value = resolveValue(_args);
363364

364365
this.setState(_prevState => {
365366
let _val = {
@@ -394,7 +395,7 @@ function Foo() {
394395
<input
395396
value={data}
396397
onChange={(..._args) => {
397-
let _value = require("babel-plugin-react-directives/lib/runtime").resolveValue(_args);
398+
let _value = resolveValue(_args);
398399

399400
setData(_value);
400401
}}
@@ -406,6 +407,51 @@ function Foo() {
406407
**Note**: If you use [**ESLint**](https://eslint.org), you may receive an error that `setData` is defined but never used.
407408
Please install [**eslint-plugin-react-directives**](https://github.com/peakchen90/eslint-plugin-react-directives) plugin to solve it.
408409

410+
### <span id="toc-directives-x-class">x-class</span>
411+
412+
> *New in 1.1.0*
413+
414+
The `x-class` for conditionally joining classNames together by [classnames](https://github.com/JedWatson/classnames), and it is useful for dynamically generating className.
415+
Usage is the same as [classnames](https://github.com/JedWatson/classnames), the binding value will be passed as a parameter to the [`classNames`](https://github.com/JedWatson/classnames#usage) method.
416+
417+
**Example:**
418+
```jsx harmony
419+
const foo = <div x-class={{ abc: true, def: false }}>
420+
```
421+
422+
**Convert to:**
423+
```jsx harmony
424+
const foo = <div className={classNames({ abc: true, def: false })}>
425+
// className="abc"
426+
```
427+
**Note**: `classNames` method references [runtime/classnames.js](./runtime/classnames.js).
428+
429+
Of course, it will also merge other `className` props, for example:
430+
**Example:**
431+
```jsx harmony
432+
const foo = <div x-class={{ abc: true, def: false }} className="xyz">
433+
```
434+
435+
will be converted to:
436+
```jsx harmony
437+
const foo = <div className={classNames(["xyz", { abc: true, def: false }])}>
438+
// className="xyz abc"
439+
```
440+
441+
The `x-class` can also be used with [css-modules](https://github.com/css-modules/css-modules), for example:
442+
```jsx harmony
443+
import styles from './style.css';
444+
445+
const foo = (
446+
<div
447+
className={styles.foo}
448+
x-class={{
449+
[styles.bar]: true,
450+
[styles.qux]: false
451+
}}
452+
/>
453+
)
454+
```
409455

410456
## <span id="toc-related-packages">Related Packages</span>
411457
- [eslint-plugin-react-directives](https://github.com/peakchen90/eslint-plugin-react-directives)

package-lock.json

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
{
22
"name": "babel-plugin-react-directives",
3-
"version": "1.0.2",
3+
"version": "1.1.0-rc.1",
44
"description": "A babel plugin that provides some directives for react(any JSX), similar to directive of vue.",
55
"main": "src/index.js",
66
"files": [
77
"src",
8-
"lib",
8+
"runtime",
99
"package.json",
1010
"README.md",
1111
"LICENSE"

src/directives/model.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -321,7 +321,7 @@ function setOnChangeProp(path, attrPath, stateBindingStack, useType) {
321321
t.blockStatement([
322322

323323
/**
324-
* let _val = require('babel-plugin-react-directives').resolveValue(_args)
324+
* let _val = require('babel-plugin-react-directives/runtime/resolve-value.js')(_args)
325325
*/
326326
t.variableDeclaration('let', [
327327
t.variableDeclarator(
@@ -339,7 +339,7 @@ function setOnChangeProp(path, attrPath, stateBindingStack, useType) {
339339
...setStateExpression,
340340

341341
/**
342-
* require("babel-plugin-react-directives/lib/runtime").invokeOnChange.call(this, _args, []);
342+
* require('babel-plugin-react-directives/runtime/invoke-onchange.js').call(this, _args, []);
343343
*/
344344
mergeItems.length > 0 && t.expressionStatement(
345345
builder.buildCallRuntimeExpression(

0 commit comments

Comments
 (0)