svseeds 0.1.1 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/_svseeds/DarkToggle.svelte +92 -5
- package/_svseeds/core.d.ts +1 -13
- package/_svseeds/core.js +1 -1
- package/package.json +1 -1
|
@@ -13,8 +13,96 @@
|
|
|
13
13
|
|
|
14
14
|
const ariaLabel = "Toggle theme color";
|
|
15
15
|
|
|
16
|
-
|
|
17
|
-
|
|
16
|
+
class Theme {
|
|
17
|
+
static #DARK = "dark";
|
|
18
|
+
static #LIGHT = "light";
|
|
19
|
+
static #REGEX = /\(prefers-color-scheme:\s*(light|dark)\s*\)/i;
|
|
20
|
+
static #SELECTOR = ":root";
|
|
21
|
+
#props: Map<string, Record<string, string>> = new Map();
|
|
22
|
+
#dark;
|
|
23
|
+
set dark(bool: boolean) {
|
|
24
|
+
this.#switch(bool);
|
|
25
|
+
}
|
|
26
|
+
get dark(): boolean {
|
|
27
|
+
return this.#dark;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
constructor() {
|
|
31
|
+
this.#dark = Theme.#isPreferDark();
|
|
32
|
+
this.#initProps();
|
|
33
|
+
this.#setColorScheme();
|
|
34
|
+
}
|
|
35
|
+
#switch(dark: boolean) {
|
|
36
|
+
const theme = dark ? Theme.#DARK : Theme.#LIGHT;
|
|
37
|
+
if (!this.#props.has(theme)) return;
|
|
38
|
+
this.#dark = dark;
|
|
39
|
+
this.#apply(theme);
|
|
40
|
+
}
|
|
41
|
+
#apply(theme: string) {
|
|
42
|
+
if (typeof window === "undefined") return;
|
|
43
|
+
const style = window.document.documentElement.style;
|
|
44
|
+
Object.entries(this.#props.get(theme) ?? {})
|
|
45
|
+
.forEach(([name, value]) => style.setProperty(name, value));
|
|
46
|
+
}
|
|
47
|
+
#setColorScheme() {
|
|
48
|
+
if (typeof window === "undefined") return;
|
|
49
|
+
const themes = Object.keys(this.#props).filter((x) => x === Theme.#LIGHT || x === Theme.#DARK);
|
|
50
|
+
window.document.documentElement.style.colorScheme = themes.join(" ");
|
|
51
|
+
}
|
|
52
|
+
#initProps() {
|
|
53
|
+
if (typeof window === "undefined") return;
|
|
54
|
+
const sheets = window.document.styleSheets;
|
|
55
|
+
for (let i = 0; i < sheets.length; i++) {
|
|
56
|
+
this.#scanGroup(sheets[i]);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
#scanGroup(group: CSSStyleSheet | CSSGroupingRule, theme?: string) {
|
|
60
|
+
const rules = Theme.#getRules(group);
|
|
61
|
+
if (!rules) return;
|
|
62
|
+
for (let i = 0; i < rules.length; i++) {
|
|
63
|
+
this.#scanRule(rules[i], theme);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
#scanRule(rule: CSSRule, theme?: string) {
|
|
67
|
+
if (rule instanceof CSSMediaRule) theme = this.#getTheme(rule.conditionText);
|
|
68
|
+
if (rule instanceof CSSGroupingRule) return this.#scanGroup(rule, theme);
|
|
69
|
+
if (!(rule instanceof CSSStyleRule) && !(rule instanceof CSSPageRule)) return;
|
|
70
|
+
if (rule.selectorText.includes(Theme.#SELECTOR)) this.#setProps(rule.style, theme);
|
|
71
|
+
}
|
|
72
|
+
#setProps(style: CSSStyleDeclaration, theme?: string) {
|
|
73
|
+
if (!theme) return;
|
|
74
|
+
for (let i = 0; i < style.length; i++) {
|
|
75
|
+
const prop = style[i];
|
|
76
|
+
if (prop.startsWith("--")) {
|
|
77
|
+
const value = theme ? style.getPropertyValue(prop).trim() : "";
|
|
78
|
+
this.#setEachProp(theme, prop, value);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
#getTheme(condition: string): string | undefined {
|
|
83
|
+
const match = condition.match(Theme.#REGEX);
|
|
84
|
+
return match?.[1]?.toLowerCase();
|
|
85
|
+
}
|
|
86
|
+
#setEachProp(theme: string, name: string, value: string) {
|
|
87
|
+
if (!theme) return;
|
|
88
|
+
if (!this.#props.has(theme)) this.#props.set(theme, {});
|
|
89
|
+
this.#props.get(theme)![name] = value;
|
|
90
|
+
}
|
|
91
|
+
static #getRules(sheet: CSSStyleSheet | CSSGroupingRule): CSSRuleList | undefined {
|
|
92
|
+
try {
|
|
93
|
+
return sheet.cssRules;
|
|
94
|
+
} catch (e) { // mainly, due to CORS
|
|
95
|
+
return;
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
static #isPreferDark(): boolean {
|
|
99
|
+
if (typeof window === "undefined") return true;
|
|
100
|
+
return window.matchMedia("(prefers-color-scheme: dark)").matches;
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
const theme = new Theme();
|
|
104
|
+
|
|
105
|
+
import { STATE, omit } from "./core";
|
|
18
106
|
import Toggle, { type ToggleProps, type ToggleReqdProps, type ToggleBindProps } from "./_Toggle.svelte";
|
|
19
107
|
</script>
|
|
20
108
|
|
|
@@ -23,12 +111,11 @@
|
|
|
23
111
|
|
|
24
112
|
// *** Initialize *** //
|
|
25
113
|
if (!status) status = STATE.DEFAULT;
|
|
114
|
+
dark = theme.dark;
|
|
26
115
|
const propsToggle = omit(deps?.svsToggle, "main");
|
|
27
116
|
|
|
28
117
|
// *** Bind Handlers *** //
|
|
29
|
-
$effect.pre(() => { dark;
|
|
30
|
-
untrack(() => theme.switch(dark ? "dark" : "light"));
|
|
31
|
-
});
|
|
118
|
+
$effect.pre(() => { theme.dark = dark });
|
|
32
119
|
</script>
|
|
33
120
|
|
|
34
121
|
<!---------------------------------------->
|
package/_svseeds/core.d.ts
CHANGED
|
@@ -1,8 +1,6 @@
|
|
|
1
|
-
export { type ClassRuleSet,
|
|
1
|
+
export { type ClassRuleSet, CONST, STATE, AREA, elemId, fnClass, isNeutral, omit, debounce, throttle, UniqueId, };
|
|
2
2
|
type ClassRule = Partial<Record<string, string>>;
|
|
3
3
|
type ClassRuleSet = Partial<Record<string, ClassRule>>;
|
|
4
|
-
type CssVarSet = Record<string, string>;
|
|
5
|
-
type ThemePreset = Record<string, CssVarSet>;
|
|
6
4
|
declare const CONST = "const";
|
|
7
5
|
declare const STATE: Readonly<{
|
|
8
6
|
DEFAULT: "default";
|
|
@@ -27,17 +25,7 @@ declare class UniqueId {
|
|
|
27
25
|
constructor(len?: number);
|
|
28
26
|
get(v: unknown): string | undefined;
|
|
29
27
|
}
|
|
30
|
-
declare class ThemeSwitcher {
|
|
31
|
-
#private;
|
|
32
|
-
get current(): string;
|
|
33
|
-
constructor();
|
|
34
|
-
setPreset(preset: ThemePreset): ThemeSwitcher;
|
|
35
|
-
toLight(): void;
|
|
36
|
-
toDark(): void;
|
|
37
|
-
switch(theme: string): void;
|
|
38
|
-
}
|
|
39
28
|
declare const elemId: UniqueId;
|
|
40
|
-
declare const theme: ThemeSwitcher;
|
|
41
29
|
type ClassFn = (area: string, status: string) => string | undefined;
|
|
42
30
|
declare function fnClass(name: string, preset: ClassRuleSet, style?: ClassRuleSet | string): ClassFn;
|
|
43
31
|
declare function isNeutral(status: string): boolean;
|
package/_svseeds/core.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
var t=this&&this.__assign||function(){return t=Object.assign||function(t){for(var e
|
|
1
|
+
var t=this&&this.__assign||function(){return t=Object.assign||function(t){for(var r,e=1,n=arguments.length;e<n;e++)for(var i in r=arguments[e])Object.prototype.hasOwnProperty.call(r,i)&&(t[i]=r[i]);return t},t.apply(this,arguments)},r=this&&this.__classPrivateFieldSet||function(t,r,e,n,i){if("m"===n)throw new TypeError("Private method is not writable");if("a"===n&&!i)throw new TypeError("Private accessor was defined without a setter");if("function"==typeof r?t!==r||!i:!r.has(t))throw new TypeError("Cannot write private member to an object whose class did not declare it");return"a"===n?i.call(t,e):i?i.value=e:r.set(t,e),e},e=this&&this.__classPrivateFieldGet||function(t,r,e,n){if("a"===e&&!n)throw new TypeError("Private accessor was defined without a getter");if("function"==typeof r?t!==r||!n:!r.has(t))throw new TypeError("Cannot read private member from an object whose class did not declare it");return"m"===e?n:"a"===e?n.call(t):n?n.value:r.get(t)},n=this&&this.__spreadArray||function(t,r,e){if(e||2===arguments.length)for(var n,i=0,o=r.length;i<o;i++)!n&&i in r||(n||(n=Array.prototype.slice.call(r,0,i)),n[i]=r[i]);return t.concat(n||Array.prototype.slice.call(r))};export{i as CONST,o as STATE,a as AREA,u as elemId,l as fnClass,f as isNeutral,s as omit,h as debounce,v as throttle,c as UniqueId};var i="const",o=Object.freeze({DEFAULT:"default",ACTIVE:"active",INACTIVE:"inactive"}),a=Object.freeze({WHOLE:"whole",MIDDLE:"middle",MAIN:"main",TOP:"top",LEFT:"left",RIGHT:"right",BOTTOM:"bottom",LABEL:"label",AUX:"aux",EXTRA:"extra"}),c=function(){function t(t){void 0===t&&(t=4),i.add(this),c.set(this,new Set),u.set(this,4),t>2&&r(this,u,t,"f")}var i,o,a,c,u,l,f,s;return Object.defineProperty(t.prototype,"id",{get:function(){return this.get(!0)},enumerable:!1,configurable:!0}),t.prototype.get=function(t){if(t)return e(this,c,"f").size>1e4&&e(this,c,"f").clear(),e(this,i,"m",s).call(this)},o=t,c=new WeakMap,u=new WeakMap,i=new WeakSet,l=function(){return e(o,o,"f",a)[Math.trunc(Math.random()*e(o,o,"f",a).length)]},f=function(){var t=this;return String.fromCharCode.apply(String,Array(e(this,u,"f")).fill(null).map((function(){return e(t,i,"m",l).call(t)})))},s=function(){for(var t=e(this,i,"m",f).call(this);e(this,c,"f").has(t);)t=e(this,i,"m",f).call(this);return e(this,c,"f").add(t),t},a={value:n(n([],Array.from(Array(25).keys(),(function(t){return t+65})),!0),Array.from(Array(25).keys(),(function(t){return t+97})),!0)},t}(),u=new c;function l(r,e,a){var c=function(r,e,i){if("string"==typeof i)return i.trim()?i:r;var o=function(r,e){var i=Object.keys(r);if(i.length<=0)return e;var o=Object.keys(e);if(o.length<=0)return r;var a={};return new Set(n(n([],i,!0),o,!0)).forEach((function(n){var i,o;a[n]=t(t({},null!==(i=r[n])&&void 0!==i?i:{}),null!==(o=e[n])&&void 0!==o?o:{})})),a}(e,i);return Object.keys(o).length<=0?r:o}(r,e,null!=a?a:{});return"string"==typeof c?function(t,r){return function(t,r,e){return"".concat(t," ").concat(r).concat(e===o.DEFAULT?"":" ".concat(e))}(c,t,r)}:function(t,r){return function(t,r,e){var n,a,c,u,l,f,s=null!==(a=null===(n=t[r])||void 0===n?void 0:n[i])&&void 0!==a?a:"",h=null!==(f=null!==(u=null===(c=t[r])||void 0===c?void 0:c[e])&&void 0!==u?u:null===(l=t[r])||void 0===l?void 0:l[o.DEFAULT])&&void 0!==f?f:"";return""===s&&""===h?void 0:"".concat(s).concat(s&&h?" ":"").concat(h)}(c,t,r)}}function f(t){return t!==o.ACTIVE&&t!==o.INACTIVE}function s(r){for(var e=[],n=1;n<arguments.length;n++)e[n-1]=arguments[n];if(!r)return{};var i=t({},r);return e.forEach((function(t){return delete i[t]})),i}function h(t,r){var e;return function(){for(var i=[],o=0;o<arguments.length;o++)i[o]=arguments[o];e&&clearTimeout(e),e=setTimeout((function(){r.call.apply(r,n([null],i,!1))}),t)}}function v(t,r){var e,i=0,o=function(){return Date.now()-i},a=function(t){r.call.apply(r,n([null],t,!1)),i=Date.now()};return function(){for(var r=[],n=0;n<arguments.length;n++)r[n]=arguments[n];if(!i)return a(r);clearTimeout(e),e=setTimeout((function(){o()>=t&&a(r)}),t-o())}}
|