@x33025/sveltely 0.1.24 → 0.1.25

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 (71) hide show
  1. package/dist/actions/LoaderOverlay.svelte +10 -3
  2. package/dist/components/Library/Accordion/Accordion.demo.svelte +21 -0
  3. package/dist/components/Library/Accordion/Accordion.demo.svelte.d.ts +9 -0
  4. package/dist/components/Library/Accordion/Accordion.svelte +78 -0
  5. package/dist/components/Library/Accordion/Accordion.svelte.d.ts +14 -0
  6. package/dist/components/Library/Accordion/Content.svelte +57 -0
  7. package/dist/components/Library/Accordion/Content.svelte.d.ts +8 -0
  8. package/dist/components/Library/Accordion/Header.svelte +98 -0
  9. package/dist/components/Library/Accordion/Header.svelte.d.ts +10 -0
  10. package/dist/components/Library/Accordion/context.d.ts +9 -0
  11. package/dist/components/Library/Accordion/context.js +6 -0
  12. package/dist/components/Library/Accordion/index.d.ts +9 -0
  13. package/dist/components/Library/Accordion/index.js +7 -0
  14. package/dist/components/Library/AnimatedNumber/AnimatedNumber.demo.svelte +1 -1
  15. package/dist/components/Library/ArticleEditor/ArticleEditor.svelte +1 -2
  16. package/dist/components/Library/ArticleEditor/Blocks/Table.svelte +1 -1
  17. package/dist/components/Library/ChipInput/ChipInput.demo.svelte +1 -1
  18. package/dist/components/Library/Dropdown/Dropdown.demo.svelte +5 -3
  19. package/dist/components/Library/Grid/Grid.demo.svelte +58 -0
  20. package/dist/components/Library/Grid/Grid.demo.svelte.d.ts +25 -0
  21. package/dist/components/Library/Grid/Grid.svelte +120 -26
  22. package/dist/components/Library/Grid/Grid.svelte.d.ts +38 -10
  23. package/dist/components/Library/Grid/GridItem.svelte +8 -13
  24. package/dist/components/Library/ImageMask/ImageMask.demo.svelte +1 -1
  25. package/dist/components/Library/Label/Label.demo.svelte +1 -1
  26. package/dist/components/Library/Label/Label.svelte +5 -13
  27. package/dist/components/Library/Notifications/Notifications.demo.svelte +63 -0
  28. package/dist/components/Library/Notifications/Notifications.demo.svelte.d.ts +9 -0
  29. package/dist/components/Library/Notifications/Notifications.svelte +155 -0
  30. package/dist/components/Library/Notifications/Notifications.svelte.d.ts +35 -0
  31. package/dist/components/Library/Notifications/index.d.ts +2 -0
  32. package/dist/components/Library/Notifications/index.js +1 -0
  33. package/dist/components/Library/Notifications/types.d.ts +8 -0
  34. package/dist/components/Library/Notifications/types.js +1 -0
  35. package/dist/components/Library/NumberField/NumberField.svelte +25 -19
  36. package/dist/components/Library/Pagination/Pagination.svelte +6 -18
  37. package/dist/components/Library/ScrollView/ScrollView.svelte +76 -4
  38. package/dist/components/Library/ScrollView/ScrollView.svelte.d.ts +9 -2
  39. package/dist/components/Library/ScrollView/index.d.ts +1 -1
  40. package/dist/components/Library/SearchField/SearchField.demo.svelte +1 -1
  41. package/dist/components/Library/SegmentedPicker/SegmentedPicker.demo.svelte +1 -1
  42. package/dist/components/Library/Slider/Slider.demo.svelte +1 -1
  43. package/dist/components/Library/Table/Table.demo.svelte +9 -1
  44. package/dist/components/Library/Table/Table.svelte +315 -112
  45. package/dist/components/Library/Table/Table.svelte.d.ts +7 -1
  46. package/dist/components/Library/TextField/TextField.svelte +20 -14
  47. package/dist/components/Library/TokenSearchField/TokenSearchField.demo.svelte +1 -1
  48. package/dist/components/Local/ColorStyleControls.svelte +25 -64
  49. package/dist/components/Local/ComponentGrid.svelte +103 -22
  50. package/dist/components/Local/ComponentGrid.svelte.d.ts +2 -1
  51. package/dist/components/Local/ComponentPage.svelte +74 -0
  52. package/dist/components/Local/ComponentPage.svelte.d.ts +13 -0
  53. package/dist/components/Local/HeroCard.svelte +10 -5
  54. package/dist/components/Local/LayoutStyleControls.svelte +6 -6
  55. package/dist/index.d.ts +8 -3
  56. package/dist/index.js +4 -1
  57. package/dist/style/index.css +1 -2
  58. package/dist/style/layout.d.ts +11 -26
  59. package/dist/style/layout.js +31 -53
  60. package/dist/style.css +4 -1
  61. package/dist/viewport/geometry.d.ts +8 -0
  62. package/dist/viewport/geometry.js +43 -0
  63. package/dist/viewport/index.d.ts +4 -0
  64. package/dist/viewport/index.js +4 -0
  65. package/dist/viewport/layout.d.ts +4 -0
  66. package/dist/viewport/layout.js +138 -0
  67. package/dist/viewport/placement.d.ts +4 -0
  68. package/dist/viewport/placement.js +14 -0
  69. package/dist/viewport/types.d.ts +81 -0
  70. package/dist/viewport/types.js +1 -0
  71. package/package.json +1 -1
