Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
calebporzio committed Jul 18, 2022
1 parent b2a02fb commit 1093565
Show file tree
Hide file tree
Showing 15 changed files with 80 additions and 246 deletions.
161 changes: 8 additions & 153 deletions index.html
Original file line number Diff line number Diff line change
Expand Up @@ -11,158 +11,13 @@
<script src="//cdn.tailwindcss.com"></script>
<!-- <script src="https://unpkg.com/@popperjs/core@2"></script> -->

<div x-data x-tabs>
<div x-tabs:list>
<div><button x-tabs:tab>Hey!</button></div>
<div><button x-tabs:tab>There!</button></div>
<div><button x-tabs:tab>You!</button></div>
</div>

<div x-tabs:panels>
<div x-tabs:panel>
<h1>Hey!</h1>
</div>
<div x-tabs:panel>
<h1>There!</h1>
</div>
<div x-tabs:panel>
<h1>You!</h1>
</div>
</div>
</div>

<div x-data="{ open: false }">
<button @click="open = ! open">Open</button>

<div x-dialog x-model="open">
<div x-dialog:panel>
Hey!
</div>
</div>
<div x-data="{}">
<a href="#hello" x-bind:href="null">null</a>
<a href="#hello" x-bind:href="false">false</a>
<a href="#hello" x-bind:href="undefined">undefined</a>
<!-- custom attribute see https://github.com/alpinejs/alpine/issues/280 -->
<span visible="true" x-bind:visible="null">null</span>
<span visible="true" x-bind:visible="false">false</span>
<span visible="true" x-bind:visible="undefined">undefined</span>
</div>

<div x-data x-popover:group>
<div x-data x-popover>
<button x-popover:button>Open</button>
<ul x-popover:panel>
<li><button>yo</button></li>
<li><button>there</button></li>
<li><button>you</button></li>
</ul>
</div>
<div x-data x-popover>
<button x-popover:button>Open 2</button>
<ul x-popover:panel>
<li><button>yo</button></li>
<li><button>yins</button></li>
<li><button>yack</button></li>
</ul>
</div>
</div>

<div></div>

<!-- <div x-data x-tabs>
<button x-tabs:button>Open</button>
<ul x-tabs:panel>
hey
</ul>
</div> -->

<button>focus away</button>

<button id="hey">
hey
</button>

<script>
document.addEventListener('alpine:init', () => {
Alpine.bind(document.querySelector('#hey'), {
'@keyup.esc'() { console.log(this.$el); return 'there' }
})
})
</script>

<!-- <main class="flex-1 overflow-auto bg-gray-50 h-screen">
<div class="flex justify-center items-center space-x-12 p-12">
<button>Previous</button>
<nav
x-data="{ links: ['First', 'Second', 'Third', 'Fourth'] }"
x-popover:group
aria-label="Mythical University"
class="flex space-x-3"
>
<div x-popover class="relative">
<div
x-popover:overlay
x-transition:enter="transition ease-out duration-300 transform"
x-transition:enter-start="opacity-0"
x-transition:enter-end="opacity-100"
x-transition:leave="transition ease-in duration-300 transform"
x-transition:leave-start="opacity-100"
x-transition:leave-end="opacity-0"
class="bg-opacity-75 bg-gray-500 fixed inset-0 z-20"
></div>
<button
x-popover:button
class="px-3 py-2 bg-gray-300 border-2 border-transparent focus:outline-none focus:border-blue-900 relative z-30"
>Normal</button>
<div x-popover:panel class="absolute flex flex-col w-64 bg-gray-100 border-2 border-blue-900 z-30">
<template x-for="(link, i) of links">
<a :hidden="i === 2" href="/" class="px-3 py-2 border-2 border-transparent hover:bg-gray-200 focus:bg-gray-200 focus:outline-none focus:border-blue-900">
Normal - <span x-text="link"></span>
</a>
</template>
</div>
</div>
<div x-popover class="relative">
<button x-popover:button class="px-3 py-2 bg-gray-300 border-2 border-transparent focus:outline-none focus:border-blue-900">Focus</button>
<div x-popover:panel :focus="true" class="absolute flex flex-col w-64 bg-gray-100 border-2 border-blue-900">
<template x-for="(link, i) of links">
<a href="/" class="px-3 py-2 border-2 border-transparent hover:bg-gray-200 focus:bg-gray-200 focus:outline-none focus:border-blue-900">
Focus - <span x-text="link"></span>
</a>
</template>
</div>
</div>
<div
x-popover
class="relative"
x-init="$nextTick(() => Popper.createPopper($refs.trigger1, $refs.container1, { placement: 'bottom-start', strategy: 'fixed' }))"
>
<button x-popover:button x-ref="trigger1" class="px-3 py-2 bg-gray-300 border-2 border-transparent focus:outline-none focus:border-blue-900">Portal</button>
<template x-teleport="body">
<div x-popover:panel x-ref="container1" class="flex flex-col w-64 bg-gray-100 border-2 border-blue-900">
<template x-for="(link, i) of links">
<a href="/" class="px-3 py-2 border-2 border-transparent hover:bg-gray-200 focus:bg-gray-200 focus:outline-none focus:border-blue-900">
Portal - <span x-text="link"></span>
</a>
</template>
</div>
</template>
</div>
<div
x-popover
class="relative"
x-init="$nextTick(() => Popper.createPopper($refs.trigger2, $refs.container2, { placement: 'bottom-start', strategy: 'fixed' }))"
>
<button x-popover:button x-ref="trigger2" class="px-3 py-2 bg-gray-300 border-2 border-transparent focus:outline-none focus:border-blue-900">Focus in portal</button>
<template x-teleport="body">
<div x-popover:panel :focus="true" x-ref="container2" class="flex flex-col w-64 bg-gray-100 border-2 border-blue-900">
<template x-for="(link, i) of links">
<a href="/" class="px-3 py-2 border-2 border-transparent hover:bg-gray-200 focus:bg-gray-200 focus:outline-none focus:border-blue-900">
Focus in Portal - <span x-text="link"></span>
</a>
</template>
</div>
</template>
</div>
</nav>
<button>Next</button>
</div>
</main> -->
</html>
2 changes: 0 additions & 2 deletions packages/alpinejs/src/alpine.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ import { plugin } from './plugin'
import { magic } from './magics'
import { store } from './store'
import { bind } from './binds'
import { registerElement as element } from './elements'
import { data } from './datas'

