@real1ty-obsidian-plugins/utils 2.26.0 → 2.28.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/dist/components/index.d.ts +1 -0
- package/dist/components/index.d.ts.map +1 -1
- package/dist/components/index.js +1 -0
- package/dist/components/index.js.map +1 -1
- package/dist/components/registered-events-component.d.ts +30 -0
- package/dist/components/registered-events-component.d.ts.map +1 -0
- package/dist/components/registered-events-component.js +43 -0
- package/dist/components/registered-events-component.js.map +1 -0
- package/dist/settings/settings-ui-builder.d.ts +8 -1
- package/dist/settings/settings-ui-builder.d.ts.map +1 -1
- package/dist/settings/settings-ui-builder.js +82 -22
- package/dist/settings/settings-ui-builder.js.map +1 -1
- package/package.json +1 -1
- package/src/components/index.ts +1 -0
- package/src/components/registered-events-component.ts +56 -0
- package/src/settings/settings-ui-builder.ts +101 -29
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/components/index.ts"],"names":[],"mappings":"AAAA,cAAc,iCAAiC,CAAC;AAChD,cAAc,kBAAkB,CAAC;AACjC,cAAc,mBAAmB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/components/index.ts"],"names":[],"mappings":"AAAA,cAAc,iCAAiC,CAAC;AAChD,cAAc,kBAAkB,CAAC;AACjC,cAAc,+BAA+B,CAAC;AAC9C,cAAc,mBAAmB,CAAC"}
|
package/dist/components/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/components/index.ts"],"names":[],"mappings":"AAAA,cAAc,iCAAiC,CAAC;AAChD,cAAc,kBAAkB,CAAC;AACjC,cAAc,mBAAmB,CAAC","sourcesContent":["export * from \"./frontmatter-propagation-modal\";\nexport * from \"./input-managers\";\nexport * from \"./whats-new-modal\";\n"]}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/components/index.ts"],"names":[],"mappings":"AAAA,cAAc,iCAAiC,CAAC;AAChD,cAAc,kBAAkB,CAAC;AACjC,cAAc,+BAA+B,CAAC;AAC9C,cAAc,mBAAmB,CAAC","sourcesContent":["export * from \"./frontmatter-propagation-modal\";\nexport * from \"./input-managers\";\nexport * from \"./registered-events-component\";\nexport * from \"./whats-new-modal\";\n"]}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import type { EventRef } from "obsidian";
|
|
2
|
+
/**
|
|
3
|
+
* Base class that provides event registration and automatic cleanup.
|
|
4
|
+
* Similar to ItemView's registerEvent/registerDomEvent pattern.
|
|
5
|
+
*
|
|
6
|
+
* Subclasses should call cleanupEvents() in their destroy/cleanup method.
|
|
7
|
+
*/
|
|
8
|
+
export declare abstract class RegisteredEventsComponent {
|
|
9
|
+
protected eventRefs: EventRef[];
|
|
10
|
+
protected eventCleanupFunctions: Array<() => void>;
|
|
11
|
+
/**
|
|
12
|
+
* Register an Obsidian event (workspace, vault, metadataCache, etc.)
|
|
13
|
+
* Event will be automatically cleaned up when destroy() is called
|
|
14
|
+
*/
|
|
15
|
+
protected registerEvent<T extends keyof any>(emitter: {
|
|
16
|
+
on(event: T, callback: (...args: any[]) => void): void;
|
|
17
|
+
off(event: T, callback: (...args: any[]) => void): void;
|
|
18
|
+
}, event: T, callback: (...args: any[]) => void): void;
|
|
19
|
+
/**
|
|
20
|
+
* Register a DOM event (window, document, or element)
|
|
21
|
+
* Event will be automatically cleaned up when destroy() is called
|
|
22
|
+
*/
|
|
23
|
+
protected registerDomEvent<K extends keyof WindowEventMap>(target: Window | Document | HTMLElement, event: K, callback: (evt: WindowEventMap[K]) => void): void;
|
|
24
|
+
/**
|
|
25
|
+
* Clean up all registered events.
|
|
26
|
+
* Should be called by subclass destroy() method.
|
|
27
|
+
*/
|
|
28
|
+
protected cleanupEvents(): void;
|
|
29
|
+
}
|
|
30
|
+
//# sourceMappingURL=registered-events-component.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"registered-events-component.d.ts","sourceRoot":"","sources":["../../src/components/registered-events-component.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AAEzC;;;;;GAKG;AACH,8BAAsB,yBAAyB;IAC9C,SAAS,CAAC,SAAS,EAAE,QAAQ,EAAE,CAAM;IACrC,SAAS,CAAC,qBAAqB,EAAE,KAAK,CAAC,MAAM,IAAI,CAAC,CAAM;IAExD;;;OAGG;IACH,SAAS,CAAC,aAAa,CAAC,CAAC,SAAS,MAAM,GAAG,EAC1C,OAAO,EAAE;QACR,EAAE,CAAC,KAAK,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,IAAI,GAAG,IAAI,CAAC;QACvD,GAAG,CAAC,KAAK,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,IAAI,GAAG,IAAI,CAAC;KACxD,EACD,KAAK,EAAE,CAAC,EACR,QAAQ,EAAE,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,IAAI,GAChC,IAAI;IAOP;;;OAGG;IACH,SAAS,CAAC,gBAAgB,CAAC,CAAC,SAAS,MAAM,cAAc,EACxD,MAAM,EAAE,MAAM,GAAG,QAAQ,GAAG,WAAW,EACvC,KAAK,EAAE,CAAC,EACR,QAAQ,EAAE,CAAC,GAAG,EAAE,cAAc,CAAC,CAAC,CAAC,KAAK,IAAI,GACxC,IAAI;IAOP;;;OAGG;IACH,SAAS,CAAC,aAAa,IAAI,IAAI;CAM/B"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Base class that provides event registration and automatic cleanup.
|
|
3
|
+
* Similar to ItemView's registerEvent/registerDomEvent pattern.
|
|
4
|
+
*
|
|
5
|
+
* Subclasses should call cleanupEvents() in their destroy/cleanup method.
|
|
6
|
+
*/
|
|
7
|
+
export class RegisteredEventsComponent {
|
|
8
|
+
constructor() {
|
|
9
|
+
this.eventRefs = [];
|
|
10
|
+
this.eventCleanupFunctions = [];
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Register an Obsidian event (workspace, vault, metadataCache, etc.)
|
|
14
|
+
* Event will be automatically cleaned up when destroy() is called
|
|
15
|
+
*/
|
|
16
|
+
registerEvent(emitter, event, callback) {
|
|
17
|
+
emitter.on(event, callback);
|
|
18
|
+
this.eventCleanupFunctions.push(() => {
|
|
19
|
+
emitter.off(event, callback);
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Register a DOM event (window, document, or element)
|
|
24
|
+
* Event will be automatically cleaned up when destroy() is called
|
|
25
|
+
*/
|
|
26
|
+
registerDomEvent(target, event, callback) {
|
|
27
|
+
target.addEventListener(event, callback);
|
|
28
|
+
this.eventCleanupFunctions.push(() => {
|
|
29
|
+
target.removeEventListener(event, callback);
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Clean up all registered events.
|
|
34
|
+
* Should be called by subclass destroy() method.
|
|
35
|
+
*/
|
|
36
|
+
cleanupEvents() {
|
|
37
|
+
for (const cleanup of this.eventCleanupFunctions) {
|
|
38
|
+
cleanup();
|
|
39
|
+
}
|
|
40
|
+
this.eventCleanupFunctions = [];
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
//# sourceMappingURL=registered-events-component.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"registered-events-component.js","sourceRoot":"","sources":["../../src/components/registered-events-component.ts"],"names":[],"mappings":"AAEA;;;;;GAKG;AACH,MAAM,OAAgB,yBAAyB;IAA/C;QACW,cAAS,GAAe,EAAE,CAAC;QAC3B,0BAAqB,GAAsB,EAAE,CAAC;IA6CzD,CAAC;IA3CA;;;OAGG;IACO,aAAa,CACtB,OAGC,EACD,KAAQ,EACR,QAAkC;QAElC,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;QAC5B,IAAI,CAAC,qBAAqB,CAAC,IAAI,CAAC,GAAG,EAAE;YACpC,OAAO,CAAC,GAAG,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;QAC9B,CAAC,CAAC,CAAC;IACJ,CAAC;IAED;;;OAGG;IACO,gBAAgB,CACzB,MAAuC,EACvC,KAAQ,EACR,QAA0C;QAE1C,MAAM,CAAC,gBAAgB,CAAC,KAAK,EAAE,QAAyB,CAAC,CAAC;QAC1D,IAAI,CAAC,qBAAqB,CAAC,IAAI,CAAC,GAAG,EAAE;YACpC,MAAM,CAAC,mBAAmB,CAAC,KAAK,EAAE,QAAyB,CAAC,CAAC;QAC9D,CAAC,CAAC,CAAC;IACJ,CAAC;IAED;;;OAGG;IACO,aAAa;QACtB,KAAK,MAAM,OAAO,IAAI,IAAI,CAAC,qBAAqB,EAAE,CAAC;YAClD,OAAO,EAAE,CAAC;QACX,CAAC;QACD,IAAI,CAAC,qBAAqB,GAAG,EAAE,CAAC;IACjC,CAAC;CACD","sourcesContent":["import type { EventRef } from \"obsidian\";\n\n/**\n * Base class that provides event registration and automatic cleanup.\n * Similar to ItemView's registerEvent/registerDomEvent pattern.\n *\n * Subclasses should call cleanupEvents() in their destroy/cleanup method.\n */\nexport abstract class RegisteredEventsComponent {\n\tprotected eventRefs: EventRef[] = [];\n\tprotected eventCleanupFunctions: Array<() => void> = [];\n\n\t/**\n\t * Register an Obsidian event (workspace, vault, metadataCache, etc.)\n\t * Event will be automatically cleaned up when destroy() is called\n\t */\n\tprotected registerEvent<T extends keyof any>(\n\t\temitter: {\n\t\t\ton(event: T, callback: (...args: any[]) => void): void;\n\t\t\toff(event: T, callback: (...args: any[]) => void): void;\n\t\t},\n\t\tevent: T,\n\t\tcallback: (...args: any[]) => void\n\t): void {\n\t\temitter.on(event, callback);\n\t\tthis.eventCleanupFunctions.push(() => {\n\t\t\temitter.off(event, callback);\n\t\t});\n\t}\n\n\t/**\n\t * Register a DOM event (window, document, or element)\n\t * Event will be automatically cleaned up when destroy() is called\n\t */\n\tprotected registerDomEvent<K extends keyof WindowEventMap>(\n\t\ttarget: Window | Document | HTMLElement,\n\t\tevent: K,\n\t\tcallback: (evt: WindowEventMap[K]) => void\n\t): void {\n\t\ttarget.addEventListener(event, callback as EventListener);\n\t\tthis.eventCleanupFunctions.push(() => {\n\t\t\ttarget.removeEventListener(event, callback as EventListener);\n\t\t});\n\t}\n\n\t/**\n\t * Clean up all registered events.\n\t * Should be called by subclass destroy() method.\n\t */\n\tprotected cleanupEvents(): void {\n\t\tfor (const cleanup of this.eventCleanupFunctions) {\n\t\t\tcleanup();\n\t\t}\n\t\tthis.eventCleanupFunctions = [];\n\t}\n}\n"]}
|
|
@@ -49,6 +49,14 @@ export declare class SettingsUIBuilder<TSchema extends ZodObject<ZodRawShape>> {
|
|
|
49
49
|
constructor(settingsStore: SettingsStore<TSchema>);
|
|
50
50
|
private get settings();
|
|
51
51
|
private get schema();
|
|
52
|
+
/**
|
|
53
|
+
* Gets a nested property value using dot notation (e.g., "basesView.tasksDirectory")
|
|
54
|
+
*/
|
|
55
|
+
private getNestedValue;
|
|
56
|
+
/**
|
|
57
|
+
* Sets a nested property value using dot notation and returns updated settings
|
|
58
|
+
*/
|
|
59
|
+
private setNestedValue;
|
|
52
60
|
private updateSetting;
|
|
53
61
|
private inferSliderBounds;
|
|
54
62
|
private inferArrayItemType;
|
|
@@ -59,7 +67,6 @@ export declare class SettingsUIBuilder<TSchema extends ZodObject<ZodRawShape>> {
|
|
|
59
67
|
addTextArray<T = string>(containerEl: HTMLElement, config: ArraySettingConfig<T>): void;
|
|
60
68
|
/**
|
|
61
69
|
* Advanced array manager with add/remove buttons for each item
|
|
62
|
-
* Similar to the directory settings pattern
|
|
63
70
|
*/
|
|
64
71
|
addArrayManager(containerEl: HTMLElement, config: ArrayManagerConfig): void;
|
|
65
72
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"settings-ui-builder.d.ts","sourceRoot":"","sources":["../../src/settings/settings-ui-builder.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAuB,SAAS,EAAE,WAAW,EAAK,MAAM,KAAK,CAAC;AAC1E,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAEtD,UAAU,iBAAiB;IAC1B,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;CACb;AAED,UAAU,iBAAkB,SAAQ,iBAAiB;IACpD,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,cAAc,CAAC,EAAE,OAAO,CAAC;CACzB;AAED,UAAU,mBAAoB,SAAQ,iBAAiB;IACtD,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,cAAc,CAAC,EAAE,OAAO,CAAC;CACzB;AAED,UAAU,qBAAsB,SAAQ,iBAAiB;IACxD,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAChC;AAED,UAAU,kBAAkB,CAAC,CAAC,GAAG,MAAM,CAAE,SAAQ,iBAAiB;IACjE,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,QAAQ,CAAC,EAAE,QAAQ,GAAG,QAAQ,CAAC;IAC/B,MAAM,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,CAAC,CAAC;IAC9B,SAAS,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,OAAO,CAAC;CACjC;AAED,UAAU,kBAAmB,SAAQ,iBAAiB;IACrD,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,iBAAiB,CAAC,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,MAAM,CAAC;IAC9C,WAAW,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,EAAE,YAAY,EAAE,OAAO,EAAE,KAAK,OAAO,EAAE,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC;IAC5F,cAAc,CAAC,EAAE,CAChB,YAAY,EAAE,OAAO,EACrB,YAAY,EAAE,OAAO,EAAE,KACnB,OAAO,EAAE,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC;IACpC,YAAY,CAAC,EAAE,KAAK,CAAC;QACpB,IAAI,EAAE,MAAM,CAAC;QACb,IAAI,EAAE,MAAM,CAAC;QACb,UAAU,EAAE,MAAM,CAAC;QACnB,SAAS,CAAC,EAAE,CAAC,YAAY,EAAE,OAAO,EAAE,KAAK,OAAO,CAAC;QACjD,MAAM,EAAE,CAAC,YAAY,EAAE,OAAO,EAAE,KAAK,OAAO,EAAE,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC;KACpE,CAAC,CAAC;CACH;AAED,qBAAa,iBAAiB,CAAC,OAAO,SAAS,SAAS,CAAC,WAAW,CAAC;IACxD,OAAO,CAAC,aAAa;gBAAb,aAAa,EAAE,aAAa,CAAC,OAAO,CAAC;IAEzD,OAAO,KAAK,QAAQ,GAEnB;IAED,OAAO,KAAK,MAAM,GAEjB;
|
|
1
|
+
{"version":3,"file":"settings-ui-builder.d.ts","sourceRoot":"","sources":["../../src/settings/settings-ui-builder.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAuB,SAAS,EAAE,WAAW,EAAK,MAAM,KAAK,CAAC;AAC1E,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAEtD,UAAU,iBAAiB;IAC1B,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;CACb;AAED,UAAU,iBAAkB,SAAQ,iBAAiB;IACpD,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,cAAc,CAAC,EAAE,OAAO,CAAC;CACzB;AAED,UAAU,mBAAoB,SAAQ,iBAAiB;IACtD,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,cAAc,CAAC,EAAE,OAAO,CAAC;CACzB;AAED,UAAU,qBAAsB,SAAQ,iBAAiB;IACxD,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAChC;AAED,UAAU,kBAAkB,CAAC,CAAC,GAAG,MAAM,CAAE,SAAQ,iBAAiB;IACjE,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,QAAQ,CAAC,EAAE,QAAQ,GAAG,QAAQ,CAAC;IAC/B,MAAM,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,CAAC,CAAC;IAC9B,SAAS,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,OAAO,CAAC;CACjC;AAED,UAAU,kBAAmB,SAAQ,iBAAiB;IACrD,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,iBAAiB,CAAC,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,MAAM,CAAC;IAC9C,WAAW,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,EAAE,YAAY,EAAE,OAAO,EAAE,KAAK,OAAO,EAAE,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC;IAC5F,cAAc,CAAC,EAAE,CAChB,YAAY,EAAE,OAAO,EACrB,YAAY,EAAE,OAAO,EAAE,KACnB,OAAO,EAAE,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC;IACpC,YAAY,CAAC,EAAE,KAAK,CAAC;QACpB,IAAI,EAAE,MAAM,CAAC;QACb,IAAI,EAAE,MAAM,CAAC;QACb,UAAU,EAAE,MAAM,CAAC;QACnB,SAAS,CAAC,EAAE,CAAC,YAAY,EAAE,OAAO,EAAE,KAAK,OAAO,CAAC;QACjD,MAAM,EAAE,CAAC,YAAY,EAAE,OAAO,EAAE,KAAK,OAAO,EAAE,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC;KACpE,CAAC,CAAC;CACH;AAED,qBAAa,iBAAiB,CAAC,OAAO,SAAS,SAAS,CAAC,WAAW,CAAC;IACxD,OAAO,CAAC,aAAa;gBAAb,aAAa,EAAE,aAAa,CAAC,OAAO,CAAC;IAEzD,OAAO,KAAK,QAAQ,GAEnB;IAED,OAAO,KAAK,MAAM,GAEjB;IAED;;OAEG;IACH,OAAO,CAAC,cAAc;IActB;;OAEG;IACH,OAAO,CAAC,cAAc;YAsBR,aAAa;IAgB3B,OAAO,CAAC,iBAAiB;IA+CzB,OAAO,CAAC,kBAAkB;IAwC1B,SAAS,CAAC,WAAW,EAAE,WAAW,EAAE,MAAM,EAAE,iBAAiB,GAAG,IAAI;IAcpE,SAAS,CAAC,WAAW,EAAE,WAAW,EAAE,MAAM,EAAE,mBAAmB,GAAG,IAAI;IAqDtE,OAAO,CAAC,WAAW,EAAE,WAAW,EAAE,MAAM,EAAE,iBAAiB,GAAG,IAAI;IAqClE,WAAW,CAAC,WAAW,EAAE,WAAW,EAAE,MAAM,EAAE,qBAAqB,GAAG,IAAI;IAiB1E,YAAY,CAAC,CAAC,GAAG,MAAM,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,EAAE,kBAAkB,CAAC,CAAC,CAAC,GAAG,IAAI;IA0GvF;;OAEG;IACH,eAAe,CAAC,WAAW,EAAE,WAAW,EAAE,MAAM,EAAE,kBAAkB,GAAG,IAAI;CAuI3E"}
|
|
@@ -10,9 +10,43 @@ export class SettingsUIBuilder {
|
|
|
10
10
|
get schema() {
|
|
11
11
|
return this.settingsStore.validationSchema;
|
|
12
12
|
}
|
|
13
|
+
/**
|
|
14
|
+
* Gets a nested property value using dot notation (e.g., "basesView.tasksDirectory")
|
|
15
|
+
*/
|
|
16
|
+
getNestedValue(key) {
|
|
17
|
+
const keys = key.split(".");
|
|
18
|
+
let value = this.settings;
|
|
19
|
+
for (const k of keys) {
|
|
20
|
+
if (value === undefined || value === null) {
|
|
21
|
+
return undefined;
|
|
22
|
+
}
|
|
23
|
+
value = value[k];
|
|
24
|
+
}
|
|
25
|
+
return value;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Sets a nested property value using dot notation and returns updated settings
|
|
29
|
+
*/
|
|
30
|
+
setNestedValue(key, value) {
|
|
31
|
+
const keys = key.split(".");
|
|
32
|
+
const newSettings = JSON.parse(JSON.stringify(this.settings)); // Deep clone
|
|
33
|
+
let current = newSettings;
|
|
34
|
+
// Navigate to the parent of the target property
|
|
35
|
+
for (let i = 0; i < keys.length - 1; i++) {
|
|
36
|
+
const k = keys[i];
|
|
37
|
+
if (!(k in current)) {
|
|
38
|
+
current[k] = {};
|
|
39
|
+
}
|
|
40
|
+
current = current[k];
|
|
41
|
+
}
|
|
42
|
+
// Set the final property
|
|
43
|
+
const lastKey = keys[keys.length - 1];
|
|
44
|
+
current[lastKey] = value;
|
|
45
|
+
return newSettings;
|
|
46
|
+
}
|
|
13
47
|
updateSetting(key, value) {
|
|
14
48
|
return __awaiter(this, void 0, void 0, function* () {
|
|
15
|
-
const newSettings =
|
|
49
|
+
const newSettings = this.setNestedValue(key, value);
|
|
16
50
|
const result = this.schema.safeParse(newSettings);
|
|
17
51
|
if (!result.success) {
|
|
18
52
|
const errors = result.error.issues
|
|
@@ -25,16 +59,27 @@ export class SettingsUIBuilder {
|
|
|
25
59
|
});
|
|
26
60
|
}
|
|
27
61
|
inferSliderBounds(key) {
|
|
28
|
-
var _a, _b;
|
|
62
|
+
var _a, _b, _c, _d, _e;
|
|
29
63
|
try {
|
|
30
|
-
|
|
64
|
+
// Navigate nested schema using dot notation
|
|
65
|
+
const keys = key.split(".");
|
|
66
|
+
let fieldSchema = this.schema.shape;
|
|
67
|
+
for (const k of keys) {
|
|
68
|
+
if (!fieldSchema)
|
|
69
|
+
return {};
|
|
70
|
+
// Unwrap nested schemas
|
|
71
|
+
while ((_a = fieldSchema._def) === null || _a === void 0 ? void 0 : _a.innerType) {
|
|
72
|
+
fieldSchema = fieldSchema._def.innerType;
|
|
73
|
+
}
|
|
74
|
+
fieldSchema = (_c = (_b = fieldSchema.shape) === null || _b === void 0 ? void 0 : _b[k]) !== null && _c !== void 0 ? _c : fieldSchema[k];
|
|
75
|
+
}
|
|
31
76
|
if (!fieldSchema)
|
|
32
77
|
return {};
|
|
33
78
|
let innerSchema = fieldSchema;
|
|
34
|
-
while ((
|
|
79
|
+
while ((_d = innerSchema._def) === null || _d === void 0 ? void 0 : _d.innerType) {
|
|
35
80
|
innerSchema = innerSchema._def.innerType;
|
|
36
81
|
}
|
|
37
|
-
if (((
|
|
82
|
+
if (((_e = innerSchema._def) === null || _e === void 0 ? void 0 : _e.typeName) === "ZodNumber") {
|
|
38
83
|
const checks = innerSchema._def.checks || [];
|
|
39
84
|
let min;
|
|
40
85
|
let max;
|
|
@@ -55,21 +100,32 @@ export class SettingsUIBuilder {
|
|
|
55
100
|
return {};
|
|
56
101
|
}
|
|
57
102
|
inferArrayItemType(key) {
|
|
58
|
-
var _a, _b, _c, _d;
|
|
103
|
+
var _a, _b, _c, _d, _e, _f, _g;
|
|
59
104
|
try {
|
|
60
|
-
|
|
105
|
+
// Navigate nested schema using dot notation
|
|
106
|
+
const keys = key.split(".");
|
|
107
|
+
let fieldSchema = this.schema.shape;
|
|
108
|
+
for (const k of keys) {
|
|
109
|
+
if (!fieldSchema)
|
|
110
|
+
return undefined;
|
|
111
|
+
// Unwrap nested schemas
|
|
112
|
+
while ((_a = fieldSchema._def) === null || _a === void 0 ? void 0 : _a.innerType) {
|
|
113
|
+
fieldSchema = fieldSchema._def.innerType;
|
|
114
|
+
}
|
|
115
|
+
fieldSchema = (_c = (_b = fieldSchema.shape) === null || _b === void 0 ? void 0 : _b[k]) !== null && _c !== void 0 ? _c : fieldSchema[k];
|
|
116
|
+
}
|
|
61
117
|
if (!fieldSchema)
|
|
62
118
|
return undefined;
|
|
63
119
|
let innerSchema = fieldSchema;
|
|
64
|
-
while ((
|
|
120
|
+
while ((_d = innerSchema._def) === null || _d === void 0 ? void 0 : _d.innerType) {
|
|
65
121
|
innerSchema = innerSchema._def.innerType;
|
|
66
122
|
}
|
|
67
|
-
if (((
|
|
123
|
+
if (((_e = innerSchema._def) === null || _e === void 0 ? void 0 : _e.typeName) === "ZodArray") {
|
|
68
124
|
const elementType = innerSchema._def.type;
|
|
69
|
-
if (((
|
|
125
|
+
if (((_f = elementType._def) === null || _f === void 0 ? void 0 : _f.typeName) === "ZodNumber") {
|
|
70
126
|
return "number";
|
|
71
127
|
}
|
|
72
|
-
if (((
|
|
128
|
+
if (((_g = elementType._def) === null || _g === void 0 ? void 0 : _g.typeName) === "ZodString") {
|
|
73
129
|
return "string";
|
|
74
130
|
}
|
|
75
131
|
}
|
|
@@ -81,7 +137,7 @@ export class SettingsUIBuilder {
|
|
|
81
137
|
}
|
|
82
138
|
addToggle(containerEl, config) {
|
|
83
139
|
const { key, name, desc } = config;
|
|
84
|
-
const value = this.
|
|
140
|
+
const value = this.getNestedValue(key);
|
|
85
141
|
new Setting(containerEl)
|
|
86
142
|
.setName(name)
|
|
87
143
|
.setDesc(desc)
|
|
@@ -92,7 +148,7 @@ export class SettingsUIBuilder {
|
|
|
92
148
|
addSlider(containerEl, config) {
|
|
93
149
|
var _a, _b, _c, _d;
|
|
94
150
|
const { key, name, desc, step = 1, commitOnChange = false } = config;
|
|
95
|
-
const value = this.
|
|
151
|
+
const value = this.getNestedValue(key);
|
|
96
152
|
const inferredBounds = this.inferSliderBounds(key);
|
|
97
153
|
const min = (_b = (_a = config.min) !== null && _a !== void 0 ? _a : inferredBounds.min) !== null && _b !== void 0 ? _b : 0;
|
|
98
154
|
const max = (_d = (_c = config.max) !== null && _c !== void 0 ? _c : inferredBounds.max) !== null && _d !== void 0 ? _d : 100;
|
|
@@ -137,7 +193,7 @@ export class SettingsUIBuilder {
|
|
|
137
193
|
}
|
|
138
194
|
addText(containerEl, config) {
|
|
139
195
|
const { key, name, desc, placeholder = "", commitOnChange = false } = config;
|
|
140
|
-
const value = this.
|
|
196
|
+
const value = this.getNestedValue(key);
|
|
141
197
|
new Setting(containerEl)
|
|
142
198
|
.setName(name)
|
|
143
199
|
.setDesc(desc)
|
|
@@ -172,7 +228,7 @@ export class SettingsUIBuilder {
|
|
|
172
228
|
}
|
|
173
229
|
addDropdown(containerEl, config) {
|
|
174
230
|
const { key, name, desc, options } = config;
|
|
175
|
-
const value = this.
|
|
231
|
+
const value = this.getNestedValue(key);
|
|
176
232
|
new Setting(containerEl)
|
|
177
233
|
.setName(name)
|
|
178
234
|
.setDesc(desc)
|
|
@@ -186,7 +242,7 @@ export class SettingsUIBuilder {
|
|
|
186
242
|
addTextArray(containerEl, config) {
|
|
187
243
|
var _a, _b, _c, _d;
|
|
188
244
|
const { key, name, desc, placeholder = "", arrayDelimiter = ", ", multiline = false, commitOnChange = false, } = config;
|
|
189
|
-
const value = this.
|
|
245
|
+
const value = this.getNestedValue(key);
|
|
190
246
|
const inferredItemType = (_b = (_a = config.itemType) !== null && _a !== void 0 ? _a : this.inferArrayItemType(key)) !== null && _b !== void 0 ? _b : "string";
|
|
191
247
|
const parser = (_c = config.parser) !== null && _c !== void 0 ? _c : ((input) => {
|
|
192
248
|
if (inferredItemType === "number") {
|
|
@@ -275,7 +331,6 @@ export class SettingsUIBuilder {
|
|
|
275
331
|
}
|
|
276
332
|
/**
|
|
277
333
|
* Advanced array manager with add/remove buttons for each item
|
|
278
|
-
* Similar to the directory settings pattern
|
|
279
334
|
*/
|
|
280
335
|
addArrayManager(containerEl, config) {
|
|
281
336
|
var _a;
|
|
@@ -292,7 +347,7 @@ export class SettingsUIBuilder {
|
|
|
292
347
|
const render = () => {
|
|
293
348
|
var _a;
|
|
294
349
|
listContainer.empty();
|
|
295
|
-
const currentItems = (_a = this.
|
|
350
|
+
const currentItems = (_a = this.getNestedValue(key)) !== null && _a !== void 0 ? _a : [];
|
|
296
351
|
for (const item of currentItems) {
|
|
297
352
|
const itemSetting = new Setting(listContainer).setName(String(item)).addButton((button) => button
|
|
298
353
|
.setButtonText(removeButtonText)
|
|
@@ -333,12 +388,17 @@ export class SettingsUIBuilder {
|
|
|
333
388
|
.setCta()
|
|
334
389
|
.onClick(() => __awaiter(this, void 0, void 0, function* () {
|
|
335
390
|
var _a;
|
|
336
|
-
|
|
391
|
+
// Use document.getElementById instead of querySelector to avoid CSS selector issues with dots
|
|
392
|
+
const input = document.getElementById(inputId);
|
|
393
|
+
if (!input) {
|
|
394
|
+
console.error(`Input element not found: ${inputId}`);
|
|
395
|
+
return;
|
|
396
|
+
}
|
|
337
397
|
const newItem = input.value.trim();
|
|
338
398
|
if (!newItem) {
|
|
339
399
|
return;
|
|
340
400
|
}
|
|
341
|
-
const currentItems = (_a = this.
|
|
401
|
+
const currentItems = (_a = this.getNestedValue(key)) !== null && _a !== void 0 ? _a : [];
|
|
342
402
|
let newItems = [...currentItems];
|
|
343
403
|
// Apply custom logic before adding
|
|
344
404
|
if (onBeforeAdd) {
|
|
@@ -356,7 +416,7 @@ export class SettingsUIBuilder {
|
|
|
356
416
|
})));
|
|
357
417
|
// Quick actions
|
|
358
418
|
for (const quickAction of quickActions) {
|
|
359
|
-
const currentItems = (_a = this.
|
|
419
|
+
const currentItems = (_a = this.getNestedValue(key)) !== null && _a !== void 0 ? _a : [];
|
|
360
420
|
// Check condition if provided
|
|
361
421
|
if (quickAction.condition && !quickAction.condition(currentItems)) {
|
|
362
422
|
continue;
|
|
@@ -366,7 +426,7 @@ export class SettingsUIBuilder {
|
|
|
366
426
|
.setDesc(quickAction.desc)
|
|
367
427
|
.addButton((button) => button.setButtonText(quickAction.buttonText).onClick(() => __awaiter(this, void 0, void 0, function* () {
|
|
368
428
|
var _a;
|
|
369
|
-
const currentItems = (_a = this.
|
|
429
|
+
const currentItems = (_a = this.getNestedValue(key)) !== null && _a !== void 0 ? _a : [];
|
|
370
430
|
const newItems = yield quickAction.action(currentItems);
|
|
371
431
|
yield this.updateSetting(key, newItems);
|
|
372
432
|
render();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"settings-ui-builder.js","sourceRoot":"","sources":["../../src/settings/settings-ui-builder.ts"],"names":[],"mappings":"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","sourcesContent":["import { Notice, Setting } from \"obsidian\";\nimport type { ZodArray, ZodNumber, ZodObject, ZodRawShape, z } from \"zod\";\nimport type { SettingsStore } from \"./settings-store\";\n\ninterface BaseSettingConfig {\n\tkey: string;\n\tname: string;\n\tdesc: string;\n}\n\ninterface TextSettingConfig extends BaseSettingConfig {\n\tplaceholder?: string;\n\tcommitOnChange?: boolean;\n}\n\ninterface SliderSettingConfig extends BaseSettingConfig {\n\tmin?: number;\n\tmax?: number;\n\tstep?: number;\n\tcommitOnChange?: boolean;\n}\n\ninterface DropdownSettingConfig extends BaseSettingConfig {\n\toptions: Record<string, string>;\n}\n\ninterface ArraySettingConfig<T = string> extends BaseSettingConfig {\n\tplaceholder?: string;\n\tarrayDelimiter?: string;\n\tmultiline?: boolean;\n\tcommitOnChange?: boolean;\n\titemType?: \"string\" | \"number\";\n\tparser?: (input: string) => T;\n\tvalidator?: (item: T) => boolean;\n}\n\ninterface ArrayManagerConfig extends BaseSettingConfig {\n\tplaceholder?: string;\n\taddButtonText?: string;\n\tremoveButtonText?: string;\n\temptyArrayFallback?: unknown;\n\tpreventEmpty?: boolean;\n\titemDescriptionFn?: (item: unknown) => string;\n\tonBeforeAdd?: (newItem: unknown, currentItems: unknown[]) => unknown[] | Promise<unknown[]>;\n\tonBeforeRemove?: (\n\t\titemToRemove: unknown,\n\t\tcurrentItems: unknown[]\n\t) => unknown[] | Promise<unknown[]>;\n\tquickActions?: Array<{\n\t\tname: string;\n\t\tdesc: string;\n\t\tbuttonText: string;\n\t\tcondition?: (currentItems: unknown[]) => boolean;\n\t\taction: (currentItems: unknown[]) => unknown[] | Promise<unknown[]>;\n\t}>;\n}\n\nexport class SettingsUIBuilder<TSchema extends ZodObject<ZodRawShape>> {\n\tconstructor(private settingsStore: SettingsStore<TSchema>) {}\n\n\tprivate get settings(): z.infer<TSchema> {\n\t\treturn this.settingsStore.currentSettings;\n\t}\n\n\tprivate get schema(): TSchema {\n\t\treturn this.settingsStore.validationSchema;\n\t}\n\n\tprivate async updateSetting(key: keyof z.infer<TSchema>, value: unknown): Promise<void> {\n\t\tconst newSettings = {\n\t\t\t...this.settings,\n\t\t\t[key]: value,\n\t\t} as z.infer<TSchema>;\n\n\t\tconst result = this.schema.safeParse(newSettings);\n\n\t\tif (!result.success) {\n\t\t\tconst errors = result.error.issues\n\t\t\t\t.map((e) => `${String(e.path.join(\".\"))}${e.path.length > 0 ? \": \" : \"\"}${e.message}`)\n\t\t\t\t.join(\", \");\n\t\t\tnew Notice(`Validation failed: ${errors}`, 5000);\n\t\t\tthrow new Error(`Validation failed: ${errors}`);\n\t\t}\n\n\t\tawait this.settingsStore.updateSettings(() => newSettings);\n\t}\n\n\tprivate inferSliderBounds(key: string): { min?: number; max?: number; step?: number } {\n\t\ttry {\n\t\t\tconst fieldSchema = (this.schema.shape as any)[key];\n\t\t\tif (!fieldSchema) return {};\n\n\t\t\tlet innerSchema = fieldSchema;\n\t\t\twhile ((innerSchema as any)._def?.innerType) {\n\t\t\t\tinnerSchema = (innerSchema as any)._def.innerType;\n\t\t\t}\n\n\t\t\tif ((innerSchema as any)._def?.typeName === \"ZodNumber\") {\n\t\t\t\tconst checks = ((innerSchema as ZodNumber)._def as any).checks || [];\n\t\t\t\tlet min: number | undefined;\n\t\t\t\tlet max: number | undefined;\n\n\t\t\t\tfor (const check of checks) {\n\t\t\t\t\tif ((check as any).kind === \"min\") {\n\t\t\t\t\t\tmin = (check as any).value;\n\t\t\t\t\t}\n\t\t\t\t\tif ((check as any).kind === \"max\") {\n\t\t\t\t\t\tmax = (check as any).value;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\treturn { min, max };\n\t\t\t}\n\t\t} catch (error) {\n\t\t\tconsole.warn(`Failed to infer slider bounds for key ${key}:`, error);\n\t\t}\n\n\t\treturn {};\n\t}\n\n\tprivate inferArrayItemType(key: string): \"string\" | \"number\" | undefined {\n\t\ttry {\n\t\t\tconst fieldSchema = (this.schema.shape as any)[key];\n\t\t\tif (!fieldSchema) return undefined;\n\n\t\t\tlet innerSchema = fieldSchema;\n\t\t\twhile ((innerSchema as any)._def?.innerType) {\n\t\t\t\tinnerSchema = (innerSchema as any)._def.innerType;\n\t\t\t}\n\n\t\t\tif ((innerSchema as any)._def?.typeName === \"ZodArray\") {\n\t\t\t\tconst elementType = ((innerSchema as ZodArray<any>)._def as any).type;\n\t\t\t\tif ((elementType as any)._def?.typeName === \"ZodNumber\") {\n\t\t\t\t\treturn \"number\";\n\t\t\t\t}\n\t\t\t\tif ((elementType as any)._def?.typeName === \"ZodString\") {\n\t\t\t\t\treturn \"string\";\n\t\t\t\t}\n\t\t\t}\n\t\t} catch (error) {\n\t\t\tconsole.warn(`Failed to infer array item type for key ${key}:`, error);\n\t\t}\n\n\t\treturn undefined;\n\t}\n\n\taddToggle(containerEl: HTMLElement, config: BaseSettingConfig): void {\n\t\tconst { key, name, desc } = config;\n\t\tconst value = this.settings[key as keyof z.infer<TSchema>];\n\n\t\tnew Setting(containerEl)\n\t\t\t.setName(name)\n\t\t\t.setDesc(desc)\n\t\t\t.addToggle((toggle) =>\n\t\t\t\ttoggle.setValue(Boolean(value)).onChange(async (newValue) => {\n\t\t\t\t\tawait this.updateSetting(key as keyof z.infer<TSchema>, newValue);\n\t\t\t\t})\n\t\t\t);\n\t}\n\n\taddSlider(containerEl: HTMLElement, config: SliderSettingConfig): void {\n\t\tconst { key, name, desc, step = 1, commitOnChange = false } = config;\n\t\tconst value = this.settings[key as keyof z.infer<TSchema>];\n\n\t\tconst inferredBounds = this.inferSliderBounds(key);\n\t\tconst min = config.min ?? inferredBounds.min ?? 0;\n\t\tconst max = config.max ?? inferredBounds.max ?? 100;\n\n\t\tnew Setting(containerEl)\n\t\t\t.setName(name)\n\t\t\t.setDesc(desc)\n\t\t\t.addSlider((slider) => {\n\t\t\t\tslider.setLimits(min, max, step).setValue(Number(value)).setDynamicTooltip();\n\n\t\t\t\tif (commitOnChange) {\n\t\t\t\t\t// Reactive: commit on every change\n\t\t\t\t\tslider.onChange(async (newValue) => {\n\t\t\t\t\t\tawait this.updateSetting(key as keyof z.infer<TSchema>, newValue);\n\t\t\t\t\t});\n\t\t\t\t} else {\n\t\t\t\t\t// Commit only when user finishes dragging\n\t\t\t\t\tconst commit = async (newValue: number) => {\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\tawait this.updateSetting(key as keyof z.infer<TSchema>, newValue);\n\t\t\t\t\t\t} catch (error) {\n\t\t\t\t\t\t\tnew Notice(`Invalid input: ${error}`, 5000);\n\t\t\t\t\t\t}\n\t\t\t\t\t};\n\n\t\t\t\t\t// Update tooltip during drag for visual feedback\n\t\t\t\t\tslider.onChange((newValue) => {\n\t\t\t\t\t\tslider.sliderEl.setAttribute(\"aria-valuenow\", String(newValue));\n\t\t\t\t\t});\n\n\t\t\t\t\t// Commit on mouse up\n\t\t\t\t\tslider.sliderEl.addEventListener(\"mouseup\", () => {\n\t\t\t\t\t\tvoid commit(Number(slider.sliderEl.value));\n\t\t\t\t\t});\n\n\t\t\t\t\t// Commit on keyboard navigation\n\t\t\t\t\tslider.sliderEl.addEventListener(\"keyup\", (e: KeyboardEvent) => {\n\t\t\t\t\t\tif (\n\t\t\t\t\t\t\t[\"ArrowLeft\", \"ArrowRight\", \"ArrowUp\", \"ArrowDown\", \"Home\", \"End\"].includes(e.key)\n\t\t\t\t\t\t) {\n\t\t\t\t\t\t\tvoid commit(Number(slider.sliderEl.value));\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t\t}\n\n\t\t\t\treturn slider;\n\t\t\t});\n\t}\n\n\taddText(containerEl: HTMLElement, config: TextSettingConfig): void {\n\t\tconst { key, name, desc, placeholder = \"\", commitOnChange = false } = config;\n\t\tconst value = this.settings[key as keyof z.infer<TSchema>];\n\n\t\tnew Setting(containerEl)\n\t\t\t.setName(name)\n\t\t\t.setDesc(desc)\n\t\t\t.addText((text) => {\n\t\t\t\ttext.setPlaceholder(placeholder);\n\t\t\t\ttext.setValue(String(value ?? \"\"));\n\n\t\t\t\tif (commitOnChange) {\n\t\t\t\t\t// Reactive: commit on every change\n\t\t\t\t\ttext.onChange(async (newValue) => {\n\t\t\t\t\t\tawait this.updateSetting(key as keyof z.infer<TSchema>, newValue);\n\t\t\t\t\t});\n\t\t\t\t} else {\n\t\t\t\t\t// Commit only on blur or Ctrl/Cmd+Enter\n\t\t\t\t\tconst commit = async (inputValue: string) => {\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\tawait this.updateSetting(key as keyof z.infer<TSchema>, inputValue);\n\t\t\t\t\t\t} catch (error) {\n\t\t\t\t\t\t\tnew Notice(`Invalid input: ${error}`, 5000);\n\t\t\t\t\t\t}\n\t\t\t\t\t};\n\n\t\t\t\t\ttext.inputEl.addEventListener(\"blur\", () => void commit(text.inputEl.value));\n\t\t\t\t\ttext.inputEl.addEventListener(\"keydown\", (e: KeyboardEvent) => {\n\t\t\t\t\t\tif (e.key === \"Enter\" && (e.ctrlKey || e.metaKey)) {\n\t\t\t\t\t\t\te.preventDefault();\n\t\t\t\t\t\t\tvoid commit(text.inputEl.value);\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t});\n\t}\n\n\taddDropdown(containerEl: HTMLElement, config: DropdownSettingConfig): void {\n\t\tconst { key, name, desc, options } = config;\n\t\tconst value = this.settings[key as keyof z.infer<TSchema>];\n\n\t\tnew Setting(containerEl)\n\t\t\t.setName(name)\n\t\t\t.setDesc(desc)\n\t\t\t.addDropdown((dropdown) =>\n\t\t\t\tdropdown\n\t\t\t\t\t.addOptions(options)\n\t\t\t\t\t.setValue(String(value))\n\t\t\t\t\t.onChange(async (newValue) => {\n\t\t\t\t\t\tawait this.updateSetting(key as keyof z.infer<TSchema>, newValue);\n\t\t\t\t\t})\n\t\t\t);\n\t}\n\n\taddTextArray<T = string>(containerEl: HTMLElement, config: ArraySettingConfig<T>): void {\n\t\tconst {\n\t\t\tkey,\n\t\t\tname,\n\t\t\tdesc,\n\t\t\tplaceholder = \"\",\n\t\t\tarrayDelimiter = \", \",\n\t\t\tmultiline = false,\n\t\t\tcommitOnChange = false,\n\t\t} = config;\n\t\tconst value = this.settings[key as keyof z.infer<TSchema>] as T[];\n\n\t\tconst inferredItemType = config.itemType ?? this.inferArrayItemType(key) ?? \"string\";\n\t\tconst parser =\n\t\t\tconfig.parser ??\n\t\t\t((input: string) => {\n\t\t\t\tif (inferredItemType === \"number\") {\n\t\t\t\t\tconst num = Number(input);\n\t\t\t\t\tif (Number.isNaN(num)) {\n\t\t\t\t\t\tthrow new Error(`Invalid number: ${input}`);\n\t\t\t\t\t}\n\t\t\t\t\treturn num as T;\n\t\t\t\t}\n\t\t\t\treturn input as T;\n\t\t\t});\n\n\t\tconst validator = config.validator ?? ((_item: T) => true);\n\n\t\tconst setting = new Setting(containerEl).setName(name).setDesc(desc);\n\n\t\tif (multiline) {\n\t\t\tsetting.addTextArea((text) => {\n\t\t\t\ttext.setPlaceholder(placeholder);\n\t\t\t\ttext.setValue(Array.isArray(value) ? value.join(\"\\n\") : \"\");\n\n\t\t\t\tconst commit = async (inputValue: string) => {\n\t\t\t\t\tconst lines = inputValue\n\t\t\t\t\t\t.split(\"\\n\")\n\t\t\t\t\t\t.map((s) => s.trim())\n\t\t\t\t\t\t.filter((s) => s.length > 0);\n\n\t\t\t\t\ttry {\n\t\t\t\t\t\tconst items = lines.map(parser).filter(validator);\n\t\t\t\t\t\tawait this.updateSetting(key as keyof z.infer<TSchema>, items);\n\t\t\t\t\t} catch (error) {\n\t\t\t\t\t\tnew Notice(`Invalid input: ${error}`, 5000);\n\t\t\t\t\t}\n\t\t\t\t};\n\n\t\t\t\tif (commitOnChange) {\n\t\t\t\t\t// Reactive: commit on every change\n\t\t\t\t\ttext.onChange(async (inputValue) => {\n\t\t\t\t\t\tawait commit(inputValue);\n\t\t\t\t\t});\n\t\t\t\t} else {\n\t\t\t\t\t// Commit only on blur or Ctrl/Cmd+Enter\n\t\t\t\t\ttext.inputEl.addEventListener(\"blur\", () => void commit(text.inputEl.value));\n\t\t\t\t\ttext.inputEl.addEventListener(\"keydown\", (e: KeyboardEvent) => {\n\t\t\t\t\t\tif (e.key === \"Enter\" && (e.ctrlKey || e.metaKey)) {\n\t\t\t\t\t\t\te.preventDefault();\n\t\t\t\t\t\t\tvoid commit(text.inputEl.value);\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t\t}\n\n\t\t\t\ttext.inputEl.rows = 5;\n\t\t\t\ttext.inputEl.classList.add(\"settings-ui-builder-textarea\");\n\t\t\t});\n\t\t} else {\n\t\t\tsetting.addText((text) => {\n\t\t\t\ttext.setPlaceholder(placeholder);\n\t\t\t\ttext.setValue(Array.isArray(value) ? value.join(arrayDelimiter) : \"\");\n\n\t\t\t\tconst commit = async (inputValue: string) => {\n\t\t\t\t\tconst tokens = inputValue\n\t\t\t\t\t\t.split(\",\")\n\t\t\t\t\t\t.map((s) => s.trim())\n\t\t\t\t\t\t.filter((s) => s.length > 0);\n\n\t\t\t\t\ttry {\n\t\t\t\t\t\tconst items = tokens.map(parser).filter(validator);\n\t\t\t\t\t\tawait this.updateSetting(key as keyof z.infer<TSchema>, items);\n\t\t\t\t\t} catch (error) {\n\t\t\t\t\t\tnew Notice(`Invalid input: ${error}`, 5000);\n\t\t\t\t\t}\n\t\t\t\t};\n\n\t\t\t\tif (commitOnChange) {\n\t\t\t\t\t// Reactive: commit on every change\n\t\t\t\t\ttext.onChange(async (inputValue) => {\n\t\t\t\t\t\tawait commit(inputValue);\n\t\t\t\t\t});\n\t\t\t\t} else {\n\t\t\t\t\t// Commit only on blur or Ctrl/Cmd+Enter\n\t\t\t\t\ttext.inputEl.addEventListener(\"blur\", () => void commit(text.inputEl.value));\n\t\t\t\t\ttext.inputEl.addEventListener(\"keydown\", (e: KeyboardEvent) => {\n\t\t\t\t\t\tif (e.key === \"Enter\" && (e.ctrlKey || e.metaKey)) {\n\t\t\t\t\t\t\te.preventDefault();\n\t\t\t\t\t\t\tvoid commit(text.inputEl.value);\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\t}\n\n\t/**\n\t * Advanced array manager with add/remove buttons for each item\n\t * Similar to the directory settings pattern\n\t */\n\taddArrayManager(containerEl: HTMLElement, config: ArrayManagerConfig): void {\n\t\tconst {\n\t\t\tkey,\n\t\t\tname,\n\t\t\tdesc,\n\t\t\tplaceholder = \"\",\n\t\t\taddButtonText = \"Add\",\n\t\t\tremoveButtonText = \"Remove\",\n\t\t\temptyArrayFallback = [],\n\t\t\tpreventEmpty = false,\n\t\t\titemDescriptionFn,\n\t\t\tonBeforeAdd,\n\t\t\tonBeforeRemove,\n\t\t\tquickActions = [],\n\t\t} = config;\n\n\t\t// Section heading\n\t\tnew Setting(containerEl).setName(name).setHeading();\n\n\t\t// Description\n\t\tif (desc) {\n\t\t\tconst descEl = containerEl.createDiv(\"setting-item-description\");\n\t\t\tdescEl.setText(desc);\n\t\t}\n\n\t\t// Container for list items\n\t\tconst listContainer = containerEl.createDiv(\"settings-array-manager-list\");\n\n\t\tconst render = () => {\n\t\t\tlistContainer.empty();\n\n\t\t\tconst currentItems = (this.settings[key as keyof z.infer<TSchema>] as unknown[]) ?? [];\n\n\t\t\tfor (const item of currentItems) {\n\t\t\t\tconst itemSetting = new Setting(listContainer).setName(String(item)).addButton((button) =>\n\t\t\t\t\tbutton\n\t\t\t\t\t\t.setButtonText(removeButtonText)\n\t\t\t\t\t\t.setWarning()\n\t\t\t\t\t\t.onClick(async () => {\n\t\t\t\t\t\t\tlet newItems = currentItems.filter((i) => i !== item);\n\n\t\t\t\t\t\t\t// Apply custom logic before removal\n\t\t\t\t\t\t\tif (onBeforeRemove) {\n\t\t\t\t\t\t\t\tnewItems = await onBeforeRemove(item, currentItems);\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t// Prevent empty array if configured\n\t\t\t\t\t\t\tif (preventEmpty && newItems.length === 0) {\n\t\t\t\t\t\t\t\tnewItems = Array.isArray(emptyArrayFallback)\n\t\t\t\t\t\t\t\t\t? emptyArrayFallback\n\t\t\t\t\t\t\t\t\t: [emptyArrayFallback];\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tawait this.updateSetting(key as keyof z.infer<TSchema>, newItems);\n\t\t\t\t\t\t\trender();\n\t\t\t\t\t\t})\n\t\t\t\t);\n\n\t\t\t\t// Add custom description for each item if provided\n\t\t\t\tif (itemDescriptionFn) {\n\t\t\t\t\titemSetting.setDesc(itemDescriptionFn(item));\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\n\t\trender();\n\n\t\t// Add new item section\n\t\tconst inputId = `settings-array-manager-input-${key}`;\n\t\tnew Setting(containerEl)\n\t\t\t.setName(`Add ${name.toLowerCase()}`)\n\t\t\t.setDesc(`Enter a new value`)\n\t\t\t.addText((text) => {\n\t\t\t\ttext.setPlaceholder(placeholder);\n\t\t\t\ttext.inputEl.id = inputId;\n\t\t\t})\n\t\t\t.addButton((button) =>\n\t\t\t\tbutton\n\t\t\t\t\t.setButtonText(addButtonText)\n\t\t\t\t\t.setCta()\n\t\t\t\t\t.onClick(async () => {\n\t\t\t\t\t\tconst input = containerEl.querySelector(`#${inputId}`) as HTMLInputElement;\n\t\t\t\t\t\tconst newItem = input.value.trim();\n\n\t\t\t\t\t\tif (!newItem) {\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tconst currentItems = (this.settings[key as keyof z.infer<TSchema>] as unknown[]) ?? [];\n\t\t\t\t\t\tlet newItems = [...currentItems];\n\n\t\t\t\t\t\t// Apply custom logic before adding\n\t\t\t\t\t\tif (onBeforeAdd) {\n\t\t\t\t\t\t\tnewItems = await onBeforeAdd(newItem, currentItems);\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t// Default behavior: add if not exists\n\t\t\t\t\t\t\tif (!newItems.includes(newItem)) {\n\t\t\t\t\t\t\t\tnewItems.push(newItem);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tawait this.updateSetting(key as keyof z.infer<TSchema>, newItems);\n\t\t\t\t\t\tinput.value = \"\";\n\t\t\t\t\t\trender();\n\t\t\t\t\t})\n\t\t\t);\n\n\t\t// Quick actions\n\t\tfor (const quickAction of quickActions) {\n\t\t\tconst currentItems = (this.settings[key as keyof z.infer<TSchema>] as unknown[]) ?? [];\n\n\t\t\t// Check condition if provided\n\t\t\tif (quickAction.condition && !quickAction.condition(currentItems)) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tnew Setting(containerEl)\n\t\t\t\t.setName(quickAction.name)\n\t\t\t\t.setDesc(quickAction.desc)\n\t\t\t\t.addButton((button) =>\n\t\t\t\t\tbutton.setButtonText(quickAction.buttonText).onClick(async () => {\n\t\t\t\t\t\tconst currentItems = (this.settings[key as keyof z.infer<TSchema>] as unknown[]) ?? [];\n\t\t\t\t\t\tconst newItems = await quickAction.action(currentItems);\n\t\t\t\t\t\tawait this.updateSetting(key as keyof z.infer<TSchema>, newItems);\n\t\t\t\t\t\trender();\n\t\t\t\t\t})\n\t\t\t\t);\n\t\t}\n\t}\n}\n"]}
|
|
1
|
+
{"version":3,"file":"settings-ui-builder.js","sourceRoot":"","sources":["../../src/settings/settings-ui-builder.ts"],"names":[],"mappings":"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","sourcesContent":["import { Notice, Setting } from \"obsidian\";\nimport type { ZodArray, ZodNumber, ZodObject, ZodRawShape, z } from \"zod\";\nimport type { SettingsStore } from \"./settings-store\";\n\ninterface BaseSettingConfig {\n\tkey: string;\n\tname: string;\n\tdesc: string;\n}\n\ninterface TextSettingConfig extends BaseSettingConfig {\n\tplaceholder?: string;\n\tcommitOnChange?: boolean;\n}\n\ninterface SliderSettingConfig extends BaseSettingConfig {\n\tmin?: number;\n\tmax?: number;\n\tstep?: number;\n\tcommitOnChange?: boolean;\n}\n\ninterface DropdownSettingConfig extends BaseSettingConfig {\n\toptions: Record<string, string>;\n}\n\ninterface ArraySettingConfig<T = string> extends BaseSettingConfig {\n\tplaceholder?: string;\n\tarrayDelimiter?: string;\n\tmultiline?: boolean;\n\tcommitOnChange?: boolean;\n\titemType?: \"string\" | \"number\";\n\tparser?: (input: string) => T;\n\tvalidator?: (item: T) => boolean;\n}\n\ninterface ArrayManagerConfig extends BaseSettingConfig {\n\tplaceholder?: string;\n\taddButtonText?: string;\n\tremoveButtonText?: string;\n\temptyArrayFallback?: unknown;\n\tpreventEmpty?: boolean;\n\titemDescriptionFn?: (item: unknown) => string;\n\tonBeforeAdd?: (newItem: unknown, currentItems: unknown[]) => unknown[] | Promise<unknown[]>;\n\tonBeforeRemove?: (\n\t\titemToRemove: unknown,\n\t\tcurrentItems: unknown[]\n\t) => unknown[] | Promise<unknown[]>;\n\tquickActions?: Array<{\n\t\tname: string;\n\t\tdesc: string;\n\t\tbuttonText: string;\n\t\tcondition?: (currentItems: unknown[]) => boolean;\n\t\taction: (currentItems: unknown[]) => unknown[] | Promise<unknown[]>;\n\t}>;\n}\n\nexport class SettingsUIBuilder<TSchema extends ZodObject<ZodRawShape>> {\n\tconstructor(private settingsStore: SettingsStore<TSchema>) {}\n\n\tprivate get settings(): z.infer<TSchema> {\n\t\treturn this.settingsStore.currentSettings;\n\t}\n\n\tprivate get schema(): TSchema {\n\t\treturn this.settingsStore.validationSchema;\n\t}\n\n\t/**\n\t * Gets a nested property value using dot notation (e.g., \"basesView.tasksDirectory\")\n\t */\n\tprivate getNestedValue(key: string): unknown {\n\t\tconst keys = key.split(\".\");\n\t\tlet value: any = this.settings;\n\n\t\tfor (const k of keys) {\n\t\t\tif (value === undefined || value === null) {\n\t\t\t\treturn undefined;\n\t\t\t}\n\t\t\tvalue = value[k];\n\t\t}\n\n\t\treturn value;\n\t}\n\n\t/**\n\t * Sets a nested property value using dot notation and returns updated settings\n\t */\n\tprivate setNestedValue(key: string, value: unknown): z.infer<TSchema> {\n\t\tconst keys = key.split(\".\");\n\t\tconst newSettings = JSON.parse(JSON.stringify(this.settings)); // Deep clone\n\n\t\tlet current: any = newSettings;\n\n\t\t// Navigate to the parent of the target property\n\t\tfor (let i = 0; i < keys.length - 1; i++) {\n\t\t\tconst k = keys[i];\n\t\t\tif (!(k in current)) {\n\t\t\t\tcurrent[k] = {};\n\t\t\t}\n\t\t\tcurrent = current[k];\n\t\t}\n\n\t\t// Set the final property\n\t\tconst lastKey = keys[keys.length - 1];\n\t\tcurrent[lastKey] = value;\n\n\t\treturn newSettings;\n\t}\n\n\tprivate async updateSetting(key: string, value: unknown): Promise<void> {\n\t\tconst newSettings = this.setNestedValue(key, value);\n\n\t\tconst result = this.schema.safeParse(newSettings);\n\n\t\tif (!result.success) {\n\t\t\tconst errors = result.error.issues\n\t\t\t\t.map((e) => `${String(e.path.join(\".\"))}${e.path.length > 0 ? \": \" : \"\"}${e.message}`)\n\t\t\t\t.join(\", \");\n\t\t\tnew Notice(`Validation failed: ${errors}`, 5000);\n\t\t\tthrow new Error(`Validation failed: ${errors}`);\n\t\t}\n\n\t\tawait this.settingsStore.updateSettings(() => newSettings);\n\t}\n\n\tprivate inferSliderBounds(key: string): { min?: number; max?: number; step?: number } {\n\t\ttry {\n\t\t\t// Navigate nested schema using dot notation\n\t\t\tconst keys = key.split(\".\");\n\t\t\tlet fieldSchema: any = this.schema.shape;\n\n\t\t\tfor (const k of keys) {\n\t\t\t\tif (!fieldSchema) return {};\n\n\t\t\t\t// Unwrap nested schemas\n\t\t\t\twhile ((fieldSchema as any)._def?.innerType) {\n\t\t\t\t\tfieldSchema = (fieldSchema as any)._def.innerType;\n\t\t\t\t}\n\n\t\t\t\tfieldSchema = (fieldSchema as any).shape?.[k] ?? (fieldSchema as any)[k];\n\t\t\t}\n\n\t\t\tif (!fieldSchema) return {};\n\n\t\t\tlet innerSchema = fieldSchema;\n\t\t\twhile ((innerSchema as any)._def?.innerType) {\n\t\t\t\tinnerSchema = (innerSchema as any)._def.innerType;\n\t\t\t}\n\n\t\t\tif ((innerSchema as any)._def?.typeName === \"ZodNumber\") {\n\t\t\t\tconst checks = ((innerSchema as ZodNumber)._def as any).checks || [];\n\t\t\t\tlet min: number | undefined;\n\t\t\t\tlet max: number | undefined;\n\n\t\t\t\tfor (const check of checks) {\n\t\t\t\t\tif ((check as any).kind === \"min\") {\n\t\t\t\t\t\tmin = (check as any).value;\n\t\t\t\t\t}\n\t\t\t\t\tif ((check as any).kind === \"max\") {\n\t\t\t\t\t\tmax = (check as any).value;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\treturn { min, max };\n\t\t\t}\n\t\t} catch (error) {\n\t\t\tconsole.warn(`Failed to infer slider bounds for key ${key}:`, error);\n\t\t}\n\n\t\treturn {};\n\t}\n\n\tprivate inferArrayItemType(key: string): \"string\" | \"number\" | undefined {\n\t\ttry {\n\t\t\t// Navigate nested schema using dot notation\n\t\t\tconst keys = key.split(\".\");\n\t\t\tlet fieldSchema: any = this.schema.shape;\n\n\t\t\tfor (const k of keys) {\n\t\t\t\tif (!fieldSchema) return undefined;\n\n\t\t\t\t// Unwrap nested schemas\n\t\t\t\twhile ((fieldSchema as any)._def?.innerType) {\n\t\t\t\t\tfieldSchema = (fieldSchema as any)._def.innerType;\n\t\t\t\t}\n\n\t\t\t\tfieldSchema = (fieldSchema as any).shape?.[k] ?? (fieldSchema as any)[k];\n\t\t\t}\n\n\t\t\tif (!fieldSchema) return undefined;\n\n\t\t\tlet innerSchema = fieldSchema;\n\t\t\twhile ((innerSchema as any)._def?.innerType) {\n\t\t\t\tinnerSchema = (innerSchema as any)._def.innerType;\n\t\t\t}\n\n\t\t\tif ((innerSchema as any)._def?.typeName === \"ZodArray\") {\n\t\t\t\tconst elementType = ((innerSchema as ZodArray<any>)._def as any).type;\n\t\t\t\tif ((elementType as any)._def?.typeName === \"ZodNumber\") {\n\t\t\t\t\treturn \"number\";\n\t\t\t\t}\n\t\t\t\tif ((elementType as any)._def?.typeName === \"ZodString\") {\n\t\t\t\t\treturn \"string\";\n\t\t\t\t}\n\t\t\t}\n\t\t} catch (error) {\n\t\t\tconsole.warn(`Failed to infer array item type for key ${key}:`, error);\n\t\t}\n\n\t\treturn undefined;\n\t}\n\n\taddToggle(containerEl: HTMLElement, config: BaseSettingConfig): void {\n\t\tconst { key, name, desc } = config;\n\t\tconst value = this.getNestedValue(key);\n\n\t\tnew Setting(containerEl)\n\t\t\t.setName(name)\n\t\t\t.setDesc(desc)\n\t\t\t.addToggle((toggle) =>\n\t\t\t\ttoggle.setValue(Boolean(value)).onChange(async (newValue) => {\n\t\t\t\t\tawait this.updateSetting(key, newValue);\n\t\t\t\t})\n\t\t\t);\n\t}\n\n\taddSlider(containerEl: HTMLElement, config: SliderSettingConfig): void {\n\t\tconst { key, name, desc, step = 1, commitOnChange = false } = config;\n\t\tconst value = this.getNestedValue(key);\n\n\t\tconst inferredBounds = this.inferSliderBounds(key);\n\t\tconst min = config.min ?? inferredBounds.min ?? 0;\n\t\tconst max = config.max ?? inferredBounds.max ?? 100;\n\n\t\tnew Setting(containerEl)\n\t\t\t.setName(name)\n\t\t\t.setDesc(desc)\n\t\t\t.addSlider((slider) => {\n\t\t\t\tslider.setLimits(min, max, step).setValue(Number(value)).setDynamicTooltip();\n\n\t\t\t\tif (commitOnChange) {\n\t\t\t\t\t// Reactive: commit on every change\n\t\t\t\t\tslider.onChange(async (newValue) => {\n\t\t\t\t\t\tawait this.updateSetting(key, newValue);\n\t\t\t\t\t});\n\t\t\t\t} else {\n\t\t\t\t\t// Commit only when user finishes dragging\n\t\t\t\t\tconst commit = async (newValue: number) => {\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\tawait this.updateSetting(key, newValue);\n\t\t\t\t\t\t} catch (error) {\n\t\t\t\t\t\t\tnew Notice(`Invalid input: ${error}`, 5000);\n\t\t\t\t\t\t}\n\t\t\t\t\t};\n\n\t\t\t\t\t// Update tooltip during drag for visual feedback\n\t\t\t\t\tslider.onChange((newValue) => {\n\t\t\t\t\t\tslider.sliderEl.setAttribute(\"aria-valuenow\", String(newValue));\n\t\t\t\t\t});\n\n\t\t\t\t\t// Commit on mouse up\n\t\t\t\t\tslider.sliderEl.addEventListener(\"mouseup\", () => {\n\t\t\t\t\t\tvoid commit(Number(slider.sliderEl.value));\n\t\t\t\t\t});\n\n\t\t\t\t\t// Commit on keyboard navigation\n\t\t\t\t\tslider.sliderEl.addEventListener(\"keyup\", (e: KeyboardEvent) => {\n\t\t\t\t\t\tif (\n\t\t\t\t\t\t\t[\"ArrowLeft\", \"ArrowRight\", \"ArrowUp\", \"ArrowDown\", \"Home\", \"End\"].includes(e.key)\n\t\t\t\t\t\t) {\n\t\t\t\t\t\t\tvoid commit(Number(slider.sliderEl.value));\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t\t}\n\n\t\t\t\treturn slider;\n\t\t\t});\n\t}\n\n\taddText(containerEl: HTMLElement, config: TextSettingConfig): void {\n\t\tconst { key, name, desc, placeholder = \"\", commitOnChange = false } = config;\n\t\tconst value = this.getNestedValue(key);\n\n\t\tnew Setting(containerEl)\n\t\t\t.setName(name)\n\t\t\t.setDesc(desc)\n\t\t\t.addText((text) => {\n\t\t\t\ttext.setPlaceholder(placeholder);\n\t\t\t\ttext.setValue(String(value ?? \"\"));\n\n\t\t\t\tif (commitOnChange) {\n\t\t\t\t\t// Reactive: commit on every change\n\t\t\t\t\ttext.onChange(async (newValue) => {\n\t\t\t\t\t\tawait this.updateSetting(key, newValue);\n\t\t\t\t\t});\n\t\t\t\t} else {\n\t\t\t\t\t// Commit only on blur or Ctrl/Cmd+Enter\n\t\t\t\t\tconst commit = async (inputValue: string) => {\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\tawait this.updateSetting(key, inputValue);\n\t\t\t\t\t\t} catch (error) {\n\t\t\t\t\t\t\tnew Notice(`Invalid input: ${error}`, 5000);\n\t\t\t\t\t\t}\n\t\t\t\t\t};\n\n\t\t\t\t\ttext.inputEl.addEventListener(\"blur\", () => void commit(text.inputEl.value));\n\t\t\t\t\ttext.inputEl.addEventListener(\"keydown\", (e: KeyboardEvent) => {\n\t\t\t\t\t\tif (e.key === \"Enter\" && (e.ctrlKey || e.metaKey)) {\n\t\t\t\t\t\t\te.preventDefault();\n\t\t\t\t\t\t\tvoid commit(text.inputEl.value);\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t});\n\t}\n\n\taddDropdown(containerEl: HTMLElement, config: DropdownSettingConfig): void {\n\t\tconst { key, name, desc, options } = config;\n\t\tconst value = this.getNestedValue(key);\n\n\t\tnew Setting(containerEl)\n\t\t\t.setName(name)\n\t\t\t.setDesc(desc)\n\t\t\t.addDropdown((dropdown) =>\n\t\t\t\tdropdown\n\t\t\t\t\t.addOptions(options)\n\t\t\t\t\t.setValue(String(value))\n\t\t\t\t\t.onChange(async (newValue) => {\n\t\t\t\t\t\tawait this.updateSetting(key, newValue);\n\t\t\t\t\t})\n\t\t\t);\n\t}\n\n\taddTextArray<T = string>(containerEl: HTMLElement, config: ArraySettingConfig<T>): void {\n\t\tconst {\n\t\t\tkey,\n\t\t\tname,\n\t\t\tdesc,\n\t\t\tplaceholder = \"\",\n\t\t\tarrayDelimiter = \", \",\n\t\t\tmultiline = false,\n\t\t\tcommitOnChange = false,\n\t\t} = config;\n\t\tconst value = this.getNestedValue(key) as T[];\n\n\t\tconst inferredItemType = config.itemType ?? this.inferArrayItemType(key) ?? \"string\";\n\t\tconst parser =\n\t\t\tconfig.parser ??\n\t\t\t((input: string) => {\n\t\t\t\tif (inferredItemType === \"number\") {\n\t\t\t\t\tconst num = Number(input);\n\t\t\t\t\tif (Number.isNaN(num)) {\n\t\t\t\t\t\tthrow new Error(`Invalid number: ${input}`);\n\t\t\t\t\t}\n\t\t\t\t\treturn num as T;\n\t\t\t\t}\n\t\t\t\treturn input as T;\n\t\t\t});\n\n\t\tconst validator = config.validator ?? ((_item: T) => true);\n\n\t\tconst setting = new Setting(containerEl).setName(name).setDesc(desc);\n\n\t\tif (multiline) {\n\t\t\tsetting.addTextArea((text) => {\n\t\t\t\ttext.setPlaceholder(placeholder);\n\t\t\t\ttext.setValue(Array.isArray(value) ? value.join(\"\\n\") : \"\");\n\n\t\t\t\tconst commit = async (inputValue: string) => {\n\t\t\t\t\tconst lines = inputValue\n\t\t\t\t\t\t.split(\"\\n\")\n\t\t\t\t\t\t.map((s) => s.trim())\n\t\t\t\t\t\t.filter((s) => s.length > 0);\n\n\t\t\t\t\ttry {\n\t\t\t\t\t\tconst items = lines.map(parser).filter(validator);\n\t\t\t\t\t\tawait this.updateSetting(key, items);\n\t\t\t\t\t} catch (error) {\n\t\t\t\t\t\tnew Notice(`Invalid input: ${error}`, 5000);\n\t\t\t\t\t}\n\t\t\t\t};\n\n\t\t\t\tif (commitOnChange) {\n\t\t\t\t\t// Reactive: commit on every change\n\t\t\t\t\ttext.onChange(async (inputValue) => {\n\t\t\t\t\t\tawait commit(inputValue);\n\t\t\t\t\t});\n\t\t\t\t} else {\n\t\t\t\t\t// Commit only on blur or Ctrl/Cmd+Enter\n\t\t\t\t\ttext.inputEl.addEventListener(\"blur\", () => void commit(text.inputEl.value));\n\t\t\t\t\ttext.inputEl.addEventListener(\"keydown\", (e: KeyboardEvent) => {\n\t\t\t\t\t\tif (e.key === \"Enter\" && (e.ctrlKey || e.metaKey)) {\n\t\t\t\t\t\t\te.preventDefault();\n\t\t\t\t\t\t\tvoid commit(text.inputEl.value);\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t\t}\n\n\t\t\t\ttext.inputEl.rows = 5;\n\t\t\t\ttext.inputEl.classList.add(\"settings-ui-builder-textarea\");\n\t\t\t});\n\t\t} else {\n\t\t\tsetting.addText((text) => {\n\t\t\t\ttext.setPlaceholder(placeholder);\n\t\t\t\ttext.setValue(Array.isArray(value) ? value.join(arrayDelimiter) : \"\");\n\n\t\t\t\tconst commit = async (inputValue: string) => {\n\t\t\t\t\tconst tokens = inputValue\n\t\t\t\t\t\t.split(\",\")\n\t\t\t\t\t\t.map((s) => s.trim())\n\t\t\t\t\t\t.filter((s) => s.length > 0);\n\n\t\t\t\t\ttry {\n\t\t\t\t\t\tconst items = tokens.map(parser).filter(validator);\n\t\t\t\t\t\tawait this.updateSetting(key, items);\n\t\t\t\t\t} catch (error) {\n\t\t\t\t\t\tnew Notice(`Invalid input: ${error}`, 5000);\n\t\t\t\t\t}\n\t\t\t\t};\n\n\t\t\t\tif (commitOnChange) {\n\t\t\t\t\t// Reactive: commit on every change\n\t\t\t\t\ttext.onChange(async (inputValue) => {\n\t\t\t\t\t\tawait commit(inputValue);\n\t\t\t\t\t});\n\t\t\t\t} else {\n\t\t\t\t\t// Commit only on blur or Ctrl/Cmd+Enter\n\t\t\t\t\ttext.inputEl.addEventListener(\"blur\", () => void commit(text.inputEl.value));\n\t\t\t\t\ttext.inputEl.addEventListener(\"keydown\", (e: KeyboardEvent) => {\n\t\t\t\t\t\tif (e.key === \"Enter\" && (e.ctrlKey || e.metaKey)) {\n\t\t\t\t\t\t\te.preventDefault();\n\t\t\t\t\t\t\tvoid commit(text.inputEl.value);\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\t}\n\n\t/**\n\t * Advanced array manager with add/remove buttons for each item\n\t */\n\taddArrayManager(containerEl: HTMLElement, config: ArrayManagerConfig): void {\n\t\tconst {\n\t\t\tkey,\n\t\t\tname,\n\t\t\tdesc,\n\t\t\tplaceholder = \"\",\n\t\t\taddButtonText = \"Add\",\n\t\t\tremoveButtonText = \"Remove\",\n\t\t\temptyArrayFallback = [],\n\t\t\tpreventEmpty = false,\n\t\t\titemDescriptionFn,\n\t\t\tonBeforeAdd,\n\t\t\tonBeforeRemove,\n\t\t\tquickActions = [],\n\t\t} = config;\n\n\t\t// Section heading\n\t\tnew Setting(containerEl).setName(name).setHeading();\n\n\t\t// Description\n\t\tif (desc) {\n\t\t\tconst descEl = containerEl.createDiv(\"setting-item-description\");\n\t\t\tdescEl.setText(desc);\n\t\t}\n\n\t\t// Container for list items\n\t\tconst listContainer = containerEl.createDiv(\"settings-array-manager-list\");\n\n\t\tconst render = () => {\n\t\t\tlistContainer.empty();\n\n\t\t\tconst currentItems = (this.getNestedValue(key) as unknown[]) ?? [];\n\n\t\t\tfor (const item of currentItems) {\n\t\t\t\tconst itemSetting = new Setting(listContainer).setName(String(item)).addButton((button) =>\n\t\t\t\t\tbutton\n\t\t\t\t\t\t.setButtonText(removeButtonText)\n\t\t\t\t\t\t.setWarning()\n\t\t\t\t\t\t.onClick(async () => {\n\t\t\t\t\t\t\tlet newItems = currentItems.filter((i) => i !== item);\n\n\t\t\t\t\t\t\t// Apply custom logic before removal\n\t\t\t\t\t\t\tif (onBeforeRemove) {\n\t\t\t\t\t\t\t\tnewItems = await onBeforeRemove(item, currentItems);\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t// Prevent empty array if configured\n\t\t\t\t\t\t\tif (preventEmpty && newItems.length === 0) {\n\t\t\t\t\t\t\t\tnewItems = Array.isArray(emptyArrayFallback)\n\t\t\t\t\t\t\t\t\t? emptyArrayFallback\n\t\t\t\t\t\t\t\t\t: [emptyArrayFallback];\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tawait this.updateSetting(key, newItems);\n\t\t\t\t\t\t\trender();\n\t\t\t\t\t\t})\n\t\t\t\t);\n\n\t\t\t\t// Add custom description for each item if provided\n\t\t\t\tif (itemDescriptionFn) {\n\t\t\t\t\titemSetting.setDesc(itemDescriptionFn(item));\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\n\t\trender();\n\n\t\t// Add new item section\n\t\tconst inputId = `settings-array-manager-input-${key}`;\n\t\tnew Setting(containerEl)\n\t\t\t.setName(`Add ${name.toLowerCase()}`)\n\t\t\t.setDesc(`Enter a new value`)\n\t\t\t.addText((text) => {\n\t\t\t\ttext.setPlaceholder(placeholder);\n\t\t\t\ttext.inputEl.id = inputId;\n\t\t\t})\n\t\t\t.addButton((button) =>\n\t\t\t\tbutton\n\t\t\t\t\t.setButtonText(addButtonText)\n\t\t\t\t\t.setCta()\n\t\t\t\t\t.onClick(async () => {\n\t\t\t\t\t\t// Use document.getElementById instead of querySelector to avoid CSS selector issues with dots\n\t\t\t\t\t\tconst input = document.getElementById(inputId) as HTMLInputElement;\n\t\t\t\t\t\tif (!input) {\n\t\t\t\t\t\t\tconsole.error(`Input element not found: ${inputId}`);\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tconst newItem = input.value.trim();\n\n\t\t\t\t\t\tif (!newItem) {\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tconst currentItems = (this.getNestedValue(key) as unknown[]) ?? [];\n\t\t\t\t\t\tlet newItems = [...currentItems];\n\n\t\t\t\t\t\t// Apply custom logic before adding\n\t\t\t\t\t\tif (onBeforeAdd) {\n\t\t\t\t\t\t\tnewItems = await onBeforeAdd(newItem, currentItems);\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t// Default behavior: add if not exists\n\t\t\t\t\t\t\tif (!newItems.includes(newItem)) {\n\t\t\t\t\t\t\t\tnewItems.push(newItem);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tawait this.updateSetting(key, newItems);\n\t\t\t\t\t\tinput.value = \"\";\n\t\t\t\t\t\trender();\n\t\t\t\t\t})\n\t\t\t);\n\n\t\t// Quick actions\n\t\tfor (const quickAction of quickActions) {\n\t\t\tconst currentItems = (this.getNestedValue(key) as unknown[]) ?? [];\n\n\t\t\t// Check condition if provided\n\t\t\tif (quickAction.condition && !quickAction.condition(currentItems)) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tnew Setting(containerEl)\n\t\t\t\t.setName(quickAction.name)\n\t\t\t\t.setDesc(quickAction.desc)\n\t\t\t\t.addButton((button) =>\n\t\t\t\t\tbutton.setButtonText(quickAction.buttonText).onClick(async () => {\n\t\t\t\t\t\tconst currentItems = (this.getNestedValue(key) as unknown[]) ?? [];\n\t\t\t\t\t\tconst newItems = await quickAction.action(currentItems);\n\t\t\t\t\t\tawait this.updateSetting(key, newItems);\n\t\t\t\t\t\trender();\n\t\t\t\t\t})\n\t\t\t\t);\n\t\t}\n\t}\n}\n"]}
|
package/package.json
CHANGED
package/src/components/index.ts
CHANGED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import type { EventRef } from "obsidian";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Base class that provides event registration and automatic cleanup.
|
|
5
|
+
* Similar to ItemView's registerEvent/registerDomEvent pattern.
|
|
6
|
+
*
|
|
7
|
+
* Subclasses should call cleanupEvents() in their destroy/cleanup method.
|
|
8
|
+
*/
|
|
9
|
+
export abstract class RegisteredEventsComponent {
|
|
10
|
+
protected eventRefs: EventRef[] = [];
|
|
11
|
+
protected eventCleanupFunctions: Array<() => void> = [];
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Register an Obsidian event (workspace, vault, metadataCache, etc.)
|
|
15
|
+
* Event will be automatically cleaned up when destroy() is called
|
|
16
|
+
*/
|
|
17
|
+
protected registerEvent<T extends keyof any>(
|
|
18
|
+
emitter: {
|
|
19
|
+
on(event: T, callback: (...args: any[]) => void): void;
|
|
20
|
+
off(event: T, callback: (...args: any[]) => void): void;
|
|
21
|
+
},
|
|
22
|
+
event: T,
|
|
23
|
+
callback: (...args: any[]) => void
|
|
24
|
+
): void {
|
|
25
|
+
emitter.on(event, callback);
|
|
26
|
+
this.eventCleanupFunctions.push(() => {
|
|
27
|
+
emitter.off(event, callback);
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Register a DOM event (window, document, or element)
|
|
33
|
+
* Event will be automatically cleaned up when destroy() is called
|
|
34
|
+
*/
|
|
35
|
+
protected registerDomEvent<K extends keyof WindowEventMap>(
|
|
36
|
+
target: Window | Document | HTMLElement,
|
|
37
|
+
event: K,
|
|
38
|
+
callback: (evt: WindowEventMap[K]) => void
|
|
39
|
+
): void {
|
|
40
|
+
target.addEventListener(event, callback as EventListener);
|
|
41
|
+
this.eventCleanupFunctions.push(() => {
|
|
42
|
+
target.removeEventListener(event, callback as EventListener);
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Clean up all registered events.
|
|
48
|
+
* Should be called by subclass destroy() method.
|
|
49
|
+
*/
|
|
50
|
+
protected cleanupEvents(): void {
|
|
51
|
+
for (const cleanup of this.eventCleanupFunctions) {
|
|
52
|
+
cleanup();
|
|
53
|
+
}
|
|
54
|
+
this.eventCleanupFunctions = [];
|
|
55
|
+
}
|
|
56
|
+
}
|
|
@@ -66,11 +66,50 @@ export class SettingsUIBuilder<TSchema extends ZodObject<ZodRawShape>> {
|
|
|
66
66
|
return this.settingsStore.validationSchema;
|
|
67
67
|
}
|
|
68
68
|
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
69
|
+
/**
|
|
70
|
+
* Gets a nested property value using dot notation (e.g., "basesView.tasksDirectory")
|
|
71
|
+
*/
|
|
72
|
+
private getNestedValue(key: string): unknown {
|
|
73
|
+
const keys = key.split(".");
|
|
74
|
+
let value: any = this.settings;
|
|
75
|
+
|
|
76
|
+
for (const k of keys) {
|
|
77
|
+
if (value === undefined || value === null) {
|
|
78
|
+
return undefined;
|
|
79
|
+
}
|
|
80
|
+
value = value[k];
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
return value;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* Sets a nested property value using dot notation and returns updated settings
|
|
88
|
+
*/
|
|
89
|
+
private setNestedValue(key: string, value: unknown): z.infer<TSchema> {
|
|
90
|
+
const keys = key.split(".");
|
|
91
|
+
const newSettings = JSON.parse(JSON.stringify(this.settings)); // Deep clone
|
|
92
|
+
|
|
93
|
+
let current: any = newSettings;
|
|
94
|
+
|
|
95
|
+
// Navigate to the parent of the target property
|
|
96
|
+
for (let i = 0; i < keys.length - 1; i++) {
|
|
97
|
+
const k = keys[i];
|
|
98
|
+
if (!(k in current)) {
|
|
99
|
+
current[k] = {};
|
|
100
|
+
}
|
|
101
|
+
current = current[k];
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
// Set the final property
|
|
105
|
+
const lastKey = keys[keys.length - 1];
|
|
106
|
+
current[lastKey] = value;
|
|
107
|
+
|
|
108
|
+
return newSettings;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
private async updateSetting(key: string, value: unknown): Promise<void> {
|
|
112
|
+
const newSettings = this.setNestedValue(key, value);
|
|
74
113
|
|
|
75
114
|
const result = this.schema.safeParse(newSettings);
|
|
76
115
|
|
|
@@ -87,7 +126,21 @@ export class SettingsUIBuilder<TSchema extends ZodObject<ZodRawShape>> {
|
|
|
87
126
|
|
|
88
127
|
private inferSliderBounds(key: string): { min?: number; max?: number; step?: number } {
|
|
89
128
|
try {
|
|
90
|
-
|
|
129
|
+
// Navigate nested schema using dot notation
|
|
130
|
+
const keys = key.split(".");
|
|
131
|
+
let fieldSchema: any = this.schema.shape;
|
|
132
|
+
|
|
133
|
+
for (const k of keys) {
|
|
134
|
+
if (!fieldSchema) return {};
|
|
135
|
+
|
|
136
|
+
// Unwrap nested schemas
|
|
137
|
+
while ((fieldSchema as any)._def?.innerType) {
|
|
138
|
+
fieldSchema = (fieldSchema as any)._def.innerType;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
fieldSchema = (fieldSchema as any).shape?.[k] ?? (fieldSchema as any)[k];
|
|
142
|
+
}
|
|
143
|
+
|
|
91
144
|
if (!fieldSchema) return {};
|
|
92
145
|
|
|
93
146
|
let innerSchema = fieldSchema;
|
|
@@ -120,7 +173,21 @@ export class SettingsUIBuilder<TSchema extends ZodObject<ZodRawShape>> {
|
|
|
120
173
|
|
|
121
174
|
private inferArrayItemType(key: string): "string" | "number" | undefined {
|
|
122
175
|
try {
|
|
123
|
-
|
|
176
|
+
// Navigate nested schema using dot notation
|
|
177
|
+
const keys = key.split(".");
|
|
178
|
+
let fieldSchema: any = this.schema.shape;
|
|
179
|
+
|
|
180
|
+
for (const k of keys) {
|
|
181
|
+
if (!fieldSchema) return undefined;
|
|
182
|
+
|
|
183
|
+
// Unwrap nested schemas
|
|
184
|
+
while ((fieldSchema as any)._def?.innerType) {
|
|
185
|
+
fieldSchema = (fieldSchema as any)._def.innerType;
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
fieldSchema = (fieldSchema as any).shape?.[k] ?? (fieldSchema as any)[k];
|
|
189
|
+
}
|
|
190
|
+
|
|
124
191
|
if (!fieldSchema) return undefined;
|
|
125
192
|
|
|
126
193
|
let innerSchema = fieldSchema;
|
|
@@ -146,21 +213,21 @@ export class SettingsUIBuilder<TSchema extends ZodObject<ZodRawShape>> {
|
|
|
146
213
|
|
|
147
214
|
addToggle(containerEl: HTMLElement, config: BaseSettingConfig): void {
|
|
148
215
|
const { key, name, desc } = config;
|
|
149
|
-
const value = this.
|
|
216
|
+
const value = this.getNestedValue(key);
|
|
150
217
|
|
|
151
218
|
new Setting(containerEl)
|
|
152
219
|
.setName(name)
|
|
153
220
|
.setDesc(desc)
|
|
154
221
|
.addToggle((toggle) =>
|
|
155
222
|
toggle.setValue(Boolean(value)).onChange(async (newValue) => {
|
|
156
|
-
await this.updateSetting(key
|
|
223
|
+
await this.updateSetting(key, newValue);
|
|
157
224
|
})
|
|
158
225
|
);
|
|
159
226
|
}
|
|
160
227
|
|
|
161
228
|
addSlider(containerEl: HTMLElement, config: SliderSettingConfig): void {
|
|
162
229
|
const { key, name, desc, step = 1, commitOnChange = false } = config;
|
|
163
|
-
const value = this.
|
|
230
|
+
const value = this.getNestedValue(key);
|
|
164
231
|
|
|
165
232
|
const inferredBounds = this.inferSliderBounds(key);
|
|
166
233
|
const min = config.min ?? inferredBounds.min ?? 0;
|
|
@@ -175,13 +242,13 @@ export class SettingsUIBuilder<TSchema extends ZodObject<ZodRawShape>> {
|
|
|
175
242
|
if (commitOnChange) {
|
|
176
243
|
// Reactive: commit on every change
|
|
177
244
|
slider.onChange(async (newValue) => {
|
|
178
|
-
await this.updateSetting(key
|
|
245
|
+
await this.updateSetting(key, newValue);
|
|
179
246
|
});
|
|
180
247
|
} else {
|
|
181
248
|
// Commit only when user finishes dragging
|
|
182
249
|
const commit = async (newValue: number) => {
|
|
183
250
|
try {
|
|
184
|
-
await this.updateSetting(key
|
|
251
|
+
await this.updateSetting(key, newValue);
|
|
185
252
|
} catch (error) {
|
|
186
253
|
new Notice(`Invalid input: ${error}`, 5000);
|
|
187
254
|
}
|
|
@@ -213,7 +280,7 @@ export class SettingsUIBuilder<TSchema extends ZodObject<ZodRawShape>> {
|
|
|
213
280
|
|
|
214
281
|
addText(containerEl: HTMLElement, config: TextSettingConfig): void {
|
|
215
282
|
const { key, name, desc, placeholder = "", commitOnChange = false } = config;
|
|
216
|
-
const value = this.
|
|
283
|
+
const value = this.getNestedValue(key);
|
|
217
284
|
|
|
218
285
|
new Setting(containerEl)
|
|
219
286
|
.setName(name)
|
|
@@ -225,13 +292,13 @@ export class SettingsUIBuilder<TSchema extends ZodObject<ZodRawShape>> {
|
|
|
225
292
|
if (commitOnChange) {
|
|
226
293
|
// Reactive: commit on every change
|
|
227
294
|
text.onChange(async (newValue) => {
|
|
228
|
-
await this.updateSetting(key
|
|
295
|
+
await this.updateSetting(key, newValue);
|
|
229
296
|
});
|
|
230
297
|
} else {
|
|
231
298
|
// Commit only on blur or Ctrl/Cmd+Enter
|
|
232
299
|
const commit = async (inputValue: string) => {
|
|
233
300
|
try {
|
|
234
|
-
await this.updateSetting(key
|
|
301
|
+
await this.updateSetting(key, inputValue);
|
|
235
302
|
} catch (error) {
|
|
236
303
|
new Notice(`Invalid input: ${error}`, 5000);
|
|
237
304
|
}
|
|
@@ -250,7 +317,7 @@ export class SettingsUIBuilder<TSchema extends ZodObject<ZodRawShape>> {
|
|
|
250
317
|
|
|
251
318
|
addDropdown(containerEl: HTMLElement, config: DropdownSettingConfig): void {
|
|
252
319
|
const { key, name, desc, options } = config;
|
|
253
|
-
const value = this.
|
|
320
|
+
const value = this.getNestedValue(key);
|
|
254
321
|
|
|
255
322
|
new Setting(containerEl)
|
|
256
323
|
.setName(name)
|
|
@@ -260,7 +327,7 @@ export class SettingsUIBuilder<TSchema extends ZodObject<ZodRawShape>> {
|
|
|
260
327
|
.addOptions(options)
|
|
261
328
|
.setValue(String(value))
|
|
262
329
|
.onChange(async (newValue) => {
|
|
263
|
-
await this.updateSetting(key
|
|
330
|
+
await this.updateSetting(key, newValue);
|
|
264
331
|
})
|
|
265
332
|
);
|
|
266
333
|
}
|
|
@@ -275,7 +342,7 @@ export class SettingsUIBuilder<TSchema extends ZodObject<ZodRawShape>> {
|
|
|
275
342
|
multiline = false,
|
|
276
343
|
commitOnChange = false,
|
|
277
344
|
} = config;
|
|
278
|
-
const value = this.
|
|
345
|
+
const value = this.getNestedValue(key) as T[];
|
|
279
346
|
|
|
280
347
|
const inferredItemType = config.itemType ?? this.inferArrayItemType(key) ?? "string";
|
|
281
348
|
const parser =
|
|
@@ -308,7 +375,7 @@ export class SettingsUIBuilder<TSchema extends ZodObject<ZodRawShape>> {
|
|
|
308
375
|
|
|
309
376
|
try {
|
|
310
377
|
const items = lines.map(parser).filter(validator);
|
|
311
|
-
await this.updateSetting(key
|
|
378
|
+
await this.updateSetting(key, items);
|
|
312
379
|
} catch (error) {
|
|
313
380
|
new Notice(`Invalid input: ${error}`, 5000);
|
|
314
381
|
}
|
|
@@ -346,7 +413,7 @@ export class SettingsUIBuilder<TSchema extends ZodObject<ZodRawShape>> {
|
|
|
346
413
|
|
|
347
414
|
try {
|
|
348
415
|
const items = tokens.map(parser).filter(validator);
|
|
349
|
-
await this.updateSetting(key
|
|
416
|
+
await this.updateSetting(key, items);
|
|
350
417
|
} catch (error) {
|
|
351
418
|
new Notice(`Invalid input: ${error}`, 5000);
|
|
352
419
|
}
|
|
@@ -373,7 +440,6 @@ export class SettingsUIBuilder<TSchema extends ZodObject<ZodRawShape>> {
|
|
|
373
440
|
|
|
374
441
|
/**
|
|
375
442
|
* Advanced array manager with add/remove buttons for each item
|
|
376
|
-
* Similar to the directory settings pattern
|
|
377
443
|
*/
|
|
378
444
|
addArrayManager(containerEl: HTMLElement, config: ArrayManagerConfig): void {
|
|
379
445
|
const {
|
|
@@ -406,7 +472,7 @@ export class SettingsUIBuilder<TSchema extends ZodObject<ZodRawShape>> {
|
|
|
406
472
|
const render = () => {
|
|
407
473
|
listContainer.empty();
|
|
408
474
|
|
|
409
|
-
const currentItems = (this.
|
|
475
|
+
const currentItems = (this.getNestedValue(key) as unknown[]) ?? [];
|
|
410
476
|
|
|
411
477
|
for (const item of currentItems) {
|
|
412
478
|
const itemSetting = new Setting(listContainer).setName(String(item)).addButton((button) =>
|
|
@@ -428,7 +494,7 @@ export class SettingsUIBuilder<TSchema extends ZodObject<ZodRawShape>> {
|
|
|
428
494
|
: [emptyArrayFallback];
|
|
429
495
|
}
|
|
430
496
|
|
|
431
|
-
await this.updateSetting(key
|
|
497
|
+
await this.updateSetting(key, newItems);
|
|
432
498
|
render();
|
|
433
499
|
})
|
|
434
500
|
);
|
|
@@ -456,14 +522,20 @@ export class SettingsUIBuilder<TSchema extends ZodObject<ZodRawShape>> {
|
|
|
456
522
|
.setButtonText(addButtonText)
|
|
457
523
|
.setCta()
|
|
458
524
|
.onClick(async () => {
|
|
459
|
-
|
|
525
|
+
// Use document.getElementById instead of querySelector to avoid CSS selector issues with dots
|
|
526
|
+
const input = document.getElementById(inputId) as HTMLInputElement;
|
|
527
|
+
if (!input) {
|
|
528
|
+
console.error(`Input element not found: ${inputId}`);
|
|
529
|
+
return;
|
|
530
|
+
}
|
|
531
|
+
|
|
460
532
|
const newItem = input.value.trim();
|
|
461
533
|
|
|
462
534
|
if (!newItem) {
|
|
463
535
|
return;
|
|
464
536
|
}
|
|
465
537
|
|
|
466
|
-
const currentItems = (this.
|
|
538
|
+
const currentItems = (this.getNestedValue(key) as unknown[]) ?? [];
|
|
467
539
|
let newItems = [...currentItems];
|
|
468
540
|
|
|
469
541
|
// Apply custom logic before adding
|
|
@@ -476,7 +548,7 @@ export class SettingsUIBuilder<TSchema extends ZodObject<ZodRawShape>> {
|
|
|
476
548
|
}
|
|
477
549
|
}
|
|
478
550
|
|
|
479
|
-
await this.updateSetting(key
|
|
551
|
+
await this.updateSetting(key, newItems);
|
|
480
552
|
input.value = "";
|
|
481
553
|
render();
|
|
482
554
|
})
|
|
@@ -484,7 +556,7 @@ export class SettingsUIBuilder<TSchema extends ZodObject<ZodRawShape>> {
|
|
|
484
556
|
|
|
485
557
|
// Quick actions
|
|
486
558
|
for (const quickAction of quickActions) {
|
|
487
|
-
const currentItems = (this.
|
|
559
|
+
const currentItems = (this.getNestedValue(key) as unknown[]) ?? [];
|
|
488
560
|
|
|
489
561
|
// Check condition if provided
|
|
490
562
|
if (quickAction.condition && !quickAction.condition(currentItems)) {
|
|
@@ -496,9 +568,9 @@ export class SettingsUIBuilder<TSchema extends ZodObject<ZodRawShape>> {
|
|
|
496
568
|
.setDesc(quickAction.desc)
|
|
497
569
|
.addButton((button) =>
|
|
498
570
|
button.setButtonText(quickAction.buttonText).onClick(async () => {
|
|
499
|
-
const currentItems = (this.
|
|
571
|
+
const currentItems = (this.getNestedValue(key) as unknown[]) ?? [];
|
|
500
572
|
const newItems = await quickAction.action(currentItems);
|
|
501
|
-
await this.updateSetting(key
|
|
573
|
+
await this.updateSetting(key, newItems);
|
|
502
574
|
render();
|
|
503
575
|
})
|
|
504
576
|
);
|