Enhances event color styling with flexible metadata system
Introduces a new color customization approach for calendar events using CSS custom properties and metadata - Adds support for dynamic color assignment via event metadata - Implements a flexible color utility class system - Replaces hardcoded event type colors with a more generic color-mix() approach - Provides broader color palette for event styling
This commit is contained in:
parent
d8b9f6dabd
commit
be551f88e5
7 changed files with 269 additions and 4135 deletions
147
.workbench/event-colors.txt
Normal file
147
.workbench/event-colors.txt
Normal file
|
|
@ -0,0 +1,147 @@
|
||||||
|
|
||||||
|
<!doctype html>
|
||||||
|
<html lang="da">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8" />
|
||||||
|
<title>Event Farvesystem Demo</title>
|
||||||
|
<style>
|
||||||
|
:root {
|
||||||
|
/* Palette */
|
||||||
|
--b-color-red: #e53935;
|
||||||
|
--b-color-pink: #d81b60;
|
||||||
|
--b-color-magenta: #c200c2;
|
||||||
|
--b-color-purple: #8e24aa;
|
||||||
|
--b-color-violet: #5e35b1;
|
||||||
|
--b-color-deep-purple: #4527a0;
|
||||||
|
--b-color-indigo: #3949ab;
|
||||||
|
--b-color-blue: #1e88e5;
|
||||||
|
--b-color-light-blue: #03a9f4;
|
||||||
|
--b-color-cyan: #3bc9db;
|
||||||
|
--b-color-teal: #00897b;
|
||||||
|
--b-color-green: #43a047;
|
||||||
|
--b-color-light-green: #8bc34a;
|
||||||
|
--b-color-lime: #c0ca33;
|
||||||
|
--b-color-yellow: #fdd835;
|
||||||
|
--b-color-amber: #ffb300;
|
||||||
|
--b-color-orange: #fb8c00;
|
||||||
|
--b-color-deep-orange: #f4511e;
|
||||||
|
|
||||||
|
/* Basismix (lysning). Kan skiftes til #000 for mørkning */
|
||||||
|
--b-mix: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
font-family: system-ui, sans-serif;
|
||||||
|
background: #f3f3f3;
|
||||||
|
margin: 0;
|
||||||
|
padding: 2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1 { margin-top: 0; }
|
||||||
|
|
||||||
|
.grid {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
|
||||||
|
gap: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -----------------------------------------------------------
|
||||||
|
EVENT KOMPONENT
|
||||||
|
----------------------------------------------------------- */
|
||||||
|
.event {
|
||||||
|
--b-text: var(--b-primary);
|
||||||
|
|
||||||
|
display: flex;
|
||||||
|
border-radius: .5rem;
|
||||||
|
overflow: hidden;
|
||||||
|
cursor: pointer;
|
||||||
|
padding: 1rem 1rem 1rem .75rem;
|
||||||
|
background-color: color-mix(in srgb, var(--b-primary) 15%, var(--b-mix));
|
||||||
|
color: var(--b-text);
|
||||||
|
border-left: 6px solid var(--b-primary);
|
||||||
|
|
||||||
|
transition:
|
||||||
|
background-color .2s ease,
|
||||||
|
border-color .2s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.event:hover {
|
||||||
|
background-color: color-mix(in srgb, var(--b-primary) 25%, var(--b-mix));
|
||||||
|
}
|
||||||
|
|
||||||
|
.event-title {
|
||||||
|
font-weight: 600;
|
||||||
|
margin-bottom: .25rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.event-meta {
|
||||||
|
font-size: .85rem;
|
||||||
|
opacity: .8;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -----------------------------------------------------------
|
||||||
|
eksempel på UTILITY-KLASSER
|
||||||
|
----------------------------------------------------------- */
|
||||||
|
.is-red { --b-primary: var(--b-color-red); }
|
||||||
|
.is-blue { --b-primary: var(--b-color-blue); }
|
||||||
|
.is-green { --b-primary: var(--b-color-green); }
|
||||||
|
.is-magenta { --b-primary: var(--b-color-magenta); }
|
||||||
|
.is-amber { --b-primary: var(--b-color-amber); }
|
||||||
|
.is-orange { --b-primary: var(--b-color-orange); }
|
||||||
|
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
|
||||||
|
<h1>Event Farvesystem Demo</h1>
|
||||||
|
<p>Baggrunden er dæmpet primærfarve, hover gør den mørkere, venstre kant og tekst bruger den rene farve.</p>
|
||||||
|
|
||||||
|
<div class="grid">
|
||||||
|
|
||||||
|
<div class="event is-blue">
|
||||||
|
<div>
|
||||||
|
<div class="event-title">Blå event</div>
|
||||||
|
<div class="event-meta">.is-blue</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="event is-red">
|
||||||
|
<div>
|
||||||
|
<div class="event-title">Rød event</div>
|
||||||
|
<div class="event-meta">.is-red</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="event is-green">
|
||||||
|
<div>
|
||||||
|
<div class="event-title">Grøn event</div>
|
||||||
|
<div class="event-meta">.is-green</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="event is-magenta">
|
||||||
|
<div>
|
||||||
|
<div class="event-title">Magenta event</div>
|
||||||
|
<div class="event-meta">.is-magenta</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="event is-amber">
|
||||||
|
<div>
|
||||||
|
<div class="event-title">Amber event</div>
|
||||||
|
<div class="event-meta">.is-amber</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="event is-orange">
|
||||||
|
<div>
|
||||||
|
<div class="event-title">Orange event</div>
|
||||||
|
<div class="event-meta">.is-orange</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
|
||||||
|
|
@ -296,6 +296,11 @@ export class SwpEventElement extends BaseSwpEventElement {
|
||||||
element.dataset.type = event.type;
|
element.dataset.type = event.type;
|
||||||
element.dataset.duration = event.metadata?.duration?.toString() || '60';
|
element.dataset.duration = event.metadata?.duration?.toString() || '60';
|
||||||
|
|
||||||
|
// Apply color class from metadata
|
||||||
|
if (event.metadata?.color) {
|
||||||
|
element.classList.add(`is-${event.metadata.color}`);
|
||||||
|
}
|
||||||
|
|
||||||
return element;
|
return element;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -373,6 +378,11 @@ export class SwpAllDayEventElement extends BaseSwpEventElement {
|
||||||
element.dataset.allday = 'true';
|
element.dataset.allday = 'true';
|
||||||
element.textContent = event.title;
|
element.textContent = event.title;
|
||||||
|
|
||||||
|
// Apply color class from metadata
|
||||||
|
if (event.metadata?.color) {
|
||||||
|
element.classList.add(`is-${event.metadata.color}`);
|
||||||
|
}
|
||||||
|
|
||||||
return element;
|
return element;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -141,7 +141,7 @@ async function initializeCalendar(): Promise<void> {
|
||||||
builder.registerType(MockAuditRepository).as<IApiRepository<IAuditEntry>>();
|
builder.registerType(MockAuditRepository).as<IApiRepository<IAuditEntry>>();
|
||||||
|
|
||||||
|
|
||||||
let calendarMode = 'date' ;
|
let calendarMode = 'resource' ;
|
||||||
// Register DataSource and HeaderRenderer based on mode
|
// Register DataSource and HeaderRenderer based on mode
|
||||||
if (calendarMode === 'resource') {
|
if (calendarMode === 'resource') {
|
||||||
builder.registerType(ResourceColumnDataSource).as<IColumnDataSource>();
|
builder.registerType(ResourceColumnDataSource).as<IColumnDataSource>();
|
||||||
|
|
|
||||||
|
|
@ -41,22 +41,28 @@
|
||||||
--color-work-hours: rgba(255, 255, 255, 0.9);
|
--color-work-hours: rgba(255, 255, 255, 0.9);
|
||||||
--color-current-time: #ff0000;
|
--color-current-time: #ff0000;
|
||||||
|
|
||||||
/* Event colors - Updated with month-view-expanded.html color scheme */
|
/* Named color palette for events */
|
||||||
--color-event-meeting: #e8f5e8;
|
--b-color-red: #e53935;
|
||||||
--color-event-meeting-border: #4caf50;
|
--b-color-pink: #d81b60;
|
||||||
--color-event-meeting-hl: #c8e6c9;
|
--b-color-magenta: #c200c2;
|
||||||
--color-event-meal: #fff8e1;
|
--b-color-purple: #8e24aa;
|
||||||
--color-event-meal-border: #ff9800;
|
--b-color-violet: #5e35b1;
|
||||||
--color-event-meal-hl: #ffe0b2;
|
--b-color-deep-purple: #4527a0;
|
||||||
--color-event-work: #fff8e1;
|
--b-color-indigo: #3949ab;
|
||||||
--color-event-work-border: #ff9800;
|
--b-color-blue: #1e88e5;
|
||||||
--color-event-work-hl: #ffe0b2;
|
--b-color-light-blue: #03a9f4;
|
||||||
--color-event-milestone: #ffebee;
|
--b-color-cyan: #3bc9db;
|
||||||
--color-event-milestone-border: #f44336;
|
--b-color-teal: #00897b;
|
||||||
--color-event-milestone-hl: #ffcdd2;
|
--b-color-green: #43a047;
|
||||||
--color-event-personal: #f3e5f5;
|
--b-color-light-green: #8bc34a;
|
||||||
--color-event-personal-border: #9c27b0;
|
--b-color-lime: #c0ca33;
|
||||||
--color-event-personal-hl: #e1bee7;
|
--b-color-yellow: #fdd835;
|
||||||
|
--b-color-amber: #ffb300;
|
||||||
|
--b-color-orange: #fb8c00;
|
||||||
|
--b-color-deep-orange: #f4511e;
|
||||||
|
|
||||||
|
/* Base mix for color-mix() function */
|
||||||
|
--b-mix: #fff;
|
||||||
|
|
||||||
/* UI colors */
|
/* UI colors */
|
||||||
--color-background: #ffffff;
|
--color-background: #ffffff;
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,8 @@
|
||||||
|
|
||||||
/* Event base styles */
|
/* Event base styles */
|
||||||
swp-day-columns swp-event {
|
swp-day-columns swp-event {
|
||||||
|
--b-text: var(--color-text);
|
||||||
|
|
||||||
position: absolute;
|
position: absolute;
|
||||||
border-radius: 3px;
|
border-radius: 3px;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
|
|
@ -10,10 +12,14 @@ swp-day-columns swp-event {
|
||||||
z-index: 10;
|
z-index: 10;
|
||||||
left: 2px;
|
left: 2px;
|
||||||
right: 2px;
|
right: 2px;
|
||||||
color: var(--color-text);
|
|
||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
padding: 4px 6px;
|
padding: 4px 6px;
|
||||||
|
|
||||||
|
/* Color system using color-mix() */
|
||||||
|
background-color: color-mix(in srgb, var(--b-primary) 10%, var(--b-mix));
|
||||||
|
color: var(--b-text);
|
||||||
|
border-left: 4px solid var(--b-primary);
|
||||||
|
|
||||||
/* Enable container queries for responsive layout */
|
/* Enable container queries for responsive layout */
|
||||||
container-type: size;
|
container-type: size;
|
||||||
container-name: event;
|
container-name: event;
|
||||||
|
|
@ -25,43 +31,6 @@ swp-day-columns swp-event {
|
||||||
gap: 2px 4px;
|
gap: 2px 4px;
|
||||||
align-items: start;
|
align-items: start;
|
||||||
|
|
||||||
/* Event types */
|
|
||||||
&[data-type="meeting"] {
|
|
||||||
background: var(--color-event-meeting);
|
|
||||||
border-left: 4px solid var(--color-event-meeting-border);
|
|
||||||
color: var(--color-text);
|
|
||||||
}
|
|
||||||
|
|
||||||
&[data-type="meal"] {
|
|
||||||
background: var(--color-event-meal);
|
|
||||||
border-left: 4px solid var(--color-event-meal-border);
|
|
||||||
color: var(--color-text);
|
|
||||||
}
|
|
||||||
|
|
||||||
&[data-type="work"] {
|
|
||||||
background: var(--color-event-work);
|
|
||||||
border-left: 4px solid var(--color-event-work-border);
|
|
||||||
color: var(--color-text);
|
|
||||||
}
|
|
||||||
|
|
||||||
&[data-type="milestone"] {
|
|
||||||
background: var(--color-event-milestone);
|
|
||||||
border-left: 4px solid var(--color-event-milestone-border);
|
|
||||||
color: var(--color-text);
|
|
||||||
}
|
|
||||||
|
|
||||||
&[data-type="personal"] {
|
|
||||||
background: var(--color-event-personal);
|
|
||||||
border-left: 4px solid var(--color-event-personal-border);
|
|
||||||
color: var(--color-text);
|
|
||||||
}
|
|
||||||
|
|
||||||
&[data-type="deadline"] {
|
|
||||||
background: var(--color-event-milestone);
|
|
||||||
border-left: 4px solid var(--color-event-milestone-border);
|
|
||||||
color: var(--color-text);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Dragging state */
|
/* Dragging state */
|
||||||
&.dragging {
|
&.dragging {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
|
|
@ -72,31 +41,10 @@ swp-day-columns swp-event {
|
||||||
width: auto;
|
width: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Hover state - highlight colors */
|
/* Hover state */
|
||||||
&:hover[data-type="meeting"] {
|
&:hover {
|
||||||
background: var(--color-event-meeting-hl);
|
background-color: color-mix(in srgb, var(--b-primary) 15%, var(--b-mix));
|
||||||
}
|
}
|
||||||
|
|
||||||
&:hover[data-type="meal"] {
|
|
||||||
background: var(--color-event-meal-hl);
|
|
||||||
}
|
|
||||||
|
|
||||||
&:hover[data-type="work"] {
|
|
||||||
background: var(--color-event-work-hl);
|
|
||||||
}
|
|
||||||
|
|
||||||
&:hover[data-type="milestone"] {
|
|
||||||
background: var(--color-event-milestone-hl);
|
|
||||||
}
|
|
||||||
|
|
||||||
&:hover[data-type="personal"] {
|
|
||||||
background: var(--color-event-personal-hl);
|
|
||||||
}
|
|
||||||
|
|
||||||
&:hover[data-type="deadline"] {
|
|
||||||
background: var(--color-event-milestone-hl);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
swp-day-columns swp-event:hover {
|
swp-day-columns swp-event:hover {
|
||||||
|
|
@ -218,10 +166,14 @@ swp-multi-day-event {
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
text-overflow: ellipsis;
|
text-overflow: ellipsis;
|
||||||
|
|
||||||
/* Event type colors */
|
/* Color system using color-mix() */
|
||||||
&[data-type="milestone"] {
|
--b-text: var(--color-text);
|
||||||
background: var(--color-event-milestone);
|
background-color: color-mix(in srgb, var(--b-primary) 10%, var(--b-mix));
|
||||||
color: var(--color-event-milestone-border);
|
color: var(--b-text);
|
||||||
|
border-left: 4px solid var(--b-primary);
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background-color: color-mix(in srgb, var(--b-primary) 15%, var(--b-mix));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Continuation indicators */
|
/* Continuation indicators */
|
||||||
|
|
@ -259,6 +211,19 @@ swp-multi-day-event {
|
||||||
transform: translateY(-1px);
|
transform: translateY(-1px);
|
||||||
box-shadow: var(--shadow-sm);
|
box-shadow: var(--shadow-sm);
|
||||||
}
|
}
|
||||||
|
/* All-day events */
|
||||||
|
swp-allday-event {
|
||||||
|
--b-text: var(--color-text);
|
||||||
|
background-color: color-mix(in srgb, var(--b-primary) 10%, var(--b-mix));
|
||||||
|
color: var(--b-text);
|
||||||
|
border-left: 4px solid var(--b-primary);
|
||||||
|
cursor: pointer;
|
||||||
|
transition: background-color 200ms ease;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background-color: color-mix(in srgb, var(--b-primary) 15%, var(--b-mix));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Event creation preview */
|
/* Event creation preview */
|
||||||
|
|
@ -351,3 +316,23 @@ swp-event-group swp-event {
|
||||||
swp-allday-container swp-event.transitioning {
|
swp-allday-container swp-event.transitioning {
|
||||||
transition: grid-area 200ms ease-out, grid-row 200ms ease-out, grid-column 200ms ease-out;
|
transition: grid-area 200ms ease-out, grid-row 200ms ease-out, grid-column 200ms ease-out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Color utility classes */
|
||||||
|
.is-red { --b-primary: var(--b-color-red); }
|
||||||
|
.is-pink { --b-primary: var(--b-color-pink); }
|
||||||
|
.is-magenta { --b-primary: var(--b-color-magenta); }
|
||||||
|
.is-purple { --b-primary: var(--b-color-purple); }
|
||||||
|
.is-violet { --b-primary: var(--b-color-violet); }
|
||||||
|
.is-deep-purple { --b-primary: var(--b-color-deep-purple); }
|
||||||
|
.is-indigo { --b-primary: var(--b-color-indigo); }
|
||||||
|
.is-blue { --b-primary: var(--b-color-blue); }
|
||||||
|
.is-light-blue { --b-primary: var(--b-color-light-blue); }
|
||||||
|
.is-cyan { --b-primary: var(--b-color-cyan); }
|
||||||
|
.is-teal { --b-primary: var(--b-color-teal); }
|
||||||
|
.is-green { --b-primary: var(--b-color-green); }
|
||||||
|
.is-light-green { --b-primary: var(--b-color-light-green); }
|
||||||
|
.is-lime { --b-primary: var(--b-color-lime); }
|
||||||
|
.is-yellow { --b-primary: var(--b-color-yellow); }
|
||||||
|
.is-amber { --b-primary: var(--b-color-amber); }
|
||||||
|
.is-orange { --b-primary: var(--b-color-orange); }
|
||||||
|
.is-deep-orange { --b-primary: var(--b-color-deep-orange); }
|
||||||
|
|
|
||||||
|
|
@ -322,67 +322,20 @@ swp-allday-container {
|
||||||
font-size: 0.75rem;
|
font-size: 0.75rem;
|
||||||
border-radius: 3px;
|
border-radius: 3px;
|
||||||
|
|
||||||
/* Event type colors - normal state */
|
/* Color system using color-mix() */
|
||||||
&[data-type="meeting"] {
|
--b-text: var(--color-text);
|
||||||
background: var(--color-event-meeting);
|
background-color: color-mix(in srgb, var(--b-primary) 10%, var(--b-mix));
|
||||||
color: var(--color-text);
|
color: var(--b-text);
|
||||||
}
|
border-left: 4px solid var(--b-primary);
|
||||||
|
|
||||||
&[data-type="meal"] {
|
|
||||||
background: var(--color-event-meal);
|
|
||||||
color: var(--color-text);
|
|
||||||
}
|
|
||||||
|
|
||||||
&[data-type="work"] {
|
|
||||||
background: var(--color-event-work);
|
|
||||||
color: var(--color-text);
|
|
||||||
}
|
|
||||||
|
|
||||||
&[data-type="milestone"] {
|
|
||||||
background: var(--color-event-milestone);
|
|
||||||
color: var(--color-text);
|
|
||||||
}
|
|
||||||
|
|
||||||
&[data-type="personal"] {
|
|
||||||
background: var(--color-event-personal);
|
|
||||||
color: var(--color-text);
|
|
||||||
}
|
|
||||||
|
|
||||||
&[data-type="deadline"] {
|
|
||||||
background: var(--color-event-milestone);
|
|
||||||
color: var(--color-text);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Dragging state */
|
/* Dragging state */
|
||||||
&.dragging {
|
&.dragging {
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Highlight state for all event types */
|
/* Highlight state */
|
||||||
&.highlight {
|
&.highlight {
|
||||||
&[data-type="meeting"] {
|
background-color: color-mix(in srgb, var(--b-primary) 15%, var(--b-mix)) !important;
|
||||||
background: var(--color-event-meeting-hl) !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
&[data-type="meal"] {
|
|
||||||
background: var(--color-event-meal-hl) !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
&[data-type="work"] {
|
|
||||||
background: var(--color-event-work-hl) !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
&[data-type="milestone"] {
|
|
||||||
background: var(--color-event-milestone-hl) !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
&[data-type="personal"] {
|
|
||||||
background: var(--color-event-personal-hl) !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
&[data-type="deadline"] {
|
|
||||||
background: var(--color-event-milestone-hl) !important;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Overflow indicator styling */
|
/* Overflow indicator styling */
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load diff
Loading…
Add table
Add a link
Reference in a new issue