let Alpine = {
Expand Down Expand Up @@ -52,7 +51,6 @@ let Alpine = {
initTree,
nextTick,
prefixed,
element,
prefix,
plugin,
magic,
Expand Down
20 changes: 0 additions & 20 deletions packages/alpinejs/src/directives.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,26 +22,6 @@ export function directive(name, callback) {
export function directives(el, attributes, originalAttributeOverride) {
attributes = Array.from(attributes)

if (el._x_virtualDirectives) {
let vAttributes = Object.entries(el._x_virtualDirectives).map(([name, value]) => ({ name, value }))

let staticAttributes = attributesOnly(vAttributes)

// Handle binding normal HTML attributes (non-Alpine directives).
vAttributes = vAttributes.map(attribute => {
if (staticAttributes.find(attr => attr.name === attribute.name)) {
return {
name: `x-bind:${attribute.name}`,
value: `"${attribute.value}"`,
}
}

return attribute
})

attributes = attributes.concat(vAttributes)
}

let transformedAttributeMap = {}

let directives = attributes
Expand Down
12 changes: 6 additions & 6 deletions packages/alpinejs/src/utils/bind.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ export default function bind(el, name, value, modifiers = []) {
if (! el._x_bindings) el._x_bindings = reactive({})

el._x_bindings[name] = value

name = modifiers.includes('camel') ? camelCase(name) : name

switch (name) {
Expand Down Expand Up @@ -129,21 +129,21 @@ function attributeShouldntBePreservedIfFalsy(name) {
}

export function getBinding(el, name, fallback) {
// First let's get it out of Alpine bound data.
// First let's get it out of Alpine bound data.
if (el._x_bindings && el._x_bindings[name] !== undefined) return el._x_bindings[name]

// If not, we'll return the literal attribute.
// If not, we'll return the literal attribute.
let attr = el.getAttribute(name)

// Nothing bound:
if (attr === null) return typeof fallback === 'function' ? fallback() : fallback

if (isBooleanAttr(name)) {
return !! [name, 'true'].includes(attr)
}

// The case of a custom attribute with no value. Ex: <div manual>
// The case of a custom attribute with no value. Ex: <div manual>
if (attr === '') return true

return attr
}
1 change: 1 addition & 0 deletions packages/ui/src/dialog.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ function handleRoot(el, Alpine) {
else this.__isOpenState = false
},
get __isOpen() {
console.log('foo', Alpine.bound(el, 'static', this.__isOpenState))
return Alpine.bound(el, 'static', this.__isOpenState)
},
}
Expand Down
4 changes: 0 additions & 4 deletions packages/ui/src/index.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,5 @@
import dialog from './dialog'
import popover from './popover'
import tabs from './tabs'

export default function (Alpine) {
dialog(Alpine)
popover(Alpine)
tabs(Alpine)
}
12 changes: 6 additions & 6 deletions tests/cypress/integration/directives/x-bind.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -49,12 +49,12 @@ test('non-boolean attributes set to null/undefined/false are removed from the el
</div>
`,
({ get }) => {
get('a:nth-child(1)').should(notHaveAttribute('href'))
get('a:nth-child(2)').should(notHaveAttribute('href'))
get('a:nth-child(3)').should(notHaveAttribute('href'))
get('span:nth-child(1)').should(notHaveAttribute('visible'))
get('span:nth-child(2)').should(notHaveAttribute('visible'))
get('span:nth-child(3)').should(notHaveAttribute('visible'))
get('a:nth-of-type(1)').should(notHaveAttribute('href'))
get('a:nth-of-type(2)').should(notHaveAttribute('href'))
get('a:nth-of-type(3)').should(notHaveAttribute('href'))
get('span:nth-of-type(1)').should(notHaveAttribute('visible'))
get('span:nth-of-type(2)').should(notHaveAttribute('visible'))
get('span:nth-of-type(3)').should(notHaveAttribute('visible'))
}
)

Expand Down
42 changes: 21 additions & 21 deletions tests/cypress/integration/directives/x-for.spec.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { beVisible, haveLength, haveText, html, notBeVisible, test } from '../../utils'
import { exist, haveLength, haveText, html, notExist, test } from '../../utils'

test('renders loops with x-for',
html`
Expand All @@ -12,7 +12,7 @@ test('renders loops with x-for',
`,
({ get }) => {
get('span:nth-of-type(1)').should(haveText('foo'))
get('span:nth-of-type(2)').should(notBeVisible())
get('span:nth-of-type(2)').should(notExist())
get('button').click()
get('span:nth-of-type(1)').should(haveText('foo'))
get('span:nth-of-type(2)').should(haveText('bar'))
Expand Down Expand Up @@ -47,9 +47,9 @@ test('renders loops with x-for that have space or newline',
`,
({ get }) => {
get('#1 span:nth-of-type(1)').should(haveText('foo'))
get('#1 span:nth-of-type(2)').should(notBeVisible())
get('#1 span:nth-of-type(2)').should(notExist())
get('#2 span:nth-of-type(1)').should(haveText('foo'))
get('#2 span:nth-of-type(2)').should(notBeVisible())
get('#2 span:nth-of-type(2)').should(notExist())
get('button').click()
get('#1 span:nth-of-type(1)').should(haveText('foo'))
get('#1 span:nth-of-type(2)').should(haveText('bar'))
Expand Down Expand Up @@ -107,9 +107,9 @@ test('removes all elements when array is empty and previously had one item',
</div>
`,
({ get }) => {
get('span').should(beVisible())
get('span').should(exist())
get('button').click()
get('span').should(notBeVisible())
get('span').should(notExist())
}
)

Expand All @@ -124,13 +124,13 @@ test('removes all elements when array is empty and previously had multiple items
</div>
`,
({ get }) => {
get('span:nth-of-type(1)').should(beVisible())
get('span:nth-of-type(2)').should(beVisible())
get('span:nth-of-type(3)').should(beVisible())
get('span:nth-of-type(1)').should(exist())
get('span:nth-of-type(2)').should(exist())
get('span:nth-of-type(3)').should(exist())
get('button').click()
get('span:nth-of-type(1)').should(notBeVisible())
get('span:nth-of-type(2)').should(notBeVisible())
get('span:nth-of-type(3)').should(notBeVisible())
get('span:nth-of-type(1)').should(notExist())
get('span:nth-of-type(2)').should(notExist())
get('span:nth-of-type(3)').should(notExist())
}
)

Expand All @@ -148,11 +148,11 @@ test('elements inside of loop are reactive',
</div>
`,
({ get }) => {
get('span').should(beVisible())
get('span').should(exist())
get('h1').should(haveText('first'))
get('h2').should(haveText('bar'))
get('button').click()
get('span').should(beVisible())
get('span').should(exist())
get('h1').should(haveText('first'))
get('h2').should(haveText('baz'))
}
Expand Down Expand Up @@ -315,13 +315,13 @@ test('nested x-for',
</div>
`,
({ get }) => {
get('h1:nth-of-type(1) h2:nth-of-type(1)').should(beVisible())
get('h1:nth-of-type(1) h2:nth-of-type(2)').should(beVisible())
get('h1:nth-of-type(2) h2:nth-of-type(1)').should(notBeVisible())
get('h1:nth-of-type(1) h2:nth-of-type(1)').should(exist())
get('h1:nth-of-type(1) h2:nth-of-type(2)').should(exist())
get('h1:nth-of-type(2) h2:nth-of-type(1)').should(notExist())
get('button').click()
get('h1:nth-of-type(1) h2:nth-of-type(1)').should(beVisible())
get('h1:nth-of-type(1) h2:nth-of-type(2)').should(beVisible())
get('h1:nth-of-type(2) h2:nth-of-type(1)').should(beVisible())
get('h1:nth-of-type(1) h2:nth-of-type(1)').should(exist())
get('h1:nth-of-type(1) h2:nth-of-type(2)').should(exist())
get('h1:nth-of-type(2) h2:nth-of-type(1)').should(exist())
}
)

Expand Down Expand Up @@ -538,7 +538,7 @@ test('x-for removed dom node does not evaluate child expressions after being rem
get('span').should(haveText('lebowski'))

/** Clicking button sets users=[] and thus x-for loop will remove all children.
If the sub-expression x-text="users[idx].name" is evaluated, the button click
If the sub-expression x-text="users[idx].name" is evaluated, the button click
will produce an error because users[idx] is no longer defined and the test will fail
**/
get('button').click()
Expand Down
Loading

0 comments on commit 1093565

Please sign in to comment.