Redraw the calendar as an almanac: gridless cells, typed bands

Day cells lose their borders and fills; red days, klämdagar and
Saturdays are told apart by the numeral's ink with a 12px R/K mark,
today is a filled circle, overrides and exclusions mark the numeral.
Bands carry their funding type by fill, ink and hatching and their
owner by a left cap. The preset rail becomes a chip row, the legend a
help popover, the period popover's three delete buttons fold behind
one "Ta bort…", and solo users pick a type directly in the day modal.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XBRLomdLK9jF7wU7a8AA6H
This commit is contained in:
2026-09-19 19:02:02 +02:00
parent d14f86478a
commit dbef997da4
28 changed files with 1486 additions and 1109 deletions
+13 -1
View File
@@ -1,5 +1,5 @@
import { describe, it, expect } from 'vitest'
import { getColorForType, getInkForType, getLabelForType, getTypeModifier } from './leaveTypes'
import { getColorForType, getInkForType, getLabelForType, getTypeKey, getTypeModifier } from './leaveTypes'
import { translate } from '@/i18n'
describe('getColorForType', () => {
@@ -32,6 +32,18 @@ describe('getInkForType', () => {
})
})
describe('getTypeKey', () => {
it('returns the bare type word for each known type', () => {
expect(getTypeKey('vacation')).toBe('vacation')
expect(getTypeKey('sjukpenning')).toBe('sjukpenning')
expect(getTypeKey('lagsta')).toBe('lagsta')
})
it('returns unknown for an unknown type', () => {
expect(getTypeKey('something-else')).toBe('unknown')
})
})
describe('getTypeModifier', () => {
it('returns a type-* modifier suffix for each known type', () => {
expect(getTypeModifier('vacation')).toBe('type-vacation')
+15 -4
View File
@@ -25,13 +25,24 @@ export function getInkForType(type: string): string {
return isKnownType(type) ? `var(--c-leave-${type}-ink)` : 'var(--c-surface)'
}
export type LeaveTypeKey = KnownType | 'unknown'
/**
* BEM modifier suffix for a leave type, for callers that need a class hook
* (lägsta's outline/hatch can't be expressed as a single inline colour):
* `` `calendar-band--${getTypeModifier(type)}` ``.
* The leave type as a bare BEM modifier word (`vacation` / `sjukpenning` /
* `lagsta`, or `unknown`) — the calendar's bands and ticks use it directly:
* `` `calendar-band--${getTypeKey(type)}` ``.
*/
export function getTypeKey(type: string): LeaveTypeKey {
return isKnownType(type) ? type : 'unknown'
}
/**
* The older `type-*` prefixed modifier, still used by the dashboard's year
* timeline (`year-timeline__band--type-lagsta`); the calendar has moved to
* `getTypeKey`.
*/
export function getTypeModifier(type: string): string {
return isKnownType(type) ? `type-${type}` : 'type-unknown'
return `type-${getTypeKey(type)}`
}
/**