mirror of
https://github.com/mara-li/obsidian-context-menu-hider.git
synced 2026-07-22 05:34:31 +00:00
Initial Release of this Plugin
This commit is contained in:
parent
c2e2a3f5bc
commit
e0a68cfcd4
12 changed files with 256 additions and 174 deletions
60
README.md
60
README.md
|
|
@ -1,57 +1,21 @@
|
|||
## Obsidian Sample Plugin
|
||||
# Obsidian Customizable Sidebar Plugin [](https://github.com/phibr0/obsidian-customizable-sidebar/releases) 
|
||||
|
||||
This is a sample plugin for Obsidian (https://obsidian.md).
|
||||
This Plugin allows you to add any Command, including those of Plugins, to the Sidebar and assign Custom Icons to them.
|
||||
|
||||
This project uses Typescript to provide type checking and documentation.
|
||||
The repo depends on the latest plugin API (obsidian.d.ts) in Typescript Definition format, which contains TSDoc comments describing what it does.
|
||||
## Custom Icons
|
||||
|
||||
**Note:** The Obsidian API is still in early alpha and is subject to change at any time!
|
||||
If the Command doesn't yet have any Icon, you can select from a Range of Icons, including Obsidian's internal Icons and all Feather Icons.
|
||||
|
||||
This sample plugin demonstrates some of the basic functionality the plugin API can do.
|
||||
- Changes the default font color to red using `styles.css`.
|
||||
- Adds a ribbon icon, which shows a Notice when clicked.
|
||||
- Adds a command "Open Sample Modal" which opens a Modal.
|
||||
- Adds a plugin setting tab to the settings page.
|
||||
- Registers a global click event and output 'click' to the console.
|
||||
- Registers a global interval which logs 'setInterval' to the console.
|
||||
|
||||
### First time developing plugins?
|
||||
## How to install
|
||||
|
||||
Quick starting guide for new plugin devs:
|
||||
1. Go to **Community Plugins** in your [Obsidian](https://www.obsidian.md) Settings and **disable** Safe Mode
|
||||
2. Click on **Browse** and search for „Obsidian Customizable Sidebar“
|
||||
3. Click install
|
||||
4. Toggle the Plugin on in the **Community Plugins** Tab
|
||||
|
||||
- Make a copy of this repo as a template with the "Use this template" button (login to GitHub if you don't see it).
|
||||
- Clone your repo to a local development folder. For convenience, you can place this folder in your `.obsidian/plugins/your-plugin-name` folder.
|
||||
- Install NodeJS, then run `npm i` in the command line under your repo folder.
|
||||
- Run `npm run dev` to compile your plugin from `main.ts` to `main.js`.
|
||||
- Make changes to `main.ts` (or create new `.ts` files). Those changes should be automatically compiled into `main.js`.
|
||||
- Reload Obsidian to load the new version of your plugin.
|
||||
- Enable plugin in settings window.
|
||||
- For updates to the Obsidian API run `npm update` in the command line under your repo folder.
|
||||
## Support me
|
||||
|
||||
### Releasing new releases
|
||||
If you find this Plugin helpful, consider supporting me:
|
||||
|
||||
- Update your `manifest.json` with your new version number, such as `1.0.1`, and the minimum Obsidian version required for your latest release.
|
||||
- Update your `versions.json` file with `"new-plugin-version": "minimum-obsidian-version"` so older versions of Obsidian can download an older version of your plugin that's compatible.
|
||||
- Create new GitHub release using your new version number as the "Tag version". Use the exact version number, don't include a prefix `v`. See here for an example: https://github.com/obsidianmd/obsidian-sample-plugin/releases
|
||||
- Upload the files `manifest.json`, `main.js`, `styles.css` as binary attachments.
|
||||
- Publish the release.
|
||||
|
||||
### Adding your plugin to the community plugin list
|
||||
|
||||
- Publish an initial version.
|
||||
- Make sure you have a `README.md` file in the root of your repo.
|
||||
- Make a pull request at https://github.com/obsidianmd/obsidian-releases to add your plugin.
|
||||
|
||||
### How to use
|
||||
|
||||
- Clone this repo.
|
||||
- `npm i` or `yarn` to install dependencies
|
||||
- `npm run dev` to start compilation in watch mode.
|
||||
|
||||
### Manually installing the plugin
|
||||
|
||||
- Copy over `main.js`, `styles.css`, `manifest.json` to your vault `VaultFolder/.obsidian/plugins/your-plugin-id/`.
|
||||
|
||||
### API Documentation
|
||||
|
||||
See https://github.com/obsidianmd/obsidian-api
|
||||
<a href="https://www.buymeacoffee.com/phibr0"><img src="https://img.buymeacoffee.com/button-api/?text=Buy me a coffee&emoji=&slug=phibr0&button_colour=5F7FFF&font_colour=ffffff&font_family=Inter&outline_colour=000000&coffee_colour=FFDD00"></a>
|
||||
|
|
|
|||
112
main.ts
112
main.ts
|
|
@ -1,112 +0,0 @@
|
|||
import { App, Modal, Notice, Plugin, PluginSettingTab, Setting } from 'obsidian';
|
||||
|
||||
interface MyPluginSettings {
|
||||
mySetting: string;
|
||||
}
|
||||
|
||||
const DEFAULT_SETTINGS: MyPluginSettings = {
|
||||
mySetting: 'default'
|
||||
}
|
||||
|
||||
export default class MyPlugin extends Plugin {
|
||||
settings: MyPluginSettings;
|
||||
|
||||
async onload() {
|
||||
console.log('loading plugin');
|
||||
|
||||
await this.loadSettings();
|
||||
|
||||
this.addRibbonIcon('dice', 'Sample Plugin', () => {
|
||||
new Notice('This is a notice!');
|
||||
});
|
||||
|
||||
this.addStatusBarItem().setText('Status Bar Text');
|
||||
|
||||
this.addCommand({
|
||||
id: 'open-sample-modal',
|
||||
name: 'Open Sample Modal',
|
||||
// callback: () => {
|
||||
// console.log('Simple Callback');
|
||||
// },
|
||||
checkCallback: (checking: boolean) => {
|
||||
let leaf = this.app.workspace.activeLeaf;
|
||||
if (leaf) {
|
||||
if (!checking) {
|
||||
new SampleModal(this.app).open();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
});
|
||||
|
||||
this.addSettingTab(new SampleSettingTab(this.app, this));
|
||||
|
||||
this.registerCodeMirror((cm: CodeMirror.Editor) => {
|
||||
console.log('codemirror', cm);
|
||||
});
|
||||
|
||||
this.registerDomEvent(document, 'click', (evt: MouseEvent) => {
|
||||
console.log('click', evt);
|
||||
});
|
||||
|
||||
this.registerInterval(window.setInterval(() => console.log('setInterval'), 5 * 60 * 1000));
|
||||
}
|
||||
|
||||
onunload() {
|
||||
console.log('unloading plugin');
|
||||
}
|
||||
|
||||
async loadSettings() {
|
||||
this.settings = Object.assign({}, DEFAULT_SETTINGS, await this.loadData());
|
||||
}
|
||||
|
||||
async saveSettings() {
|
||||
await this.saveData(this.settings);
|
||||
}
|
||||
}
|
||||
|
||||
class SampleModal extends Modal {
|
||||
constructor(app: App) {
|
||||
super(app);
|
||||
}
|
||||
|
||||
onOpen() {
|
||||
let {contentEl} = this;
|
||||
contentEl.setText('Woah!');
|
||||
}
|
||||
|
||||
onClose() {
|
||||
let {contentEl} = this;
|
||||
contentEl.empty();
|
||||
}
|
||||
}
|
||||
|
||||
class SampleSettingTab extends PluginSettingTab {
|
||||
plugin: MyPlugin;
|
||||
|
||||
constructor(app: App, plugin: MyPlugin) {
|
||||
super(app, plugin);
|
||||
this.plugin = plugin;
|
||||
}
|
||||
|
||||
display(): void {
|
||||
let {containerEl} = this;
|
||||
|
||||
containerEl.empty();
|
||||
|
||||
containerEl.createEl('h2', {text: 'Settings for my awesome plugin.'});
|
||||
|
||||
new Setting(containerEl)
|
||||
.setName('Setting #1')
|
||||
.setDesc('It\'s a secret')
|
||||
.addText(text => text
|
||||
.setPlaceholder('Enter your secret')
|
||||
.setValue('')
|
||||
.onChange(async (value) => {
|
||||
console.log('Secret: ' + value);
|
||||
this.plugin.settings.mySetting = value;
|
||||
await this.plugin.saveSettings();
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
|
@ -1,10 +1,10 @@
|
|||
{
|
||||
"id": "obsidian-sample-plugin",
|
||||
"name": "Sample Plugin",
|
||||
"version": "1.0.1",
|
||||
"minAppVersion": "0.9.12",
|
||||
"description": "This is a sample plugin for Obsidian. This plugin demonstrates some of the capabilities of the Obsidian API.",
|
||||
"author": "Obsidian",
|
||||
"id": "customizable-sidebar",
|
||||
"name": "Customizable Sidebar",
|
||||
"version": "0.0.1",
|
||||
"minAppVersion": "0.12.11",
|
||||
"description": "This Plugin allows to add any Command to Obsidian's Sidebar Ribbon.",
|
||||
"author": "phibr0",
|
||||
"authorUrl": "https://obsidian.md/about",
|
||||
"isDesktopOnly": false
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,10 +14,14 @@
|
|||
"@rollup/plugin-commonjs": "^18.0.0",
|
||||
"@rollup/plugin-node-resolve": "^11.2.1",
|
||||
"@rollup/plugin-typescript": "^8.2.1",
|
||||
"@types/feather-icons": "^4.7.0",
|
||||
"@types/node": "^14.14.37",
|
||||
"obsidian": "^0.12.0",
|
||||
"rollup": "^2.32.1",
|
||||
"tslib": "^2.2.0",
|
||||
"typescript": "^4.2.4"
|
||||
},
|
||||
"dependencies": {
|
||||
"feather-icons": "^4.28.0"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ if you want to view the source visit the plugins github repository
|
|||
`;
|
||||
|
||||
export default {
|
||||
input: 'main.ts',
|
||||
input: 'src/main.ts',
|
||||
output: {
|
||||
dir: '.',
|
||||
sourcemap: 'inline',
|
||||
|
|
|
|||
37
src/main.ts
Normal file
37
src/main.ts
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
import { App, Command, FuzzyMatch, FuzzySuggestModal, Modal, Notice, Plugin, PluginSettingTab, setIcon, Setting } from 'obsidian';
|
||||
import { addFeatherIcons } from './ui/icons';
|
||||
import CustomSidebarSettingsTab, { CustomSidebarSettings, DEFAULT_SETTINGS } from './ui/settingsTab';
|
||||
|
||||
export default class CustomSidebarPlugin extends Plugin {
|
||||
settings: CustomSidebarSettings;
|
||||
iconList: string[] = ["any-key", "audio-file", "blocks", "bold-glyph", "bracket-glyph", "broken-link", "bullet-list", "bullet-list-glyph", "calendar-with-checkmark", "check-in-circle", "check-small", "checkbox-glyph", "checkmark", "clock", "cloud", "code-glyph", "create-new", "cross", "cross-in-box", "crossed-star", "csv", "deleteColumn", "deleteRow", "dice", "document", "documents", "dot-network", "double-down-arrow-glyph", "double-up-arrow-glyph", "down-arrow-with-tail", "down-chevron-glyph", "enter", "exit-fullscreen", "expand-vertically", "filled-pin", "folder", "formula", "forward-arrow", "fullscreen", "gear", "go-to-file", "hashtag", "heading-glyph", "help", "highlight-glyph", "horizontal-split", "image-file", "image-glyph", "indent-glyph", "info", "insertColumn", "insertRow", "install", "italic-glyph", "keyboard-glyph", "languages", "left-arrow", "left-arrow-with-tail", "left-chevron-glyph", "lines-of-text", "link", "link-glyph", "logo-crystal", "magnifying-glass", "microphone", "microphone-filled", "minus-with-circle", "moveColumnLeft", "moveColumnRight", "moveRowDown", "moveRowUp", "note-glyph", "number-list-glyph", "open-vault", "pane-layout", "paper-plane", "paused", "pdf-file", "pencil", "percent-sign-glyph", "pin", "plus-with-circle", "popup-open", "presentation", "price-tag-glyph", "quote-glyph", "redo-glyph", "reset", "right-arrow", "right-arrow-with-tail", "right-chevron-glyph", "right-triangle", "run-command", "search", "sheets-in-box", "sortAsc", "sortDesc", "spreadsheet", "stacked-levels", "star", "star-list", "strikethrough-glyph", "switch", "sync", "sync-small", "tag-glyph", "three-horizontal-bars", "trash", "undo-glyph", "unindent-glyph", "up-and-down-arrows", "up-arrow-with-tail", "up-chevron-glyph", "uppercase-lowercase-a", "vault", "vertical-split", "vertical-three-dots", "wrench-screwdriver-glyph"];
|
||||
|
||||
async onload() {
|
||||
console.log('loading plugin');
|
||||
|
||||
await this.loadSettings();
|
||||
|
||||
this.addSettingTab(new CustomSidebarSettingsTab(this.app, this));
|
||||
|
||||
addFeatherIcons(this.iconList);
|
||||
|
||||
this.settings.sidebarCommands.forEach(c => {
|
||||
this.addRibbonIcon(c.icon, c.name, () => {
|
||||
//@ts-ignore
|
||||
this.app.commands.executeCommandById(this.command.id);
|
||||
});
|
||||
})
|
||||
}
|
||||
|
||||
onunload() {
|
||||
console.log('unloading plugin');
|
||||
}
|
||||
|
||||
async loadSettings() {
|
||||
this.settings = Object.assign({}, DEFAULT_SETTINGS, await this.loadData());
|
||||
}
|
||||
|
||||
async saveSettings() {
|
||||
await this.saveData(this.settings);
|
||||
}
|
||||
}
|
||||
36
src/ui/commandSuggester.ts
Normal file
36
src/ui/commandSuggester.ts
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
import { FuzzySuggestModal, Command } from "obsidian";
|
||||
import CustomSidebarPlugin from "src/main";
|
||||
import IconPicker from "./iconPicker";
|
||||
|
||||
export default class CommandSuggester extends FuzzySuggestModal<Command> {
|
||||
|
||||
constructor(private plugin: CustomSidebarPlugin) {
|
||||
super(plugin.app);
|
||||
}
|
||||
|
||||
getItems(): Command[] {
|
||||
//@ts-ignore
|
||||
return this.app.commands.listCommands();
|
||||
}
|
||||
|
||||
getItemText(item: Command): string {
|
||||
return item.name;
|
||||
}
|
||||
|
||||
async onChooseItem(item: Command, evt: MouseEvent | KeyboardEvent): Promise<void> {
|
||||
if (item.icon) {
|
||||
this.plugin.addRibbonIcon(item.icon ?? "", item.name, () => {
|
||||
//@ts-ignore
|
||||
this.app.commands.executeCommandById(item.id);
|
||||
})
|
||||
this.plugin.settings.sidebarCommands.push(item);
|
||||
await this.plugin.saveSettings();
|
||||
setTimeout(() => {
|
||||
dispatchEvent(new Event("CS-addedCommand"));
|
||||
}, 100);
|
||||
} else {
|
||||
new IconPicker(this.plugin, item).open()
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
52
src/ui/iconPicker.ts
Normal file
52
src/ui/iconPicker.ts
Normal file
|
|
@ -0,0 +1,52 @@
|
|||
import { FuzzySuggestModal, Command, FuzzyMatch, setIcon } from "obsidian";
|
||||
import CustomSidebarPlugin from "src/main";
|
||||
|
||||
export default class IconPicker extends FuzzySuggestModal<string>{
|
||||
plugin: CustomSidebarPlugin;
|
||||
command: Command;
|
||||
|
||||
constructor(plugin: CustomSidebarPlugin, command: Command) {
|
||||
super(plugin.app);
|
||||
this.plugin = plugin;
|
||||
this.command = command;
|
||||
this.setPlaceholder("Pick an Icon");
|
||||
}
|
||||
|
||||
private cap(string: string): string {
|
||||
const words = string.split(" ");
|
||||
|
||||
return words.map((word) => {
|
||||
return word[0].toUpperCase() + word.substring(1);
|
||||
}).join(" ");
|
||||
}
|
||||
|
||||
getItems(): string[] {
|
||||
return this.plugin.iconList;
|
||||
}
|
||||
|
||||
getItemText(item: string): string {
|
||||
return this.cap(item.replace("feather-", "").replace(/-/ig, " "));
|
||||
}
|
||||
|
||||
renderSuggestion(item: FuzzyMatch<string>, el: HTMLElement): void {
|
||||
el.addClass("CS-icon-container");
|
||||
const div = createDiv({ cls: "CS-icon" });
|
||||
el.appendChild(div);
|
||||
setIcon(div, item.item);
|
||||
super.renderSuggestion(item, el);
|
||||
}
|
||||
|
||||
async onChooseItem(item: string): Promise<void> {
|
||||
this.plugin.addRibbonIcon(item, this.command.name, () => {
|
||||
//@ts-ignore
|
||||
this.app.commands.executeCommandById(this.command.id);
|
||||
})
|
||||
this.command.icon = item;
|
||||
this.plugin.settings.sidebarCommands.push(this.command);
|
||||
await this.plugin.saveSettings();
|
||||
setTimeout(() => {
|
||||
dispatchEvent(new Event("CS-addedCommand"));
|
||||
}, 100);
|
||||
}
|
||||
|
||||
}
|
||||
11
src/ui/icons.ts
Normal file
11
src/ui/icons.ts
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
import * as feather from "feather-icons";
|
||||
import { addIcon } from "obsidian";
|
||||
|
||||
export function addFeatherIcons(iconList: string[]) {
|
||||
Object.values(feather.icons).forEach((i) => {
|
||||
const svg = i.toSvg({viewBox: "0 0 24 24", width: "100", height: "100"});
|
||||
//Remove the svg tag: svg.match(/(?<=>).*(?=<\/svg>)/).first()
|
||||
addIcon("feather-" + i.name, svg);
|
||||
iconList.push("feather-" + i.name);
|
||||
});
|
||||
}
|
||||
70
src/ui/settingsTab.ts
Normal file
70
src/ui/settingsTab.ts
Normal file
|
|
@ -0,0 +1,70 @@
|
|||
import { PluginSettingTab, App, Setting, setIcon, Command, Notice } from "obsidian";
|
||||
import CustomSidebarPlugin from "src/main";
|
||||
import CommandSuggester from "./commandSuggester";
|
||||
|
||||
export interface CustomSidebarSettings {
|
||||
sidebarCommands: Command[];
|
||||
}
|
||||
|
||||
export const DEFAULT_SETTINGS: CustomSidebarSettings = {
|
||||
sidebarCommands: [],
|
||||
}
|
||||
|
||||
export default class CustomSidebarSettingsTab extends PluginSettingTab {
|
||||
plugin: CustomSidebarPlugin;
|
||||
|
||||
constructor(app: App, plugin: CustomSidebarPlugin) {
|
||||
super(app, plugin);
|
||||
this.plugin = plugin;
|
||||
addEventListener("CS-addedCommand", () => {
|
||||
this.display();
|
||||
});
|
||||
}
|
||||
|
||||
display(): void {
|
||||
let { containerEl } = this;
|
||||
|
||||
containerEl.empty();
|
||||
|
||||
containerEl.createEl('h2', { text: 'Customizable Sidebar Settings' });
|
||||
|
||||
new Setting(containerEl)
|
||||
.setName("Add Command to Sidebar")
|
||||
.setDesc("Add a new Command to the left Sidebar Ribbon")
|
||||
.addButton((bt) => {
|
||||
bt.setButtonText("Add Command")
|
||||
.onClick(() => {
|
||||
new CommandSuggester(this.plugin).open();
|
||||
});
|
||||
});
|
||||
|
||||
this.plugin.settings.sidebarCommands.forEach(c => {
|
||||
const iconDiv = createDiv({ cls: "CS-settings-icon" });
|
||||
setIcon(iconDiv, c.icon, 20);
|
||||
const setting = new Setting(containerEl)
|
||||
.setName(c.name)
|
||||
.addButton(bt => {
|
||||
bt.setButtonText("Remove Command")
|
||||
.onClick(async () => {
|
||||
this.plugin.settings.sidebarCommands.remove(c);
|
||||
await this.plugin.saveSettings();
|
||||
this.display();
|
||||
new Notice("You will need to restart Obsidian for the Command to dissapear.")
|
||||
})
|
||||
});
|
||||
setting.nameEl.prepend(iconDiv);
|
||||
setting.nameEl.addClass("CS-flex");
|
||||
})
|
||||
|
||||
new Setting(containerEl)
|
||||
.setName('Donate')
|
||||
.setDesc('If you like this Plugin, consider donating to support continued development:')
|
||||
.setClass("AT-extra")
|
||||
.addButton((bt) => {
|
||||
bt.buttonEl.outerHTML = `<a href="https://www.buymeacoffee.com/phibr0"><img src="https://img.buymeacoffee.com/button-api/?text=Buy me a coffee&emoji=&slug=phibr0&button_colour=5F7FFF&font_colour=ffffff&font_family=Inter&outline_colour=000000&coffee_colour=FFDD00"></a>`;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
29
styles.css
29
styles.css
|
|
@ -1,4 +1,27 @@
|
|||
/* Sets all the text color to red! */
|
||||
body {
|
||||
color: red;
|
||||
/*Icon Picker*/
|
||||
.CS-icon {
|
||||
transform: translateY(3px);
|
||||
margin-right: 8px;
|
||||
}
|
||||
|
||||
.CS-icon-container{
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.CS-settings-icon {
|
||||
height: 20px;
|
||||
margin-right: 0.5rem;
|
||||
transform: translateY(2px);
|
||||
}
|
||||
|
||||
.CS-flex {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
a[href="https://www.buymeacoffee.com/phibr0"] > img {
|
||||
height: 2.2em;
|
||||
}
|
||||
|
||||
a[href="https://www.buymeacoffee.com/phibr0"]{
|
||||
transform: translate(0, 5%);
|
||||
}
|
||||
|
|
@ -1,4 +1 @@
|
|||
{
|
||||
"1.0.1": "0.9.12",
|
||||
"1.0.0": "0.9.7"
|
||||
}
|
||||
{}
|
||||
Loading…
Reference in a new issue