-
Notifications
You must be signed in to change notification settings - Fork 77
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: add mode publisher to manage component modes
required to reduce file size of calcite.css
- Loading branch information
1 parent
aa33ba3
commit 2772014
Showing
3 changed files
with
63 additions
and
0 deletions.
There are no files selected for viewing
2 changes: 2 additions & 0 deletions
2
packages/calcite-components/src/components/accordion-item/accordion-item.scss
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
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
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,53 @@ | ||
// Default | ||
let modeStore: Mode = "light"; | ||
// TODO: is this the right local storage key name? | ||
export const storageKey = "calcite-theme"; | ||
export type Mode = "dark" | "light"; | ||
export type Disconnect = () => void; | ||
|
||
export type ModePublisher<T> = () => { | ||
(value: T): void; | ||
subscribe(listener: (msg: T) => void): () => boolean; | ||
}; | ||
|
||
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types | ||
export const modePublisher = <T>() => { | ||
const listeners = new Set<(value: T) => void>(); | ||
function createPublisher(value: T) { | ||
for (const cb of listeners) { | ||
cb(value); | ||
} | ||
} | ||
createPublisher.subscribe = (listener: (msg: T) => void) => { | ||
listeners.add(listener); | ||
return () => listeners.delete(listener); | ||
}; | ||
return createPublisher; | ||
}; | ||
|
||
type GetMode<T> = { | ||
(): T; | ||
subscribe(cb: (arg: T) => void): Disconnect; | ||
}; | ||
|
||
if (window.matchMedia && window.matchMedia("(prefers-color-scheme: light)").matches) { | ||
// is light | ||
modeStore = "light"; | ||
} else if (window.matchMedia && window.matchMedia("(prefers-color-scheme: dark)").matches) { | ||
// is dark | ||
modeStore = "dark"; | ||
} | ||
|
||
let pub: ReturnType<ModePublisher<Mode>>; | ||
|
||
export const getMode: GetMode<Mode> = () => (localStorage.getItem(storageKey) as Mode) ?? modeStore; | ||
|
||
getMode.subscribe = (cb: (arg: Mode) => void) => { | ||
pub = pub ?? modePublisher<Mode>(); | ||
return pub.subscribe(cb); | ||
}; | ||
|
||
export const setMode = (mode: Mode): void => { | ||
localStorage.setItem(storageKey, mode); | ||
pub && pub(mode); | ||
}; |