@@ -157,9 +157,8 @@
157
157
  .pagination {
158
158
  --pagination-font-size: calc(var(--sveltely-font-size) * 0.875);
159
159
  --pagination-scale: calc(var(--pagination-font-size) / 0.875rem);
160
- --pagination-icon-size: calc(var(--pagination-font-size) * 1.143);
160
+ --pagination-icon-size: calc(var(--pagination-font-size) * 0.95);
161
161
  --pagination-gap: calc(var(--sveltely-gap) * 2);
162
- --pagination-icon-shift: calc(var(--sveltely-gap) / 2);
163
162
  display: inline-flex;
164
163
  width: fit-content;
165
164
  gap: var(--pagination-gap);
@@ -173,18 +172,12 @@
173
172
  }
174
173
 
175
174
  .pagination-icon {
175
+ display: block;
176
+ flex: 0 0 auto;
176
177
  width: var(--pagination-icon-size);
177
178
  height: var(--pagination-icon-size);
178
179
  }
179
180
 
180
- .pagination-icon-backward {
181
- transform: translateX(calc(var(--pagination-icon-shift) * -1));
182
- }
183
-
184
- .pagination-icon-forward {
185
- transform: translateX(var(--pagination-icon-shift));
186
- }
187
-
188
181
  .pagination-button {
189
182
  border-radius: var(--sveltely-border-radius);
190
183
  background: var(--sveltely-control-inactive-color);
@@ -193,14 +186,9 @@
193
186
  }
194
187
 
195
188
  .pagination-button-icon {
196
- padding: calc(var(--sveltely-padding-y) * 0.67 * var(--pagination-scale))
197
- calc(var(--sveltely-padding-x) * 0.67 * var(--pagination-scale));
198
- min-width: calc(
199
- (var(--sveltely-padding-x) * 1.34 * var(--pagination-scale)) + var(--pagination-icon-size)
200
- );
201
- min-height: calc(
202
- (var(--sveltely-padding-y) * 1.34 * var(--pagination-scale)) + var(--pagination-icon-size)
203
- );
189
+ width: calc(var(--pagination-icon-size) + var(--sveltely-padding-x) * var(--pagination-scale));
190
+ height: calc(var(--pagination-icon-size) + var(--sveltely-padding-y) * var(--pagination-scale));
191
+ padding: 0;
204
192
  }
205
193
 
206
194
  .pagination-button:disabled {
@@ -48,12 +48,18 @@
48
48
  };
49
49
 
50
50
  export type ScrollViewOverscrollBehavior = 'auto' | 'contain' | 'none';
51
+ export type ScrollContentSize = {
52
+ width: number;
53
+ height: number;
54
+ };
51
55
 
52
56
  type Props = {
53
- children: Snippet;
57
+ children?: Snippet;
58
+ layout?: Snippet<[geometry: ScrollGeometry]>;
54
59
  viewport?: ScrollViewHandle | null;
55
60
  axis?: ScrollAxis;
56
61
  contentStyles?: StyleProps;
62
+ contentSize?: ScrollContentSize | null;
57
63
  onScroll?: (geometry: ScrollGeometry) => void;
58
64
  scrollGradient?: boolean;
59
65
  scrollGradientSize?: number | string;
@@ -65,16 +71,18 @@
65
71
 
66
72
  let {
67
73
  children,
74
+ layout,
68
75
  viewport = $bindable<ScrollViewHandle | null>(null),
69
76
  axis = 'vertical',
70
77
  contentStyles = {},
78
+ contentSize = null,
71
79
  onScroll,
72
80
  scrollGradient = true,
73
81
  scrollGradientSize = '2.5rem',
74
82
  showIndicators = true,
75
83
  overscrollBehavior = 'contain',
76
84
  ...restProps
77
- }: Props = $props();
85
+ }: Props & Record<string, unknown> = $props();
78
86
 
79
87
  const extractedLoaderProps = $derived.by(() => extractLoaderProps(restProps));
80
88
  const loaderProps = $derived(extractedLoaderProps.loaderProps);
