Skip to content

Commit

Permalink
Merge pull request #10 from Marcisbee/lit
Browse files Browse the repository at this point in the history
Add support for `lit`
  • Loading branch information
Marcisbee authored Sep 1, 2021
2 parents 919bef7 + 651340e commit 7d4721a
Show file tree
Hide file tree
Showing 12 changed files with 768 additions and 23 deletions.
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
# Changelog

## 0.16.0

### Feature
* Adds `lit` support.

Added new ReactiveController named `StoreController` as part of lit v2.0.

## 0.15.0

### Feature
Expand Down
58 changes: 58 additions & 0 deletions e2e/lit/async-action.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import { join } from 'path'
import { suite } from 'uvu'
import assert from 'uvu/assert'

import * as ENV from '../setup/playwright'
import { BrowserContext } from '../setup/playwright'

const entry = join(__dirname, './async-action.ts')
const test = suite<BrowserContext>('Async action', { entry } as any)

test.before(ENV.setup)
test.before.each(ENV.homepage)
test.after(ENV.reset)

test('renders nothing inside <h1>', async({ page }) => {
const h1 = (await page.$('h1'))!
const span = (await page.$('span'))!

assert.equal(await h1.innerText(), '')
assert.equal(await span.innerText(), '1')
})

test('renders content inside <h1> after action finishes', async({ page }) => {
const h1 = (await page.$('h1'))!
const span = (await page.$('span'))!

assert.equal(await h1.innerText(), '')
assert.equal(await span.innerText(), '1')

await page.click('#getMessage')

assert.equal(await h1.innerText(), '')
assert.equal(await span.innerText(), '1')

await page.waitForTimeout(100)

assert.equal(await h1.innerText(), 'Hello world')
assert.equal(await span.innerText(), '2')
})

test('manages loading state correctly', async({ page }) => {
const span = (await page.$('span'))!

assert.equal((await page.$('#loading')) === null, true)
assert.equal(await span.innerText(), '1')

await page.click('#getMessageWithLoading')

assert.equal((await page.$('#loading')) === null, false)
assert.equal(await span.innerText(), '2')

await page.waitForTimeout(100)

assert.equal((await page.$('#loading')) === null, true)
assert.equal(await span.innerText(), '4')
})

test.run()
30 changes: 30 additions & 0 deletions e2e/lit/async-action.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import { StoreController } from 'exome/lit'
import { LitElement, html } from 'lit'
import { customElement } from 'lit/decorators.js'

import { asyncStore } from '../stores/async-store'

@customElement('lit-app')
export class LitApp extends LitElement {
// Create the controller and store it
private readonly asyncStore = new StoreController(this, asyncStore)

private renders = 0

// Use the controller in render()
render() {
const { message, loading, getMessage, getMessageWithLoading } = this.asyncStore.store

this.renders += 1

return html`
${loading && (html`<i id="loading" />`)}
<h1>${message}</h1>
<button id="getMessage" @click=${getMessage}>Get message</button>
<button id="getMessageWithLoading" @click=${getMessageWithLoading}>Get message with loading</button>
<span>${this.renders}</span>
`
}
}

document.body.innerHTML = '<lit-app />'
42 changes: 42 additions & 0 deletions e2e/lit/counter.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import { join } from 'path'
import { suite } from 'uvu'
import assert from 'uvu/assert'

import * as ENV from '../setup/playwright'
import { BrowserContext } from '../setup/playwright'

const entry = join(__dirname, './counter.ts')
const test = suite<BrowserContext>('Counter', { entry } as any)

test.before(ENV.setup)
test.before.each(ENV.homepage)
test.after(ENV.reset)

test('renders <h1> with "0" inside', async({ page }) => {
const counterValue = await (await page.$('h1'))!.innerText()

assert.equal(counterValue, '0')
})

test('increments count on click', async({ page }) => {
await page.click('h1')

const counterValue = await (await page.$('h1'))!.innerText()

assert.equal(counterValue, '1')
})

test('increments count on click multiple times', async({ page }) => {
await page.click('h1')
await page.click('h1')
await page.click('h1')
await page.click('h1')

const counterValue = await (await page.$('h1'))!.innerText()
const renderCount = await (await page.$('span'))!.innerText()

assert.equal(counterValue, '4')
assert.equal(renderCount, '5')
})

test.run()
27 changes: 27 additions & 0 deletions e2e/lit/counter.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { StoreController } from 'exome/lit'
import { LitElement, html } from 'lit'
import { customElement } from 'lit/decorators.js'

import { counter } from '../stores/counter'

