diff --git a/package.json b/package.json index b732501..d184515 100644 --- a/package.json +++ b/package.json @@ -20,6 +20,7 @@ "@codemirror/view": "^6.34.0", "@lezer/common": "^1.2.1", "@types/node": "^22.13.1", + "@types/sortablejs": "^1.15.8", "@typescript-eslint/eslint-plugin": "^8.23.0", "@typescript-eslint/parser": "^8.23.0", "builtin-modules": "^4.0.0", @@ -35,10 +36,12 @@ "redirecter": "^0.0.1", "rollup": "^4.34.1", "tslib": "^2.8.1", - "typescript": "^5.7.3" + "typescript": "^5.7.3", + "sortablejs": "^1.15.6" }, "devDependencies": { "@types/node": "^22.13.1", + "@types/sortablejs": "^1.15.8", "@typescript-eslint/eslint-plugin": "^8.23.0", "@typescript-eslint/parser": "^8.23.0", "builtin-modules": "^4.0.0", @@ -46,6 +49,7 @@ "obsidian": "latest", "obsidian-typings": "^2.2.0", "tslib": "2.8.1", - "typescript": "5.7.3" + "typescript": "5.7.3", + "sortablejs": "^1.15.6" } } \ No newline at end of file diff --git a/src/settings/interface/ExtendedSettingTab.ts b/src/settings/interface/ExtendedSettingTab.ts index 35f29b8..7f295f6 100644 --- a/src/settings/interface/ExtendedSettingTab.ts +++ b/src/settings/interface/ExtendedSettingTab.ts @@ -32,6 +32,7 @@ export class ExtendedSettingTab extends PluginSettingTab { containerEl.empty(); let settingsUIConfig = retrieveSettingUIConfigs(settings); this.drawFromConfig(settingsUIConfig, containerEl); + this.isHidden = false; } hide(): void { if (this.refreshInternal) { @@ -42,6 +43,7 @@ export class ExtendedSettingTab extends PluginSettingTab { } this.refreshInternal = this.rebuildColorStyleRules = false; this.colorSettingItems.splice(0); + this.isHidden = true; super.hide(); } removeSetting(setting: Setting) { @@ -131,12 +133,29 @@ export class ExtendedSettingTab extends PluginSettingTab { if (collapsible) { controlSetting.setClass("is-collapsible"); } + this.makeDragable(groupEl, evt => { + let oldIndex = evt.oldDraggableIndex, + newIndex = evt.newDraggableIndex, + colorConfigs = this.plugin.settings.colorConfigs; + if (this.isHidden || oldIndex === undefined || newIndex === undefined || oldIndex == newIndex) { return } + colorConfigs.splice( + Math.min(oldIndex, newIndex), + 0, + ...colorConfigs.splice(Math.max(oldIndex, newIndex), 1) + ); + this.plugin.colorsHandler.moveRule(oldIndex, newIndex); + }); } - setColorItem(config: ColorConfig, configArr: ColorConfig[], containerEl: HTMLElement) { + setColorItem(config: ColorConfig, configs: ColorConfig[], containerEl: HTMLElement) { if (/[^a-z0-9-]/i.test(config.tag)) { config.tag = config.tag.replaceAll(/[^a-z0-9-]/ig, "") } let colorSetting = new Setting(containerEl) .setClass("ems-setting-item") .setClass("ems-highlight-color-config") + .addExtraButton(btn => { + btn.extraSettingsEl.addClasses(["ems-button", "ems-button-drag-handle"]); + btn.setIcon("grip-vertical"); + btn.setTooltip("Hold and drag to move", { placement: "left" }); + }) .addText(text => { text.setPlaceholder("Color name"); text.setValue(config.name); @@ -297,4 +316,16 @@ export class ExtendedSettingTab extends PluginSettingTab { }); }); } + makeDragable(groupEl: HTMLElement, onEnd: (evt: SortableEvent) => unknown) { + Sortable.create(groupEl, { + handle: ".ems-button-drag-handle", + animation: 200, + easing: "cubic-bezier(0.2, 0, 0, 1)", + forceFallback: true, + fallbackOnBody: true, + fallbackClass: "ems-setting-item-dragged", + fallbackTolerance: 4, + onEnd: onEnd, + }); + } } \ No newline at end of file diff --git a/tsconfig.json b/tsconfig.json index 2cbfd14..384f127 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -11,6 +11,7 @@ "importHelpers": true, "isolatedModules": true, "strictNullChecks": true, + "esModuleInterop": true, "types": ["obsidian-typings"], "lib": [ "DOM",