mountain-ui 1.0.171 → 1.0.172

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.
Files changed (23) hide show
  1. package/package.json +1 -1
  2. package/src/lib/registry/navigationRegistry/components/Navbar.svelte +1 -3
  3. package/src/lib/registry/webComponentRegistry/components/WebComponent.svelte +27 -0
  4. package/src/lib/registry/webComponentRegistry/createWebComponent.js +619 -0
  5. package/src/lib/registry/webComponentRegistry/registerWebComponents.js +12 -0
  6. package/src/lib/registry/webComponentRegistry/registry.svelte.js +64 -0
  7. package/src/lib/registry/webComponentTypeRegistry/components/WebComponentType.svelte +18 -0
  8. package/src/lib/registry/webComponentTypeRegistry/createWebComponentType.js +59 -0
  9. package/src/lib/registry/webComponentTypeRegistry/registerWebComponentTypes.js +12 -0
  10. package/src/lib/registry/webComponentTypeRegistry/registry.svelte.js +42 -0
  11. package/src/lib/registry/webComponentTypeRegistry/webComponentTypes/Frame/Frame.svelte +7 -0
  12. package/src/lib/registry/webComponentTypeRegistry/webComponentTypes/Frame/index.js +52 -0
  13. package/src/lib/registry/webComponentTypeRegistry/webComponentTypes/Page/Page.svelte +259 -0
  14. package/src/lib/registry/webComponentTypeRegistry/webComponentTypes/Page/index.js +52 -0
  15. package/src/lib/registry/webPageRegistry/components/WebPage.svelte +14 -0
  16. package/src/lib/registry/webPageRegistry/createWebPage.js +22 -0
  17. package/src/lib/registry/webPageRegistry/registerWebPage.js +9 -0
  18. package/src/lib/registry/webPageRegistry/registry.svelte.js +106 -0
  19. package/src/lib/registry/webSite/components/Editor.svelte +11 -0
  20. package/src/lib/registry/webSite/createWebComponentType.js +13 -0
  21. package/src/lib/registry/webSite/registerWebComponentTypes.js +12 -0
  22. package/src/lib/registry/webSite/registry.svelte.js +42 -0
  23. package/src/routes/exemple/[project_normalized_name]/site-builder/+page.svelte +391 -0
