mirror of
https://github.com/logancyang/obsidian-copilot.git
synced 2026-07-22 07:50:24 +00:00
* feat(agent-home): brand icon, rotating greeting, and collapsible landing sections - Add CopilotBrandIcon (inline brand SVG) beside the landing title; new ui-title font token sizes the heading off the Obsidian UI font, and register text-ui-title in the tailwind-merge font-size group so cn() dedupes it. - Rotate the landing title through a curated greeting pool (landingGreetings), re-rolled per session so each new chat opens with a fresh line. - Make AgentHomeSection collapsible (local state, chevron toggle, keyboard support, aria-controls). The disclosure and the header action sit as siblings to avoid nesting interactive controls, and the body's children unmount on collapse so an open "View all" popover tears down with it. Enable on Projects and Recent Chats. - Resolve the landing subtitle's mode label through getModeLabel so it matches the ModePicker trigger (default -> Safe) from one source. * fix(agent-home): keep landing scrollable on very short panes The landing column was overflow-hidden, so a pane too short to fit the status/title/composer stack clipped them with no way to scroll back (small Obsidian splits / popouts). Restore overflow-y-auto on the landing branch: the flex spacers still fill the column when there's room (no scrollbar), and the column scrolls only when the fixed elements genuinely overflow. * fix(agent-home): resolve UI font token across themes Obsidian's stock 20px UI token is --font-ui-larger, but some themes (e.g. Primary) define --font-ui-large instead and omit the stock one. Chain both for ui-larger/ui-title with a literal 20px floor, so the landing title renders at the intended size under either convention instead of dropping to inherited sizing when one var is missing. * feat(agent-home): polish landing — colored project tiles, uppercase section headers, tighter spacing - Section headers (Projects / Recent Chats): uppercase + tracking, drop the parens around the count, remove the leading section icon (keep the collapse chevron) since rows now carry their own leading marks. - Project rows: stable per-id colored folder tile (tinted square + solid-hue folder) via new theme-aware `text/bg.project.*` tailwind tokens; hashed from the project id so the color is fixed per project. - Landing: drop the redundant backend/mode subtitle (the composer pills already show it); retune spacing (heading→input, input→projects, between sections). - Add-context "+" button: drop the border, bare glyph. - "View all" project/chat links now use the theme accent color. * docs(agent-home): refresh AgentHome section comments after icon removal Drop stale references to the removed section icon in AgentHomeSection's doc comments (section no longer supplies a type icon; rows carry their own leading mark via `leading`/`icon`), and clarify the Recent Chats "View all" trigger's pl-6 vs the Projects list's pl-8 alignment. * refactor(agent-home): render brand icon from shared glyph data Replace the dangerouslySetInnerHTML injection in CopilotBrandIcon with plain JSX. Extract the glyph transform and path into COPILOT_AGENT_ICON_TRANSFORM and COPILOT_AGENT_ICON_PATH constants; the addIcon string is now built from the same primitives, so the React surface and the native Obsidian icon share one source of truth and cannot drift. * fix(agent-home): drop redundant count from "View all" links The section header already shows the total (PROJECTS 10 / RECENT CHATS 582), so repeating it in the "View all projects (N)" / "View all chats (N)" trigger was duplicated. Trim both to "View all projects" / "View all chats". * feat(agent-home): chip shelf landing — collapse sections into a covering panel Replace the two always-open landing sections with a Claude-style chip shelf: - Collapsed, Projects / Recent Chats are a centered row of pill chips (icon + title + count), built on the shared Button. - Opening a chip *covers* the row with that section's panel — a titled card (icon + title + close ✕) over the section body; only one is ever open. - Click anywhere outside the open panel collapses it (bound to the panel's ownerDocument for popout windows; Radix "View all" popovers are exempt). - Projects' "New project" action moves to the panel's top-right, under the ✕. AgentHomeSection loses its header component (title/count/collapse now live in the chip); ProjectPickerList / GlobalRecentChatsSection render plain panel bodies and keep the colored tiles, accent "View all", and count-free trigger. * feat(agent-home): segmented-tab shelf, aligned rows, top-anchored composer Turn the landing's Projects / Recent Chats into a persistent segmented-tab card and polish the surrounding composer behaviour: - Rename AgentHomeChip -> AgentHomeTab. Tabs use the ghost2 Button variant so Obsidian's native button chrome doesn't bleed through; selection is shown by background fill only (no border/shadow). - Shelf card: one outer border + rounded-md. The panel is the scroll container via a min-h-0 chain, so on a short pane the card caps to the available height and its list scrolls internally while the tab bar stays pinned, instead of being clipped out of reach. An inner min-h reserves a consistent height across tabs. - Recent-chat rows get a size-6 neutral icon tile matching the project tiles, so the leading slot is the same width and labels line up when switching tabs. - Landing composer is top-anchored: a fixed-fraction (h-1/4) top spacer that doesn't absorb the composer's height changes, plus a flex-1 shelf region that does. Removing the active-note context chip now collapses the composer's lower half and the shelf upward, keeping the greeting fixed, instead of re-centering and dropping the top. The conversation state is unchanged (composer stays docked at the bottom). * docs(agent-home): drop PR1 milestone label from project-sort DESIGN NOTE Codex flagged the (PR1) reference as a STYLE_GUIDE violation (no milestone/plan-step refs in code). State the read-only invariant directly instead. Pre-existing PR1 refs from the merged PR1 are baseline and left untouched.
277 lines
10 KiB
JavaScript
277 lines
10 KiB
JavaScript
// tailwind.config.js
|
|
|
|
import { colorOpacityPlugin } from "./src/lib/plugins/colorOpacityPlugin";
|
|
import colors from "tailwindcss/colors";
|
|
import containerQueries from "@tailwindcss/container-queries";
|
|
|
|
/** @type {import("tailwindcss").Config} */
|
|
module.exports = {
|
|
prefix: "tw-",
|
|
content: ["./src/**/*.{js,ts,jsx,tsx}", "./src/styles/tailwind.css"],
|
|
darkMode: ["class"],
|
|
// tailwindcss-animate doesn't work with linter when using import statement.
|
|
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
plugins: [require("tailwindcss-animate"), colorOpacityPlugin, containerQueries],
|
|
corePlugins: {
|
|
preflight: false,
|
|
},
|
|
// https://github.com/tailwindlabs/tailwindcss/blob/main/stubs/config.full.js
|
|
theme: {
|
|
textColor: {
|
|
inherit: colors.inherit,
|
|
current: colors.current,
|
|
transparent: colors.transparent,
|
|
normal: "var(--text-normal)",
|
|
muted: "var(--text-muted)",
|
|
faint: "var(--text-faint)",
|
|
"on-accent": "var(--text-on-accent)",
|
|
"on-accent-inverted": "var(--text-on-accent-inverted)",
|
|
success: "var(--text-success)",
|
|
warning: "var(--text-warning)",
|
|
loading: "var(--color-blue)",
|
|
error: "var(--text-error)",
|
|
accent: "var(--text-accent)",
|
|
"accent-hover": "var(--text-accent-hover)",
|
|
selection: "var(--text-selection)",
|
|
"highlight-bg": "var(--text-highlight-bg)",
|
|
callout: {
|
|
warning: "rgba(var(--callout-warning),<alpha-value>)",
|
|
},
|
|
"model-capabilities": {
|
|
green: "var(--color-green)",
|
|
blue: "var(--color-blue)",
|
|
},
|
|
"context-manager": {
|
|
blue: "var(--color-blue)",
|
|
green: "var(--color-green)",
|
|
red: "var(--color-red)",
|
|
yellow: "var(--color-yellow)",
|
|
orange: "var(--color-orange)",
|
|
purple: "var(--color-purple)",
|
|
},
|
|
// Per-project accent hues (Agent Home project tiles). Theme-aware via
|
|
// Obsidian's named color vars; paired with the matching `bg.project` tints.
|
|
project: {
|
|
red: "var(--color-red)",
|
|
orange: "var(--color-orange)",
|
|
yellow: "var(--color-yellow)",
|
|
green: "var(--color-green)",
|
|
blue: "var(--color-blue)",
|
|
purple: "var(--color-purple)",
|
|
},
|
|
},
|
|
backgroundColor: {
|
|
inherit: colors.inherit,
|
|
current: colors.current,
|
|
transparent: colors.transparent,
|
|
primary: "var(--background-primary)",
|
|
"primary-alt": "var(--background-primary-alt)",
|
|
secondary: "var(--background-secondary)",
|
|
"secondary-alt": "var(--background-secondary-alt)",
|
|
success: "rgba(var(--color-green-rgb),0.2)",
|
|
error: "rgba(var(--color-red-rgb),0.2)",
|
|
// Soft tints behind Agent Home project tiles; deeper `text.project` hue
|
|
// sits on top. Same six hues, kept in sync with `textColor.project`.
|
|
project: {
|
|
red: "rgba(var(--color-red-rgb),0.16)",
|
|
orange: "rgba(var(--color-orange-rgb),0.16)",
|
|
yellow: "rgba(var(--color-yellow-rgb),0.16)",
|
|
green: "rgba(var(--color-green-rgb),0.16)",
|
|
blue: "rgba(var(--color-blue-rgb),0.16)",
|
|
purple: "rgba(var(--color-purple-rgb),0.16)",
|
|
},
|
|
modifier: {
|
|
hover: "var(--background-modifier-hover)",
|
|
"active-hover": "var(--background-modifier-active-hover)",
|
|
|
|
error: "var(--background-modifier-error)",
|
|
"error-rgb": "rgba(var(--background-modifier-error-rgb),<alpha-value>)",
|
|
"error-hover": "var(--background-modifier-error-hover)",
|
|
success: "var(--background-modifier-success)",
|
|
"success-rgb": "rgba(var(--background-modifier-success-rgb),<alpha-value>)",
|
|
message: "var(--background-modifier-message)",
|
|
"form-field": "var(--background-form-field)",
|
|
},
|
|
interactive: {
|
|
normal: "var(--interactive-normal)",
|
|
hover: "var(--interactive-hover)",
|
|
accent: "var(--interactive-accent)",
|
|
"accent-hsl": "hsl(var(--interactive-accent-hsl),<alpha-value>)",
|
|
"accent-hover": "var(--interactive-accent-hover)",
|
|
},
|
|
dropdown: {
|
|
DEFAULT: "var(--dropdown-background)",
|
|
blend: "var(--dropdown-background-blend-mode)",
|
|
hover: "var(--dropdown-background-hover)",
|
|
},
|
|
callout: {
|
|
warning: "rgba(var(--callout-warning),<alpha-value>)",
|
|
},
|
|
overlay: {
|
|
DEFAULT: "#000",
|
|
},
|
|
toggle: {
|
|
thumb: "var(--toggle-thumb-color)",
|
|
},
|
|
},
|
|
borderColor: {
|
|
inherit: colors.inherit,
|
|
current: colors.current,
|
|
transparent: colors.transparent,
|
|
border: "var(--background-modifier-border)",
|
|
"border-hover": "var(--background-modifier-border-hover)",
|
|
"border-focus": "var(--background-modifier-border-focus)",
|
|
"interactive-accent": "var(--interactive-accent)",
|
|
},
|
|
ringColor: {
|
|
ring: "var(--interactive-accent)",
|
|
},
|
|
ringOffsetColor: {
|
|
ring: "var(--interactive-accent)",
|
|
},
|
|
|
|
colors: {
|
|
inherit: colors.inherit,
|
|
current: colors.current,
|
|
transparent: colors.transparent,
|
|
|
|
// preDefine CSS variables in Obsidian.(https://docs.obsidian.md/Reference/CSS+variables/Foundations/Colors)
|
|
base: {
|
|
"00": "var(--color-base-00)",
|
|
"05": "var(--color-base-05)",
|
|
10: "var(--color-base-10)",
|
|
20: "var(--color-base-20)",
|
|
25: "var(--color-base-25)",
|
|
30: "var(--color-base-30)",
|
|
35: "var(--color-base-35)",
|
|
40: "var(--color-base-40)",
|
|
50: "var(--color-base-50)",
|
|
60: "var(--color-base-60)",
|
|
70: "var(--color-base-70)",
|
|
100: "var(--color-base-100)",
|
|
},
|
|
red: "var(--color-red)",
|
|
"red-rgb": "rgba(var(--color-red-rgb),<alpha-value>)",
|
|
orange: "var(--color-orange)",
|
|
"orange-rgb": "rgba(var(--color-orange-rgb),<alpha-value>)",
|
|
yellow: "var(--color-yellow)",
|
|
"yellow-rgb": "rgba(var(--color-yellow-rgb),<alpha-value>)",
|
|
green: "var(--color-green)",
|
|
"green-rgb": "rgba(var(--color-green-rgb),<alpha-value>)",
|
|
cyan: "var(--color-cyan)",
|
|
"cyan-rgb": "rgba(var(--color-cyan-rgb),<alpha-value>)",
|
|
blue: "var(--color-blue)",
|
|
"blue-rgb": "rgba(var(--color-blue-rgb),<alpha-value>)",
|
|
purple: "var(--color-purple)",
|
|
"purple-rgb": "rgba(var(--color-purple-rgb),<alpha-value>)",
|
|
pink: "var(--color-pink)",
|
|
"pink-rgb": "rgba(var(--color-pink-rgb),<alpha-value>)",
|
|
gray: "var(--color-gray)",
|
|
"mono-rgb": {
|
|
0: "rgba(var(--mono-rgb-0),<alpha-value>)",
|
|
100: "rgba(var(--mono-rgb-100),<alpha-value>)",
|
|
},
|
|
|
|
caret: "var(--caret-color)",
|
|
icon: {
|
|
DEFAULT: "var(--icon-color)",
|
|
hover: "var(--icon-color-hover)",
|
|
active: "var(--icon-color-active)",
|
|
focused: "var(--icon-color-focused)",
|
|
},
|
|
},
|
|
borderWidth: {
|
|
DEFAULT: "var(--border-width)",
|
|
},
|
|
zIndex: {
|
|
cover: "var(--layer-cover)", // 5
|
|
sidedock: "var(--layer-sidedock)", // 10
|
|
"status-bar": "var(--layer-status-bar)", // 15
|
|
popover: "var(--layer-popover)", // 30
|
|
slides: "var(--layer-slides)", // 45
|
|
modal: "var(--layer-modal)", // 50
|
|
notice: "var(--layer-notice)", // 60
|
|
menu: "var(--layer-menu)", // 65
|
|
tooltip: "var(--layer-tooltip)", // 70
|
|
"dragged-item": "var(--layer-dragged-item)", // 80
|
|
},
|
|
fontWeight: {
|
|
thin: "var(--font-thin)", // 100
|
|
extralight: "var(--font-extralight)", // 200
|
|
light: "var(--font-light)", // 300
|
|
normal: "var(--font-normal)", // 400
|
|
medium: "var(--font-medium)", // 500
|
|
semibold: "var(--font-semibold)", // 600
|
|
bold: "var(--font-bold)", // 700
|
|
extrabold: "var(--font-extrabold)", // 800
|
|
black: "var(--font-black)", // 900
|
|
},
|
|
extend: {
|
|
borderRadius: {
|
|
"clickable-icon": "var(--clickable-icon-radius)",
|
|
xl: "var(--radius-xl)", // 16px
|
|
lg: "var(--radius-l)", // 12px
|
|
md: "var(--radius-m)", // 8px
|
|
sm: "var(--radius-s)", // 4px
|
|
},
|
|
spacing: {
|
|
0.5: "calc(var(--size-4-1) / 2)", // 2px
|
|
1: "var(--size-4-1)", // 4px
|
|
1.5: "calc(var(--size-4-1) * 1.5)", // 6px
|
|
2: "var(--size-4-2)",
|
|
3: "var(--size-4-3)",
|
|
4: "var(--size-4-4)",
|
|
5: "var(--size-4-5)",
|
|
5.5: "calc(var(--size-4-5) + 2px)",
|
|
6: "var(--size-4-6)",
|
|
},
|
|
cursor: {
|
|
DEFAULT: "var(--cursor)",
|
|
auto: "var(--cursor)",
|
|
pointer: "var(--cursor-link)",
|
|
},
|
|
fontSize: {
|
|
text: "var(--font-text-size)", // 16px
|
|
smallest: "var(--font-smallest)", // 0.8em
|
|
smaller: "var(--font-smaller)", // 0.875em
|
|
small: "var(--font-small)", // 0.933em
|
|
"ui-smaller": "var(--font-ui-smaller)", // 12px
|
|
"ui-small": "var(--font-ui-small)", // 13px
|
|
"ui-medium": "var(--font-ui-medium)", // 15px
|
|
// Obsidian's stock 20px UI token is `--font-ui-larger` (per the
|
|
// Typography docs), but some themes (e.g. Primary) ship `--font-ui-large`
|
|
// instead and omit the stock one. Chain both so the size resolves under
|
|
// either, falling back to a literal 20px if a theme defines neither
|
|
// (otherwise the font-size is invalid and the text drops to inherited).
|
|
"ui-larger": "var(--font-ui-large, var(--font-ui-larger, 20px))", // 20px
|
|
"ui-title": "var(--font-ui-large, var(--font-ui-larger, 20px))", // ~20px
|
|
},
|
|
strokeWidth: {
|
|
icon: "var(--icon-stroke)", // 1.75px
|
|
"icon-xs": "var(--icon-xs-stroke-width)", // 2px
|
|
"icon-s": "var(--icon-s-stroke-width)", // 2px
|
|
"icon-m": "var(--icon-m-stroke-width)", // 1.75px
|
|
"icon-l": "var(--icon-l-stroke-width)", // 1.75px
|
|
"icon-xl": "var(--icon-xl-stroke-width)", // 1.25px
|
|
},
|
|
lineHeight: {
|
|
normal: "var(--line-height-normal)", // 1.5
|
|
tight: "var(--line-height-tight)", // 1.3
|
|
},
|
|
size: {
|
|
icon: "var(--icon-size)", // 18px
|
|
"icon-xs": "var(--icon-xs)", // 14px
|
|
"icon-s": "var(--icon-s)", // 16px
|
|
"icon-m": "var(--icon-m)", // 18px
|
|
"icon-l": "var(--icon-l)", // 18px
|
|
"icon-xl": "var(--icon-xl)", // 32px
|
|
checkbox: "var(--checkbox-size)", //
|
|
},
|
|
opacity: {
|
|
icon: "var(--icon-opacity)", // 0.85
|
|
"icon-hover": "var(--icon-opacity-hover)", // 1
|
|
"icon-active": "var(--icon-opacity-active)", // 1
|
|
},
|
|
},
|
|
},
|
|
};
|