Skip to content

Commit

Permalink
Add steps component
Browse files Browse the repository at this point in the history
  • Loading branch information
zzq0826 committed Jul 22, 2024
1 parent ae30f0c commit ed2922a
Show file tree
Hide file tree
Showing 4 changed files with 152 additions and 0 deletions.
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

0 comments on commit ed2922a

Please sign in to comment.