@@ -108,11 +116,17 @@
108
116
  let thumbYOffset = $state(0);
109
117
  let resizeObserver: ResizeObserver | null = null;
110
118
  let mutationObserver: MutationObserver | null = null;
119
+ let scrollAnimationFrame: number | null = null;
111
120
  const scrollGradientEnabled = $derived(scrollGradient && axis !== 'horizontal');
112
121
  const verticalScrollbarEnabled = $derived(showIndicators && axis !== 'horizontal' && canScrollY);
113
122
  const horizontalScrollbarEnabled = $derived(showIndicators && axis !== 'vertical' && canScrollX);
123
+ const syntheticContentStyle = $derived.by(() => {
124
+ if (!contentSize) return '';
125
+ return `width: ${contentSize.width}px; height: ${contentSize.height}px; min-width: ${contentSize.width}px; min-height: ${contentSize.height}px;`;
126
+ });
114
127
 
115
128
  const measuredContentSize = () => {
129
+ if (contentSize) return contentSize;
116
130
  if (!contentElement) return { width: 0, height: 0 };
117
131
 
118
132
  const contentRect = contentElement.getBoundingClientRect();
@@ -169,6 +183,7 @@
169
183
  }
170
184
  };
171
185
  }
186
+ const scrollGeometry = $derived.by(() => getScrollGeometry());
172
187
 
173
188
  function syncScrollbarGeometry() {
174
189
  if (!viewportElement || !contentElement) {
@@ -224,7 +239,14 @@
224
239
  onScroll?.(getScrollGeometry());
225
240
  }
226
241
 
242
+ function stopScrollAnimation() {
243
+ if (scrollAnimationFrame === null || typeof cancelAnimationFrame === 'undefined') return;
244
+ cancelAnimationFrame(scrollAnimationFrame);
245
+ scrollAnimationFrame = null;
246
+ }
247
+
227
248
  function scrollTo(nextX: number, nextY: number) {
249
+ stopScrollAnimation();
228
250
  const previousX = offsetX;
229
251
  const previousY = offsetY;
230
252
  offsetX = clamp(axis === 'vertical' ? 0 : nextX, 0, maxOffsetX());
@@ -233,6 +255,41 @@
233
255
  return offsetX !== previousX || offsetY !== previousY;
234
256
  }
235
257
 
258
+ function animateScrollTo(nextX: number, nextY: number) {
259
+ if (typeof requestAnimationFrame === 'undefined') {
260
+ scrollTo(nextX, nextY);
261
+ return;
262
+ }
263
+
264
+ stopScrollAnimation();
265
+ const fromX = offsetX;
266
+ const fromY = offsetY;
267
+ const toX = clamp(axis === 'vertical' ? 0 : nextX, 0, maxOffsetX());
268
+ const toY = clamp(axis === 'horizontal' ? 0 : nextY, 0, maxOffsetY());
269
+ const duration = 260;
270
+ const startedAt = performance.now();
271
+ const easeOutCubic = (value: number) => 1 - Math.pow(1 - value, 3);
272
+
273
+ const step = (now: number) => {
274
+ const progress = Math.min(1, (now - startedAt) / duration);
275
+ const eased = easeOutCubic(progress);
276
+ offsetX = fromX + (toX - fromX) * eased;
277
+ offsetY = fromY + (toY - fromY) * eased;
278
+ publishScroll();
279
+
280
+ if (progress < 1) {
281
+ scrollAnimationFrame = requestAnimationFrame(step);
282
+ } else {
283
+ scrollAnimationFrame = null;
284
+ offsetX = toX;
285
+ offsetY = toY;
286
+ publishScroll();
287
+ }
288
+ };
289
+
290
+ scrollAnimationFrame = requestAnimationFrame(step);
291
+ }
292
+
236
293
  function shouldContainOverscroll(consumed: boolean) {
237
294
  if (overscrollBehavior === 'none') return true;
238
295
  return overscrollBehavior === 'contain' && consumed;
@@ -274,6 +331,10 @@
274
331
  scrollTo(options, y ?? offsetY);
275
332
  return;
276
333
  }
334
+ if (options.behavior === 'smooth') {
335
+ animateScrollTo(options.left ?? offsetX, options.top ?? offsetY);
336
+ return;
337
+ }
277
338
  scrollTo(options.left ?? offsetX, options.top ?? offsetY);
278
339
  }
279
340
  };
@@ -340,6 +401,7 @@
340
401
  });
341
402
 
