forked from microsoft/fast
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: enable shared CSSStyleSheets in DesignSystemProvider (microsoft…
…#4065) * adding tests for ensuring CSS custom properties exist * use a HTMLStyleSheet element instead of inline style if addoptedStyleSheets is not supported * wire assignable custom property stylesheet * fixing comment * manager incorporated * correct dsp property behavior * ensure registry gets updated when stylesheet updates * adding parent provider resolution tests * more tests * refactor to invert control of the custom property manager to make testing easier * organize the custom property manager to its own file * export manager * write manager code * add some provider tests to test subscription and unsubscription * cleanup * revert checkbox fixture * address comments * adding documentation Co-authored-by: nicholasrice <nicholasrice@users.noreply.github.com>
- Loading branch information
1 parent
bd09fbc
commit 5579c2e
Showing
7 changed files
with
1,058 additions
and
99 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
1 change: 1 addition & 0 deletions
1
packages/web-components/fast-foundation/src/custom-properties/index.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,2 @@ | ||
export * from "./behavior"; | ||
export * from "./manager"; |
191 changes: 191 additions & 0 deletions
191
packages/web-components/fast-foundation/src/custom-properties/manager.spec.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,191 @@ | ||
import { customElement, elements, FASTElement } from "@microsoft/fast-element"; | ||
import { assert, expect } from "chai"; | ||
import { fixture } from "../fixture"; | ||
import { CSSCustomPropertyDefinition } from "./behavior"; | ||
import { | ||
ConstructableStylesCustomPropertyManager, | ||
CustomPropertyManagerClient, | ||
StyleElementCustomPropertyManager, | ||
} from "./manager"; | ||
|
||
@customElement("fast-client") | ||
class Client extends FASTElement implements CustomPropertyManagerClient { | ||
public evaluate(definition: CSSCustomPropertyDefinition) { | ||
return typeof definition.value === "function" | ||
? definition.value() | ||
: definition.value; | ||
} | ||
|
||
public cssCustomPropertyDefinitions = new Map(); | ||
} | ||
|
||
async function setup() { | ||
const { element, connect, disconnect } = await fixture<Client>("fast-client"); | ||
|
||
return { | ||
element, | ||
connect, | ||
disconnect, | ||
}; | ||
} | ||
|
||
describe("ConstructableStylesCustomPropertyManager", () => { | ||
it("should construct with a constructable stylesheet", () => { | ||
assert(new ConstructableStylesCustomPropertyManager(new CSSStyleSheet())); | ||
}); | ||
|
||
describe("on subscription", () => { | ||
it("should set the subscriber to the owner if it is the first subscriber", async () => { | ||
const { element, connect, disconnect } = await setup(); | ||
const manager = new ConstructableStylesCustomPropertyManager( | ||
new CSSStyleSheet() | ||
); | ||
|
||
await connect(); | ||
manager.subscribe(element); | ||
|
||
expect(manager.owner).to.equal(element); | ||
await disconnect(); | ||
}); | ||
it("should keep the first subscriber as the owner after multiple subscribers", async () => { | ||
const { element, connect, disconnect } = await setup(); | ||
const clone = element.cloneNode() as Client; | ||
document.body.appendChild(clone); | ||
const manager = new ConstructableStylesCustomPropertyManager( | ||
new CSSStyleSheet() | ||
); | ||
|
||
await connect(); | ||
manager.subscribe(element); | ||
manager.subscribe(clone); | ||
|
||
expect(manager.owner).to.equal(element); | ||
await disconnect(); | ||
}); | ||
it("should evaluate and write the value of all CSSCustomPropertyDefinitions in the client", async () => { | ||
const { element, connect, disconnect } = await setup(); | ||
const manager = new ConstructableStylesCustomPropertyManager( | ||
new CSSStyleSheet() | ||
); | ||
|
||
await connect(); | ||
element.cssCustomPropertyDefinitions.set("my-property", { | ||
name: "my-property", | ||
value: "value", | ||
}); | ||
|
||
manager.subscribe(element); | ||
|
||
expect( | ||
window.getComputedStyle(element).getPropertyValue("--my-property") | ||
).to.equal("value"); | ||
await disconnect(); | ||
}); | ||
}); | ||
describe("on un-subscription", () => { | ||
it("should set the owner to null if it is the only subscriber", async () => { | ||
const { element, connect, disconnect } = await setup(); | ||
const manager = new ConstructableStylesCustomPropertyManager( | ||
new CSSStyleSheet() | ||
); | ||
|
||
await connect(); | ||
manager.subscribe(element); | ||
manager.unsubscribe(element); | ||
|
||
expect(manager.owner).to.equal(null); | ||
await disconnect(); | ||
}); | ||
it("of the owner should set the owner to the subsequent subscriber", async () => { | ||
const { element, connect, disconnect } = await setup(); | ||
const b = element.cloneNode() as Client; | ||
const c = element.cloneNode() as Client; | ||
document.body.appendChild(b); | ||
document.body.appendChild(c); | ||
const manager = new ConstructableStylesCustomPropertyManager( | ||
new CSSStyleSheet() | ||
); | ||
|
||
await connect(); | ||
manager.subscribe(element); | ||
manager.subscribe(b); | ||
manager.subscribe(c); | ||
|
||
manager.unsubscribe(element); | ||
expect(manager.owner).to.equal(b); | ||
|
||
await disconnect(); | ||
}); | ||
it("should remove all CSSCustomPropertyDefinition custom properties in the client", async () => { | ||
const { element, connect, disconnect } = await setup(); | ||
const manager = new ConstructableStylesCustomPropertyManager( | ||
new CSSStyleSheet() | ||
); | ||
|
||
await connect(); | ||
element.cssCustomPropertyDefinitions.set("my-property", { | ||
name: "my-property", | ||
value: "value", | ||
}); | ||
|
||
manager.subscribe(element); | ||
manager.unsubscribe(element); | ||
|
||
expect( | ||
window.getComputedStyle(element).getPropertyValue("--my-property") | ||
).to.equal(""); | ||
await disconnect(); | ||
}); | ||
}); | ||
}); | ||
|
||
describe("StyleElementCustomPropertyManager", () => { | ||
it("should construct with a style element and client instance", async () => { | ||
const { element, connect, disconnect } = await setup(); | ||
|
||
await connect(); | ||
|
||
assert( | ||
new StyleElementCustomPropertyManager( | ||
document.createElement("style"), | ||
element | ||
) | ||
); | ||
|
||
await disconnect(); | ||
}); | ||
|
||
it("should connect the style element to the DOM during construction", async () => { | ||
const { element, connect, disconnect } = await setup(); | ||
|
||
await connect(); | ||
const style = document.createElement("style"); | ||
|
||
const manager = new StyleElementCustomPropertyManager(style, element); | ||
|
||
assert(style.isConnected); | ||
assert(element.shadowRoot?.contains(style)); | ||
|
||
await disconnect(); | ||
}); | ||
|
||
it("should evaluate and write the value of all CSSCustomPropertyDefinitions in the client on construction", async () => { | ||
const { element, connect, disconnect } = await setup(); | ||
|
||
element.cssCustomPropertyDefinitions.set("my-property", { | ||
name: "my-property", | ||
value: "value", | ||
}); | ||
|
||
await connect(); | ||
const style = document.createElement("style"); | ||
const manager = new StyleElementCustomPropertyManager(style, element); | ||
|
||
assert.equal( | ||
window.getComputedStyle(element).getPropertyValue("--my-property"), | ||
"value" | ||
); | ||
|
||
await disconnect(); | ||
}); | ||
}); |
Oops, something went wrong.