@customElement('lit-app')
export class LitApp extends LitElement {
// Create the controller and store it
private readonly counter = new StoreController(this, counter)

private renders = 0

// Use the controller in render()
render() {
const { count, increment } = this.counter.store

this.renders += 1

return html`
<h1 @click=${increment}>${count}</h1>
<span>${this.renders}</span>
`
}
}

document.body.innerHTML = '<lit-app />'
65 changes: 65 additions & 0 deletions e2e/lit/recursive.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
import { join } from 'path'
import { suite } from 'uvu'
import assert from 'uvu/assert'

import * as ENV from '../setup/playwright'
import { BrowserContext } from '../setup/playwright'

const entry = join(__dirname, './recursive.ts')
const test = suite<BrowserContext>('Recursive', { entry } as any)

test.before(ENV.setup)
test.before.each(ENV.homepage)
test.after(ENV.reset)

test('renders correct amount of <input> elements', async({ page }) => {
const inputs = await page.$$('input')

assert.equal(inputs.length, 9)
})

test('has correct values in input fields', async({ page }) => {
const inputs = await page.$$('input')

assert.equal(await inputs[0].getAttribute('value'), 'root')
assert.equal(await inputs[1].getAttribute('value'), 'one')
assert.equal(await inputs[2].getAttribute('value'), 'ref')
assert.equal(await inputs[3].getAttribute('value'), 'first')
assert.equal(await inputs[4].getAttribute('value'), 'second')
assert.equal(await inputs[5].getAttribute('value'), 'two')
assert.equal(await inputs[6].getAttribute('value'), 'ref')
assert.equal(await inputs[7].getAttribute('value'), 'first')
assert.equal(await inputs[8].getAttribute('value'), 'second')
})

test('updates root value correctly', async({ page }) => {
const inputs = await page.$$('input')

assert.equal(await inputs[0].getAttribute('value'), 'root')

await inputs[0].fill('Foo')

assert.equal(await inputs[0].getAttribute('value'), 'Foo')
assert.equal(await inputs[1].getAttribute('value'), 'one')
assert.equal(await inputs[2].getAttribute('value'), 'ref')
assert.equal(await inputs[3].getAttribute('value'), 'first')
assert.equal(await inputs[4].getAttribute('value'), 'second')
assert.equal(await inputs[5].getAttribute('value'), 'two')
assert.equal(await inputs[6].getAttribute('value'), 'ref')
assert.equal(await inputs[7].getAttribute('value'), 'first')
assert.equal(await inputs[8].getAttribute('value'), 'second')
})

test('updates reference value correctly', async({ page }) => {
const inputs = await page.$$('input')

assert.equal(await inputs[2].getAttribute('value'), 'ref')
assert.equal(await inputs[6].getAttribute('value'), 'ref')

await inputs[2].fill('Bar')

assert.equal(await inputs[2].getAttribute('value'), 'Bar')
assert.equal(await inputs[6].getAttribute('value'), 'Bar')
})

test.run()
65 changes: 65 additions & 0 deletions e2e/lit/recursive.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
import { StoreController } from 'exome/lit'
import { LitElement, html } from 'lit'
import { customElement, property } from 'lit/decorators.js'

import { RecursiveStore, recursiveStore } from '../stores/recursive'

@customElement('lit-item')
export class LitItem extends LitElement {
@property()
public item!: RecursiveStore

// Create the controller and store it
private recursiveStore!: StoreController<RecursiveStore>

connectedCallback() {
this.recursiveStore = new StoreController(this, this.item)
super.connectedCallback()
}

// Use the controller in render()
render() {
const { name, items, rename } = this.recursiveStore.store

return html`
<li>
<input
type="text"
value=${name}
@input=${(e: any) => {
rename(e.target.value)
}}
/>
${items && html`
<ul>
${items.map((subItem) => html`
<lit-item .item=${subItem}></lit-item>
`)}
</ul>
`}
</li>
`
}

// Allow external css
createRenderRoot() {
return this
}
}

@customElement('lit-app')
export class LitApp extends LitElement {
render() {
return html`
<ul><lit-item .item=${recursiveStore}></lit-item></ul>
`
}

// Allow external css
createRenderRoot() {
return this
}
}

document.body.innerHTML = '<lit-app />'
24 changes: 24 additions & 0 deletions e2e/lit/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
{
"compilerOptions": {
"target": "es6",
"module": "commonjs",
"lib": [
"DOM",
"es2015"
],
"strict": true,
"esModuleInterop": true,
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true,
"experimentalDecorators": true,
"paths": {
"exome": [
"../../src/index.ts"
],
"exome/lit": [
"../../src/lit.ts"
]
},
"allowJs": true
}
}
Loading

0 comments on commit 7d4721a

Please sign in to comment.