From 4e2f1e0233d6854f72f214e397cc74624d420b72 Mon Sep 17 00:00:00 2001 From: Benjamin Charity Date: Sat, 3 Feb 2024 00:16:07 -0500 Subject: [PATCH] feat: add wrappers for styling --- README.md | 12 +++ package.json | 4 +- src/index.ts | 83 +++++++++++--------- tests/fixtures/additionalClasses/input.html | 4 +- tests/fixtures/additionalClasses/output.html | 12 ++- tests/fixtures/basic/output.html | 8 +- tests/fixtures/customAriaLabels/output.html | 8 +- tests/fixtures/customIDs/output.html | 12 ++- tests/fixtures/customText/output.html | 8 +- tests/fixtures/disableBottomLink/output.html | 4 +- tests/fixtures/disableTopLink/output.html | 4 +- 11 files changed, 102 insertions(+), 57 deletions(-) diff --git a/README.md b/README.md index 438841e..5dce6e8 100644 --- a/README.md +++ b/README.md @@ -25,6 +25,18 @@ unified() .use(rehypeParse, {fragment: true}) .use(rehypeScrollToTop) .process('

Title

Content

') + +// Or with options: +unified() + .use(rehypeParse, {fragment: true}) + .use(rehypeScrollToTop, { + topLink: { disabled: true }, + bottomLink: { + text: `Back to top ↑`, + classes: 'animated-link-underline', + }, + }) + .process('

Title

Content

') ``` ### Input diff --git a/package.json b/package.json index d95e79a..f10b6a9 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@benjc/rehype-scroll-to-top", - "version": "0.1.3", + "version": "0.1.4", "description": "A Rehype plugin that adds a 'scroll to top' & 'scroll to bottom' links to the page.", "type": "module", "main": "dist/index.js", @@ -44,7 +44,7 @@ "vitest": "^1.2.2" }, "peerDependencies": { - "rehype": "^13.0.1", + "rehype": "^11.0.0", "unified": "^11.0.4" }, "engines": { diff --git a/src/index.ts b/src/index.ts index a7cb9a5..6e84601 100644 --- a/src/index.ts +++ b/src/index.ts @@ -10,8 +10,8 @@ export type RehypeScrollToLink = { }; export type RehypeScrollToTopOptions = { - topLink: Partial; - bottomLink: Partial; + topLink?: Partial; + bottomLink?: Partial; }; export type RehypeScrollToTopOptionsRequired = { @@ -36,45 +36,11 @@ const defaultOptions: RehypeScrollToTopOptionsRequired = { }, }; -function mergeOptions(userOptions: Partial = {}): RehypeScrollToTopOptionsRequired { - return { - bottomLink: { - ariaLabel: userOptions.bottomLink?.ariaLabel ?? defaultOptions.bottomLink.ariaLabel, - classes: userOptions.bottomLink?.classes ?? defaultOptions.bottomLink.classes, - disabled: userOptions.bottomLink?.disabled ?? defaultOptions.bottomLink.disabled, - id: userOptions.bottomLink?.id ?? defaultOptions.bottomLink.id, - text: userOptions.bottomLink?.text ?? defaultOptions.bottomLink.text, - }, - topLink: { - ariaLabel: userOptions.topLink?.ariaLabel ?? defaultOptions.topLink.ariaLabel, - classes: userOptions.topLink?.classes ?? defaultOptions.topLink.classes, - disabled: userOptions.topLink?.disabled ?? defaultOptions.topLink.disabled, - id: userOptions.topLink?.id ?? defaultOptions.topLink.id, - text: userOptions.topLink?.text ?? defaultOptions.topLink.text, - }, - }; -} - const baseClass = "scroll-to"; const bottomClass = "scroll-to--bottom"; const topClass = "scroll-to--top"; -const createLinkElement = (props: RehypeScrollToLink & { destinationId: string }): Element => { - const { ariaLabel, classes, disabled, id, text, destinationId } = props; - return { - type: "element", - tagName: "a", - properties: { - "aria-label": ariaLabel, - href: `#${destinationId}`, - id, - className: [classes], - }, - children: [{ type: "text", value: text }], - }; -}; - -const rehypeScrollToTop: Plugin<[Partial?], Root> = (options = {}) => { +const rehypeScrollToTop: Plugin<[RehypeScrollToTopOptions?], Root> = (options = {}) => { const opts = mergeOptions(options); return (tree) => { @@ -115,3 +81,46 @@ const rehypeScrollToTop: Plugin<[Partial?], Root> = (o }; export default rehypeScrollToTop; + +function mergeOptions(userOptions: Partial = {}): RehypeScrollToTopOptionsRequired { + return { + bottomLink: { + ariaLabel: userOptions.bottomLink?.ariaLabel ?? defaultOptions.bottomLink.ariaLabel, + classes: userOptions.bottomLink?.classes ?? defaultOptions.bottomLink.classes, + disabled: userOptions.bottomLink?.disabled ?? defaultOptions.bottomLink.disabled, + id: userOptions.bottomLink?.id ?? defaultOptions.bottomLink.id, + text: userOptions.bottomLink?.text ?? defaultOptions.bottomLink.text, + }, + topLink: { + ariaLabel: userOptions.topLink?.ariaLabel ?? defaultOptions.topLink.ariaLabel, + classes: userOptions.topLink?.classes ?? defaultOptions.topLink.classes, + disabled: userOptions.topLink?.disabled ?? defaultOptions.topLink.disabled, + id: userOptions.topLink?.id ?? defaultOptions.topLink.id, + text: userOptions.topLink?.text ?? defaultOptions.topLink.text, + }, + }; +} + +function createLinkElement(props: RehypeScrollToLink & { destinationId: string }): Element { + const { ariaLabel, classes, disabled, id, text, destinationId } = props; + const linkElement: Element = { + type: "element", + tagName: "a", + properties: { + "aria-label": ariaLabel, + href: `#${destinationId}`, + id, + className: [classes], + }, + children: [{ type: "text", value: text }], + }; + + return { + type: "element", + tagName: "div", + properties: { + className: ["scroll-to-wrapper"], + }, + children: [linkElement], + }; +} diff --git a/tests/fixtures/additionalClasses/input.html b/tests/fixtures/additionalClasses/input.html index 59b0a98..be63008 100644 --- a/tests/fixtures/additionalClasses/input.html +++ b/tests/fixtures/additionalClasses/input.html @@ -1,2 +1,2 @@ -

h1

-

test

+

Title

+

Content

diff --git a/tests/fixtures/additionalClasses/output.html b/tests/fixtures/additionalClasses/output.html index ce3537b..eaa7d02 100644 --- a/tests/fixtures/additionalClasses/output.html +++ b/tests/fixtures/additionalClasses/output.html @@ -1,4 +1,8 @@ -Scroll to bottom -

h1

-

test

-Scroll to top + +

Title

+

Content

+ diff --git a/tests/fixtures/basic/output.html b/tests/fixtures/basic/output.html index a7a4567..b154635 100644 --- a/tests/fixtures/basic/output.html +++ b/tests/fixtures/basic/output.html @@ -1,4 +1,8 @@ -Scroll to bottom +

Title

Content

-Scroll to top + diff --git a/tests/fixtures/customAriaLabels/output.html b/tests/fixtures/customAriaLabels/output.html index dee0104..fb5756a 100644 --- a/tests/fixtures/customAriaLabels/output.html +++ b/tests/fixtures/customAriaLabels/output.html @@ -1,4 +1,8 @@ -Scroll to bottom +

Title

Content

-Scroll to top + diff --git a/tests/fixtures/customIDs/output.html b/tests/fixtures/customIDs/output.html index 69e9c46..8c66d17 100644 --- a/tests/fixtures/customIDs/output.html +++ b/tests/fixtures/customIDs/output.html @@ -1,8 +1,12 @@ - + Scroll to bottom + > +

Title

Content

- + Scroll to top + > + diff --git a/tests/fixtures/customText/output.html b/tests/fixtures/customText/output.html index 556c52e..89be42e 100644 --- a/tests/fixtures/customText/output.html +++ b/tests/fixtures/customText/output.html @@ -1,4 +1,8 @@ -Custom top text +

Title

Content

-Custom bottom text + diff --git a/tests/fixtures/disableBottomLink/output.html b/tests/fixtures/disableBottomLink/output.html index 7af8131..7e9fd38 100644 --- a/tests/fixtures/disableBottomLink/output.html +++ b/tests/fixtures/disableBottomLink/output.html @@ -1,3 +1,5 @@ -Scroll to bottom +

Title

Content

diff --git a/tests/fixtures/disableTopLink/output.html b/tests/fixtures/disableTopLink/output.html index 0889886..c916b3e 100644 --- a/tests/fixtures/disableTopLink/output.html +++ b/tests/fixtures/disableTopLink/output.html @@ -1,3 +1,5 @@

Title

Content

-Scroll to top +