fix: relation chips now show type color instead of default blue (#68)
* fix: relation chips now display correct type color instead of default blue Root cause: resolveRef matched entries by path/filename only, while wiki-links used findEntryByTarget (title, filename, aliases). When a wikilink target used the note title (differing from filename), resolveRef failed → null type → default blue. Changes: - resolveRef now calls findEntryByTarget first (title/alias match) - Default color for typeless notes changed from blue to neutral grey - TypeSelector passes custom color key from Type entries - DynamicPropertiesPanel refactored to reduce cyclomatic complexity Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * design: add before/after visual for relations type color fix Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * docs: add task completion summary Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
49
src/utils/typeColors.test.ts
Normal file
49
src/utils/typeColors.test.ts
Normal file
@@ -0,0 +1,49 @@
|
||||
import { describe, it, expect } from 'vitest'
|
||||
import { getTypeColor, getTypeLightColor } from './typeColors'
|
||||
|
||||
describe('getTypeColor', () => {
|
||||
it('returns hardcoded color for known types', () => {
|
||||
expect(getTypeColor('Project')).toBe('var(--accent-red)')
|
||||
expect(getTypeColor('Person')).toBe('var(--accent-yellow)')
|
||||
expect(getTypeColor('Topic')).toBe('var(--accent-green)')
|
||||
})
|
||||
|
||||
it('returns neutral muted color for null type', () => {
|
||||
expect(getTypeColor(null)).toBe('var(--muted-foreground)')
|
||||
})
|
||||
|
||||
it('returns neutral muted color for unknown type without custom key', () => {
|
||||
expect(getTypeColor('UnknownType')).toBe('var(--muted-foreground)')
|
||||
})
|
||||
|
||||
it('uses custom color key over hardcoded map', () => {
|
||||
expect(getTypeColor('Project', 'green')).toBe('var(--accent-green)')
|
||||
})
|
||||
|
||||
it('uses custom color key for unknown type', () => {
|
||||
expect(getTypeColor('Recipe', 'orange')).toBe('var(--accent-orange)')
|
||||
})
|
||||
|
||||
it('ignores invalid custom color key', () => {
|
||||
expect(getTypeColor('Project', 'invalid')).toBe('var(--accent-red)')
|
||||
})
|
||||
})
|
||||
|
||||
describe('getTypeLightColor', () => {
|
||||
it('returns hardcoded light color for known types', () => {
|
||||
expect(getTypeLightColor('Project')).toBe('var(--accent-red-light)')
|
||||
expect(getTypeLightColor('Person')).toBe('var(--accent-yellow-light)')
|
||||
})
|
||||
|
||||
it('returns neutral muted light color for null type', () => {
|
||||
expect(getTypeLightColor(null)).toBe('var(--muted)')
|
||||
})
|
||||
|
||||
it('returns neutral muted light color for unknown type without custom key', () => {
|
||||
expect(getTypeLightColor('UnknownType')).toBe('var(--muted)')
|
||||
})
|
||||
|
||||
it('uses custom color key for light variant', () => {
|
||||
expect(getTypeLightColor('Recipe', 'purple')).toBe('var(--accent-purple-light)')
|
||||
})
|
||||
})
|
||||
@@ -25,8 +25,8 @@ const TYPE_LIGHT_COLOR_MAP: Record<string, string> = {
|
||||
Type: 'var(--accent-blue-light)',
|
||||
}
|
||||
|
||||
const DEFAULT_COLOR = 'var(--accent-blue)'
|
||||
const DEFAULT_LIGHT_COLOR = 'var(--accent-blue-light)'
|
||||
const DEFAULT_COLOR = 'var(--muted-foreground)'
|
||||
const DEFAULT_LIGHT_COLOR = 'var(--muted)'
|
||||
|
||||
/** Color key → CSS variable mapping for the design system accent palette */
|
||||
export const ACCENT_COLORS: { key: string; label: string; css: string; cssLight: string }[] = [
|
||||
|
||||
@@ -87,8 +87,8 @@ describe('lookupColorForEntry', () => {
|
||||
expect(lookupColorForEntry(allEntries, recipeEntry)).toBe('var(--accent-orange)')
|
||||
})
|
||||
|
||||
it('returns default blue for an entry with no type', () => {
|
||||
expect(lookupColorForEntry(allEntries, untypedEntry)).toBe('var(--accent-blue)')
|
||||
it('returns neutral color for an entry with no type', () => {
|
||||
expect(lookupColorForEntry(allEntries, untypedEntry)).toBe('var(--muted-foreground)')
|
||||
})
|
||||
})
|
||||
|
||||
@@ -105,16 +105,16 @@ describe('resolveWikilinkColor', () => {
|
||||
expect(result.color).toBe('var(--text-muted)')
|
||||
})
|
||||
|
||||
it('returns default color for an untyped note', () => {
|
||||
it('returns neutral color for an untyped note', () => {
|
||||
const result = resolveWikilinkColor(allEntries, 'Random Thought')
|
||||
expect(result.isBroken).toBe(false)
|
||||
expect(result.color).toBe('var(--accent-blue)')
|
||||
expect(result.color).toBe('var(--muted-foreground)')
|
||||
})
|
||||
|
||||
it('returns default color when entries list is empty', () => {
|
||||
it('returns neutral color when entries list is empty', () => {
|
||||
const result = resolveWikilinkColor([], 'Anything')
|
||||
expect(result.isBroken).toBe(false)
|
||||
expect(result.color).toBe('var(--accent-blue)')
|
||||
expect(result.color).toBe('var(--muted-foreground)')
|
||||
})
|
||||
|
||||
it('resolves alias-based wikilink target', () => {
|
||||
|
||||
Reference in New Issue
Block a user