ID registration primitive

This commit is contained in:
Mats Bosson 2026-03-29 02:46:51 +07:00
parent bedfa33117
commit b291ceab50
3 changed files with 52 additions and 0 deletions

View File

@ -0,0 +1,15 @@
import type { Accessor } from "solid-js";
import { createSignal } from "solid-js";
/**
* Creates a reactive slot for an element's ID.
* Child parts (e.g. Dialog.Title) call setId on mount and clear it on cleanup.
* Parent parts (e.g. Dialog.Content) read getId to set aria-labelledby etc.
*/
export function createRegisterId(): [
Accessor<string | undefined>,
(id: string | undefined) => void,
] {
const [id, setId] = createSignal<string | undefined>(undefined);
return [id, setId];
}

View File

@ -0,0 +1,5 @@
export { createControllableSignal } from "./create-controllable-signal";
export type { CreateControllableSignalOptions } from "./create-controllable-signal";
export { createDisclosureState } from "./create-disclosure-state";
export type { CreateDisclosureStateOptions, DisclosureState } from "./create-disclosure-state";
export { createRegisterId } from "./create-register-id";

View File

@ -0,0 +1,32 @@
import { createRoot } from "solid-js";
import { describe, expect, it } from "vitest";
import { createRegisterId } from "../../src/primitives/create-register-id";
describe("createRegisterId", () => {
it("starts with undefined", () => {
createRoot((dispose) => {
const [getId] = createRegisterId();
expect(getId()).toBeUndefined();
dispose();
});
});
it("returns registered id after set", () => {
createRoot((dispose) => {
const [getId, setId] = createRegisterId();
setId("my-id");
expect(getId()).toBe("my-id");
dispose();
});
});
it("returns undefined after clearing", () => {
createRoot((dispose) => {
const [getId, setId] = createRegisterId();
setId("my-id");
setId(undefined);
expect(getId()).toBeUndefined();
dispose();
});
});
});