devonthesofa_obsidian-note-.../components/StatusBar/StatusBarGroup.tsx

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>
</>
);
};