generated from obsidianmd/obsidian-sample-plugin
-
-
Notifications
You must be signed in to change notification settings - Fork 40
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
68d3b18
commit 361dbb7
Showing
18 changed files
with
456 additions
and
44 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,7 +1,7 @@ | ||
--- | ||
slider1: 23 | ||
slider2: 13 | ||
slider3: 319 | ||
slider1: 51 | ||
slider2: 2 | ||
slider3: 233 | ||
--- | ||
|
||
### Simple Slider | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,5 @@ | ||
--- | ||
text: text | ||
text: test | ||
textArea: textArea | ||
--- | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,12 +1,13 @@ | ||
--- | ||
toggle2: 14 | ||
toggle1: false | ||
toggle2: 1 | ||
--- | ||
|
||
|
||
```meta-bind | ||
INPUT[toggle(showcase):toggle1] | ||
``` | ||
|
||
```meta-bind | ||
INPUT[toggle(showcase, onValue(1), offValue(0)):toggle2] | ||
INPUT[toggle(showcase, onValue(1), offValue(0), defaultValue(1)):toggle2] | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,8 @@ | ||
import { IAPI } from './api/IAPI'; | ||
import { MetaBindPluginSettings } from './settings/Settings'; | ||
|
||
export interface IPlugin { | ||
api: IAPI; | ||
settings: MetaBindPluginSettings; | ||
getFilePathsByName: (name: string) => string[]; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
import { SvelteComponent } from 'svelte'; | ||
import { Listener, Notifier } from '../../utils/Signal'; | ||
|
||
export class InputFieldComponent<Value> extends Notifier<Value, Listener<Value>> { | ||
private readonly svelteComponent: typeof SvelteComponent; | ||
private svelteComponentInstance?: SvelteComponent; | ||
|
||
constructor(svelteComponent: typeof SvelteComponent) { | ||
super(); | ||
|
||
this.svelteComponent = svelteComponent; | ||
} | ||
|
||
/** | ||
* This sets the value without triggering an update. | ||
* | ||
* @param value | ||
*/ | ||
public setValue(value: Value): void { | ||
this.svelteComponentInstance?.setValue(value); | ||
} | ||
|
||
/** | ||
* This mounts the component to the container element. | ||
* Don't forget to call unmount. | ||
* | ||
* @param container | ||
* @param initialValue | ||
* @param mountArgs | ||
*/ | ||
public mount(container: HTMLElement, initialValue: Value, mountArgs: Record<string, any> = {}): void { | ||
const props = Object.assign( | ||
{ | ||
value: initialValue, | ||
onValueChange: (value: Value) => { | ||
console.log('prop value change'); | ||
this.notifyListeners(value); | ||
}, | ||
}, | ||
mountArgs | ||
); | ||
|
||
this.svelteComponentInstance = new this.svelteComponent({ | ||
target: container, | ||
props: props, | ||
}); | ||
} | ||
|
||
/** | ||
* This unmounts the component. | ||
*/ | ||
public unmount(): void { | ||
this.listeners = []; | ||
this.svelteComponentInstance?.$destroy(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,95 @@ | ||
import { InputFieldMDRC } from '../../renderChildren/InputFieldMDRC'; | ||
import { InputFieldComponent } from './InputFieldComponent'; | ||
import { SvelteComponent } from 'svelte'; | ||
import { ComputedSignal, Listener, Notifier } from '../../utils/Signal'; | ||
import { InputFieldArgumentType } from '../InputFieldConfigs'; | ||
import { DefaultValueInputFieldArgument } from '../../inputFieldArguments/arguments/DefaultValueInputFieldArgument'; | ||
|
||
export abstract class NewAbstractInputField<MetadataValueType, ComponentValueType> extends Notifier<MetadataValueType, Listener<MetadataValueType>> { | ||
readonly renderChild: InputFieldMDRC; | ||
readonly inputFieldComponent: InputFieldComponent<ComponentValueType>; | ||
readonly signal: ComputedSignal<any, MetadataValueType>; | ||
|
||
protected constructor(renderChild: InputFieldMDRC) { | ||
super(); | ||
|
||
this.renderChild = renderChild; | ||
this.inputFieldComponent = new InputFieldComponent<ComponentValueType>(this.getSvelteComponent()); | ||
|
||
this.signal = new ComputedSignal<any, MetadataValueType>(this.renderChild.writeSignal, (value: any): MetadataValueType => { | ||
const filteredValue = this.filterValue(value); | ||
return filteredValue !== undefined ? filteredValue : this.getDefaultValue(); | ||
}); | ||
|
||
this.signal.registerListener({ | ||
callback: value => this.inputFieldComponent.setValue(this.reverseMapValue(value)), | ||
}); | ||
|
||
this.inputFieldComponent.registerListener({ | ||
callback: value => { | ||
console.log('input field component change', value); | ||
this.notifyListeners(this.mapValue(value)); | ||
}, | ||
}); | ||
} | ||
|
||
protected abstract getSvelteComponent(): typeof SvelteComponent; | ||
|
||
/** | ||
* Takes in any value and returns the value if it is type of `T`, `undefined` otherwise. | ||
* | ||
* @param value | ||
*/ | ||
protected abstract filterValue(value: any): MetadataValueType | undefined; | ||
|
||
protected abstract getFallbackDefaultValue(): ComponentValueType; | ||
|
||
/** | ||
* Maps a metadata value to a component value. If the value can't be mapped, the function should return `undefined`. | ||
* | ||
* @param value | ||
*/ | ||
protected abstract rawReverseMapValue(value: MetadataValueType): ComponentValueType | undefined; | ||
protected abstract rawMapValue(value: ComponentValueType): MetadataValueType; | ||
|
||
private reverseMapValue(value: MetadataValueType): ComponentValueType { | ||
const mappedValue = this.rawReverseMapValue(value); | ||
if (mappedValue !== undefined) { | ||
return mappedValue; | ||
} | ||
const mappedDefaultValue = this.rawReverseMapValue(this.getDefaultValue()); | ||
if (mappedDefaultValue !== undefined) { | ||
return mappedDefaultValue; | ||
} | ||
return this.getFallbackDefaultValue(); | ||
} | ||
|
||
private mapValue(value: ComponentValueType): MetadataValueType { | ||
return this.rawMapValue(value); | ||
} | ||
|
||
private getValue(): MetadataValueType { | ||
return this.signal.get(); | ||
} | ||
|
||
private getDefaultValue(): MetadataValueType { | ||
const defaultValueArgument = this.renderChild.getArgument(InputFieldArgumentType.DEFAULT_VALUE) as DefaultValueInputFieldArgument | undefined; | ||
if (!defaultValueArgument) { | ||
return this.mapValue(this.getFallbackDefaultValue()); | ||
} | ||
const filteredValue = this.filterValue(defaultValueArgument.value); | ||
return filteredValue !== undefined ? filteredValue : this.mapValue(this.getFallbackDefaultValue()); | ||
} | ||
|
||
protected getMountArgs(): Record<string, any> { | ||
return {}; | ||
} | ||
|
||
public mount(container: HTMLElement): void { | ||
this.inputFieldComponent.mount(container, this.reverseMapValue(this.getValue()), this.getMountArgs()); | ||
} | ||
|
||
public unmount(): void { | ||
this.inputFieldComponent.unmount(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
import { InputFieldConfig, InputFieldConfigs, InputFieldType } from '../InputFieldConfigs'; | ||
import { InputFieldMDRC, RenderChildType } from '../../renderChildren/InputFieldMDRC'; | ||
import { ErrorLevel, MetaBindParsingError } from '../../utils/errors/MetaBindErrors'; | ||
import { IPlugin } from '../../IPlugin'; | ||
import { Toggle } from './fields/Toggle/Toggle'; | ||
import { Text } from './fields/Text/Text'; | ||
import { Slider } from './fields/Slider/Slider'; | ||
|
||
export type NewInputField = Toggle | Slider | Text; | ||
|
||
export class NewInputFieldFactory { | ||
plugin: IPlugin; | ||
|
||
constructor(plugin: IPlugin) { | ||
this.plugin = plugin; | ||
} | ||
|
||
createInputField(type: InputFieldType, renderChildType: RenderChildType, renderChild: InputFieldMDRC): NewInputField | undefined { | ||
if (type !== InputFieldType.INVALID) { | ||
this.checkRenderChildTypeAllowed(type, renderChildType); | ||
} | ||
|
||
if (type === InputFieldType.TOGGLE) { | ||
return new Toggle(renderChild); | ||
} else if (type === InputFieldType.SLIDER) { | ||
return new Slider(renderChild); | ||
} else if (type === InputFieldType.TEXT) { | ||
return new Text(renderChild); | ||
} | ||
|
||
return undefined; | ||
} | ||
|
||
checkRenderChildTypeAllowed(type: InputFieldType, renderChildType: RenderChildType): void { | ||
if (this.plugin.settings.ignoreCodeBlockRestrictions) { | ||
return; | ||
} | ||
|
||
const inputFieldConfig: InputFieldConfig = InputFieldConfigs[type]; | ||
if (renderChildType === RenderChildType.BLOCK && !inputFieldConfig.allowInBlock) { | ||
throw new MetaBindParsingError(ErrorLevel.CRITICAL, 'can not create input field', `'${type}' is not allowed as code block`); | ||
} | ||
if (renderChildType === RenderChildType.INLINE && !inputFieldConfig.allowInline) { | ||
throw new MetaBindParsingError(ErrorLevel.CRITICAL, 'can not create input field', `'${type}' is not allowed as inline code block`); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
import { NewAbstractInputField } from '../../NewAbstractInputField'; | ||
import { clamp } from '../../../../utils/Utils'; | ||
import { InputFieldMDRC } from '../../../../renderChildren/InputFieldMDRC'; | ||
import { SvelteComponent } from 'svelte'; | ||
import SliderComponent from './SliderComponent.svelte'; | ||
import { InputFieldArgumentType } from '../../../InputFieldConfigs'; | ||
|
||
export class Slider extends NewAbstractInputField<number, number> { | ||
minValue: number; | ||
maxValue: number; | ||
|
||
constructor(renderChild: InputFieldMDRC) { | ||
super(renderChild); | ||
|
||
this.minValue = this.renderChild.getArgument(InputFieldArgumentType.MIN_VALUE)?.value ?? 0; | ||
this.maxValue = this.renderChild.getArgument(InputFieldArgumentType.MAX_VALUE)?.value ?? 100; | ||
} | ||
|
||
protected filterValue(value: any): number | undefined { | ||
if (typeof value === 'number') { | ||
return clamp(value, this.minValue, this.maxValue); | ||
} else if (typeof value === 'string') { | ||
const v = Number.parseFloat(value); | ||
if (Number.isNaN(v)) { | ||
return undefined; | ||
} else { | ||
return clamp(v, this.minValue, this.maxValue); | ||
} | ||
} else { | ||
return undefined; | ||
} | ||
} | ||
|
||
protected getFallbackDefaultValue(): number { | ||
return this.minValue; | ||
} | ||
|
||
protected getSvelteComponent(): typeof SvelteComponent { | ||
return SliderComponent; | ||
} | ||
|
||
protected rawReverseMapValue(value: number): number | undefined { | ||
return value; | ||
} | ||
|
||
protected rawMapValue(value: number): number { | ||
return value; | ||
} | ||
|
||
protected getMountArgs(): Record<string, any> { | ||
return { | ||
minValue: this.minValue, | ||
maxValue: this.maxValue, | ||
addLabels: this.renderChild.getArgument(InputFieldArgumentType.ADD_LABELS)?.value === true, | ||
}; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
<script lang="ts"> | ||
export let value: number; | ||
export let minValue: number; | ||
export let maxValue: number; | ||
export let addLabels: boolean; | ||
export let onValueChange: (value: number) => void; | ||
export function setValue(v: number): void { | ||
value = v; | ||
} | ||
</script> | ||
|
||
{#if addLabels} | ||
<span class="meta-bind-plugin-slider-input-label">{minValue}</span> | ||
<input type="range" tabindex="0" min={minValue} max={maxValue} bind:value={value} on:input={() => onValueChange(value)}> | ||
<span class="meta-bind-plugin-slider-input-label">{maxValue}</span> | ||
{:else} | ||
<input type="range" tabindex="0" min={minValue} max={maxValue} bind:value={value} on:input={() => onValueChange(value)}> | ||
{/if} | ||
|
||
|
Oops, something went wrong.