@brytdesigns/web-component-gnav-header 1.0.1 → 1.0.2
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/dist/esm/index.js
CHANGED
|
@@ -33,11 +33,13 @@ var CSSVars = {
|
|
|
33
33
|
stickyHeaderHeight: "--sticky-header-height",
|
|
34
34
|
stickyHeaderTop: "--sticky-header-top"
|
|
35
35
|
};
|
|
36
|
-
function updateCssVar(
|
|
37
|
-
|
|
36
|
+
function updateCssVar(varName, amount) {
|
|
37
|
+
document.documentElement.style.setProperty(CSSVars[varName], `${amount}px`);
|
|
38
38
|
}
|
|
39
|
-
function getCssVarValue(
|
|
40
|
-
const raw = getComputedStyle(
|
|
39
|
+
function getCssVarValue(varName) {
|
|
40
|
+
const raw = getComputedStyle(document.documentElement).getPropertyValue(
|
|
41
|
+
CSSVars[varName]
|
|
42
|
+
);
|
|
41
43
|
return parseFloat(raw) || 0;
|
|
42
44
|
}
|
|
43
45
|
|
|
@@ -83,8 +85,8 @@ var Component = (props, { element }) => {
|
|
|
83
85
|
if (!sections().length) {
|
|
84
86
|
console.warn("No gnav-header-section found!");
|
|
85
87
|
}
|
|
86
|
-
updateCssVar(
|
|
87
|
-
updateCssVar(
|
|
88
|
+
updateCssVar("headerHeight", element.offsetHeight);
|
|
89
|
+
updateCssVar("collapsedHeaderHeight", getCollapsedHeaderHeight());
|
|
88
90
|
const observer = new MutationObserver((mutations) => {
|
|
89
91
|
const relevant = mutations.some(
|
|
90
92
|
(m) => nodesContainSection(m.addedNodes) || nodesContainSection(m.removedNodes)
|
|
@@ -106,12 +108,8 @@ var Component = (props, { element }) => {
|
|
|
106
108
|
previousScroll = Math.max(0, window.scrollY);
|
|
107
109
|
}
|
|
108
110
|
const handleResize = debounce(function() {
|
|
109
|
-
updateCssVar(
|
|
110
|
-
updateCssVar(
|
|
111
|
-
element,
|
|
112
|
-
"collapsedHeaderHeight",
|
|
113
|
-
getCollapsedHeaderHeight()
|
|
114
|
-
);
|
|
111
|
+
updateCssVar("headerHeight", element.offsetHeight);
|
|
112
|
+
updateCssVar("collapsedHeaderHeight", getCollapsedHeaderHeight());
|
|
115
113
|
if (props.collapsed) handleScrollDownAnimation();
|
|
116
114
|
else handleScrollUpAnimation();
|
|
117
115
|
}, 200);
|
|
@@ -191,8 +189,8 @@ var Component = (props, { element }) => {
|
|
|
191
189
|
offset += bounding.height;
|
|
192
190
|
animations.push(animation);
|
|
193
191
|
});
|
|
194
|
-
updateCssVar(
|
|
195
|
-
updateCssVar(
|
|
192
|
+
updateCssVar("stickyHeaderHeight", offset);
|
|
193
|
+
updateCssVar("collapsedHeaderHeight", offset);
|
|
196
194
|
animations.push(animateStickyHeaderTop());
|
|
197
195
|
return awaitAllAnimations(animations);
|
|
198
196
|
}
|
|
@@ -202,24 +200,20 @@ var Component = (props, { element }) => {
|
|
|
202
200
|
if (!currentSections.length) return;
|
|
203
201
|
await awaitInFlightSectionAnimations(currentSections);
|
|
204
202
|
if (id !== runId) return;
|
|
205
|
-
updateCssVar(
|
|
206
|
-
element,
|
|
207
|
-
"stickyHeaderHeight",
|
|
208
|
-
element.getBoundingClientRect().height
|
|
209
|
-
);
|
|
203
|
+
updateCssVar("stickyHeaderHeight", element.getBoundingClientRect().height);
|
|
210
204
|
return awaitAllAnimations([
|
|
211
205
|
animate(currentSections, { y: "0px" }, getTransition(element)),
|
|
212
206
|
animateStickyHeaderTop(false)
|
|
213
207
|
]);
|
|
214
208
|
}
|
|
215
209
|
function animateStickyHeaderTop(isScrollingDown = true) {
|
|
216
|
-
let from = getCssVarValue(
|
|
210
|
+
let from = getCssVarValue("stickyHeaderTop");
|
|
217
211
|
if (!from)
|
|
218
212
|
from = isScrollingDown ? element.offsetHeight : getCollapsedHeaderHeight();
|
|
219
213
|
const to = isScrollingDown ? getCollapsedHeaderHeight() : element.getBoundingClientRect().height;
|
|
220
214
|
return animate(from, to, {
|
|
221
215
|
...getTransition(element),
|
|
222
|
-
onUpdate: (latest) => updateCssVar(
|
|
216
|
+
onUpdate: (latest) => updateCssVar("stickyHeaderTop", latest)
|
|
223
217
|
});
|
|
224
218
|
}
|
|
225
219
|
};
|
package/dist/esm/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/components/gnav-header.ts","../../src/utils.ts","../../src/components/gnav-header-section.ts","../../src/index.ts"],"names":["Component","Name"],"mappings":"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","file":"index.js","sourcesContent":["import { type CorrectComponentType } from \"@brytdesigns/web-component-core/utils\";\nimport {\n awaitAllAnimations,\n getTransitionConfig,\n} from \"@brytdesigns/web-component-core/animation\";\nimport { debounce } from \"@solid-primitives/scheduled\";\nimport { onCleanup, createEffect, createSignal, on } from \"solid-js\";\nimport { animate } from \"motion\";\n\nimport { groupBy, updateCssVar, getCssVarValue } from \"../utils.js\";\n\nexport type Props = {\n scrollThreshold: number;\n collapsed: boolean;\n};\n\nexport const Name = `gnav-header`;\n\nconst SECTION_TAG = \"gnav-header-section\";\n\nfunction awaitInFlightSectionAnimations(sections: HTMLElement[]) {\n return Promise.allSettled(\n sections.flatMap((section) =>\n section.getAnimations().map((animation) => animation.finished),\n ),\n );\n}\n\nfunction nodesContainSection(nodes: NodeList): boolean {\n return Array.from(nodes).some(\n (node) =>\n node instanceof Element &&\n (node.tagName.toLowerCase() === SECTION_TAG ||\n node.querySelector(SECTION_TAG) !== null),\n );\n}\n\nfunction getTransition(host: HTMLElement) {\n const fromCss = getTransitionConfig(getComputedStyle(host));\n const cleaned = Object.fromEntries(\n Object.entries(fromCss).filter(([, v]) => v !== undefined),\n );\n return { duration: 0.3, ease: \"easeOut\" as const, ...cleaned };\n}\n\nexport const Component: CorrectComponentType<Props> = (props, { element }) => {\n const [sections, setSections] = createSignal<HTMLElement[]>([]);\n let runId = 0;\n\n function setupSection(section: HTMLElement, position: number) {\n section.setAttribute(\"position\", String(position));\n if (!section.style.position) section.style.position = \"relative\";\n if (section.hasAttribute(\"hide-on-trigger\")) section.style.zIndex = \"99\";\n else section.style.zIndex = \"100\";\n }\n\n function refreshSections() {\n const found = Array.from(\n document.querySelectorAll<HTMLElement>(SECTION_TAG),\n );\n found.forEach((section, i) => setupSection(section, i + 1));\n setSections(found);\n }\n\n refreshSections();\n\n if (!sections().length) {\n console.warn(\"No gnav-header-section found!\");\n }\n\n updateCssVar(element, \"headerHeight\", element.offsetHeight);\n updateCssVar(element, \"collapsedHeaderHeight\", getCollapsedHeaderHeight());\n\n const observer = new MutationObserver((mutations) => {\n const relevant = mutations.some(\n (m) =>\n nodesContainSection(m.addedNodes) ||\n nodesContainSection(m.removedNodes),\n );\n if (relevant) refreshSections();\n });\n observer.observe(document.body, { childList: true, subtree: true });\n onCleanup(() => observer.disconnect());\n\n createEffect(\n on(\n () => props.scrollThreshold,\n (scrollThreshold) => {\n const controller = new AbortController();\n let previousScroll = window.scrollY;\n\n function handleScroll() {\n const delta = window.scrollY - previousScroll;\n if (Math.abs(delta) < scrollThreshold) return;\n element.setAttribute(\"collapsed\", String(delta > 0));\n previousScroll = Math.max(0, window.scrollY);\n }\n\n const handleResize = debounce(function () {\n updateCssVar(element, \"headerHeight\", element.offsetHeight);\n updateCssVar(\n element,\n \"collapsedHeaderHeight\",\n getCollapsedHeaderHeight(),\n );\n if (props.collapsed) handleScrollDownAnimation();\n else handleScrollUpAnimation();\n }, 200);\n\n window.addEventListener(\"scroll\", handleScroll, {\n capture: true,\n signal: controller.signal,\n });\n window.addEventListener(\"resize\", handleResize, {\n capture: true,\n signal: controller.signal,\n });\n\n onCleanup(() => {\n controller.abort();\n handleResize.clear();\n });\n },\n ),\n );\n\n createEffect(\n on(\n () => props.collapsed,\n (collapsed) => {\n if (collapsed) {\n return handleScrollDownAnimation();\n }\n return handleScrollUpAnimation();\n },\n ),\n );\n\n function shouldHideSectionOnTrigger(section: HTMLElement) {\n return section.hasAttribute(\"hide-on-trigger\");\n }\n\n function getCollapsedHeaderHeight() {\n return sections().reduce((total, section) => {\n if (shouldHideSectionOnTrigger(section)) return total;\n return total + section.getBoundingClientRect().height;\n }, 0);\n }\n\n function getGroupedSections() {\n return groupBy(sections(), (section) =>\n shouldHideSectionOnTrigger(section) ? \"hidden\" : \"visible\",\n );\n }\n\n async function handleScrollDownAnimation() {\n const id = ++runId;\n const currentSections = sections();\n if (!currentSections.length) return;\n\n await awaitInFlightSectionAnimations(currentSections);\n if (id !== runId) return;\n\n const transition = getTransition(element);\n const animations = [];\n const groupedSections = getGroupedSections();\n\n if (!groupedSections.hidden) groupedSections.hidden = [];\n if (!groupedSections.visible) groupedSections.visible = [];\n\n let offset = groupedSections.hidden.reduce((total, el) => {\n return total + el.getBoundingClientRect().height;\n }, 0);\n\n groupedSections.hidden.forEach((section) => {\n const bounding = section.getBoundingClientRect();\n const animation = animate(\n section,\n { y: `${(section.offsetTop + offset) * -1}px` },\n transition,\n );\n offset -= bounding.height;\n animations.push(animation);\n });\n\n offset = 0;\n\n groupedSections.visible.forEach((section) => {\n const bounding = section.getBoundingClientRect();\n const animation = animate(\n section,\n { y: `${offset - section.offsetTop}px` },\n transition,\n );\n offset += bounding.height;\n animations.push(animation);\n });\n\n updateCssVar(element, \"stickyHeaderHeight\", offset);\n updateCssVar(element, \"collapsedHeaderHeight\", offset);\n\n animations.push(animateStickyHeaderTop());\n\n return awaitAllAnimations(animations);\n }\n\n async function handleScrollUpAnimation() {\n const id = ++runId;\n const currentSections = sections();\n if (!currentSections.length) return;\n\n await awaitInFlightSectionAnimations(currentSections);\n if (id !== runId) return;\n\n updateCssVar(\n element,\n \"stickyHeaderHeight\",\n element.getBoundingClientRect().height,\n );\n return awaitAllAnimations([\n animate(currentSections, { y: \"0px\" }, getTransition(element)),\n animateStickyHeaderTop(false),\n ]);\n }\n\n function animateStickyHeaderTop(isScrollingDown = true) {\n let from = getCssVarValue(element, \"stickyHeaderTop\");\n\n if (!from)\n from = isScrollingDown ? element.offsetHeight : getCollapsedHeaderHeight();\n\n const to = isScrollingDown\n ? getCollapsedHeaderHeight()\n : element.getBoundingClientRect().height;\n\n return animate(from, to, {\n ...getTransition(element),\n onUpdate: (latest) => updateCssVar(element, \"stickyHeaderTop\", latest),\n });\n }\n};\n","export const groupBy = <T, K extends PropertyKey>(\n list: T[],\n getKey: (item: T, index: number) => K\n) =>\n list.reduce(\n (previous, currentItem, index) => {\n const group = getKey(currentItem, index);\n if (!previous[group]) previous[group] = [];\n previous[group].push(currentItem);\n return previous;\n },\n {} as Record<K, T[]>\n );\n\nexport const CSSVars = {\n headerHeight: \"--header-height\",\n collapsedHeaderHeight: \"--collapsed-header-height\",\n stickyHeaderHeight: \"--sticky-header-height\",\n stickyHeaderTop: \"--sticky-header-top\",\n} as const;\n\nexport function updateCssVar(\n host: HTMLElement,\n varName: keyof typeof CSSVars,\n amount: number\n) {\n host.style.setProperty(CSSVars[varName], `${amount}px`);\n}\n\nexport function getCssVarValue(\n host: HTMLElement,\n varName: keyof typeof CSSVars\n): number {\n const raw = getComputedStyle(host).getPropertyValue(CSSVars[varName]);\n return parseFloat(raw) || 0;\n}\n","import type { CorrectComponentType } from \"@brytdesigns/web-component-core/utils\";\n\nexport type Props = {\n shouldTrigger: boolean;\n position: number;\n hideOnTrigger: boolean;\n};\n\nexport const Name = \"gnav-header-section\";\n\nexport const Component: CorrectComponentType<Props> = () => {};\n","import {\n\tcorrectElementType,\n\tcustomShadowlessElement,\n} from \"@brytdesigns/web-component-core/utils\";\n\nimport { GnavHeader, GnavHeaderSection } from \"./components/index.js\";\n\nexport type GnavHeaderProps = GnavHeader.Props;\nexport type GnavHeaderSectionProps = GnavHeaderSection.Props;\n\ncustomShadowlessElement(\n\tGnavHeader.Name,\n\t{\n\t\tscrollThreshold: 20,\n\t\tcollapsed: false\n\t},\n\tcorrectElementType(GnavHeader.Component),\n);\n\ncustomShadowlessElement(GnavHeaderSection.Name, {\n\thideOnTrigger: false,\n\tposition: 0,\n\tshouldTrigger: false\n}, correctElementType(GnavHeaderSection.Component))"]}
|
|
1
|
+
{"version":3,"sources":["../../src/components/gnav-header.ts","../../src/utils.ts","../../src/components/gnav-header-section.ts","../../src/index.ts"],"names":["Component","Name"],"mappings":"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","file":"index.js","sourcesContent":["import { type CorrectComponentType } from \"@brytdesigns/web-component-core/utils\";\nimport {\n awaitAllAnimations,\n getTransitionConfig,\n} from \"@brytdesigns/web-component-core/animation\";\nimport { debounce } from \"@solid-primitives/scheduled\";\nimport { onCleanup, createEffect, createSignal, on } from \"solid-js\";\nimport { animate } from \"motion\";\n\nimport { groupBy, updateCssVar, getCssVarValue } from \"../utils.js\";\n\nexport type Props = {\n scrollThreshold: number;\n collapsed: boolean;\n};\n\nexport const Name = `gnav-header`;\n\nconst SECTION_TAG = \"gnav-header-section\";\n\nfunction awaitInFlightSectionAnimations(sections: HTMLElement[]) {\n return Promise.allSettled(\n sections.flatMap((section) =>\n section.getAnimations().map((animation) => animation.finished),\n ),\n );\n}\n\nfunction nodesContainSection(nodes: NodeList): boolean {\n return Array.from(nodes).some(\n (node) =>\n node instanceof Element &&\n (node.tagName.toLowerCase() === SECTION_TAG ||\n node.querySelector(SECTION_TAG) !== null),\n );\n}\n\nfunction getTransition(host: HTMLElement) {\n const fromCss = getTransitionConfig(getComputedStyle(host));\n const cleaned = Object.fromEntries(\n Object.entries(fromCss).filter(([, v]) => v !== undefined),\n );\n return { duration: 0.3, ease: \"easeOut\" as const, ...cleaned };\n}\n\nexport const Component: CorrectComponentType<Props> = (props, { element }) => {\n const [sections, setSections] = createSignal<HTMLElement[]>([]);\n let runId = 0;\n\n function setupSection(section: HTMLElement, position: number) {\n section.setAttribute(\"position\", String(position));\n if (!section.style.position) section.style.position = \"relative\";\n if (section.hasAttribute(\"hide-on-trigger\")) section.style.zIndex = \"99\";\n else section.style.zIndex = \"100\";\n }\n\n function refreshSections() {\n const found = Array.from(\n document.querySelectorAll<HTMLElement>(SECTION_TAG),\n );\n found.forEach((section, i) => setupSection(section, i + 1));\n setSections(found);\n }\n\n refreshSections();\n\n if (!sections().length) {\n console.warn(\"No gnav-header-section found!\");\n }\n\n updateCssVar(\"headerHeight\", element.offsetHeight);\n updateCssVar(\"collapsedHeaderHeight\", getCollapsedHeaderHeight());\n\n const observer = new MutationObserver((mutations) => {\n const relevant = mutations.some(\n (m) =>\n nodesContainSection(m.addedNodes) ||\n nodesContainSection(m.removedNodes),\n );\n if (relevant) refreshSections();\n });\n observer.observe(document.body, { childList: true, subtree: true });\n onCleanup(() => observer.disconnect());\n\n createEffect(\n on(\n () => props.scrollThreshold,\n (scrollThreshold) => {\n const controller = new AbortController();\n let previousScroll = window.scrollY;\n\n function handleScroll() {\n const delta = window.scrollY - previousScroll;\n if (Math.abs(delta) < scrollThreshold) return;\n element.setAttribute(\"collapsed\", String(delta > 0));\n previousScroll = Math.max(0, window.scrollY);\n }\n\n const handleResize = debounce(function () {\n updateCssVar(\"headerHeight\", element.offsetHeight);\n updateCssVar(\"collapsedHeaderHeight\", getCollapsedHeaderHeight());\n if (props.collapsed) handleScrollDownAnimation();\n else handleScrollUpAnimation();\n }, 200);\n\n window.addEventListener(\"scroll\", handleScroll, {\n capture: true,\n signal: controller.signal,\n });\n window.addEventListener(\"resize\", handleResize, {\n capture: true,\n signal: controller.signal,\n });\n\n onCleanup(() => {\n controller.abort();\n handleResize.clear();\n });\n },\n ),\n );\n\n createEffect(\n on(\n () => props.collapsed,\n (collapsed) => {\n if (collapsed) {\n return handleScrollDownAnimation();\n }\n return handleScrollUpAnimation();\n },\n ),\n );\n\n function shouldHideSectionOnTrigger(section: HTMLElement) {\n return section.hasAttribute(\"hide-on-trigger\");\n }\n\n function getCollapsedHeaderHeight() {\n return sections().reduce((total, section) => {\n if (shouldHideSectionOnTrigger(section)) return total;\n return total + section.getBoundingClientRect().height;\n }, 0);\n }\n\n function getGroupedSections() {\n return groupBy(sections(), (section) =>\n shouldHideSectionOnTrigger(section) ? \"hidden\" : \"visible\",\n );\n }\n\n async function handleScrollDownAnimation() {\n const id = ++runId;\n const currentSections = sections();\n if (!currentSections.length) return;\n\n await awaitInFlightSectionAnimations(currentSections);\n if (id !== runId) return;\n\n const transition = getTransition(element);\n const animations = [];\n const groupedSections = getGroupedSections();\n\n if (!groupedSections.hidden) groupedSections.hidden = [];\n if (!groupedSections.visible) groupedSections.visible = [];\n\n let offset = groupedSections.hidden.reduce((total, el) => {\n return total + el.getBoundingClientRect().height;\n }, 0);\n\n groupedSections.hidden.forEach((section) => {\n const bounding = section.getBoundingClientRect();\n const animation = animate(\n section,\n { y: `${(section.offsetTop + offset) * -1}px` },\n transition,\n );\n offset -= bounding.height;\n animations.push(animation);\n });\n\n offset = 0;\n\n groupedSections.visible.forEach((section) => {\n const bounding = section.getBoundingClientRect();\n const animation = animate(\n section,\n { y: `${offset - section.offsetTop}px` },\n transition,\n );\n offset += bounding.height;\n animations.push(animation);\n });\n\n updateCssVar(\"stickyHeaderHeight\", offset);\n updateCssVar(\"collapsedHeaderHeight\", offset);\n\n animations.push(animateStickyHeaderTop());\n\n return awaitAllAnimations(animations);\n }\n\n async function handleScrollUpAnimation() {\n const id = ++runId;\n const currentSections = sections();\n if (!currentSections.length) return;\n\n await awaitInFlightSectionAnimations(currentSections);\n if (id !== runId) return;\n\n updateCssVar(\"stickyHeaderHeight\", element.getBoundingClientRect().height);\n return awaitAllAnimations([\n animate(currentSections, { y: \"0px\" }, getTransition(element)),\n animateStickyHeaderTop(false),\n ]);\n }\n\n function animateStickyHeaderTop(isScrollingDown = true) {\n let from = getCssVarValue(\"stickyHeaderTop\");\n\n if (!from)\n from = isScrollingDown ? element.offsetHeight : getCollapsedHeaderHeight();\n\n const to = isScrollingDown\n ? getCollapsedHeaderHeight()\n : element.getBoundingClientRect().height;\n\n return animate(from, to, {\n ...getTransition(element),\n onUpdate: (latest) => updateCssVar(\"stickyHeaderTop\", latest),\n });\n }\n};\n","export const groupBy = <T, K extends PropertyKey>(\n list: T[],\n getKey: (item: T, index: number) => K\n) =>\n list.reduce(\n (previous, currentItem, index) => {\n const group = getKey(currentItem, index);\n if (!previous[group]) previous[group] = [];\n previous[group].push(currentItem);\n return previous;\n },\n {} as Record<K, T[]>\n );\n\nexport const CSSVars = {\n headerHeight: \"--header-height\",\n collapsedHeaderHeight: \"--collapsed-header-height\",\n stickyHeaderHeight: \"--sticky-header-height\",\n stickyHeaderTop: \"--sticky-header-top\",\n} as const;\n\nexport function updateCssVar(\n varName: keyof typeof CSSVars,\n amount: number\n) {\n document.documentElement.style.setProperty(CSSVars[varName], `${amount}px`);\n}\n\nexport function getCssVarValue(varName: keyof typeof CSSVars): number {\n const raw = getComputedStyle(document.documentElement).getPropertyValue(\n CSSVars[varName]\n );\n return parseFloat(raw) || 0;\n}\n","import type { CorrectComponentType } from \"@brytdesigns/web-component-core/utils\";\n\nexport type Props = {\n shouldTrigger: boolean;\n position: number;\n hideOnTrigger: boolean;\n};\n\nexport const Name = \"gnav-header-section\";\n\nexport const Component: CorrectComponentType<Props> = () => {};\n","import {\n\tcorrectElementType,\n\tcustomShadowlessElement,\n} from \"@brytdesigns/web-component-core/utils\";\n\nimport { GnavHeader, GnavHeaderSection } from \"./components/index.js\";\n\nexport type GnavHeaderProps = GnavHeader.Props;\nexport type GnavHeaderSectionProps = GnavHeaderSection.Props;\n\ncustomShadowlessElement(\n\tGnavHeader.Name,\n\t{\n\t\tscrollThreshold: 20,\n\t\tcollapsed: false\n\t},\n\tcorrectElementType(GnavHeader.Component),\n);\n\ncustomShadowlessElement(GnavHeaderSection.Name, {\n\thideOnTrigger: false,\n\tposition: 0,\n\tshouldTrigger: false\n}, correctElementType(GnavHeaderSection.Component))"]}
|
|
@@ -46,8 +46,8 @@ const Component = (props, { element }) => {
|
|
|
46
46
|
if (!sections().length) {
|
|
47
47
|
console.warn("No gnav-header-section found!");
|
|
48
48
|
}
|
|
49
|
-
updateCssVar(
|
|
50
|
-
updateCssVar(
|
|
49
|
+
updateCssVar("headerHeight", element.offsetHeight);
|
|
50
|
+
updateCssVar("collapsedHeaderHeight", getCollapsedHeaderHeight());
|
|
51
51
|
const observer = new MutationObserver((mutations) => {
|
|
52
52
|
const relevant = mutations.some(
|
|
53
53
|
(m) => nodesContainSection(m.addedNodes) || nodesContainSection(m.removedNodes)
|
|
@@ -69,12 +69,8 @@ const Component = (props, { element }) => {
|
|
|
69
69
|
previousScroll = Math.max(0, window.scrollY);
|
|
70
70
|
}
|
|
71
71
|
const handleResize = debounce(function() {
|
|
72
|
-
updateCssVar(
|
|
73
|
-
updateCssVar(
|
|
74
|
-
element,
|
|
75
|
-
"collapsedHeaderHeight",
|
|
76
|
-
getCollapsedHeaderHeight()
|
|
77
|
-
);
|
|
72
|
+
updateCssVar("headerHeight", element.offsetHeight);
|
|
73
|
+
updateCssVar("collapsedHeaderHeight", getCollapsedHeaderHeight());
|
|
78
74
|
if (props.collapsed) handleScrollDownAnimation();
|
|
79
75
|
else handleScrollUpAnimation();
|
|
80
76
|
}, 200);
|
|
@@ -154,8 +150,8 @@ const Component = (props, { element }) => {
|
|
|
154
150
|
offset += bounding.height;
|
|
155
151
|
animations.push(animation);
|
|
156
152
|
});
|
|
157
|
-
updateCssVar(
|
|
158
|
-
updateCssVar(
|
|
153
|
+
updateCssVar("stickyHeaderHeight", offset);
|
|
154
|
+
updateCssVar("collapsedHeaderHeight", offset);
|
|
159
155
|
animations.push(animateStickyHeaderTop());
|
|
160
156
|
return awaitAllAnimations(animations);
|
|
161
157
|
}
|
|
@@ -165,24 +161,20 @@ const Component = (props, { element }) => {
|
|
|
165
161
|
if (!currentSections.length) return;
|
|
166
162
|
await awaitInFlightSectionAnimations(currentSections);
|
|
167
163
|
if (id !== runId) return;
|
|
168
|
-
updateCssVar(
|
|
169
|
-
element,
|
|
170
|
-
"stickyHeaderHeight",
|
|
171
|
-
element.getBoundingClientRect().height
|
|
172
|
-
);
|
|
164
|
+
updateCssVar("stickyHeaderHeight", element.getBoundingClientRect().height);
|
|
173
165
|
return awaitAllAnimations([
|
|
174
166
|
animate(currentSections, { y: "0px" }, getTransition(element)),
|
|
175
167
|
animateStickyHeaderTop(false)
|
|
176
168
|
]);
|
|
177
169
|
}
|
|
178
170
|
function animateStickyHeaderTop(isScrollingDown = true) {
|
|
179
|
-
let from = getCssVarValue(
|
|
171
|
+
let from = getCssVarValue("stickyHeaderTop");
|
|
180
172
|
if (!from)
|
|
181
173
|
from = isScrollingDown ? element.offsetHeight : getCollapsedHeaderHeight();
|
|
182
174
|
const to = isScrollingDown ? getCollapsedHeaderHeight() : element.getBoundingClientRect().height;
|
|
183
175
|
return animate(from, to, {
|
|
184
176
|
...getTransition(element),
|
|
185
|
-
onUpdate: (latest) => updateCssVar(
|
|
177
|
+
onUpdate: (latest) => updateCssVar("stickyHeaderTop", latest)
|
|
186
178
|
});
|
|
187
179
|
}
|
|
188
180
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/components/gnav-header.ts"],"names":[],"mappings":"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","file":"gnav-header.js","sourcesContent":["import { type CorrectComponentType } from \"@brytdesigns/web-component-core/utils\";\nimport {\n awaitAllAnimations,\n getTransitionConfig,\n} from \"@brytdesigns/web-component-core/animation\";\nimport { debounce } from \"@solid-primitives/scheduled\";\nimport { onCleanup, createEffect, createSignal, on } from \"solid-js\";\nimport { animate } from \"motion\";\n\nimport { groupBy, updateCssVar, getCssVarValue } from \"../utils.js\";\n\nexport type Props = {\n scrollThreshold: number;\n collapsed: boolean;\n};\n\nexport const Name = `gnav-header`;\n\nconst SECTION_TAG = \"gnav-header-section\";\n\nfunction awaitInFlightSectionAnimations(sections: HTMLElement[]) {\n return Promise.allSettled(\n sections.flatMap((section) =>\n section.getAnimations().map((animation) => animation.finished),\n ),\n );\n}\n\nfunction nodesContainSection(nodes: NodeList): boolean {\n return Array.from(nodes).some(\n (node) =>\n node instanceof Element &&\n (node.tagName.toLowerCase() === SECTION_TAG ||\n node.querySelector(SECTION_TAG) !== null),\n );\n}\n\nfunction getTransition(host: HTMLElement) {\n const fromCss = getTransitionConfig(getComputedStyle(host));\n const cleaned = Object.fromEntries(\n Object.entries(fromCss).filter(([, v]) => v !== undefined),\n );\n return { duration: 0.3, ease: \"easeOut\" as const, ...cleaned };\n}\n\nexport const Component: CorrectComponentType<Props> = (props, { element }) => {\n const [sections, setSections] = createSignal<HTMLElement[]>([]);\n let runId = 0;\n\n function setupSection(section: HTMLElement, position: number) {\n section.setAttribute(\"position\", String(position));\n if (!section.style.position) section.style.position = \"relative\";\n if (section.hasAttribute(\"hide-on-trigger\")) section.style.zIndex = \"99\";\n else section.style.zIndex = \"100\";\n }\n\n function refreshSections() {\n const found = Array.from(\n document.querySelectorAll<HTMLElement>(SECTION_TAG),\n );\n found.forEach((section, i) => setupSection(section, i + 1));\n setSections(found);\n }\n\n refreshSections();\n\n if (!sections().length) {\n console.warn(\"No gnav-header-section found!\");\n }\n\n updateCssVar(element, \"headerHeight\", element.offsetHeight);\n updateCssVar(element, \"collapsedHeaderHeight\", getCollapsedHeaderHeight());\n\n const observer = new MutationObserver((mutations) => {\n const relevant = mutations.some(\n (m) =>\n nodesContainSection(m.addedNodes) ||\n nodesContainSection(m.removedNodes),\n );\n if (relevant) refreshSections();\n });\n observer.observe(document.body, { childList: true, subtree: true });\n onCleanup(() => observer.disconnect());\n\n createEffect(\n on(\n () => props.scrollThreshold,\n (scrollThreshold) => {\n const controller = new AbortController();\n let previousScroll = window.scrollY;\n\n function handleScroll() {\n const delta = window.scrollY - previousScroll;\n if (Math.abs(delta) < scrollThreshold) return;\n element.setAttribute(\"collapsed\", String(delta > 0));\n previousScroll = Math.max(0, window.scrollY);\n }\n\n const handleResize = debounce(function () {\n updateCssVar(element, \"headerHeight\", element.offsetHeight);\n updateCssVar(\n element,\n \"collapsedHeaderHeight\",\n getCollapsedHeaderHeight(),\n );\n if (props.collapsed) handleScrollDownAnimation();\n else handleScrollUpAnimation();\n }, 200);\n\n window.addEventListener(\"scroll\", handleScroll, {\n capture: true,\n signal: controller.signal,\n });\n window.addEventListener(\"resize\", handleResize, {\n capture: true,\n signal: controller.signal,\n });\n\n onCleanup(() => {\n controller.abort();\n handleResize.clear();\n });\n },\n ),\n );\n\n createEffect(\n on(\n () => props.collapsed,\n (collapsed) => {\n if (collapsed) {\n return handleScrollDownAnimation();\n }\n return handleScrollUpAnimation();\n },\n ),\n );\n\n function shouldHideSectionOnTrigger(section: HTMLElement) {\n return section.hasAttribute(\"hide-on-trigger\");\n }\n\n function getCollapsedHeaderHeight() {\n return sections().reduce((total, section) => {\n if (shouldHideSectionOnTrigger(section)) return total;\n return total + section.getBoundingClientRect().height;\n }, 0);\n }\n\n function getGroupedSections() {\n return groupBy(sections(), (section) =>\n shouldHideSectionOnTrigger(section) ? \"hidden\" : \"visible\",\n );\n }\n\n async function handleScrollDownAnimation() {\n const id = ++runId;\n const currentSections = sections();\n if (!currentSections.length) return;\n\n await awaitInFlightSectionAnimations(currentSections);\n if (id !== runId) return;\n\n const transition = getTransition(element);\n const animations = [];\n const groupedSections = getGroupedSections();\n\n if (!groupedSections.hidden) groupedSections.hidden = [];\n if (!groupedSections.visible) groupedSections.visible = [];\n\n let offset = groupedSections.hidden.reduce((total, el) => {\n return total + el.getBoundingClientRect().height;\n }, 0);\n\n groupedSections.hidden.forEach((section) => {\n const bounding = section.getBoundingClientRect();\n const animation = animate(\n section,\n { y: `${(section.offsetTop + offset) * -1}px` },\n transition,\n );\n offset -= bounding.height;\n animations.push(animation);\n });\n\n offset = 0;\n\n groupedSections.visible.forEach((section) => {\n const bounding = section.getBoundingClientRect();\n const animation = animate(\n section,\n { y: `${offset - section.offsetTop}px` },\n transition,\n );\n offset += bounding.height;\n animations.push(animation);\n });\n\n updateCssVar(element, \"stickyHeaderHeight\", offset);\n updateCssVar(element, \"collapsedHeaderHeight\", offset);\n\n animations.push(animateStickyHeaderTop());\n\n return awaitAllAnimations(animations);\n }\n\n async function handleScrollUpAnimation() {\n const id = ++runId;\n const currentSections = sections();\n if (!currentSections.length) return;\n\n await awaitInFlightSectionAnimations(currentSections);\n if (id !== runId) return;\n\n updateCssVar(\n element,\n \"stickyHeaderHeight\",\n element.getBoundingClientRect().height,\n );\n return awaitAllAnimations([\n animate(currentSections, { y: \"0px\" }, getTransition(element)),\n animateStickyHeaderTop(false),\n ]);\n }\n\n function animateStickyHeaderTop(isScrollingDown = true) {\n let from = getCssVarValue(element, \"stickyHeaderTop\");\n\n if (!from)\n from = isScrollingDown ? element.offsetHeight : getCollapsedHeaderHeight();\n\n const to = isScrollingDown\n ? getCollapsedHeaderHeight()\n : element.getBoundingClientRect().height;\n\n return animate(from, to, {\n ...getTransition(element),\n onUpdate: (latest) => updateCssVar(element, \"stickyHeaderTop\", latest),\n });\n }\n};\n"]}
|
|
1
|
+
{"version":3,"sources":["../../../src/components/gnav-header.ts"],"names":[],"mappings":"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","file":"gnav-header.js","sourcesContent":["import { type CorrectComponentType } from \"@brytdesigns/web-component-core/utils\";\nimport {\n awaitAllAnimations,\n getTransitionConfig,\n} from \"@brytdesigns/web-component-core/animation\";\nimport { debounce } from \"@solid-primitives/scheduled\";\nimport { onCleanup, createEffect, createSignal, on } from \"solid-js\";\nimport { animate } from \"motion\";\n\nimport { groupBy, updateCssVar, getCssVarValue } from \"../utils.js\";\n\nexport type Props = {\n scrollThreshold: number;\n collapsed: boolean;\n};\n\nexport const Name = `gnav-header`;\n\nconst SECTION_TAG = \"gnav-header-section\";\n\nfunction awaitInFlightSectionAnimations(sections: HTMLElement[]) {\n return Promise.allSettled(\n sections.flatMap((section) =>\n section.getAnimations().map((animation) => animation.finished),\n ),\n );\n}\n\nfunction nodesContainSection(nodes: NodeList): boolean {\n return Array.from(nodes).some(\n (node) =>\n node instanceof Element &&\n (node.tagName.toLowerCase() === SECTION_TAG ||\n node.querySelector(SECTION_TAG) !== null),\n );\n}\n\nfunction getTransition(host: HTMLElement) {\n const fromCss = getTransitionConfig(getComputedStyle(host));\n const cleaned = Object.fromEntries(\n Object.entries(fromCss).filter(([, v]) => v !== undefined),\n );\n return { duration: 0.3, ease: \"easeOut\" as const, ...cleaned };\n}\n\nexport const Component: CorrectComponentType<Props> = (props, { element }) => {\n const [sections, setSections] = createSignal<HTMLElement[]>([]);\n let runId = 0;\n\n function setupSection(section: HTMLElement, position: number) {\n section.setAttribute(\"position\", String(position));\n if (!section.style.position) section.style.position = \"relative\";\n if (section.hasAttribute(\"hide-on-trigger\")) section.style.zIndex = \"99\";\n else section.style.zIndex = \"100\";\n }\n\n function refreshSections() {\n const found = Array.from(\n document.querySelectorAll<HTMLElement>(SECTION_TAG),\n );\n found.forEach((section, i) => setupSection(section, i + 1));\n setSections(found);\n }\n\n refreshSections();\n\n if (!sections().length) {\n console.warn(\"No gnav-header-section found!\");\n }\n\n updateCssVar(\"headerHeight\", element.offsetHeight);\n updateCssVar(\"collapsedHeaderHeight\", getCollapsedHeaderHeight());\n\n const observer = new MutationObserver((mutations) => {\n const relevant = mutations.some(\n (m) =>\n nodesContainSection(m.addedNodes) ||\n nodesContainSection(m.removedNodes),\n );\n if (relevant) refreshSections();\n });\n observer.observe(document.body, { childList: true, subtree: true });\n onCleanup(() => observer.disconnect());\n\n createEffect(\n on(\n () => props.scrollThreshold,\n (scrollThreshold) => {\n const controller = new AbortController();\n let previousScroll = window.scrollY;\n\n function handleScroll() {\n const delta = window.scrollY - previousScroll;\n if (Math.abs(delta) < scrollThreshold) return;\n element.setAttribute(\"collapsed\", String(delta > 0));\n previousScroll = Math.max(0, window.scrollY);\n }\n\n const handleResize = debounce(function () {\n updateCssVar(\"headerHeight\", element.offsetHeight);\n updateCssVar(\"collapsedHeaderHeight\", getCollapsedHeaderHeight());\n if (props.collapsed) handleScrollDownAnimation();\n else handleScrollUpAnimation();\n }, 200);\n\n window.addEventListener(\"scroll\", handleScroll, {\n capture: true,\n signal: controller.signal,\n });\n window.addEventListener(\"resize\", handleResize, {\n capture: true,\n signal: controller.signal,\n });\n\n onCleanup(() => {\n controller.abort();\n handleResize.clear();\n });\n },\n ),\n );\n\n createEffect(\n on(\n () => props.collapsed,\n (collapsed) => {\n if (collapsed) {\n return handleScrollDownAnimation();\n }\n return handleScrollUpAnimation();\n },\n ),\n );\n\n function shouldHideSectionOnTrigger(section: HTMLElement) {\n return section.hasAttribute(\"hide-on-trigger\");\n }\n\n function getCollapsedHeaderHeight() {\n return sections().reduce((total, section) => {\n if (shouldHideSectionOnTrigger(section)) return total;\n return total + section.getBoundingClientRect().height;\n }, 0);\n }\n\n function getGroupedSections() {\n return groupBy(sections(), (section) =>\n shouldHideSectionOnTrigger(section) ? \"hidden\" : \"visible\",\n );\n }\n\n async function handleScrollDownAnimation() {\n const id = ++runId;\n const currentSections = sections();\n if (!currentSections.length) return;\n\n await awaitInFlightSectionAnimations(currentSections);\n if (id !== runId) return;\n\n const transition = getTransition(element);\n const animations = [];\n const groupedSections = getGroupedSections();\n\n if (!groupedSections.hidden) groupedSections.hidden = [];\n if (!groupedSections.visible) groupedSections.visible = [];\n\n let offset = groupedSections.hidden.reduce((total, el) => {\n return total + el.getBoundingClientRect().height;\n }, 0);\n\n groupedSections.hidden.forEach((section) => {\n const bounding = section.getBoundingClientRect();\n const animation = animate(\n section,\n { y: `${(section.offsetTop + offset) * -1}px` },\n transition,\n );\n offset -= bounding.height;\n animations.push(animation);\n });\n\n offset = 0;\n\n groupedSections.visible.forEach((section) => {\n const bounding = section.getBoundingClientRect();\n const animation = animate(\n section,\n { y: `${offset - section.offsetTop}px` },\n transition,\n );\n offset += bounding.height;\n animations.push(animation);\n });\n\n updateCssVar(\"stickyHeaderHeight\", offset);\n updateCssVar(\"collapsedHeaderHeight\", offset);\n\n animations.push(animateStickyHeaderTop());\n\n return awaitAllAnimations(animations);\n }\n\n async function handleScrollUpAnimation() {\n const id = ++runId;\n const currentSections = sections();\n if (!currentSections.length) return;\n\n await awaitInFlightSectionAnimations(currentSections);\n if (id !== runId) return;\n\n updateCssVar(\"stickyHeaderHeight\", element.getBoundingClientRect().height);\n return awaitAllAnimations([\n animate(currentSections, { y: \"0px\" }, getTransition(element)),\n animateStickyHeaderTop(false),\n ]);\n }\n\n function animateStickyHeaderTop(isScrollingDown = true) {\n let from = getCssVarValue(\"stickyHeaderTop\");\n\n if (!from)\n from = isScrollingDown ? element.offsetHeight : getCollapsedHeaderHeight();\n\n const to = isScrollingDown\n ? getCollapsedHeaderHeight()\n : element.getBoundingClientRect().height;\n\n return animate(from, to, {\n ...getTransition(element),\n onUpdate: (latest) => updateCssVar(\"stickyHeaderTop\", latest),\n });\n }\n};\n"]}
|
package/dist/main/utils.js
CHANGED
|
@@ -13,11 +13,13 @@ const CSSVars = {
|
|
|
13
13
|
stickyHeaderHeight: "--sticky-header-height",
|
|
14
14
|
stickyHeaderTop: "--sticky-header-top"
|
|
15
15
|
};
|
|
16
|
-
function updateCssVar(
|
|
17
|
-
|
|
16
|
+
function updateCssVar(varName, amount) {
|
|
17
|
+
document.documentElement.style.setProperty(CSSVars[varName], `${amount}px`);
|
|
18
18
|
}
|
|
19
|
-
function getCssVarValue(
|
|
20
|
-
const raw = getComputedStyle(
|
|
19
|
+
function getCssVarValue(varName) {
|
|
20
|
+
const raw = getComputedStyle(document.documentElement).getPropertyValue(
|
|
21
|
+
CSSVars[varName]
|
|
22
|
+
);
|
|
21
23
|
return parseFloat(raw) || 0;
|
|
22
24
|
}
|
|
23
25
|
|
package/dist/main/utils.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/utils.ts"],"names":[],"mappings":"AAAO,MAAM,OAAU,GAAA,CACrB,IACA,EAAA,MAAA,KAEA,IAAK,CAAA,MAAA;AAAA,EACH,CAAC,QAAU,EAAA,WAAA,EAAa,KAAU,KAAA;AAChC,IAAM,MAAA,KAAA,GAAQ,MAAO,CAAA,WAAA,EAAa,KAAK,CAAA;AACvC,IAAA,IAAI,CAAC,QAAS,CAAA,KAAK,GAAY,QAAA,CAAA,KAAK,IAAI,EAAC;AACzC,IAAS,QAAA,CAAA,KAAK,CAAE,CAAA,IAAA,CAAK,WAAW,CAAA;AAChC,IAAO,OAAA,QAAA;AAAA,GACT;AAAA,EACA;AACF;AAEK,MAAM,OAAU,GAAA;AAAA,EACrB,YAAc,EAAA,iBAAA;AAAA,EACd,qBAAuB,EAAA,2BAAA;AAAA,EACvB,kBAAoB,EAAA,wBAAA;AAAA,EACpB,eAAiB,EAAA;AACnB;AAEO,SAAS,YAAA,CACd,
|
|
1
|
+
{"version":3,"sources":["../../src/utils.ts"],"names":[],"mappings":"AAAO,MAAM,OAAU,GAAA,CACrB,IACA,EAAA,MAAA,KAEA,IAAK,CAAA,MAAA;AAAA,EACH,CAAC,QAAU,EAAA,WAAA,EAAa,KAAU,KAAA;AAChC,IAAM,MAAA,KAAA,GAAQ,MAAO,CAAA,WAAA,EAAa,KAAK,CAAA;AACvC,IAAA,IAAI,CAAC,QAAS,CAAA,KAAK,GAAY,QAAA,CAAA,KAAK,IAAI,EAAC;AACzC,IAAS,QAAA,CAAA,KAAK,CAAE,CAAA,IAAA,CAAK,WAAW,CAAA;AAChC,IAAO,OAAA,QAAA;AAAA,GACT;AAAA,EACA;AACF;AAEK,MAAM,OAAU,GAAA;AAAA,EACrB,YAAc,EAAA,iBAAA;AAAA,EACd,qBAAuB,EAAA,2BAAA;AAAA,EACvB,kBAAoB,EAAA,wBAAA;AAAA,EACpB,eAAiB,EAAA;AACnB;AAEO,SAAS,YAAA,CACd,SACA,MACA,EAAA;AACA,EAAS,QAAA,CAAA,eAAA,CAAgB,MAAM,WAAY,CAAA,OAAA,CAAQ,OAAO,CAAG,EAAA,CAAA,EAAG,MAAM,CAAI,EAAA,CAAA,CAAA;AAC5E;AAEO,SAAS,eAAe,OAAuC,EAAA;AACpE,EAAA,MAAM,GAAM,GAAA,gBAAA,CAAiB,QAAS,CAAA,eAAe,CAAE,CAAA,gBAAA;AAAA,IACrD,QAAQ,OAAO;AAAA,GACjB;AACA,EAAO,OAAA,UAAA,CAAW,GAAG,CAAK,IAAA,CAAA;AAC5B","file":"utils.js","sourcesContent":["export const groupBy = <T, K extends PropertyKey>(\n list: T[],\n getKey: (item: T, index: number) => K\n) =>\n list.reduce(\n (previous, currentItem, index) => {\n const group = getKey(currentItem, index);\n if (!previous[group]) previous[group] = [];\n previous[group].push(currentItem);\n return previous;\n },\n {} as Record<K, T[]>\n );\n\nexport const CSSVars = {\n headerHeight: \"--header-height\",\n collapsedHeaderHeight: \"--collapsed-header-height\",\n stickyHeaderHeight: \"--sticky-header-height\",\n stickyHeaderTop: \"--sticky-header-top\",\n} as const;\n\nexport function updateCssVar(\n varName: keyof typeof CSSVars,\n amount: number\n) {\n document.documentElement.style.setProperty(CSSVars[varName], `${amount}px`);\n}\n\nexport function getCssVarValue(varName: keyof typeof CSSVars): number {\n const raw = getComputedStyle(document.documentElement).getPropertyValue(\n CSSVars[varName]\n );\n return parseFloat(raw) || 0;\n}\n"]}
|
package/package.json
CHANGED