Hi, I found a possible issue with the declarative settings API introduced in Obsidian 1.13.
When using PluginSettingTab.getSettingDefinitions() with a dynamic SettingDefinitionGroup, custom CSS classes assigned in a render callback may persist when Obsidian reuses a Setting row after the definitions are rebuilt.
Minimal reproduction:
-
Create a dynamic group with a list of custom rows.
-
In each list row, assign a custom class inside render:
render: (setting) => {
setting.setClass("custom-list-row");
// Render the row contents
}
- Add a new item to the list and call:
this.update();
- Delete the newly added item and call
this.update()again.
In my case, the separate “Add item” row was reused from a previous list row. It retained the previous row’s classes, such as:
custom-list-row mod-toggle
This caused the Add button row to inherit the list-row CSS layout and changed its appearance/alignment.
The issue seems to be that the framework reuses the existing Setting DOM element, but does not remove custom classes assigned by a previous render callback before rendering the element again.
As a workaround, I currently remove the possible stale classes explicitly in the Add button row’s render callback:
render: (setting) => {
setting.settingEl.removeClass(
"custom-list-row",
"custom-other-row",
"mod-toggle",
);
setting.addButton((button) => {
// ...
});
}
Could the declarative settings renderer either:
- clear custom classes from a reused Setting row before invoking render, or
- provide a documented cleanup/reset mechanism for classes added through setting.setClass()?
This was observed with getSettingDefinitions(), dynamic groups, render callbacks, and this.update() after adding/removing items.
Recording
(video not allowed, so I transform it to a gif)
