Skip to content

Commit bf5f826

Browse files
authored
Merge pull request #2667 from redsh4de/feat/stableid-helper
use sha256 for deterministic ids [beta]
2 parents 1f70722 + e6a5e1d commit bf5f826

4 files changed

Lines changed: 16 additions & 16 deletions

File tree

src/components/ui/accordion/Accordion.astro

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
---
22
import AccordionItem from "./AccordionItem.astro";
3+
import { stableId } from "@/utils/stableId";
34
45
export interface AccordionItemType {
56
title: string;
@@ -13,15 +14,11 @@ export interface Props {
1314
}
1415
1516
const { items, multiExpand = false, variant = "default" } = Astro.props;
16-
if (items?.some((i) => typeof i.title !== "string" || !i.title.trim())) {
17+
const titles = items?.map((i) => i.title) ?? [];
18+
if (titles.some((t) => !t.trim())) {
1719
throw new Error("<Accordion> item has an empty title.");
1820
}
19-
const accordionId = items?.length
20-
? `${variant}-${[...items.map((i) => i.title).join("")]
21-
.slice(0, 7)
22-
.map((c) => c.codePointAt(0))
23-
.join("-")}`
24-
: `${variant}-slot`;
21+
const accordionId = `${variant}-${titles.length ? stableId(titles) : "slot"}`;
2522
const accordionName = multiExpand ? undefined : `accordion-${accordionId}`;
2623
---
2724

src/components/ui/header/NavItem.astro

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import type { ImageMetadata } from "astro";
44
import MaskIcon from "@/components/ui/icons/MaskIcon.astro";
55
import NavDropdownLink from "./NavDropdownLink.astro";
66
import { icons } from "@/utils/icons";
7+
import { stableId } from "@/utils/stableId";
78
89
export interface DropdownItem {
910
label: string;
@@ -21,11 +22,8 @@ export interface Props {
2122
2223
const { label, href, dropdown = [] } = Astro.props;
2324
const isDropdown = dropdown.length > 0;
24-
const id = `dd-${[...label]
25-
.slice(0, 7)
26-
.map((c) => c.codePointAt(0))
27-
.join("-")}`;
28-
const closeId = id + "-close";
25+
const id = `dd-${stableId(label)}`;
26+
const closeId = `${id}-close`;
2927
---
3028

3129
<li class="nav-item" data-is-dropdown={isDropdown || undefined}>

src/components/ui/tabs/SectionTabs.astro

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
---
2+
import { stableId } from "@/utils/stableId";
3+
24
interface Tab {
35
label: string;
46
count?: number;
@@ -15,10 +17,7 @@ if (!tabs || tabs.length === 0) {
1517
throw new Error("<SectionTabs> requires at least one tab");
1618
}
1719
18-
const uid = `stabs-${[...tabs.map((t) => t.label).join("")]
19-
.slice(0, 7)
20-
.map((c) => c.codePointAt(0))
21-
.join("-")}`;
20+
const uid = `stabs-${stableId(tabs.map((t) => t.label))}`;
2221
---
2322

2423
<div class:list={["section-tabs", className]} id={uid}>

src/utils/stableId.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
import { createHash } from "node:crypto";
2+
3+
export const stableId = (input: string | string[], length = 12): string => {
4+
const data = typeof input === "string" ? input : JSON.stringify(input);
5+
return createHash("sha256").update(data).digest("hex").slice(0, length);
6+
};

0 commit comments

Comments
 (0)