342
403
  return () => {
404
+ stopScrollAnimation();
343
405
  resizeObserver?.disconnect();
344
406
  resizeObserver = null;
345
407
  mutationObserver?.disconnect();
@@ -421,9 +483,14 @@
421
483
  <div
422
484
  bind:this={contentElement}
423
485
  class="scroll-view-content"
424
- style={`${contentStyle} transform: translate3d(${-offsetX}px, ${-offsetY}px, 0);`}
486
+ class:scroll-view-content-engine={Boolean(layout)}
487
+ style={`${contentStyle} ${syntheticContentStyle} transform: translate3d(${-offsetX}px, ${-offsetY}px, 0);`}
425
488
  >
426
- {@render children()}
489
+ {#if layout}
490
+ {@render layout(scrollGeometry)}
491
+ {:else if children}
492
+ {@render children()}
493
+ {/if}
427
494
  </div>
428
495
  </div>
429
496
  {#if scrollGradientEnabled}
@@ -488,6 +555,11 @@
488
555
  will-change: transform;
489
556
  }
490
557
 
558
+ .scroll-view-content-engine {
559
+ position: relative;
560
+ padding: 0;
561
+ }
562
+
491
563
  .scroll-view-horizontal .scroll-view-content {
492
564
  min-height: 100%;
493
565
  width: max-content;
@@ -42,17 +42,24 @@ export type ScrollViewHandle = {
42
42
  scrollTo: (options: ScrollToOptions | number, y?: number) => void;
43
43
  };
44
44
  export type ScrollViewOverscrollBehavior = 'auto' | 'contain' | 'none';
45
+ export type ScrollContentSize = {
46
+ width: number;
47
+ height: number;
48
+ };
45
49
  type Props = {
46
- children: Snippet;
50
+ children?: Snippet;
51
+ layout?: Snippet<[geometry: ScrollGeometry]>;
47
52
  viewport?: ScrollViewHandle | null;
48
53
  axis?: ScrollAxis;
49
54
  contentStyles?: StyleProps;
55
+ contentSize?: ScrollContentSize | null;
50
56
  onScroll?: (geometry: ScrollGeometry) => void;
51
57
  scrollGradient?: boolean;
52
58
  scrollGradientSize?: number | string;
53
59
  showIndicators?: boolean;
54
60
  overscrollBehavior?: ScrollViewOverscrollBehavior;
55
61
  } & LayoutProps & StyleProps & LoaderProps;
56
- declare const ScrollView: import("svelte").Component<Props, {}, "viewport">;
62
+ type $$ComponentProps = Props & Record<string, unknown>;
63
+ declare const ScrollView: import("svelte").Component<$$ComponentProps, {}, "viewport">;
57
64
  type ScrollView = ReturnType<typeof ScrollView>;
58
65
  export default ScrollView;
@@ -1,2 +1,2 @@
1
1
  export { default } from './ScrollView.svelte';
2
- export type { ScrollGeometry, ScrollViewHandle, ScrollViewOverscrollBehavior } from './ScrollView.svelte';
2
+ export type { ScrollGeometry, ScrollContentSize, ScrollViewHandle, ScrollViewOverscrollBehavior } from './ScrollView.svelte';
@@ -12,7 +12,7 @@
12
12
  let value = $state('');
13
13
  </script>
14
14
 
15
- <VStack width="100%" maxWidth="24rem" gap={5}>
15
+ <VStack width="24rem" gap={5}>
16
16
  <SearchField bind:value placeholder="Search components..." />
17
17
  <p class="text-xs text-[var(--sveltely-text-secondary-color)]">Value: {value || 'empty'}</p>
18
18
  </VStack>
@@ -18,7 +18,7 @@
18
18
  let value = $state('day');
19
19
  </script>
20
20
 
21
- <VStack align="center" justify="center" gap={5}>
21
+ <VStack gap={5}>
22
22
  <SegmentedPicker {options} bind:value />
23
23
  <p class="text-xs text-[var(--sveltely-text-secondary-color)]">Selected: {value}</p>
24
24
  </VStack>
@@ -12,7 +12,7 @@
12
12
  let value = $state(35);
13
13
  </script>
14
14
 
15
- <VStack width="100%" maxWidth="24rem" gap={5}>
15
+ <VStack width="24rem" gap={5}>
16
16
  <Slider bind:value min={0} max={100} />
17
17
  <p class="text-xs text-[var(--sveltely-text-secondary-color)]">Value: {value}</p>
18
18
  </VStack>
@@ -270,7 +270,15 @@
270
270
  })}
271
271
  {/snippet}
272
272
 
273
- <Table data={rows} bind:selection bind:sortOrder selectionMode="multiple" height="100%">
273
+ <Table
274
+ data={rows}
275
+ bind:selection
276
+ bind:sortOrder
277
+ selectionMode="multiple"
278
+ virtualized
279
+ rowHeight={48}
280
+ height="100%"
281
+ >
274
282
  <Table.Column label="Project" sortKey="name" sortable minWidth={160}>
275
283
  {#snippet cell(project: Project)}
276
284
  {@render projectCell(project)}