Skip to content

Commit

Permalink
feat: alpha
Browse files Browse the repository at this point in the history
  • Loading branch information
sebkolind authored Nov 14, 2023
2 parents e901460 + 2336186 commit 21f91f5
Show file tree
Hide file tree
Showing 39 changed files with 7,430 additions and 3,387 deletions.
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
name: Run Jest Tests
name: Jest & Standard

on: [push, pull_request]

Expand All @@ -18,5 +18,8 @@ jobs:
- name: Install Dependencies
run: npm install

- name: Run Jest Tests
- name: Run standard
run: npm run standard

- name: Run Jest
run: npm test
5 changes: 5 additions & 0 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
repos:
- repo: https://github.com/standard/standard
rev: v17.1.0
hooks:
- id: standard
8 changes: 0 additions & 8 deletions .prettierrc

This file was deleted.

155 changes: 111 additions & 44 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,55 +1,122 @@
# else.js
# one.js

Build web apps with atomic components.
A lightweight library to build reactive web apps — fast.

One is in alpha and is under heavy development. You *can* use this for building web apps today, but the library is still considered very immature. All discussions, questions, ideas and PR's are welcome!

## Usage

```js
import {e} from 'else'

e(
'div',
({context}) => [
e('div', `Hello ${context.text}`),
e('button', 'Click me!', {
onclick() {
context.text = context.text.split('').reverse().join('')
},
}),
],
{
data() {
return {text: 'World!'}
},
mount: document.querySelector('#app'),
}
)
import {o, mount} from 'one'

const MyComponent = {
data() {
return {
name: 'John Doe',
}
),
view({ data }) {
return o('div', [
o('p', `Hello ${data.name}`),
])
},
}

mount(document.body, MyComponent)
```
### Router
## Gotchas
Since One is as lightweight as it is, there are a couple of gotchas that you should
be aware of. Feel free to submit a PR if you've found a lightweight way of fixing these.
However, these are gotchas, and can easily be avoided.
### Conditional rendering
When using conditional rendering in a components `view` function, you should
structure your view in such a way, that you don't break the natural render tree.
```js
import {e, createRouter} from 'else'

const Layout = e('div', [
e('header', 'Header'),
e('main', [], {view: true}),
e('footer', 'Footer'),
])

const Home = e('div', e('div', 'This is home'))

const AboutUs = e('div', e('div', 'This is all about us'))

createRouter(
[
{path: '/', component: Home},
{path: '/about-us', component: AboutUs},
],
{
fallback: '/',
layout: Layout,
root: document.querySelector('#app'),
// ok
const Component = {
view({ data }) {
return o('div', [
o('ul',
data.items.length
? data.items.map(item => o('li', `${item.name}`))
: o('li', 'Loading')
)
])
}
)
}

const Component = {
view({ data }) {
return o('div',
data.items.length
? o('nav', data.items.map(item => o('a', `${item.name}`)))
// Notice that both ternaries return same root element.
: o('nav', o('div', 'Loading...'))
)
}
}

const Component = {
view ({ data }) {
return o(
'ul',
data.items.map(item => o('li', `${item.name}`))
)
}
}

// not ok
const Component = {
view({ data }) {
return data.items.length
? o('ul', data.items.map(item => o('li', `${item.name}`)))
: o('div', o('p', 'Loading...'))
}
}

const Component = {
view({ data }) {
return o('div',
data.items.length
? o('ul', data.items.map(item => o('li', `${item.name}`)))
: o('div', o('p', 'Loading...'))
)
}
}

const Component = {
view({ data }) {
if (!data.items.length) {
return o('div', 'Loading')
}

return o('div', 'p', 'Items loaded...')
}
}
```
### Dangling TextNodes
One is built around diffing HTML elements and not text nodes. This means that you shouldn't have "dangling" text nodes.
A dangling text node is a text node with HTML element siblings. See below for examples.
It *is* possible, but since One doesn't care about text nodes, they will often be removed from the DOM during rendering.
```js
// ok
o('div',
o('h1', 'This is a heading'),
o('p', 'This is a paragraph'),
)

// not ok
o('div',
o('h1', 'This is a heading'),
'This is a "dangling" text node',
)
```
8 changes: 0 additions & 8 deletions example/.prettierrc

This file was deleted.

55 changes: 39 additions & 16 deletions example/app.js
Original file line number Diff line number Diff line change
@@ -1,18 +1,41 @@
import {createRouter} from '../dist/else'
import {Home, About, Layout, Form, Post} from './pages'
import { o, mount } from '../dist/one'
import { getItems } from './services/get-items'

createRouter(
[
{path: '/', component: Home},
{path: '/about-us', component: About},
{path: '/about-us/:id', component: About},
{path: '/form', component: Form},
{path: '/post/:id', component: Post},
{path: '/some/:param/:id', component: About},
],
{
fallback: '/',
layout: Layout,
root: document.querySelector('#app'),
const Component = {
data () {
return {
items: []
}
},
async onmount ({ data }) {
data.items = await getItems()
},
view ({ data }) {
return o('div', [
o('h1', 'Items'),
o(List, { items: data.items })
])
}
)
}

const List = {
view ({ props }) {
return o('div', [
o('ul',
props.items.length
? props.items.map(item => o('li', `${item.name}`))
: o('li', 'Loading')
)
])
}
}

const View = {
view () {
return o('div', [
o(Component)
])
}
}

mount(View, document.body)
23 changes: 0 additions & 23 deletions example/components/List.js

This file was deleted.

39 changes: 0 additions & 39 deletions example/components/ListInput.js

This file was deleted.

40 changes: 0 additions & 40 deletions example/components/ListItem.js

This file was deleted.

4 changes: 0 additions & 4 deletions example/components/index.js

This file was deleted.

Loading

0 comments on commit 21f91f5

Please sign in to comment.