Cleanup, layout fixes, better event colors.
This commit is contained in:
parent
c0d76109a1
commit
93c23c594c
6
calendar-main.css
Normal file
6
calendar-main.css
Normal file
@ -0,0 +1,6 @@
|
||||
/* Calendar CSS - Main file with imports */
|
||||
@import url('colors.css');
|
||||
@import url('layout.css');
|
||||
@import url('cells.css');
|
||||
@import url('events.css');
|
||||
@import url('utilities.css');
|
42
calendar.js
42
calendar.js
@ -113,7 +113,7 @@ class InfiniteCalendar {
|
||||
const handleWheel = e => {
|
||||
e.preventDefault()
|
||||
e.stopPropagation()
|
||||
const currentYear = parseInt(this.weekLabel.textContent)
|
||||
const currentYear = parseInt(this.yearLabel.textContent)
|
||||
const topDisplayIndex = Math.floor(this.viewport.scrollTop / this.rowHeight)
|
||||
const currentWeekIndex = topDisplayIndex + this.minVirtualWeek
|
||||
const sensitivity = 1/3
|
||||
@ -125,7 +125,7 @@ class InfiniteCalendar {
|
||||
this.navigateToYear(newYear, currentWeekIndex)
|
||||
setTimeout(() => throttled = false, 100)
|
||||
}
|
||||
this.weekLabel.addEventListener('wheel', handleWheel, { passive: false })
|
||||
this.yearLabel.addEventListener('wheel', handleWheel, { passive: false })
|
||||
}
|
||||
|
||||
navigateTo(date) {
|
||||
@ -206,15 +206,15 @@ class InfiniteCalendar {
|
||||
}
|
||||
|
||||
createHeader() {
|
||||
this.weekLabel = document.createElement('div')
|
||||
this.weekLabel.className = 'dow-label'
|
||||
this.weekLabel.textContent = isoWeekInfo(new Date()).year
|
||||
this.header.appendChild(this.weekLabel)
|
||||
this.yearLabel = document.createElement('div')
|
||||
this.yearLabel.className = 'year-label'
|
||||
this.yearLabel.textContent = isoWeekInfo(new Date()).year
|
||||
this.header.appendChild(this.yearLabel)
|
||||
|
||||
const names = this.getLocalizedWeekdayNames()
|
||||
names.forEach((name, i) => {
|
||||
const c = document.createElement('div')
|
||||
c.className = 'cell dow'
|
||||
c.classList.add('dow')
|
||||
const dayIdx = (i + 1) % 7
|
||||
if (this.weekend[dayIdx]) c.classList.add('weekend')
|
||||
c.textContent = name
|
||||
@ -294,7 +294,7 @@ class InfiniteCalendar {
|
||||
const topVW = topDisplayIndex + this.minVirtualWeek
|
||||
const monday = this.getMondayForVirtualWeek(topVW)
|
||||
const { year } = isoWeekInfo(monday)
|
||||
if (this.weekLabel.textContent !== String(year)) this.weekLabel.textContent = year
|
||||
if (this.yearLabel.textContent !== String(year)) this.yearLabel.textContent = year
|
||||
}
|
||||
|
||||
createWeekElement(virtualWeek) {
|
||||
@ -626,7 +626,7 @@ class InfiniteCalendar {
|
||||
title: eventData.title,
|
||||
startDate: eventData.startDate,
|
||||
endDate: eventData.endDate,
|
||||
color: this.generateEventColor()
|
||||
colorId: this.generateEventColorId()
|
||||
}
|
||||
|
||||
const startDate = new Date(fromLocalString(event.startDate))
|
||||
@ -641,12 +641,9 @@ class InfiniteCalendar {
|
||||
this.refreshEvents()
|
||||
}
|
||||
|
||||
generateEventColor() {
|
||||
const colors = [
|
||||
'#ff6b6b', '#4ecdc4', '#45b7d1', '#96ceb4', '#feca57',
|
||||
'#ff9ff3', '#54a0ff', '#5f27cd', '#00d2d3', '#ff9f43'
|
||||
]
|
||||
return colors[Math.floor(Math.random() * colors.length)]
|
||||
generateEventColorId() {
|
||||
// Return a color ID from 0-11 for 12 evenly spaced hues
|
||||
return Math.floor(Math.random() * 12)
|
||||
}
|
||||
|
||||
refreshEvents() {
|
||||
@ -705,22 +702,9 @@ class InfiniteCalendar {
|
||||
|
||||
createOverlaySpan(overlay, w) {
|
||||
const span = document.createElement('div')
|
||||
span.className = 'event-span'
|
||||
span.className = `event-span event-color-${w.colorId}`
|
||||
span.style.gridColumn = `${w.startIdx + 1} / ${w.endIdx + 2}`
|
||||
span.style.gridRow = `${w._row}`
|
||||
span.style.height = '1.2em'
|
||||
span.style.borderRadius = '.4em'
|
||||
span.style.fontSize = '.75em'
|
||||
span.style.lineHeight = '1.2'
|
||||
span.style.padding = '0 .5em'
|
||||
span.style.whiteSpace = 'nowrap'
|
||||
span.style.overflow = 'hidden'
|
||||
span.style.textOverflow = 'ellipsis'
|
||||
span.style.background = w.color
|
||||
span.style.color = 'white'
|
||||
span.style.fontWeight = '600'
|
||||
span.style.pointerEvents = 'auto'
|
||||
span.style.zIndex = '1'
|
||||
span.textContent = w.title
|
||||
span.title = `${w.title} (${w.startDate === w.endDate ? w.startDate : w.startDate + ' - ' + w.endDate})`
|
||||
overlay.appendChild(span)
|
||||
|
39
colors.css
39
colors.css
@ -1,10 +1,9 @@
|
||||
/* Color tokens */
|
||||
:root {
|
||||
--bg: #f6f7fb;
|
||||
--panel: #fff;
|
||||
--today: #f83;
|
||||
--ink: #111;
|
||||
--ink-rgb: 17, 17, 17;
|
||||
--ink: #222;
|
||||
--inkstrong: #000;
|
||||
--muted: #888;
|
||||
--weekend: #888;
|
||||
--firstday: #000;
|
||||
@ -27,14 +26,26 @@
|
||||
.oct { background: hsl(18 78% 95%) }
|
||||
.nov { background: hsl(18 78% 88%) }
|
||||
|
||||
.event-color-0 { background: hsl(0, 40%, 80%); }
|
||||
.event-color-1 { background: hsl(30, 40%, 80%); }
|
||||
.event-color-2 { background: hsl(60, 40%, 80%); }
|
||||
.event-color-3 { background: hsl(90, 40%, 80%); }
|
||||
.event-color-4 { background: hsl(120, 40%, 80%); }
|
||||
.event-color-5 { background: hsl(150, 40%, 80%); }
|
||||
.event-color-6 { background: hsl(180, 40%, 80%); }
|
||||
.event-color-7 { background: hsl(210, 40%, 80%); }
|
||||
.event-color-8 { background: hsl(240, 40%, 80%); }
|
||||
.event-color-9 { background: hsl(270, 40%, 80%); }
|
||||
.event-color-10 { background: hsl(300, 40%, 80%); }
|
||||
.event-color-11 { background: hsl(330, 40%, 80%); }
|
||||
|
||||
/* Color tokens (dark) */
|
||||
@media (prefers-color-scheme: dark) {
|
||||
:root {
|
||||
--bg: radial-gradient(1200px 800px at 20% -10%, #1c2130 0%, #0c0f16 35%, #0a0b11 100%);
|
||||
--panel: #111318;
|
||||
--today: #f83;
|
||||
--ink: #ddd;
|
||||
--ink-rgb: 221, 221, 221;
|
||||
--inkstrong: #fff;
|
||||
--muted: #888;
|
||||
--weekend: #999;
|
||||
--firstday: #fff;
|
||||
@ -56,15 +67,29 @@
|
||||
.sep { background: hsl(18 70% 18%) }
|
||||
.oct { background: hsl(18 70% 26%) }
|
||||
.nov { background: hsl(18 70% 18%) }
|
||||
|
||||
.event-color-0 { background: hsl(0, 40%, 50%); }
|
||||
.event-color-1 { background: hsl(30, 40%, 50%); }
|
||||
.event-color-2 { background: hsl(60, 40%, 50%); }
|
||||
.event-color-3 { background: hsl(90, 40%, 50%); }
|
||||
.event-color-4 { background: hsl(120, 40%, 50%); }
|
||||
.event-color-5 { background: hsl(150, 40%, 50%); }
|
||||
.event-color-6 { background: hsl(180, 40%, 50%); }
|
||||
.event-color-7 { background: hsl(210, 40%, 50%); }
|
||||
.event-color-8 { background: hsl(240, 40%, 50%); }
|
||||
.event-color-9 { background: hsl(270, 40%, 50%); }
|
||||
.event-color-10 { background: hsl(300, 40%, 50%); }
|
||||
.event-color-11 { background: hsl(330, 40%, 50%); }
|
||||
|
||||
}
|
||||
|
||||
/* Selection styles */
|
||||
.weekend { color: var(--weekend) }
|
||||
.firstday { color: var(--firstday); text-shadow: 0 0 .1em rgba(var(--ink-rgb), .5) }
|
||||
.firstday { color: var(--firstday); text-shadow: 0 0 .1em; }
|
||||
|
||||
.selected {
|
||||
background: var(--select);
|
||||
border: 2px solid rgba(var(--ink-rgb), .3);
|
||||
border: 2px solid var(--ink);
|
||||
box-shadow: inset 0 0 0 1px rgba(255,255,255,.3);
|
||||
}
|
||||
.selected .event { opacity: .7 }
|
||||
|
@ -4,9 +4,8 @@
|
||||
padding: .1em .3em;
|
||||
margin: .1em 0;
|
||||
border-radius: .2em;
|
||||
color: white;
|
||||
font-weight: 500;
|
||||
white-space: nowrap;
|
||||
white-space: normal;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
width: 100%;
|
||||
@ -15,14 +14,13 @@
|
||||
cursor: pointer;
|
||||
z-index: 5;
|
||||
}
|
||||
.event:hover { opacity: .8 }
|
||||
|
||||
/* Spanning events in the overlay (grid-positioned, not absolutely measured) */
|
||||
.event-span {
|
||||
font-size: .75em;
|
||||
padding: 0 .5em;
|
||||
border-radius: .4em;
|
||||
color: white;
|
||||
color: var(--inkstrong);
|
||||
font-weight: 600;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
|
10
layout.css
10
layout.css
@ -51,13 +51,11 @@ header {
|
||||
.calendar-header, #calendar-header {
|
||||
display: grid;
|
||||
grid-template-columns: var(--label-w) repeat(7, var(--cell-w)) var(--overlay-w);
|
||||
border-bottom: .1em solid var(--muted);
|
||||
border-bottom: .2em solid var(--muted);
|
||||
align-items: last baseline;
|
||||
flex-shrink: 0;
|
||||
width: 100%;
|
||||
}
|
||||
.calendar-header .dow-label { display:grid; place-items:center; height: var(--cell-h); color: var(--muted) }
|
||||
.overlay-header-spacer { grid-column: -2 / -1 }
|
||||
|
||||
/* Main container */
|
||||
.calendar-container, #calendar-container {
|
||||
@ -108,16 +106,18 @@ header {
|
||||
}
|
||||
|
||||
/* Label cells */
|
||||
.dow-label, .week-label {
|
||||
.year-label, .week-label {
|
||||
display: grid;
|
||||
place-items: center;
|
||||
width: 100%;
|
||||
height: var(--cell-h);
|
||||
color: var(--muted);
|
||||
cursor: ns-resize;
|
||||
font-size: 1.2em;
|
||||
}
|
||||
|
||||
.week-label {
|
||||
height: var(--cell-h);
|
||||
}
|
||||
/* 7-day grid inside each week row */
|
||||
.week-row > .days-grid {
|
||||
grid-column: 2 / span 7;
|
||||
|
Loading…
x
Reference in New Issue
Block a user