1
+ import * as obs from 'obsidian' ;
2
+ import SettingsTab from "./settings.js" ;
3
+ import { BaseComponent } from "obsidian" ;
4
+
5
+ export interface Settings {
6
+
7
+ }
8
+
9
+ export const default_settings : Settings = { } ;
10
+
11
+ export type Widget = ( ButtonWidget | TextInputWidget | ListBoxWidget ) & {
12
+ id ?: WidgetId ,
13
+ label ?: string ,
14
+ description ?: string ,
15
+ } ;
16
+
17
+ export type ButtonWidget = {
18
+ text : string ,
19
+ icon ?: string ,
20
+ onClick : ( e : MouseEvent ) => void ,
21
+ } ;
22
+
23
+ export type TextInputWidget = {
24
+ getTextContent ?: ( ) => string ,
25
+ setTextContent ?: ( text : string ) => void ,
26
+
27
+ placeholder ?: string ,
28
+
29
+ multiline ?: boolean
30
+ }
31
+
32
+ export type ListBoxWidget = {
33
+ listItems : ( ) => {
34
+ label : string ,
35
+ key ?: string
36
+ } [ ] ,
37
+
38
+ multiple ?: boolean ,
39
+ extend ?: boolean
40
+ }
41
+
42
+ export type WidgetId = string ;
43
+
44
+ export default class Form extends obs . Plugin {
45
+
46
+ settingsTab : SettingsTab | null = null ;
47
+ settings : Settings = default_settings ;
48
+
49
+ widgets : Map < WidgetId , { widget : Widget , component : obs . BaseComponent } > = new Map ( ) ;
50
+ updateHooks : Array < ( ) => void > = [ ] ;
51
+
52
+ async onload ( ) {
53
+ const self = this ;
54
+ console . log ( ( this . app as any ) . plugins ) ;
55
+
56
+ this . registerMarkdownCodeBlockProcessor ( "form-control" , function ( source , el , ctx ) {
57
+ try {
58
+ const getId = ( widget : Widget ) : WidgetId => `${ self . app . workspace . getActiveFile ( ) ?. path ?? '/' } /${ widget . id ?? self . widgets . size } ` ;
59
+
60
+ let form ;
61
+ const widget = new Function ( "form" , source ) ( form = {
62
+ app : ( ) => self . app ,
63
+ obs : ( ) => obs ,
64
+ createButton ( widget : Widget & ButtonWidget ) {
65
+ const id = getId ( widget ) ;
66
+ new obs . Setting ( el )
67
+ . addButton ( button => {
68
+ self . widgets . set ( id , {
69
+ widget,
70
+ component : button
71
+ } ) ;
72
+
73
+ button . setButtonText ( widget . text ) ;
74
+ if ( widget . icon ) button . setIcon ( widget . icon ) ;
75
+
76
+ button . onClick ( e => widget . onClick ?.( e ) ) ;
77
+ } )
78
+ . setName ( widget . label ?? '' )
79
+ . setDesc ( widget . description ?? '' ) ;
80
+ } ,
81
+ createTextWidget ( widget : Widget & TextInputWidget ) {
82
+ const id = getId ( widget ) ;
83
+ const cb = function ( input : obs . TextComponent | obs . TextAreaComponent ) {
84
+ self . widgets . set ( id , {
85
+ widget,
86
+ component : input
87
+ } ) ;
88
+
89
+ if ( widget . getTextContent ) input . setValue ( String ( widget . getTextContent ( ) ) ) ;
90
+ input . onChange ( value => {
91
+ widget . setTextContent ?.( value ) ;
92
+ self . updateHooks . forEach ( i => i ( ) ) ;
93
+ } ) ;
94
+
95
+ if ( widget . getTextContent && ! widget . setTextContent ) {
96
+ input . setDisabled ( true ) ;
97
+ self . updateHooks . push ( ( ) => void input . setValue ( String ( widget . getTextContent ! ( ) ) ) )
98
+ }
99
+
100
+ if ( widget . placeholder ) input . setPlaceholder ( widget . placeholder ) ;
101
+ } ;
102
+
103
+ ( widget . multiline ? new obs . Setting ( el )
104
+ . addTextArea ( cb ) : new obs . Setting ( el ) . addText ( cb ) )
105
+ . setName ( widget . label ?? '' )
106
+ . setDesc ( widget . description ?? '' ) ;
107
+ } ,
108
+ query ( id : WidgetId ) : BaseComponent | null {
109
+ if ( self . widgets . has ( id ) )
110
+ return self . widgets . get ( id ) ! . component ;
111
+
112
+ const new_id = `${ self . app . workspace . getActiveFile ( ) ?. path ?? '/' } /${ id } ` ;
113
+
114
+ if ( self . widgets . has ( new_id ) )
115
+ return self . widgets . get ( new_id ) ! . component ;
116
+
117
+ return null ;
118
+ }
119
+ } ) ;
120
+ } catch ( err ) {
121
+ el . createEl ( "pre" , {
122
+ cls : [ "error" ] ,
123
+ text : String ( err instanceof Error ? err . stack : err )
124
+ } )
125
+ }
126
+ } ) ;
127
+ this . addSettingTab ( new SettingsTab ( this . app , this ) ) ;
128
+ }
129
+ }
0 commit comments