Skip to content

Commit c5b2c32

Browse files
committed
the fixing part 2
1 parent 5eb5c72 commit c5b2c32

File tree

11 files changed

+325
-7
lines changed

11 files changed

+325
-7
lines changed

exampleVault/Input Fields/Date and Time.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
---
22
time: 14:12
3-
date2:
3+
date2: 2023-10-21
44
date1: 2023-06-08
55
---
66

exampleVault/Input Fields/Select and Multi Select.md

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,17 @@
11
---
22
select: 1
3+
select2: false
4+
select3: 3
35
multiSelect:
46
- option 1
57
- option 3
6-
select2: false
7-
select3: 3
8+
multiSelect2:
9+
- option 3
10+
- option 1
11+
multiSelect3:
12+
-
13+
- false
14+
- 1
815
---
916

1017
### Select
@@ -38,12 +45,32 @@ showcase
3845
```
3946

4047
### Multi Select
48+
4149
```meta-bind
4250
INPUT[multi_select(
4351
option(option 1),
4452
option(option 2),
4553
option(option 3),
4654
showcase
4755
):multiSelect]
56+
```
57+
58+
```meta-bind
59+
INPUT[multiSelect(
60+
option(option 1),
61+
option(option 2),
62+
option(option 3),
63+
option(option 3),
64+
option(option 2),
65+
showcase
66+
):multiSelect2]
67+
```
4868

69+
```meta-bind
70+
INPUT[multiSelect(
71+
option(1, option 1),
72+
option(false, option 2),
73+
option(null, option 3),
74+
showcase
75+
):multiSelect3]
4976
```

src/inputFields/_new/NewAbstractInputField.ts

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,10 +68,39 @@ export abstract class NewAbstractInputField<MetadataValueType, ComponentValueTyp
6868
return this.rawMapValue(value);
6969
}
7070

71-
private getValue(): MetadataValueType {
71+
/**
72+
* Get the metadata value that the input field currently has.
73+
*/
74+
public getValue(): MetadataValueType {
7275
return this.signal.get();
7376
}
7477

78+
/**
79+
* Get the internal representation of the metadata value that the input field currently has.
80+
*/
81+
public getInternalValue(): ComponentValueType {
82+
return this.reverseMapValue(this.getValue());
83+
}
84+
85+
/**
86+
* Set the value of this input field as if the user updated the field.
87+
*
88+
* @param value
89+
*/
90+
public setValue(value: MetadataValueType): void {
91+
this.signal.set(value);
92+
this.notifyListeners(value);
93+
}
94+
95+
/**
96+
* Set the value of this input field as if the user updated the field.
97+
*
98+
* @param value
99+
*/
100+
public setInternalValue(value: ComponentValueType): void {
101+
this.setValue(this.mapValue(value));
102+
}
103+
75104
private getDefaultValue(): MetadataValueType {
76105
const defaultValueArgument = this.renderChild.getArgument(InputFieldArgumentType.DEFAULT_VALUE) as DefaultValueInputFieldArgument | undefined;
77106
if (!defaultValueArgument) {

src/inputFields/_new/NewInputFieldFactory.ts

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,10 @@ import { Text } from './fields/Text/Text';
77
import { Slider } from './fields/Slider/Slider';
88
import { TextArea } from './fields/TextArea/TextArea';
99
import { Select } from './fields/Select/Select';
10+
import { MultiSelect } from './fields/MultiSelect/MultiSelect';
11+
import { DatePicker } from './fields/DatePicker/DatePicker';
1012

11-
export type NewInputField = Toggle | Slider | Text | TextArea | Select;
13+
export type NewInputField = Toggle | Slider | Text | TextArea | Select | MultiSelect | DatePicker;
1214

1315
export class NewInputFieldFactory {
1416
plugin: IPlugin;
@@ -22,6 +24,8 @@ export class NewInputFieldFactory {
2224
this.checkRenderChildTypeAllowed(type, renderChildType);
2325
}
2426

27+
// Skipped: Date, Time
28+
2529
if (type === InputFieldType.TOGGLE) {
2630
return new Toggle(renderChild);
2731
} else if (type === InputFieldType.SLIDER) {
@@ -34,6 +38,14 @@ export class NewInputFieldFactory {
3438
return new TextArea(renderChild);
3539
} else if (type === InputFieldType.SELECT) {
3640
return new Select(renderChild);
41+
} else if (type === InputFieldType.MULTI_SELECT) {
42+
return new MultiSelect(renderChild);
43+
} else if (type === InputFieldType.MULTI_SELECT_DEPRECATED) {
44+
return new MultiSelect(renderChild);
45+
} else if (type === InputFieldType.DATE_PICKER) {
46+
return new DatePicker(renderChild);
47+
} else if (type === InputFieldType.DATE_PICKER_DEPRECATED) {
48+
return new DatePicker(renderChild);
3749
}
3850

3951
return undefined;
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
import { NewAbstractInputField } from '../../NewAbstractInputField';
2+
import { OptionInputFieldArgument } from '../../../../inputFieldArguments/arguments/OptionInputFieldArgument';
3+
import { InputFieldMDRC } from '../../../../renderChildren/InputFieldMDRC';
4+
import { InputFieldArgumentType } from '../../../InputFieldConfigs';
5+
import { SvelteComponent } from 'svelte';
6+
import { moment } from 'obsidian';
7+
import DatePickerComponent from './DatePickerComponent.svelte';
8+
import { DateParser } from '../../../../parsers/DateParser';
9+
import { DatePickerInputModal } from './DatePickerInputModal';
10+
11+
export class DatePicker extends NewAbstractInputField<string | null, moment.Moment | null> {
12+
options: OptionInputFieldArgument[];
13+
14+
constructor(renderChild: InputFieldMDRC) {
15+
super(renderChild);
16+
17+
this.options = this.renderChild.getArguments(InputFieldArgumentType.OPTION) as OptionInputFieldArgument[];
18+
}
19+
20+
protected filterValue(value: any): string | null | undefined {
21+
if (value === null) {
22+
return null;
23+
}
24+
if (value === undefined || typeof value !== 'string') {
25+
return undefined;
26+
}
27+
const date = DateParser.parse(value);
28+
if (date.isValid()) {
29+
return DateParser.stringify(date);
30+
} else {
31+
return undefined;
32+
}
33+
}
34+
35+
protected getFallbackDefaultValue(): moment.Moment {
36+
return DateParser.getDefaultDate();
37+
}
38+
39+
protected getSvelteComponent(): typeof SvelteComponent {
40+
return DatePickerComponent;
41+
}
42+
43+
protected rawMapValue(value: moment.Moment | null): string | null {
44+
if (value === null) {
45+
return null;
46+
}
47+
return DateParser.stringify(value);
48+
}
49+
50+
protected rawReverseMapValue(value: string | null): moment.Moment | null | undefined {
51+
if (value === null) {
52+
return null;
53+
}
54+
const date = DateParser.parse(value);
55+
if (date.isValid()) {
56+
return date;
57+
} else {
58+
return undefined;
59+
}
60+
}
61+
62+
protected getMountArgs(): Record<string, any> {
63+
return {
64+
dateFormat: this.renderChild.plugin.settings.preferredDateFormat,
65+
showDatePicker: (): void => {
66+
new DatePickerInputModal(this.renderChild.plugin.app, this).open();
67+
},
68+
};
69+
}
70+
}
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
<script lang="ts">
2+
import type {Moment} from 'moment';
3+
import Icon from '../../../../utils/Icon.svelte';
4+
5+
export let value: Moment | null;
6+
export let dateFormat: string;
7+
export let showDatePicker: () => void;
8+
export let onValueChange: (value: Moment | null) => void;
9+
10+
export function setValue(v: Moment | null): void {
11+
value = v;
12+
}
13+
14+
function datePicker(event: MouseEvent) {
15+
showDatePicker();
16+
}
17+
18+
function datePickerKey(event: KeyboardEvent) {
19+
if (event.key === ' ') {
20+
showDatePicker();
21+
}
22+
}
23+
</script>
24+
25+
<style>
26+
.date-picker-input {
27+
background: var(--background-secondary);
28+
border-radius: var(--mb-border-radius);
29+
border: var(--mb-border-width) solid var(--background-modifier-border);
30+
padding: 5px 5px 5px 7px;
31+
cursor: pointer;
32+
position: relative;
33+
color: var(--text-normal);
34+
display: inline-flex;
35+
align-items: center;
36+
gap: 5px;
37+
}
38+
39+
.date-picker-text {
40+
display: inline-block;
41+
}
42+
</style>
43+
44+
<div
45+
class="date-picker-input"
46+
on:click={datePicker}
47+
on:keydown={datePickerKey}
48+
role='button'
49+
tabindex='0'
50+
>
51+
<div class="date-picker-text">
52+
<span>{value ? value.format(dateFormat) : "none"}</span>
53+
</div>
54+
<Icon iconName="calendar"/>
55+
</div>
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
import { App, Modal } from 'obsidian';
2+
import DatePickerInput from '../../../fields/DatePicker/DatePicker.svelte';
3+
import { DatePicker } from './DatePicker';
4+
import { Moment } from 'moment/moment';
5+
6+
export class DatePickerInputModal extends Modal {
7+
datePickerInput: DatePickerInput | undefined;
8+
datePicker: DatePicker;
9+
10+
constructor(app: App, datePicker: DatePicker) {
11+
super(app);
12+
this.datePicker = datePicker;
13+
}
14+
15+
public onOpen(): void {
16+
this.datePickerInput = new DatePickerInput({
17+
target: this.contentEl,
18+
props: {
19+
selectedDate: this.datePicker.getInternalValue(),
20+
dateChangeCallback: (value: Moment | null) => {
21+
this.datePicker.setInternalValue(value);
22+
this.close();
23+
},
24+
},
25+
});
26+
}
27+
28+
public onClose(): void {
29+
this.datePickerInput?.$destroy();
30+
}
31+
}
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
import { NewAbstractInputField } from '../../NewAbstractInputField';
2+
import { isLiteral, MBLiteral } from '../../../../utils/Utils';
3+
import { OptionInputFieldArgument } from '../../../../inputFieldArguments/arguments/OptionInputFieldArgument';
4+
import { InputFieldMDRC } from '../../../../renderChildren/InputFieldMDRC';
5+
import { InputFieldArgumentType } from '../../../InputFieldConfigs';
6+
import { SvelteComponent } from 'svelte';
7+
import MultiSelectComponent from './MultiSelectComponent.svelte';
8+
9+
export class MultiSelect extends NewAbstractInputField<MBLiteral[], MBLiteral[]> {
10+
options: OptionInputFieldArgument[];
11+
12+
constructor(renderChild: InputFieldMDRC) {
13+
super(renderChild);
14+
15+
this.options = this.renderChild.getArguments(InputFieldArgumentType.OPTION) as OptionInputFieldArgument[];
16+
}
17+
18+
protected filterValue(value: any): MBLiteral[] | undefined {
19+
if (value === null || value === undefined) {
20+
return undefined;
21+
} else if (Array.isArray(value)) {
22+
return value;
23+
} else {
24+
return [value];
25+
}
26+
}
27+
28+
protected getFallbackDefaultValue(): MBLiteral[] {
29+
return [];
30+
}
31+
32+
protected getSvelteComponent(): typeof SvelteComponent {
33+
return MultiSelectComponent;
34+
}
35+
36+
protected rawMapValue(value: MBLiteral[]): MBLiteral[] {
37+
return value;
38+
}
39+
40+
protected rawReverseMapValue(value: MBLiteral[]): MBLiteral[] | undefined {
41+
return value;
42+
}
43+
44+
protected getMountArgs(): Record<string, any> {
45+
return {
46+
options: this.options,
47+
};
48+
}
49+
}
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
<script lang="ts">
2+
import {MBLiteral, stringifyLiteral} from '../../../../utils/Utils';
3+
import {OptionInputFieldArgument} from '../../../../inputFieldArguments/arguments/OptionInputFieldArgument';
4+
5+
export let value: MBLiteral[];
6+
export let options: OptionInputFieldArgument[];
7+
export let onValueChange: (value: MBLiteral[]) => void;
8+
9+
export function setValue(v: MBLiteral[]): void {
10+
value = v;
11+
}
12+
13+
function selectOption(option: MBLiteral) {
14+
if (value.includes(option)) {
15+
value = value.filter(x => x !== option);
16+
} else {
17+
value.push(option);
18+
value = value;
19+
}
20+
21+
onValueChange(value);
22+
}
23+
24+
function selectOptionOnKey(event: KeyboardEvent, option: MBLiteral) {
25+
if (event.key === ' ') {
26+
selectOption(option);
27+
}
28+
}
29+
</script>
30+
31+
{#each options as option}
32+
<div
33+
class="mb-select-input-element"
34+
class:is-selected={value.includes(option.value)}
35+
role="button"
36+
tabindex="0"
37+
on:click={() => selectOption(option.value)}
38+
on:keypress={(event) => selectOptionOnKey(event, option.value)}
39+
>
40+
{option.name}
41+
</div>
42+
{/each}

0 commit comments

Comments
 (0)