galath 1.0.3 → 1.0.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +19 -6
- package/{packages/galath/src → src}/rendering.js +4 -5
- package/.nojekyll +0 -0
- package/AGENTS.md +0 -1
- package/TODO.md +0 -140
- package/index.html +0 -188
- package/logo.jpg +0 -0
- package/logo.svg +0 -96
- package/packages/galath/package.json +0 -28
- package/packages/galath-css/css/bootstrap-icons.min.css +0 -5
- package/packages/galath-css/css/bootstrap.min.css +0 -6
- package/packages/galath-css/css/fonts/bootstrap-icons.json +0 -2077
- package/packages/galath-css/css/fonts/bootstrap-icons.woff +0 -0
- package/packages/galath-css/css/fonts/bootstrap-icons.woff2 +0 -0
- package/packages/galath-css/js/bootstrap.bundle.min.js +0 -7
- package/packages/galath-css/package.json +0 -13
- package/playground/app.xml +0 -214
- package/playground/chapters/01-welcome.xml +0 -94
- package/playground/chapters/02-signals.xml +0 -166
- package/playground/chapters/03-instance.xml +0 -130
- package/playground/chapters/04-bindings.xml +0 -156
- package/playground/chapters/05-lists.xml +0 -138
- package/playground/chapters/06-commands.xml +0 -144
- package/playground/chapters/07-controller.xml +0 -115
- package/playground/chapters/08-events.xml +0 -126
- package/playground/chapters/09-behaviors.xml +0 -210
- package/playground/chapters/10-components.xml +0 -152
- package/playground/chapters/11-imports.xml +0 -108
- package/playground/chapters/12-expressions.xml +0 -161
- package/playground/chapters/13-paths.xml +0 -197
- package/playground/components/chapter-shell.xml +0 -29
- package/playground/components/highlighter.js +0 -111
- package/playground/components/run-snippet.js +0 -120
- package/public/basic/bootstrap-icons.min.css +0 -5
- package/public/basic/bootstrap.bundle.min.js +0 -7
- package/public/basic/bootstrap.min.css +0 -6
- package/public/basic/fonts/bootstrap-icons.json +0 -2077
- package/public/basic/fonts/bootstrap-icons.woff +0 -0
- package/public/basic/fonts/bootstrap-icons.woff2 +0 -0
- package/public/basic/theme.css +0 -209
- package/seed.html +0 -321
- /package/{packages/galath/src → src}/behavior.js +0 -0
- /package/{packages/galath/src → src}/binding.js +0 -0
- /package/{packages/galath/src → src}/boot.js +0 -0
- /package/{packages/galath/src → src}/command.js +0 -0
- /package/{packages/galath/src → src}/component.js +0 -0
- /package/{packages/galath/src → src}/controller.js +0 -0
- /package/{packages/galath/src → src}/core.js +0 -0
- /package/{packages/galath/src → src}/imports.js +0 -0
- /package/{packages/galath/src → src}/index.js +0 -0
- /package/{packages/galath/src → src}/instance-model.js +0 -0
- /package/{packages/galath/src → src}/morph.js +0 -0
- /package/{packages/galath/src → src}/signals.js +0 -0
- /package/{packages/galath/src → src}/templates.js +0 -0
- /package/{packages/galath/src → src}/xml-events.js +0 -0
|
@@ -1,144 +0,0 @@
|
|
|
1
|
-
<!--
|
|
2
|
-
chapters/06-commands.xml
|
|
3
|
-
|
|
4
|
-
XUL-style commandsets. A <command> bundles a name, an enabled
|
|
5
|
-
predicate, and a list of operations. Buttons attach to commands via
|
|
6
|
-
command="name" and pick up their enabled state automatically.
|
|
7
|
-
-->
|
|
8
|
-
<galath xmlns:bind="urn:galath:bind" xmlns:on="urn:galath:on" xmlns:use="urn:galath:use" xmlns:drag="urn:galath:drag" xmlns:drop="urn:galath:drop" xmlns:class="urn:galath:class">
|
|
9
|
-
<component name="chapter-commands" tag="x-chapter-commands">
|
|
10
|
-
<model>
|
|
11
|
-
<instance>
|
|
12
|
-
<draft text="" />
|
|
13
|
-
<items>
|
|
14
|
-
<item id="i1" text="Bread" />
|
|
15
|
-
<item id="i2" text="Apples" />
|
|
16
|
-
</items>
|
|
17
|
-
</instance>
|
|
18
|
-
|
|
19
|
-
<signal name="snippet"><![CDATA[<commandset>
|
|
20
|
-
<command name="addItem"
|
|
21
|
-
shortcut="ctrl+enter"
|
|
22
|
-
enabled="valueOf('/draft/@text').trim().length > 0">
|
|
23
|
-
<insert ref="/items">
|
|
24
|
-
<item id="{uid()}" text="{valueOf('/draft/@text')}" />
|
|
25
|
-
</insert>
|
|
26
|
-
<setvalue ref="/draft/@text" value="''" />
|
|
27
|
-
</command>
|
|
28
|
-
|
|
29
|
-
<command name="clearAll"
|
|
30
|
-
shortcut="ctrl+shift+x"
|
|
31
|
-
enabled="select('/items/item').length > 0">
|
|
32
|
-
<delete ref="/items/item" />
|
|
33
|
-
</command>
|
|
34
|
-
</commandset>
|
|
35
|
-
|
|
36
|
-
<button command="addItem">Add (Ctrl+Enter)</button>
|
|
37
|
-
<button command="clearAll">Clear all (Ctrl+Shift+X)</button>]]></signal>
|
|
38
|
-
</model>
|
|
39
|
-
|
|
40
|
-
<commandset>
|
|
41
|
-
<command name="addItem"
|
|
42
|
-
shortcut="ctrl+enter"
|
|
43
|
-
enabled="valueOf('/draft/@text').trim().length > 0">
|
|
44
|
-
<insert ref="/items">
|
|
45
|
-
<item id="{uid()}" text="{valueOf('/draft/@text')}" />
|
|
46
|
-
</insert>
|
|
47
|
-
<setvalue ref="/draft/@text" value="''" />
|
|
48
|
-
</command>
|
|
49
|
-
|
|
50
|
-
<command name="clearAll"
|
|
51
|
-
shortcut="ctrl+shift+x"
|
|
52
|
-
enabled="select('/items/item').length > 0">
|
|
53
|
-
<delete ref="/items/item" />
|
|
54
|
-
</command>
|
|
55
|
-
</commandset>
|
|
56
|
-
|
|
57
|
-
<view>
|
|
58
|
-
<div class="px-4 py-5">
|
|
59
|
-
<x-chapter-heading icon="bi-command" title="Commands"
|
|
60
|
-
subtitle="Centralize operations and let buttons inherit their enabled/disabled state." />
|
|
61
|
-
|
|
62
|
-
<div class="row g-4 mb-4">
|
|
63
|
-
<div class="col-lg-6">
|
|
64
|
-
<div class="card xes-card h-100">
|
|
65
|
-
<div class="card-body">
|
|
66
|
-
<h2 class="h5"><i class="bi bi-journal-text me-2 text-info"></i>How it works</h2>
|
|
67
|
-
<p class="text-secondary">
|
|
68
|
-
A <code><commandset></code> declares named commands. Each
|
|
69
|
-
<code><command></code> has:
|
|
70
|
-
</p>
|
|
71
|
-
<ul class="text-secondary">
|
|
72
|
-
<li><strong>name</strong> - referenced by <code>command="..."</code>.</li>
|
|
73
|
-
<li><strong>enabled</strong> (optional) - an expression. Buttons are auto-disabled when it is falsy.</li>
|
|
74
|
-
<li><strong>shortcut</strong> (optional) - a keybinding like
|
|
75
|
-
<code>ctrl+s</code> or <code>ctrl+shift+x</code>. The runtime installs a
|
|
76
|
-
global keydown listener; modifier-bearing shortcuts work even while a
|
|
77
|
-
form field has focus.</li>
|
|
78
|
-
<li>A body of operations: <code><set></code>, <code><setvalue></code>,
|
|
79
|
-
<code><insert></code>, <code><delete></code>, <code><call></code>,
|
|
80
|
-
<code><eval></code>, <code><log></code>, <code><fetch></code>.</li>
|
|
81
|
-
</ul>
|
|
82
|
-
<p class="text-secondary mb-0">
|
|
83
|
-
Why bother? Three reasons: re-use (one command, many buttons / menu items), one
|
|
84
|
-
source of enabled/disabled truth, and a clean separation between intent ("add
|
|
85
|
-
item") and visual layout.
|
|
86
|
-
</p>
|
|
87
|
-
</div>
|
|
88
|
-
</div>
|
|
89
|
-
</div>
|
|
90
|
-
<div class="col-lg-6">
|
|
91
|
-
<div class="card xes-card h-100">
|
|
92
|
-
<div class="card-header bg-transparent d-flex justify-content-between align-items-center">
|
|
93
|
-
<strong><i class="bi bi-code-slash me-2"></i>Source</strong>
|
|
94
|
-
<div class="btn-group btn-group-sm" role="group"><button class="btn btn-outline-info" on:click="window.galathRunSnippet(snippet)" title="Open this snippet in a new tab"><i class="bi bi-play-fill me-1"></i>Run</button><button class="btn btn-outline-info" use:copy="snippet" title="Copy to clipboard"><i class="bi bi-clipboard me-1"></i>Copy</button></div>
|
|
95
|
-
</div>
|
|
96
|
-
<div class="card-body p-0">
|
|
97
|
-
<pre class="xes-code rounded p-3 mb-0"><code><text value="snippet" /></code></pre>
|
|
98
|
-
</div>
|
|
99
|
-
</div>
|
|
100
|
-
</div>
|
|
101
|
-
</div>
|
|
102
|
-
|
|
103
|
-
<div class="card xes-card">
|
|
104
|
-
<div class="card-header bg-transparent">
|
|
105
|
-
<strong><i class="bi bi-play-circle me-2"></i>Live demo</strong>
|
|
106
|
-
</div>
|
|
107
|
-
<div class="card-body">
|
|
108
|
-
<div class="input-group mb-3">
|
|
109
|
-
<span class="input-group-text"><i class="bi bi-pencil-square"></i></span>
|
|
110
|
-
<input class="form-control" placeholder="Type something to add (or hit Ctrl+Enter)..." bind:value="/draft/@text" />
|
|
111
|
-
<button class="btn btn-info" command="addItem">
|
|
112
|
-
<i class="bi bi-plus-circle me-1"></i>Add <kbd class="ms-1">Ctrl+Enter</kbd>
|
|
113
|
-
</button>
|
|
114
|
-
<button class="btn btn-outline-light" command="clearAll">
|
|
115
|
-
<i class="bi bi-trash me-1"></i>Clear <kbd class="ms-1">Ctrl+Shift+X</kbd>
|
|
116
|
-
</button>
|
|
117
|
-
</div>
|
|
118
|
-
|
|
119
|
-
<p class="text-secondary xes-tiny">
|
|
120
|
-
Notice how <strong>Add</strong> stays disabled until you type something, and
|
|
121
|
-
<strong>Clear all</strong> stays disabled when the list is empty - both with no
|
|
122
|
-
hand-written disabled logic. The shortcuts run the same commands, so they
|
|
123
|
-
also respect those <code>enabled</code> predicates.
|
|
124
|
-
</p>
|
|
125
|
-
|
|
126
|
-
<ul class="list-group">
|
|
127
|
-
<repeat ref="/items/item" as="it">
|
|
128
|
-
<li class="list-group-item d-flex align-items-center justify-content-between">
|
|
129
|
-
<span><text value="$it/@text" /></span>
|
|
130
|
-
<button class="btn btn-sm btn-outline-danger" on:click="deleteNode($it)">
|
|
131
|
-
<i class="bi bi-x-lg"></i>
|
|
132
|
-
</button>
|
|
133
|
-
</li>
|
|
134
|
-
</repeat>
|
|
135
|
-
<if test="select('/items/item').length === 0">
|
|
136
|
-
<li class="list-group-item text-secondary text-center">No items yet.</li>
|
|
137
|
-
</if>
|
|
138
|
-
</ul>
|
|
139
|
-
</div>
|
|
140
|
-
</div>
|
|
141
|
-
</div>
|
|
142
|
-
</view>
|
|
143
|
-
</component>
|
|
144
|
-
</galath>
|
|
@@ -1,115 +0,0 @@
|
|
|
1
|
-
<!--
|
|
2
|
-
chapters/07-controller.xml
|
|
3
|
-
|
|
4
|
-
FXML-style controllers. Named actions live in <controller> and are
|
|
5
|
-
invoked from the view via on:click="#actionName" or from <listener
|
|
6
|
-
handler="#actionName">. They are also reachable from <call action="..."/>
|
|
7
|
-
so commands can compose with controllers.
|
|
8
|
-
-->
|
|
9
|
-
<galath xmlns:bind="urn:galath:bind" xmlns:on="urn:galath:on" xmlns:use="urn:galath:use" xmlns:drag="urn:galath:drag" xmlns:drop="urn:galath:drop" xmlns:class="urn:galath:class">
|
|
10
|
-
<component name="chapter-controller" tag="x-chapter-controller">
|
|
11
|
-
<model>
|
|
12
|
-
<signal name="message" value="Click a button to see what controllers do." />
|
|
13
|
-
<signal name="counter" value="0" />
|
|
14
|
-
<signal name="snippet"><![CDATA[<controller>
|
|
15
|
-
<action name="greet">
|
|
16
|
-
<set signal="message" value="'Hello, ' + ($event.target.dataset.name || 'world') + '!'" />
|
|
17
|
-
</action>
|
|
18
|
-
|
|
19
|
-
<action name="bump">
|
|
20
|
-
<set signal="counter" value="counter + 1" />
|
|
21
|
-
<call action="greet" />
|
|
22
|
-
</action>
|
|
23
|
-
</controller>
|
|
24
|
-
|
|
25
|
-
<button data-name="Ada" on:click="#greet">Greet Ada</button>
|
|
26
|
-
<button on:click="#bump">Bump & greet</button>]]></signal>
|
|
27
|
-
</model>
|
|
28
|
-
|
|
29
|
-
<controller>
|
|
30
|
-
<action name="greet">
|
|
31
|
-
<set signal="message" value="'Hello, ' + ($event.currentTarget.dataset.name || 'world') + '!'" />
|
|
32
|
-
</action>
|
|
33
|
-
|
|
34
|
-
<action name="bump">
|
|
35
|
-
<set signal="counter" value="counter + 1" />
|
|
36
|
-
<call action="greet" />
|
|
37
|
-
</action>
|
|
38
|
-
|
|
39
|
-
<action name="reset">
|
|
40
|
-
<set signal="counter" value="0" />
|
|
41
|
-
<set signal="message" value="'Reset.'" />
|
|
42
|
-
</action>
|
|
43
|
-
</controller>
|
|
44
|
-
|
|
45
|
-
<view>
|
|
46
|
-
<div class="px-4 py-5">
|
|
47
|
-
<x-chapter-heading icon="bi-person-gear" title="Controllers"
|
|
48
|
-
subtitle="Named actions in one place. The view calls them by name." />
|
|
49
|
-
|
|
50
|
-
<div class="row g-4 mb-4">
|
|
51
|
-
<div class="col-lg-6">
|
|
52
|
-
<div class="card xes-card h-100">
|
|
53
|
-
<div class="card-body">
|
|
54
|
-
<h2 class="h5"><i class="bi bi-journal-text me-2 text-info"></i>How it works</h2>
|
|
55
|
-
<p class="text-secondary">
|
|
56
|
-
A <code><controller></code> contains <code><action></code>s -
|
|
57
|
-
named procedures of operations. Anywhere a handler is expected
|
|
58
|
-
(<code>on:click</code>, <code><listener handler="..."></code>,
|
|
59
|
-
<code><call></code>) you can reference one with <code>#actionName</code>.
|
|
60
|
-
</p>
|
|
61
|
-
<p class="text-secondary">
|
|
62
|
-
The same operation vocabulary is shared with
|
|
63
|
-
<code><commandset></code>: <code><set></code>,
|
|
64
|
-
<code><setvalue></code>, <code><insert></code>,
|
|
65
|
-
<code><delete></code>, <code><call></code>, <code><log></code>,
|
|
66
|
-
<code><eval></code>.
|
|
67
|
-
</p>
|
|
68
|
-
<p class="text-secondary mb-0">
|
|
69
|
-
Inside an action, <code>$event</code> is the originating DOM event (when
|
|
70
|
-
there was one). Read <code>$event.currentTarget.dataset.X</code> to pass small
|
|
71
|
-
data from the markup without a separate signal per button.
|
|
72
|
-
</p>
|
|
73
|
-
</div>
|
|
74
|
-
</div>
|
|
75
|
-
</div>
|
|
76
|
-
<div class="col-lg-6">
|
|
77
|
-
<div class="card xes-card h-100">
|
|
78
|
-
<div class="card-header bg-transparent d-flex justify-content-between align-items-center">
|
|
79
|
-
<strong><i class="bi bi-code-slash me-2"></i>Source</strong>
|
|
80
|
-
<div class="btn-group btn-group-sm" role="group"><button class="btn btn-outline-info" on:click="window.galathRunSnippet(snippet)" title="Open this snippet in a new tab"><i class="bi bi-play-fill me-1"></i>Run</button><button class="btn btn-outline-info" use:copy="snippet" title="Copy to clipboard"><i class="bi bi-clipboard me-1"></i>Copy</button></div>
|
|
81
|
-
</div>
|
|
82
|
-
<div class="card-body p-0">
|
|
83
|
-
<pre class="xes-code rounded p-3 mb-0"><code><text value="snippet" /></code></pre>
|
|
84
|
-
</div>
|
|
85
|
-
</div>
|
|
86
|
-
</div>
|
|
87
|
-
</div>
|
|
88
|
-
|
|
89
|
-
<div class="card xes-card">
|
|
90
|
-
<div class="card-header bg-transparent">
|
|
91
|
-
<strong><i class="bi bi-play-circle me-2"></i>Live demo</strong>
|
|
92
|
-
</div>
|
|
93
|
-
<div class="card-body">
|
|
94
|
-
<div class="d-flex gap-2 flex-wrap mb-3">
|
|
95
|
-
<button class="btn btn-info" data-name="Ada" on:click="#greet">Greet Ada</button>
|
|
96
|
-
<button class="btn btn-info" data-name="Linus" on:click="#greet">Greet Linus</button>
|
|
97
|
-
<button class="btn btn-info" data-name="Grace" on:click="#greet">Greet Grace</button>
|
|
98
|
-
<button class="btn btn-outline-light" on:click="#bump">Bump & greet</button>
|
|
99
|
-
<button class="btn btn-outline-secondary" on:click="#reset">Reset</button>
|
|
100
|
-
</div>
|
|
101
|
-
|
|
102
|
-
<div class="alert alert-info">
|
|
103
|
-
<i class="bi bi-chat-quote me-1"></i>
|
|
104
|
-
<strong>Message:</strong> {message}
|
|
105
|
-
</div>
|
|
106
|
-
|
|
107
|
-
<div class="text-secondary xes-tiny">
|
|
108
|
-
Counter: <span class="badge text-bg-secondary">{counter}</span>
|
|
109
|
-
</div>
|
|
110
|
-
</div>
|
|
111
|
-
</div>
|
|
112
|
-
</div>
|
|
113
|
-
</view>
|
|
114
|
-
</component>
|
|
115
|
-
</galath>
|
|
@@ -1,126 +0,0 @@
|
|
|
1
|
-
<!--
|
|
2
|
-
chapters/08-events.xml
|
|
3
|
-
|
|
4
|
-
XML Events: declarative listeners on the data tree, separate from DOM
|
|
5
|
-
events. Useful for cross-cutting concerns like logging, undo stacks,
|
|
6
|
-
or syncing to a server.
|
|
7
|
-
-->
|
|
8
|
-
<galath xmlns:bind="urn:galath:bind" xmlns:on="urn:galath:on" xmlns:use="urn:galath:use" xmlns:drag="urn:galath:drag" xmlns:drop="urn:galath:drop" xmlns:class="urn:galath:class">
|
|
9
|
-
<component name="chapter-events" tag="x-chapter-events">
|
|
10
|
-
<model>
|
|
11
|
-
<signal name="log" value="" />
|
|
12
|
-
|
|
13
|
-
<instance>
|
|
14
|
-
<project name="Galath">
|
|
15
|
-
<task id="t1" title="Write the runtime" done="true" />
|
|
16
|
-
<task id="t2" title="Write the playground" done="false" />
|
|
17
|
-
</project>
|
|
18
|
-
</instance>
|
|
19
|
-
|
|
20
|
-
<signal name="snippet"><![CDATA[<listeners>
|
|
21
|
-
<listener event="xforms-insert" observer="/project" handler="#log" />
|
|
22
|
-
<listener event="xforms-delete" observer="/project" handler="#log" />
|
|
23
|
-
<listener event="xforms-value-changed" observer="/project" handler="#log" />
|
|
24
|
-
</listeners>
|
|
25
|
-
|
|
26
|
-
<controller>
|
|
27
|
-
<action name="log">
|
|
28
|
-
<set signal="log" value="$event.type + ' at ' + $event.path + '\n' + log" />
|
|
29
|
-
</action>
|
|
30
|
-
</controller>]]></signal>
|
|
31
|
-
</model>
|
|
32
|
-
|
|
33
|
-
<controller>
|
|
34
|
-
<action name="log">
|
|
35
|
-
<set signal="log" value="$event.type + ' at ' + $event.path + '\n' + log" />
|
|
36
|
-
</action>
|
|
37
|
-
<action name="addTask">
|
|
38
|
-
<insert ref="/project">
|
|
39
|
-
<task id="{uid()}" title="New task" done="false" />
|
|
40
|
-
</insert>
|
|
41
|
-
</action>
|
|
42
|
-
<action name="clearLog">
|
|
43
|
-
<set signal="log" value="''" />
|
|
44
|
-
</action>
|
|
45
|
-
</controller>
|
|
46
|
-
|
|
47
|
-
<listeners>
|
|
48
|
-
<listener event="xforms-insert" observer="/project" handler="#log" />
|
|
49
|
-
<listener event="xforms-delete" observer="/project" handler="#log" />
|
|
50
|
-
<listener event="xforms-value-changed" observer="/project" handler="#log" />
|
|
51
|
-
</listeners>
|
|
52
|
-
|
|
53
|
-
<view>
|
|
54
|
-
<div class="px-4 py-5">
|
|
55
|
-
<x-chapter-heading icon="bi-broadcast-pin" title="XML Events"
|
|
56
|
-
subtitle="Listen to data-tree mutations the same way DOM events work, but for state." />
|
|
57
|
-
|
|
58
|
-
<div class="row g-4 mb-4">
|
|
59
|
-
<div class="col-lg-6">
|
|
60
|
-
<div class="card xes-card h-100">
|
|
61
|
-
<div class="card-body">
|
|
62
|
-
<h2 class="h5"><i class="bi bi-journal-text me-2 text-info"></i>How it works</h2>
|
|
63
|
-
<p class="text-secondary">
|
|
64
|
-
Three event types fire on every instance-tree mutation:
|
|
65
|
-
</p>
|
|
66
|
-
<ul class="text-secondary">
|
|
67
|
-
<li><code>xforms-insert</code> - a node was added.</li>
|
|
68
|
-
<li><code>xforms-delete</code> - a node was removed.</li>
|
|
69
|
-
<li><code>xforms-value-changed</code> - an attribute or text was updated.</li>
|
|
70
|
-
</ul>
|
|
71
|
-
<p class="text-secondary">
|
|
72
|
-
The <code>observer="/path"</code> attribute filters by path prefix, so you can
|
|
73
|
-
listen to only the part of the tree you care about. <code>$event</code> exposes
|
|
74
|
-
<code>type</code>, <code>path</code>, <code>node</code>, <code>parent</code>,
|
|
75
|
-
and the attribute fields.
|
|
76
|
-
</p>
|
|
77
|
-
<p class="text-secondary mb-0">
|
|
78
|
-
Use these for logging, undo, persistence, or any side effect that should fire on
|
|
79
|
-
data change.
|
|
80
|
-
</p>
|
|
81
|
-
</div>
|
|
82
|
-
</div>
|
|
83
|
-
</div>
|
|
84
|
-
<div class="col-lg-6">
|
|
85
|
-
<div class="card xes-card h-100">
|
|
86
|
-
<div class="card-header bg-transparent d-flex justify-content-between align-items-center">
|
|
87
|
-
<strong><i class="bi bi-code-slash me-2"></i>Source</strong>
|
|
88
|
-
<div class="btn-group btn-group-sm" role="group"><button class="btn btn-outline-info" on:click="window.galathRunSnippet(snippet)" title="Open this snippet in a new tab"><i class="bi bi-play-fill me-1"></i>Run</button><button class="btn btn-outline-info" use:copy="snippet" title="Copy to clipboard"><i class="bi bi-clipboard me-1"></i>Copy</button></div>
|
|
89
|
-
</div>
|
|
90
|
-
<div class="card-body p-0">
|
|
91
|
-
<pre class="xes-code rounded p-3 mb-0"><code><text value="snippet" /></code></pre>
|
|
92
|
-
</div>
|
|
93
|
-
</div>
|
|
94
|
-
</div>
|
|
95
|
-
</div>
|
|
96
|
-
|
|
97
|
-
<div class="card xes-card">
|
|
98
|
-
<div class="card-header bg-transparent">
|
|
99
|
-
<strong><i class="bi bi-play-circle me-2"></i>Live demo</strong>
|
|
100
|
-
</div>
|
|
101
|
-
<div class="card-body">
|
|
102
|
-
<div class="d-flex gap-2 flex-wrap mb-3">
|
|
103
|
-
<button class="btn btn-info" on:click="#addTask"><i class="bi bi-plus-circle me-1"></i>Add task</button>
|
|
104
|
-
<button class="btn btn-outline-light" on:click="#clearLog"><i class="bi bi-eraser me-1"></i>Clear log</button>
|
|
105
|
-
</div>
|
|
106
|
-
|
|
107
|
-
<ul class="list-group mb-3">
|
|
108
|
-
<repeat ref="/project/task" as="t">
|
|
109
|
-
<li class="list-group-item d-flex align-items-center gap-2">
|
|
110
|
-
<input class="form-check-input m-0" type="checkbox" bind:checked="$t/@done" />
|
|
111
|
-
<input class="form-control form-control-sm flex-grow-1" bind:value="$t/@title" />
|
|
112
|
-
<button class="btn btn-sm btn-outline-danger" on:click="deleteNode($t)">
|
|
113
|
-
<i class="bi bi-x-lg"></i>
|
|
114
|
-
</button>
|
|
115
|
-
</li>
|
|
116
|
-
</repeat>
|
|
117
|
-
</ul>
|
|
118
|
-
|
|
119
|
-
<label class="form-label">Live event log</label>
|
|
120
|
-
<textarea class="form-control font-monospace" rows="6" bind:value="log"></textarea>
|
|
121
|
-
</div>
|
|
122
|
-
</div>
|
|
123
|
-
</div>
|
|
124
|
-
</view>
|
|
125
|
-
</component>
|
|
126
|
-
</galath>
|
|
@@ -1,210 +0,0 @@
|
|
|
1
|
-
<!--
|
|
2
|
-
chapters/09-behaviors.xml
|
|
3
|
-
|
|
4
|
-
Attached behaviors: tiny disposable extensions to a single element. The
|
|
5
|
-
built-ins are use:copy, use:focus, use:autosize, plus the drag/drop
|
|
6
|
-
pair.
|
|
7
|
-
-->
|
|
8
|
-
<galath xmlns:bind="urn:galath:bind" xmlns:on="urn:galath:on" xmlns:use="urn:galath:use" xmlns:drag="urn:galath:drag" xmlns:drop="urn:galath:drop" xmlns:class="urn:galath:class">
|
|
9
|
-
<component name="chapter-behaviors" tag="x-chapter-behaviors">
|
|
10
|
-
<model>
|
|
11
|
-
<instance>
|
|
12
|
-
<cards>
|
|
13
|
-
<card id="c1" text="Drag me" color="info" />
|
|
14
|
-
<card id="c2" text="Or me" color="success" />
|
|
15
|
-
<card id="c3" text="Reorder by dropping onto another card" color="warning" />
|
|
16
|
-
</cards>
|
|
17
|
-
</instance>
|
|
18
|
-
|
|
19
|
-
<signal name="memo" value="Type something then click Copy." />
|
|
20
|
-
|
|
21
|
-
<signal name="snippet"><![CDATA[<button use:copy="memo">Copy</button>
|
|
22
|
-
|
|
23
|
-
<textarea use:autosize bind:value="notes"></textarea>
|
|
24
|
-
|
|
25
|
-
<input use:focus="open" />
|
|
26
|
-
|
|
27
|
-
<div drag:source="$card"
|
|
28
|
-
drop:target="$card"
|
|
29
|
-
drop:command="reorder">
|
|
30
|
-
...
|
|
31
|
-
</div>
|
|
32
|
-
|
|
33
|
-
<commandset>
|
|
34
|
-
<command name="reorder">
|
|
35
|
-
<eval>
|
|
36
|
-
$source.remove();
|
|
37
|
-
$target.parent.insertBefore($source, $target);
|
|
38
|
-
</eval>
|
|
39
|
-
</command>
|
|
40
|
-
</commandset>]]></signal>
|
|
41
|
-
</model>
|
|
42
|
-
|
|
43
|
-
<commandset>
|
|
44
|
-
<command name="reorder">
|
|
45
|
-
<eval>
|
|
46
|
-
if ($source && $target && $source !== $target) {
|
|
47
|
-
$source.remove();
|
|
48
|
-
$target.parent.insertBefore($source, $target);
|
|
49
|
-
}
|
|
50
|
-
</eval>
|
|
51
|
-
</command>
|
|
52
|
-
</commandset>
|
|
53
|
-
|
|
54
|
-
<!--
|
|
55
|
-
Build your own behavior. We register `use:tilt` here at chapter
|
|
56
|
-
mount time. Real apps would register inside their own feature
|
|
57
|
-
plugin; this is the same API. The behavior receives the live DOM
|
|
58
|
-
element and returns a Disposable so the runtime can clean it up
|
|
59
|
-
on the next render.
|
|
60
|
-
-->
|
|
61
|
-
<on:mount>
|
|
62
|
-
<eval>
|
|
63
|
-
const lang = window.galath;
|
|
64
|
-
if (lang && !lang.behaviors.has('tilt')) {
|
|
65
|
-
lang.behaviors.set('tilt', (element) => {
|
|
66
|
-
const onEnter = () => {
|
|
67
|
-
const angle = (Math.random() * 6 - 3).toFixed(2);
|
|
68
|
-
element.style.transition = 'transform .15s ease';
|
|
69
|
-
element.style.transform = `rotate(${angle}deg) scale(1.04)`;
|
|
70
|
-
};
|
|
71
|
-
const onLeave = () => { element.style.transform = ''; };
|
|
72
|
-
element.addEventListener('mouseenter', onEnter);
|
|
73
|
-
element.addEventListener('mouseleave', onLeave);
|
|
74
|
-
return new lang.Disposable(() => {
|
|
75
|
-
element.removeEventListener('mouseenter', onEnter);
|
|
76
|
-
element.removeEventListener('mouseleave', onLeave);
|
|
77
|
-
element.style.transform = '';
|
|
78
|
-
});
|
|
79
|
-
});
|
|
80
|
-
}
|
|
81
|
-
</eval>
|
|
82
|
-
</on:mount>
|
|
83
|
-
|
|
84
|
-
<view>
|
|
85
|
-
<div class="px-4 py-5">
|
|
86
|
-
<x-chapter-heading icon="bi-puzzle" title="Behaviors"
|
|
87
|
-
subtitle="use:* attaches small reusable extensions; drag:* / drop:* compose into drag-and-drop." />
|
|
88
|
-
|
|
89
|
-
<div class="row g-4 mb-4">
|
|
90
|
-
<div class="col-lg-6">
|
|
91
|
-
<div class="card xes-card h-100">
|
|
92
|
-
<div class="card-body">
|
|
93
|
-
<h2 class="h5"><i class="bi bi-journal-text me-2 text-info"></i>How it works</h2>
|
|
94
|
-
<p class="text-secondary">
|
|
95
|
-
A behavior is a function attached to a single element. It returns a
|
|
96
|
-
<code>Disposable</code> so it cleans up on the next render. Built-ins:
|
|
97
|
-
</p>
|
|
98
|
-
<ul class="text-secondary">
|
|
99
|
-
<li><code>use:copy="signalOrPath"</code> - click to copy.</li>
|
|
100
|
-
<li><code>use:focus="expr"</code> - focus when truthy.</li>
|
|
101
|
-
<li><code>use:autosize</code> - growing textarea.</li>
|
|
102
|
-
<li><code>drag:source="$x"</code> + <code>drop:target="$y"</code> +
|
|
103
|
-
<code>drop:command="cmd"</code> - run a command with
|
|
104
|
-
<code>$source</code>/<code>$target</code> in scope on drop.</li>
|
|
105
|
-
</ul>
|
|
106
|
-
<p class="text-secondary mb-0">
|
|
107
|
-
Add your own with <code>language.behaviors.set('name', fn)</code> in a feature
|
|
108
|
-
plugin. Each function receives <code>(element, value, instance, local)</code>
|
|
109
|
-
and returns a Disposable.
|
|
110
|
-
</p>
|
|
111
|
-
</div>
|
|
112
|
-
</div>
|
|
113
|
-
</div>
|
|
114
|
-
<div class="col-lg-6">
|
|
115
|
-
<div class="card xes-card h-100">
|
|
116
|
-
<div class="card-header bg-transparent d-flex justify-content-between align-items-center">
|
|
117
|
-
<strong><i class="bi bi-code-slash me-2"></i>Source</strong>
|
|
118
|
-
<div class="btn-group btn-group-sm" role="group"><button class="btn btn-outline-info" on:click="window.galathRunSnippet(snippet)" title="Open this snippet in a new tab"><i class="bi bi-play-fill me-1"></i>Run</button><button class="btn btn-outline-info" use:copy="snippet" title="Copy to clipboard"><i class="bi bi-clipboard me-1"></i>Copy</button></div>
|
|
119
|
-
</div>
|
|
120
|
-
<div class="card-body p-0">
|
|
121
|
-
<pre class="xes-code rounded p-3 mb-0"><code><text value="snippet" /></code></pre>
|
|
122
|
-
</div>
|
|
123
|
-
</div>
|
|
124
|
-
</div>
|
|
125
|
-
</div>
|
|
126
|
-
|
|
127
|
-
<div class="card xes-card mb-4">
|
|
128
|
-
<div class="card-header bg-transparent">
|
|
129
|
-
<strong><i class="bi bi-clipboard me-2"></i>use:copy</strong>
|
|
130
|
-
</div>
|
|
131
|
-
<div class="card-body">
|
|
132
|
-
<div class="input-group">
|
|
133
|
-
<input class="form-control" bind:value="memo" />
|
|
134
|
-
<button class="btn btn-info" use:copy="memo">
|
|
135
|
-
<i class="bi bi-clipboard me-1"></i>Copy
|
|
136
|
-
</button>
|
|
137
|
-
</div>
|
|
138
|
-
<small class="text-secondary">Click Copy; the button briefly turns green and the value lands in your clipboard.</small>
|
|
139
|
-
</div>
|
|
140
|
-
</div>
|
|
141
|
-
|
|
142
|
-
<div class="card xes-card mb-4">
|
|
143
|
-
<div class="card-header bg-transparent">
|
|
144
|
-
<strong><i class="bi bi-tools me-2"></i>Build your own behavior</strong>
|
|
145
|
-
</div>
|
|
146
|
-
<div class="card-body">
|
|
147
|
-
<p class="text-secondary">
|
|
148
|
-
A behavior is just a function with the signature
|
|
149
|
-
<code>(element, value, instance, local) => Disposable</code>. Register it
|
|
150
|
-
once with <code>language.behaviors.set('name', fn)</code>; from then on,
|
|
151
|
-
any view can use it via <code>use:name="..."</code>. The runtime collects
|
|
152
|
-
the returned Disposable on the active render scope, so it is detached on
|
|
153
|
-
the next render or unmount automatically.
|
|
154
|
-
</p>
|
|
155
|
-
<pre class="xes-code rounded p-3"><code>language.behaviors.set('tilt', (element) => {
|
|
156
|
-
const onEnter = () => { element.style.transform = `rotate(${(Math.random() * 6 - 3)}deg)`; };
|
|
157
|
-
const onLeave = () => { element.style.transform = ''; };
|
|
158
|
-
element.addEventListener('mouseenter', onEnter);
|
|
159
|
-
element.addEventListener('mouseleave', onLeave);
|
|
160
|
-
return new language.Disposable(() => {
|
|
161
|
-
element.removeEventListener('mouseenter', onEnter);
|
|
162
|
-
element.removeEventListener('mouseleave', onLeave);
|
|
163
|
-
});
|
|
164
|
-
});
|
|
165
|
-
|
|
166
|
-
<!-- and then anywhere in a view: -->
|
|
167
|
-
<button use:tilt>Hover me</button></code></pre>
|
|
168
|
-
<div class="d-flex gap-2 flex-wrap mt-2">
|
|
169
|
-
<button class="btn btn-info" use:tilt="">Hover me</button>
|
|
170
|
-
<button class="btn btn-outline-info" use:tilt="">Or me</button>
|
|
171
|
-
<button class="btn btn-outline-warning" use:tilt="">Behavior in action</button>
|
|
172
|
-
</div>
|
|
173
|
-
<small class="text-secondary mt-3 d-block">
|
|
174
|
-
All three buttons share the same behavior; each gets its own listener pair
|
|
175
|
-
and its own Disposable cleanup.
|
|
176
|
-
</small>
|
|
177
|
-
</div>
|
|
178
|
-
</div>
|
|
179
|
-
|
|
180
|
-
<div class="card xes-card">
|
|
181
|
-
<div class="card-header bg-transparent">
|
|
182
|
-
<strong><i class="bi bi-arrows-move me-2"></i>Drag & drop</strong>
|
|
183
|
-
</div>
|
|
184
|
-
<div class="card-body">
|
|
185
|
-
<div class="row g-3">
|
|
186
|
-
<repeat ref="/cards/card" as="card">
|
|
187
|
-
<div class="col-md-4">
|
|
188
|
-
<div class="card text-bg-{$card/@color}"
|
|
189
|
-
drag:source="$card"
|
|
190
|
-
drop:target="$card"
|
|
191
|
-
drop:command="reorder"
|
|
192
|
-
style="cursor: grab;">
|
|
193
|
-
<div class="card-body">
|
|
194
|
-
<i class="bi bi-grip-vertical me-2"></i>
|
|
195
|
-
<strong><text value="$card/@text" /></strong>
|
|
196
|
-
</div>
|
|
197
|
-
</div>
|
|
198
|
-
</div>
|
|
199
|
-
</repeat>
|
|
200
|
-
</div>
|
|
201
|
-
<small class="text-secondary mt-3 d-block">
|
|
202
|
-
Drag a card onto another to reorder. The drag is wired by attaching three attributes
|
|
203
|
-
and writing a single command - no event handlers in JS.
|
|
204
|
-
</small>
|
|
205
|
-
</div>
|
|
206
|
-
</div>
|
|
207
|
-
</div>
|
|
208
|
-
</view>
|
|
209
|
-
</component>
|
|
210
|
-
</galath>
|