Skip to content

Commit

Permalink
Merge pull request #4 from ChristoPy/develop
Browse files Browse the repository at this point in the history
Version v0.0.2
  • Loading branch information
ChristoPy authored Oct 20, 2021
2 parents ed786f1 + a83e5ea commit ce94a47
Show file tree
Hide file tree
Showing 7 changed files with 79 additions and 69 deletions.
37 changes: 19 additions & 18 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# Kuva
Aims to be a lighweight and straightforward reactive front-end library.
Aims to be a lightweight and straightforward reactive front-end library.
Always basic and easy to read.

# Installation
Expand All @@ -14,36 +14,37 @@ import Kuva from 'kuva';

const app = Kuva({
name: 'John',
lastName: 'Snow',
fullName () {
return `${this.name} ${this.lastName}`
},
canShowFullName: false
canShowLastName: false
})

setTimeout(() => app.canShowFullName = true)

```
Your HTML
```html
<p k-text="name"></p>
<p k-text="lastName"></p>
<p k-if="canShowFullName" k-text="fullName"></p>
<label for="name-input">What is your name?</label>
<input k-bind="name" name="name-input"/>

<div>your name is:
<b k-text="name"></b>
</div>

<p k-if="canShowLastName">This node doesn't exists</p>
<p k-hide="canShowLastName">This node is hidden</p>
```

# Directives
Every Kuva directive, starts with a k- prefix.
The available ones are:

* k-text:
Shows the text of the received reference.
* k-if:
Shows the element if the received value is reference.
* k-model:
* **k-text**:
Shows the value of the received reference in the element's text.
* **k-if**:
Removes the element if received reference is falsy. Add if truthy.
* **k-hide**:
Hides the element if received reference is falsy. Shows if truthy.
* **k-bind**:
Adds two way data binding to an input with the received reference.

# Docs
Soon

# Version
0.0.1, not stable nor production ready, use with caution
0.0.2, not stable nor production ready, use with caution
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "kuva",
"version": "0.0.1",
"description": "Lighweight and straightforward reactive front-end library.",
"version": "0.0.2",
"description": "Lightweight and straightforward reactive front-end library.",
"main": "dist/index.js",
"files": ["dist/*"],
"scripts": {
Expand Down
46 changes: 32 additions & 14 deletions src/directives.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,4 @@
const valueToText = (data, value) => {
if (typeof value === "function") return value.call(data)
if (typeof value === "object") return JSON.stringify(value)
return value
}
import { valueToText, get } from './shared.js'

let directives = [
{
Expand Down Expand Up @@ -39,19 +35,37 @@ let directives = [
innerHandler()
return innerHandler
}
}
},
{
name: "bind",
elements: [],
handler: (element, data, value) => {
const modelName = element.getAttribute("k-bind")
element.oninput = () => {
data[modelName] = element.value
}

const innerHandler = () => element.value = data[value]

innerHandler()
return innerHandler
}
},
]

const getAll = (name) => document.querySelectorAll(`[k-${name}]`)
export default (model) => {
const handlersPerPath = {}
const executeDirectiveHandler = (name, element, handler) => {
const propertyPath = element.getAttribute(`k-${name}`)
if (!handlersPerPath[propertyPath]) handlersPerPath[propertyPath] = []

export const attachDirectives = (model) => {
const innerDirectivesHandler = []
const executeDirectiveHandler = (name, element, handler) => innerDirectivesHandler.push(
handler(element, model, element.getAttribute(`k-${name}`))
)
handlersPerPath[propertyPath].push(
handler(element, model, propertyPath)
)
}

directives = directives.map(({ name, handler, elements }) => {
elements = getAll(name)
elements = get(`[k-${name}]`)
elements.forEach((element) => executeDirectiveHandler(name, element, handler))

return {
Expand All @@ -61,5 +75,9 @@ export const attachDirectives = (model) => {
}
})

return () => innerDirectivesHandler.forEach(innerDirective => innerDirective())
return (_, path) => {
const handlers = handlersPerPath[path]
if (!handlers) return
handlers.forEach(innerDirective => innerDirective())
}
}
7 changes: 7 additions & 0 deletions src/dom.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import directives from './directives.js'

export default (model) => {
let runInnerDirective = directives(model)

return (model, path) => runInnerDirective(model, path)
}
9 changes: 4 additions & 5 deletions src/index.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
import model from "./model.js"
import { attachDirectives } from "./directives.js"
import dom from "./dom.js"

export default (data) => {
let runInnerDirective = null
let updateDOM = null

const app = model(data, () => runInnerDirective())

runInnerDirective = attachDirectives(app)
const app = model(data, (path) => updateDOM(app, path))
updateDOM = dom(app)

return app
}
38 changes: 8 additions & 30 deletions src/model.js
Original file line number Diff line number Diff line change
@@ -1,30 +1,8 @@
const getAll = (name) =>
document.querySelectorAll(name ? `[k-model="${name}"]` : "[k-model]")

const updateModel = (value, name) =>
getAll(name).forEach(
(element) =>
(element.value =
typeof value !== "string" ? JSON.stringify(value) : value)
)

const setupModels = (model) => {
getAll().forEach((element) => {
const modelName = element.getAttribute("k-model")
updateModel(model[modelName] || "", modelName)
element.oninput = () => (model[modelName] = element.value)
})
return model
}

export default (data, callback) => setupModels(
new Proxy(data, {
get: (target, path) => target[path],
set: (target, path, value) => {
data[path] = value
updateModel(data[path], path)
callback(data)
return true
}
})
)
export default (data, callback) => new Proxy(data, {
get: (target, path) => target[path],
set: (_, path, value) => {
data[path] = value
callback(path)
return true
}
})
7 changes: 7 additions & 0 deletions src/shared.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
export const valueToText = (data, value) => {
if (typeof value === "function") return value.call(data)
if (typeof value === "object") return JSON.stringify(value)
return value
}

export const get = (selector) => [...document.querySelectorAll(selector)]

0 comments on commit ce94a47

Please sign in to comment.