Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/sister-software/my-app

Fast and simple web apps without build tools. (Work in progress)
https://github.com/sister-software/my-app

custom-elements unframework web-components

Last synced: 10 days ago
JSON representation

Fast and simple web apps without build tools. (Work in progress)

Awesome Lists containing this project

README

        

# ``

_Progressive Web Components_

**Unreleased work in progress**

No Babel. No Webpack. Progressive Web Components let you build full web apps native custom HTML elements.

```css
:host {
--primary-color-base: #ff0000;
}
```

```html








${this.humanizedTime()}


import moment from './node_modules/moment/moment.js'

this.humanizedTime = () => {
return moment.fromNow(this.observedAttributes.date)
}

this.addEventListener('afterInsert', () => {
this.interval = setInterval(() => {
this.requestTemplateUpdate()
}, 1000 * 60)
})

this.addEventListener('beforeRemove', () => {
clearInterval(this.interval)
})


import WebComponent from 'node_modules/@progressive-web-components/web-component.js'
import moment from './node_modules/moment/moment.js'

class HumanTime extends WebComponent {
static tagName = 'human-time'

static observedAttributes = {
date: {
type: Date,
required: true
}
}

onafterinsert() {
this.interval = setInterval(() => {
this.requestTemplateUpdate()
}, 1000 * 60)
}

onbeforeremove() {
clearInterval(this.interval)
}

humanizedTime() {
return moment.fromNow(this.observedAttributes.date)
}

template(html) {
return html`
<span title="${this.observedAttributes.date}">${this.humanizedTime()}</span>
`
}
}


// ...Then natively import them — without a build step.
import MyApp from '/vendor/my-app.js'

// Create native custom elements.
MyApp.createElement('todo-list-page', {
// Element scoped styles.
styles(css) {
css`
:host {
border: 1px dashed black;
}
.todos {
border: 1px solid black;
}
`
},

methods: {
markTodoComplete(event) {
const { todoId } = event.target.dataset

this.parentApp.sharable.markTodoComplete(todoId)
}
},

render(html) {
const { todos } = this.parentApp.sharable

return html`
<div>
<h1>Todo List</h1>

<ul class="todos">
${
todos.entries.map(
todo => html`
<li onClick=${this.markTodoComplete} data-todo-id=${todo.id}>${todo.title}</li>
`
)
}
</ul>
</div>
`
}
})

const myApp = new MyApp({
// Share global data with child nodes.
sharable: {
todos: {
entries: [{ id: 'abc123', title: 'Try MyApp', complete: true }],
markTodoComplete(todoId) {
const todo = this.todos.find(todo => todo.id === todoId)
todo.complete = true
}
}
},
routes: {
// Map routes to custom elements.
'/': TodoListPage,
login: LoginPage
}
})

document.body.appendChild(myApp)

```

## Theming (WIP)

```html




/* Global theme variables. */
:root {
--font-size: 16px;
--color: #111;
}

/* Element overrides */
material-button::part(text) {
font-style: italic;
}

Click me!

```