Skip to content

Commit d7f2566

Browse files
committed
fix #260
1 parent 95a1840 commit d7f2566

File tree

10 files changed

+139
-57
lines changed

10 files changed

+139
-57
lines changed

exampleVault/Advanced Examples/Using JS Engine for Complex things.md

Lines changed: 1 addition & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -77,42 +77,7 @@ const mb = engine.getPlugin('obsidian-meta-bind-plugin').api;
7777
const mbFrom = mb.parseBindTarget('from_year', context.file.path);
7878
const mbTo = mb.parseBindTarget('to_year', context.file.path);
7979
80-
const headers = ["Date", "File"];
81-
82-
function onUpdate(uFrom, fTo) {
83-
return [uFrom, fTo];
84-
}
85-
86-
const reactive = engine.reactive(
87-
// update function
88-
onUpdate,
89-
// arguments
90-
mb.getMetadata(mbFrom),
91-
mb.getMetadata(mbTo)
92-
);
93-
94-
const subscriptionFrom = mb.subscribeToMetadata(
95-
mbFrom,
96-
component,
97-
(newFrom) => {console.log(newFrom); reactive.refresh(newFrom, mb.getMetadata(mbTo))}
98-
);
99-
100-
const subscriptionTo = mb.subscribeToMetadata(
101-
mbTo,
102-
component,
103-
(newTo) => {console.log(newTo); reactive.refresh(mb.getMetadata(mbFrom), newTo)}
104-
);
105-
106-
return reactive;
107-
```
108-
109-
```js-engine
110-
// Grab metabind API and extract metadata fields
111-
const mb = engine.getPlugin('obsidian-meta-bind-plugin').api;
112-
const mbFrom = mb.parseBindTarget('from_year', context.file.path);
113-
const mbTo = mb.parseBindTarget('to_year', context.file.path);
114-
115-
return mb.renderOnChanges([mbFrom, mbTo], component, (from, to) => {
80+
return mb.reactiveMetadata([mbFrom, mbTo], component, (from, to) => {
11681
return [from, to]
11782
})
11883
```

exampleVault/View Fields/View Field.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ images:
2424
`INPUT[number:number2]`
2525
`INPUT[text:unit]`
2626

27-
Number one is: `VIEW[{number1}]` units
27+
Number one is: `VIEW[{number1}][math(class(mod-warning))]` units
2828
Number two is: `VIEW[{number2}]` units
2929

3030
Combined: `VIEW[{number1} * {number2}]` cm equals `VIEW[{number2} * {number1} cm to {unit}]`

packages/core/src/config/FieldConfigs.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -509,6 +509,7 @@ export enum ViewFieldType {
509509
export enum ViewFieldArgumentType {
510510
RENDER_MARKDOWN = 'renderMarkdown',
511511
HIDDEN = 'hidden',
512+
CLASS = 'class',
512513

513514
INVALID = 'invalid',
514515
}
@@ -546,6 +547,20 @@ export const ViewFieldArgumentConfigs: Record<ViewFieldArgumentType, ViewFieldAr
546547
],
547548
allowMultiple: false,
548549
},
550+
[ViewFieldArgumentType.CLASS]: {
551+
type: ViewFieldArgumentType.CLASS,
552+
allowedFieldTypes: [],
553+
values: [
554+
[
555+
{
556+
name: 'className',
557+
allowed: [],
558+
description: 'the name of the css class to add',
559+
},
560+
],
561+
],
562+
allowMultiple: true,
563+
},
549564
[ViewFieldArgumentType.INVALID]: {
550565
type: ViewFieldArgumentType.INVALID,
551566
allowedFieldTypes: [],

packages/core/src/fields/fieldArguments/viewFieldArguments/ViewFieldArgumentFactory.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { ViewFieldArgumentType } from 'packages/core/src/config/FieldConfigs';
22
import { HiddenViewFieldArgument } from 'packages/core/src/fields/fieldArguments/viewFieldArguments/argumnets/HiddenViewFieldArgument';
33
import { RenderMarkdownViewFieldArgument } from 'packages/core/src/fields/fieldArguments/viewFieldArguments/argumnets/RenderMarkdownViewFieldArgument';
44
import { ErrorLevel, MetaBindParsingError } from 'packages/core/src/utils/errors/MetaBindErrors';
5+
import { ClassViewFieldArgument } from 'packages/core/src/fields/fieldArguments/viewFieldArguments/argumnets/ClassViewFieldArgument';
56

67
/**
78
* Maps the view field argument types to the view field constructors.
@@ -10,6 +11,7 @@ import { ErrorLevel, MetaBindParsingError } from 'packages/core/src/utils/errors
1011
export const VIEW_FIELD_ARGUMENT_MAP = {
1112
[ViewFieldArgumentType.RENDER_MARKDOWN]: RenderMarkdownViewFieldArgument,
1213
[ViewFieldArgumentType.HIDDEN]: HiddenViewFieldArgument,
14+
[ViewFieldArgumentType.CLASS]: ClassViewFieldArgument,
1315
} as const;
1416

1517
export type ViewFieldArgumentMapType<T extends ViewFieldArgumentType> = T extends keyof typeof VIEW_FIELD_ARGUMENT_MAP
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import type { ParsingResultNode } from 'packages/core/src/parsers/nomParsers/GeneralNomParsers';
2+
import { type ViewFieldArgumentConfig, ViewFieldArgumentConfigs } from 'packages/core/src/config/FieldConfigs';
3+
import { AbstractViewFieldArgument } from 'packages/core/src/fields/fieldArguments/viewFieldArguments/AbstractViewFieldArgument';
4+
5+
export class ClassViewFieldArgument extends AbstractViewFieldArgument {
6+
value: string[] = [];
7+
8+
_parseValue(value: ParsingResultNode[]): void {
9+
this.value = value[0].value.split(' ');
10+
}
11+
12+
public getConfig(): ViewFieldArgumentConfig {
13+
return ViewFieldArgumentConfigs.class;
14+
}
15+
}

packages/core/src/fields/viewFields/ViewFieldBase.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { type IPlugin } from 'packages/core/src/IPlugin';
2-
import { RenderChildType, type ViewFieldArgumentType } from 'packages/core/src/config/FieldConfigs';
2+
import { RenderChildType, ViewFieldArgumentType } from 'packages/core/src/config/FieldConfigs';
33
import { FieldBase } from 'packages/core/src/fields/FieldBase';
44
import { type ViewFieldArgumentMapType } from 'packages/core/src/fields/fieldArguments/viewFieldArguments/ViewFieldArgumentFactory';
55
import { type AbstractViewField } from 'packages/core/src/fields/viewFields/AbstractViewField';
@@ -113,6 +113,11 @@ export class ViewFieldBase extends FieldBase {
113113
this.createErrorIndicator(targetEl);
114114
targetEl.append(wrapperEl);
115115

116+
const classArguments = this.getArguments(ViewFieldArgumentType.CLASS);
117+
for (const classArgument of classArguments) {
118+
DomHelpers.addClasses(wrapperEl, classArgument.value);
119+
}
120+
116121
DomHelpers.addClass(wrapperEl, `mb-view-type-${this.declaration.viewFieldType}`);
117122

118123
if (this.renderChildType === RenderChildType.BLOCK) {

packages/core/src/utils/InputFieldExamples.ts

Lines changed: 51 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -32,13 +32,54 @@ export const INPUT_FIELD_EXAMPLE_DECLARATIONS: Record<InputFieldType, string> =
3232
invalid: '',
3333
};
3434

35-
export const VIEW_FIELD_EXAMPLE_DECLARATIONS: Record<ViewFieldType, string> = {
36-
image: 'VIEW[{exampleProperty}][image]',
37-
link: 'VIEW[{exampleProperty}][link]',
38-
math: 'VIEW[{exampleProperty} + 2][math]',
39-
text: 'VIEW[some text {exampleProperty}][text]',
35+
export interface ViewFieldExampleDeclaration {
36+
title: string;
37+
declaration: string;
38+
display: string;
39+
inputField: string;
40+
}
4041

41-
invalid: '',
42+
export const VIEW_FIELD_EXAMPLE_DECLARATIONS: Record<ViewFieldType, ViewFieldExampleDeclaration[]> = {
43+
image: [
44+
{
45+
title: 'Image',
46+
declaration: 'VIEW[{globalMemory^MB_VF_image_example}][image]',
47+
display: 'VIEW[{imageExampleProperty}][image]',
48+
inputField: 'INPUT[imageSuggester(optionQuery("")):globalMemory^MB_VF_image_example]',
49+
},
50+
],
51+
link: [
52+
{
53+
title: 'Link',
54+
declaration: 'VIEW[{globalMemory^MB_VF_link_example}][link]',
55+
display: 'VIEW[{linkExampleProperty}][link]',
56+
inputField: 'INPUT[suggester(optionQuery("")):globalMemory^MB_VF_link_example]',
57+
},
58+
],
59+
math: [
60+
{
61+
title: 'Math',
62+
declaration: 'VIEW[{globalMemory^MB_VF_math_example} + 2][math]',
63+
display: 'VIEW[{mathExampleProperty} + 2][math]',
64+
inputField: 'INPUT[number:globalMemory^MB_VF_math_example]',
65+
},
66+
],
67+
text: [
68+
{
69+
title: 'Text',
70+
declaration: 'VIEW[some text {globalMemory^MB_VF_text_example}][text]',
71+
display: 'VIEW[some text {textExampleProperty}][text]',
72+
inputField: 'INPUT[text:globalMemory^MB_VF_text_example]',
73+
},
74+
{
75+
title: 'Markdown',
76+
declaration: 'VIEW[**some markdown** {globalMemory^MB_VF_text_markdown_example}][text(renderMarkdown)]',
77+
display: 'VIEW[**some markdown** {markdownExampleProperty}][text(renderMarkdown)]',
78+
inputField: 'INPUT[text:globalMemory^MB_VF_text_markdown_example]',
79+
},
80+
],
81+
82+
invalid: [],
4283
};
4384

4485
export function createInputFieldFAQExamples(plugin: IPlugin): [InputFieldType, InputFieldDeclaration][] {
@@ -66,6 +107,7 @@ export function createInputFieldFAQExamples(plugin: IPlugin): [InputFieldType, I
66107
});
67108

68109
parsedDeclaration = plugin.api.inputFieldParser.merge(parsedDeclaration, overrides);
110+
parsedDeclaration.declarationString = `INPUT[${declaration}]`;
69111
const validatedDeclaration = plugin.api.inputFieldParser.validate(parsedDeclaration, '', undefined);
70112

71113
ret.push([type as InputFieldType, validatedDeclaration]);
@@ -99,19 +141,12 @@ export function createInputFieldInsertExamples(_plugin: IPlugin): [string, strin
99141

100142
export function createViewFieldInsertExamples(_plugin: IPlugin): [string, string][] {
101143
const ret: [string, string][] = [];
102-
for (const [type, declaration] of Object.entries(VIEW_FIELD_EXAMPLE_DECLARATIONS)) {
103-
if (declaration === '') {
104-
continue;
144+
for (const declarations of Object.values(VIEW_FIELD_EXAMPLE_DECLARATIONS)) {
145+
for (const declaration of declarations) {
146+
ret.push([declaration.title, `\`${declaration.declaration}]\``]);
105147
}
106-
const vfType = type as ViewFieldType;
107-
108-
const fullDeclaration = `\`${declaration}\``;
109-
110-
ret.push([vfType, fullDeclaration]);
111148
}
112149

