Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add steps component #305

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@
"query-string": "^7.1.1",
"react-instantsearch-hooks-web": "^6.38.1",
"react-mailchimp-subscribe": "^2.1.3",
"rehype-format": "^5.0.0",
"rehype-katex": "^7.0.0",
"rehype-mermaidjs": "^1.0.1",
"remark-gfm": "^4.0.0",
Expand Down
91 changes: 91 additions & 0 deletions src/components/Steps/Steps.astro
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
---
import { processSteps } from "./rehype-steps"

const content = await Astro.slots.render("default")
const { html } = processSteps(content)
---

<Fragment set:html={html} />

<style is:global>
.sl-steps {
--bullet-size: calc(1.75 * 1rem);
--bullet-margin: 0.375rem;

list-style: none;
counter-reset: steps-counter var(--sl-steps-start, 0);
padding-inline-start: 0;
}

.sl-steps > li {
counter-increment: steps-counter;
position: relative;
padding-inline-start: calc(var(--bullet-size) + 1rem);
/* HACK: Keeps any `margin-bottom` inside the `<li>`’s padding box to avoid gaps in the hairline border. */
padding-bottom: 1px;
/* Prevent bullets from touching in short list items. */
min-height: calc(var(--bullet-size) + var(--bullet-margin));
}
.sl-steps > li + li {
/* Remove margin between steps. */
margin-top: 0;
}

/* Custom list marker element. */
.sl-steps > li::before {
content: counter(steps-counter);
position: absolute;
top: 0;
inset-inline-start: 0;
width: var(--bullet-size);
height: var(--bullet-size);
line-height: var(--bullet-size);

font-size: var(--sl-text-xs);
font-weight: 600;
text-align: center;
color: hsl(0, 0%, 100%);
background-color: hsl(224, 14%, 16%);
border-radius: 99rem;
box-shadow: inset 0 0 0 1px hsl(224, 10%, 23%);
}

/* Vertical guideline linking list numbers. */
.sl-steps > li:not(:last-of-type)::after {
--guide-width: 1px;
content: "";
position: absolute;
top: calc(var(--bullet-size) + var(--bullet-margin));
bottom: var(--bullet-margin);
inset-inline-start: calc((var(--bullet-size) - var(--guide-width)) / 2);
width: var(--guide-width);
background-color: #24262e;
}

/* Adjust first item inside a step so that it aligns vertically with the number
even if using a larger font size (e.g. a heading) */
.sl-steps > li > :first-child {
/*
The `lh` unit is not yet supported by all browsers in our support matrix
— see https://caniuse.com/mdn-css_types_length_lh
In unsupported browsers we approximate this using our known line-heights.
*/
--lh: calc(1em * var(--sl-line-height));
--shift-y: calc(0.5 * (var(--bullet-size) - var(--lh)));
transform: translateY(var(--shift-y));
margin-bottom: var(--shift-y);
}
.sl-steps > li > :first-child:where(h1, h2, h3, h4, h5, h6) {
--lh: calc(1em * var(--sl-line-height-headings));
}
@supports (--prop: 1lh) {
.sl-steps > li > :first-child {
--lh: 1lh;
}
}

.sl-steps .expressive-code {
margin-top: 1rem;
margin-bottom: 1.25rem;
}
</style>
44 changes: 44 additions & 0 deletions src/components/Steps/rehype-steps.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import type { Element, Root } from "hast"
import { rehype } from "rehype"
import rehypeFormat from "rehype-format"
import type { VFile } from "vfile"

const prettyPrintProcessor = rehype().data("settings", { fragment: true }).use(rehypeFormat)
const prettyPrintHtml = (html: string) => prettyPrintProcessor.processSync({ value: html }).toString()

const stepsProcessor = rehype()
.data("settings", { fragment: true })
.use(function steps() {
return (tree: Root, vfile: VFile) => {
const rootElements = tree.children.filter((item): item is Element => item.type === "element")
const [rootElement] = rootElements

// Ensure `role="list"` is set on the ordered list.
// We use `list-style: none` in the styles for this component and need to ensure the list
// retains its semantics in Safari, which will remove them otherwise.
rootElement.properties.role = "list"
// Add the required CSS class name, preserving existing classes if present.
if (!Array.isArray(rootElement.properties.className)) {
rootElement.properties.className = ["sl-steps"]
} else {
rootElement.properties.className.push("sl-steps")
}

// Add the `start` attribute as a CSS custom property so we can use it as the starting index
// of the steps custom counter.
if (typeof rootElement.properties.start === "number") {
const styles = [`--sl-steps-start: ${rootElement.properties.start - 1}`]
if (rootElement.properties.style) styles.push(String(rootElement.properties.style))
rootElement.properties.style = styles.join(";")
}
}
})

/**
* Process steps children: validates the HTML and adds `role="list"` to the ordered list.
* @param html Inner HTML passed to the `<Steps>` component.
*/
export const processSteps = (html: string | undefined) => {
const file = stepsProcessor.processSync({ value: html })
return { html: file.toString() }
}
16 changes: 16 additions & 0 deletions src/content/docs/en/article-components.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import Aside from "../../../components/Aside.astro"
import MarkmapView from "../../../components/MarkmapView/index.astro"
import RPCTable from "../../../components/RPCTable/RPCTable.astro"
import { Tabs, TabsContent } from "../../../components/Tabs"
import Steps from '../../../components/Steps/Steps.astro';

This is body text right under the article title. It typically is just paragraph text that's pretty straightforward. Then there's **bold text**, and _italic text_, and **_bold-italic text_**, and `inline-code` and **`bold inline code`** and even _`italic inline code`_ and **_`bold italic inline code`_**. And of course don't forget [links](#), and [**bold links**](#), and [_italic links_](#), and [**_bold-italic links_**](#).

Expand All @@ -38,6 +39,21 @@ What else do we have?

##### H5 Heading

### Steps


<Steps>

1. Import the component into your MDX file:

```js
import { Steps } from '@astrojs/starlight/components';
```

2. Wrap `<Steps>` around your ordered list items.

</Steps>

Let's see a horizontal rule.

---
Expand Down