@seamline-kit/seamline-settings 0.0.4 → 0.0.5
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/dist/main.cjs +40 -6
- package/dist/main.d.cts +3 -13
- package/dist/main.d.cts.map +1 -1
- package/dist/main.d.ts +3 -13
- package/dist/main.d.ts.map +1 -1
- package/dist/main.js +39 -2
- package/dist/main.js.map +1 -1
- package/package.json +13 -14
package/dist/main.cjs
CHANGED
|
@@ -74,6 +74,39 @@ function SettingsPage({ defaultTheme }) {
|
|
|
74
74
|
})] });
|
|
75
75
|
}
|
|
76
76
|
|
|
77
|
+
//#endregion
|
|
78
|
+
//#region src/theme-persistence.ts
|
|
79
|
+
const THEME_STORAGE_KEY = `${DEFAULT_PREFIX}-theme`;
|
|
80
|
+
function getStorage() {
|
|
81
|
+
try {
|
|
82
|
+
return globalThis.localStorage ?? null;
|
|
83
|
+
} catch {
|
|
84
|
+
return null;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
function readPersistedTheme() {
|
|
88
|
+
const storage = getStorage();
|
|
89
|
+
if (!storage) return null;
|
|
90
|
+
let value = null;
|
|
91
|
+
try {
|
|
92
|
+
value = storage.getItem(THEME_STORAGE_KEY);
|
|
93
|
+
} catch {
|
|
94
|
+
return null;
|
|
95
|
+
}
|
|
96
|
+
if (!isTheme(value)) return null;
|
|
97
|
+
return value;
|
|
98
|
+
}
|
|
99
|
+
function persistTheme(theme) {
|
|
100
|
+
const storage = getStorage();
|
|
101
|
+
if (!storage) return;
|
|
102
|
+
try {
|
|
103
|
+
storage.setItem(THEME_STORAGE_KEY, theme);
|
|
104
|
+
} catch {
|
|
105
|
+
return;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
const THEME_BOOTSTRAP_SCRIPT = "try{let theme=localStorage.getItem('slk-settings-theme');if(['system','light','dark'].includes(theme)){document.documentElement.setAttribute('data-slk-settings-theme',theme)}}catch{}";
|
|
109
|
+
|
|
77
110
|
//#endregion
|
|
78
111
|
//#region src/theme-form-controller.ts
|
|
79
112
|
function getSelectedTheme(form) {
|
|
@@ -96,13 +129,17 @@ function bindThemeForm(onThemeChange) {
|
|
|
96
129
|
const selectedTheme = getSelectedTheme(form);
|
|
97
130
|
if (!selectedTheme) return;
|
|
98
131
|
onThemeChange(selectedTheme);
|
|
132
|
+
persistTheme(selectedTheme);
|
|
99
133
|
}
|
|
100
|
-
const
|
|
134
|
+
const persistedTheme = readPersistedTheme();
|
|
135
|
+
if (persistedTheme) syncThemeStateToDom(radios, persistedTheme);
|
|
136
|
+
const initialSelectedTheme = persistedTheme ?? getSelectedTheme(form);
|
|
101
137
|
if (initialSelectedTheme) onThemeChange(initialSelectedTheme);
|
|
102
138
|
form.addEventListener("change", syncThemeFromForm);
|
|
103
139
|
return {
|
|
104
140
|
sync(theme) {
|
|
105
141
|
syncThemeStateToDom(radios, theme);
|
|
142
|
+
persistTheme(theme);
|
|
106
143
|
},
|
|
107
144
|
unbind() {
|
|
108
145
|
form.removeEventListener("change", syncThemeFromForm);
|
|
@@ -122,10 +159,7 @@ function render(defaultTheme) {
|
|
|
122
159
|
}
|
|
123
160
|
|
|
124
161
|
//#endregion
|
|
125
|
-
exports.DEFAULT_PREFIX = DEFAULT_PREFIX;
|
|
126
162
|
exports.DEFAULT_THEME = DEFAULT_THEME;
|
|
127
|
-
exports.
|
|
128
|
-
exports.THEME_FIELD_NAME = THEME_FIELD_NAME;
|
|
163
|
+
exports.THEME_BOOTSTRAP_SCRIPT = THEME_BOOTSTRAP_SCRIPT;
|
|
129
164
|
exports.bindThemeForm = bindThemeForm;
|
|
130
|
-
exports.init = init;
|
|
131
|
-
exports.isTheme = isTheme;
|
|
165
|
+
exports.init = init;
|
package/dist/main.d.cts
CHANGED
|
@@ -3,20 +3,10 @@ import { Result } from "hastscript";
|
|
|
3
3
|
//#region src/theme.d.ts
|
|
4
4
|
declare const THEMES: readonly ["system", "light", "dark"];
|
|
5
5
|
type Theme = (typeof THEMES)[number];
|
|
6
|
-
declare const THEME_FIELD_NAME: string;
|
|
7
6
|
declare const DEFAULT_THEME: Theme;
|
|
8
|
-
declare function isTheme(value: unknown): value is Theme;
|
|
9
7
|
//#endregion
|
|
10
|
-
//#region src/
|
|
11
|
-
declare const
|
|
12
|
-
interface SettingsPageNames {
|
|
13
|
-
appearanceTitle: string;
|
|
14
|
-
appearanceForm: string;
|
|
15
|
-
themeSystem: string;
|
|
16
|
-
themeLight: string;
|
|
17
|
-
themeDark: string;
|
|
18
|
-
}
|
|
19
|
-
declare const SETTINGS_PAGE_NAMES: SettingsPageNames;
|
|
8
|
+
//#region src/theme-persistence.d.ts
|
|
9
|
+
declare const THEME_BOOTSTRAP_SCRIPT = "try{let theme=localStorage.getItem('slk-settings-theme');if(['system','light','dark'].includes(theme)){document.documentElement.setAttribute('data-slk-settings-theme',theme)}}catch{}";
|
|
20
10
|
//#endregion
|
|
21
11
|
//#region src/theme-form-controller.d.ts
|
|
22
12
|
interface ThemeFormBinding {
|
|
@@ -36,5 +26,5 @@ declare function init({
|
|
|
36
26
|
defaultTheme
|
|
37
27
|
}?: InitOptions): SettingsRenderer;
|
|
38
28
|
//#endregion
|
|
39
|
-
export {
|
|
29
|
+
export { DEFAULT_THEME, THEME_BOOTSTRAP_SCRIPT, type Theme, bindThemeForm, init };
|
|
40
30
|
//# sourceMappingURL=main.d.cts.map
|
package/dist/main.d.cts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"main.d.cts","names":[],"sources":["../src/theme.ts","../src/
|
|
1
|
+
{"version":3,"file":"main.d.cts","names":[],"sources":["../src/theme.ts","../src/theme-persistence.ts","../src/theme-form-controller.ts","../src/main.ts"],"mappings":";;;cAEM,MAAA;AAAA,KACM,KAAA,WAAgB,MAAA;AAAA,cAGf,aAAA,EAAe,KAAA;;;cCwCf,sBAAA;;;UC1CH,gBAAA;EACR,IAAA,GAAO,KAAA,EAAO,KAAA;EACd,MAAA;AAAA;AAAA,iBAsBc,aAAA,CAAc,aAAA,GAAgB,KAAA,EAAO,KAAA,YAAiB,gBAAA;;;UCvB5D,WAAA;EACR,YAAA,GAAe,KAAA;AAAA;AAAA,UAGP,gBAAA;EACR,MAAA,QAAc,MAAA;AAAA;AAAA,iBAGA,IAAA,CAAA;EAAO;AAAA,IAAgC,WAAA,GAAmB,gBAAA"}
|
package/dist/main.d.ts
CHANGED
|
@@ -3,20 +3,10 @@ import { Result } from "hastscript";
|
|
|
3
3
|
//#region src/theme.d.ts
|
|
4
4
|
declare const THEMES: readonly ["system", "light", "dark"];
|
|
5
5
|
type Theme = (typeof THEMES)[number];
|
|
6
|
-
declare const THEME_FIELD_NAME: string;
|
|
7
6
|
declare const DEFAULT_THEME: Theme;
|
|
8
|
-
declare function isTheme(value: unknown): value is Theme;
|
|
9
7
|
//#endregion
|
|
10
|
-
//#region src/
|
|
11
|
-
declare const
|
|
12
|
-
interface SettingsPageNames {
|
|
13
|
-
appearanceTitle: string;
|
|
14
|
-
appearanceForm: string;
|
|
15
|
-
themeSystem: string;
|
|
16
|
-
themeLight: string;
|
|
17
|
-
themeDark: string;
|
|
18
|
-
}
|
|
19
|
-
declare const SETTINGS_PAGE_NAMES: SettingsPageNames;
|
|
8
|
+
//#region src/theme-persistence.d.ts
|
|
9
|
+
declare const THEME_BOOTSTRAP_SCRIPT = "try{let theme=localStorage.getItem('slk-settings-theme');if(['system','light','dark'].includes(theme)){document.documentElement.setAttribute('data-slk-settings-theme',theme)}}catch{}";
|
|
20
10
|
//#endregion
|
|
21
11
|
//#region src/theme-form-controller.d.ts
|
|
22
12
|
interface ThemeFormBinding {
|
|
@@ -36,5 +26,5 @@ declare function init({
|
|
|
36
26
|
defaultTheme
|
|
37
27
|
}?: InitOptions): SettingsRenderer;
|
|
38
28
|
//#endregion
|
|
39
|
-
export {
|
|
29
|
+
export { DEFAULT_THEME, THEME_BOOTSTRAP_SCRIPT, type Theme, bindThemeForm, init };
|
|
40
30
|
//# sourceMappingURL=main.d.ts.map
|
package/dist/main.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"main.d.ts","names":[],"sources":["../src/theme.ts","../src/
|
|
1
|
+
{"version":3,"file":"main.d.ts","names":[],"sources":["../src/theme.ts","../src/theme-persistence.ts","../src/theme-form-controller.ts","../src/main.ts"],"mappings":";;;cAEM,MAAA;AAAA,KACM,KAAA,WAAgB,MAAA;AAAA,cAGf,aAAA,EAAe,KAAA;;;cCwCf,sBAAA;;;UC1CH,gBAAA;EACR,IAAA,GAAO,KAAA,EAAO,KAAA;EACd,MAAA;AAAA;AAAA,iBAsBc,aAAA,CAAc,aAAA,GAAgB,KAAA,EAAO,KAAA,YAAiB,gBAAA;;;UCvB5D,WAAA;EACR,YAAA,GAAe,KAAA;AAAA;AAAA,UAGP,gBAAA;EACR,MAAA,QAAc,MAAA;AAAA;AAAA,iBAGA,IAAA,CAAA;EAAO;AAAA,IAAgC,WAAA,GAAmB,gBAAA"}
|
package/dist/main.js
CHANGED
|
@@ -73,6 +73,39 @@ function SettingsPage({ defaultTheme }) {
|
|
|
73
73
|
})] });
|
|
74
74
|
}
|
|
75
75
|
|
|
76
|
+
//#endregion
|
|
77
|
+
//#region src/theme-persistence.ts
|
|
78
|
+
const THEME_STORAGE_KEY = `${DEFAULT_PREFIX}-theme`;
|
|
79
|
+
function getStorage() {
|
|
80
|
+
try {
|
|
81
|
+
return globalThis.localStorage ?? null;
|
|
82
|
+
} catch {
|
|
83
|
+
return null;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
function readPersistedTheme() {
|
|
87
|
+
const storage = getStorage();
|
|
88
|
+
if (!storage) return null;
|
|
89
|
+
let value = null;
|
|
90
|
+
try {
|
|
91
|
+
value = storage.getItem(THEME_STORAGE_KEY);
|
|
92
|
+
} catch {
|
|
93
|
+
return null;
|
|
94
|
+
}
|
|
95
|
+
if (!isTheme(value)) return null;
|
|
96
|
+
return value;
|
|
97
|
+
}
|
|
98
|
+
function persistTheme(theme) {
|
|
99
|
+
const storage = getStorage();
|
|
100
|
+
if (!storage) return;
|
|
101
|
+
try {
|
|
102
|
+
storage.setItem(THEME_STORAGE_KEY, theme);
|
|
103
|
+
} catch {
|
|
104
|
+
return;
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
const THEME_BOOTSTRAP_SCRIPT = "try{let theme=localStorage.getItem('slk-settings-theme');if(['system','light','dark'].includes(theme)){document.documentElement.setAttribute('data-slk-settings-theme',theme)}}catch{}";
|
|
108
|
+
|
|
76
109
|
//#endregion
|
|
77
110
|
//#region src/theme-form-controller.ts
|
|
78
111
|
function getSelectedTheme(form) {
|
|
@@ -95,13 +128,17 @@ function bindThemeForm(onThemeChange) {
|
|
|
95
128
|
const selectedTheme = getSelectedTheme(form);
|
|
96
129
|
if (!selectedTheme) return;
|
|
97
130
|
onThemeChange(selectedTheme);
|
|
131
|
+
persistTheme(selectedTheme);
|
|
98
132
|
}
|
|
99
|
-
const
|
|
133
|
+
const persistedTheme = readPersistedTheme();
|
|
134
|
+
if (persistedTheme) syncThemeStateToDom(radios, persistedTheme);
|
|
135
|
+
const initialSelectedTheme = persistedTheme ?? getSelectedTheme(form);
|
|
100
136
|
if (initialSelectedTheme) onThemeChange(initialSelectedTheme);
|
|
101
137
|
form.addEventListener("change", syncThemeFromForm);
|
|
102
138
|
return {
|
|
103
139
|
sync(theme) {
|
|
104
140
|
syncThemeStateToDom(radios, theme);
|
|
141
|
+
persistTheme(theme);
|
|
105
142
|
},
|
|
106
143
|
unbind() {
|
|
107
144
|
form.removeEventListener("change", syncThemeFromForm);
|
|
@@ -121,5 +158,5 @@ function render(defaultTheme) {
|
|
|
121
158
|
}
|
|
122
159
|
|
|
123
160
|
//#endregion
|
|
124
|
-
export {
|
|
161
|
+
export { DEFAULT_THEME, THEME_BOOTSTRAP_SCRIPT, bindThemeForm, init };
|
|
125
162
|
//# sourceMappingURL=main.js.map
|
package/dist/main.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"main.js","names":[],"sources":["../src/settings-page-names.ts","../src/theme.ts","../src/settings-page.tsx","../src/theme-form-controller.ts","../src/main.ts"],"sourcesContent":["export const DEFAULT_PREFIX = \"slk-settings\";\n\nexport interface SettingsPageNames {\n appearanceTitle: string;\n appearanceForm: string;\n themeSystem: string;\n themeLight: string;\n themeDark: string;\n}\n\nexport const SETTINGS_PAGE_NAMES: SettingsPageNames = {\n appearanceTitle: `${DEFAULT_PREFIX}-appearance-title`,\n appearanceForm: `${DEFAULT_PREFIX}-appearance-form`,\n themeSystem: `${DEFAULT_PREFIX}-theme-system`,\n themeLight: `${DEFAULT_PREFIX}-theme-light`,\n themeDark: `${DEFAULT_PREFIX}-theme-dark`,\n};\n","import { DEFAULT_PREFIX } from \"./settings-page-names\";\n\nconst THEMES = [\"system\", \"light\", \"dark\"] as const;\nexport type Theme = (typeof THEMES)[number];\n\nexport const THEME_FIELD_NAME: string = `${DEFAULT_PREFIX}-theme`;\nexport const DEFAULT_THEME: Theme = THEMES[0];\n\nexport function isTheme(value: unknown): value is Theme {\n return THEMES.some((theme) => theme === value);\n}\n","/** @jsxImportSource hastscript */\n\nimport type { Result as HastResult } from \"hastscript\";\nimport { SETTINGS_PAGE_NAMES } from \"./settings-page-names\";\nimport { THEME_FIELD_NAME, type Theme } from \"./theme\";\n\nexport interface SettingsPageProps {\n defaultTheme: Theme;\n}\n\nexport function SettingsPage({ defaultTheme }: SettingsPageProps): HastResult {\n return (\n <>\n <h1>Settings</h1>\n <section aria-labelledby={SETTINGS_PAGE_NAMES.appearanceTitle}>\n <h2 id={SETTINGS_PAGE_NAMES.appearanceTitle}>Appearance</h2>\n <form id={SETTINGS_PAGE_NAMES.appearanceForm}>\n <fieldset>\n <legend>Theme</legend>\n <input\n type=\"radio\"\n id={SETTINGS_PAGE_NAMES.themeSystem}\n name={THEME_FIELD_NAME}\n value=\"system\"\n checked={defaultTheme === \"system\"}\n />\n <label for={SETTINGS_PAGE_NAMES.themeSystem}>System</label>\n <input\n type=\"radio\"\n id={SETTINGS_PAGE_NAMES.themeLight}\n name={THEME_FIELD_NAME}\n value=\"light\"\n checked={defaultTheme === \"light\"}\n />\n <label for={SETTINGS_PAGE_NAMES.themeLight}>Light</label>\n <input\n type=\"radio\"\n id={SETTINGS_PAGE_NAMES.themeDark}\n name={THEME_FIELD_NAME}\n value=\"dark\"\n checked={defaultTheme === \"dark\"}\n />\n <label for={SETTINGS_PAGE_NAMES.themeDark}>Dark</label>\n </fieldset>\n </form>\n </section>\n </>\n );\n}\n","import { SETTINGS_PAGE_NAMES } from \"./settings-page-names\";\nimport { isTheme, THEME_FIELD_NAME, type Theme } from \"./theme\";\n\ninterface ThemeFormBinding {\n sync: (theme: Theme) => void;\n unbind: () => void;\n}\n\nfunction getSelectedTheme(form: HTMLFormElement): Theme | null {\n const theme = new FormData(form).get(THEME_FIELD_NAME);\n if (!isTheme(theme)) {\n return null;\n }\n\n return theme;\n}\n\nfunction syncThemeStateToDom(radios: NodeListOf<HTMLInputElement>, theme: Theme) {\n for (const radio of radios) {\n const checked = radio.value === theme;\n radio.checked = checked;\n radio.defaultChecked = checked;\n }\n\n document.documentElement.setAttribute(`data-${THEME_FIELD_NAME}`, theme);\n}\n\nexport function bindThemeForm(onThemeChange: (theme: Theme) => void): ThemeFormBinding {\n const form = document.getElementById(SETTINGS_PAGE_NAMES.appearanceForm) as HTMLFormElement;\n const radios = form.querySelectorAll<HTMLInputElement>(`input[name=\"${THEME_FIELD_NAME}\"]`);\n\n function syncThemeFromForm() {\n const selectedTheme = getSelectedTheme(form);\n if (!selectedTheme) {\n return;\n }\n\n onThemeChange(selectedTheme);\n }\n\n const initialSelectedTheme = getSelectedTheme(form);\n if (initialSelectedTheme) {\n onThemeChange(initialSelectedTheme);\n }\n\n form.addEventListener(\"change\", syncThemeFromForm);\n\n return {\n sync(theme: Theme) {\n syncThemeStateToDom(radios, theme);\n },\n unbind() {\n form.removeEventListener(\"change\", syncThemeFromForm);\n },\n };\n}\n","import type { Result as HastResult } from \"hastscript\";\nimport { SettingsPage } from \"./settings-page\";\nimport { DEFAULT_THEME, type Theme } from \"./theme\";\n\ninterface InitOptions {\n defaultTheme?: Theme;\n}\n\ninterface SettingsRenderer {\n render: () => HastResult;\n}\n\nexport function init({ defaultTheme = DEFAULT_THEME }: InitOptions = {}): SettingsRenderer {\n return {\n render() {\n return render(defaultTheme);\n },\n };\n}\n\nfunction render(defaultTheme: Theme): HastResult {\n return SettingsPage({ defaultTheme });\n}\n\nexport {
|
|
1
|
+
{"version":3,"file":"main.js","names":[],"sources":["../src/settings-page-names.ts","../src/theme.ts","../src/settings-page.tsx","../src/theme-persistence.ts","../src/theme-form-controller.ts","../src/main.ts"],"sourcesContent":["export const DEFAULT_PREFIX = \"slk-settings\";\n\nexport interface SettingsPageNames {\n appearanceTitle: string;\n appearanceForm: string;\n themeSystem: string;\n themeLight: string;\n themeDark: string;\n}\n\nexport const SETTINGS_PAGE_NAMES: SettingsPageNames = {\n appearanceTitle: `${DEFAULT_PREFIX}-appearance-title`,\n appearanceForm: `${DEFAULT_PREFIX}-appearance-form`,\n themeSystem: `${DEFAULT_PREFIX}-theme-system`,\n themeLight: `${DEFAULT_PREFIX}-theme-light`,\n themeDark: `${DEFAULT_PREFIX}-theme-dark`,\n};\n","import { DEFAULT_PREFIX } from \"./settings-page-names\";\n\nconst THEMES = [\"system\", \"light\", \"dark\"] as const;\nexport type Theme = (typeof THEMES)[number];\n\nexport const THEME_FIELD_NAME: string = `${DEFAULT_PREFIX}-theme`;\nexport const DEFAULT_THEME: Theme = THEMES[0];\n\nexport function isTheme(value: unknown): value is Theme {\n return THEMES.some((theme) => theme === value);\n}\n","/** @jsxImportSource hastscript */\n\nimport type { Result as HastResult } from \"hastscript\";\nimport { SETTINGS_PAGE_NAMES } from \"./settings-page-names\";\nimport { THEME_FIELD_NAME, type Theme } from \"./theme\";\n\nexport interface SettingsPageProps {\n defaultTheme: Theme;\n}\n\nexport function SettingsPage({ defaultTheme }: SettingsPageProps): HastResult {\n return (\n <>\n <h1>Settings</h1>\n <section aria-labelledby={SETTINGS_PAGE_NAMES.appearanceTitle}>\n <h2 id={SETTINGS_PAGE_NAMES.appearanceTitle}>Appearance</h2>\n <form id={SETTINGS_PAGE_NAMES.appearanceForm}>\n <fieldset>\n <legend>Theme</legend>\n <input\n type=\"radio\"\n id={SETTINGS_PAGE_NAMES.themeSystem}\n name={THEME_FIELD_NAME}\n value=\"system\"\n checked={defaultTheme === \"system\"}\n />\n <label for={SETTINGS_PAGE_NAMES.themeSystem}>System</label>\n <input\n type=\"radio\"\n id={SETTINGS_PAGE_NAMES.themeLight}\n name={THEME_FIELD_NAME}\n value=\"light\"\n checked={defaultTheme === \"light\"}\n />\n <label for={SETTINGS_PAGE_NAMES.themeLight}>Light</label>\n <input\n type=\"radio\"\n id={SETTINGS_PAGE_NAMES.themeDark}\n name={THEME_FIELD_NAME}\n value=\"dark\"\n checked={defaultTheme === \"dark\"}\n />\n <label for={SETTINGS_PAGE_NAMES.themeDark}>Dark</label>\n </fieldset>\n </form>\n </section>\n </>\n );\n}\n","import { DEFAULT_PREFIX } from \"./settings-page-names\";\nimport { isTheme, type Theme } from \"./theme\";\n\nconst THEME_STORAGE_KEY: string = `${DEFAULT_PREFIX}-theme`;\n\nfunction getStorage(): Storage | null {\n try {\n return globalThis.localStorage ?? null;\n } catch {\n return null;\n }\n}\n\nexport function readPersistedTheme(): Theme | null {\n const storage = getStorage();\n if (!storage) {\n return null;\n }\n\n let value: string | null = null;\n try {\n value = storage.getItem(THEME_STORAGE_KEY);\n } catch {\n return null;\n }\n\n if (!isTheme(value)) {\n return null;\n }\n\n return value;\n}\n\nexport function persistTheme(theme: Theme): void {\n const storage = getStorage();\n if (!storage) {\n return;\n }\n\n try {\n storage.setItem(THEME_STORAGE_KEY, theme);\n } catch {\n return;\n }\n}\n\nexport const THEME_BOOTSTRAP_SCRIPT =\n \"try{let theme=localStorage.getItem('slk-settings-theme');if(['system','light','dark'].includes(theme)){document.documentElement.setAttribute('data-slk-settings-theme',theme)}}catch{}\";\n","import { SETTINGS_PAGE_NAMES } from \"./settings-page-names\";\nimport { isTheme, THEME_FIELD_NAME, type Theme } from \"./theme\";\nimport { persistTheme, readPersistedTheme } from \"./theme-persistence\";\n\ninterface ThemeFormBinding {\n sync: (theme: Theme) => void;\n unbind: () => void;\n}\n\nfunction getSelectedTheme(form: HTMLFormElement): Theme | null {\n const theme = new FormData(form).get(THEME_FIELD_NAME);\n if (!isTheme(theme)) {\n return null;\n }\n\n return theme;\n}\n\nfunction syncThemeStateToDom(radios: NodeListOf<HTMLInputElement>, theme: Theme) {\n for (const radio of radios) {\n const checked = radio.value === theme;\n radio.checked = checked;\n radio.defaultChecked = checked;\n }\n\n document.documentElement.setAttribute(`data-${THEME_FIELD_NAME}`, theme);\n}\n\nexport function bindThemeForm(onThemeChange: (theme: Theme) => void): ThemeFormBinding {\n const form = document.getElementById(SETTINGS_PAGE_NAMES.appearanceForm) as HTMLFormElement;\n const radios = form.querySelectorAll<HTMLInputElement>(`input[name=\"${THEME_FIELD_NAME}\"]`);\n\n function syncThemeFromForm() {\n const selectedTheme = getSelectedTheme(form);\n if (!selectedTheme) {\n return;\n }\n\n onThemeChange(selectedTheme);\n persistTheme(selectedTheme);\n }\n\n const persistedTheme = readPersistedTheme();\n if (persistedTheme) {\n syncThemeStateToDom(radios, persistedTheme);\n }\n\n const initialSelectedTheme = persistedTheme ?? getSelectedTheme(form);\n if (initialSelectedTheme) {\n onThemeChange(initialSelectedTheme);\n }\n\n form.addEventListener(\"change\", syncThemeFromForm);\n\n return {\n sync(theme: Theme) {\n syncThemeStateToDom(radios, theme);\n persistTheme(theme);\n },\n unbind() {\n form.removeEventListener(\"change\", syncThemeFromForm);\n },\n };\n}\n","import type { Result as HastResult } from \"hastscript\";\nimport { SettingsPage } from \"./settings-page\";\nimport { DEFAULT_THEME, type Theme } from \"./theme\";\nimport { THEME_BOOTSTRAP_SCRIPT } from \"./theme-persistence\";\n\ninterface InitOptions {\n defaultTheme?: Theme;\n}\n\ninterface SettingsRenderer {\n render: () => HastResult;\n}\n\nexport function init({ defaultTheme = DEFAULT_THEME }: InitOptions = {}): SettingsRenderer {\n return {\n render() {\n return render(defaultTheme);\n },\n };\n}\n\nfunction render(defaultTheme: Theme): HastResult {\n return SettingsPage({ defaultTheme });\n}\n\nexport { bindThemeForm } from \"./theme-form-controller\";\nexport { DEFAULT_THEME, type Theme } from \"./theme\";\nexport { THEME_BOOTSTRAP_SCRIPT };\n"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@seamline-kit/seamline-settings",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.5",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"files": [
|
|
6
6
|
"dist"
|
|
@@ -19,6 +19,16 @@
|
|
|
19
19
|
"publishConfig": {
|
|
20
20
|
"access": "public"
|
|
21
21
|
},
|
|
22
|
+
"dependencies": {
|
|
23
|
+
"hastscript": "9.0.1"
|
|
24
|
+
},
|
|
25
|
+
"devDependencies": {
|
|
26
|
+
"@vitest/browser-playwright": "4.0.18",
|
|
27
|
+
"oxfmt": "0.32.0",
|
|
28
|
+
"oxlint": "1.47.0",
|
|
29
|
+
"tsdown": "0.20.3",
|
|
30
|
+
"vitest": "4.0.18"
|
|
31
|
+
},
|
|
22
32
|
"scripts": {
|
|
23
33
|
"dev": "tsdown --watch",
|
|
24
34
|
"build": "tsdown",
|
|
@@ -33,16 +43,5 @@
|
|
|
33
43
|
"lint:fix": "oxlint --fix",
|
|
34
44
|
"format": "oxfmt --ignore-path ../../.gitignore .",
|
|
35
45
|
"format:check": "oxfmt --check --ignore-path ../../.gitignore ."
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
"hastscript": "9.0.1"
|
|
39
|
-
},
|
|
40
|
-
"devDependencies": {
|
|
41
|
-
"@vitest/browser-playwright": "4.0.18",
|
|
42
|
-
"oxfmt": "0.32.0",
|
|
43
|
-
"oxlint": "1.47.0",
|
|
44
|
-
"tsdown": "0.20.3",
|
|
45
|
-
"vitest": "4.0.18"
|
|
46
|
-
},
|
|
47
|
-
"packageManager": "pnpm@10.29.3"
|
|
48
|
-
}
|
|
46
|
+
}
|
|
47
|
+
}
|