Skip to content
This repository was archived by the owner on Feb 7, 2022. It is now read-only.
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 2 additions & 5 deletions .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ module.exports = {
browser: true,
es6: true
},
extends: 'eslint:recommended',
globals: {
Atomics: 'readonly',
SharedArrayBuffer: 'readonly'
Expand All @@ -14,11 +13,9 @@ module.exports = {
sourceType: 'module'
},
rules: {
indent: ['error', 2],
'linebreak-style': ['error', 'unix'],
quotes: ['error', 'single'],
semi: ['error', 'never'],
'comma-dangle': ['error', 'never'],
'arrow-parens': ['error', 'as-needed']
quotes: ['error', 'single'],
indent: ['error', 2]
}
}
6 changes: 6 additions & 0 deletions .prettierrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"trailingComma": "none",
"tabWidth": 2,
"semi": false,
"singleQuote": true
}
145 changes: 82 additions & 63 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,19 +10,21 @@ Goals:
- Event system over state machine

## Install

```bash
npm i -S @wallerbuilt/mantle
```

```javascript
import { DOM, mount, dispatch } from '@wallerbuilt/mantle'
import { DOM, mount, dispatch } from "@wallerbuilt/mantle";
```

## Examples

Demo card game
- repo: https://github.com/wallerbuilt/mantle-card-game
- preview: https://mantle-card-game.netlify.app/

- repo: https://github.com/wallerbuilt/mantle-card-game
- preview: https://mantle-card-game.netlify.app/

## Documentation

Expand All @@ -35,144 +37,160 @@ Mantle comes with three main concepts:
- Provides html elements as functions with additional features, ie: `div(), a()`
- Each element has two chained functions `on` and `when`
- `on` handles native events on the element itself
- returns the event callback
- can target the main element with `on` attached using `this` , ie:

```jsx
a({ href: "/" }, "I am a link")
.on({
click(e) {
e.preventDefault()
this.style.color = "tomato" // this refers to the actual anchor element
}
})
```
- returns the event callback
- can target the main element with `on` attached using `this` , ie:

```jsx
a({ href: "/" }, "I am a link").on({
click(e) {
e.preventDefault();
this.style.color = "tomato"; // this refers to the actual anchor element
},
});
```

- `when` encompasses global event listening functions that are triggered using `dispatch`
- returns `self` and the optional `payload` (`self` referring to the main element `when` is attached to)

```jsx
/**
* if payload is a person object { name: "Dave" } passed in the dispatch payload
*/
when({
"person:added": (self, payload) => self.appendChild(li({}, payload.name))
})
```
- returns `self` and the optional `payload` (`self` referring to the main element `when` is attached to)

```jsx
/**
* if payload is a person object { name: "Dave" } passed in the dispatch payload
*/
when({
"person:added": (self, payload) => self.appendChild(li({}, payload.name)),
});
```

### Dispatch

- `dispatch` takes two arguments
- First argument is the event key. This is best used in a format of prefixing the subject and then the action, ie:

```jsx
dispatch("person:added") // without payload as second argument
```
- First argument is the event key. This is best used in a format of prefixing the subject and then the action, ie:

```jsx
dispatch("person:added"); // without payload as second argument
```

- Second argument is the payload for the event for global event listeners (`when`) to receive, ie:
- Second argument is the payload for the event for global event listeners (`when`) to receive, ie:

```jsx
dispatch("person:added", { name: "Dave", age: 50, city: "Chicago" })
```jsx
dispatch("person:added", { name: "Dave", age: 50, city: "Chicago" });

// an example of an element receiving person:added
const { ul, li } = DOM;
// an example of an element receiving person:added
const { ul, li } = DOM;

const listItem = person => li({}, person.name)
const listItem = (person) => li({}, person.name);

const PeopleList = ul({}, "")
.when({
"person:added": (self, person) => self.appendChild(listItem(person))
})
```
const PeopleList = ul({}, "").when({
"person:added": (self, person) => self.appendChild(listItem(person)),
});
```

### Mount

- Is the main function that attaches the app element or the outermost element (container) containing all elements used in the app
- `mount` takes two arguments
- existing dom element to attach to in your html, ie: `document.getElementById("app")`
- your app element created

```jsx
// ...imports
- existing dom element to attach to in your html, ie: `document.getElementById("app")`
- your app element created

const { div, p } = DOM
```jsx
// ...imports

const Intro = p({},
"lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum"
)
const { div, p } = DOM;

const App = children => div({ className: "my-app" }, children)
const Intro = p(
{},
"lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum"
);

// Apply App to existing element in the DOM on load with it's children
mount(document.getElementById("app"), App([Intro]))
```
const App = (children) => div({ className: "my-app" }, children);

// Apply App to existing element in the DOM on load with it's children
mount(document.getElementById("app"), App([Intro]));
```

### Helper methods for easier DOM manipulation

- **append** -> append child element to target element

```javascript
append(li({}, 'List Item'))(el)
append(li({}, "List Item"))(el);
```

- **clear** -> clear all child elements on target element

```javascript
clear(el)
clear(el);
```

- **compose** -> curried composition to use with most helper functions

```javascript
// get text of first span element in el
compose(getText, qs('span'))(el)
compose(getText, qs("span"))(el);
```

- **getProp** -> get attribute property from target element

```javascript
getProp('data-title')(el)
getProp("data-title")(el);
```

- **setProp** -> set attribute property on target element

```javascript
setProp('disabled', true)(el)
setProp("disabled", true)(el);
```

- **remove** -> remove child element from target element

```javascript
remove(child)(el)
remove(child)(el);
```

- **setStyle** -> Set an elements style properties

```javascript
setStyle([
['background', 'orange'],
['fontSize', '18px']
])(el)
["background", "orange"],
["fontSize", "18px"],
])(el);
```

- **getText** -> get `textContent` or `innerText` of element

```javascript
getText(el)
getText(el);
```

- **setText** -> set `textContent` or `innerText` of element

```javascript
setText('hello text')(el)
setText("hello text")(el);
```

- **qs** -> query selector from target element

```javascript
qs('span')(el)
qs("span")(el);
```

- **qsAll** -> query all selectors from target element
```javascript
qsAll('li')(ul)
qsAll("li")(ul);
```

## Development Setup

- `nvm install && nvm use`
- `npm i`
- `npm start`

### e2e tests for examples

- `npm run cypress` (will start cypress)

### Unit tests
Expand All @@ -186,4 +204,5 @@ To run tests once:
`npm run test`

### Build

- `npm run build`
Loading