@danielito1996/compose-svelted 0.2.7-alpha02 → 0.2.7-alpha03

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.
@@ -18,7 +18,7 @@
18
18
  let scrollTop = 0;
19
19
  let viewportHeight = 0;
20
20
 
21
- let estimatedItemHeight = 56; // fallback Material
21
+ let estimatedItemHeight = 56;
22
22
  let measured = false;
23
23
 
24
24
  const overscan = 3;
@@ -43,7 +43,7 @@
43
43
  scrollTop = (e.target as HTMLDivElement).scrollTop;
44
44
  }
45
45
 
46
- // --- Virtualization math ---
46
+ // --- Virtualization ---
47
47
  $: totalHeight = items.length * estimatedItemHeight;
48
48
 
49
49
  $: startIndex = Math.max(
@@ -55,13 +55,11 @@
55
55
  Math.ceil(viewportHeight / estimatedItemHeight) + overscan * 2;
56
56
 
57
57
  $: endIndex = Math.min(items.length, startIndex + visibleCount);
58
-
59
58
  $: visibleItems = items.slice(startIndex, endIndex);
60
59
 
61
- // --- Arrangement ---
62
- function resolveGap(arrangement: ArrangementValue): string {
63
- return arrangement.type === "spaced"
64
- ? `${arrangement.gap}px`
60
+ function resolveGap(): string {
61
+ return verticalArrangement.type === "spaced"
62
+ ? `${verticalArrangement.gap}px`
65
63
  : "0px";
66
64
  }
67
65
  </script>
@@ -69,15 +67,17 @@
69
67
  <div
70
68
  bind:this={container}
71
69
  on:scroll={onScroll}
70
+ class="compose-lazy-column"
72
71
  style={`
73
- overflow-y:auto;
74
- position:relative;
72
+ overflow-y: auto;
73
+ overflow-x: hidden;
74
+ position: relative;
75
75
  ${modifier.toStyle()}
76
76
  `}
77
77
  >
78
- <!-- Total scroll space -->
78
+ <!-- Espacio total -->
79
79
  <div style={`height:${totalHeight}px; position:relative;`}>
80
- <!-- Visible window -->
80
+ <!-- Ventana visible -->
81
81
  <div
82
82
  style={`
83
83
  position:absolute;
@@ -88,7 +88,7 @@
88
88
  display:flex;
89
89
  flex-direction:column;
90
90
  align-items:${horizontalAlignment};
91
- gap:${resolveGap(verticalArrangement)};
91
+ gap:${resolveGap()};
92
92
  `}
93
93
  >
94
94
  {#each visibleItems as item, i}
@@ -1,71 +1,107 @@
1
1
  <script lang="ts">
2
2
  import { Modifier } from "../../core/modifier/Modifier";
3
+ import { onMount, tick } from "svelte";
3
4
  import { Alignment } from "./Alignment";
4
5
  import { Arrangement } from "./Arrangement";
5
6
  import type { ArrangementValue } from "./Arrangement";
6
- import type { VerticalAlignment } from "./Alignment";
7
+ import type { HorizontalAlignment } from "./Alignment";
7
8
 
8
9
  export let items: any[] = [];
9
10
  export let modifier: Modifier = Modifier.empty();
10
11
 
11
- export let verticalAlignment: VerticalAlignment = Alignment.Top;
12
- export let horizontalArrangement: ArrangementValue = Arrangement.Start;
12
+ export let horizontalAlignment: HorizontalAlignment = Alignment.Start;
13
+ export let verticalArrangement: ArrangementValue = Arrangement.Start;
13
14
 
14
- export let scrollEnabled: boolean = true;
15
- export let hideScrollbar: boolean = false;
16
- export let horizontalSpacing: number | null = null;
15
+ let container: HTMLDivElement;
16
+ let probeItem: HTMLDivElement | null = null;
17
17
 
18
- function resolveGap(): string {
19
- if (horizontalSpacing !== null) {
20
- return `${horizontalSpacing}px`;
18
+ let scrollTop = 0;
19
+ let viewportHeight = 0;
20
+
21
+ let estimatedItemHeight = 56; // fallback Material
22
+ let measured = false;
23
+
24
+ const overscan = 3;
25
+
26
+ onMount(() => {
27
+ viewportHeight = container.clientHeight;
28
+ });
29
+
30
+ async function measure() {
31
+ await tick();
32
+ if (probeItem) {
33
+ estimatedItemHeight = probeItem.offsetHeight;
34
+ measured = true;
21
35
  }
36
+ }
22
37
 
23
- return horizontalArrangement.type === "spaced"
24
- ? `${horizontalArrangement.gap}px`
25
- : "0px";
38
+ $: if (probeItem && !measured) {
39
+ measure();
26
40
  }
27
41
 
28
- function resolveOverflowX(): string {
29
- return scrollEnabled ? "auto" : "hidden";
42
+ function onScroll(e: Event) {
43
+ scrollTop = (e.target as HTMLDivElement).scrollTop;
30
44
  }
31
45
 
32
- function resolveScrollbarStyle(): string {
33
- if (!hideScrollbar) return "";
46
+ // --- Virtualization math ---
47
+ $: totalHeight = items.length * estimatedItemHeight;
34
48
 
35
- return `
36
- scrollbar-width: none;
37
- -ms-overflow-style: none;
38
- `;
39
- }
40
- </script>
49
+ $: startIndex = Math.max(
50
+ 0,
51
+ Math.floor(scrollTop / estimatedItemHeight) - overscan
52
+ );
41
53
 
42
- <div
43
- class={hideScrollbar ? "lazy-row--hide-scrollbar" : ""}
44
- style={`
45
- display: flex;
46
- flex-direction: row;
54
+ $: visibleCount =
55
+ Math.ceil(viewportHeight / estimatedItemHeight) + overscan * 2;
47
56
 
48
- align-items: ${verticalAlignment};
49
- justify-content: ${horizontalArrangement.justifyContent};
50
- gap: ${resolveGap()};
57
+ $: endIndex = Math.min(items.length, startIndex + visibleCount);
51
58
 
52
- overflow-x: ${resolveOverflowX()};
53
- overflow-y: visible;
59
+ $: visibleItems = items.slice(startIndex, endIndex);
54
60
 
55
- height: fit-content;
56
- min-height: fit-content;
61
+ // --- Arrangement ---
62
+ function resolveGap(arrangement: ArrangementValue): string {
63
+ return arrangement.type === "spaced"
64
+ ? `${arrangement.gap}px`
65
+ : "0px";
66
+ }
67
+ </script>
57
68
 
58
- ${resolveScrollbarStyle()}
69
+ <div
70
+ bind:this={container}
71
+ on:scroll={onScroll}
72
+ style={`
73
+ overflow-y:auto;
74
+ position:relative;
59
75
  ${modifier.toStyle()}
60
76
  `}
61
77
  >
62
- {#each items as item}
63
- <slot {item} />
64
- {/each}
65
- </div>
66
-
67
- <style>
68
- .lazy-row--hide-scrollbar::-webkit-scrollbar {
69
- display: none;
70
- }
71
- </style>
78
+ <!-- Total scroll space -->
79
+ <div style={`height:${totalHeight}px; position:relative;`}>
80
+ <!-- Visible window -->
81
+ <div
82
+ style={`
83
+ position:absolute;
84
+ top:${startIndex * estimatedItemHeight}px;
85
+ left:0;
86
+ right:0;
87
+
88
+ display:flex;
89
+ flex-direction:column;
90
+ align-items:${horizontalAlignment};
91
+ gap:${resolveGap(verticalArrangement)};
92
+ `}
93
+ >
94
+ {#each visibleItems as item, i}
95
+ {#if i === 0 && !measured}
96
+ <div bind:this={probeItem}>
97
+ <slot {item} />
98
+ </div>
99
+ {:else}
100
+ <div>
101
+ <slot {item} />
102
+ </div>
103
+ {/if}
104
+ {/each}
105
+ </div>
106
+ </div>
107
+ </div>
@@ -1,6 +1,6 @@
1
1
  import { Modifier } from "../../core/modifier/Modifier";
2
2
  import type { ArrangementValue } from "./Arrangement";
3
- import type { VerticalAlignment } from "./Alignment";
3
+ import type { HorizontalAlignment } from "./Alignment";
4
4
  interface $$__sveltets_2_IsomorphicComponent<Props extends Record<string, any> = any, Events extends Record<string, any> = any, Slots extends Record<string, any> = any, Exports = {}, Bindings = string> {
5
5
  new (options: import('svelte').ComponentConstructorOptions<Props>): import('svelte').SvelteComponent<Props, Events, Slots> & {
6
6
  $$bindings?: Bindings;
@@ -22,11 +22,8 @@ type $$__sveltets_2_PropsWithChildren<Props, Slots> = Props & (Slots extends {
22
22
  declare const LazyRow: $$__sveltets_2_IsomorphicComponent<$$__sveltets_2_PropsWithChildren<{
23
23
  items?: any[];
24
24
  modifier?: Modifier;
25
- verticalAlignment?: VerticalAlignment;
26
- horizontalArrangement?: ArrangementValue;
27
- scrollEnabled?: boolean;
28
- hideScrollbar?: boolean;
29
- horizontalSpacing?: number | null;
25
+ horizontalAlignment?: HorizontalAlignment;
26
+ verticalArrangement?: ArrangementValue;
30
27
  }, {
31
28
  default: {
32
29
  item: any;
@@ -1,70 +1,50 @@
1
1
  <script lang="ts">
2
2
  import { Modifier } from "../../core/modifier/Modifier";
3
+ import { resolveBoxAlignment } from "./resolveAlignment";
4
+ import {Alignment, BoxAlignment} from "./Alignment";
3
5
 
4
6
  export let modifier: Modifier = Modifier.empty();
5
-
6
- // Padding interno aplicado al content (como Scaffold paddingValues)
7
- export let contentPadding: number = 16;
8
-
9
- // Control del FAB
10
- export let fabAlignment:
11
- | "bottom-end"
12
- | "bottom-center"
13
- | "bottom-start" = "bottom-end";
7
+ export let contentPadding = 16;
8
+ export let fabAlignment: BoxAlignment = Alignment.BottomEnd;
14
9
  </script>
15
10
 
16
11
  <div
12
+ class="compose-relative"
17
13
  style={`
18
14
  display: flex;
19
15
  flex-direction: column;
20
- height: 100%;
21
16
  width: 100%;
22
- position: relative;
17
+ height: 100%;
23
18
  ${modifier.toStyle()}
24
19
  `}
25
20
  >
26
- <!-- Top Bar -->
27
- <div>
28
- <slot name="topBar" />
29
- </div>
21
+ <!-- Top bar -->
22
+ <slot name="topBar" />
30
23
 
31
24
  <!-- Content -->
32
25
  <div
33
- style={`
34
- flex: 1;
35
- position: relative;
36
- padding: ${contentPadding}px;
37
- overflow: auto;
38
- `}
26
+ class="compose-scaffold-content"
27
+ style={`padding:${contentPadding}px;`}
39
28
  >
40
29
  <slot />
41
30
  </div>
42
31
 
43
- <!-- Bottom Bar -->
44
- <div>
45
- <slot name="bottomBar" />
46
- </div>
32
+ <!-- Bottom bar -->
33
+ <slot name="bottomBar" />
47
34
 
48
- <!-- Floating Action Button -->
35
+ <!-- FAB overlay -->
49
36
  <div
50
37
  style={`
51
- position: absolute;
52
- pointer-events: none;
53
- inset: 0;
38
+ position:absolute;
39
+ inset:0;
40
+ pointer-events:none;
54
41
  `}
55
42
  >
56
43
  <div
57
44
  style={`
58
- position: absolute;
59
- pointer-events: auto;
60
-
61
- ${
62
- fabAlignment === "bottom-end"
63
- ? "right: 16px; bottom: 16px;"
64
- : fabAlignment === "bottom-center"
65
- ? "left: 50%; transform: translateX(-50%); bottom: 16px;"
66
- : "left: 16px; bottom: 16px;"
67
- }
45
+ ${resolveBoxAlignment(fabAlignment)}
46
+ pointer-events:auto;
47
+ margin:16px;
68
48
  `}
69
49
  >
70
50
  <slot name="floatingActionButton" />
@@ -1,4 +1,5 @@
1
1
  import { Modifier } from "../../core/modifier/Modifier";
2
+ import { BoxAlignment } from "./Alignment";
2
3
  interface $$__sveltets_2_IsomorphicComponent<Props extends Record<string, any> = any, Events extends Record<string, any> = any, Slots extends Record<string, any> = any, Exports = {}, Bindings = string> {
3
4
  new (options: import('svelte').ComponentConstructorOptions<Props>): import('svelte').SvelteComponent<Props, Events, Slots> & {
4
5
  $$bindings?: Bindings;
@@ -20,7 +21,7 @@ type $$__sveltets_2_PropsWithChildren<Props, Slots> = Props & (Slots extends {
20
21
  declare const Scaffold: $$__sveltets_2_IsomorphicComponent<$$__sveltets_2_PropsWithChildren<{
21
22
  modifier?: Modifier;
22
23
  contentPadding?: number;
23
- fabAlignment?: "bottom-end" | "bottom-center" | "bottom-start";
24
+ fabAlignment?: BoxAlignment;
24
25
  }, {
25
26
  topBar: {};
26
27
  default: {};
@@ -0,0 +1,49 @@
1
+ /* compose-svelted baseline.css */
2
+
3
+ /* 1. Modelo de caja consistente */
4
+ *, *::before, *::after {
5
+ box-sizing: border-box;
6
+ }
7
+
8
+ /* 2. Root layout estable */
9
+ html, body {
10
+ margin: 0;
11
+ padding: 0;
12
+ width: 100%;
13
+ height: 100%;
14
+ }
15
+
16
+ /* 3. Host de la app */
17
+ #app, body > div {
18
+ width: 100%;
19
+ height: 100%;
20
+ }
21
+
22
+ /* 4. Prevención de colapso en flex */
23
+ * {
24
+ min-width: 0;
25
+ min-height: 0;
26
+ }
27
+
28
+ /* 5. Soporte para absolute alignment */
29
+ .compose-relative {
30
+ position: relative;
31
+ }
32
+
33
+ /* 6. Clickable base */
34
+ .compose-clickable {
35
+ cursor: pointer;
36
+ user-select: none;
37
+ }
38
+
39
+ /* 7. Evitar interferencia de estilos externos */
40
+ img, svg, video, canvas {
41
+ display: block;
42
+ max-width: 100%;
43
+ }
44
+
45
+ .compose-lazy-row,
46
+ .compose-lazy-column {
47
+ min-width: 0;
48
+ min-height: 0;
49
+ }
package/dist/index.js CHANGED
@@ -1,3 +1,4 @@
1
+ import "./core/styles/baseline.css";
1
2
  // Root
2
3
  export { default as ComposeTheme } from "./core/theme/ComposeTheme.svelte";
3
4
  export { default as AppRoot } from "./components/AppRoot.svelte";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@danielito1996/compose-svelted",
3
- "version": "0.2.7-alpha02",
3
+ "version": "0.2.7-alpha03",
4
4
  "description": "Compose-like UI toolkit for Svelte, inspired by Jetpack Compose",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -18,7 +18,8 @@
18
18
  "types": "./dist/index.d.ts",
19
19
  "import": "./dist/index.js",
20
20
  "svelte": "./dist/index.js"
21
- }
21
+ },
22
+ "./baseline.css": "./dist/core/styles/baseline.css"
22
23
  },
23
24
  "files": [
24
25
  "dist"