Skip to content

Commit e26ee9d

Browse files
committed
Complete new js-element version with complete new API
1 parent 676cc5d commit e26ee9d

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

43 files changed

+12242
-16321
lines changed

.storybook/webpack.config.js

Lines changed: 0 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,10 @@
11
const path = require('path')
22

33
module.exports = ({ config }) => {
4-
config.module.rules.push({
5-
test: /\.(ts|tsx)$/,
6-
7-
use: [
8-
{
9-
loader: require.resolve('awesome-typescript-loader')
10-
}
11-
]
12-
})
13-
144
const alias = (config.resolve && config.resolve.alias) || {}
155

166
alias['js-element$'] = path.resolve(__dirname, '../src/main/js-element.ts')
177

18-
alias['js-element/core$'] = path.resolve(
19-
__dirname,
20-
'../src/main/js-element-core.ts'
21-
)
22-
238
alias['js-element/hooks$'] = path.resolve(
249
__dirname,
2510
'../src/main/js-element-hooks.ts'
@@ -30,16 +15,6 @@ module.exports = ({ config }) => {
3015
'../src/main/js-element-utils.ts'
3116
)
3217

33-
alias['js-element/lit$'] = path.resolve(
34-
__dirname,
35-
'../src/main/js-element-lit.ts'
36-
)
37-
38-
alias['js-element/uhtml$'] = path.resolve(
39-
__dirname,
40-
'../src/main/js-element-uhtml.ts'
41-
)
42-
4318
config.resolve.alias = alias
4419
config.resolve.extensions.push('.ts', '.tsx')
4520

README.md

Lines changed: 35 additions & 174 deletions
Original file line numberDiff line numberDiff line change
@@ -1,195 +1,56 @@
11
# js-element
22

33
A R&D project to evaluate an alternative approach to develop custom elements.
4-
The package `js-element` uses a patched version of [superfine](https://github.com/jorgebucaran/superfine), a very lightweight virtual DOM library.
5-
The subpackages `js-element/lit` and `js-element/uhtml` use [lit-html](https://lit-html.polymer-project.org/) respective [uhtml](https://github.com/WebReflection/uhtml) instead.
64

75
#### Disclaimer:
86

97
Project is in an early state ...
108
and it is currently not meant to ever be used in production.
119

12-
## Examples
10+
## Example (simple counter)
1311

14-
### Example 1 (using JSX)
15-
16-
```jsx
17-
import { define, h, render } from 'js-element'
12+
```tsx
13+
import { component, elem, prop, setMethods, Attrs } from 'js-element'
1814
import { useState } from 'js-element/hooks'
19-
20-
const Counter = define('demo-counter', () => {
21-
const [state, setState] = useState({ count: 0 })
22-
const onClick = () => setState('count', it => it + 1)
23-
24-
return () => (
25-
<button onclick={onClick}>
26-
Count: {state.count}
27-
</button>
28-
)
29-
})
30-
31-
render(<Counter />, '#app')
32-
```
33-
34-
### Example 2 (using lit-html)
35-
36-
```js
37-
import { define, html, render } from 'js-element/lit'
38-
import { useState } from 'js-element/hooks'
39-
40-
define('demo-counter', () => {
41-
const [state, setState] = useState({ count: 0 })
42-
const onClick = () => setState('count', it => it + 1)
43-
44-
return () => html`
45-
<button @click=${onClick}>
46-
Count: ${state.count}
47-
</button>
48-
`
49-
})
50-
51-
render(html`<demo-counter></demo-counter>`, '#app')
52-
```
53-
54-
### Example 3 (using uhtml)
55-
56-
```js
57-
import { define, html, render } from 'js-element/uhtml'
58-
import { useState } from 'js-element/hooks'
59-
60-
define('demo-counter', () => {
61-
const [state, setState] = useState({ count: 0 })
62-
const onClick = () => setState('count', it => it + 1)
63-
64-
return () => html`
65-
<button @click=${onClick}>
66-
Count: ${state.count}
67-
</button>
68-
`
69-
})
70-
71-
render(html`<demo-counter />`, '#app')
72-
```
73-
74-
### Example 4
75-
76-
```jsx
77-
import { define, h, render } from 'js-element'
78-
79-
class SayHelloProps {
80-
salutation = 'Hello'
81-
name = 'World'
15+
import { html } from 'lit-html'
16+
import { createRef, ref } from 'lit-html/directives/ref'
17+
import counterStyles from './counter.css'
18+
19+
@elem({
20+
tag: 'x-counter',
21+
styles: counterStyles,
22+
impl: counterImpl
23+
})
24+
class Counter extends component<{
25+
reset(): void
26+
increment(): void
27+
decrement(): void
28+
}>() {
29+
@prop({ attr: Attrs.string, refl: true })
30+
labelText = 'Counter'
31+
32+
@prop({ attr: Attrs.boolean, refl: true })
33+
disabled = false
8234
}
8335

84-
const SayHello = define('say-hello', SayHelloProps, (props) => {
85-
return () => (
86-
<div>
87-
{props.salutation}, {props.name}!
88-
</div>
89-
)
90-
})
91-
92-
render(<SayHello salutation="Hi" name="Jane Doe" />, '#app')
93-
```
94-
95-
### Example 5
96-
97-
```jsx
98-
// the author's preferred syntax and naming convention -
99-
// may look a bit odd first, but you'll get used to it ;-)
100-
101-
import { attr, define, h, render, Attr } from 'js-element'
102-
import { useEffect, useAfterMount, useState } from 'js-element/hooks'
103-
import counterStyles from './counter.scss'
104-
105-
class CounterProps {
106-
@attr(Attr.number, true) // true as 2nd argument means: reflect attribute
107-
initialCount = 0
108-
109-
@attr(Attr.string, true)
110-
label = 'Counter'
111-
}
112-
113-
const Counter = define({
114-
tag: 'demo-counter',
115-
props: CounterProps,
116-
styles: counterStyles
117-
}).bind((p) => {
36+
function counterImpl(self: Counter) {
11837
const [state, setState] = useState({
119-
count: p.initialCount
38+
count: 0
12039
})
12140

122-
const onClick = () => setState('count', it => it + 1)
123-
124-
useAfterMount(() => {
125-
console.log(`"${p.label}" has been mounted`)
41+
const onClick = () => setState('count', (it) => it + 1)
12642

127-
return () => console.log(`Unmounting "${p.label}"`)
43+
setMethods(self, {
44+
reset: () => setState('count', 0),
45+
increment: () => setState('count', (it) => it + 1),
46+
decrement: () => setState('count', (it) => it - 1)
12847
})
12948

130-
useEffect(
131-
() => console.log(`Value of "${p.label}": ${s.count}`),
132-
() => [s.count]
133-
)
134-
135-
return () => (
136-
<div class="counter">
137-
<label class="label">{p.label}: </label>
138-
<button class="button" onclick={onClick}>
139-
{s.count}
140-
</button>
141-
</div>
142-
)
143-
})
144-
145-
render(<Counter />, '#app')
146-
```
147-
148-
### Example 6
149-
150-
```jsx
151-
import { define, h, render } from 'js-element'
152-
import { useTimer } from 'js-element/hooks'
153-
154-
const Clock = define('demo-clock', () => {
155-
const getTime = useTimer(1000, () => new Date().toLocaleTimeString())
156-
return () => <div>Current time: {getTime()}</div>
157-
})
158-
159-
render(<Clock />, '#app')
49+
return () => html`
50+
<button ?disabled=${self.disabled} @click=${onClick}>
51+
${self.labelText}: ${state.count}
52+
</button>
53+
`
54+
}
16055
```
16156

162-
### Example 7 (using context)
163-
164-
```jsx
165-
import { createCtx, define, defineProvider, h, render } from 'js-element'
166-
import { useCtx, useInterval, useState } from 'js-element/hooks'
167-
168-
const ThemeCtx = createCtx('light')
169-
const ThemeProvider = defineProvider('theme-provider', ThemeCtx)
170-
171-
const ContextDemo = define('context-demo', () => {
172-
const [state, setState] = useState({ theme: 'light' })
173-
174-
useInterval(() => {
175-
setState('theme', state.theme === 'light' ? 'dark' : 'light')
176-
}, 1000)
177-
178-
return () => (
179-
<div>
180-
<b>Value for theme will change every second:</b>
181-
<br />
182-
<ThemeProvider value={state.theme}>
183-
<ThemeInfo />
184-
</ThemeProvider>
185-
</div>
186-
)
187-
})
188-
189-
const ThemeInfo = define('theme-info', () => {
190-
const ctx = useCtx({ theme: ThemeCtx })
191-
return () => <div>Current theme: {ctx.theme}</div>
192-
})
193-
194-
render(<ContextDemo/>, '#app')
195-
```

core/index.js

Lines changed: 0 additions & 7 deletions
This file was deleted.

core/package.json

Lines changed: 0 additions & 10 deletions
This file was deleted.

lit/index.js

Lines changed: 0 additions & 7 deletions
This file was deleted.

lit/package.json

Lines changed: 0 additions & 10 deletions
This file was deleted.

package.json

Lines changed: 25 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -152,52 +152,42 @@
152152
"zipsource": "shx rm -rf ./build/source && shx mkdir -p ./build/source && copyfiles -a ./* ./build/source && shx cp -r ./src ./build/source && shx mkdir -p ./dist/source && cd build && bestzip --force node ../dist/source/source.zip source && cd .."
153153
},
154154
"devDependencies": {
155-
"@babel/core": "^7.13.14",
156-
"@nx-js/observer-util": "^4.2.2",
157-
"@rollup/plugin-commonjs": "^18.0.0",
158-
"@rollup/plugin-node-resolve": "^11.2.1",
159-
"@rollup/plugin-replace": "^2.4.2",
160-
"@rollup/plugin-typescript": "^8.2.1",
161-
"@storybook/addon-actions": "^6.2.3",
162-
"@storybook/addon-essentials": "^6.2.3",
163-
"@storybook/addon-links": "^6.2.3",
164-
"@storybook/addons": "^6.2.3",
165-
"@storybook/html": "^6.2.3",
166-
"@storybook/web-components": "^6.2.3",
167-
"@types/chai": "^4.2.16",
168-
"@types/jest": "^26.0.22",
169-
"@types/mocha": "^8.2.2",
170-
"awesome-typescript-loader": "^5.2.1",
155+
"@babel/core": "^7.15.0",
156+
"@rollup/plugin-commonjs": "^20.0.0",
157+
"@rollup/plugin-node-resolve": "^13.0.4",
158+
"@rollup/plugin-replace": "^3.0.0",
159+
"@rollup/plugin-typescript": "^8.2.5",
160+
"@storybook/addon-actions": "^6.3.7",
161+
"@storybook/addon-essentials": "^6.3.7",
162+
"@storybook/addon-links": "^6.3.7",
163+
"@storybook/addons": "^6.3.7",
164+
"@storybook/html": "^6.3.7",
165+
"@storybook/web-components": "^6.3.7",
166+
"@types/chai": "^4.2.21",
167+
"@types/jest": "^27.0.1",
168+
"@types/mocha": "^9.0.0",
171169
"babel-loader": "^8.2.2",
172170
"bestzip": "^2.2.0",
173171
"copyfiles": "^2.4.1",
174172
"cross-env": "^7.0.3",
175-
"eslint": "^7.23.0",
176-
"htm": "^3.0.4",
177-
"html-webpack-plugin": "^5.3.1",
178-
"jest": "^26.6.3",
179-
"js-immutables": "^0.0.5",
180-
"js-messages": "^0.1.37",
181-
"js-reducers": "0.0.8",
182-
"js-stores": "^0.1.24",
183-
"npm-check-updates": "^11.3.0",
184-
"prettier": "^2.2.1",
185-
"rollup": "^2.44.0",
173+
"eslint": "^7.32.0",
174+
"htm": "^3.1.0",
175+
"html-webpack-plugin": "^5.3.2",
176+
"jest": "^27.0.6",
177+
"npm-check-updates": "^11.8.3",
178+
"rollup": "^2.56.2",
186179
"rollup-plugin-brotli": "^3.1.0",
187180
"rollup-plugin-gzip": "^2.5.0",
188181
"rollup-plugin-replace": "^2.2.0",
189182
"rollup-plugin-terser": "^7.0.2",
190183
"rollup-plugin-typescript2": "^0.30.0",
191-
"rxjs": "^6.6.7",
192184
"shx": "^0.3.3",
193-
"ts-jest": "^26.5.4",
194-
"ts-loader": "^8.1.0",
195-
"ts-node": "^9.1.1",
196-
"typescript": "^4.2.3"
185+
"ts-jest": "^27.0.5",
186+
"ts-node": "^10.2.1",
187+
"typescript": "^4.3.5",
188+
"webpack": "^5.51.1"
197189
},
198190
"dependencies": {
199-
"lit-html": "^1.3.0",
200-
"mobx": "^6.1.8",
201-
"uhtml": "^2.7.1"
191+
"lit-html": "2.0.0-rc.4"
202192
}
203193
}

0 commit comments

Comments
 (0)