Refactor Dialog abstraction (#90)

This PR overhauls the Dialog abstractions in `studio-ui` to be more
flexible for a wider variety of use cases, and adds a placeholder
"Import Asset" sub-dialog to the Media Library dialog.
This commit is contained in:
Danny McGee
2024-03-21 22:38:33 -04:00
committed by GitHub
parent 67a12e42e2
commit 701ba04765
17 changed files with 835 additions and 283 deletions
+1
View File
@@ -1,4 +1,5 @@
export * from "./lib/decorators";
export * from "./lib/deref";
export * from "./lib/di";
export { default as bind, type Props as BindProps } from "./lib/directives/bind";
export { default as drag, type Props as DragProps } from "./lib/directives/drag";
+38
View File
@@ -0,0 +1,38 @@
import { html, render } from "lit";
import { createRef, ref } from "lit/directives/ref.js";
import { deref } from "./deref";
describe("deref", () => {
let elRef = createRef();
beforeEach(() => {
elRef = createRef();
render(html`<div ${ref(elRef)}></div>`, document.body);
});
it("should return an HTML element when given an HTML element", () => {
const el = elRef.value;
expect(el).toBeDefined();
const derefed = deref(el);
expect(derefed).toBe(el);
});
it("should return an HTML element when given a `Ref<HTMLElement>`", () => {
const el = elRef.value;
const derefed = deref(elRef);
expect(derefed).toBe(el);
});
it("should safely return `undefined` when given a nullish value", () => {
const v1 = deref(null);
expect(v1).toBe(undefined);
const v2 = deref(undefined);
expect(v2).toBe(undefined);
const v3 = deref((() => {})());
expect(v3).toBe(undefined);
});
});
+16
View File
@@ -0,0 +1,16 @@
import { Ref } from "lit/directives/ref.js";
export function deref<T>(refOrValue: Ref<T> | T | null | undefined): T | undefined {
if (isRef(refOrValue))
return refOrValue.value;
return (refOrValue ?? undefined);
}
function isRef<T>(refOrValue: Ref<T> | T): refOrValue is Ref<T> {
if (!refOrValue || typeof refOrValue !== "object")
return false;
const keys = Object.keys(refOrValue);
return keys.length === 1 && keys[0] === "value"
}