@adaas/are-html 0.0.23 → 0.0.24
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/dist/browser/index.d.mts +18 -2
- package/dist/browser/index.mjs +35 -10
- package/dist/browser/index.mjs.map +1 -1
- package/dist/node/directives/AreDirectiveIf.directive.d.mts +17 -1
- package/dist/node/directives/AreDirectiveIf.directive.d.ts +17 -1
- package/dist/node/directives/AreDirectiveIf.directive.js +29 -6
- package/dist/node/directives/AreDirectiveIf.directive.js.map +1 -1
- package/dist/node/directives/AreDirectiveIf.directive.mjs +29 -6
- package/dist/node/directives/AreDirectiveIf.directive.mjs.map +1 -1
- package/dist/node/engine/AreHTML.compiler.d.mts +3 -1
- package/dist/node/engine/AreHTML.compiler.d.ts +3 -1
- package/dist/node/engine/AreHTML.compiler.js +7 -4
- package/dist/node/engine/AreHTML.compiler.js.map +1 -1
- package/dist/node/engine/AreHTML.compiler.mjs +7 -4
- package/dist/node/engine/AreHTML.compiler.mjs.map +1 -1
- package/examples/for-perf/dist/index.html +1 -1
- package/examples/for-perf/dist/{mqj1mpf2-z4aokv.js → mqp8i2py-vltsx0.js} +2488 -2373
- package/examples/lazy-loading/README.md +76 -0
- package/examples/lazy-loading/concept.ts +55 -0
- package/examples/lazy-loading/containers/UI.container.ts +215 -0
- package/examples/lazy-loading/dist/app.js +3803 -0
- package/examples/{for-perf/dist/mqj1mpff-4fr7mw.js → lazy-loading/dist/chunks/chunk-6K72IBO4.js} +2688 -5897
- package/examples/lazy-loading/dist/index.html +36 -0
- package/examples/lazy-loading/dist/lazy/about-page.js +59 -0
- package/examples/lazy-loading/dist/lazy/reports-page.js +65 -0
- package/examples/lazy-loading/dist/lazy/settings-page.js +54 -0
- package/examples/lazy-loading/public/index.html +36 -0
- package/examples/lazy-loading/src/components/AppShell.component.ts +44 -0
- package/examples/lazy-loading/src/components/HomePage.component.ts +59 -0
- package/examples/lazy-loading/src/components/LazyOutlet.component.ts +108 -0
- package/examples/lazy-loading/src/components/NavBar.component.ts +98 -0
- package/examples/lazy-loading/src/concept.ts +116 -0
- package/examples/lazy-loading/src/lazy/AboutPage.component.ts +54 -0
- package/examples/lazy-loading/src/lazy/ReportsPage.component.ts +56 -0
- package/examples/lazy-loading/src/lazy/SettingsPage.component.ts +45 -0
- package/examples/lazy-loading/src/runtime/ComponentManifest.fragment.ts +61 -0
- package/examples/lazy-loading/src/runtime/LazyComponentResolver.fragment.ts +77 -0
- package/examples/os-desktop/README.md +91 -0
- package/examples/os-desktop/concept.ts +54 -0
- package/examples/os-desktop/containers/OS.container.ts +198 -0
- package/examples/os-desktop/containers/apps/AppBackend.ts +29 -0
- package/examples/os-desktop/containers/apps/GanttApp.backend.ts +56 -0
- package/examples/os-desktop/containers/apps/MarketingApp.backend.ts +68 -0
- package/examples/os-desktop/dist/app.js +4410 -0
- package/examples/os-desktop/dist/apps/gantt/app.js +271 -0
- package/examples/os-desktop/dist/apps/marketing/app.js +346 -0
- package/examples/os-desktop/dist/chunks/chunk-6K72IBO4.js +12455 -0
- package/examples/os-desktop/dist/chunks/chunk-EIIGUL6N.js +30 -0
- package/examples/os-desktop/dist/chunks/chunk-WOH7L5UR.js +30 -0
- package/examples/os-desktop/dist/index.html +33 -0
- package/examples/os-desktop/public/index.html +33 -0
- package/examples/os-desktop/src/apps/gantt/GanttApp.component.ts +41 -0
- package/examples/os-desktop/src/apps/gantt/GanttChart.component.ts +126 -0
- package/examples/os-desktop/src/apps/gantt/GanttStore.ts +47 -0
- package/examples/os-desktop/src/apps/gantt/GanttToolbar.component.ts +73 -0
- package/examples/os-desktop/src/apps/gantt/index.ts +13 -0
- package/examples/os-desktop/src/apps/marketing/MarketingApp.component.ts +53 -0
- package/examples/os-desktop/src/apps/marketing/MarketingStore.ts +34 -0
- package/examples/os-desktop/src/apps/marketing/PostEditor.component.ts +153 -0
- package/examples/os-desktop/src/apps/marketing/PostPreview.component.ts +110 -0
- package/examples/os-desktop/src/apps/marketing/index.ts +16 -0
- package/examples/os-desktop/src/concept.ts +126 -0
- package/examples/os-desktop/src/os/AppStage.component.ts +112 -0
- package/examples/os-desktop/src/os/AppWindow.component.ts +102 -0
- package/examples/os-desktop/src/os/Desktop.component.ts +106 -0
- package/examples/os-desktop/src/os/Dock.component.ts +174 -0
- package/examples/os-desktop/src/os/Hud.component.ts +83 -0
- package/examples/os-desktop/src/os/Launchpad.component.ts +191 -0
- package/examples/os-desktop/src/os/MenuBar.component.ts +156 -0
- package/examples/os-desktop/src/runtime/AppComponentResolver.fragment.ts +121 -0
- package/examples/os-desktop/src/runtime/AppRegistry.fragment.ts +104 -0
- package/examples/os-desktop/src/signals/MouseState.signal.ts +34 -0
- package/examples/os-desktop/src/signals/OSRoute.signal.ts +37 -0
- package/examples/os-desktop/src/signals/SelectionState.signal.ts +34 -0
- package/examples/signal-routing/dist/index.html +1 -1
- package/examples/signal-routing/dist/{mqiwo23h-bhcolu.js → mqp8hgce-4d6rh0.js} +2911 -2708
- package/package.json +11 -7
- package/src/directives/AreDirectiveIf.directive.ts +33 -4
- package/src/engine/AreHTML.compiler.ts +12 -2
- package/tests/PropPropagation.test.ts +181 -0
- package/tests/jest.setup.ts +11 -0
|
@@ -0,0 +1,271 @@
|
|
|
1
|
+
import {
|
|
2
|
+
MouseState
|
|
3
|
+
} from "../../chunks/chunk-EIIGUL6N.js";
|
|
4
|
+
import {
|
|
5
|
+
A_Logger,
|
|
6
|
+
Are,
|
|
7
|
+
Yt,
|
|
8
|
+
__decorateClass,
|
|
9
|
+
__decorateParam,
|
|
10
|
+
__name,
|
|
11
|
+
te
|
|
12
|
+
} from "../../chunks/chunk-6K72IBO4.js";
|
|
13
|
+
|
|
14
|
+
// examples/os-desktop/src/apps/gantt/GanttApp.component.ts
|
|
15
|
+
var _GanttApp = class _GanttApp extends Are {
|
|
16
|
+
template(node) {
|
|
17
|
+
node.setContent(`
|
|
18
|
+
<div class="gt">
|
|
19
|
+
<div class="gt-head">
|
|
20
|
+
<h2>Project Timeline</h2>
|
|
21
|
+
<span class="gt-be">backend \xB7 <code>/apps/gantt/api</code></span>
|
|
22
|
+
</div>
|
|
23
|
+
<gantt-toolbar></gantt-toolbar>
|
|
24
|
+
<gantt-chart></gantt-chart>
|
|
25
|
+
</div>
|
|
26
|
+
`);
|
|
27
|
+
}
|
|
28
|
+
styles(node) {
|
|
29
|
+
node.setStyles(`
|
|
30
|
+
gantt-toolbar, gantt-chart { display: block; }
|
|
31
|
+
.gt { display: flex; flex-direction: column; height: 100%; color: #ececf1; }
|
|
32
|
+
.gt-head {
|
|
33
|
+
display: flex; align-items: baseline; justify-content: space-between;
|
|
34
|
+
padding: 18px 24px; border-bottom: 1px solid rgba(255,255,255,0.07);
|
|
35
|
+
}
|
|
36
|
+
.gt-head h2 { font-size: 18px; font-weight: 700; }
|
|
37
|
+
.gt-be { font-size: 11px; color: #7fa0c8; }
|
|
38
|
+
.gt-be code { color: #b8d4ff; }
|
|
39
|
+
`);
|
|
40
|
+
}
|
|
41
|
+
};
|
|
42
|
+
__name(_GanttApp, "GanttApp");
|
|
43
|
+
__decorateClass([
|
|
44
|
+
Are.Template,
|
|
45
|
+
__decorateParam(0, Yt(te))
|
|
46
|
+
], _GanttApp.prototype, "template", 1);
|
|
47
|
+
__decorateClass([
|
|
48
|
+
Are.Styles,
|
|
49
|
+
__decorateParam(0, Yt(te))
|
|
50
|
+
], _GanttApp.prototype, "styles", 1);
|
|
51
|
+
var GanttApp = _GanttApp;
|
|
52
|
+
|
|
53
|
+
// examples/os-desktop/src/apps/gantt/GanttStore.ts
|
|
54
|
+
var _GanttStoreImpl = class _GanttStoreImpl {
|
|
55
|
+
constructor() {
|
|
56
|
+
this._tasks = [];
|
|
57
|
+
this._listeners = /* @__PURE__ */ new Set();
|
|
58
|
+
}
|
|
59
|
+
get tasks() {
|
|
60
|
+
return this._tasks;
|
|
61
|
+
}
|
|
62
|
+
set(tasks) {
|
|
63
|
+
this._tasks = tasks;
|
|
64
|
+
this.emit();
|
|
65
|
+
}
|
|
66
|
+
add(task) {
|
|
67
|
+
this._tasks = [...this._tasks, task];
|
|
68
|
+
this.emit();
|
|
69
|
+
}
|
|
70
|
+
subscribe(listener) {
|
|
71
|
+
this._listeners.add(listener);
|
|
72
|
+
return () => this._listeners.delete(listener);
|
|
73
|
+
}
|
|
74
|
+
emit() {
|
|
75
|
+
for (const listener of this._listeners) listener();
|
|
76
|
+
}
|
|
77
|
+
};
|
|
78
|
+
__name(_GanttStoreImpl, "GanttStoreImpl");
|
|
79
|
+
var GanttStoreImpl = _GanttStoreImpl;
|
|
80
|
+
var GanttStore = new GanttStoreImpl();
|
|
81
|
+
|
|
82
|
+
// examples/os-desktop/src/apps/gantt/GanttToolbar.component.ts
|
|
83
|
+
var COLORS = ["#5b8def", "#34c759", "#ff9f0a", "#bf5af2", "#ff375f", "#64d2ff"];
|
|
84
|
+
var NAMES = ["Discovery", "Design", "Build", "Review", "QA", "Launch", "Retro"];
|
|
85
|
+
var _GanttToolbar = class _GanttToolbar extends Are {
|
|
86
|
+
template(node) {
|
|
87
|
+
node.setContent(`
|
|
88
|
+
<div class="tb">
|
|
89
|
+
<button class="tb-btn tb-add" @click="$add()">\uFF0B Add task</button>
|
|
90
|
+
<button class="tb-btn" @click="$reload()">\u21BB Reload from backend</button>
|
|
91
|
+
<span class="tb-hint">Tasks are served by the Gantt app's own backend.</span>
|
|
92
|
+
</div>
|
|
93
|
+
`);
|
|
94
|
+
}
|
|
95
|
+
add() {
|
|
96
|
+
const tracks = GanttStore.tasks.length;
|
|
97
|
+
const start = Math.floor(Math.random() * 20);
|
|
98
|
+
const task = {
|
|
99
|
+
id: `t-${Date.now()}`,
|
|
100
|
+
name: NAMES[Math.floor(Math.random() * NAMES.length)],
|
|
101
|
+
start,
|
|
102
|
+
end: start + 3 + Math.floor(Math.random() * 6),
|
|
103
|
+
color: COLORS[tracks % COLORS.length],
|
|
104
|
+
track: tracks
|
|
105
|
+
};
|
|
106
|
+
GanttStore.add(task);
|
|
107
|
+
}
|
|
108
|
+
async reload(logger) {
|
|
109
|
+
try {
|
|
110
|
+
const res = await fetch("/apps/gantt/api/tasks");
|
|
111
|
+
const data = await res.json();
|
|
112
|
+
if (Array.isArray(data.tasks)) GanttStore.set(data.tasks);
|
|
113
|
+
} catch (error) {
|
|
114
|
+
logger.error(error);
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
styles(node) {
|
|
118
|
+
node.setStyles(`
|
|
119
|
+
.tb {
|
|
120
|
+
display: flex; align-items: center; gap: 10px;
|
|
121
|
+
padding: 14px 24px; border-bottom: 1px solid rgba(255,255,255,0.07);
|
|
122
|
+
}
|
|
123
|
+
.tb-btn {
|
|
124
|
+
padding: 7px 13px; border: 1px solid rgba(255,255,255,0.14);
|
|
125
|
+
border-radius: 9px; background: rgba(255,255,255,0.06);
|
|
126
|
+
color: #ececf1; font-size: 13px; font-weight: 600; cursor: pointer;
|
|
127
|
+
}
|
|
128
|
+
.tb-btn:hover { background: rgba(255,255,255,0.12); }
|
|
129
|
+
.tb-add { background: #2f6df6; border-color: transparent; }
|
|
130
|
+
.tb-hint { font-size: 11px; color: #7d889a; margin-left: auto; }
|
|
131
|
+
`);
|
|
132
|
+
}
|
|
133
|
+
};
|
|
134
|
+
__name(_GanttToolbar, "GanttToolbar");
|
|
135
|
+
__decorateClass([
|
|
136
|
+
Are.Template,
|
|
137
|
+
__decorateParam(0, Yt(te))
|
|
138
|
+
], _GanttToolbar.prototype, "template", 1);
|
|
139
|
+
__decorateClass([
|
|
140
|
+
Are.EventHandler
|
|
141
|
+
], _GanttToolbar.prototype, "add", 1);
|
|
142
|
+
__decorateClass([
|
|
143
|
+
Are.EventHandler,
|
|
144
|
+
__decorateParam(0, Yt(A_Logger))
|
|
145
|
+
], _GanttToolbar.prototype, "reload", 1);
|
|
146
|
+
__decorateClass([
|
|
147
|
+
Are.Styles,
|
|
148
|
+
__decorateParam(0, Yt(te))
|
|
149
|
+
], _GanttToolbar.prototype, "styles", 1);
|
|
150
|
+
var GanttToolbar = _GanttToolbar;
|
|
151
|
+
|
|
152
|
+
// examples/os-desktop/src/apps/gantt/GanttChart.component.ts
|
|
153
|
+
var TOTAL_DAYS = 30;
|
|
154
|
+
var ROW_H = 30;
|
|
155
|
+
var _GanttChart = class _GanttChart extends Are {
|
|
156
|
+
template(node) {
|
|
157
|
+
const cols = Array.from({ length: TOTAL_DAYS / 5 }, (_, i) => `<div class="gc-col"><span>d${i * 5}</span></div>`).join("");
|
|
158
|
+
node.setContent(`
|
|
159
|
+
<div class="gc">
|
|
160
|
+
<div class="gc-grid">${cols}</div>
|
|
161
|
+
<div class="gc-bars"></div>
|
|
162
|
+
<div class="gc-cursor"></div>
|
|
163
|
+
</div>
|
|
164
|
+
`);
|
|
165
|
+
}
|
|
166
|
+
async onMount(logger) {
|
|
167
|
+
this._unsubscribe = GanttStore.subscribe(() => this.paint());
|
|
168
|
+
try {
|
|
169
|
+
const res = await fetch("/apps/gantt/api/tasks");
|
|
170
|
+
const data = await res.json();
|
|
171
|
+
GanttStore.set(Array.isArray(data.tasks) ? data.tasks : []);
|
|
172
|
+
} catch (error) {
|
|
173
|
+
logger.error(error);
|
|
174
|
+
this.paint();
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
onUnmount() {
|
|
178
|
+
this._unsubscribe?.();
|
|
179
|
+
this._unsubscribe = void 0;
|
|
180
|
+
}
|
|
181
|
+
onMouse(signal) {
|
|
182
|
+
const cursor = document.querySelector(".gc-cursor");
|
|
183
|
+
if (!cursor || !cursor.parentElement) return;
|
|
184
|
+
const rect = cursor.parentElement.getBoundingClientRect();
|
|
185
|
+
const x = Math.max(0, Math.min(signal.x - rect.left, rect.width));
|
|
186
|
+
cursor.style.left = `${x}px`;
|
|
187
|
+
}
|
|
188
|
+
paint() {
|
|
189
|
+
const bars = document.querySelector(".gc-bars");
|
|
190
|
+
if (!bars) return;
|
|
191
|
+
bars.style.height = `${Math.max(1, GanttStore.tasks.length) * ROW_H + 8}px`;
|
|
192
|
+
bars.innerHTML = GanttStore.tasks.map((task) => {
|
|
193
|
+
const left = task.start / TOTAL_DAYS * 100;
|
|
194
|
+
const width = (task.end - task.start) / TOTAL_DAYS * 100;
|
|
195
|
+
const top = task.track * ROW_H + 4;
|
|
196
|
+
return `
|
|
197
|
+
<div class="gc-bar" style="left:${left}%;width:${width}%;top:${top}px;background:${task.color}">
|
|
198
|
+
<span>${task.name}</span>
|
|
199
|
+
</div>
|
|
200
|
+
`;
|
|
201
|
+
}).join("");
|
|
202
|
+
}
|
|
203
|
+
styles(node) {
|
|
204
|
+
node.setStyles(`
|
|
205
|
+
.gc {
|
|
206
|
+
position: relative;
|
|
207
|
+
flex: 1;
|
|
208
|
+
margin: 18px 24px;
|
|
209
|
+
border-radius: 12px;
|
|
210
|
+
background: rgba(0,0,0,0.22);
|
|
211
|
+
border: 1px solid rgba(255,255,255,0.08);
|
|
212
|
+
overflow: hidden;
|
|
213
|
+
}
|
|
214
|
+
.gc-grid { position: absolute; inset: 0; display: flex; }
|
|
215
|
+
.gc-col {
|
|
216
|
+
flex: 1;
|
|
217
|
+
border-right: 1px dashed rgba(255,255,255,0.07);
|
|
218
|
+
padding: 6px 8px;
|
|
219
|
+
}
|
|
220
|
+
.gc-col span { font-size: 10px; color: #6f7a8c; font-family: ui-monospace, monospace; }
|
|
221
|
+
.gc-bars { position: relative; margin-top: 26px; }
|
|
222
|
+
.gc-bar {
|
|
223
|
+
position: absolute;
|
|
224
|
+
height: ${ROW_H - 8}px;
|
|
225
|
+
border-radius: 6px;
|
|
226
|
+
display: flex; align-items: center;
|
|
227
|
+
padding: 0 10px;
|
|
228
|
+
color: white; font-size: 12px; font-weight: 600;
|
|
229
|
+
box-shadow: 0 4px 12px rgba(0,0,0,0.3);
|
|
230
|
+
overflow: hidden; white-space: nowrap;
|
|
231
|
+
transition: left 0.2s, width 0.2s;
|
|
232
|
+
}
|
|
233
|
+
.gc-cursor {
|
|
234
|
+
position: absolute; top: 0; bottom: 0; left: 0; width: 2px;
|
|
235
|
+
background: rgba(255,255,255,0.55);
|
|
236
|
+
pointer-events: none;
|
|
237
|
+
box-shadow: 0 0 10px rgba(255,255,255,0.5);
|
|
238
|
+
}
|
|
239
|
+
`);
|
|
240
|
+
}
|
|
241
|
+
};
|
|
242
|
+
__name(_GanttChart, "GanttChart");
|
|
243
|
+
__decorateClass([
|
|
244
|
+
Are.Template,
|
|
245
|
+
__decorateParam(0, Yt(te))
|
|
246
|
+
], _GanttChart.prototype, "template", 1);
|
|
247
|
+
__decorateClass([
|
|
248
|
+
Are.onAfterMount,
|
|
249
|
+
__decorateParam(0, Yt(A_Logger))
|
|
250
|
+
], _GanttChart.prototype, "onMount", 1);
|
|
251
|
+
__decorateClass([
|
|
252
|
+
Are.onBeforeUnmount
|
|
253
|
+
], _GanttChart.prototype, "onUnmount", 1);
|
|
254
|
+
__decorateClass([
|
|
255
|
+
Are.Signal(MouseState),
|
|
256
|
+
__decorateParam(0, Yt(MouseState))
|
|
257
|
+
], _GanttChart.prototype, "onMouse", 1);
|
|
258
|
+
__decorateClass([
|
|
259
|
+
Are.Styles,
|
|
260
|
+
__decorateParam(0, Yt(te))
|
|
261
|
+
], _GanttChart.prototype, "styles", 1);
|
|
262
|
+
var GanttChart = _GanttChart;
|
|
263
|
+
|
|
264
|
+
// examples/os-desktop/src/apps/gantt/index.ts
|
|
265
|
+
var gantt_default = GanttApp;
|
|
266
|
+
export {
|
|
267
|
+
GanttApp,
|
|
268
|
+
GanttChart,
|
|
269
|
+
GanttToolbar,
|
|
270
|
+
gantt_default as default
|
|
271
|
+
};
|
|
@@ -0,0 +1,346 @@
|
|
|
1
|
+
import {
|
|
2
|
+
SelectionState
|
|
3
|
+
} from "../../chunks/chunk-WOH7L5UR.js";
|
|
4
|
+
import {
|
|
5
|
+
A_Logger,
|
|
6
|
+
Are,
|
|
7
|
+
AreEvent,
|
|
8
|
+
Yt,
|
|
9
|
+
__decorateClass,
|
|
10
|
+
__decorateParam,
|
|
11
|
+
__name,
|
|
12
|
+
te
|
|
13
|
+
} from "../../chunks/chunk-6K72IBO4.js";
|
|
14
|
+
|
|
15
|
+
// examples/os-desktop/src/apps/marketing/MarketingApp.component.ts
|
|
16
|
+
var _MarketingApp = class _MarketingApp extends Are {
|
|
17
|
+
template(node) {
|
|
18
|
+
node.setContent(`
|
|
19
|
+
<div class="mk">
|
|
20
|
+
<div class="mk-head">
|
|
21
|
+
<h2>LinkedIn Post Builder</h2>
|
|
22
|
+
<span class="mk-be">backend \xB7 <code>/apps/marketing/api</code></span>
|
|
23
|
+
</div>
|
|
24
|
+
<div class="mk-grid">
|
|
25
|
+
<post-editor></post-editor>
|
|
26
|
+
<post-preview></post-preview>
|
|
27
|
+
</div>
|
|
28
|
+
</div>
|
|
29
|
+
`);
|
|
30
|
+
}
|
|
31
|
+
styles(node) {
|
|
32
|
+
node.setStyles(`
|
|
33
|
+
post-editor, post-preview { display: contents; }
|
|
34
|
+
.mk { display: flex; flex-direction: column; height: 100%; color: #ececf1; }
|
|
35
|
+
.mk-head {
|
|
36
|
+
display: flex; align-items: baseline; justify-content: space-between;
|
|
37
|
+
padding: 18px 24px; border-bottom: 1px solid rgba(255,255,255,0.07);
|
|
38
|
+
}
|
|
39
|
+
.mk-head h2 { font-size: 18px; font-weight: 700; }
|
|
40
|
+
.mk-be { font-size: 11px; color: #8b7fb0; }
|
|
41
|
+
.mk-be code { color: #c9b8ff; }
|
|
42
|
+
.mk-grid {
|
|
43
|
+
flex: 1;
|
|
44
|
+
display: grid;
|
|
45
|
+
grid-template-columns: 1fr 1fr;
|
|
46
|
+
gap: 0;
|
|
47
|
+
min-height: 0;
|
|
48
|
+
}
|
|
49
|
+
`);
|
|
50
|
+
}
|
|
51
|
+
};
|
|
52
|
+
__name(_MarketingApp, "MarketingApp");
|
|
53
|
+
__decorateClass([
|
|
54
|
+
Are.Template,
|
|
55
|
+
__decorateParam(0, Yt(te))
|
|
56
|
+
], _MarketingApp.prototype, "template", 1);
|
|
57
|
+
__decorateClass([
|
|
58
|
+
Are.Styles,
|
|
59
|
+
__decorateParam(0, Yt(te))
|
|
60
|
+
], _MarketingApp.prototype, "styles", 1);
|
|
61
|
+
var MarketingApp = _MarketingApp;
|
|
62
|
+
|
|
63
|
+
// examples/os-desktop/src/apps/marketing/MarketingStore.ts
|
|
64
|
+
var _MarketingStoreImpl = class _MarketingStoreImpl {
|
|
65
|
+
constructor() {
|
|
66
|
+
this._text = "Thrilled to share that we shipped runtime app loading in our OS shell! \u{1F680}\n\nEach app is its own bundle + backend, loaded on demand. No redeploys, no reloads.";
|
|
67
|
+
this._listeners = /* @__PURE__ */ new Set();
|
|
68
|
+
}
|
|
69
|
+
get text() {
|
|
70
|
+
return this._text;
|
|
71
|
+
}
|
|
72
|
+
set(text) {
|
|
73
|
+
this._text = text;
|
|
74
|
+
for (const listener of this._listeners) {
|
|
75
|
+
listener();
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
subscribe(listener) {
|
|
79
|
+
this._listeners.add(listener);
|
|
80
|
+
return () => this._listeners.delete(listener);
|
|
81
|
+
}
|
|
82
|
+
};
|
|
83
|
+
__name(_MarketingStoreImpl, "MarketingStoreImpl");
|
|
84
|
+
var MarketingStoreImpl = _MarketingStoreImpl;
|
|
85
|
+
var MarketingStore = new MarketingStoreImpl();
|
|
86
|
+
|
|
87
|
+
// examples/os-desktop/src/apps/marketing/PostEditor.component.ts
|
|
88
|
+
var _PostEditor = class _PostEditor extends Are {
|
|
89
|
+
constructor() {
|
|
90
|
+
super(...arguments);
|
|
91
|
+
this._hashtags = [];
|
|
92
|
+
}
|
|
93
|
+
template(node) {
|
|
94
|
+
node.setContent(this.build());
|
|
95
|
+
}
|
|
96
|
+
edit(event) {
|
|
97
|
+
const el = event.get("native")?.target;
|
|
98
|
+
if (el) MarketingStore.set(el.value);
|
|
99
|
+
}
|
|
100
|
+
async suggest(logger) {
|
|
101
|
+
const btn = document.getElementById("pe-suggest");
|
|
102
|
+
if (btn) {
|
|
103
|
+
btn.disabled = true;
|
|
104
|
+
btn.textContent = "Asking backend\u2026";
|
|
105
|
+
}
|
|
106
|
+
try {
|
|
107
|
+
const topic = encodeURIComponent(MarketingStore.text.slice(0, 60));
|
|
108
|
+
const res = await fetch(`/apps/marketing/api/hashtags?topic=${topic}`);
|
|
109
|
+
const data = await res.json();
|
|
110
|
+
this._hashtags = Array.isArray(data.hashtags) ? data.hashtags : [];
|
|
111
|
+
} catch (error) {
|
|
112
|
+
logger.error(error);
|
|
113
|
+
this._hashtags = [];
|
|
114
|
+
}
|
|
115
|
+
if (btn) {
|
|
116
|
+
btn.disabled = false;
|
|
117
|
+
btn.textContent = "Suggest hashtags";
|
|
118
|
+
}
|
|
119
|
+
this.paintChips();
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Renders the suggested-hashtag chips imperatively. Each chip appends its
|
|
123
|
+
* tag to the app's store (and the textarea) via a native listener — the
|
|
124
|
+
* editor never re-renders, so the textarea keeps its caret and focus.
|
|
125
|
+
*/
|
|
126
|
+
paintChips() {
|
|
127
|
+
const host = document.getElementById("pe-chips");
|
|
128
|
+
if (!host) return;
|
|
129
|
+
host.innerHTML = "";
|
|
130
|
+
if (!this._hashtags.length) {
|
|
131
|
+
const empty = document.createElement("span");
|
|
132
|
+
empty.className = "pe-empty";
|
|
133
|
+
empty.textContent = "Click \u201CSuggest\u201D to ask the marketing backend for hashtags.";
|
|
134
|
+
host.appendChild(empty);
|
|
135
|
+
return;
|
|
136
|
+
}
|
|
137
|
+
for (const tag of this._hashtags) {
|
|
138
|
+
const chip = document.createElement("button");
|
|
139
|
+
chip.className = "pe-chip";
|
|
140
|
+
chip.textContent = `#${tag}`;
|
|
141
|
+
chip.addEventListener("click", () => this.appendTag(tag));
|
|
142
|
+
host.appendChild(chip);
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
appendTag(tag) {
|
|
146
|
+
MarketingStore.set(`${MarketingStore.text} #${tag}`);
|
|
147
|
+
const ta = document.querySelector(".pe-text");
|
|
148
|
+
if (ta) ta.value = MarketingStore.text;
|
|
149
|
+
}
|
|
150
|
+
build() {
|
|
151
|
+
return `
|
|
152
|
+
<section class="pe">
|
|
153
|
+
<label class="pe-label">Draft</label>
|
|
154
|
+
<textarea class="pe-text" @input="$edit()" spellcheck="false">${this.escape(MarketingStore.text)}</textarea>
|
|
155
|
+
<div class="pe-tools">
|
|
156
|
+
<button class="pe-suggest" id="pe-suggest" @click="$suggest()">Suggest hashtags</button>
|
|
157
|
+
</div>
|
|
158
|
+
<div class="pe-chips" id="pe-chips">
|
|
159
|
+
<span class="pe-empty">Click \u201CSuggest\u201D to ask the marketing backend for hashtags.</span>
|
|
160
|
+
</div>
|
|
161
|
+
</section>
|
|
162
|
+
`;
|
|
163
|
+
}
|
|
164
|
+
escape(text) {
|
|
165
|
+
return text.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">");
|
|
166
|
+
}
|
|
167
|
+
styles(node) {
|
|
168
|
+
node.setStyles(`
|
|
169
|
+
.pe {
|
|
170
|
+
display: flex;
|
|
171
|
+
flex-direction: column;
|
|
172
|
+
gap: 12px;
|
|
173
|
+
padding: 22px 24px;
|
|
174
|
+
border-right: 1px solid rgba(255,255,255,0.07);
|
|
175
|
+
min-height: 0;
|
|
176
|
+
}
|
|
177
|
+
.pe-label { font-size: 11px; text-transform: uppercase; letter-spacing: 0.08em; color: #8b7fb0; }
|
|
178
|
+
.pe-text {
|
|
179
|
+
flex: 1;
|
|
180
|
+
min-height: 200px;
|
|
181
|
+
resize: none;
|
|
182
|
+
padding: 14px 16px;
|
|
183
|
+
border-radius: 12px;
|
|
184
|
+
border: 1px solid rgba(255,255,255,0.1);
|
|
185
|
+
background: rgba(0,0,0,0.25);
|
|
186
|
+
color: #f2f2f5;
|
|
187
|
+
font-size: 14px;
|
|
188
|
+
line-height: 1.6;
|
|
189
|
+
font-family: inherit;
|
|
190
|
+
}
|
|
191
|
+
.pe-text:focus { outline: none; border-color: #7c6fd6; }
|
|
192
|
+
.pe-suggest {
|
|
193
|
+
padding: 9px 16px;
|
|
194
|
+
border: none;
|
|
195
|
+
border-radius: 10px;
|
|
196
|
+
background: #2f6df6;
|
|
197
|
+
color: white;
|
|
198
|
+
font-size: 13px;
|
|
199
|
+
font-weight: 600;
|
|
200
|
+
cursor: pointer;
|
|
201
|
+
}
|
|
202
|
+
.pe-suggest:disabled { opacity: 0.6; cursor: default; }
|
|
203
|
+
.pe-chips { display: flex; flex-wrap: wrap; gap: 6px; min-height: 24px; }
|
|
204
|
+
.pe-chip {
|
|
205
|
+
padding: 4px 10px;
|
|
206
|
+
border: 1px solid rgba(124,111,214,0.5);
|
|
207
|
+
border-radius: 999px;
|
|
208
|
+
background: rgba(124,111,214,0.14);
|
|
209
|
+
color: #c9b8ff;
|
|
210
|
+
font-size: 12px;
|
|
211
|
+
cursor: pointer;
|
|
212
|
+
}
|
|
213
|
+
.pe-chip:hover { background: rgba(124,111,214,0.28); }
|
|
214
|
+
.pe-empty { font-size: 12px; color: #6f6790; }
|
|
215
|
+
`);
|
|
216
|
+
}
|
|
217
|
+
};
|
|
218
|
+
__name(_PostEditor, "PostEditor");
|
|
219
|
+
__decorateClass([
|
|
220
|
+
Are.Template,
|
|
221
|
+
__decorateParam(0, Yt(te))
|
|
222
|
+
], _PostEditor.prototype, "template", 1);
|
|
223
|
+
__decorateClass([
|
|
224
|
+
Are.EventHandler,
|
|
225
|
+
__decorateParam(0, Yt(AreEvent))
|
|
226
|
+
], _PostEditor.prototype, "edit", 1);
|
|
227
|
+
__decorateClass([
|
|
228
|
+
Are.EventHandler,
|
|
229
|
+
__decorateParam(0, Yt(A_Logger))
|
|
230
|
+
], _PostEditor.prototype, "suggest", 1);
|
|
231
|
+
__decorateClass([
|
|
232
|
+
Are.Styles,
|
|
233
|
+
__decorateParam(0, Yt(te))
|
|
234
|
+
], _PostEditor.prototype, "styles", 1);
|
|
235
|
+
var PostEditor = _PostEditor;
|
|
236
|
+
|
|
237
|
+
// examples/os-desktop/src/apps/marketing/PostPreview.component.ts
|
|
238
|
+
var _PostPreview = class _PostPreview extends Are {
|
|
239
|
+
template(node) {
|
|
240
|
+
node.setContent(`
|
|
241
|
+
<article class="pp">
|
|
242
|
+
<header class="pp-top">
|
|
243
|
+
<div class="pp-avatar">A</div>
|
|
244
|
+
<div>
|
|
245
|
+
<div class="pp-name">ARE Platform</div>
|
|
246
|
+
<div class="pp-sub">Runtime \xB7 1m \xB7 \u{1F310}</div>
|
|
247
|
+
</div>
|
|
248
|
+
</header>
|
|
249
|
+
<p class="pp-body">${this.escape(MarketingStore.text)}</p>
|
|
250
|
+
<div class="pp-sel" hidden></div>
|
|
251
|
+
<footer class="pp-actions">
|
|
252
|
+
<span>\u{1F44D} Like</span><span>\u{1F4AC} Comment</span><span>\u21AA Share</span>
|
|
253
|
+
</footer>
|
|
254
|
+
</article>
|
|
255
|
+
`);
|
|
256
|
+
}
|
|
257
|
+
onMount() {
|
|
258
|
+
this._unsubscribe = MarketingStore.subscribe(() => {
|
|
259
|
+
const el = document.querySelector(".pp-body");
|
|
260
|
+
if (el) el.textContent = MarketingStore.text;
|
|
261
|
+
});
|
|
262
|
+
}
|
|
263
|
+
onUnmount() {
|
|
264
|
+
this._unsubscribe?.();
|
|
265
|
+
this._unsubscribe = void 0;
|
|
266
|
+
}
|
|
267
|
+
onSelection(signal) {
|
|
268
|
+
const el = document.querySelector(".pp-sel");
|
|
269
|
+
if (!el) return;
|
|
270
|
+
const text = signal.text.trim();
|
|
271
|
+
if (text.length) {
|
|
272
|
+
const tag = text.replace(/\s+/g, "").replace(/[^\w]/g, "").slice(0, 24);
|
|
273
|
+
el.hidden = false;
|
|
274
|
+
el.textContent = tag ? `Selected on desktop \u2192 add #${tag}` : `Selected ${signal.length} characters`;
|
|
275
|
+
} else {
|
|
276
|
+
el.hidden = true;
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
escape(text) {
|
|
280
|
+
return text.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">");
|
|
281
|
+
}
|
|
282
|
+
styles(node) {
|
|
283
|
+
node.setStyles(`
|
|
284
|
+
.pp {
|
|
285
|
+
margin: 22px 24px;
|
|
286
|
+
padding: 18px;
|
|
287
|
+
border-radius: 14px;
|
|
288
|
+
background: #ffffff;
|
|
289
|
+
color: #1d2226;
|
|
290
|
+
box-shadow: 0 12px 30px rgba(0,0,0,0.25);
|
|
291
|
+
align-self: start;
|
|
292
|
+
}
|
|
293
|
+
.pp-top { display: flex; align-items: center; gap: 12px; margin-bottom: 12px; }
|
|
294
|
+
.pp-avatar {
|
|
295
|
+
width: 44px; height: 44px; border-radius: 50%;
|
|
296
|
+
display: flex; align-items: center; justify-content: center;
|
|
297
|
+
background: #2f6df6; color: white; font-weight: 700;
|
|
298
|
+
}
|
|
299
|
+
.pp-name { font-weight: 700; font-size: 14px; }
|
|
300
|
+
.pp-sub { font-size: 12px; color: #66707a; }
|
|
301
|
+
.pp-body { font-size: 14px; line-height: 1.55; white-space: pre-wrap; word-break: break-word; }
|
|
302
|
+
.pp-sel {
|
|
303
|
+
margin-top: 12px;
|
|
304
|
+
padding: 8px 12px;
|
|
305
|
+
border-radius: 8px;
|
|
306
|
+
background: #eaf1ff;
|
|
307
|
+
color: #2f6df6;
|
|
308
|
+
font-size: 12px;
|
|
309
|
+
font-weight: 600;
|
|
310
|
+
}
|
|
311
|
+
.pp-actions {
|
|
312
|
+
display: flex; gap: 18px; margin-top: 14px; padding-top: 12px;
|
|
313
|
+
border-top: 1px solid #e6e9ec; color: #66707a; font-size: 13px; font-weight: 600;
|
|
314
|
+
}
|
|
315
|
+
`);
|
|
316
|
+
}
|
|
317
|
+
};
|
|
318
|
+
__name(_PostPreview, "PostPreview");
|
|
319
|
+
__decorateClass([
|
|
320
|
+
Are.Template,
|
|
321
|
+
__decorateParam(0, Yt(te))
|
|
322
|
+
], _PostPreview.prototype, "template", 1);
|
|
323
|
+
__decorateClass([
|
|
324
|
+
Are.onAfterMount
|
|
325
|
+
], _PostPreview.prototype, "onMount", 1);
|
|
326
|
+
__decorateClass([
|
|
327
|
+
Are.onBeforeUnmount
|
|
328
|
+
], _PostPreview.prototype, "onUnmount", 1);
|
|
329
|
+
__decorateClass([
|
|
330
|
+
Are.Signal(SelectionState),
|
|
331
|
+
__decorateParam(0, Yt(SelectionState))
|
|
332
|
+
], _PostPreview.prototype, "onSelection", 1);
|
|
333
|
+
__decorateClass([
|
|
334
|
+
Are.Styles,
|
|
335
|
+
__decorateParam(0, Yt(te))
|
|
336
|
+
], _PostPreview.prototype, "styles", 1);
|
|
337
|
+
var PostPreview = _PostPreview;
|
|
338
|
+
|
|
339
|
+
// examples/os-desktop/src/apps/marketing/index.ts
|
|
340
|
+
var marketing_default = MarketingApp;
|
|
341
|
+
export {
|
|
342
|
+
MarketingApp,
|
|
343
|
+
PostEditor,
|
|
344
|
+
PostPreview,
|
|
345
|
+
marketing_default as default
|
|
346
|
+
};
|