@x33025/sveltely 0.1.23 → 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 (107) 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 +3 -2
  15. package/dist/components/Library/ArticleEditor/ArticleEditor.svelte +1 -2
  16. package/dist/components/Library/ArticleEditor/Blocks/Table.svelte +133 -172
  17. package/dist/components/Library/Checkbox/Checkbox.demo.svelte +5 -4
  18. package/dist/components/Library/Checkbox/Checkbox.svelte +6 -5
  19. package/dist/components/Library/Checkbox/Checkbox.svelte.d.ts +2 -1
  20. package/dist/components/Library/ChipInput/ChipInput.demo.svelte +3 -2
  21. package/dist/components/Library/Dropdown/Dropdown.demo.svelte +20 -15
  22. package/dist/components/Library/Floating/Floating.svelte +5 -6
  23. package/dist/components/Library/Grid/Grid.demo.svelte +58 -0
  24. package/dist/components/Library/Grid/Grid.demo.svelte.d.ts +25 -0
  25. package/dist/components/Library/Grid/Grid.svelte +128 -25
  26. package/dist/components/Library/Grid/Grid.svelte.d.ts +38 -9
  27. package/dist/components/Library/Grid/GridItem.svelte +18 -14
  28. package/dist/components/Library/Grid/GridItem.svelte.d.ts +2 -1
  29. package/dist/components/Library/HStack/HStack.svelte +4 -4
  30. package/dist/components/Library/HStack/HStack.svelte.d.ts +2 -1
  31. package/dist/components/Library/Image/Image.demo.svelte +3 -1
  32. package/dist/components/Library/Image/Image.demo.svelte.d.ts +2 -0
  33. package/dist/components/Library/ImageMask/ImageMask.demo.svelte +8 -6
  34. package/dist/components/Library/Label/Label.demo.svelte +5 -5
  35. package/dist/components/Library/Label/Label.svelte +10 -26
  36. package/dist/components/Library/NavigationStack/Link.svelte +1 -4
  37. package/dist/components/Library/Notifications/Notifications.demo.svelte +63 -0
  38. package/dist/components/Library/Notifications/Notifications.demo.svelte.d.ts +9 -0
  39. package/dist/components/Library/Notifications/Notifications.svelte +155 -0
  40. package/dist/components/Library/Notifications/Notifications.svelte.d.ts +35 -0
  41. package/dist/components/Library/Notifications/index.d.ts +2 -0
  42. package/dist/components/Library/Notifications/index.js +1 -0
  43. package/dist/components/Library/Notifications/types.d.ts +8 -0
  44. package/dist/components/Library/Notifications/types.js +1 -0
  45. package/dist/components/Library/NumberField/NumberField.svelte +25 -19
  46. package/dist/components/Library/Pagination/Pagination.demo.svelte +3 -2
  47. package/dist/components/Library/Pagination/Pagination.svelte +6 -18
  48. package/dist/components/Library/Popover/PopoverDebugOverlay.svelte +3 -3
  49. package/dist/components/Library/Portal/Content.svelte +20 -0
  50. package/dist/components/Library/Portal/Content.svelte.d.ts +10 -0
  51. package/dist/components/Library/Portal/Portal.svelte +4 -0
  52. package/dist/components/Library/Portal/Portal.svelte.d.ts +1 -0
  53. package/dist/components/Library/Portal/index.d.ts +1 -0
  54. package/dist/components/Library/Portal/index.js +1 -0
  55. package/dist/components/Library/ScrollView/ScrollView.svelte +88 -9
  56. package/dist/components/Library/ScrollView/ScrollView.svelte.d.ts +9 -2
  57. package/dist/components/Library/ScrollView/index.d.ts +1 -1
  58. package/dist/components/Library/SearchField/SearchField.demo.svelte +3 -2
  59. package/dist/components/Library/SearchField/SearchField.svelte +5 -5
  60. package/dist/components/Library/SearchField/SearchField.svelte.d.ts +2 -1
  61. package/dist/components/Library/SegmentedPicker/SegmentedPicker.demo.svelte +3 -2
  62. package/dist/components/Library/Sheet/Sheet.demo.svelte +3 -2
  63. package/dist/components/Library/Sheet/Sheet.svelte +3 -3
  64. package/dist/components/Library/Slider/Slider.demo.svelte +3 -2
  65. package/dist/components/Library/Spinner/Spinner.demo.svelte +3 -2
  66. package/dist/components/Library/Switch/Switch.demo.svelte +5 -4
  67. package/dist/components/Library/Switch/Switch.svelte +6 -5
  68. package/dist/components/Library/Switch/Switch.svelte.d.ts +2 -1
  69. package/dist/components/Library/Table/Column.svelte +3 -0
  70. package/dist/components/Library/Table/Column.svelte.d.ts +1 -0
  71. package/dist/components/Library/Table/Table.demo.svelte +230 -17
  72. package/dist/components/Library/Table/Table.svelte +322 -78
  73. package/dist/components/Library/Table/Table.svelte.d.ts +5 -0
  74. package/dist/components/Library/Table/types.d.ts +1 -0
  75. package/dist/components/Library/TextField/TextField.svelte +20 -14
  76. package/dist/components/Library/TextShimmer/TextShimmer.demo.svelte +3 -2
  77. package/dist/components/Library/TimePicker/TimePicker.demo.svelte +3 -10
  78. package/dist/components/Library/TokenSearchField/TokenSearchField.demo.svelte +3 -2
  79. package/dist/components/Library/VStack/VStack.svelte +4 -4
  80. package/dist/components/Library/VStack/VStack.svelte.d.ts +2 -1
  81. package/dist/components/Local/ColorStyleControls.svelte +25 -72
  82. package/dist/components/Local/ComponentGrid.svelte +99 -27
  83. package/dist/components/Local/ComponentGrid.svelte.d.ts +2 -1
  84. package/dist/components/Local/ComponentPage.svelte +74 -0
  85. package/dist/components/Local/ComponentPage.svelte.d.ts +13 -0
  86. package/dist/components/Local/HeroCard.svelte +10 -6
  87. package/dist/components/Local/LayoutStyleControls.svelte +33 -25
  88. package/dist/components/Local/StyleControls.svelte +1 -1
  89. package/dist/index.d.ts +8 -3
  90. package/dist/index.js +4 -1
  91. package/dist/style/index.css +3 -4
  92. package/dist/style/layout.d.ts +15 -36
  93. package/dist/style/layout.js +35 -83
  94. package/dist/style/surface.d.ts +1 -0
  95. package/dist/style/surface.js +10 -0
  96. package/dist/style.css +3 -51
  97. package/dist/viewport/geometry.d.ts +8 -0
  98. package/dist/viewport/geometry.js +43 -0
  99. package/dist/viewport/index.d.ts +4 -0
  100. package/dist/viewport/index.js +4 -0
  101. package/dist/viewport/layout.d.ts +4 -0
  102. package/dist/viewport/layout.js +138 -0
  103. package/dist/viewport/placement.d.ts +4 -0
  104. package/dist/viewport/placement.js +14 -0
  105. package/dist/viewport/types.d.ts +81 -0
  106. package/dist/viewport/types.js +1 -0
  107. package/package.json +1 -1
