Skip to content

Commit b18a5cf

Browse files
committed
buttons: tooltip and css class
1 parent 335dde7 commit b18a5cf

File tree

17 files changed

+322
-254
lines changed

17 files changed

+322
-254
lines changed

exampleVault/Button Example.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@ actions:
6969

7070
```meta-bind-button
7171
label: This is a button
72+
class: test-class
7273
hidden: false
7374
id: ""
7475
style: primary
@@ -86,6 +87,7 @@ actions:
8687
```meta-bind-button
8788
label: Input
8889
hidden: false
90+
tooltip: "Open command palette and then search for 'help'"
8991
id: ""
9092
style: default
9193
actions:

src/api/API.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import { ViewFieldMDRC } from '../renderChildren/ViewFieldMDRC';
55
import { JsViewFieldMDRC } from '../renderChildren/JsViewFieldMDRC';
66
import type MetaBindPlugin from '../main';
77
import { InputFieldDeclarationParser } from '../parsers/inputFieldParser/InputFieldParser';
8-
import { type Component, type MarkdownPostProcessorContext } from 'obsidian';
8+
import { type Component } from 'obsidian';
99
import { InputFieldAPI } from './InputFieldAPI';
1010
import { type IAPI } from './IAPI';
1111
import { ExcludedMDRC } from '../renderChildren/ExcludedMDRC';
@@ -36,7 +36,6 @@ import { SyntaxHighlightingAPI } from './SyntaxHighlightingAPI';
3636
import {
3737
V_BindTargetDeclaration,
3838
V_BindTargetScope,
39-
V_Component,
4039
V_ComponentLike,
4140
V_FilePath,
4241
V_HTMLElement,

src/api/APIValidators.ts

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,25 @@
11
import { z } from 'zod';
2-
import { oneOf, schemaForType } from '../utils/ZodUtils';
3-
import { API, ComponentLike } from './API';
2+
import { schemaForType } from '../utils/ZodUtils';
3+
import { type ComponentLike } from './API';
44
import { RenderChildType } from '../config/FieldConfigs';
55
import {
6-
UnvalidatedFieldArgument,
7-
UnvalidatedInputFieldDeclaration,
6+
type UnvalidatedFieldArgument,
7+
type UnvalidatedInputFieldDeclaration,
88
} from '../parsers/inputFieldParser/InputFieldDeclaration';
9-
import { ParsingResultNode } from '../parsers/nomParsers/GeneralNomParsers';
10-
import { ParsingPosition, ParsingRange } from '@lemons_dev/parsinom/lib/HelperTypes';
9+
import { type ParsingResultNode } from '../parsers/nomParsers/GeneralNomParsers';
10+
import { type ParsingPosition, type ParsingRange } from '@lemons_dev/parsinom/lib/HelperTypes';
1111
import {
12-
BindTargetDeclaration,
12+
type BindTargetDeclaration,
1313
BindTargetStorageType,
14-
UnvalidatedBindTargetDeclaration,
15-
UnvalidatedPropAccess,
14+
type UnvalidatedBindTargetDeclaration,
15+
type UnvalidatedPropAccess,
1616
} from '../parsers/bindTargetParser/BindTargetDeclaration';
1717
import { PROP_ACCESS_TYPE } from '../utils/prop/PropAccess';
1818
import { ErrorCollection } from '../utils/errors/ErrorCollection';
1919
import { Component } from 'obsidian';
2020
import { BindTargetScope } from '../metadata/BindTargetScope';
2121
import { Signal } from '../utils/Signal';
22-
import { UnvalidatedViewFieldDeclaration } from '../parsers/viewFieldParser/ViewFieldDeclaration';
22+
import { type UnvalidatedViewFieldDeclaration } from '../parsers/viewFieldParser/ViewFieldDeclaration';
2323
import { PropPath } from '../utils/prop/PropPath';
2424

2525
export const V_FilePath = schemaForType<string>()(z.string());

src/api/internalApi/IInternalAPI.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,4 +33,6 @@ export interface IInternalAPI {
3333
openFile(filePath: string, callingFilePath: string): void;
3434

3535
getFilePathByName(name: string): string | undefined;
36+
37+
showNotice(message: string): void;
3638
}

src/api/internalApi/ObsidianAPIAdapter.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { type IInternalAPI } from './IInternalAPI';
22
import type MetaBindPlugin from '../../main';
3-
import { type App, Component, MarkdownRenderer, TFile } from 'obsidian';
3+
import { type App, Component, MarkdownRenderer, Notice, TFile } from 'obsidian';
44
import { type DatePickerIPF } from '../../fields/inputFields/fields/DatePicker/DatePickerIPF';
55
import { type ImageSuggesterIPF } from '../../fields/inputFields/fields/ImageSuggester/ImageSuggesterIPF';
66
import { type SuggesterLikeIFP, type SuggesterOption } from '../../fields/inputFields/fields/Suggester/SuggesterHelper';
@@ -114,4 +114,8 @@ export class ObsidianAPIAdapter implements IInternalAPI {
114114
public getFilePathByName(name: string): string | undefined {
115115
return this.app.metadataCache.getFirstLinkpathDest(name, '')?.path;
116116
}
117+
118+
public showNotice(message: string): void {
119+
new Notice(message);
120+
}
117121
}

src/api/internalApi/PublishAPIAdapter.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,4 +54,6 @@ export class PublishAPIAdapter implements IInternalAPI {
5454
public getFilePathByName(name: string): string | undefined {
5555
return name;
5656
}
57+
58+
public showNotice(_: string): void {}
5759
}

src/config/ButtonConfig.ts

Lines changed: 2 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,3 @@
1-
import { z } from 'zod';
2-
import { oneOf, schemaForType } from '../utils/ZodUtils';
3-
41
export enum ButtonStyleType {
52
DEFAULT = 'default',
63
PRIMARY = 'primary',
@@ -22,61 +19,26 @@ export interface CommandButtonAction {
2219
command: string;
2320
}
2421

25-
export const CommandButtonActionValidator = schemaForType<CommandButtonAction>()(
26-
z.object({
27-
type: z.literal(ButtonActionType.COMMAND),
28-
command: z.string(),
29-
}),
30-
);
31-
3222
export interface JSButtonAction {
3323
type: ButtonActionType.JS;
3424
file: string;
3525
}
3626

37-
export const JSButtonActionValidator = schemaForType<JSButtonAction>()(
38-
z.object({
39-
type: z.literal(ButtonActionType.JS),
40-
file: z.string(),
41-
}),
42-
);
43-
4427
export interface OpenButtonAction {
4528
type: ButtonActionType.OPEN;
4629
link: string;
4730
}
4831

49-
export const OpenButtonActionValidator = schemaForType<OpenButtonAction>()(
50-
z.object({
51-
type: z.literal(ButtonActionType.OPEN),
52-
link: z.string(),
53-
}),
54-
);
55-
5632
export interface InputButtonAction {
5733
type: ButtonActionType.INPUT;
5834
str: string;
5935
}
6036

61-
export const InputButtonActionValidator = schemaForType<InputButtonAction>()(
62-
z.object({
63-
type: z.literal(ButtonActionType.INPUT),
64-
str: z.string(),
65-
}),
66-
);
67-
6837
export interface SleepButtonAction {
6938
type: ButtonActionType.SLEEP;
7039
ms: number;
7140
}
7241

73-
export const SleepButtonActionValidator = schemaForType<SleepButtonAction>()(
74-
z.object({
75-
type: z.literal(ButtonActionType.SLEEP),
76-
ms: z.number(),
77-
}),
78-
);
79-
8042
export interface TemplaterCreateNoteButtonAction {
8143
type: ButtonActionType.TEMPLATER_CREATE_NOTE;
8244
templateFile: string;
@@ -85,16 +47,6 @@ export interface TemplaterCreateNoteButtonAction {
8547
openNote?: boolean;
8648
}
8749

88-
export const TemplaterCreateNoteButtonActionValidator = schemaForType<TemplaterCreateNoteButtonAction>()(
89-
z.object({
90-
type: z.literal(ButtonActionType.TEMPLATER_CREATE_NOTE),
91-
templateFile: z.string(),
92-
folderPath: z.string().optional(),
93-
fileName: z.string().optional(),
94-
openNote: z.boolean().optional(),
95-
}),
96-
);
97-
9850
export type ButtonAction =
9951
| CommandButtonAction
10052
| JSButtonAction
@@ -103,38 +55,13 @@ export type ButtonAction =
10355
| SleepButtonAction
10456
| TemplaterCreateNoteButtonAction;
10557

106-
export const ButtonActionValidator = schemaForType<ButtonAction>()(
107-
z.union([
108-
CommandButtonActionValidator,
109-
JSButtonActionValidator,
110-
OpenButtonActionValidator,
111-
InputButtonActionValidator,
112-
SleepButtonActionValidator,
113-
TemplaterCreateNoteButtonActionValidator,
114-
]),
115-
);
116-
11758
export interface ButtonConfig {
11859
label: string;
11960
style: ButtonStyleType;
61+
class?: string;
62+
tooltip?: string;
12063
id?: string;
12164
hidden?: boolean;
12265
action?: ButtonAction;
12366
actions?: ButtonAction[];
12467
}
125-
126-
type Tuple<T> = [T, ...T[]];
127-
export const ButtonStyleValidator = z.enum(Object.values(ButtonStyleType) as Tuple<ButtonStyleType>);
128-
129-
export const ButtonConfigValidator = schemaForType<ButtonConfig>()(
130-
z
131-
.object({
132-
label: z.string(),
133-
style: ButtonStyleValidator,
134-
id: z.string().optional(),
135-
hidden: z.boolean().optional(),
136-
action: ButtonActionValidator.optional(),
137-
actions: ButtonActionValidator.array().optional(),
138-
})
139-
.superRefine(oneOf('action', 'actions')),
140-
);
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
import { oneOf, schemaForType } from '../utils/ZodUtils';
2+
import { z } from 'zod';
3+
import {
4+
type ButtonAction,
5+
ButtonActionType,
6+
type ButtonConfig,
7+
ButtonStyleType,
8+
type CommandButtonAction,
9+
type InputButtonAction,
10+
type JSButtonAction,
11+
type OpenButtonAction,
12+
type SleepButtonAction,
13+
type TemplaterCreateNoteButtonAction,
14+
} from './ButtonConfig';
15+
16+
export const ButtonConfigValidators = schemaForType<CommandButtonAction>()(
17+
z.object({
18+
type: z.literal(ButtonActionType.COMMAND),
19+
command: z.string(),
20+
}),
21+
);
22+
export const JSButtonActionValidator = schemaForType<JSButtonAction>()(
23+
z.object({
24+
type: z.literal(ButtonActionType.JS),
25+
file: z.string(),
26+
}),
27+
);
28+
export const OpenButtonActionValidator = schemaForType<OpenButtonAction>()(
29+
z.object({
30+
type: z.literal(ButtonActionType.OPEN),
31+
link: z.string(),
32+
}),
33+
);
34+
export const InputButtonActionValidator = schemaForType<InputButtonAction>()(
35+
z.object({
36+
type: z.literal(ButtonActionType.INPUT),
37+
str: z.string(),
38+
}),
39+
);
40+
export const SleepButtonActionValidator = schemaForType<SleepButtonAction>()(
41+
z.object({
42+
type: z.literal(ButtonActionType.SLEEP),
43+
ms: z.number(),
44+
}),
45+
);
46+
export const TemplaterCreateNoteButtonActionValidator = schemaForType<TemplaterCreateNoteButtonAction>()(
47+
z.object({
48+
type: z.literal(ButtonActionType.TEMPLATER_CREATE_NOTE),
49+
templateFile: z.string(),
50+
folderPath: z.string().optional(),
51+
fileName: z.string().optional(),
52+
openNote: z.boolean().optional(),
53+
}),
54+
);
55+
export const ButtonActionValidator = schemaForType<ButtonAction>()(
56+
z.union([
57+
ButtonConfigValidators,
58+
JSButtonActionValidator,
59+
OpenButtonActionValidator,
60+
InputButtonActionValidator,
61+
SleepButtonActionValidator,
62+
TemplaterCreateNoteButtonActionValidator,
63+
]),
64+
);
65+
export const ButtonStyleValidator = z.nativeEnum(ButtonStyleType);
66+
export const ButtonConfigValidator = schemaForType<ButtonConfig>()(
67+
z
68+
.object({
69+
label: z.string(),
70+
style: ButtonStyleValidator,
71+
class: z.string().optional(),
72+
tooltip: z.string().optional(),
73+
id: z.string().optional(),
74+
hidden: z.boolean().optional(),
75+
action: ButtonActionValidator.optional(),
76+
actions: ButtonActionValidator.array().optional(),
77+
})
78+
.superRefine(oneOf('action', 'actions')),
79+
);

src/fields/button/ButtonActionRunner.ts

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import {
22
type ButtonAction,
33
ButtonActionType,
4+
type ButtonConfig,
45
type CommandButtonAction,
56
type InputButtonAction,
67
type JSButtonAction,
@@ -9,8 +10,8 @@ import {
910
type TemplaterCreateNoteButtonAction,
1011
} from '../../config/ButtonConfig';
1112
import { MDLinkParser } from '../../parsers/MarkdownLinkParser';
12-
import { DocsUtils } from '../../utils/DocsUtils';
1313
import { type IPlugin } from '../../IPlugin';
14+
import { openURL } from '../../utils/Utils';
1415

1516
export class ButtonActionRunner {
1617
plugin: IPlugin;
@@ -19,6 +20,25 @@ export class ButtonActionRunner {
1920
this.plugin = plugin;
2021
}
2122

23+
async runButtonAction(buttonConfig: ButtonConfig, filePath: string): Promise<void> {
24+
try {
25+
if (buttonConfig.action) {
26+
await this.plugin.api.buttonActionRunner.runAction(buttonConfig.action, filePath);
27+
} else if (buttonConfig.actions) {
28+
for (const action of buttonConfig.actions) {
29+
await this.plugin.api.buttonActionRunner.runAction(action, filePath);
30+
}
31+
} else {
32+
console.warn('meta-bind | ButtonMDRC >> no action defined');
33+
}
34+
} catch (e) {
35+
console.warn('meta-bind | ButtonMDRC >> error while running action', e);
36+
this.plugin.internal.showNotice(
37+
'meta-bind | Error while running button action. Check the console for details.',
38+
);
39+
}
40+
}
41+
2242
createDefaultAction(type: ButtonActionType): ButtonAction {
2343
if (type === ButtonActionType.COMMAND) {
2444
return { type: ButtonActionType.COMMAND, command: '' } satisfies CommandButtonAction;
@@ -81,8 +101,7 @@ export class ButtonActionRunner {
81101
if (link.internal) {
82102
this.plugin.internal.openFile(link.target, filePath);
83103
} else {
84-
// TODO: replace this with a proper function
85-
DocsUtils.open(link.target);
104+
openURL(link.target);
86105
}
87106
}
88107

0 commit comments

Comments
 (0)