113-
ret.push(['markdown', `\`VIEW[**some markdown** {exampleProperty}][text(renderMarkdown)]\``]);
114-
115150
ret.sort((a, b) => a[0].localeCompare(b[0]));
116151

117152
return ret;

packages/core/src/utils/faq/FaqComponent.svelte

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,12 @@
11
<script lang="ts">
22
import ErrorIndicatorComponent from 'packages/core/src/utils/errors/ErrorIndicatorComponent.svelte';
33
import { onMount } from 'svelte';
4-
import { createInputFieldFAQExamples } from 'packages/core/src/utils/InputFieldExamples';
4+
import {
5+
createInputFieldFAQExamples,
6+
VIEW_FIELD_EXAMPLE_DECLARATIONS,
7+
} from 'packages/core/src/utils/InputFieldExamples';
58
import InputFieldExampleComponent from 'packages/core/src/utils/faq/InputFieldExampleComponent.svelte';
9+
import ViewFieldExampleComponent from 'packages/core/src/utils/faq/ViewFieldExampleComponent.svelte';
610
import Button from 'packages/core/src/utils/components/Button.svelte';
711
import { ErrorCollection } from 'packages/core/src/utils/errors/ErrorCollection';
812
import { ErrorLevel, MetaBindExampleError } from 'packages/core/src/utils/errors/MetaBindErrors';
@@ -106,6 +110,12 @@
106110
fields and as fast as obsidian allows it for changes from other sources.
107111
</p>
108112

