Skip to content

Commit

Permalink
move things around and finish README/examples
Browse files Browse the repository at this point in the history
  • Loading branch information
fennifith committed Sep 5, 2019
1 parent ab6a087 commit 4dd0f1e
Show file tree
Hide file tree
Showing 8 changed files with 97 additions and 9 deletions.
49 changes: 46 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,12 @@ container(

## Installation

**Note:** although this library can and does use it, it _does not_ depend on jQuery. It will behave the same regardless of whether it is passed an unwrapped HTMLElement or a jQuery class. This is because of _perplexed kittens_ and [_fairy dust_](./src/util/dom-wrapper.js).

#### Script Tag

```html
<script type="text/javascript" src="https://unpkg.com/declarativ@0.0.3/dist/declarativ.js"></script>
<script type="text/javascript" src="https://unpkg.com/declarativ@0.0.4/dist/declarativ.js"></script>
```

(the module will be included in the global scope as the `declarativ` variable)
Expand Down Expand Up @@ -98,8 +100,49 @@ el.div(
)
```

Okay, a lot is happening here. I'll slow down and explain. The `bind` function allows you to specify a set of data to be passed to other parts of a component - and extends upon the types of nodes that can be placed inside it. Because the paragraph elements inside the div are not bound to any data, they inherit the Promise that is bound to their parent. The nodes inside of the paragraph elements are then specified as a function of the resolved data, returning the text to render.
Okay, a lot is happening here. I'll slow down and explain.

The `bind` function allows you to specify a set of data to be passed to other parts of a component - and extends upon the types of nodes that can be placed inside it. Because the paragraph elements inside the div are not bound to any data, they inherit the Promise that is bound to their parent. The nodes inside of the paragraph elements are then specified as a function of the resolved data, returning the text to render.

A more complex data binding situation based off the GitHub API can be found in [examples/binding.html](./examples/binding.html).

### Templates

Coming soon...
Templating functionality is crucial for projects that involve a large number of elements or repeat a common set of element structures in multiple places. There are a few different ways to create them:

#### Functions

The easiest is to just create a function that returns another component, like so:

```js
function myComponent(title, description) {
return el.div(
el.h3(title),
el.p(description)
);
}
```

Because you're just passing the arguments directly into the structure, this allows you to pass your function a string, another component, a function(data), or a Promise, and have it resolve during the render.

#### Wrapped Components

If you want to make a component that just slightly extends upon an existing instance of one, it can be wrapped in a function that will act like other components during use. This isn't useful very often, as any child components will be lost in the process, but it is useful if you just want to add a class name or attribute to a component without defining a structure.

```js
const myComponent = declarativ.wrapCompose(
el.div().className("fancypants")
);
```

#### Custom Elements

This is possibly the least useful kind of template, but I'll leave it here anyway. Most elements are specified inside `declarativ.elements`, but in the event that you want to use one that isn't, you can create an element template by calling `declarativ.compose()` with a template function.

By "template function", it must be a function that accepts a string and returns that string inside of the element's HTML tag. For example, here I implement the deprecated `<center>` tag.

```js
const myComponent = declarativ.compose((inner) => `<center>${inner}</center>`);
```

Working examples of all of these templates can be found in [examples/templates.html](./examples/templates.html).
43 changes: 43 additions & 0 deletions examples/templates.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
<!doctype html>
<html lang="en">
<head>
<title>Basic - Declarativ Examples</title>
</head>
<body>
<div id="render-target"></div>
<script type="text/javascript" src="https://unpkg.com/jquery@3.3.1/dist/jquery.min.js"></script>
<script type="text/javascript" src="../dist/declarativ.js"></script>
<script>
const { wrapCompose, compose, renderElement, elements: el } = declarativ;

function article(title, body) {
return el.article(
el.h2(title),
el.p(body)
);
}

const bigHeader = wrapCompose(el.h1().attr("style", "font-size: 3em;"));

const center = compose((inner) => `<center>${inner}</center>`);

renderElement(
$("#render-target"),
el.div(
center(
bigHeader("My Blog!"),
el.p("This is my blog, where I post my blog posts.")
),
el.hr(),
article(
"Why Cream Tea is far superior to a Tea Sandwich",
[
"The cream. I just love the cream. I can't live without it. It consumes me. ",
el.a("Look at this cream.").attr("href", "https://en.wikipedia.org/wiki/Cream_tea#/media/File:Cornish_cream_tea_2.jpg")
]
)
)
);
</script>
</body>
</html>
2 changes: 1 addition & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "declarativ",
"version": "0.0.3",
"version": "0.0.4",
"description": "This is definitely not JSX.",
"main": "dist/declarativ.js",
"scripts": {
Expand Down
4 changes: 2 additions & 2 deletions src/component.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
const { DataResolvable, PendingTasks, forEachAsync, escapeHtml } = require('./util.js');
const dom = require('./dom/dom-wrapper.js');
const { DataResolvable, PendingTasks, forEachAsync, escapeHtml } = require('./util/util.js');
const dom = require('./util/dom-wrapper.js');

function resolveNode(variable) {
if (variable instanceof Node)
Expand Down
2 changes: 1 addition & 1 deletion src/compose.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
* @module compose/index
*/

const dom = require('./dom/dom-wrapper.js');
const dom = require('./util/dom-wrapper.js');
const { Component } = require('./component.js');

/**
Expand Down
File renamed without changes.
4 changes: 3 additions & 1 deletion src/util.js → src/util/util.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,9 @@ class DataResolvable {
}

async resolve(data) {
// TODO: ideally, Promises/functions should resolve recursively (e.g. Promises that return a function), but this breaks the Component's forEach functionality
// TODO: ideally, Promises/functions should resolve recursively (e.g. Promises that return a function), but this breaks the Component's forEach functionality.
// I'm not entirely sure why this happens. Everything seems to work fine as it is, though, so I'll just leave it alone.

if (this.value instanceof Promise) {
return await this.value;
} else if (typeof this.value === 'function') {
Expand Down

0 comments on commit 4dd0f1e

Please sign in to comment.