@astronox/core 0.4.6 → 0.4.7
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/package.json +1 -1
- package/src/composition/Stack/Stack.astro +1 -1
- package/src/composition/Stack/Stack.css +4 -0
- package/src/composition/SurfaceGroup/SurfaceGroup.css +10 -4
- package/src/composition/SurfaceGroup/stickySurfaceGroupController.ts +16 -0
- package/src/patterns/Table/Table.css +3 -6
- package/src/patterns/Table/tableViewport.ts +13 -9
package/package.json
CHANGED
|
@@ -3,7 +3,7 @@ import type { HTMLAttributes } from 'astro/types';
|
|
|
3
3
|
import type { Tone } from '../../theme/contracts';
|
|
4
4
|
|
|
5
5
|
type StackElement = 'div' | 'form' | 'section' | 'nav';
|
|
6
|
-
type StackGap = 'none' | 'xs' | 'sm' | 'md' | 'lg' | 'xl';
|
|
6
|
+
type StackGap = 'none' | 'xs' | 'sm' | 'md' | 'lg' | 'xl' | 'layout';
|
|
7
7
|
type StackAttributes = HTMLAttributes<'div'> &
|
|
8
8
|
HTMLAttributes<'form'> &
|
|
9
9
|
HTMLAttributes<'section'> &
|
|
@@ -16,9 +16,15 @@
|
|
|
16
16
|
pointer-events: none;
|
|
17
17
|
}
|
|
18
18
|
|
|
19
|
+
.surface-group:has(> [data-sticky-surface]) {
|
|
20
|
+
--surface-group-sticky-surface-block-size: var(
|
|
21
|
+
--nox-section-responsive-block-size
|
|
22
|
+
);
|
|
23
|
+
}
|
|
24
|
+
|
|
19
25
|
.surface-group:has(> [data-sticky-surface])::before {
|
|
20
26
|
--surface-group-sticky-occlusion-size: calc(
|
|
21
|
-
var(--nox-layout-gap) + var(--
|
|
27
|
+
var(--nox-layout-gap) + var(--surface-group-sticky-surface-block-size)
|
|
22
28
|
);
|
|
23
29
|
|
|
24
30
|
position: sticky;
|
|
@@ -71,9 +77,9 @@
|
|
|
71
77
|
}
|
|
72
78
|
|
|
73
79
|
@container nox-surface-group (width < 32rem) {
|
|
74
|
-
.surface-group:has(> [data-sticky-surface])
|
|
75
|
-
--surface-group-sticky-
|
|
76
|
-
|
|
80
|
+
.surface-group:has(> [data-sticky-surface]) {
|
|
81
|
+
--surface-group-sticky-surface-block-size: var(
|
|
82
|
+
--nox-section-compact-block-size
|
|
77
83
|
);
|
|
78
84
|
}
|
|
79
85
|
}
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
const noop = () => {};
|
|
2
|
+
const stickySurfaceBlockSizeProperty =
|
|
3
|
+
'--surface-group-sticky-surface-block-size';
|
|
2
4
|
|
|
3
5
|
const getScrollParent = (element: HTMLElement): HTMLElement | Window => {
|
|
4
6
|
let parent = element.parentElement;
|
|
@@ -37,12 +39,21 @@ export const initStickySurfaceGroup = (root: HTMLElement): (() => void) => {
|
|
|
37
39
|
stickySurface.before(sentinel);
|
|
38
40
|
|
|
39
41
|
let observer: IntersectionObserver | null = null;
|
|
42
|
+
let surfaceResizeObserver: ResizeObserver | null = null;
|
|
40
43
|
let resizeFrame = 0;
|
|
41
44
|
|
|
42
45
|
const observe = () => {
|
|
43
46
|
resizeFrame = 0;
|
|
44
47
|
observer?.disconnect();
|
|
45
48
|
|
|
49
|
+
const stickySurfaceBlockSize = stickySurface.getBoundingClientRect().height;
|
|
50
|
+
if (stickySurfaceBlockSize > 0) {
|
|
51
|
+
root.style.setProperty(
|
|
52
|
+
stickySurfaceBlockSizeProperty,
|
|
53
|
+
`${stickySurfaceBlockSize}px`,
|
|
54
|
+
);
|
|
55
|
+
}
|
|
56
|
+
|
|
46
57
|
const stickyOffset =
|
|
47
58
|
Number.parseFloat(window.getComputedStyle(stickySurface).top) || 0;
|
|
48
59
|
observer = new IntersectionObserver(
|
|
@@ -72,11 +83,15 @@ export const initStickySurfaceGroup = (root: HTMLElement): (() => void) => {
|
|
|
72
83
|
|
|
73
84
|
root.setAttribute('data-sticky-initialized', 'true');
|
|
74
85
|
window.addEventListener('resize', scheduleObserve, { passive: true });
|
|
86
|
+
surfaceResizeObserver =
|
|
87
|
+
'ResizeObserver' in window ? new ResizeObserver(scheduleObserve) : null;
|
|
88
|
+
surfaceResizeObserver?.observe(stickySurface);
|
|
75
89
|
observe();
|
|
76
90
|
|
|
77
91
|
return () => {
|
|
78
92
|
window.removeEventListener('resize', scheduleObserve);
|
|
79
93
|
observer?.disconnect();
|
|
94
|
+
surfaceResizeObserver?.disconnect();
|
|
80
95
|
sentinel.remove();
|
|
81
96
|
|
|
82
97
|
if (resizeFrame !== 0) {
|
|
@@ -85,5 +100,6 @@ export const initStickySurfaceGroup = (root: HTMLElement): (() => void) => {
|
|
|
85
100
|
|
|
86
101
|
root.removeAttribute('data-sticky-active');
|
|
87
102
|
root.removeAttribute('data-sticky-initialized');
|
|
103
|
+
root.style.removeProperty(stickySurfaceBlockSizeProperty);
|
|
88
104
|
};
|
|
89
105
|
};
|
|
@@ -49,7 +49,9 @@
|
|
|
49
49
|
|
|
50
50
|
.table[data-table-sticky-header]:has([data-sticky-surface])
|
|
51
51
|
[data-table-header] {
|
|
52
|
-
top: calc(
|
|
52
|
+
top: calc(
|
|
53
|
+
var(--nox-layout-gap) + var(--surface-group-sticky-surface-block-size)
|
|
54
|
+
);
|
|
53
55
|
}
|
|
54
56
|
|
|
55
57
|
@container nox-table (width < 32rem) {
|
|
@@ -57,11 +59,6 @@
|
|
|
57
59
|
--table-cell-padding-inline: var(--nox-space-1);
|
|
58
60
|
--table-edge-padding-inline: var(--nox-space-2);
|
|
59
61
|
}
|
|
60
|
-
|
|
61
|
-
.table[data-table-sticky-header]:has([data-sticky-surface])
|
|
62
|
-
[data-table-header] {
|
|
63
|
-
top: calc(var(--nox-layout-gap) + var(--nox-section-compact-block-size));
|
|
64
|
-
}
|
|
65
62
|
}
|
|
66
63
|
|
|
67
64
|
@container nox-table (width < 36rem) {
|
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
type TableStartScrollInput = {
|
|
2
2
|
currentScrollTop: number;
|
|
3
|
-
|
|
3
|
+
stickyOffset: number;
|
|
4
4
|
tableTop: number;
|
|
5
5
|
viewportTop: number;
|
|
6
6
|
};
|
|
7
7
|
|
|
8
8
|
export function resolveTableStartScrollTop({
|
|
9
9
|
currentScrollTop,
|
|
10
|
-
|
|
10
|
+
stickyOffset,
|
|
11
11
|
tableTop,
|
|
12
12
|
viewportTop,
|
|
13
13
|
}: TableStartScrollInput): number {
|
|
14
|
-
const targetTop = viewportTop +
|
|
14
|
+
const targetTop = viewportTop + stickyOffset;
|
|
15
15
|
if (tableTop >= targetTop) return currentScrollTop;
|
|
16
16
|
|
|
17
17
|
return Math.max(0, currentScrollTop + tableTop - targetTop);
|
|
@@ -21,18 +21,22 @@ export function resolveTableScrollRoot(root: HTMLElement): HTMLElement | null {
|
|
|
21
21
|
return root.closest<HTMLElement>('[data-site-viewport]');
|
|
22
22
|
}
|
|
23
23
|
|
|
24
|
+
function resolveTableStickyOffset(root: HTMLElement): number {
|
|
25
|
+
const stickySurface = root.querySelector<HTMLElement>(
|
|
26
|
+
'[data-sticky-surface]',
|
|
27
|
+
);
|
|
28
|
+
if (!stickySurface) return 0;
|
|
29
|
+
|
|
30
|
+
return Number.parseFloat(window.getComputedStyle(stickySurface).top) || 0;
|
|
31
|
+
}
|
|
32
|
+
|
|
24
33
|
export function revealTableStart(root: HTMLElement): void {
|
|
25
34
|
const scrollRoot = resolveTableScrollRoot(root);
|
|
26
35
|
if (!scrollRoot) return;
|
|
27
36
|
|
|
28
37
|
const nextScrollTop = resolveTableStartScrollTop({
|
|
29
38
|
currentScrollTop: scrollRoot.scrollTop,
|
|
30
|
-
|
|
31
|
-
Number.parseFloat(
|
|
32
|
-
window
|
|
33
|
-
.getComputedStyle(document.documentElement)
|
|
34
|
-
.getPropertyValue('--nox-layout-gap'),
|
|
35
|
-
) || 0,
|
|
39
|
+
stickyOffset: resolveTableStickyOffset(root),
|
|
36
40
|
tableTop: root.getBoundingClientRect().top,
|
|
37
41
|
viewportTop: scrollRoot.getBoundingClientRect().top,
|
|
38
42
|
});
|