113+
{#each Object.values(VIEW_FIELD_EXAMPLE_DECLARATIONS) as examples}
114+
{#each examples as example}
115+
<ViewFieldExampleComponent declaration={example} plugin={plugin}></ViewFieldExampleComponent>
116+
{/each}
117+
{/each}
118+
109119
<h2>Bind Targets</h2>
110120
<p>
111121
<a href="https://mprojectscode.github.io/obsidian-meta-bind-plugin-docs/guides/inputfields/#binding-to-metadata"
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
<script lang="ts">
2+
import { ViewFieldExampleDeclaration } from 'packages/core/src/utils/InputFieldExamples';
3+
import { IPlugin } from 'packages/core/src/IPlugin';
4+
import { FieldBase } from 'packages/core/src/fields/FieldBase';
5+
import MountableComponent from 'packages/core/src/utils/components/MountableComponent.svelte';
6+
import { RenderChildType } from 'packages/core/src/config/FieldConfigs';
7+
8+
export let declaration: ViewFieldExampleDeclaration;
9+
10+
export let plugin: IPlugin;
11+
12+
let ipf: FieldBase = plugin.api.createInlineFieldFromString(
13+
declaration.inputField,
14+
'',
15+
undefined,
16+
RenderChildType.BLOCK,
17+
);
18+
let vf: FieldBase = plugin.api.createInlineFieldFromString(
19+
declaration.declaration,
20+
'',
21+
undefined,
22+
RenderChildType.BLOCK,
23+
);
24+
</script>
25+
26+
<div class="mb-card">
27+
<h3>{declaration.title}</h3>
28+
29+
<MountableComponent mountable={ipf}></MountableComponent>
30+
<MountableComponent mountable={vf}></MountableComponent>
31+
32+
<code>{declaration.display}</code>
33+
</div>

packages/obsidian/src/ObsidianAPI.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -128,18 +128,20 @@ export class ObsidianAPI extends API<MetaBindPlugin> {
128128
callbackSignal: new Signal<unknown>(undefined),
129129
}));
130130

131+
let reactive: ReactiveComponent | undefined = undefined;
132+
131133
const subscription = this.plugin.metadataManager.subscribeComputed(
132134
uuid,
133135
signal,
134136
undefined,
135137
dependencies,
136-
(values: unknown[]) => reactive.refresh(...values),
138+
(values: unknown[]) => reactive?.refresh(...values),
137139
() => {},
138140
);
139141

140142
lifecycleHook.register(() => subscription.unsubscribe());
141143

142-
const reactive = jsEngine.reactive(callback, ...dependencies.map(x => x.callbackSignal.get()));
144+
reactive = jsEngine.reactive(callback, ...dependencies.map(x => x.callbackSignal.get()));
143145

144146
return reactive;
145147
}

0 commit comments

Comments
 (0)