diff options
| author | s-ol <s-ol@users.noreply.github.com> | 2018-11-14 08:29:40 +0000 |
|---|---|---|
| committer | s-ol <s-ol@users.noreply.github.com> | 2018-11-14 08:29:40 +0000 |
| commit | f30666c74f29af8bd714f451e045187e34d7929f (patch) | |
| tree | 17c365312c89ff138d04f6d98eb43400bbaa4823 /root/meta/mmm.component | |
| parent | fix bug compiling overlapping Lua/Moon facets (diff) | |
| download | mmm-f30666c74f29af8bd714f451e045187e34d7929f.tar.gz mmm-f30666c74f29af8bd714f451e045187e34d7929f.zip | |
update mmm.component docs
Diffstat (limited to 'root/meta/mmm.component')
8 files changed, 218 insertions, 180 deletions
diff --git a/root/meta/mmm.component/$order b/root/meta/mmm.component/$order new file mode 100644 index 0000000..b670206 --- /dev/null +++ b/root/meta/mmm.component/$order @@ -0,0 +1,4 @@ +simple_counter +text_input +dropdown_menu +todoMVC diff --git a/root/meta/mmm.component/dropdown_menu/text$lua -> mmm$component.lua b/root/meta/mmm.component/dropdown_menu/text$lua -> mmm$component.lua new file mode 100644 index 0000000..12c1b53 --- /dev/null +++ b/root/meta/mmm.component/dropdown_menu/text$lua -> mmm$component.lua @@ -0,0 +1,17 @@ +local comp = require 'mmm.component' +local e = comp.elements + +local color = comp.ReactiveVar 'red' + +return e.div { + e.div { 'test', style = color:map(function (bg) + return { padding = '1em', background = bg } + end) }, + e.select { + onchange = function (_, e) color:set(e.target.value) end, + + e.option 'red', + e.option 'green', + e.option 'blue', + }, +} diff --git a/root/meta/mmm.component/dropdown_menu/text$moonscript -> mmm$component.moon b/root/meta/mmm.component/dropdown_menu/text$moonscript -> mmm$component.moon new file mode 100644 index 0000000..a4f1e04 --- /dev/null +++ b/root/meta/mmm.component/dropdown_menu/text$moonscript -> mmm$component.moon @@ -0,0 +1,17 @@ +import ReactiveVar, text, elements from require 'mmm.component' +import div, select, option from elements + +color = ReactiveVar 'white' + +div { + div 'test', style: color\map (background) -> + { padding: '1em', :background } + + select { + onchange: (e) => color\set e.target.value + + option 'white' + option 'red' + option 'green' + } +} diff --git a/root/meta/mmm.component/simple_counter/text$lua -> mmm$component.lua b/root/meta/mmm.component/simple_counter/text$lua -> mmm$component.lua new file mode 100644 index 0000000..6912f02 --- /dev/null +++ b/root/meta/mmm.component/simple_counter/text$lua -> mmm$component.lua @@ -0,0 +1,18 @@ +local comp = require 'mmm.component' +local div, button = comp.elements.div, comp.elements.button + +local count = comp.ReactiveVar(0) + +return div { + button { + '-', + onclick = function () count:set(count:get() - 1) end + }, + " count is: ", + count:map(comp.text), + " ", + button { + '+', + onclick = function () count:set(count:get() + 1) end + }, +} diff --git a/root/meta/mmm.component/simple_counter/text$moonscript -> mmm$component.moon b/root/meta/mmm.component/simple_counter/text$moonscript -> mmm$component.moon new file mode 100644 index 0000000..0c40f7a --- /dev/null +++ b/root/meta/mmm.component/simple_counter/text$moonscript -> mmm$component.moon @@ -0,0 +1,12 @@ +import ReactiveVar, text, elements from require 'mmm.component' +import div, button from elements + +count = ReactiveVar 0 + +div { + button '-', onclick: () -> count\transform (c) -> c - 1 + " count is: " + count\map text + " " + button '+', onclick: () -> count\transform (c) -> c + 1 +} diff --git a/root/meta/mmm.component/text$moonscript -> fn -> mmm$dom.moon b/root/meta/mmm.component/text$moonscript -> fn -> mmm$dom.moon index 6840e42..ca9a13f 100644 --- a/root/meta/mmm.component/text$moonscript -> fn -> mmm$dom.moon +++ b/root/meta/mmm.component/text$moonscript -> fn -> mmm$dom.moon @@ -1,4 +1,4 @@ -import article, section, h1, h2, h3, p, a, div, ul, li, pre, code from require 'mmm.dom' +import article, section, h1, h2, h3, p, a, b, div, ul, li, pre, code from require 'mmm.dom' import tohtml from require 'mmm.component' import lua, moonscript from (require 'mmm.highlighting').languages @@ -10,80 +10,103 @@ source = do return the_code unless demo - example = assert load lua_src - div the_code, div (tohtml example!), class: 'example' + if demo == true + example = assert load lua_src + demo = tohtml example! -=> article { - h1 mmmcomp! - p mmmcomp!, " is a small and DOM-centric framework for reactive web interfaces." + div the_code, div demo, class: 'example' - p do - fengari = a "fengari.io", href: '//fengari.io' +raw_find = (fileder, key_pat) -> + for key, val in pairs fileder.facets + return val if key\tostring!\match key_pat - "Built for reactive UI, ", mmmcomp!, " is meant to run on the client using ", fengari, ". - However, like ", (code 'mmm.dom'), ", the API is supported both on the client as well as - on the server (were most reactive features have been omitted) so that static pre-rendered - content can still be generated from the same code that powers the reactive interface." +=> + example = (name) -> + for child in *@children + if name == child\gett 'name: alpha' + moon_src = child\get 'text/moonscript.*' + lua_src = child\get 'text/lua.*' + dom = child\gett 'mmm/dom' - h2 "Examples" - p "Feel free to read the documentation below, or take a look at the following examples using the ", - (code 'mmmfs'), " inspect mode:" + return source moon_src, lua_src, dom - ul for child in *@children - li a (child\gett 'name: alpha'), { - href: child.path, - onclick: (e) => - e\preventDefault! - BROWSER\navigate child.path - } + article { + h1 mmmcomp! + p mmmcomp!, " is a small and DOM-centric framework for reactive web interfaces." - h2 "Guide" - p "Begin by requiring ", mmmcomp!, ". The module returns a table containing the following:" + p do + fengari = a "fengari.io", href: '//fengari.io' - ul { - li (code 'ReactiveVar'), ": class/constructor for reactive state variables.", - li (code 'ReactiveElement'), ": class/constructor for reactive DOM elements. Rarely used directly." - li (code 'elements'), ": 'magic table' containing constructors for ReactiveElements by tag name." - li (code 'tohtml'), ": helper to convert from ReactiveElements to mmm/dom (DOM nodes / HTML strings)" - li (code 'text'), ": helper to convert Lua strings to DOM Text Nodes." - li (code 'get_or_create'), ": helper for rehydratable views." - } + "Built for reactive UI, ", mmmcomp!, " is meant to run on the client using ", fengari, ". + However, like ", (code 'mmm.dom'), ", the API is supported both on the client as well as + on the server (were most reactive features have been omitted) so that static pre-rendered + content can still be generated from the same code that powers the reactive interface." + + h2 "Examples" + p "Feel free to read the documentation below, or take a look at the following examples using the ", + (code 'mmmfs'), " inspect mode:" - section do - rvar = -> code 'ReactiveVar' + ul for child in *@children + li a (child\gett 'name: alpha'), { + href: child.path, + onclick: (e) => + e\preventDefault! + BROWSER\navigate child.path + } + + p do + repo = a 'here', href: '//github.com/s-ol/mmm' - { - id: 'ReactiveVar' + "You will also find that most interactive UI on this page, including the navigation and browsing system, + have been built using ", mmmcomp!, " as well. The source code is available ", repo, "." - h3 "Reactive Variables" - p mmmcomp!, " is centered around the concept of Reactive Variables (", rvar!, "s). - A ", rvar!, " is a container for a piece of application state that other pieces of code can - subscribe to. These attached callbacks are invoked whenever the value changes." + h2 "Guide" + p "Begin by requiring ", mmmcomp!, ". The module returns a table containing the following:" - p "You can instantiate a ", rvar!, " via the constructor at any time. The constructor takes - the initial variable as an argument, but if you omit it ", (code 'nil'), " will work fine as well. - After instantiation, ", (code ':get()'), " and ", (code ':set(val)'), " will give access to the value:" + ul { + li (code 'ReactiveVar'), ": class/constructor for reactive state variables.", + li (code 'ReactiveElement'), ": class/constructor for reactive DOM elements. Rarely used directly." + li (code 'elements'), ": 'magic table' containing constructors for ReactiveElements by tag name." + li (code 'tohtml'), ": helper to convert from ReactiveElements to mmm/dom (DOM nodes / HTML strings)" + li (code 'text'), ": helper to convert Lua strings to DOM Text Nodes." + li (code 'get_or_create'), ": helper for rehydratable views." + } - source [[ + section do + rvar = -> code 'ReactiveVar' + + { + id: 'ReactiveVar' + + h3 "Reactive Variables" + p mmmcomp!, " is centered around the concept of Reactive Variables (", rvar!, "s). + A ", rvar!, " is a container for a piece of application state that other pieces of code can + subscribe to. These attached callbacks are invoked whenever the value changes." + + p "You can instantiate a ", rvar!, " via the constructor at any time. The constructor takes + the initial variable as an argument, but if you omit it ", (code 'nil'), " will work fine as well. + After instantiation, ", (code ':get()'), " and ", (code ':set(val)'), " will give access to the value:" + + source [[ import ReactiveVar from require 'mmm.component' test = ReactiveVar 3 print test\get! -- prints '3' test\set 4 print test\get! -- prints '4' - ]], [[ + ]], [[ local ReactiveVar = require 'mmm.component'.ReactiveVar local test = ReactiveVar(3) print(test:get()) -- prints '3' test:set(4) print(test:get()) -- prints '4' - ]], false + ]], false - p "The value can also be changed using ", (code ':transform(fn)'), ", which is simply a shorthand for ", - (code 'var:set(fn(var:get()))'), ":" + p "The value can also be changed using ", (code ':transform(fn)'), ", which is simply a shorthand for ", + (code 'var:set(fn(var:get()))'), ":" - source [[ + source [[ import ReactiveVar from require 'mmm.component' add_one = (n) -> n + 1 @@ -94,7 +117,7 @@ print test\get! -- prints '2' count\transform add_one print test\get! -- prints '3' - ]], [[ + ]], [[ local ReactiveVar = require 'mmm.component'.ReactiveVar local function add_one(x) return x + 1 end @@ -105,13 +128,13 @@ print(test:get()) -- prints '2' count:transform(add_one) print(test:get()) -- prints '3' - ]], false + ]], false - p "Now, so far we haven't really seen anything useful - this is all just behaving like a normal variable. - The ", (code ':subscribe(callback)'), " method is what makes ", rvar!, "s interesting: Whenever the value - changes, the ", rvar!, " calls each of the registered handlers, passing the new as well as the previous value:" + p "Now, so far we haven't really seen anything useful - this is all just behaving like a normal variable. + The ", (code ':subscribe(callback)'), " method is what makes ", rvar!, "s interesting: Whenever the value + changes, the ", rvar!, " calls each of the registered handlers, passing the new as well as the previous value:" - source [[ + source [[ import ReactiveVar from require 'mmm.component' add_one = (n) -> n + 1 @@ -122,7 +145,7 @@ count\subscribe (new, old) -> count\transform add_one -- changing from 1 to 2 count\set "a string" -- changing from 2 to a string - ]], [[ + ]], [[ local ReactiveVar = require 'mmm.component'.ReactiveVar local function add_one(x) return x + 1 end @@ -133,17 +156,17 @@ end) count:transform(add_one) -- changing from 1 to 2 count:set("a string") -- changing from 2 to a string - ]], false + ]], false - p "This allows other code (such as ", (code 'ReactiveElement'), "s) to react to value changes and update - themselves, as we will see in a minute. Often you will want to derive state from other state. To make this - easy while keeping everything reactive, ", mmmcomp!, " includes the ", (code ':map(fn)'), " method." + p "This allows other code (such as ", (code 'ReactiveElement'), "s) to react to value changes and update + themselves, as we will see in a minute. Often you will want to derive state from other state. To make this + easy while keeping everything reactive, ", mmmcomp!, " includes the ", (code ':map(fn)'), " method." - p (code ':map(fn)'), " applies the function ", (code 'fn'), " to the current value, just as ", - (code ':transform(fn)'), " would, but it doesn't update the value itself - it rather returns a new ", rvar!, - " instance that is already set up to update whenever the original one changes." + p (code ':map(fn)'), " applies the function ", (code 'fn'), " to the current value, just as ", + (code ':transform(fn)'), " would, but it doesn't update the value itself - it rather returns a new ", rvar!, + " instance that is already set up to update whenever the original one changes." - source [[ + source [[ import ReactiveVar from require 'mmm.component' fruit = ReactiveVar "apple" @@ -154,7 +177,7 @@ print loud_fruit\get! -- prints 'APPLE' fruit\set "orange" print loud_fruit\get! -- prints 'ORANGE' - ]], [[ + ]], [[ local ReactiveVar = require 'mmm.component'.ReactiveVar local fruit = ReactiveVar("apple") @@ -165,120 +188,37 @@ print(loud_fruit:get()) -- prints 'APPLE' fruit:set("orange") print(loud_fruit:get()) -- prints 'ORANGE' - ]], false - } + ]], false + } - section do - relem = -> code 'ReactiveElement' - rvar = -> code 'ReactiveVar' - - { - id: 'ReactiveElement' - - h3 relem!, "s" - p relem!, " is a wrapper around DOM elements that allows you to use ", rvar!, "s to specify attributes and - children of the element. Internally it ", (code ':subscribe()'), "s to each of the ", rvar!, "s so that it can - update whenever any of the values change." - - p relem!, "s can be instantiated using the ", relem!, " constructor, but usually you will want to use the - shorthand functions that you can pull out of the ", (code 'elements'), " 'magic table', as they will make your - code much more legible. This table provides functions for creating any HTML element based on it's name. - The elements you use are automatically cached so you can either pull out only the ones you want to use into - your local namespace or use the table itself." - - p "Each of these node creation functions accept any number of nodes or strings as arguments and will attach these - as their children:" - - source [[ -import elements from require 'mmm.component' -import h1, code from elements - -h1 "Hello from ", code 'mmm.component' - --- or if you want to keep your namespace clean: -e = elements -e.h1 "Hello from ", e.code 'mmm.component' - ]], [[ -local elements = require'mmm.component'.elements -local h1, code = elements.h1, elements.code - -h1("Hello from ", code 'mmm.component') - --- or if you want to keep your namespace clean: -local e = elements -return e.h1("Hello from ", e.code 'mmm.component') - ]] - - source [[ -import text, elements from require 'mmm.component' -import div, button from elements - -count = ReactiveVar 0 - -div { - button '-', onclick: () -> count\transform (c) -> c - 1 - " count is: " - count\map (num) -> text num - " " - button '+', onclick: () -> count\transform (c) -> c + 1 -} - ]], [[ -local comp = require 'mmm.component' -local div, button = comp.elements.div, comp.elements.button - -local count = comp.ReactiveVar(0) - -return div { - button { - '-', - onclick = function () count:set(count:get() - 1) end - }, - " count is: ", - count:map(function (num) return comp.text(num) end), - " ", - button { - '+', - onclick = function () count:set(count:get() + 1) end - }, -} - ]] - - source [[ -import text, elements from require 'mmm.component' -import select, option from elements - -color = ReactiveVar 'white' - -div { - div 'test', style: color\map (background) -> - { padding: '1em', :background } - - select { - onchange: (e) => color\set e.target.value - - option 'white' - option 'red' - option 'green' - } -} - ]], [[ -local comp = require 'mmm.component' -local e = comp.elements - -local color = comp.ReactiveVar 'red' - -return e.div { - e.div { 'test', style = color:map(function (bg) - return { padding = '1em', background = bg } - end) }, - e.select { - onchange = function (_, e) color:set(e.target.value) end, - - e.option 'red', - e.option 'green', - e.option 'blue', - }, -} - ]] + section do + relem = -> code 'ReactiveElement' + rvar = -> code 'ReactiveVar' + + { + id: 'ReactiveElement' + + h3 relem!, "s" + p relem!, " is a wrapper around DOM elements that allows you to use ", rvar!, "s to specify attributes and + children of the element. Internally it ", (code ':subscribe()'), "s to each of the ", rvar!, "s so that it can + update whenever any of the values change." + + p relem!, "s can be instantiated using the ", relem!, " constructor, but usually you will want to use the + shorthand functions that you can pull out of the ", (code 'elements'), " 'magic table', as they will make your + code much more legible. This table provides functions for creating any HTML element based on it's name. + The elements you use are automatically cached so you can either pull out only the ones you want to use into + your local namespace or use the table itself." + + p "Each of the node creation functions behave just like the counterparts in ", (code 'mmm.dom'), ", except for + the fact that each child or attribute value can also be provided as a ", rvar!, " instance and will be + unwrapped and tracked automatically:" + + example 'text_input' + + p "Note that when you want to pass non-elements (e.g. strings or numbers) to an element as children, they will + automatically be escaped using ", (code 'text'), ", but this ", (b "breaks reactivity"), ", so you should ", + (code ':map(text)'), " these values before passing them to an element, like this:" + + example 'simple_counter' } -} + } diff --git a/root/meta/mmm.component/text_input/text$lua -> mmm$component.lua b/root/meta/mmm.component/text_input/text$lua -> mmm$component.lua new file mode 100644 index 0000000..9039e24 --- /dev/null +++ b/root/meta/mmm.component/text_input/text$lua -> mmm$component.lua @@ -0,0 +1,18 @@ +local comp = require 'mmm.component' +local div, input, br = comp.elements.div, comp.elements.input, comp.elements.br + +local text = comp.ReactiveVar "your text here" + +return div{ + input{ + value = text:get(), + oninput = function (_, e) + text:set(e.target.value) + end, + }, + br(), + input{ + disabled = true, + value = text, + }, +} diff --git a/root/meta/mmm.component/text_input/text$moonscript -> mmm$component.moon b/root/meta/mmm.component/text_input/text$moonscript -> mmm$component.moon new file mode 100644 index 0000000..7678b1b --- /dev/null +++ b/root/meta/mmm.component/text_input/text$moonscript -> mmm$component.moon @@ -0,0 +1,12 @@ +import ReactiveVar, elements from require 'mmm.component' +import div, input, br from elements + +text = ReactiveVar "your text here" + +handler = (e) => text\set e.target.value + +div { + input value: text\get!, oninput: hander + br! + input disabled: true, value: text +} |
