@nonamelego/dsh-catppuccin 0.1.2 → 0.2.2
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/README.md +81 -7
- package/assets/previews/combine.py +39 -0
- package/assets/previews/combined.png +0 -0
- package/assets/previews/frappe.png +0 -0
- package/assets/previews/glass-latte.png +0 -0
- package/assets/previews/glass-mocha.png +0 -0
- package/assets/previews/latte.png +0 -0
- package/assets/previews/macchiato.png +0 -0
- package/assets/previews/mocha.png +0 -0
- package/lib/client.js +688 -30
- package/lib/client.js.map +1 -1
- package/lib/index.js +11 -39
- package/package.json +5 -9
- package/assets/previews/hero-mocha.png +0 -0
package/lib/client.js
CHANGED
|
@@ -119,7 +119,23 @@ window.__ModuleLoader__.load({
|
|
|
119
119
|
"flavor.latte": "Latte",
|
|
120
120
|
"flavor.frappe": "Frappé",
|
|
121
121
|
"flavor.macchiato": "Macchiato",
|
|
122
|
-
"flavor.mocha": "Mocha"
|
|
122
|
+
"flavor.mocha": "Mocha",
|
|
123
|
+
"glass.title": "玻璃质感",
|
|
124
|
+
"glass.description": "顶栏、侧边栏、输入框、统计行、轨迹视图的磨砂玻璃效果,一键开关。",
|
|
125
|
+
"glass.enable": "总开关",
|
|
126
|
+
"glass.on": "开启",
|
|
127
|
+
"glass.off": "关闭",
|
|
128
|
+
"glass.mode": "模式",
|
|
129
|
+
"glass.modeMica": "云母效果",
|
|
130
|
+
"glass.modeCompat": "兼容模式",
|
|
131
|
+
"glass.modeHint": "云母效果把界面改成悬浮磨砂卡片;兼容模式保持原版排版,只换玻璃材质",
|
|
132
|
+
"glass.blur": "玻璃模糊度",
|
|
133
|
+
"glass.frost": "磨砂度",
|
|
134
|
+
"glass.brightness": "背景亮度",
|
|
135
|
+
"glass.brightnessHintDark": "深色模式:0 压暗至纯黑,50 原样",
|
|
136
|
+
"glass.brightnessHintLight": "浅色模式:50 原样,100 提亮至纯白",
|
|
137
|
+
"glass.hue": "背景色调",
|
|
138
|
+
"glass.hueHint": "背景渐变与光晕的色相偏移(0–360°)"
|
|
123
139
|
};
|
|
124
140
|
/** English dictionary, checked complete against the zh key set. */
|
|
125
141
|
const en = {
|
|
@@ -129,7 +145,23 @@ window.__ModuleLoader__.load({
|
|
|
129
145
|
"flavor.latte": "Latte",
|
|
130
146
|
"flavor.frappe": "Frappé",
|
|
131
147
|
"flavor.macchiato": "Macchiato",
|
|
132
|
-
"flavor.mocha": "Mocha"
|
|
148
|
+
"flavor.mocha": "Mocha",
|
|
149
|
+
"glass.title": "Glassmorphism",
|
|
150
|
+
"glass.description": "Frosted glass for the top bar, sidebar, composer, stats line and trajectory view — one click on/off.",
|
|
151
|
+
"glass.enable": "Master switch",
|
|
152
|
+
"glass.on": "On",
|
|
153
|
+
"glass.off": "Off",
|
|
154
|
+
"glass.mode": "Mode",
|
|
155
|
+
"glass.modeMica": "Mica",
|
|
156
|
+
"glass.modeCompat": "Compatibility",
|
|
157
|
+
"glass.modeHint": "Mica restyles the UI into floating frosted cards; Compatibility keeps the stock layout and only swaps the material to glass",
|
|
158
|
+
"glass.blur": "Glass blur",
|
|
159
|
+
"glass.frost": "Frost",
|
|
160
|
+
"glass.brightness": "Backdrop brightness",
|
|
161
|
+
"glass.brightnessHintDark": "Dark mode: 0 fades to pure black, 50 unchanged",
|
|
162
|
+
"glass.brightnessHintLight": "Light mode: 50 unchanged, 100 brightens to pure white",
|
|
163
|
+
"glass.hue": "Backdrop hue",
|
|
164
|
+
"glass.hueHint": "Hue shift for the backdrop gradient and glow (0–360°)"
|
|
133
165
|
};
|
|
134
166
|
const CATPPUCCIN_FLAVORS = [
|
|
135
167
|
{
|
|
@@ -814,11 +846,581 @@ window.__ModuleLoader__.load({
|
|
|
814
846
|
}
|
|
815
847
|
];
|
|
816
848
|
//#endregion
|
|
849
|
+
//#region src/client/glass/glass-seams.ts
|
|
850
|
+
const SEAMS = [
|
|
851
|
+
{
|
|
852
|
+
attribute: "data-dsh-glass-frame",
|
|
853
|
+
selector: ":has(> [class*=\"sidebarCol\"])"
|
|
854
|
+
},
|
|
855
|
+
{
|
|
856
|
+
attribute: "data-dsh-glass-sidebar-root",
|
|
857
|
+
selector: "[class*=\"sidebarCol\"] [class*=\"root\"]",
|
|
858
|
+
first: true
|
|
859
|
+
},
|
|
860
|
+
{
|
|
861
|
+
attribute: "data-dsh-glass-surface",
|
|
862
|
+
selector: "button[class*=\"newSession\"]"
|
|
863
|
+
},
|
|
864
|
+
{
|
|
865
|
+
attribute: "data-dsh-glass-trajectory",
|
|
866
|
+
selector: "[data-conversation-composer-overlay]"
|
|
867
|
+
},
|
|
868
|
+
{
|
|
869
|
+
attribute: "data-dsh-glass-details",
|
|
870
|
+
selector: "[class*=\"detailsCol\"] [class*=\"root\"]",
|
|
871
|
+
first: true
|
|
872
|
+
},
|
|
873
|
+
{
|
|
874
|
+
attribute: "data-dsh-glass-inputbar",
|
|
875
|
+
selector: ":has(> [data-composer-card])"
|
|
876
|
+
},
|
|
877
|
+
{
|
|
878
|
+
attribute: "data-dsh-glass-add",
|
|
879
|
+
selector: "[data-composer-card] [class*=\"add\"]"
|
|
880
|
+
},
|
|
881
|
+
{
|
|
882
|
+
attribute: "data-dsh-glass-stats",
|
|
883
|
+
selector: "[data-slot=\"conversation.composer.dock\"] [class*=\"root\"]"
|
|
884
|
+
}
|
|
885
|
+
];
|
|
886
|
+
function stamp(seam) {
|
|
887
|
+
if (seam.first) {
|
|
888
|
+
const el = document.querySelector(seam.selector);
|
|
889
|
+
if (el !== null && !el.hasAttribute(seam.attribute)) el.setAttribute(seam.attribute, "");
|
|
890
|
+
return;
|
|
891
|
+
}
|
|
892
|
+
for (const el of document.querySelectorAll(seam.selector)) if (!el.hasAttribute(seam.attribute)) el.setAttribute(seam.attribute, "");
|
|
893
|
+
}
|
|
894
|
+
function stampAll() {
|
|
895
|
+
for (const seam of SEAMS) stamp(seam);
|
|
896
|
+
}
|
|
897
|
+
/**
|
|
898
|
+
* Stamp the seams once, then keep them stamped as React remounts nodes.
|
|
899
|
+
* @returns a disposer that disconnects the observer.
|
|
900
|
+
*/
|
|
901
|
+
function startGlassSeamStamper() {
|
|
902
|
+
stampAll();
|
|
903
|
+
const observer = new MutationObserver(() => {
|
|
904
|
+
stampAll();
|
|
905
|
+
});
|
|
906
|
+
observer.observe(document.documentElement, {
|
|
907
|
+
childList: true,
|
|
908
|
+
subtree: true
|
|
909
|
+
});
|
|
910
|
+
return () => {
|
|
911
|
+
observer.disconnect();
|
|
912
|
+
};
|
|
913
|
+
}
|
|
914
|
+
//#endregion
|
|
915
|
+
//#region src/client/glass/glass-layer.ts
|
|
916
|
+
/** html attribute selecting the glass layer: CSS hooks and ambient effects. */
|
|
917
|
+
const GLASS_ATTRIBUTE = "data-dsh-glass";
|
|
918
|
+
/** html attribute selecting the mica (floating-card) layout rules. */
|
|
919
|
+
const GLASS_FLOAT_ATTRIBUTE = "data-dsh-glass-float";
|
|
920
|
+
/** html attribute selecting the compatibility (stock-layout) rules. */
|
|
921
|
+
const GLASS_COMPAT_ATTRIBUTE = "data-dsh-glass-compat";
|
|
922
|
+
/** localStorage key carrying the layer enable flag. */
|
|
923
|
+
const GLASS_ENABLED_KEY = "dsh.catppuccin.glass.enabled";
|
|
924
|
+
const SETTINGS_DEFAULTS = {
|
|
925
|
+
mode: "mica",
|
|
926
|
+
blur: 14,
|
|
927
|
+
frost: 50,
|
|
928
|
+
brightness: 50,
|
|
929
|
+
hue: 0
|
|
930
|
+
};
|
|
931
|
+
/** Numeric knob keys and their localStorage names. */
|
|
932
|
+
const NUMERIC_KEYS = {
|
|
933
|
+
blur: "dsh.catppuccin.glass.blur",
|
|
934
|
+
frost: "dsh.catppuccin.glass.frost",
|
|
935
|
+
brightness: "dsh.catppuccin.glass.brightness",
|
|
936
|
+
hue: "dsh.catppuccin.glass.hue"
|
|
937
|
+
};
|
|
938
|
+
const MODE_KEY = "dsh.catppuccin.glass.mode";
|
|
939
|
+
/** Clamp a numeric knob into its sane range. */
|
|
940
|
+
function clampSetting(key, value) {
|
|
941
|
+
const max = key === "blur" ? 40 : key === "frost" || key === "brightness" ? 100 : 360;
|
|
942
|
+
return Number.isFinite(value) ? Math.min(max, Math.max(0, value)) : SETTINGS_DEFAULTS[key];
|
|
943
|
+
}
|
|
944
|
+
/** Read one numeric knob from localStorage (absent/parse failure means the default). */
|
|
945
|
+
function readSetting(key) {
|
|
946
|
+
try {
|
|
947
|
+
const raw = localStorage.getItem(NUMERIC_KEYS[key]);
|
|
948
|
+
return raw === null ? SETTINGS_DEFAULTS[key] : clampSetting(key, Number(raw));
|
|
949
|
+
} catch {
|
|
950
|
+
return SETTINGS_DEFAULTS[key];
|
|
951
|
+
}
|
|
952
|
+
}
|
|
953
|
+
/** Persist one numeric knob (storage failures keep the in-memory state). */
|
|
954
|
+
function writeSetting(key, value) {
|
|
955
|
+
try {
|
|
956
|
+
localStorage.setItem(NUMERIC_KEYS[key], String(value));
|
|
957
|
+
} catch {}
|
|
958
|
+
}
|
|
959
|
+
/** Read the rendering mode ('mica' or 'compat'). */
|
|
960
|
+
function readMode() {
|
|
961
|
+
try {
|
|
962
|
+
return localStorage.getItem(MODE_KEY) === "compat" ? "compat" : "mica";
|
|
963
|
+
} catch {
|
|
964
|
+
return "mica";
|
|
965
|
+
}
|
|
966
|
+
}
|
|
967
|
+
/** Persist the rendering mode. */
|
|
968
|
+
function writeMode(value) {
|
|
969
|
+
try {
|
|
970
|
+
localStorage.setItem(MODE_KEY, value);
|
|
971
|
+
} catch {}
|
|
972
|
+
}
|
|
973
|
+
/** Read the persisted enable flag (absent storage means the default). */
|
|
974
|
+
function readEnabled() {
|
|
975
|
+
try {
|
|
976
|
+
const raw = localStorage.getItem(GLASS_ENABLED_KEY);
|
|
977
|
+
return raw === null ? false : raw === "true";
|
|
978
|
+
} catch {
|
|
979
|
+
return false;
|
|
980
|
+
}
|
|
981
|
+
}
|
|
982
|
+
/** Persist the enable flag (storage failures keep the in-memory state). */
|
|
983
|
+
function writeEnabled(value) {
|
|
984
|
+
try {
|
|
985
|
+
localStorage.setItem(GLASS_ENABLED_KEY, String(value));
|
|
986
|
+
} catch {}
|
|
987
|
+
}
|
|
988
|
+
/** Resolved scheme from the theme service (falls back to the body attribute). */
|
|
989
|
+
function resolveDark(ctx) {
|
|
990
|
+
try {
|
|
991
|
+
return ctx.theme.getTheme().active.colorScheme === "dark";
|
|
992
|
+
} catch {
|
|
993
|
+
return document.body.hasAttribute("data-ds-dark-theme");
|
|
994
|
+
}
|
|
995
|
+
}
|
|
996
|
+
/**
|
|
997
|
+
* The ambient backdrop markup injected while enabled (CSS-only, no WebGL):
|
|
998
|
+
* the living backdrop plus the two page-edge fade bands that blur the chat
|
|
999
|
+
* content melting into the viewport edges (ported from
|
|
1000
|
+
* DSH-Transparent-UI-Plugin). All three are fixed-position, click-through,
|
|
1001
|
+
* and removed together on disable.
|
|
1002
|
+
*/
|
|
1003
|
+
const AMBIENT_MARKUP = [
|
|
1004
|
+
"<div data-dsh-glass-ambient aria-hidden=\"true\">",
|
|
1005
|
+
" <span data-dsh-glass-blob=\"1\"></span>",
|
|
1006
|
+
" <span data-dsh-glass-blob=\"2\"></span>",
|
|
1007
|
+
" <span data-dsh-glass-blob=\"3\"></span>",
|
|
1008
|
+
"</div>",
|
|
1009
|
+
"<span data-dsh-glass-fade=\"top\" aria-hidden=\"true\"></span>",
|
|
1010
|
+
"<span data-dsh-glass-fade=\"bottom\" aria-hidden=\"true\"></span>"
|
|
1011
|
+
].join("");
|
|
1012
|
+
/**
|
|
1013
|
+
* Owns the glass layer lifecycle: reads the durable enable flag and knobs,
|
|
1014
|
+
* and applies / retracts every layer on change. Cross-tab flips arrive through
|
|
1015
|
+
* the storage event; the seam observer and every subscription are released
|
|
1016
|
+
* when the plugin fiber is disposed.
|
|
1017
|
+
*/
|
|
1018
|
+
var GlassLayer = class {
|
|
1019
|
+
enabled = false;
|
|
1020
|
+
settings = { ...SETTINGS_DEFAULTS };
|
|
1021
|
+
/** Cached snapshot for the settings row (stable reference between changes). */
|
|
1022
|
+
snapshot;
|
|
1023
|
+
listeners = /* @__PURE__ */ new Set();
|
|
1024
|
+
dark = false;
|
|
1025
|
+
seamDisposer;
|
|
1026
|
+
ctx;
|
|
1027
|
+
/**
|
|
1028
|
+
* @param ctx - owning client context (listeners ride this fiber).
|
|
1029
|
+
*/
|
|
1030
|
+
constructor(ctx) {
|
|
1031
|
+
this.ctx = ctx;
|
|
1032
|
+
this.enabled = readEnabled();
|
|
1033
|
+
this.reloadSettings();
|
|
1034
|
+
this.dark = resolveDark(ctx);
|
|
1035
|
+
this.snapshot = this.buildSnapshot();
|
|
1036
|
+
ctx.effect(() => {
|
|
1037
|
+
const onStorage = (event) => {
|
|
1038
|
+
if (event.key === null) {
|
|
1039
|
+
this.reloadSettings();
|
|
1040
|
+
this.enabled = readEnabled();
|
|
1041
|
+
this.sync();
|
|
1042
|
+
} else if (event.key === "dsh.catppuccin.glass.enabled") {
|
|
1043
|
+
this.enabled = readEnabled();
|
|
1044
|
+
this.sync();
|
|
1045
|
+
} else if (event.key === MODE_KEY || event.key in NUMERIC_KEYS) {
|
|
1046
|
+
this.reloadSettings();
|
|
1047
|
+
if (this.enabled) this.applySettings();
|
|
1048
|
+
this.publish();
|
|
1049
|
+
}
|
|
1050
|
+
};
|
|
1051
|
+
window.addEventListener("storage", onStorage);
|
|
1052
|
+
const themeListener = ctx.on("theme/change", () => {
|
|
1053
|
+
this.dark = resolveDark(ctx);
|
|
1054
|
+
if (this.enabled) this.applySettings();
|
|
1055
|
+
this.publish();
|
|
1056
|
+
});
|
|
1057
|
+
return () => {
|
|
1058
|
+
window.removeEventListener("storage", onStorage);
|
|
1059
|
+
themeListener();
|
|
1060
|
+
this.unmount();
|
|
1061
|
+
};
|
|
1062
|
+
}, "catppuccin: glass layer lifecycle");
|
|
1063
|
+
this.sync();
|
|
1064
|
+
}
|
|
1065
|
+
/** Current state snapshot (stable reference until the next change). */
|
|
1066
|
+
getSnapshot() {
|
|
1067
|
+
return this.snapshot;
|
|
1068
|
+
}
|
|
1069
|
+
/** Subscribe to snapshot changes. Returns the disposer. */
|
|
1070
|
+
subscribe(listener) {
|
|
1071
|
+
this.listeners.add(listener);
|
|
1072
|
+
return () => {
|
|
1073
|
+
this.listeners.delete(listener);
|
|
1074
|
+
};
|
|
1075
|
+
}
|
|
1076
|
+
/** Flip the layer: persist, then apply or retract every owned effect. */
|
|
1077
|
+
setEnabled(value) {
|
|
1078
|
+
if (value === this.enabled) return;
|
|
1079
|
+
this.enabled = value;
|
|
1080
|
+
writeEnabled(value);
|
|
1081
|
+
this.sync();
|
|
1082
|
+
}
|
|
1083
|
+
/** Set the rendering mode ('mica' or 'compat'). */
|
|
1084
|
+
setMode(value) {
|
|
1085
|
+
if (value === this.settings.mode) return;
|
|
1086
|
+
this.settings.mode = value;
|
|
1087
|
+
writeMode(value);
|
|
1088
|
+
if (this.enabled) this.applySettings();
|
|
1089
|
+
this.publish();
|
|
1090
|
+
}
|
|
1091
|
+
/** Set the glass blur radius (px). */
|
|
1092
|
+
setBlur(value) {
|
|
1093
|
+
const next = clampSetting("blur", value);
|
|
1094
|
+
if (next === this.settings.blur) return;
|
|
1095
|
+
this.settings.blur = next;
|
|
1096
|
+
writeSetting("blur", next);
|
|
1097
|
+
if (this.enabled) this.applySettings();
|
|
1098
|
+
this.publish();
|
|
1099
|
+
}
|
|
1100
|
+
/** Set the glass frost amount (0-100). */
|
|
1101
|
+
setFrost(value) {
|
|
1102
|
+
const next = clampSetting("frost", value);
|
|
1103
|
+
if (next === this.settings.frost) return;
|
|
1104
|
+
this.settings.frost = next;
|
|
1105
|
+
writeSetting("frost", next);
|
|
1106
|
+
if (this.enabled) this.applySettings();
|
|
1107
|
+
this.publish();
|
|
1108
|
+
}
|
|
1109
|
+
/** Set the backdrop brightness (0-100: 0 = pure black, 50 = transparent, 100 = pure white). */
|
|
1110
|
+
setBrightness(value) {
|
|
1111
|
+
const next = clampSetting("brightness", value);
|
|
1112
|
+
if (next === this.settings.brightness) return;
|
|
1113
|
+
this.settings.brightness = next;
|
|
1114
|
+
writeSetting("brightness", next);
|
|
1115
|
+
if (this.enabled) this.applySettings();
|
|
1116
|
+
this.publish();
|
|
1117
|
+
}
|
|
1118
|
+
/** Set the ambient hue shift (degrees). */
|
|
1119
|
+
setHue(value) {
|
|
1120
|
+
const next = clampSetting("hue", value);
|
|
1121
|
+
if (next === this.settings.hue) return;
|
|
1122
|
+
this.settings.hue = next;
|
|
1123
|
+
writeSetting("hue", next);
|
|
1124
|
+
if (this.enabled) this.applySettings();
|
|
1125
|
+
this.publish();
|
|
1126
|
+
}
|
|
1127
|
+
/** Re-read every knob from localStorage into memory. */
|
|
1128
|
+
reloadSettings() {
|
|
1129
|
+
this.settings = {
|
|
1130
|
+
mode: readMode(),
|
|
1131
|
+
blur: readSetting("blur"),
|
|
1132
|
+
frost: readSetting("frost"),
|
|
1133
|
+
brightness: readSetting("brightness"),
|
|
1134
|
+
hue: readSetting("hue")
|
|
1135
|
+
};
|
|
1136
|
+
}
|
|
1137
|
+
buildSnapshot() {
|
|
1138
|
+
return {
|
|
1139
|
+
...this.settings,
|
|
1140
|
+
enabled: this.enabled,
|
|
1141
|
+
dark: this.dark
|
|
1142
|
+
};
|
|
1143
|
+
}
|
|
1144
|
+
publish() {
|
|
1145
|
+
this.snapshot = this.buildSnapshot();
|
|
1146
|
+
for (const listener of this.listeners) listener();
|
|
1147
|
+
}
|
|
1148
|
+
sync() {
|
|
1149
|
+
if (this.enabled) this.mount();
|
|
1150
|
+
else this.unmount();
|
|
1151
|
+
this.publish();
|
|
1152
|
+
}
|
|
1153
|
+
/** Write the knob-driven CSS variables and mode attributes onto <html>. */
|
|
1154
|
+
applySettings() {
|
|
1155
|
+
const style = document.documentElement.style;
|
|
1156
|
+
style.setProperty("--dsh-glass-blur", `${this.settings.blur}px`);
|
|
1157
|
+
style.setProperty("--dsh-glass-frost", String(Math.min(this.settings.frost / 50, 1.4)));
|
|
1158
|
+
style.setProperty("--dsh-glass-hue", `${this.settings.hue}deg`);
|
|
1159
|
+
const dark = this.dark;
|
|
1160
|
+
style.setProperty("--dsh-glass-brightness-black", String(dark ? Math.max(0, (50 - this.settings.brightness) / 50) : 0));
|
|
1161
|
+
style.setProperty("--dsh-glass-brightness-white", String(dark ? 0 : Math.max(0, (this.settings.brightness - 50) / 50)));
|
|
1162
|
+
const compat = this.settings.mode === "compat";
|
|
1163
|
+
document.documentElement.toggleAttribute(GLASS_FLOAT_ATTRIBUTE, !compat);
|
|
1164
|
+
document.documentElement.toggleAttribute(GLASS_COMPAT_ATTRIBUTE, compat);
|
|
1165
|
+
}
|
|
1166
|
+
mount() {
|
|
1167
|
+
document.documentElement.setAttribute(GLASS_ATTRIBUTE, "");
|
|
1168
|
+
this.applySettings();
|
|
1169
|
+
this.ensureAmbient();
|
|
1170
|
+
if (this.seamDisposer === void 0) this.seamDisposer = startGlassSeamStamper();
|
|
1171
|
+
}
|
|
1172
|
+
unmount() {
|
|
1173
|
+
document.documentElement.removeAttribute(GLASS_ATTRIBUTE);
|
|
1174
|
+
document.documentElement.removeAttribute(GLASS_FLOAT_ATTRIBUTE);
|
|
1175
|
+
document.documentElement.removeAttribute(GLASS_COMPAT_ATTRIBUTE);
|
|
1176
|
+
for (const node of document.querySelectorAll("[data-dsh-glass-ambient], [data-dsh-glass-fade]")) node.remove();
|
|
1177
|
+
this.seamDisposer?.();
|
|
1178
|
+
this.seamDisposer = void 0;
|
|
1179
|
+
}
|
|
1180
|
+
/** Insert the ambient backdrop + edge fades (or reuse the existing ones). */
|
|
1181
|
+
ensureAmbient() {
|
|
1182
|
+
if (document.querySelector("[data-dsh-glass-ambient]") !== null) return;
|
|
1183
|
+
const holder = document.createElement("div");
|
|
1184
|
+
holder.innerHTML = AMBIENT_MARKUP;
|
|
1185
|
+
for (const node of Array.from(holder.children)) if (node instanceof HTMLElement) document.body.append(node);
|
|
1186
|
+
}
|
|
1187
|
+
};
|
|
1188
|
+
//#endregion
|
|
1189
|
+
//#region \0dsh-css:D:\Vibe-Coding\dsh-catppuccin\src\client\glass\GlassRow.module.css.mjs
|
|
1190
|
+
const css$1 = ".SYX6rq_group{border-bottom:1px solid var(--dsw-alias-border-l2);flex-direction:column;gap:8px;padding:16px 0;display:flex}.SYX6rq_title{color:var(--dsw-alias-label-primary);font-size:14px;line-height:22px}.SYX6rq_description{color:var(--dsw-alias-label-tertiary);font-size:12px;line-height:18px}.SYX6rq_controls{flex-direction:column;gap:10px;margin-top:6px;display:flex}.SYX6rq_row{align-items:center;gap:10px;display:flex}.SYX6rq_rowLabel{width:92px;color:var(--dsw-alias-label-secondary);flex:none;font-size:12px;line-height:18px}.SYX6rq_rowHint,.SYX6rq_knobHint{color:var(--dsw-alias-label-tertiary);margin-top:-4px;margin-left:102px;font-size:12px;line-height:18px}.SYX6rq_toggle,.SYX6rq_toggleOn{border:1px solid var(--dsw-alias-border-l2);height:28px;color:var(--dsw-alias-label-primary);cursor:pointer;background:0 0;border-radius:14px;align-items:center;gap:6px;padding:0 10px 0 6px;font-size:12px;line-height:18px;display:inline-flex}.SYX6rq_toggle:hover{background:var(--dsw-alias-interactive-bg-hover)}.SYX6rq_toggleOn{background:var(--dsw-alias-state-business-tertiary);color:var(--dsw-alias-state-business-primary);border-color:#0000}.SYX6rq_check{justify-content:center;align-items:center;width:16px;height:16px;font-size:12px;display:inline-flex}.SYX6rq_knob{align-items:center;gap:10px;display:flex}.SYX6rq_knobLabel{width:92px;color:var(--dsw-alias-label-secondary);flex:none;font-size:12px;line-height:18px}.SYX6rq_slider{min-width:0;accent-color:var(--dsw-alias-state-business-primary);flex:1}.SYX6rq_numberWrap{flex:none;align-items:center;gap:4px;display:inline-flex}.SYX6rq_number{border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-2);width:56px;height:26px;color:var(--dsw-alias-label-primary);text-align:right;border-radius:8px;padding:0 6px;font-size:12px;line-height:18px}.SYX6rq_number::-webkit-outer-spin-button,.SYX6rq_number::-webkit-inner-spin-button{-webkit-appearance:none;margin:0}.SYX6rq_unit{width:18px;color:var(--dsw-alias-label-tertiary);flex:none;font-size:12px;line-height:18px}.SYX6rq_segmented{border:1px solid var(--dsw-alias-border-l2);border-radius:8px;display:inline-flex;overflow:hidden}.SYX6rq_seg,.SYX6rq_segActive{height:26px;color:var(--dsw-alias-label-secondary);cursor:pointer;background:0 0;border:none;padding:0 12px;font-size:12px;line-height:18px}.SYX6rq_seg+.SYX6rq_seg,.SYX6rq_segActive+.SYX6rq_seg,.SYX6rq_seg+.SYX6rq_segActive{border-left:1px solid var(--dsw-alias-border-l2)}.SYX6rq_segActive{background:var(--dsw-alias-state-business-tertiary);color:var(--dsw-alias-state-business-primary)}";
|
|
1191
|
+
const tagId$1 = "@nonamelego/dsh-catppuccin/GlassRow.module.css";
|
|
1192
|
+
if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId$1) + "]") === null) {
|
|
1193
|
+
const tag = document.createElement("style");
|
|
1194
|
+
tag.dataset.plugin = "@nonamelego/dsh-catppuccin";
|
|
1195
|
+
tag.dataset.pluginCss = tagId$1;
|
|
1196
|
+
tag.textContent = css$1;
|
|
1197
|
+
document.head.appendChild(tag);
|
|
1198
|
+
}
|
|
1199
|
+
var GlassRow_module_css_default = {
|
|
1200
|
+
"check": "SYX6rq_check",
|
|
1201
|
+
"controls": "SYX6rq_controls",
|
|
1202
|
+
"description": "SYX6rq_description",
|
|
1203
|
+
"group": "SYX6rq_group",
|
|
1204
|
+
"knob": "SYX6rq_knob",
|
|
1205
|
+
"knobHint": "SYX6rq_knobHint",
|
|
1206
|
+
"knobLabel": "SYX6rq_knobLabel",
|
|
1207
|
+
"number": "SYX6rq_number",
|
|
1208
|
+
"numberWrap": "SYX6rq_numberWrap",
|
|
1209
|
+
"row": "SYX6rq_row",
|
|
1210
|
+
"rowHint": "SYX6rq_rowHint",
|
|
1211
|
+
"rowLabel": "SYX6rq_rowLabel",
|
|
1212
|
+
"seg": "SYX6rq_seg",
|
|
1213
|
+
"segActive": "SYX6rq_segActive",
|
|
1214
|
+
"segmented": "SYX6rq_segmented",
|
|
1215
|
+
"slider": "SYX6rq_slider",
|
|
1216
|
+
"title": "SYX6rq_title",
|
|
1217
|
+
"toggle": "SYX6rq_toggle",
|
|
1218
|
+
"toggleOn": "SYX6rq_toggleOn",
|
|
1219
|
+
"unit": "SYX6rq_unit"
|
|
1220
|
+
};
|
|
1221
|
+
//#endregion
|
|
1222
|
+
//#region src/client/glass/glass-row.tsx
|
|
1223
|
+
/**
|
|
1224
|
+
* Catppuccin glass settings row — registered into the General settings
|
|
1225
|
+
* section (`settings.general.item`, right under the Catppuccin flavour row).
|
|
1226
|
+
* Holds the master on/off switch plus every glass knob: mode (mica /
|
|
1227
|
+
* compatibility), blur, frost, backdrop brightness and ambient hue. Every
|
|
1228
|
+
* write goes straight through to the glass layer, so the skin moves live.
|
|
1229
|
+
*/
|
|
1230
|
+
/** One slider + number box, wired to a single value. */
|
|
1231
|
+
function Knob(props) {
|
|
1232
|
+
const { label, value, min, max, step, unit, onChange } = props;
|
|
1233
|
+
const clamp = (n) => Math.min(max, Math.max(min, Number.isFinite(n) ? n : min));
|
|
1234
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
|
|
1235
|
+
className: GlassRow_module_css_default.knob,
|
|
1236
|
+
children: [
|
|
1237
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
1238
|
+
className: GlassRow_module_css_default.knobLabel,
|
|
1239
|
+
children: label
|
|
1240
|
+
}),
|
|
1241
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
|
|
1242
|
+
type: "range",
|
|
1243
|
+
className: GlassRow_module_css_default.slider,
|
|
1244
|
+
min,
|
|
1245
|
+
max,
|
|
1246
|
+
step,
|
|
1247
|
+
value,
|
|
1248
|
+
onChange: (e) => {
|
|
1249
|
+
onChange(clamp(Number(e.target.value)));
|
|
1250
|
+
}
|
|
1251
|
+
}),
|
|
1252
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
1253
|
+
className: GlassRow_module_css_default.numberWrap,
|
|
1254
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
|
|
1255
|
+
type: "number",
|
|
1256
|
+
className: GlassRow_module_css_default.number,
|
|
1257
|
+
min,
|
|
1258
|
+
max,
|
|
1259
|
+
step,
|
|
1260
|
+
value,
|
|
1261
|
+
onChange: (e) => {
|
|
1262
|
+
onChange(clamp(Number(e.target.value)));
|
|
1263
|
+
}
|
|
1264
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
1265
|
+
className: GlassRow_module_css_default.unit,
|
|
1266
|
+
children: unit
|
|
1267
|
+
})]
|
|
1268
|
+
})
|
|
1269
|
+
]
|
|
1270
|
+
});
|
|
1271
|
+
}
|
|
1272
|
+
/** A two-option segmented picker. */
|
|
1273
|
+
function Segmented(props) {
|
|
1274
|
+
const { label, value, options, onSelect } = props;
|
|
1275
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
1276
|
+
className: GlassRow_module_css_default.segmented,
|
|
1277
|
+
role: "group",
|
|
1278
|
+
"aria-label": label,
|
|
1279
|
+
children: options.map((option) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
1280
|
+
type: "button",
|
|
1281
|
+
className: option.id === value ? GlassRow_module_css_default.segActive : GlassRow_module_css_default.seg,
|
|
1282
|
+
"aria-pressed": option.id === value,
|
|
1283
|
+
onClick: () => {
|
|
1284
|
+
onSelect(option.id);
|
|
1285
|
+
},
|
|
1286
|
+
children: option.label
|
|
1287
|
+
}, option.id))
|
|
1288
|
+
});
|
|
1289
|
+
}
|
|
1290
|
+
/**
|
|
1291
|
+
* Render the glass row: title, the master switch, and — while enabled — the
|
|
1292
|
+
* mode picker and every knob.
|
|
1293
|
+
* @param props - composed slot props.
|
|
1294
|
+
* @returns the General section row.
|
|
1295
|
+
*/
|
|
1296
|
+
function GlassRow({ t, getState, subscribe, setEnabled, setMode, setBlur, setFrost, setBrightness, setHue }) {
|
|
1297
|
+
const { enabled, mode, blur, frost, brightness, hue, dark } = (0, react.useSyncExternalStore)(subscribe, getState);
|
|
1298
|
+
const bgMin = dark ? 0 : 50;
|
|
1299
|
+
const bgMax = dark ? 50 : 100;
|
|
1300
|
+
const bgDisplay = Math.min(bgMax, Math.max(bgMin, brightness));
|
|
1301
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
1302
|
+
className: GlassRow_module_css_default.group,
|
|
1303
|
+
children: [
|
|
1304
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
1305
|
+
className: GlassRow_module_css_default.title,
|
|
1306
|
+
children: t("glass.title")
|
|
1307
|
+
}),
|
|
1308
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
1309
|
+
className: GlassRow_module_css_default.description,
|
|
1310
|
+
children: t("glass.description")
|
|
1311
|
+
}),
|
|
1312
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
1313
|
+
className: GlassRow_module_css_default.controls,
|
|
1314
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
1315
|
+
className: GlassRow_module_css_default.row,
|
|
1316
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
1317
|
+
className: GlassRow_module_css_default.rowLabel,
|
|
1318
|
+
children: t("glass.enable")
|
|
1319
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
|
|
1320
|
+
type: "button",
|
|
1321
|
+
className: enabled ? GlassRow_module_css_default.toggleOn : GlassRow_module_css_default.toggle,
|
|
1322
|
+
"aria-pressed": enabled,
|
|
1323
|
+
onClick: () => {
|
|
1324
|
+
setEnabled(!enabled);
|
|
1325
|
+
},
|
|
1326
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
1327
|
+
className: GlassRow_module_css_default.check,
|
|
1328
|
+
children: enabled ? "✓" : ""
|
|
1329
|
+
}), enabled ? t("glass.on") : t("glass.off")]
|
|
1330
|
+
})]
|
|
1331
|
+
}), enabled && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [
|
|
1332
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
1333
|
+
className: GlassRow_module_css_default.row,
|
|
1334
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
1335
|
+
className: GlassRow_module_css_default.rowLabel,
|
|
1336
|
+
children: t("glass.mode")
|
|
1337
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Segmented, {
|
|
1338
|
+
label: t("glass.mode"),
|
|
1339
|
+
value: mode,
|
|
1340
|
+
options: [{
|
|
1341
|
+
id: "mica",
|
|
1342
|
+
label: t("glass.modeMica")
|
|
1343
|
+
}, {
|
|
1344
|
+
id: "compat",
|
|
1345
|
+
label: t("glass.modeCompat")
|
|
1346
|
+
}],
|
|
1347
|
+
onSelect: setMode
|
|
1348
|
+
})]
|
|
1349
|
+
}),
|
|
1350
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
1351
|
+
className: GlassRow_module_css_default.rowHint,
|
|
1352
|
+
children: t("glass.modeHint")
|
|
1353
|
+
}),
|
|
1354
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(Knob, {
|
|
1355
|
+
label: t("glass.blur"),
|
|
1356
|
+
value: blur,
|
|
1357
|
+
min: 0,
|
|
1358
|
+
max: 40,
|
|
1359
|
+
step: .5,
|
|
1360
|
+
unit: "px",
|
|
1361
|
+
onChange: setBlur
|
|
1362
|
+
}),
|
|
1363
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(Knob, {
|
|
1364
|
+
label: t("glass.frost"),
|
|
1365
|
+
value: frost,
|
|
1366
|
+
min: 0,
|
|
1367
|
+
max: 100,
|
|
1368
|
+
step: 1,
|
|
1369
|
+
unit: "%",
|
|
1370
|
+
onChange: setFrost
|
|
1371
|
+
}),
|
|
1372
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(Knob, {
|
|
1373
|
+
label: t("glass.brightness"),
|
|
1374
|
+
value: bgDisplay,
|
|
1375
|
+
min: bgMin,
|
|
1376
|
+
max: bgMax,
|
|
1377
|
+
step: 1,
|
|
1378
|
+
unit: "%",
|
|
1379
|
+
onChange: setBrightness
|
|
1380
|
+
}),
|
|
1381
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
1382
|
+
className: GlassRow_module_css_default.knobHint,
|
|
1383
|
+
children: t(dark ? "glass.brightnessHintDark" : "glass.brightnessHintLight")
|
|
1384
|
+
}),
|
|
1385
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(Knob, {
|
|
1386
|
+
label: t("glass.hue"),
|
|
1387
|
+
value: hue,
|
|
1388
|
+
min: 0,
|
|
1389
|
+
max: 360,
|
|
1390
|
+
step: 1,
|
|
1391
|
+
unit: "°",
|
|
1392
|
+
onChange: setHue
|
|
1393
|
+
}),
|
|
1394
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
1395
|
+
className: GlassRow_module_css_default.knobHint,
|
|
1396
|
+
children: t("glass.hueHint")
|
|
1397
|
+
})
|
|
1398
|
+
] })]
|
|
1399
|
+
})
|
|
1400
|
+
]
|
|
1401
|
+
});
|
|
1402
|
+
}
|
|
1403
|
+
//#endregion
|
|
1404
|
+
//#region \0dsh-css:D:\Vibe-Coding\dsh-catppuccin\src\client\glass\glass.module.css.mjs
|
|
1405
|
+
const css = "[data-dsh-glass] body{--dsh-glass-card:linear-gradient(180deg, color-mix(in srgb, var(--dsw-alias-bg-layer-1) calc(52% * var(--dsh-glass-frost,1)), transparent), color-mix(in srgb, var(--dsw-alias-bg-layer-2) calc(40% * var(--dsh-glass-frost,1)), transparent));background:var(--dsw-alias-bg-base)}[data-dsh-glass] [data-dsh-glass-frame],[data-dsh-glass] [data-phase],[data-dsh-glass] [data-dsh-glass-details]{background:0 0}[data-dsh-glass-float] [data-phase=active] header{z-index:8;position:relative}[data-dsh-glass-float] [class*=banner]{position:static}[data-dsh-glass-float] [data-phase=active] [data-conversation-scroll]{margin-top:-95px;padding-top:107px}[data-dsh-glass] [data-phase] [class*=composerSeat][class*=composerSeat]{background:0 0}[data-dsh-glass] [data-dsh-glass-ambient]{z-index:0;pointer-events:none;filter:hue-rotate(var(--dsh-glass-hue,0deg));background:radial-gradient(760px 420px at 50% -8%, color-mix(in srgb, var(--dsw-alias-brand-primary-new-colorprimary-new-color) 18%, transparent), transparent 70%), linear-gradient(180deg, color-mix(in srgb, var(--dsw-alias-bg-layer-1) 62%, transparent) 0%, color-mix(in srgb, var(--dsw-alias-bg-layer-2) 46%, transparent) 100%), radial-gradient(900px 420px at 50% 108%, color-mix(in srgb, var(--dsw-alias-brand-primary-new-colorprimary-new-color) 10%, transparent), transparent 70%);position:fixed;inset:0;overflow:hidden}[data-dsh-glass] [data-dsh-glass-ambient]:after{content:\"\";background-image:linear-gradient(rgba(255, 255, 255, var(--dsh-glass-brightness-white,0)), rgba(255, 255, 255, var(--dsh-glass-brightness-white,0))), linear-gradient(rgba(0, 0, 0, var(--dsh-glass-brightness-black,0)), rgba(0, 0, 0, var(--dsh-glass-brightness-black,0)));position:absolute;inset:0}@media (prefers-reduced-motion:no-preference){[data-dsh-glass] [data-dsh-glass-ambient]{animation:bOHSKq_dsh-glass-breathe 9s var(--ds-ease-in-out) infinite alternate}}@keyframes bOHSKq_dsh-glass-breathe{0%{opacity:.88}to{opacity:1}}[data-dsh-glass] [data-dsh-glass-blob]{filter:blur(70px);opacity:.42;will-change:transform;border-radius:50%;position:absolute}[data-dsh-glass] [data-dsh-glass-blob=\"1\"]{background:color-mix(in srgb, var(--dsw-alias-brand-primary-new-colorprimary-new-color) 15%, transparent);width:44vw;height:44vw;animation:bOHSKq_dsh-glass-drift-a 30s var(--ds-ease-in-out) infinite alternate;top:-8vw;left:-10vw}[data-dsh-glass] [data-dsh-glass-blob=\"2\"]{background:color-mix(in srgb, var(--dsw-alias-state-success-tertiary) 45%, transparent);width:38vw;height:38vw;animation:bOHSKq_dsh-glass-drift-b 36s var(--ds-ease-in-out) infinite alternate;top:24vh;right:-12vw}[data-dsh-glass] [data-dsh-glass-blob=\"3\"]{background:color-mix(in srgb, var(--dsw-alias-state-warn-tertiary) 40%, transparent);width:30vw;height:30vw;animation:bOHSKq_dsh-glass-drift-c 42s var(--ds-ease-in-out) infinite alternate;bottom:-14vh;left:30vw}@keyframes bOHSKq_dsh-glass-drift-a{0%{transform:translate(0,0)scale(1)}to{transform:translate(6vw,4vh)scale(1.12)}}@keyframes bOHSKq_dsh-glass-drift-b{0%{transform:translate(0,0)scale(1.08)}to{transform:translate(-7vw,6vh)scale(.96)}}@keyframes bOHSKq_dsh-glass-drift-c{0%{transform:translate(0,0)scale(.96)}to{transform:translate(8vw,-5vh)scale(1.1)}}[data-dsh-glass] [data-dsh-glass-fade]{z-index:7;pointer-events:none;backdrop-filter:blur(5px);background:color-mix(in srgb, var(--dsw-alias-bg-layer-1) 50%, transparent);height:13px;position:fixed;left:0;right:0}[data-dsh-glass] [data-dsh-glass-fade=top]{top:0;-webkit-mask-image:linear-gradient(#000 0%,#0000 100%);mask-image:linear-gradient(#000 0%,#0000 100%)}[data-dsh-glass] [data-dsh-glass-fade=bottom]{bottom:0;-webkit-mask-image:linear-gradient(#0000 0%,#000 100%);mask-image:linear-gradient(#0000 0%,#000 100%)}[data-dsh-glass-float] [role=menu],[data-dsh-glass-float] [role=dialog],[data-dsh-glass-float] [role=alert],[data-dsh-glass-float] [data-dsh-glass-surface]{border-radius:14px}[data-dsh-glass-float] [role=menuitem],[data-dsh-glass-float] [role=tooltip],[data-dsh-glass-float] [class*=pill]{border-radius:8px}[data-dsh-glass-float] button[class*=button]{border-radius:10px}[data-dsh-glass-float] [class*=iconButton],[data-dsh-glass-float] [class*=searchButton]{border-radius:8px}[data-dsh-glass-float] [data-dsh-glass-add]{background:color-mix(in srgb, var(--dsw-alias-bg-layer-1) calc(55% * var(--dsh-glass-frost,1)), transparent);border:1px solid var(--dsw-alias-border-l2);box-shadow:inset 0 1px 0 color-mix(in srgb, var(--dsw-alias-label-primary) 10%, transparent);backdrop-filter:blur(var(--dsh-glass-blur,14px))}[data-dsh-glass-float] [data-dsh-glass-add]:hover:not(:disabled){background:color-mix(in srgb, var(--dsw-alias-bg-layer-1) calc(72% * var(--dsh-glass-frost,1)), transparent)}[data-dsh-glass-float] [data-dsh-glass-surface]{background:color-mix(in srgb, var(--dsw-alias-bg-layer-1) calc(62% * var(--dsh-glass-frost,1)), transparent);border:1px solid var(--dsw-alias-border-l2);box-shadow:inset 0 1px 0 color-mix(in srgb, var(--dsw-alias-label-primary) 10%, transparent);backdrop-filter:blur(var(--dsh-glass-blur,14px))}[data-dsh-glass-float] [data-dsh-glass-surface]:hover:not(:disabled){background:color-mix(in srgb, var(--dsw-alias-bg-layer-1) calc(78% * var(--dsh-glass-frost,1)), transparent)}[data-dsh-glass-float] [class*=bubble]{border:1px solid color-mix(in srgb, var(--dsw-alias-border-l2) 80%, transparent);background:color-mix(in srgb, var(--dsw-alias-bg-layer-1) calc(46% * var(--dsh-glass-frost,1)), transparent);backdrop-filter:blur(var(--dsh-glass-blur,14px));border-radius:14px}[data-dsh-glass-float] [class*=card]{border-radius:14px}[data-dsh-glass-float] header{border:1px solid var(--dsw-alias-border-l2);background:var(--dsh-glass-card);box-shadow:inset 0 1px 0 color-mix(in srgb, var(--dsw-alias-label-primary) 8%, transparent), 0 8px 28px color-mix(in srgb, var(--dsw-alias-bg-mask-2) 55%, transparent);backdrop-filter:blur(var(--dsh-glass-blur,14px));border-bottom-color:#0000;border-radius:20px;margin:12px 16px 0;padding:10px 16px 8px}[data-dsh-glass-float] header:after{display:none}[data-dsh-glass-float] [class*=sidebarCol]{--dsw-specific-sidebar-fill:transparent;z-index:9;border:1px solid var(--dsw-alias-border-l2);border-right-color:color-mix(in srgb, var(--dsw-alias-brand-primary-new-colorprimary-new-color) 22%, transparent);background:var(--dsh-glass-card);box-shadow:inset 0 1px 0 color-mix(in srgb, var(--dsw-alias-label-primary) 8%, transparent), 0 8px 28px color-mix(in srgb, var(--dsw-alias-bg-mask-2) 55%, transparent);border-radius:20px;margin:12px;padding:10px 12px 14px;position:relative;overflow:hidden}[data-dsh-glass-float] [data-dsh-glass-frame][data-sidebar-collapsed] [class*=sidebarCol]{transition:margin .15s var(--ds-ease-in-out), border-radius .15s var(--ds-ease-in-out);border-radius:16px;margin:12px -12px 12px 12px;padding:0}[data-dsh-glass-float] [data-dsh-glass-frame]:not([data-sidebar-collapsed]) [data-dsh-glass-sidebar-root]{width:100%!important}[data-dsh-glass-float] [data-dsh-glass-trajectory]{border:1px solid var(--dsw-alias-border-l2);background:var(--dsh-glass-card);width:calc(100% - 32px);height:calc(100% - 20px);box-shadow:inset 0 1px 0 color-mix(in srgb, var(--dsw-alias-label-primary) 8%, transparent), 0 8px 28px color-mix(in srgb, var(--dsw-alias-bg-mask-2) 55%, transparent);backdrop-filter:blur(var(--dsh-glass-blur,14px));border-radius:20px;margin:8px 16px 12px;overflow:hidden}[data-dsh-glass-float] [data-dsh-glass-trajectory] [role=toolbar],[data-dsh-glass-float] [data-dsh-glass-trajectory] section[aria-label=Trajectory\\ timeline]{background:0 0}[data-dsh-glass-float] [data-composer-card],[data-dsh-glass-float] [data-composer-card]:after{border-radius:24px}[data-dsh-glass-float] [data-composer-card]{z-index:8;background:var(--dsh-glass-card);border:1px solid var(--dsw-alias-border-l2);box-shadow:inset 0 1px 0 color-mix(in srgb, var(--dsw-alias-label-primary) 8%, transparent), 0 8px 32px color-mix(in srgb, var(--dsw-alias-bg-mask-2) 60%, transparent);backdrop-filter:blur(var(--dsh-glass-blur,14px));position:relative}[data-dsh-glass-float] [data-dsh-glass-inputbar]:not([class*=hero]){padding-bottom:12px}[data-dsh-glass][data-dsh-glass-float] [data-dsh-glass-inputbar] [data-slot]{border:1px solid var(--dsw-alias-border-l2);border-top-color:var(--dsw-alias-border-l1);background:linear-gradient(180deg, color-mix(in srgb, var(--dsw-alias-bg-layer-1) calc(30% * var(--dsh-glass-frost,1)), transparent), color-mix(in srgb, var(--dsw-alias-bg-layer-2) calc(18% * var(--dsh-glass-frost,1)), transparent));box-shadow:0 8px 32px color-mix(in srgb, var(--dsw-alias-bg-mask-2) 60%, transparent);backdrop-filter:blur(var(--dsh-glass-blur,14px));border-radius:0 0 24px 24px;margin:0 auto;width:var(--dsh-composer-card-max-width)!important;max-width:var(--dsh-composer-card-max-width)!important}[data-dsh-glass][data-dsh-glass-float] [data-dsh-glass-inputbar] [data-slot] [data-dsh-glass-stats]{min-width:0;box-shadow:none;backdrop-filter:none;background:0 0;border:none;border-radius:0;margin:0;width:auto!important;max-width:none!important;padding:4px 16px 0!important}[data-dsh-glass][data-dsh-glass-float] [data-dsh-glass-inputbar] [data-slot] [data-dsh-live-tps]{padding-right:16px}[data-dsh-glass-float] [data-dsh-glass-inputbar]:has([data-dsh-glass-stats]) [data-composer-card]{box-shadow:inset 0 1px 0 color-mix(in srgb, var(--dsw-alias-label-primary) 8%, transparent);border-bottom:none;border-radius:24px 24px 0 0}[data-dsh-glass-float] [role=treeitem][aria-selected=true]{box-shadow:inset 2px 0 0 var(--dsw-specific-sidebar-nav-item-active-accent), 0 0 16px color-mix(in srgb, var(--dsw-alias-brand-primary-new-colorprimary-new-color) 20%, transparent)}[data-dsh-glass-float] button[class*=button]:hover:not(:disabled),[data-dsh-glass-float] [role=menuitem]:hover:not(:disabled){box-shadow:0 0 12px color-mix(in srgb, var(--dsw-alias-brand-primary-new-colorprimary-new-color) 20%, transparent), inset 0 0 0 1px color-mix(in srgb, var(--dsw-alias-border-l3) 60%, transparent)}[data-dsh-glass-float] [role=menu]{background:color-mix(in srgb, var(--dsw-alias-bg-layer-1) calc(72% * var(--dsh-glass-frost,1)), transparent);backdrop-filter:blur(var(--dsh-glass-blur,14px))}[data-dsh-glass-float] [data-phase=hero]{animation:bOHSKq_dsh-glass-in .32s var(--ds-ease-in-out)}[data-dsh-glass-float] [data-phase=active]{animation:bOHSKq_dsh-glass-in .3s var(--ds-ease-in-out)}[data-dsh-glass-float] [data-testid^=view-]{animation:bOHSKq_dsh-glass-in .26s var(--ds-ease-in-out)}[data-dsh-glass-float] [data-tool]{animation:bOHSKq_dsh-glass-rise .3s var(--ds-ease-in-out) both}[data-dsh-glass-float] [role=dialog]{animation:bOHSKq_dsh-glass-dialog-in .24s var(--ds-ease-in-out)}@keyframes bOHSKq_dsh-glass-in{0%{opacity:0}}@keyframes bOHSKq_dsh-glass-rise{0%{opacity:0;transform:translateY(6px)}}@keyframes bOHSKq_dsh-glass-dialog-in{0%{opacity:0;transform:translateY(8px)scale(.985)}}[data-dsh-glass] :focus-visible{outline:2px solid color-mix(in srgb, var(--dsw-alias-brand-primary-new-colorprimary-new-color) 85%, transparent);outline-offset:1px}[data-dsh-glass] ::selection{background:color-mix(in srgb, var(--dsw-alias-brand-primary-new-colorprimary-new-color) 35%, transparent)}[data-dsh-glass-compat] [role=menu],[data-dsh-glass-compat] [role=tooltip],[data-dsh-glass-compat] [class*=card],[data-dsh-glass-compat] [class*=bubble],[data-dsh-glass-compat] [class*=panel],[data-dsh-glass-compat] [class*=popover],[data-dsh-glass-compat] [class*=dropdown]{backdrop-filter:blur(12px)}@media (prefers-reduced-motion:reduce){[data-dsh-glass-float] [data-phase=hero],[data-dsh-glass-float] [data-phase=active],[data-dsh-glass-float] [data-testid^=view-],[data-dsh-glass-float] [data-tool],[data-dsh-glass-float] [role=dialog],[data-dsh-glass] [data-dsh-glass-ambient],[data-dsh-glass] [data-dsh-glass-blob]{animation:none}}";
|
|
1406
|
+
const tagId = "@nonamelego/dsh-catppuccin/glass.module.css";
|
|
1407
|
+
if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId) + "]") === null) {
|
|
1408
|
+
const tag = document.createElement("style");
|
|
1409
|
+
tag.dataset.plugin = "@nonamelego/dsh-catppuccin";
|
|
1410
|
+
tag.dataset.pluginCss = tagId;
|
|
1411
|
+
tag.textContent = css;
|
|
1412
|
+
document.head.appendChild(tag);
|
|
1413
|
+
}
|
|
1414
|
+
//#endregion
|
|
817
1415
|
//#region src/client/index.ts
|
|
818
1416
|
/** Locale namespace owned by this plugin. */
|
|
819
1417
|
const NS = "catppuccin";
|
|
820
|
-
/**
|
|
821
|
-
const
|
|
1418
|
+
/** localStorage key carrying the persisted flavour choice. */
|
|
1419
|
+
const FLAVOR_STORAGE_KEY = "dsh.catppuccin.flavor";
|
|
1420
|
+
/** Accepted flavour values — the four registered theme ids plus `off`. These
|
|
1421
|
+
* MUST stay in sync with the registered themes (guarded by
|
|
1422
|
+
* tests/palettes.spec.ts) because the persisted value is the theme id. */
|
|
1423
|
+
const CATPPUCCIN_FLAVOR_VALUES = [...CATPPUCCIN_FLAVORS.map((f) => f.themeId), "off"];
|
|
822
1424
|
/** The flavour whose themeId this is, or `off`. */
|
|
823
1425
|
function flavorFromThemeId(themeId) {
|
|
824
1426
|
return CATPPUCCIN_FLAVORS.some((f) => f.themeId === themeId) ? themeId : "off";
|
|
@@ -827,14 +1429,26 @@ window.__ModuleLoader__.load({
|
|
|
827
1429
|
function flavorInfo(themeId) {
|
|
828
1430
|
return CATPPUCCIN_FLAVORS.find((f) => f.themeId === themeId);
|
|
829
1431
|
}
|
|
830
|
-
/**
|
|
1432
|
+
/** Read the persisted flavour (absent / unknown values mean the default `off`). */
|
|
1433
|
+
function readFlavor() {
|
|
1434
|
+
try {
|
|
1435
|
+
const raw = localStorage.getItem(FLAVOR_STORAGE_KEY);
|
|
1436
|
+
return raw !== null && CATPPUCCIN_FLAVOR_VALUES.includes(raw) ? raw : "off";
|
|
1437
|
+
} catch {
|
|
1438
|
+
return "off";
|
|
1439
|
+
}
|
|
1440
|
+
}
|
|
1441
|
+
/** Persist the flavour choice (storage failures keep the in-memory state). */
|
|
1442
|
+
function writeFlavor(choice) {
|
|
1443
|
+
try {
|
|
1444
|
+
localStorage.setItem(FLAVOR_STORAGE_KEY, choice);
|
|
1445
|
+
} catch {}
|
|
1446
|
+
}
|
|
1447
|
+
/** Required services: slots + locale (settings rows) and theme (register + switch). */
|
|
831
1448
|
const inject = [
|
|
832
1449
|
"slots",
|
|
833
1450
|
"locale",
|
|
834
|
-
"theme"
|
|
835
|
-
"settingsScope",
|
|
836
|
-
"connection",
|
|
837
|
-
"remote"
|
|
1451
|
+
"theme"
|
|
838
1452
|
];
|
|
839
1453
|
/**
|
|
840
1454
|
* Register the Catppuccin dictionaries, the four flavour themes, and the
|
|
@@ -857,23 +1471,38 @@ window.__ModuleLoader__.load({
|
|
|
857
1471
|
for (const dispose of disposers) dispose();
|
|
858
1472
|
};
|
|
859
1473
|
}, "catppuccin: flavour themes");
|
|
860
|
-
const scope = ctx.get("settingsScope").bind({ namespace: SETTINGS_NAMESPACE });
|
|
861
1474
|
ctx.effect(() => {
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
1475
|
+
const saved = readFlavor();
|
|
1476
|
+
if (saved === "off") return () => {};
|
|
1477
|
+
let settled = false;
|
|
1478
|
+
const started = Date.now();
|
|
1479
|
+
const applySaved = () => {
|
|
1480
|
+
if (settled) return;
|
|
1481
|
+
if (Date.now() - started > 5e3) {
|
|
1482
|
+
settled = true;
|
|
1483
|
+
return;
|
|
1484
|
+
}
|
|
1485
|
+
try {
|
|
1486
|
+
if (theme.getTheme().preference !== saved) theme.setTheme(saved);
|
|
1487
|
+
} catch {}
|
|
1488
|
+
};
|
|
1489
|
+
applySaved();
|
|
1490
|
+
const disposer = ctx.on("theme/change", applySaved);
|
|
1491
|
+
const timer = window.setTimeout(() => {
|
|
1492
|
+
settled = true;
|
|
1493
|
+
}, 5e3);
|
|
1494
|
+
const onStorage = (event) => {
|
|
1495
|
+
if (event.key !== "dsh.catppuccin.flavor") return;
|
|
1496
|
+
const next = readFlavor();
|
|
1497
|
+
if (next !== "off") try {
|
|
1498
|
+
theme.setTheme(next);
|
|
871
1499
|
} catch {}
|
|
872
1500
|
};
|
|
873
|
-
|
|
874
|
-
const unsubscribe = scope.subscribe(restoreOnce);
|
|
1501
|
+
window.addEventListener("storage", onStorage);
|
|
875
1502
|
return () => {
|
|
876
|
-
|
|
1503
|
+
disposer();
|
|
1504
|
+
window.clearTimeout(timer);
|
|
1505
|
+
window.removeEventListener("storage", onStorage);
|
|
877
1506
|
};
|
|
878
1507
|
}, "catppuccin: boot restore");
|
|
879
1508
|
const injected = () => ({
|
|
@@ -887,20 +1516,16 @@ window.__ModuleLoader__.load({
|
|
|
887
1516
|
return flavorFromThemeId(pref);
|
|
888
1517
|
},
|
|
889
1518
|
subscribe: (listener) => ctx.on("theme/change", listener),
|
|
890
|
-
select:
|
|
1519
|
+
select: (choice) => {
|
|
891
1520
|
if (choice === "off") {
|
|
892
1521
|
theme.setTheme("system");
|
|
893
|
-
|
|
894
|
-
console.error("[dsh-catppuccin] persist off failed:", err);
|
|
895
|
-
});
|
|
1522
|
+
writeFlavor("off");
|
|
896
1523
|
return;
|
|
897
1524
|
}
|
|
898
1525
|
const flavor = flavorInfo(choice);
|
|
899
1526
|
if (!flavor) return;
|
|
900
1527
|
theme.setTheme(flavor.themeId);
|
|
901
|
-
|
|
902
|
-
console.error("[dsh-catppuccin] persist flavor failed:", err);
|
|
903
|
-
});
|
|
1528
|
+
writeFlavor(flavor.themeId);
|
|
904
1529
|
}
|
|
905
1530
|
});
|
|
906
1531
|
ctx.slots.inject("settings.general.item", () => ctx.slots.register({
|
|
@@ -910,14 +1535,47 @@ window.__ModuleLoader__.load({
|
|
|
910
1535
|
locale: NS,
|
|
911
1536
|
inject: injected
|
|
912
1537
|
}, CatppuccinRow));
|
|
1538
|
+
const glass = new GlassLayer(ctx);
|
|
1539
|
+
const glassInjected = () => ({
|
|
1540
|
+
getState: () => glass.getSnapshot(),
|
|
1541
|
+
subscribe: (listener) => glass.subscribe(listener),
|
|
1542
|
+
setEnabled: (enabled) => {
|
|
1543
|
+
glass.setEnabled(enabled);
|
|
1544
|
+
},
|
|
1545
|
+
setMode: (mode) => {
|
|
1546
|
+
glass.setMode(mode);
|
|
1547
|
+
},
|
|
1548
|
+
setBlur: (blur) => {
|
|
1549
|
+
glass.setBlur(blur);
|
|
1550
|
+
},
|
|
1551
|
+
setFrost: (frost) => {
|
|
1552
|
+
glass.setFrost(frost);
|
|
1553
|
+
},
|
|
1554
|
+
setBrightness: (brightness) => {
|
|
1555
|
+
glass.setBrightness(brightness);
|
|
1556
|
+
},
|
|
1557
|
+
setHue: (hue) => {
|
|
1558
|
+
glass.setHue(hue);
|
|
1559
|
+
}
|
|
1560
|
+
});
|
|
1561
|
+
ctx.slots.inject("settings.general.item", () => ctx.slots.register({
|
|
1562
|
+
name: "settings.general.item",
|
|
1563
|
+
id: "catppuccin-glass",
|
|
1564
|
+
order: 21,
|
|
1565
|
+
locale: NS,
|
|
1566
|
+
inject: glassInjected
|
|
1567
|
+
}, GlassRow));
|
|
913
1568
|
}
|
|
914
1569
|
//#endregion
|
|
1570
|
+
exports.CATPPUCCIN_FLAVOR_VALUES = CATPPUCCIN_FLAVOR_VALUES;
|
|
1571
|
+
exports.FLAVOR_STORAGE_KEY = FLAVOR_STORAGE_KEY;
|
|
915
1572
|
exports.NS = NS;
|
|
916
|
-
exports.SETTINGS_NAMESPACE = SETTINGS_NAMESPACE;
|
|
917
1573
|
exports.apply = apply;
|
|
918
1574
|
exports.flavorFromThemeId = flavorFromThemeId;
|
|
919
1575
|
exports.flavorInfo = flavorInfo;
|
|
920
1576
|
exports.inject = inject;
|
|
1577
|
+
exports.readFlavor = readFlavor;
|
|
1578
|
+
exports.writeFlavor = writeFlavor;
|
|
921
1579
|
return module.exports;
|
|
922
1580
|
}
|
|
923
1581
|
});
|