mirror of
https://github.com/devonthesofa/obsidian-note-status.git
synced 2026-07-22 12:30:24 +00:00
79 lines
2.4 KiB
TypeScript
79 lines
2.4 KiB
TypeScript
import { CSSProperties, FC, useState } from "react";
|
|
import { NoteStatus } from "@/types/noteStatus";
|
|
import { StatusTemplate } from "@/types/pluginSettings";
|
|
import { GroupLabel } from "../atoms/GroupLabel";
|
|
import { CollapsibleCounter } from "../atoms/CollapsibleCounter";
|
|
import { StatusDisplay } from "../atoms/StatusDisplay";
|
|
import { useStatusBarContext } from "./StatusBarContext";
|
|
|
|
export interface StatusBarGroupProps {
|
|
statuses: NoteStatus[];
|
|
template: StatusTemplate;
|
|
maxVisible?: number;
|
|
templateNameMode?: "always" | "never" | "auto";
|
|
badgeStyle?: "accent" | "filled" | "dot";
|
|
badgeContentMode?: "icon-text" | "icon" | "text" | "none";
|
|
}
|
|
|
|
export const StatusBarGroup: FC<StatusBarGroupProps> = ({
|
|
statuses,
|
|
template,
|
|
maxVisible = 3,
|
|
templateNameMode = "auto",
|
|
badgeStyle = "accent",
|
|
badgeContentMode = "icon-text",
|
|
}) => {
|
|
const [isUncollapsed, setIsUncollapsed] = useState(false);
|
|
const visibleStatuses = isUncollapsed
|
|
? statuses
|
|
: statuses.slice(0, maxVisible);
|
|
const hiddenCount = Math.max(0, statuses.length - maxVisible);
|
|
|
|
const statusNames = statuses.map((s) => s.name);
|
|
const getHasConflicts = (status: NoteStatus) => {
|
|
return statusNames.filter((name) => name === status.name).length > 1;
|
|
};
|
|
const { onStatusClick } = useStatusBarContext();
|
|
|
|
return (
|
|
<>
|
|
<GroupLabel name={template.name} isHighlighted={isUncollapsed} />
|
|
<div className="status-bar-group-container">
|
|
{visibleStatuses.map((status, i) => (
|
|
// Use a wrapper so we can animate statuses when expanding
|
|
<div
|
|
key={i}
|
|
className={`status-bar-status-item${isUncollapsed && i >= maxVisible ? " status-bar-status-item--animated" : ""}`}
|
|
style={
|
|
isUncollapsed && i >= maxVisible
|
|
? ({
|
|
"--status-anim-delay": `${i * 0.05}s`,
|
|
} as CSSProperties)
|
|
: undefined
|
|
}
|
|
title={status.description}
|
|
>
|
|
<StatusDisplay
|
|
status={status}
|
|
variant="badge"
|
|
badgeStyle={badgeStyle}
|
|
badgeContentMode={badgeContentMode}
|
|
templateNameMode={templateNameMode}
|
|
hasNameConflicts={getHasConflicts(status)}
|
|
onClick={() => {
|
|
onStatusClick(status);
|
|
}}
|
|
/>
|
|
</div>
|
|
))}
|
|
{hiddenCount > 0 && (
|
|
<CollapsibleCounter
|
|
count={hiddenCount}
|
|
isCollapsed={!isUncollapsed}
|
|
onToggle={() => setIsUncollapsed(!isUncollapsed)}
|
|
/>
|
|
)}
|
|
</div>
|
|
</>
|
|
);
|
|
};
|