Skip to content

Commit 526ddc1

Browse files
committed
Add x-show
1 parent 657fea0 commit 526ddc1

File tree

9 files changed

+124
-14
lines changed

9 files changed

+124
-14
lines changed

README.md

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ Think of it like [Tailwind](https://tailwindcss.com/) for JavaScript.
1111
## Install
1212
Add the following script to the end of your `<head>` section.
1313
```html
14-
<script src="https://cdn.jsdelivr.net/gh/calebporzio/project-x@v0.3.0/dist/project-x.min.js" defer></script>
14+
<script src="https://cdn.jsdelivr.net/gh/calebporzio/project-x@v0.4.0/dist/project-x.min.js" defer></script>
1515
```
1616

1717
## Use
@@ -24,8 +24,7 @@ Add the following script to the end of your `<head>` section.
2424
<button x-on:click="open = true">Open Dropdown</button>
2525

2626
<ul
27-
class="hidden"
28-
x-bind:class="{ 'hidden': ! open }"
27+
x-show="open"
2928
x-on:click.away="open = false"
3029
>
3130
Dropdown Body
@@ -39,8 +38,8 @@ Add the following script to the end of your `<head>` section.
3938
<button x-bind:class="{ 'active': tab === 'foo' }" x-on:click="tab = 'foo'">Foo</button>
4039
<button x-bind:class="{ 'active': tab === 'bar' }" x-on:click="tab = 'bar'">Bar</button>
4140

42-
<div class="hidden" x-bind:class="{ 'hidden': tab !== 'foo' }">Tab Foo</div>
43-
<div class="hidden" x-bind:class="{ 'hidden': tab !== 'bar' }">Tab Bar</div>
41+
<div x-show="tab === 'foo'">Tab Foo</div>
42+
<div x-show="tab === 'bar'">Tab Bar</div>
4443
</div>
4544
```
4645

@@ -51,6 +50,7 @@ There are 7 directives available to you:
5150
| Directive
5251
| --- |
5352
| [`x-data`](#x-data) |
53+
| [`x-show`](#x-show) |
5454
| [`x-bind`](#x-bind) |
5555
| [`x-on`](#x-on) |
5656
| [`x-model`](#x-model) |
@@ -105,6 +105,15 @@ You can also mix-in multiple data objects using object destructuring:
105105

106106
---
107107

108+
### `x-show`
109+
**Example:** `<div x-show="open"></div>`
110+
111+
**Structure:** `<div x-show="[expression]"></div>`
112+
113+
`x-show` toggles the `display: none;` style on the element depending if the expression resolves to `true` or `false`.
114+
115+
---
116+
108117
### `x-bind`
109118
**Example:** `<input x-bind:type="inputType">`
110119

dist/mix-manifest.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
{
2-
"/project-x.js": "/project-x.js?id=bd450a04a07206020f63",
3-
"/project-x.min.js": "/project-x.min.js?id=aca2ba4b017885bdd4a5"
2+
"/project-x.js": "/project-x.js?id=a11dbcb0d5ba1786312d",
3+
"/project-x.min.js": "/project-x.min.js?id=d07f1a5dd55fedec39a4"
44
}

dist/project-x.js

Lines changed: 36 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -950,6 +950,14 @@ function () {
950950

951951
break;
952952

953+
case 'show':
954+
var _this$evaluateReturnE4 = _this.evaluateReturnExpression(expression),
955+
output = _this$evaluateReturnE4.output;
956+
957+
_this.updateVisibility(el, output);
958+
959+
break;
960+
953961
case 'cloak':
954962
el.removeAttribute('x-cloak');
955963
break;
@@ -1019,6 +1027,19 @@ function () {
10191027

10201028
break;
10211029

1030+
case 'show':
1031+
var _self$evaluateReturnE4 = self.evaluateReturnExpression(expression),
1032+
output = _self$evaluateReturnE4.output,
1033+
deps = _self$evaluateReturnE4.deps;
1034+
1035+
if (self.concernedData.filter(function (i) {
1036+
return deps.includes(i);
1037+
}).length > 0) {
1038+
self.updateVisibility(el, output);
1039+
}
1040+
1041+
break;
1042+
10221043
default:
10231044
break;
10241045
}
@@ -1111,6 +1132,19 @@ function () {
11111132
value: function updateTextValue(el, value) {
11121133
el.innerText = value;
11131134
}
1135+
}, {
1136+
key: "updateVisibility",
1137+
value: function updateVisibility(el, value) {
1138+
if (!value) {
1139+
el.style.display = 'none';
1140+
} else {
1141+
if (el.style.length === 1 && el.style.display !== '') {
1142+
el.removeAttribute('style');
1143+
} else {
1144+
el.style.removeProperty('display');
1145+
}
1146+
}
1147+
}
11141148
}, {
11151149
key: "updateAttributeValue",
11161150
value: function updateAttributeValue(el, attrName, value) {
@@ -1388,12 +1422,12 @@ function saferEvalNoReturn(expression, dataContext) {
13881422
return new Function(['$data'].concat(_toConsumableArray(Object.keys(additionalHelperVariables))), "with($data) { ".concat(expression, " }")).apply(void 0, [dataContext].concat(_toConsumableArray(Object.values(additionalHelperVariables))));
13891423
}
13901424
function isXAttr(attr) {
1391-
var xAttrRE = /x-(on|bind|data|text|model|cloak|ref)/;
1425+
var xAttrRE = /x-(on|bind|data|text|model|show|cloak|ref)/;
13921426
return xAttrRE.test(attr.name);
13931427
}
13941428
function getXAttrs(el, type) {
13951429
return Array.from(el.attributes).filter(isXAttr).map(function (attr) {
1396-
var typeMatch = attr.name.match(/x-(on|bind|data|text|model|cloak|ref)/);
1430+
var typeMatch = attr.name.match(/x-(on|bind|data|text|model|show|cloak|ref)/);
13971431
var valueMatch = attr.name.match(/:([a-zA-Z\-]+)/);
13981432
var modifiers = attr.name.match(/\.[^.\]]+(?=[^\]]*$)/g) || [];
13991433
return {

dist/project-x.min.js

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

index.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
[x-cloak] { display: none; }
66
</style>
77

8-
<script src="https://cdn.jsdelivr.net/gh/calebporzio/project-x@v0.3.0/dist/project-x.min.js" defer></script>
8+
<script src="https://cdn.jsdelivr.net/gh/calebporzio/project-x@v0.4.0/dist/project-x.min.js" defer></script>
99
</head>
1010
<body>
1111
<div x-data="{ foo: 'bar' }">

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"main": "dist/project-x.js",
33
"name": "project-x",
4-
"version": "0.3.0",
4+
"version": "0.4.0",
55
"repository": {
66
"type": "git",
77
"url": "git://github.com/calebporzio/project-x.git"

src/component.js

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,11 @@ export default class Component {
6767
this.updateTextValue(el, output)
6868
break;
6969

70+
case 'show':
71+
var { output } = this.evaluateReturnExpression(expression)
72+
this.updateVisibility(el, output)
73+
break;
74+
7075
case 'cloak':
7176
el.removeAttribute('x-cloak')
7277
break;
@@ -114,6 +119,14 @@ export default class Component {
114119
}
115120
break;
116121

122+
case 'show':
123+
var { output, deps } = self.evaluateReturnExpression(expression)
124+
125+
if (self.concernedData.filter(i => deps.includes(i)).length > 0) {
126+
self.updateVisibility(el, output)
127+
}
128+
break;
129+
117130
default:
118131
break;
119132
}
@@ -208,6 +221,18 @@ export default class Component {
208221
el.innerText = value
209222
}
210223

224+
updateVisibility(el, value) {
225+
if (! value) {
226+
el.style.display = 'none'
227+
} else {
228+
if (el.style.length === 1 && el.style.display !== '') {
229+
el.removeAttribute('style')
230+
} else {
231+
el.style.removeProperty('display')
232+
}
233+
}
234+
}
235+
211236
updateAttributeValue(el, attrName, value) {
212237
if (attrName === 'value') {
213238
if (el.type === 'radio') {

src/utils.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ export function saferEvalNoReturn(expression, dataContext, additionalHelperVaria
6161
}
6262

6363
export function isXAttr(attr) {
64-
const xAttrRE = /x-(on|bind|data|text|model|cloak|ref)/
64+
const xAttrRE = /x-(on|bind|data|text|model|show|cloak|ref)/
6565

6666
return xAttrRE.test(attr.name)
6767
}
@@ -70,7 +70,7 @@ export function getXAttrs(el, type) {
7070
return Array.from(el.attributes)
7171
.filter(isXAttr)
7272
.map(attr => {
73-
const typeMatch = attr.name.match(/x-(on|bind|data|text|model|cloak|ref)/)
73+
const typeMatch = attr.name.match(/x-(on|bind|data|text|model|show|cloak|ref)/)
7474
const valueMatch = attr.name.match(/:([a-zA-Z\-]+)/)
7575
const modifiers = attr.name.match(/\.[^.\]]+(?=[^\]]*$)/g) || []
7676

test/show.spec.js

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
import projectX from 'project-x'
2+
import { wait } from 'dom-testing-library'
3+
4+
global.MutationObserver = class {
5+
observe() {}
6+
}
7+
8+
test('x-show toggles display: none; with no other style attributes', async () => {
9+
document.body.innerHTML = `
10+
<div x-data="{ show: true }">
11+
<span x-show="show"></span>
12+
13+
<button x-on:click="show = false"></button>
14+
</div>
15+
`
16+
17+
projectX.start()
18+
19+
expect(document.querySelector('span').getAttribute('style')).toEqual(null)
20+
21+
document.querySelector('button').click()
22+
23+
await wait(() => { expect(document.querySelector('span').getAttribute('style')).toEqual('display: none;') })
24+
})
25+
26+
test('x-show toggles display: none; with no other style attributes', async () => {
27+
document.body.innerHTML = `
28+
<div x-data="{ show: true }">
29+
<span x-show="show" style="color: blue;"></span>
30+
31+
<button x-on:click="show = false"></button>
32+
</div>
33+
`
34+
35+
projectX.start()
36+
37+
expect(document.querySelector('span').getAttribute('style')).toEqual('color: blue;')
38+
39+
document.querySelector('button').click()
40+
41+
await wait(() => { expect(document.querySelector('span').getAttribute('style')).toEqual('color: blue; display: none;') })
42+
})

0 commit comments

Comments
 (0)