@@ -0,0 +1,106 @@
1
+ import { writable, derived, get } from 'svelte/store';
2
+ import { webComponentRegistry } from '../webComponentRegistry/registry.svelte';
3
+
4
+ function createWebPageRegistry() {
5
+ const store = writable({});
6
+
7
+ const all = derived(store, ($webPages) => Object.values($webPages));
8
+
9
+ return {
10
+ subscribe: store.subscribe,
11
+
12
+ register(webPage) {
13
+ store.update((webPages) => ({
14
+ ...webPages,
15
+ [webPage.path]: webPage
16
+ }));
17
+ },
18
+
19
+ unregister(path) {
20
+ store.update((webPages) => {
21
+ const copy = { ...webPages };
22
+
23
+ delete copy[path];
24
+
25
+ return copy;
26
+ });
27
+ },
28
+
29
+ get(path) {
30
+ return get(store)[path];
31
+ },
32
+
33
+ select(path) {
34
+ return derived(store, ($webPages) => $webPages[path]);
35
+ },
36
+
37
+ getAll() {
38
+ return all;
39
+ },
40
+
41
+ update(path) {
42
+ store.update((webPages) => {
43
+ return webPages;
44
+ });
45
+ },
46
+
47
+ setRootChild(path, webComponent) {
48
+ store.update((webPages) => {
49
+ webComponent.id = webPages[path].AI
50
+ webPages[path].children = {
51
+ id: webComponent.id,
52
+ children: []
53
+ }
54
+ webPages[path].children_index[webComponent.id] = webComponent
55
+
56
+ // ajouter au registry
57
+ webComponentRegistry.register(webComponent)
58
+
59
+ webPages[path].AI++
60
+
61
+ return webPages;
62
+ });
63
+
64
+ },
65
+
66
+ addChildTo(path, id, newChild) {
67
+ store.update((webPages) => {
68
+ console.log(webPages[path]);
69
+
70
+ const el = webPages[path].children_index[id]
71
+
72
+ // trouver ou il est dans le three
73
+ let children = webPages[path].children
74
+
75
+ for (const parentId of el.path) {
76
+ children = children.children.find(c => c.id = parentId)
77
+ }
78
+
79
+ newChild.id = webPages[path].AI
80
+ webPages[path].AI++
81
+
82
+ children.children.push({
83
+ id: newChild.id,
84
+ children: []
85
+ })
86
+ el.children.push(newChild.id)
87
+ webPages[path].children_index[newChild.id] = newChild
88
+
89
+ webComponentRegistry.register(newChild)
90
+
91
+ return webPages
92
+ })
93
+ },
94
+
95
+ getChildrenIds(path, id) {
96
+ return derived(store, ($webPages) => {
97
+ return $webPages[path]?.children_index[id]?.children ?? [];
98
+ });
99
+ },
100
+
101
+
102
+
103
+ };
104
+ }
105
+
106
+ export const webPageRegistry = createWebPageRegistry();
@@ -0,0 +1,11 @@
1
+ <script>
2
+ import { webComponentTypeRegistry } from "../registry.svelte";
3
+
4
+ let {
5
+ type
6
+ } = $props()
7
+
8
+ const webComponentType = $derived(webComponentTypeRegistry.get(type))
9
+ </script>
10
+
11
+
@@ -0,0 +1,13 @@
1
+ import { sendRequest } from "hamzus-ui";
2
+ import { get } from "svelte/store";
3
+
4
+ export function createWebComponentType(config = {}) {
5
+ const webSite = {
6
+ name: "",
7
+ pages:[]
8
+ };
9
+
10
+ Object.assign(webSite, config);
11
+
12
+ return webSite;
13
+ }
@@ -0,0 +1,12 @@
1
+ import { sendRequest } from "hamzus-ui";
2
+ import { webSiteRegistry } from "./registry.svelte";
3
+ import { createWebSite } from "./createWebSite.js";
4
+
5
+ import Page from "./webSites/Page/index.js";
6
+ import Frame from "./webSites/Frame/index.js";
7
+
8
+
9
+ export async function registerWebSites() {
10
+ webSiteRegistry.register(Page)
11
+ webSiteRegistry.register(Frame)
12
+ }
@@ -0,0 +1,42 @@
1
+ import { writable, derived, get } from 'svelte/store';
2
+
3
+ function createWebComponentTypeRegistry() {
4
+ const store = writable({});
5
+
6
+ const all = derived(store, ($webComponentTypes) => Object.values($webComponentTypes));
7
+
8
+ return {
9
+ subscribe: store.subscribe,
10
+
11
+ register(webComponentType) {
12
+ store.update((webComponentTypes) => ({
13
+ ...webComponentTypes,
14
+ [webComponentType.type]: webComponentType
15
+ }));
16
+ },
17
+
18
+ unregister(type) {
19
+ store.update((webComponentTypes) => {
20
+ const copy = { ...webComponentTypes };
21
+
22
+ delete copy[type];
23
+
24
+ return copy;
25
+ });
26
+ },
27
+
28
+ get(type) {
29
+ return get(store)[type];
30
+ },
31
+
32
+ select(type) {
33
+ return derived(store, ($webComponentTypes) => $webComponentTypes[type]);
34
+ },
35
+
36
+ getAll() {
37
+ return all;
38
+ },
39
+ };
40
+ }
41
+
42
+ export const webComponentTypeRegistry = createWebComponentTypeRegistry();
@@ -0,0 +1,391 @@
1
+ <script>
2
+ import { updated } from '$app/state';
3
+ import { createWebComponent } from '$lib/registry/webComponentRegistry/createWebComponent';
4
+ import { webComponentRegistry } from '$lib/registry/webComponentRegistry/registry.svelte';
5
+ import { registerWebComponentTypes } from '$lib/registry/webComponentTypeRegistry/registerWebComponentTypes';
6
+ import { webComponentTypeRegistry } from '$lib/registry/webComponentTypeRegistry/registry.svelte';
7
+ import WebPage from '$lib/registry/webPageRegistry/components/WebPage.svelte';
8
+ import { createWebPage } from '$lib/registry/webPageRegistry/createWebPage';
9
+ import { webPageRegistry } from '$lib/registry/webPageRegistry/registry.svelte';
10
+ import { Button, IconButton } from 'hamzus-ui';
11
+ import { onMount } from 'svelte';
12
+
13
+ let isMounted = $state(false);
14
+
15
+ const activeWebComponent = $derived(webComponentRegistry.getActive());
16
+ const activeWebComponentType = $derived(webComponentTypeRegistry.select($activeWebComponent?.type));
17
+
18
+ onMount(() => {
19
+ registerWebComponentTypes();
20
+
21
+ const webPage = createWebPage({});
22
+
23
+ webPageRegistry.register(webPage);
24
+
25
+ webPageRegistry.setRootChild(
26
+ webPage.path,
27
+ createWebComponent({
28
+ id: null,
29
+ type: 'page',
30
+ children: [],
31
+ breakPoints: [
32
+ {
33
+ name: 'Default',
34
+ width: 1200
35
+ }
36
+ ],
37
+ scrollSection: {
38
+ enable: false,
39
+ name: '',
40
+ offsetY: 0
41
+ },
42
+ layout: {
43
+ type: 'stack', // stack | grid | null
44
+ stack: {
45
+ direction: 'column', // row | column
46
+ distribution: 'start',
47
+ alignement: 'start',
48
+ wrap: false
49
+ },
50
+ grid: {
51
+ type: 'fixed', // fixed | auto
52
+ cols: 2,
53
+ rows: 2
54
+ },
55
+ gap: {
56
+ x: 0,
57
+ y: 0
58
+ },
59
+ padding: {
60
+ top: 0,
61
+ right: 0,
62
+ bottom: 0,
63
+ left: 0
64
+ }
65
+ },
66
+ typography: {
67
+ content: 'exemple',
68
+ weigth: 'Regular', // thin | thin-italic | extra-light | extra-light-italic | light | light-italic | regular | italic | medium | medium-italic | semi-bold | semi-bold-italic | bold | bold-italic | extra-bold | extra-bold-italic | black | black-italic
69
+ fontSize: 16,
70
+ fontSizeType: 'px', // px | rem
71
+ letterSpacing: 0,
72
+ lineHeight: 16,
73
+ alignement: 'left', // left | center | right | justify
74
+ tag: 'p' // left | center | right | justify
75
+ },
76
+ // overlay
77
+ overlay: [],
78
+ // styles
79
+ style: {
80
+ opacity: 1,
81
+ visibilty: true,
82
+ fill: {
83
+ r: 0,
84
+ g: 0,
85
+ b: 0,
86
+ a: 1
87
+ },
88
+ overflow: 'visible', // visible | clip | hidden | scroll
89
+ borderRadius: {
90
+ tl: 0,
91
+ tr: 0,
92
+ br: 0,
93
+ bl: 0
94
+ },
95
+ border: {
96
+ r: 0,
97
+ g: 0,
98
+ b: 0,
99
+ a: 1
100
+ },
101
+ ZIndex: 1
102
+ },
103
+ // link
104
+ link: {
105
+ enable: false,
106
+ href: '',
107
+ newTab: true
108
+ },
109
+ // position
110
+ position: {
111
+ type: 'absolute', // absolute | relative | fixed | sticky
112
+ absolute: {
113
+ top: null,
114
+ left: null,
115
+ right: null,
116
+ bottom: null
117
+ },
118
+ fixed: {
119
+ top: null,
120
+ left: null,
121
+ right: null,
122
+ bottom: null
123
+ },
124
+ sticky: {
125
+ top: 0
126
+ }
127
+ },
128
+ // size
129
+ size: {
130
+ widthType: 'relative', // relative | fill | fixed | fit-content | viewport
131
+ width: 100,
132
+ heightType: 'relative', // relative | fill | fixed | fit-content | viewport
133
+ height: 100,
134
+ minWidthType: 'relative', // relative | fill | fixed | fit-content | viewport
135
+ minWidth: null,
136
+ maxWidthType: 'relative', // relative | fill | fixed | fit-content | viewport
137
+ maxWidth: null,
138
+ minHeightType: 'relative', // relative | fill | fixed | fit-content | viewport
139
+ minHeight: null,
140
+ maxHeightType: 'relative', // relative | fill | fixed | fit-content | viewport
141
+ maxHeight: null
142
+ }
143
+ })
144
+ );
145
+
146
+ console.log(webPage);
147
+
148
+ isMounted = true;
149
+ });
150
+
151
+ let zoom = $state(1);
152
+
153
+ let posX = $state(0);
154
+ let posY = $state(0);
155
+
156
+ let isPanning = $state(false);
157
+ let startX = $state(0);
158
+ let startY = $state(0);
159
+ let startPosX = $state(0);
160
+ let startPosY = $state(0);
161
+
162
+ function handleMouseDown(e) {
163
+ // Molette
164
+ if (e.button !== 1) return;
165
+ console.log('dsas');
166
+
167
+ e.preventDefault();
168
+
169
+ isPanning = true;
170
+
171
+ startX = e.clientX;
172
+ startY = e.clientY;
173
+
174
+ startPosX = posX;
175
+ startPosY = posY;
176
+ }
177
+
178
+ function handleMouseMove(e) {
179
+ if (!isPanning) return;
180
+
181
+ posX = startPosX + (e.clientX - startX);
182
+ posY = startPosY + (e.clientY - startY);
183
+ }
184
+
185
+ function handleMouseUp(e) {
186
+ if (e.button !== 1) return;
187
+
188
+ isPanning = false;
189
+ }
190
+
191
+ function handleZoomIn() {
192
+ zoom += 0.1;
193
+ }
194
+ function handleZoomOut() {
195
+ if (zoom === 0.1) return;
196
+ zoom -= 0.1;
197
+ }
198
+ function handleWheel(e) {
199
+ if (!e.ctrlKey) return;
200
+
201
+ e.preventDefault();
202
+
203
+ const rect = e.currentTarget.getBoundingClientRect();
204
+
205
+ // Position de la souris dans l'éditeur
206
+ const mouseX = e.clientX - rect.left;
207
+ const mouseY = e.clientY - rect.top;
208
+
209
+ // Ancien zoom
210
+ const oldZoom = zoom;
211
+
212
+ // Sens du zoom
213
+ const direction = e.deltaY < 0 ? 1 : -1;
214
+
215
+ const newZoom = Math.min(3, Math.max(0.1, oldZoom + direction * 0.1));
216
+
217
+ if (newZoom === oldZoom) return;
218
+
219
+ // Position du point sous la souris avant le zoom
220
+ const contentX = (mouseX - posX) / oldZoom;
221
+ const contentY = (mouseY - posY) / oldZoom;
222
+
223
+ zoom = newZoom;
224
+
225
+ // On repositionne pour garder le même point sous la souris
226
+ posX = mouseX - contentX * newZoom;
227
+ posY = mouseY - contentY * newZoom;
228
+ }
229
+ function handleClickOnNothing(e) {
230
+ if (e.target.closest(".right-bar")) {
231
+ return
232
+ }
233
+ webComponentRegistry.unsetActive();
234
+ }
235
+
236
+ function update(callback) {
237
+ callback()
238
+
239
+ webPageRegistry.update("/")
240
+ }
241
+ </script>
242
+
243
+ {#if isMounted}
244
+ <div
245
+ class="editor"
246
+ class:panning={isPanning}
247
+ onmousedown={handleMouseDown}
248
+ onmousemove={handleMouseMove}
249
+ onmouseup={handleMouseUp}
250
+ onmouseleave={handleMouseUp}
251
+ onwheel={handleWheel}
252
+ onclick={handleClickOnNothing}
253
+ >
254
+ <div class="pages" style="--pos-x:{posX}px;--pos-y:{posY}px;--zoom:{zoom};">
255
+ <WebPage path="/"></WebPage>
256
+ </div>
257
+ <div class="top-bar">
258
+ <IconButton onClick={handleZoomOut} variant="ghost" size="24px">
259
+ <svg
260
+ width="24"
261
+ height="24"
262
+ viewBox="0 0 24 24"
263
+ fill="none"
264
+ xmlns="http://www.w3.org/2000/svg"
265
+ >
266
+ <path
267
+ d="M14 12.45H9C8.59 12.45 8.25 12.11 8.25 11.7C8.25 11.29 8.59 10.95 9 10.95H14C14.41 10.95 14.75 11.29 14.75 11.7C14.75 12.11 14.41 12.45 14 12.45Z"
268
+ fill="#292D32"
269
+ />
270
+ <path
271
+ d="M11.5 21.75C5.85 21.75 1.25 17.15 1.25 11.5C1.25 5.85 5.85 1.25 11.5 1.25C17.15 1.25 21.75 5.85 21.75 11.5C21.75 17.15 17.15 21.75 11.5 21.75ZM11.5 2.75C6.67 2.75 2.75 6.68 2.75 11.5C2.75 16.32 6.67 20.25 11.5 20.25C16.33 20.25 20.25 16.32 20.25 11.5C20.25 6.68 16.33 2.75 11.5 2.75Z"
272
+ fill="#292D32"
273
+ />
274
+ <path
275
+ d="M22.0004 22.7499C21.8104 22.7499 21.6204 22.6799 21.4704 22.5299L19.4704 20.5299C19.1804 20.2399 19.1804 19.7599 19.4704 19.4699C19.7604 19.1799 20.2404 19.1799 20.5304 19.4699L22.5304 21.4699C22.8204 21.7599 22.8204 22.2399 22.5304 22.5299C22.3804 22.6799 22.1904 22.7499 22.0004 22.7499Z"
276
+ fill="#292D32"
277
+ />
278
+ </svg>
279
+ </IconButton>
280
+ <h5>{(zoom * 100).toFixed(2)}%</h5>
281
+ <IconButton onClick={handleZoomIn} variant="ghost" size="24px">
282
+ <svg
283
+ width="24"
284
+ height="24"
285
+ viewBox="0 0 24 24"
286
+ fill="none"
287
+ xmlns="http://www.w3.org/2000/svg"
288
+ >
289
+ <path
290
+ d="M14.2002 12.45H9.2002C8.7902 12.45 8.4502 12.11 8.4502 11.7C8.4502 11.29 8.7902 10.95 9.2002 10.95H14.2002C14.6102 10.95 14.9502 11.29 14.9502 11.7C14.9502 12.11 14.6102 12.45 14.2002 12.45Z"
291
+ fill="#292D32"
292
+ />
293
+ <path
294
+ d="M11.7002 14.95C11.2902 14.95 10.9502 14.61 10.9502 14.2V9.19995C10.9502 8.78995 11.2902 8.44995 11.7002 8.44995C12.1102 8.44995 12.4502 8.78995 12.4502 9.19995V14.2C12.4502 14.61 12.1102 14.95 11.7002 14.95Z"
295
+ fill="#292D32"
296
+ />
297
+ <path
298
+ d="M11.5 21.75C5.85 21.75 1.25 17.15 1.25 11.5C1.25 5.85 5.85 1.25 11.5 1.25C17.15 1.25 21.75 5.85 21.75 11.5C21.75 17.15 17.15 21.75 11.5 21.75ZM11.5 2.75C6.67 2.75 2.75 6.68 2.75 11.5C2.75 16.32 6.67 20.25 11.5 20.25C16.33 20.25 20.25 16.32 20.25 11.5C20.25 6.68 16.33 2.75 11.5 2.75Z"
299
+ fill="#292D32"
300
+ />
301
+ <path
302
+ d="M22.0004 22.7499C21.8104 22.7499 21.6204 22.6799 21.4704 22.5299L19.4704 20.5299C19.1804 20.2399 19.1804 19.7599 19.4704 19.4699C19.7604 19.1799 20.2404 19.1799 20.5304 19.4699L22.5304 21.4699C22.8204 21.7599 22.8204 22.2399 22.5304 22.5299C22.3804 22.6799 22.1904 22.7499 22.0004 22.7499Z"
303
+ fill="#292D32"
304
+ />
305
+ </svg>
306
+ </IconButton>
307
+ </div>
308
+
309
+ {#if $activeWebComponent}
310
+ <div class="right-bar">
311
+ {#if $activeWebComponentType}
312
+ {#if $activeWebComponentType.allowLayout}
313
+ <h5 class="title">Layout</h5>
314
+ <div class="grid-selector">
315
+ <Button onClick={()=>{update(()=>{$activeWebComponent.setLayout("grid")})}} variant="{$activeWebComponent.layout.type === "grid" ? "secondary" : "ghost"}" style="width:1fr;flex:1;justify-content:center;">
316
+ <h5>grille</h5>
317
+ </Button>
318
+ <Button onClick={()=>{update(()=>{$activeWebComponent.setLayout("stack")})}} variant="{$activeWebComponent.layout.type === "stack" ? "secondary" : "ghost"}" style="width:1fr;flex:1;justify-content:center;">
319
+ <h5>pile</h5>
320
+ </Button>
321
+ </div>
322
+ {/if}
323
+ {/if}
324
+ </div>
325
+ {/if}
326
+ </div>
327
+ {/if}
328
+
329
+ <style>
330
+ .editor {
331
+ width: 100%;
332
+ height: calc(100dvh - 45px);
333
+ overflow: hidden;
334
+ position: relative;
335
+ background-image: repeating-linear-gradient(315deg,currentColor 0 1px,#0000 0 50%);
336
+ background-size: 8px 8px;
337
+ background-position: 0 0;
338
+ color: var(--bg-2);
339
+ }
340
+ .editor * {
341
+ color: initial;
342
+ }
343
+ .pages {
344
+ display: flex;
345
+ column-gap: calc(var(--pad-m) * var(--zoom));
346
+ position: absolute;
347
+ top: var(--pos-y);
348
+ left: var(--pos-x);
349
+ width: max-content;
350
+ height: max-content;
351
+ overflow: visible;
352
+ }
353
+
354
+ .top-bar {
355
+ display: flex;
356
+ align-items: center;
357
+ padding: var(--pad-xs);
358
+ column-gap: var(--pad-xs);
359
+ border-radius: var(--radius-xl);
360
+ background-color: var(--bg-1);
361
+ border: 1px solid var(--bg-2);
362
+ position: absolute;
363
+ top: var(--pad-xs);
364
+ left: var(--pad-xs);
365
+ max-width: calc(100% - var(--pad-xs) * 2);
366
+ }
367
+
368
+ .right-bar {
369
+ position: absolute;
370
+ top: 0;
371
+ right: 0;
372
+ width: min(100%, 250px);
373
+ height: 100%;
374
+ border-left: 1px solid var(--bg-2);
375
+ background-color: var(--bg-1);
376
+ z-index: 1;
377
+ }
378
+
379
+ .title {
380
+ padding: var(--pad-m);
381
+ border-bottom: 1px solid var(--bg-2);
382
+ }
383
+
384
+ .grid-selector {
385
+ display: flex;
386
+ width: 100%;
387
+ padding: var(--pad-xs);
388
+ border-radius: var(--radius-m);
389
+ background-color: var(--bg-blur);
390
+ }
391
+ </style>