@everystate/examples 1.0.0 → 1.0.1
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/README.md +15 -0
- package/everyState-core/001-counter/README.md +44 -0
- package/everyState-core/001-counter/index.html +79 -0
- package/everyState-core/002-counter-improved/README.md +44 -0
- package/everyState-core/002-counter-improved/index.html +83 -0
- package/everyState-core/003-input-reactive/README.md +44 -0
- package/everyState-core/003-input-reactive/index.html +68 -0
- package/everyState-core/004-computed-state/README.md +45 -0
- package/everyState-core/004-computed-state/index.html +83 -0
- package/everyState-core/005-conditional-rendering/README.md +42 -0
- package/everyState-core/005-conditional-rendering/index.html +68 -0
- package/everyState-core/006-list-rendering/README.md +49 -0
- package/everyState-core/006-list-rendering/index.html +92 -0
- package/everyState-core/007-form-validation/README.md +52 -0
- package/everyState-core/007-form-validation/index.html +108 -0
- package/everyState-core/008-undo-redo/README.md +70 -0
- package/everyState-core/008-undo-redo/index.html +133 -0
- package/everyState-core/009-localStorage-side-effects/README.md +72 -0
- package/everyState-core/009-localStorage-side-effects/index.html +80 -0
- package/everyState-core/010-decoupled-components/README.md +74 -0
- package/everyState-core/010-decoupled-components/index.html +117 -0
- package/everyState-core/011-async-patterns/README.md +98 -0
- package/everyState-core/011-async-patterns/index.html +132 -0
- package/everyState-css/001-stateDrivenCSS/index.html +377 -0
- package/everyState-css/002-cssV2FullDemo/index.html +630 -0
- package/everyState-view/001/counter/index.css +31 -0
- package/everyState-view/001/counter/index.html +50 -0
- package/everyState-view/002/datatable/index.css +70 -0
- package/everyState-view/002/datatable/index.html +118 -0
- package/everyState-view/003/todo/index.css +260 -0
- package/everyState-view/003/todo/index.html +218 -0
- package/everyState-view/003-input-reactive/README.md +44 -0
- package/everyState-view/003-input-reactive/index.html +68 -0
- package/everyState-view/004/quotesFetcher/index.css +124 -0
- package/everyState-view/004/quotesFetcher/index.html +108 -0
- package/everyState-view/004_01/quotesFetcher/app.js +32 -0
- package/everyState-view/004_01/quotesFetcher/components/appHeader/appSubtitle.js +2 -0
- package/everyState-view/004_01/quotesFetcher/components/appHeader/appTitle.js +2 -0
- package/everyState-view/004_01/quotesFetcher/components/appHeader.js +9 -0
- package/everyState-view/004_01/quotesFetcher/components/historyHeading.js +2 -0
- package/everyState-view/004_01/quotesFetcher/components/historyList/histAuthor.js +2 -0
- package/everyState-view/004_01/quotesFetcher/components/historyList/histQuote.js +2 -0
- package/everyState-view/004_01/quotesFetcher/components/historyList.js +14 -0
- package/everyState-view/004_01/quotesFetcher/components/quoteCard/fetchButton.js +2 -0
- package/everyState-view/004_01/quotesFetcher/components/quoteCard/quoteAuthor.js +2 -0
- package/everyState-view/004_01/quotesFetcher/components/quoteCard/quoteMessage.js +2 -0
- package/everyState-view/004_01/quotesFetcher/components/quoteCard/quoteText.js +2 -0
- package/everyState-view/004_01/quotesFetcher/components/quoteCard.js +11 -0
- package/everyState-view/004_01/quotesFetcher/index.css +124 -0
- package/everyState-view/004_01/quotesFetcher/index.html +23 -0
- package/everyState-view/004_01/quotesFetcher/store.js +35 -0
- package/everyState-view/004_02/quotesFetcher/app.js +20 -0
- package/everyState-view/004_02/quotesFetcher/components.js +46 -0
- package/everyState-view/004_02/quotesFetcher/index.css +124 -0
- package/everyState-view/004_02/quotesFetcher/index.html +23 -0
- package/everyState-view/004_02/quotesFetcher/store.js +35 -0
- package/everyState-view/004_03/quotesFetcher/actions.js +27 -0
- package/everyState-view/004_03/quotesFetcher/app.js +19 -0
- package/everyState-view/004_03/quotesFetcher/components.js +28 -0
- package/everyState-view/004_03/quotesFetcher/index.css +124 -0
- package/everyState-view/004_03/quotesFetcher/index.html +23 -0
- package/everyState-view/004_03/quotesFetcher/resolve.js +34 -0
- package/everyState-view/004_03/quotesFetcher/store.js +11 -0
- package/everyState-view/004_04/quotesFetcher/actions.js +66 -0
- package/everyState-view/004_04/quotesFetcher/app.js +24 -0
- package/everyState-view/004_04/quotesFetcher/components/archive.js +40 -0
- package/everyState-view/004_04/quotesFetcher/components/fetcher.js +29 -0
- package/everyState-view/004_04/quotesFetcher/components.js +20 -0
- package/everyState-view/004_04/quotesFetcher/index.css +283 -0
- package/everyState-view/004_04/quotesFetcher/index.html +24 -0
- package/everyState-view/004_04/quotesFetcher/resolve.js +34 -0
- package/everyState-view/004_04/quotesFetcher/store.js +21 -0
- package/everyState-view/004_04/statedump.json +826 -0
- package/everyState-view/004_05/quoteExplorer/actions.js +58 -0
- package/everyState-view/004_05/quoteExplorer/app.js +27 -0
- package/everyState-view/004_05/quoteExplorer/components.js +83 -0
- package/everyState-view/004_05/quoteExplorer/index.css +231 -0
- package/everyState-view/004_05/quoteExplorer/index.html +23 -0
- package/everyState-view/004_05/quoteExplorer/resolve.js +50 -0
- package/everyState-view/004_05/quoteExplorer/store.js +33 -0
- package/everyState-view/004_06/quoteExplorer/actions.js +21 -0
- package/everyState-view/004_06/quoteExplorer/app.js +44 -0
- package/everyState-view/004_06/quoteExplorer/components.js +80 -0
- package/everyState-view/004_06/quoteExplorer/derived.js +43 -0
- package/everyState-view/004_06/quoteExplorer/index.css +346 -0
- package/everyState-view/004_06/quoteExplorer/index.html +25 -0
- package/everyState-view/004_06/quoteExplorer/intents.js +44 -0
- package/everyState-view/004_06/quoteExplorer/policies.js +25 -0
- package/everyState-view/004_06/quoteExplorer/resolve.js +51 -0
- package/everyState-view/004_06/quoteExplorer/store.js +44 -0
- package/everyState-view/004_07/quoteExplorer/app.js +47 -0
- package/everyState-view/004_07/quoteExplorer/components.js +85 -0
- package/everyState-view/004_07/quoteExplorer/derived.js +43 -0
- package/everyState-view/004_07/quoteExplorer/index.css +346 -0
- package/everyState-view/004_07/quoteExplorer/index.html +25 -0
- package/everyState-view/004_07/quoteExplorer/intents.js +51 -0
- package/everyState-view/004_07/quoteExplorer/policies.js +21 -0
- package/everyState-view/004_07/quoteExplorer/resolve.js +39 -0
- package/everyState-view/004_07/quoteExplorer/store.js +44 -0
- package/everyState-view/004_08/quoteExplorer/app.js +78 -0
- package/everyState-view/004_08/quoteExplorer/components.js +85 -0
- package/everyState-view/004_08/quoteExplorer/derived.js +43 -0
- package/everyState-view/004_08/quoteExplorer/index.css +346 -0
- package/everyState-view/004_08/quoteExplorer/index.html +25 -0
- package/everyState-view/004_08/quoteExplorer/intents.js +51 -0
- package/everyState-view/004_08/quoteExplorer/policies.js +21 -0
- package/everyState-view/004_08/quoteExplorer/resolve.js +39 -0
- package/everyState-view/004_08/quoteExplorer/store.js +44 -0
- package/everyState-view/004_08_V2/app.js +78 -0
- package/everyState-view/004_08_V2/components/appDetail.js +8 -0
- package/everyState-view/004_08_V2/components/appDetailBar.js +7 -0
- package/everyState-view/004_08_V2/components/appDetailBarClose.js +8 -0
- package/everyState-view/004_08_V2/components/appDetailBarCount.js +7 -0
- package/everyState-view/004_08_V2/components/appDetailBarHeading.js +7 -0
- package/everyState-view/004_08_V2/components/appDetailQuotes.js +15 -0
- package/everyState-view/004_08_V2/components/appHeader.js +7 -0
- package/everyState-view/004_08_V2/components/appHeaderSubtitle.js +7 -0
- package/everyState-view/004_08_V2/components/appHeaderTitle.js +7 -0
- package/everyState-view/004_08_V2/components/appLog.js +7 -0
- package/everyState-view/004_08_V2/components/appLogHeading.js +7 -0
- package/everyState-view/004_08_V2/components/appLogList.js +16 -0
- package/everyState-view/004_08_V2/components/appSearch.js +7 -0
- package/everyState-view/004_08_V2/components/appSearchInput.js +9 -0
- package/everyState-view/004_08_V2/components/appStats.js +7 -0
- package/everyState-view/004_08_V2/components/appStatsContent.js +8 -0
- package/everyState-view/004_08_V2/components/appStatsContentFavcount.js +7 -0
- package/everyState-view/004_08_V2/components/appStatsContentText.js +7 -0
- package/everyState-view/004_08_V2/components/appStatsToggle.js +8 -0
- package/everyState-view/004_08_V2/components/appTags.js +7 -0
- package/everyState-view/004_08_V2/components/appTagsLabel.js +7 -0
- package/everyState-view/004_08_V2/components/appTagsRow.js +15 -0
- package/everyState-view/004_08_V2/components/index.js +59 -0
- package/everyState-view/004_08_V2/components/utils/css.js +88 -0
- package/everyState-view/004_08_V2/components/utils/elements.js +87 -0
- package/everyState-view/004_08_V2/components.js +79 -0
- package/everyState-view/004_08_V2/derived.js +43 -0
- package/everyState-view/004_08_V2/index.css +350 -0
- package/everyState-view/004_08_V2/index.html +25 -0
- package/everyState-view/004_08_V2/intents.js +51 -0
- package/everyState-view/004_08_V2/policies.js +21 -0
- package/everyState-view/004_08_V2/resolve.js +39 -0
- package/everyState-view/004_08_V2/store.js +44 -0
- package/everyState-view/006/api-datatable/index.css +388 -0
- package/everyState-view/006/api-datatable/index.html +355 -0
- package/everyState-view/007/apiUsers/index.html +307 -0
- package/everyState-view/007-form-validation/README.md +52 -0
- package/everyState-view/007-form-validation/index.html +108 -0
- package/everyState-view/010-decoupled-components/README.md +74 -0
- package/everyState-view/010-decoupled-components/index.html +117 -0
- package/everyState-view/index.html +36 -0
- package/index.js +0 -5
- package/package.json +2 -4
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
// ─── Store: namespaced state tree ───────────────────────────────
|
|
2
|
+
// state.* = source of truth (user data)
|
|
3
|
+
// derived.* = auto-computed by subscribers
|
|
4
|
+
// ui.* = ephemeral UI flags
|
|
5
|
+
// intent.* = written directly by UI events, consumed by intent handlers
|
|
6
|
+
|
|
7
|
+
import { createEveryState } from '@everystate/core';
|
|
8
|
+
|
|
9
|
+
export const store = createEveryState({
|
|
10
|
+
state: {
|
|
11
|
+
quotes: [
|
|
12
|
+
{ id: 1, author: 'Rumi', text: 'Your heart is the size of an ocean. Go find yourself in its hidden depths.', fav: false },
|
|
13
|
+
{ id: 2, author: 'Rumi', text: 'Respond to every call that excites your spirit.', fav: false },
|
|
14
|
+
{ id: 3, author: 'Rumi', text: 'Everything in the universe is within you. Ask all from yourself.', fav: false },
|
|
15
|
+
{ id: 4, author: 'Rumi', text: 'When I am silent, I have thunder hidden inside.', fav: false },
|
|
16
|
+
{ id: 5, author: 'Einstein', text: 'Imagination is more important than knowledge.', fav: false },
|
|
17
|
+
{ id: 6, author: 'Einstein', text: 'Life is like riding a bicycle. To keep your balance, you must keep moving.', fav: false },
|
|
18
|
+
{ id: 7, author: 'Einstein', text: "If you can't explain it simply, you don't understand it well enough.", fav: false },
|
|
19
|
+
{ id: 8, author: 'Mother Teresa', text: 'Spread love everywhere you go.', fav: false },
|
|
20
|
+
{ id: 9, author: 'Mother Teresa', text: 'If you judge people, you have no time to love them.', fav: false },
|
|
21
|
+
{ id: 10, author: 'Mother Teresa', text: 'Not all of us can do great things. But we can do small things with great love.', fav: false },
|
|
22
|
+
{ id: 11, author: 'Muhammad Ali', text: 'Float like a butterfly, sting like a bee.', fav: false },
|
|
23
|
+
{ id: 12, author: 'Muhammad Ali', text: "Don't count the days, make the days count.", fav: false },
|
|
24
|
+
{ id: 13, author: 'Muhammad Ali', text: 'Service to others is the rent you pay for your room here on earth.', fav: false },
|
|
25
|
+
{ id: 14, author: 'Socrates', text: 'The unexamined life is not worth living.', fav: false },
|
|
26
|
+
{ id: 15, author: 'Socrates', text: 'I know that I know nothing.', fav: false },
|
|
27
|
+
{ id: 16, author: 'Socrates', text: 'Wonder is the beginning of wisdom.', fav: false },
|
|
28
|
+
],
|
|
29
|
+
authors: ['Rumi', 'Einstein', 'Mother Teresa', 'Muhammad Ali', 'Socrates'],
|
|
30
|
+
selectedAuthor: '',
|
|
31
|
+
searchTerm: '',
|
|
32
|
+
},
|
|
33
|
+
derived: {
|
|
34
|
+
filteredQuotes: [],
|
|
35
|
+
quoteCount: 0,
|
|
36
|
+
favCount: 0,
|
|
37
|
+
stats: '',
|
|
38
|
+
activityLog: [],
|
|
39
|
+
},
|
|
40
|
+
ui: {
|
|
41
|
+
statsVisible: false,
|
|
42
|
+
toggleLabel: '📊 Show Stats',
|
|
43
|
+
},
|
|
44
|
+
});
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
// ─── App: boot sequence ─────────────────────────────────────────
|
|
2
|
+
// 004_08: Fully transparent auto-intent.
|
|
3
|
+
//
|
|
4
|
+
// No Proxy. No actions.js. No runtime metaprogramming.
|
|
5
|
+
// intentHandlers() scans the component registry at boot time and
|
|
6
|
+
// builds a plain handlers map: { 'intent.X': fn } for every
|
|
7
|
+
// onClick/onDblClick/onEnter/onBlur target starting with 'intent.'.
|
|
8
|
+
//
|
|
9
|
+
// The result is a regular object. console.log(handlers) shows every key.
|
|
10
|
+
// grep 'intent.' finds the spec, the handler, and the subscriber.
|
|
11
|
+
|
|
12
|
+
import { flatten } from '@everystate/view/resolve';
|
|
13
|
+
import { mount } from '@everystate/view/project';
|
|
14
|
+
import { createPerfMonitor, mountOverlay } from '@everystate/perf';
|
|
15
|
+
import { store } from './store.js';
|
|
16
|
+
import { c } from './components.js';
|
|
17
|
+
import { resolveTree, buildRefs } from './resolve.js';
|
|
18
|
+
import { mountIntents } from './intents.js';
|
|
19
|
+
import { mountDerived } from './derived.js';
|
|
20
|
+
import { mountPolicies } from './policies.js';
|
|
21
|
+
|
|
22
|
+
// ─── intentHandlers: scan registry, build plain handlers map ────
|
|
23
|
+
// Walks all component specs + nested templates. For every event
|
|
24
|
+
// target starting with 'intent.', registers a handler that calls
|
|
25
|
+
// store.set(intentPath, resolvedArg). Returns a plain object.
|
|
26
|
+
|
|
27
|
+
function intentHandlers(store, components) {
|
|
28
|
+
const handlers = {};
|
|
29
|
+
const seen = new Set();
|
|
30
|
+
const EVENT_KEYS = ['onClick', 'onDblClick', 'onEnter', 'onBlur'];
|
|
31
|
+
|
|
32
|
+
function scan(spec) {
|
|
33
|
+
if (!spec || typeof spec !== 'object') return;
|
|
34
|
+
for (const key of EVENT_KEYS) {
|
|
35
|
+
const target = spec[key];
|
|
36
|
+
if (typeof target === 'string' && target.startsWith('intent.')) {
|
|
37
|
+
const name = target.replace(/\(.*\)$/, '');
|
|
38
|
+
if (!seen.has(name)) {
|
|
39
|
+
seen.add(name);
|
|
40
|
+
handlers[name] = (arg, event) => {
|
|
41
|
+
store.set(name, arg instanceof Event ? Date.now() : (arg ?? Date.now()));
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
// Recurse into templates and template children
|
|
47
|
+
if (spec.template) scan(spec.template);
|
|
48
|
+
if (Array.isArray(spec.template?.children)) {
|
|
49
|
+
spec.template.children.forEach(scan);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
Object.values(components).forEach(scan);
|
|
54
|
+
return handlers;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
// ─── Boot ───────────────────────────────────────────────────────
|
|
58
|
+
|
|
59
|
+
// 1. Resolve component tree + flatten into store
|
|
60
|
+
const spec = resolveTree(c, 'app');
|
|
61
|
+
const { nodes } = flatten(spec, store, 'view');
|
|
62
|
+
const refs = buildRefs(nodes);
|
|
63
|
+
|
|
64
|
+
// 2. Mount reactive subscribers (order: derived, policies, intents)
|
|
65
|
+
mountDerived(store);
|
|
66
|
+
mountPolicies(store);
|
|
67
|
+
mountIntents(store, refs);
|
|
68
|
+
|
|
69
|
+
// 3. Build handlers from registry (plain object, fully inspectable)
|
|
70
|
+
const handlers = intentHandlers(store, c);
|
|
71
|
+
console.log('[004_08 intent handlers]', Object.keys(handlers));
|
|
72
|
+
|
|
73
|
+
// 4. Mount DOM
|
|
74
|
+
mount(store, 'view', document.getElementById('app'), handlers);
|
|
75
|
+
|
|
76
|
+
// 5. Perf overlay
|
|
77
|
+
const perf = createPerfMonitor(store);
|
|
78
|
+
mountOverlay(perf, document.body);
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { ul, li, span, button } from "./utils/elements.js";
|
|
2
|
+
|
|
3
|
+
export const appDetailQuotes = {
|
|
4
|
+
...ul,
|
|
5
|
+
class: 'detail-quotes',
|
|
6
|
+
forEach: 'derived.filteredQuotes', as: 'item',
|
|
7
|
+
template: {
|
|
8
|
+
...li,
|
|
9
|
+
class: 'quote-item',
|
|
10
|
+
children: [
|
|
11
|
+
{ ...span, class: 'quote-text', text: 'item.text' },
|
|
12
|
+
{ ...button, class: 'fav-btn', classIf: { 'is-fav': 'item.fav' }, text: '♥', onClick: 'intent.toggleFav(item.id)' }
|
|
13
|
+
]
|
|
14
|
+
}
|
|
15
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { ul, li, span } from "./utils/elements.js";
|
|
2
|
+
|
|
3
|
+
export const appLogList = {
|
|
4
|
+
...ul,
|
|
5
|
+
class: 'log-list',
|
|
6
|
+
forEach: 'derived.activityLog', as: 'entry',
|
|
7
|
+
template: {
|
|
8
|
+
...li,
|
|
9
|
+
class: 'log-entry',
|
|
10
|
+
children: [
|
|
11
|
+
{ ...span, class: 'log-time', text: 'entry.time' },
|
|
12
|
+
{ ...span, class: 'log-intent', text: 'entry.intent' },
|
|
13
|
+
{ ...span, class: 'log-value', text: 'entry.value' },
|
|
14
|
+
]
|
|
15
|
+
}
|
|
16
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { div, button } from "./utils/elements.js";
|
|
2
|
+
import { cssClasses } from "./utils/css.js";
|
|
3
|
+
|
|
4
|
+
export const appTagsRow = {
|
|
5
|
+
...div,
|
|
6
|
+
class: 'tags-row',
|
|
7
|
+
forEach: 'state.authors',
|
|
8
|
+
as: 'author',
|
|
9
|
+
template: {
|
|
10
|
+
...button,
|
|
11
|
+
class: 'tag',
|
|
12
|
+
text: 'author',
|
|
13
|
+
onClick: 'intent.selectAuthor(author)'
|
|
14
|
+
}
|
|
15
|
+
}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
// components/index.js
|
|
2
|
+
import { appHeader } from "./appHeader.js";
|
|
3
|
+
import { appHeaderTitle } from './appHeaderTitle.js';
|
|
4
|
+
import { appHeaderSubtitle } from './appHeaderSubtitle.js';
|
|
5
|
+
import { appSearch } from './appSearch.js';
|
|
6
|
+
import { appSearchInput } from './appSearchInput.js';
|
|
7
|
+
import { appTags } from './appTags.js';
|
|
8
|
+
import { appTagsLabel } from './appTagsLabel.js';
|
|
9
|
+
import { appTagsRow } from './appTagsRow.js';
|
|
10
|
+
import { appDetail } from './appDetail.js';
|
|
11
|
+
import { appDetailBar } from './appDetailBar.js';
|
|
12
|
+
import { appDetailBarHeading } from './appDetailBarHeading.js';
|
|
13
|
+
import { appDetailBarCount } from './appDetailBarCount.js';
|
|
14
|
+
import { appDetailBarClose } from './appDetailBarClose.js';
|
|
15
|
+
import { appDetailQuotes } from './appDetailQuotes.js';
|
|
16
|
+
import { appStats } from './appStats.js';
|
|
17
|
+
import { appStatsToggle } from './appStatsToggle.js';
|
|
18
|
+
import { appStatsContent } from './appStatsContent.js';
|
|
19
|
+
import { appStatsContentText } from './appStatsContentText.js';
|
|
20
|
+
import { appStatsContentFavcount } from './appStatsContentFavcount.js';
|
|
21
|
+
import { appLog } from "./appLog.js";
|
|
22
|
+
import { appLogHeading } from "./appLogHeading.js";
|
|
23
|
+
import { appLogList } from "./appLogList.js";
|
|
24
|
+
|
|
25
|
+
export {
|
|
26
|
+
appHeader,
|
|
27
|
+
appHeaderTitle,
|
|
28
|
+
appHeaderSubtitle,
|
|
29
|
+
appSearch,
|
|
30
|
+
appSearchInput,
|
|
31
|
+
appTags,
|
|
32
|
+
appTagsLabel,
|
|
33
|
+
appTagsRow,
|
|
34
|
+
appDetail,
|
|
35
|
+
appDetailBar,
|
|
36
|
+
appDetailBarHeading,
|
|
37
|
+
appDetailBarCount,
|
|
38
|
+
appDetailBarClose,
|
|
39
|
+
appDetailQuotes,
|
|
40
|
+
appStats,
|
|
41
|
+
appStatsToggle,
|
|
42
|
+
appStatsContent,
|
|
43
|
+
appStatsContentText,
|
|
44
|
+
appStatsContentFavcount,
|
|
45
|
+
appLog,
|
|
46
|
+
appLogHeading,
|
|
47
|
+
appLogList,
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
/*
|
|
51
|
+
// Optional: Group them logically
|
|
52
|
+
export const header = {
|
|
53
|
+
app: appHeader,
|
|
54
|
+
title: appHeaderTitle,
|
|
55
|
+
subtitle: appHeaderSubtitle
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
export const searchBar = appSearch;
|
|
59
|
+
*/
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
// Composable CSS classes
|
|
2
|
+
// Atomic building blocks. Each export is a minimal spec object representing a single css class
|
|
3
|
+
// Compose with obbject spread:
|
|
4
|
+
// { ...cssAppHeader }
|
|
5
|
+
// The state engine hydrates text, bindings, and handlers via
|
|
6
|
+
// dot-path addressing - elements don't need content at birth.
|
|
7
|
+
// Observer before observed.
|
|
8
|
+
|
|
9
|
+
export const cssClasses = {
|
|
10
|
+
appHeader: `
|
|
11
|
+
app-header
|
|
12
|
+
text-align-center
|
|
13
|
+
margin-bottom-2rem`,
|
|
14
|
+
appHeaderTitle: `
|
|
15
|
+
app-header-title
|
|
16
|
+
font-size-2rem
|
|
17
|
+
font-weight-700
|
|
18
|
+
background-linear-gradient-135deg-var-accent-a78bfa
|
|
19
|
+
background-clip-text
|
|
20
|
+
-webkit-background-clip-text
|
|
21
|
+
-webkit-text-fill-color-transparent`,
|
|
22
|
+
appHeaderSubtitle: `
|
|
23
|
+
app-header-subtitle
|
|
24
|
+
color-var-text-muted
|
|
25
|
+
font-size-0_85rem
|
|
26
|
+
margin-top-0_25rem
|
|
27
|
+
letter-spacing-0_04em`,
|
|
28
|
+
appSearch: `
|
|
29
|
+
app-search
|
|
30
|
+
margin-bottom-1_5rem`,
|
|
31
|
+
appSearchInput: `
|
|
32
|
+
app-search-input
|
|
33
|
+
width-100p
|
|
34
|
+
padding-0_7rem-1rem
|
|
35
|
+
background-var-surface
|
|
36
|
+
color-var-text
|
|
37
|
+
border-1px-solid-var-border
|
|
38
|
+
border-radius-var-radius
|
|
39
|
+
font-size-0_95rem
|
|
40
|
+
outline-none
|
|
41
|
+
transition-border-color-0_2s`,
|
|
42
|
+
appTags: `
|
|
43
|
+
app-tags
|
|
44
|
+
margin-bottom-1_5rem`,
|
|
45
|
+
appTagsLabel: `
|
|
46
|
+
app-tags-label
|
|
47
|
+
display-block
|
|
48
|
+
font-size-0_8rem
|
|
49
|
+
color-var-text-muted
|
|
50
|
+
margin-bottom-0_5rem
|
|
51
|
+
text-transform-uppercase
|
|
52
|
+
letter-spacing-0_06em`,
|
|
53
|
+
appTagsRow: `
|
|
54
|
+
app-tags-row
|
|
55
|
+
display-flex
|
|
56
|
+
flex-wrap
|
|
57
|
+
gap-0_5rem`,
|
|
58
|
+
tag: `
|
|
59
|
+
tag
|
|
60
|
+
padding-0_4rem-0_9rem
|
|
61
|
+
background-var-accent
|
|
62
|
+
color-white
|
|
63
|
+
border-none
|
|
64
|
+
border-radius-0_25rem
|
|
65
|
+
cursor-pointer
|
|
66
|
+
font-size-0_85rem
|
|
67
|
+
transition-background-0_2s`,
|
|
68
|
+
appDetail: `
|
|
69
|
+
app-detail
|
|
70
|
+
background-var-surface
|
|
71
|
+
border-1px-solid-var-border
|
|
72
|
+
border-radius-var-radius
|
|
73
|
+
padding-1_25rem
|
|
74
|
+
margin-bottom-1_5rem
|
|
75
|
+
animation-slideIn-0_25s-ease-out`,
|
|
76
|
+
appDetailBar: `
|
|
77
|
+
detail-bar
|
|
78
|
+
display-flex
|
|
79
|
+
align-items-center
|
|
80
|
+
gap-0_75rem
|
|
81
|
+
margin-bottom-1rem
|
|
82
|
+
padding-bottom-0_75rem
|
|
83
|
+
border-bottom-1px-solid-var-border`,
|
|
84
|
+
appDetailBarHeading: 'detail-bar-heading',
|
|
85
|
+
appDetailBarCount: 'detail-bar-count',
|
|
86
|
+
appDetailBarClose: 'detail-bar-close',
|
|
87
|
+
appDetailQuotes: 'detail-quotes',
|
|
88
|
+
}
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
// ─── Composable HTML Elements ────────────────────────────────────
|
|
2
|
+
// Atomic building blocks. Each export is a minimal spec object
|
|
3
|
+
// representing a single HTML element. Compose with object spread:
|
|
4
|
+
//
|
|
5
|
+
// { ...div, class: 'card', children: ['child1', 'child2'] }
|
|
6
|
+
//
|
|
7
|
+
// The state engine hydrates text, bindings, and handlers via
|
|
8
|
+
// dot-path addressing - elements don't need content at birth.
|
|
9
|
+
// Observer before observed.
|
|
10
|
+
|
|
11
|
+
// ── Document sections ──
|
|
12
|
+
export const header = { tag: 'header' };
|
|
13
|
+
export const footer = { tag: 'footer' };
|
|
14
|
+
export const main = { tag: 'main' };
|
|
15
|
+
export const nav = { tag: 'nav' };
|
|
16
|
+
export const section = { tag: 'section' };
|
|
17
|
+
export const article = { tag: 'article' };
|
|
18
|
+
export const aside = { tag: 'aside' };
|
|
19
|
+
|
|
20
|
+
// ── Headings ──
|
|
21
|
+
export const h1 = { tag: 'h1' };
|
|
22
|
+
export const h2 = { tag: 'h2' };
|
|
23
|
+
export const h3 = { tag: 'h3' };
|
|
24
|
+
export const h4 = { tag: 'h4' };
|
|
25
|
+
export const h5 = { tag: 'h5' };
|
|
26
|
+
export const h6 = { tag: 'h6' };
|
|
27
|
+
|
|
28
|
+
// ── Block content ──
|
|
29
|
+
export const div = { tag: 'div' };
|
|
30
|
+
export const p = { tag: 'p' };
|
|
31
|
+
export const blockquote = { tag: 'blockquote' };
|
|
32
|
+
export const pre = { tag: 'pre' };
|
|
33
|
+
export const code = { tag: 'code' };
|
|
34
|
+
export const hr = { tag: 'hr' };
|
|
35
|
+
|
|
36
|
+
// ── Inline content ──
|
|
37
|
+
export const span = { tag: 'span' };
|
|
38
|
+
export const a = { tag: 'a' };
|
|
39
|
+
export const strong = { tag: 'strong' };
|
|
40
|
+
export const em = { tag: 'em' };
|
|
41
|
+
export const small = { tag: 'small' };
|
|
42
|
+
export const mark = { tag: 'mark' };
|
|
43
|
+
export const time = { tag: 'time' };
|
|
44
|
+
export const abbr = { tag: 'abbr' };
|
|
45
|
+
|
|
46
|
+
// ── Lists ──
|
|
47
|
+
export const ul = { tag: 'ul' };
|
|
48
|
+
export const ol = { tag: 'ol' };
|
|
49
|
+
export const li = { tag: 'li' };
|
|
50
|
+
export const dl = { tag: 'dl' };
|
|
51
|
+
export const dt = { tag: 'dt' };
|
|
52
|
+
export const dd = { tag: 'dd' };
|
|
53
|
+
|
|
54
|
+
// ── Forms ──
|
|
55
|
+
export const form = { tag: 'form' };
|
|
56
|
+
export const input = { tag: 'input' };
|
|
57
|
+
export const textarea = { tag: 'textarea' };
|
|
58
|
+
export const select = { tag: 'select' };
|
|
59
|
+
export const option = { tag: 'option' };
|
|
60
|
+
export const label = { tag: 'label' };
|
|
61
|
+
export const fieldset = { tag: 'fieldset' };
|
|
62
|
+
export const legend = { tag: 'legend' };
|
|
63
|
+
export const button = { tag: 'button' };
|
|
64
|
+
export const output = { tag: 'output' };
|
|
65
|
+
|
|
66
|
+
// ── Media ──
|
|
67
|
+
export const img = { tag: 'img' };
|
|
68
|
+
export const video = { tag: 'video' };
|
|
69
|
+
export const audio = { tag: 'audio' };
|
|
70
|
+
export const canvas = { tag: 'canvas' };
|
|
71
|
+
export const svg = { tag: 'svg' };
|
|
72
|
+
|
|
73
|
+
// ── Table ──
|
|
74
|
+
export const table = { tag: 'table' };
|
|
75
|
+
export const thead = { tag: 'thead' };
|
|
76
|
+
export const tbody = { tag: 'tbody' };
|
|
77
|
+
export const tfoot = { tag: 'tfoot' };
|
|
78
|
+
export const tr = { tag: 'tr' };
|
|
79
|
+
export const th = { tag: 'th' };
|
|
80
|
+
export const td = { tag: 'td' };
|
|
81
|
+
|
|
82
|
+
// ── Interactive / Semantic ──
|
|
83
|
+
export const details = { tag: 'details' };
|
|
84
|
+
export const summary = { tag: 'summary' };
|
|
85
|
+
export const dialog = { tag: 'dialog' };
|
|
86
|
+
export const progress = { tag: 'progress' };
|
|
87
|
+
export const meter = { tag: 'meter' };
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
// Component registry
|
|
2
|
+
// Flat dot-path keyed specs. Every component is a resource.
|
|
3
|
+
// children/template are dot-path strings or inline objects.
|
|
4
|
+
//
|
|
5
|
+
// KEY CHANGE from 004_06:
|
|
6
|
+
// onClick targets use 'intent.*' directly instead of 'actions.*'.
|
|
7
|
+
// The view engine's auto-intent handler writes the resolved arg
|
|
8
|
+
// to the store at the intent path. No actions.js file needed.
|
|
9
|
+
//
|
|
10
|
+
// {path} interpolation reads from the store at mount time.
|
|
11
|
+
// ref: stable handle for intent handlers to toggle view node classes.
|
|
12
|
+
// bind: two-way binding to a store path (no action needed).
|
|
13
|
+
|
|
14
|
+
import {
|
|
15
|
+
appHeader,
|
|
16
|
+
appHeaderTitle,
|
|
17
|
+
appHeaderSubtitle,
|
|
18
|
+
appSearch,
|
|
19
|
+
appSearchInput,
|
|
20
|
+
appTags,
|
|
21
|
+
appTagsLabel,
|
|
22
|
+
appTagsRow,
|
|
23
|
+
appDetail,
|
|
24
|
+
appDetailBar,
|
|
25
|
+
appDetailBarHeading,
|
|
26
|
+
appDetailBarCount,
|
|
27
|
+
appDetailBarClose,
|
|
28
|
+
appDetailQuotes,
|
|
29
|
+
appStats,
|
|
30
|
+
appStatsToggle,
|
|
31
|
+
appStatsContent,
|
|
32
|
+
appStatsContentText,
|
|
33
|
+
appStatsContentFavcount,
|
|
34
|
+
appLog,
|
|
35
|
+
appLogHeading,
|
|
36
|
+
appLogList,
|
|
37
|
+
} from "./components/index.js";
|
|
38
|
+
|
|
39
|
+
export const c = {
|
|
40
|
+
// Root
|
|
41
|
+
'app': {
|
|
42
|
+
tag: 'div', class: 'app',
|
|
43
|
+
children: ['app.header', 'app.search', 'app.tags', 'app.detail', 'app.stats', 'app.log']
|
|
44
|
+
},
|
|
45
|
+
|
|
46
|
+
// Header
|
|
47
|
+
'app.header': appHeader,
|
|
48
|
+
'app.header.title': appHeaderTitle,
|
|
49
|
+
'app.header.subtitle': appHeaderSubtitle,
|
|
50
|
+
|
|
51
|
+
// Search (two-way bind - no action needed)
|
|
52
|
+
'app.search': appSearch,
|
|
53
|
+
'app.search.input': appSearchInput,
|
|
54
|
+
|
|
55
|
+
// Author Tags
|
|
56
|
+
'app.tags': appTags,
|
|
57
|
+
'app.tags.label': appTagsLabel,
|
|
58
|
+
'app.tags.row': appTagsRow,
|
|
59
|
+
|
|
60
|
+
// Detail Panel (conditional - hidden by default)
|
|
61
|
+
'app.detail': appDetail,
|
|
62
|
+
'app.detail.bar': appDetailBar,
|
|
63
|
+
'app.detail.bar.heading': appDetailBarHeading,
|
|
64
|
+
'app.detail.bar.count': appDetailBarCount,
|
|
65
|
+
'app.detail.bar.close': appDetailBarClose,
|
|
66
|
+
'app.detail.quotes': appDetailQuotes,
|
|
67
|
+
|
|
68
|
+
// Stats Section (conditional toggle)
|
|
69
|
+
'app.stats': appStats,
|
|
70
|
+
'app.stats.toggle': appStatsToggle,
|
|
71
|
+
'app.stats.content': appStatsContent,
|
|
72
|
+
'app.stats.content.text': appStatsContentText,
|
|
73
|
+
'app.stats.content.favcount': appStatsContentFavcount,
|
|
74
|
+
|
|
75
|
+
// Activity Log (policy-driven via intent.* wildcard)
|
|
76
|
+
'app.log': appLog,
|
|
77
|
+
'app.log.heading': appLogHeading,
|
|
78
|
+
'app.log.list': appLogList,
|
|
79
|
+
};
|