mirror of
https://github.com/devonthesofa/obsidian-note-status.git
synced 2026-07-22 05:45:04 +00:00
feat: make status bar badges reactive and add content modes
This commit is contained in:
parent
5ddecab6ee
commit
6c4dcbc293
9 changed files with 77 additions and 5 deletions
|
|
@ -95,6 +95,29 @@ export const UISettings: React.FC<Props> = ({ settings, onChange }) => {
|
|||
/>
|
||||
</SettingItem>
|
||||
|
||||
<SettingItem
|
||||
name="Status bar badge content"
|
||||
description="Choose whether the badge shows icon, text, both, or an empty accent."
|
||||
>
|
||||
<Select
|
||||
options={[
|
||||
{
|
||||
value: "icon-text",
|
||||
display: "Icon + text (default)",
|
||||
},
|
||||
{ value: "icon", display: "Icon only" },
|
||||
{ value: "text", display: "Text only" },
|
||||
{ value: "none", display: "Empty badge (accent only)" },
|
||||
]}
|
||||
defaultValue={
|
||||
settings.statusBarBadgeContentMode || "icon-text"
|
||||
}
|
||||
onChange={(value) =>
|
||||
onChange("statusBarBadgeContentMode", value)
|
||||
}
|
||||
/>
|
||||
</SettingItem>
|
||||
|
||||
<h4>No Status Display</h4>
|
||||
|
||||
<SettingItem
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ export type Props = {
|
|||
onStatusClick: StatusBarContextProps["onStatusClick"];
|
||||
templateNameMode?: "always" | "never" | "auto";
|
||||
badgeStyle?: "accent" | "filled" | "dot";
|
||||
badgeContentMode?: "icon-text" | "icon" | "text" | "none";
|
||||
noStatusConfig?: {
|
||||
text: string;
|
||||
showIcon: boolean;
|
||||
|
|
@ -30,6 +31,7 @@ export const StatusBar: FC<Props> = ({
|
|||
onStatusClick,
|
||||
templateNameMode = "auto",
|
||||
badgeStyle = "accent",
|
||||
badgeContentMode = "icon-text",
|
||||
noStatusConfig,
|
||||
}) => {
|
||||
const statusEntries = Object.entries(statuses);
|
||||
|
|
@ -83,6 +85,7 @@ export const StatusBar: FC<Props> = ({
|
|||
statuses={statusList}
|
||||
templateNameMode={templateNameMode}
|
||||
badgeStyle={badgeStyle}
|
||||
badgeContentMode={badgeContentMode}
|
||||
template={{
|
||||
description: "Note status",
|
||||
name: "",
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@ export interface StatusBarGroupProps {
|
|||
maxVisible?: number;
|
||||
templateNameMode?: "always" | "never" | "auto";
|
||||
badgeStyle?: "accent" | "filled" | "dot";
|
||||
badgeContentMode?: "icon-text" | "icon" | "text" | "none";
|
||||
}
|
||||
|
||||
export const StatusBarGroup: FC<StatusBarGroupProps> = ({
|
||||
|
|
@ -20,6 +21,7 @@ export const StatusBarGroup: FC<StatusBarGroupProps> = ({
|
|||
maxVisible = 3,
|
||||
templateNameMode = "auto",
|
||||
badgeStyle = "accent",
|
||||
badgeContentMode = "icon-text",
|
||||
}) => {
|
||||
const [isUncollapsed, setIsUncollapsed] = useState(false);
|
||||
const visibleStatuses = isUncollapsed
|
||||
|
|
@ -55,6 +57,7 @@ export const StatusBarGroup: FC<StatusBarGroupProps> = ({
|
|||
status={status}
|
||||
variant="badge"
|
||||
badgeStyle={badgeStyle}
|
||||
badgeContentMode={badgeContentMode}
|
||||
templateNameMode={templateNameMode}
|
||||
hasNameConflicts={getHasConflicts(status)}
|
||||
onClick={() => {
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ interface StatusDisplayProps {
|
|||
status: NoteStatus;
|
||||
variant: StatusDisplayVariant;
|
||||
badgeStyle?: "accent" | "filled" | "dot";
|
||||
badgeContentMode?: "icon-text" | "icon" | "text" | "none";
|
||||
removable?: boolean;
|
||||
hasNameConflicts?: boolean;
|
||||
templateNameMode?: "always" | "never" | "auto";
|
||||
|
|
@ -32,6 +33,7 @@ export const StatusDisplay: FC<StatusDisplayProps> = memo(
|
|||
variant,
|
||||
removable = false,
|
||||
badgeStyle = "accent",
|
||||
badgeContentMode = "icon-text",
|
||||
hasNameConflicts = false,
|
||||
templateNameMode = "auto",
|
||||
icon,
|
||||
|
|
@ -132,10 +134,16 @@ export const StatusDisplay: FC<StatusDisplayProps> = memo(
|
|||
"status-badge-container",
|
||||
`status-badge--${badgeStyle}`,
|
||||
onClick ? "status-badge-container--clickable" : "",
|
||||
badgeContentMode === "none" ? "status-badge--empty" : "",
|
||||
]
|
||||
.filter(Boolean)
|
||||
.join(" ");
|
||||
const showDot = badgeStyle === "dot";
|
||||
const showIcon =
|
||||
badgeContentMode === "icon-text" || badgeContentMode === "icon";
|
||||
const showText =
|
||||
badgeContentMode === "icon-text" || badgeContentMode === "text";
|
||||
const isEmptyBadge = badgeContentMode === "none";
|
||||
|
||||
return (
|
||||
<div
|
||||
|
|
@ -143,15 +151,28 @@ export const StatusDisplay: FC<StatusDisplayProps> = memo(
|
|||
style={badgeStyleVars}
|
||||
onClick={handleClick}
|
||||
data-clickable={!!onClick}
|
||||
title={getStatusTooltip(status)}
|
||||
>
|
||||
{showDot && (
|
||||
<span className="status-badge-dot" aria-hidden="true" />
|
||||
)}
|
||||
<div className="status-badge-item">
|
||||
<span className="status-badge-icon">{iconNode}</span>
|
||||
<span className="status-badge-text">
|
||||
{getDisplayName()}
|
||||
</span>
|
||||
{showIcon && (
|
||||
<span className="status-badge-icon">
|
||||
{iconNode}
|
||||
</span>
|
||||
)}
|
||||
{showText && (
|
||||
<span className="status-badge-text">
|
||||
{getDisplayName()}
|
||||
</span>
|
||||
)}
|
||||
{isEmptyBadge && (
|
||||
<span
|
||||
className="status-badge-empty"
|
||||
aria-hidden="true"
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
|
|
|||
|
|
@ -46,6 +46,7 @@ export const DEFAULT_PLUGIN_SETTINGS: PluginSettings = {
|
|||
statusBarShowNoStatusIcon: false,
|
||||
statusBarShowNoStatusText: true,
|
||||
statusBarBadgeStyle: "accent",
|
||||
statusBarBadgeContentMode: "icon-text",
|
||||
vaultSizeLimit: 15000, // Disable dashboard and grouped view for vaults with more notes than this limit
|
||||
// Editor toolbar button settings
|
||||
showEditorToolbarButton: true, // Default to show the toolbar button
|
||||
|
|
|
|||
|
|
@ -38,6 +38,12 @@ export class StatusBarIntegration {
|
|||
if (key === "statusBarShowTemplateName") {
|
||||
this.render(); // INFO: Force a render to set disabled or enabled
|
||||
}
|
||||
if (
|
||||
key === "statusBarBadgeStyle" ||
|
||||
key === "statusBarBadgeContentMode"
|
||||
) {
|
||||
this.render();
|
||||
}
|
||||
if (key === "enabledTemplates" || key === "templates") {
|
||||
this.handleActiveFileChange().catch(console.error); // INFO: Force a re-read of the statuses and render
|
||||
}
|
||||
|
|
@ -155,6 +161,9 @@ export class StatusBarIntegration {
|
|||
settingsService.settings.statusBarShowTemplateName
|
||||
}
|
||||
badgeStyle={settingsService.settings.statusBarBadgeStyle}
|
||||
badgeContentMode={
|
||||
settingsService.settings.statusBarBadgeContentMode
|
||||
}
|
||||
onStatusClick={() => this.openStatusModal()}
|
||||
noStatusConfig={this.getNoStatusConfig()}
|
||||
/>,
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
|
|
@ -155,6 +155,11 @@
|
|||
box-shadow: 0 0 0 1px var(--background-primary);
|
||||
}
|
||||
|
||||
.status-badge--empty {
|
||||
min-width: 32px;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.status-badge-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
|
@ -172,6 +177,12 @@
|
|||
font-size: var(--font-ui-small);
|
||||
}
|
||||
|
||||
.status-badge-empty {
|
||||
display: inline-block;
|
||||
min-width: var(--size-3-2);
|
||||
height: var(--size-3-2);
|
||||
}
|
||||
|
||||
/* Template variant */
|
||||
.template-status-chip {
|
||||
display: inline-flex;
|
||||
|
|
|
|||
|
|
@ -37,6 +37,7 @@ export type PluginSettings = {
|
|||
customStatuses: NoteStatus[];
|
||||
statusBarShowTemplateName: "always" | "never" | "auto"; // How to show template names in status bar
|
||||
statusBarBadgeStyle: "accent" | "filled" | "dot";
|
||||
statusBarBadgeContentMode: "icon-text" | "icon" | "text" | "none";
|
||||
showStatusIconsInExplorer: boolean;
|
||||
hideUnknownStatusInExplorer: boolean;
|
||||
fileExplorerColorFileName: boolean; // Whether to color the file explorer filename text using the current status color
|
||||
|
|
|
|||
Loading…
Reference in a new issue