@@ -1,43 +1,22 @@
1
1
  type StringWithAutocomplete<T extends string> = T | (string & {});
2
- export declare const LayoutSize: {
3
- readonly full: "full";
4
- readonly fit: "fit";
2
+ export declare const Axis: {
3
+ readonly X: "x";
4
+ readonly Y: "y";
5
5
  };
6
- export declare const LayoutAlignment: {
7
- readonly start: "start";
8
- readonly center: "center";
9
- readonly end: "end";
10
- readonly stretch: "stretch";
11
- readonly baseline: "baseline";
6
+ export declare const LayoutDimension: {
7
+ readonly infinity: "infinity";
12
8
  };
13
- export declare const LayoutJustification: {
14
- readonly start: "start";
15
- readonly center: "center";
16
- readonly end: "end";
17
- readonly between: "between";
18
- readonly around: "around";
19
- readonly evenly: "evenly";
20
- };
21
- export type LayoutSizeValue = (typeof LayoutSize)[keyof typeof LayoutSize];
22
- export type LayoutAlignmentValue = (typeof LayoutAlignment)[keyof typeof LayoutAlignment];
23
- export type LayoutJustificationValue = (typeof LayoutJustification)[keyof typeof LayoutJustification];
24
- export type LayoutSize = StringWithAutocomplete<LayoutSizeValue> | number;
25
- export type LayoutAlignment = LayoutAlignmentValue;
26
- export type LayoutJustification = LayoutJustificationValue;
9
+ export type AxisValue = (typeof Axis)[keyof typeof Axis];
10
+ export type LayoutDimensionValue = (typeof LayoutDimension)[keyof typeof LayoutDimension];
11
+ export type Axis = AxisValue;
12
+ export type LayoutAxis = Axis | Axis[];
13
+ export type LayoutAxisBehavior = boolean | LayoutAxis;
14
+ export type LayoutDimension = StringWithAutocomplete<LayoutDimensionValue> | number;
27
15
  export type LayoutProps = {
28
- size?: LayoutSize;
29
- width?: number | string;
30
- height?: number | string;
31
- minWidth?: number | string;
32
- minHeight?: number | string;
33
- maxWidth?: number | string;
34
- maxHeight?: number | string;
35
- grow?: boolean | number;
36
- shrink?: boolean | number;
37
- basis?: number | string;
38
- border?: boolean | string;
39
- align?: LayoutAlignment;
40
- justify?: LayoutJustification;
16
+ grow?: LayoutAxisBehavior;
17
+ fit?: LayoutAxisBehavior;
18
+ width?: LayoutDimension;
19
+ height?: LayoutDimension;
41
20
  };
42
21
  export declare const extractLayoutProps: <T extends Record<string, unknown>>(props: T) => {
43
22
  layoutProps: Partial<LayoutProps>;
@@ -1,71 +1,41 @@
1
- export const LayoutSize = {
2
- full: 'full',
3
- fit: 'fit'
1
+ export const Axis = {
2
+ X: 'x',
3
+ Y: 'y'
4
4
  };
5
- export const LayoutAlignment = {
6
- start: 'start',
7
- center: 'center',
8
- end: 'end',
9
- stretch: 'stretch',
10
- baseline: 'baseline'
5
+ export const LayoutDimension = {
6
+ infinity: 'infinity'
11
7
  };
12
- export const LayoutJustification = {
13
- start: 'start',
14
- center: 'center',
15
- end: 'end',
16
- between: 'between',
17
- around: 'around',
18
- evenly: 'evenly'
19
- };
20
- const LAYOUT_PROP_KEYS = new Set([
21
- 'size',
22
- 'width',
23
- 'height',
24
- 'minWidth',
25
- 'minHeight',
26
- 'maxWidth',
27
- 'maxHeight',
28
- 'grow',
29
- 'shrink',
30
- 'basis',
31
- 'border',
32
- 'align',
33
- 'justify'
34
- ]);
8
+ const LAYOUT_PROP_KEYS = new Set(['grow', 'fit', 'width', 'height']);
35
9
  const toRem = (value) => value === undefined ? undefined : typeof value === 'number' ? `${value}rem` : value;
36
- const toSize = (value) => {
37
- if (value === 'full')
10
+ const toDimension = (value) => {
11
+ if (value === 'infinity')
38
12
  return '100%';
39
- if (value === 'fit')
40
- return 'fit-content';
41
13
  return toRem(value);
42
14
  };
15
+ const axisHas = (value, axis) => {
16
+ if (value === undefined || value === false)
17
+ return false;
18
+ if (value === true)
19
+ return true;
20
+ if (Array.isArray(value))
21
+ return value.includes(axis);
22
+ return value === axis;
23
+ };
24
+ const pushAxisDeclarations = (declarations, styles, axis, properties) => {
25
+ if (axisHas(styles.grow, axis)) {
26
+ declarations.push(`${properties.size}: 100%;`);
27
+ declarations.push(`${properties.minSize}: 0;`);
28
+ }
29
+ if (axisHas(styles.fit, axis)) {
30
+ declarations.push(`${properties.size}: fit-content;`);
31
+ }
32
+ };
43
33
  const pushDeclaration = (declarations, name, value) => {
44
- const resolved = toRem(value);
34
+ const resolved = toDimension(value);
45
35
  if (resolved === undefined)
46
36
  return;
47
37
  declarations.push(`${name}: ${resolved};`);
48
38
  };
49
- const pushFlexValue = (declarations, name, value) => {
50
- if (value === undefined)
51
- return;
52
- declarations.push(`${name}: ${value === true ? 1 : value === false ? 0 : value};`);
53
- };
54
- const alignValues = {
55
- start: 'flex-start',
56
- center: 'center',
57
- end: 'flex-end',
58
- stretch: 'stretch',
59
- baseline: 'baseline'
60
- };
61
- const justifyValues = {
62
- start: 'flex-start',
63
- center: 'center',
64
- end: 'flex-end',
65
- between: 'space-between',
66
- around: 'space-around',
67
- evenly: 'space-evenly'
68
- };
69
39
  export const extractLayoutProps = (props) => {
70
40
  const layoutProps = {};
71
41
  const restProps = {};
@@ -85,33 +55,15 @@ export const layoutStyle = (styles) => {
85
55
  if (!styles)
86
56
  return '';
87
57
  const declarations = [];
88
- const resolvedSize = toSize(styles.size);
89
- if (resolvedSize !== undefined) {
90
- declarations.push(`width: ${resolvedSize};`, `height: ${resolvedSize};`);
91
- }
58
+ pushAxisDeclarations(declarations, styles, Axis.X, {
59
+ size: 'width',
60
+ minSize: 'min-width'
61
+ });
62
+ pushAxisDeclarations(declarations, styles, Axis.Y, {
63
+ size: 'height',
64
+ minSize: 'min-height'
65
+ });
92
66
  pushDeclaration(declarations, 'width', styles.width);
93
67
  pushDeclaration(declarations, 'height', styles.height);
94
- pushDeclaration(declarations, 'min-width', styles.minWidth);
95
- pushDeclaration(declarations, 'min-height', styles.minHeight);
96
- pushDeclaration(declarations, 'max-width', styles.maxWidth);
97
- pushDeclaration(declarations, 'max-height', styles.maxHeight);
98
- pushFlexValue(declarations, 'flex-grow', styles.grow);
99
- pushFlexValue(declarations, 'flex-shrink', styles.shrink);
100
- pushDeclaration(declarations, 'flex-basis', styles.basis);
101
- if (styles.border === true) {
102
- declarations.push('border: 1px solid var(--sveltely-border-color);');
103
- }
104
- else if (typeof styles.border === 'string') {
105
- const borderValue = /\b(solid|dashed|dotted|double|none|hidden)\b|\d/.test(styles.border)
106
- ? styles.border
107
- : `1px solid ${styles.border}`;
108
- declarations.push(`border: ${borderValue};`);
109
- }
110
- if (styles.align !== undefined) {
111
- declarations.push(`align-items: ${alignValues[styles.align]};`);
112
- }
113
- if (styles.justify !== undefined) {
114
- declarations.push(`justify-content: ${justifyValues[styles.justify]};`);
115
- }
116
68
  return declarations.join(' ');
117
69
  };
@@ -5,6 +5,7 @@ export type StyleProps = {
5
5
  gap?: number;
6
6
  borderRadius?: number;
7
7
  inset?: number;
8
+ border?: boolean | string;
8
9
  background?: string;
9
10
  borderColor?: string;
10
11
  color?: string;
@@ -5,6 +5,7 @@ const STYLE_PROP_KEYS = new Set([
5
5
  'gap',
6
6
  'borderRadius',
7
7
  'inset',
8
+ 'border',
8
9
  'background',
9
10
  'borderColor',
10
11
  'color'
@@ -45,6 +46,15 @@ export const surfaceStyle = (styles, prefix = 'surface') => {
45
46
  pushVar(declarations, `--${prefix}-gap`, styles.gap);
46
47
  pushVar(declarations, `--${prefix}-border-radius`, styles.borderRadius);
47
48
  pushVar(declarations, `--${prefix}-inset`, styles.inset);
49
+ if (styles.border === true) {
50
+ declarations.push('border: 1px solid var(--sveltely-border-color);');
51
+ }
52
+ else if (typeof styles.border === 'string') {
53
+ const borderValue = /\b(solid|dashed|dotted|double|none|hidden)\b|\d/.test(styles.border)
54
+ ? styles.border
55
+ : `1px solid ${styles.border}`;
56
+ declarations.push(`border: ${borderValue};`);
57
+ }
48
58
  if (styles.background !== undefined) {
49
59
  declarations.push(`background: ${styles.background};`);
50
60
  }
package/dist/style.css CHANGED
@@ -24,8 +24,6 @@
24
24
  --color-black: #000;
25
25
  --color-white: #fff;
26
26
  --spacing: 0.25rem;
27
- --container-sm: 24rem;
28
- --container-md: 28rem;
29
27
  --container-3xl: 48rem;
30
28
  --text-xs: 0.75rem;
31
29
  --text-xs--line-height: calc(1 / 0.75);
@@ -289,9 +287,6 @@
289
287
  .h-5 {
290
288
  height: calc(var(--spacing) * 5);
291
289
  }
292
- .h-36 {
293
- height: calc(var(--spacing) * 36);
294
- }
295
290
  .h-full {
296
291
  height: 100%;
297
292
  }
@@ -313,30 +308,15 @@
313
308
  .max-w-3xl {
314
309
  max-width: var(--container-3xl);
315
310
  }
316
- .max-w-md {
317
- max-width: var(--container-md);
318
- }
319
- .max-w-sm {
320
- max-width: var(--container-sm);
321
- }
322
- .min-w-0 {
323
- min-width: calc(var(--spacing) * 0);
324
- }
325
311
  .flex-1 {
326
312
  flex: 1;
327
313
  }
328
314
  .flex-shrink {
329
315
  flex-shrink: 1;
330
316
  }
331
- .shrink {
332
- flex-shrink: 1;
333
- }
334
317
  .shrink-0 {
335
318
  flex-shrink: 0;
336
319
  }
337
- .flex-grow {
338
- flex-grow: 1;
339
- }
340
320
  .grow {
341
321
  flex-grow: 1;
342
322
  }
@@ -379,30 +359,15 @@
379
359
  .items-center {
380
360
  align-items: center;
381
361
  }
382
- .items-start {
383
- align-items: flex-start;
384
- }
385
362
  .justify-between {
386
363
  justify-content: space-between;
387
364
  }
388
365
  .justify-center {
389
366
  justify-content: center;
390
367
  }
391
- .gap-0\.5 {
392
- gap: calc(var(--spacing) * 0.5);
393
- }
394
- .gap-1 {
395
- gap: calc(var(--spacing) * 1);
396
- }
397
368
  .gap-2 {
398
369
  gap: calc(var(--spacing) * 2);
399
370
  }
400
- .gap-3 {
401
- gap: calc(var(--spacing) * 3);
402
- }
403
- .gap-4 {
404
- gap: calc(var(--spacing) * 4);
405
- }
406
371
  .space-y-1 {
407
372
  :where(& > :not(:last-child)) {
408
373
  --tw-space-y-reverse: 0;
@@ -473,9 +438,6 @@
473
438
  .bg-transparent {
474
439
  background-color: transparent;
475
440
  }
476
- .bg-white {
477
- background-color: var(--color-white);
478
- }
479
441
  .bg-zinc-100 {
480
442
  background-color: var(--color-zinc-100);
481
443
  }
@@ -771,16 +733,6 @@
771
733
  opacity: 50%;
772
734
  }
773
735
  }
774
- .md\:grid-cols-2 {
775
- @media (width >= 48rem) {
776
- grid-template-columns: repeat(2, minmax(0, 1fr));
777
- }
778
- }
779
- .md\:grid-cols-\[minmax\(0\,18rem\)_minmax\(8rem\,1fr\)\] {
780
- @media (width >= 48rem) {
781
- grid-template-columns: minmax(0,18rem) minmax(8rem,1fr);
782
- }
783
- }
784
736
  }
785
737
  @layer base {
786
738
  :root {
@@ -850,13 +802,13 @@
850
802
  justify-content: center;
851
803
  }
852
804
  .vstack {
853
- display: flex;
805
+ display: inline-flex;
854
806
  min-height: calc(var(--spacing) * 0);
855
807
  min-width: calc(var(--spacing) * 0);
856
808
  flex-direction: column;
857
809
  }
858
810
  .hstack {
859
- display: flex;
811
+ display: inline-flex;
860
812
  min-height: calc(var(--spacing) * 0);
861
813
  min-width: calc(var(--spacing) * 0);
862
814
  flex-direction: row;
@@ -865,7 +817,7 @@
865
817
  flex-shrink: 0;
866
818
  }
867
819
  }
868
- .overflow-auto > .vstack, .overflow-auto > .hstack, .overflow-auto > .grid {
820
+ .overflow-auto > .vstack, .overflow-auto > .hstack {
869
821
  flex-shrink: 0;
870
822
  }
871
823
  @property --tw-rotate-x {
@@ -0,0 +1,8 @@
1
+ import type { LayoutRange, ViewportGeometry, ViewportOverscan, ViewportRect, ViewportSize } from './types';
2
+ export declare const clamp: (value: number, min: number, max: number) => number;
3
+ export declare const range: (start: number, end: number) => LayoutRange;
4
+ export declare const rectsIntersect: (first: ViewportRect, second: ViewportRect) => boolean;
5
+ export declare const overscanRect: (geometry: ViewportGeometry, overscan?: ViewportOverscan) => ViewportRect;
6
+ export declare const fixedRange: (offset: number, viewportSize: number, itemSize: number, count: number, gap?: number, overscan?: number) => LayoutRange;
7
+ export declare const sumSizes: (sizes: number[], gap?: number) => number;
8
+ export declare const emptySize: ViewportSize;
@@ -0,0 +1,43 @@
1
+ export const clamp = (value, min, max) => Math.min(Math.max(value, min), max);
2
+ export const range = (start, end) => ({
3
+ start: Math.max(0, start),
4
+ end: Math.max(start, end)
5
+ });
6
+ export const rectsIntersect = (first, second) => first.x < second.x + second.width &&
7
+ first.x + first.width > second.x &&
8
+ first.y < second.y + second.height &&
9
+ first.y + first.height > second.y;
10
+ export const overscanRect = (geometry, overscan = 0) => {
11
+ const resolved = typeof overscan === 'number'
12
+ ? {
13
+ top: overscan,
14
+ right: overscan,
15
+ bottom: overscan,
16
+ left: overscan
17
+ }
18
+ : {
19
+ top: overscan.top ?? overscan.y ?? 0,
20
+ right: overscan.right ?? overscan.x ?? 0,
21
+ bottom: overscan.bottom ?? overscan.y ?? 0,
22
+ left: overscan.left ?? overscan.x ?? 0
23
+ };
24
+ return {
25
+ x: Math.max(0, geometry.offset.x - resolved.left),
26
+ y: Math.max(0, geometry.offset.y - resolved.top),
27
+ width: geometry.viewport.width + resolved.left + resolved.right,
28
+ height: geometry.viewport.height + resolved.top + resolved.bottom
29
+ };
30
+ };
31
+ export const fixedRange = (offset, viewportSize, itemSize, count, gap = 0, overscan = 0) => {
32
+ if (count <= 0 || itemSize <= 0)
33
+ return range(0, 0);
34
+ const stride = itemSize + gap;
35
+ const start = clamp(Math.floor((offset - overscan) / stride), 0, count);
36
+ const end = clamp(Math.ceil((offset + viewportSize + overscan) / stride), start, count);
37
+ return range(start, end);
38
+ };
39
+ export const sumSizes = (sizes, gap = 0) => sizes.reduce((total, size) => total + size, 0) + Math.max(0, sizes.length - 1) * gap;
40
+ export const emptySize = {
41
+ width: 0,
42
+ height: 0
43
+ };
@@ -0,0 +1,4 @@
1
+ export * from './types';
2
+ export * from './geometry';
3
+ export * from './placement';
4
+ export * from './layout';
@@ -0,0 +1,4 @@
1
+ export * from './types';
2
+ export * from './geometry';
3
+ export * from './placement';
4
+ export * from './layout';
@@ -0,0 +1,4 @@
1
+ import type { FixedGridLayoutOptions, FixedListLayoutOptions, LayoutResult, TableViewportLayout, TableViewportLayoutOptions } from './types';
2
+ export declare const fixedListLayout: <T>({ items, viewport, itemSize, gap, overscan, key }: FixedListLayoutOptions<T>) => LayoutResult<T>;
3
+ export declare const fixedGridLayout: <T>({ items, viewport, columnWidth, rowHeight, columns, columnGap, rowGap, overscan, key }: FixedGridLayoutOptions<T>) => LayoutResult<T>;
4
+ export declare const tableViewportLayout: <T>({ rows, columns, viewport, rowHeight, headerHeight, overscan, rowKey }: TableViewportLayoutOptions<T>) => TableViewportLayout<T>;
@@ -0,0 +1,138 @@
1
+ import { fixedRange, rectsIntersect, sumSizes, overscanRect } from './geometry';
2
+ const defaultKey = (_item, index) => index;
3
+ const itemKey = (item, index, key) => String((key ?? defaultKey)(item, index));
4
+ export const fixedListLayout = ({ items, viewport, itemSize, gap = 0, overscan = 0, key }) => {
5
+ const visibleRange = fixedRange(viewport.offset.y, viewport.viewport.height, itemSize, items.length, gap, typeof overscan === 'number' ? overscan : (overscan.y ?? overscan.top ?? 0));
6
+ const contentHeight = items.length * itemSize + Math.max(0, items.length - 1) * gap;
7
+ const visible = [];
8
+ for (let index = visibleRange.start; index < visibleRange.end; index += 1) {
9
+ const item = items[index];
10
+ visible.push({
11
+ key: itemKey(item, index, key),
12
+ item,
13
+ index,
14
+ rect: {
15
+ x: 0,
16
+ y: index * (itemSize + gap),
17
+ width: viewport.viewport.width,
18
+ height: itemSize
19
+ }
20
+ });
21
+ }
22
+ return {
23
+ content: {
24
+ width: viewport.viewport.width,
25
+ height: contentHeight
26
+ },
27
+ visible
28
+ };
29
+ };
30
+ export const fixedGridLayout = ({ items, viewport, columnWidth, rowHeight, columns, columnGap = 0, rowGap = 0, overscan = 0, key }) => {
31
+ const columnCount = Math.max(1, columns);
32
+ const rowCount = Math.ceil(items.length / columnCount);
33
+ const visibleRows = fixedRange(viewport.offset.y, viewport.viewport.height, rowHeight, rowCount, rowGap, typeof overscan === 'number' ? overscan : (overscan.y ?? overscan.top ?? 0));
34
+ const visibleRect = overscanRect(viewport, overscan);
35
+ const visible = [];
36
+ for (let row = visibleRows.start; row < visibleRows.end; row += 1) {
37
+ for (let column = 0; column < columnCount; column += 1) {
38
+ const index = row * columnCount + column;
39
+ const item = items[index];
40
+ if (item === undefined)
41
+ continue;
42
+ const rect = {
43
+ x: column * (columnWidth + columnGap),
44
+ y: row * (rowHeight + rowGap),
45
+ width: columnWidth,
46
+ height: rowHeight
47
+ };
48
+ if (!rectsIntersect(rect, visibleRect))
49
+ continue;
50
+ visible.push({
51
+ key: itemKey(item, index, key),
52
+ item,
53
+ index,
54
+ rect
55
+ });
56
+ }
57
+ }
58
+ return {
59
+ content: {
60
+ width: columnCount * columnWidth + Math.max(0, columnCount - 1) * columnGap,
61
+ height: rowCount * rowHeight + Math.max(0, rowCount - 1) * rowGap
62
+ },
63
+ visible
64
+ };
65
+ };
66
+ export const tableViewportLayout = ({ rows, columns, viewport, rowHeight, headerHeight = 0, overscan = 0, rowKey }) => {
67
+ const columnWidths = columns.map((column) => column.width);
68
+ const columnOffsets = columns.map((_, index) => index === 0 ? 0 : sumSizes(columnWidths.slice(0, index)));
69
+ const contentWidth = sumSizes(columnWidths);
70
+ const contentHeight = headerHeight + rows.length * rowHeight;
71
+ const visibleRect = overscanRect(viewport, overscan);
72
+ const rowRange = fixedRange(Math.max(0, viewport.offset.y - headerHeight), viewport.viewport.height, rowHeight, rows.length, 0, typeof overscan === 'number' ? overscan : (overscan.y ?? overscan.top ?? 0));
73
+ const header = [];
74
+ const visibleRows = [];
75
+ const cells = [];
76
+ for (const [columnIndex, column] of columns.entries()) {
77
+ const rect = {
78
+ x: columnOffsets[columnIndex],
79
+ y: 0,
80
+ width: column.width,
81
+ height: headerHeight
82
+ };
83
+ if (headerHeight > 0 && rectsIntersect(rect, visibleRect)) {
84
+ header.push({
85
+ key: column.key,
86
+ item: column,
87
+ index: columnIndex,
88
+ rect
89
+ });
90
+ }
91
+ }
92
+ for (let rowIndex = rowRange.start; rowIndex < rowRange.end; rowIndex += 1) {
93
+ const row = rows[rowIndex];
94
+ const rowRect = {
95
+ x: 0,
96
+ y: headerHeight + rowIndex * rowHeight,
97
+ width: contentWidth,
98
+ height: rowHeight
99
+ };
100
+ const resolvedRowKey = itemKey(row, rowIndex, rowKey);
101
+ visibleRows.push({
102
+ key: resolvedRowKey,
103
+ item: row,
104
+ index: rowIndex,
105
+ rect: rowRect
106
+ });
107
+ for (const [columnIndex, column] of columns.entries()) {
108
+ const rect = {
109
+ x: columnOffsets[columnIndex],
110
+ y: rowRect.y,
111
+ width: column.width,
112
+ height: rowHeight
113
+ };
114
+ if (!rectsIntersect(rect, visibleRect))
115
+ continue;
116
+ cells.push({
117
+ key: `${resolvedRowKey}:${column.key}`,
118
+ index: cells.length,
119
+ item: {
120
+ row,
121
+ column,
122
+ rowIndex,
123
+ columnIndex
124
+ },
125
+ rect
126
+ });
127
+ }
128
+ }
129
+ return {
130
+ content: {
131
+ width: contentWidth,
132
+ height: contentHeight
133
+ },
134
+ header,
135
+ rows: visibleRows,
136
+ cells
137
+ };
138
+ };
@@ -0,0 +1,4 @@
1
+ import type { ViewportRect, ViewportSize } from './types';
2
+ export declare const px: (value: number) => string;
3
+ export declare const placementStyle: (rect: ViewportRect) => string;
4
+ export declare const contentStyle: (size: ViewportSize) => string;
@@ -0,0 +1,14 @@
1
+ export const px = (value) => `${Math.max(0, value)}px`;
2
+ export const placementStyle = (rect) => [
3
+ 'position: absolute;',
4
+ `width: ${px(rect.width)};`,
5
+ `height: ${px(rect.height)};`,
6
+ `transform: translate3d(${rect.x}px, ${rect.y}px, 0);`
7
+ ].join(' ');
8
+ export const contentStyle = (size) => [
9
+ 'position: relative;',
10
+ `width: ${px(size.width)};`,
11
+ `height: ${px(size.height)};`,
12
+ 'min-width: 100%;',
13
+ 'min-height: 100%;'
14
+ ].join(' ');
@@ -0,0 +1,81 @@
1
+ export type ViewportPoint = {
2
+ x: number;
3
+ y: number;
4
+ };
5
+ export type ViewportSize = {
6
+ width: number;
7
+ height: number;
8
+ };
9
+ export type ViewportRect = ViewportPoint & ViewportSize;
10
+ export type ViewportGeometry = {
11
+ offset: ViewportPoint;
12
+ viewport: ViewportSize;
13
+ };
14
+ export type ViewportOverscan = number | {
15
+ x?: number;
16
+ y?: number;
17
+ top?: number;
18
+ right?: number;
19
+ bottom?: number;
20
+ left?: number;
21
+ };
22
+ export type LayoutContentSize = ViewportSize;
23
+ export type PlacedItem<T> = {
24
+ key: string;
25
+ item: T;
26
+ rect: ViewportRect;
27
+ index: number;
28
+ };
29
+ export type LayoutResult<T> = {
30
+ content: LayoutContentSize;
31
+ visible: PlacedItem<T>[];
32
+ };
33
+ export type LayoutKey<T> = (item: T, index: number) => string | number;
34
+ export type LayoutRange = {
35
+ start: number;
36
+ end: number;
37
+ };
38
+ export type FixedListLayoutOptions<T> = {
39
+ items: T[];
40
+ viewport: ViewportGeometry;
41
+ itemSize: number;
42
+ gap?: number;
43
+ overscan?: ViewportOverscan;
44
+ key?: LayoutKey<T>;
45
+ };
46
+ export type FixedGridLayoutOptions<T> = {
47
+ items: T[];
48
+ viewport: ViewportGeometry;
49
+ columnWidth: number;
50
+ rowHeight: number;
51
+ columns: number;
52
+ columnGap?: number;
53
+ rowGap?: number;
54
+ overscan?: ViewportOverscan;
55
+ key?: LayoutKey<T>;
56
+ };
57
+ export type TableColumnLayout = {
58
+ key: string;
59
+ width: number;
60
+ };
61
+ export type TableCellPlacement<T> = {
62
+ row: T;
63
+ column: TableColumnLayout;
64
+ rowIndex: number;
65
+ columnIndex: number;
66
+ };
67
+ export type TableViewportLayoutOptions<T> = {
68
+ rows: T[];
69
+ columns: TableColumnLayout[];
70
+ viewport: ViewportGeometry;
71
+ rowHeight: number;
72
+ headerHeight?: number;
73
+ overscan?: ViewportOverscan;
74
+ rowKey?: LayoutKey<T>;
75
+ };
76
+ export type TableViewportLayout<T> = {
77
+ content: LayoutContentSize;
78
+ header: PlacedItem<TableColumnLayout>[];
79
+ rows: PlacedItem<T>[];
80
+ cells: PlacedItem<TableCellPlacement<T>>[];
81
+ };
@@ -0,0 +1 @@
1
+ export {};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@x33025/sveltely",
3
- "version": "0.1.23",
3
+ "version": "0.1.25",
4
4
  "scripts": {
5
5
  "dev": "vite dev",
6
6
  "build": "vite build && npm run prepack",