Introduces HeaderDrawerRenderer and HeaderDrawerLayoutEngine to support dragging events into an all-day header drawer Enables dynamic event placement and conversion between timed and all-day events through new drag interactions Implements flexible layout calculation for header items with column and row management Extends DragDropManager to handle header zone interactions Adds new event types for header drag events
302 lines
6.4 KiB
CSS
302 lines
6.4 KiB
CSS
/* V2 Layout - Calendar structure, grid, navigation */
|
|
|
|
.calendar-wrapper {
|
|
height: 100vh;
|
|
display: flex;
|
|
flex-direction: column;
|
|
}
|
|
|
|
swp-calendar {
|
|
display: grid;
|
|
grid-template-rows: auto 1fr;
|
|
height: 100%;
|
|
background: var(--color-surface);
|
|
}
|
|
|
|
/* Nav */
|
|
swp-calendar-nav {
|
|
display: flex;
|
|
gap: 16px;
|
|
padding: 12px 16px;
|
|
border-bottom: 1px solid var(--color-border);
|
|
align-items: center;
|
|
}
|
|
|
|
swp-nav-button {
|
|
padding: 8px 16px;
|
|
border: 1px solid var(--color-border);
|
|
border-radius: 4px;
|
|
cursor: pointer;
|
|
background: var(--color-surface);
|
|
|
|
&:hover { background: var(--color-background-hover); }
|
|
}
|
|
|
|
swp-week-info {
|
|
margin-left: auto;
|
|
text-align: right;
|
|
|
|
swp-week-number {
|
|
font-weight: 600;
|
|
display: block;
|
|
}
|
|
|
|
swp-date-range {
|
|
font-size: 12px;
|
|
color: var(--color-text-secondary);
|
|
}
|
|
}
|
|
|
|
/* Container */
|
|
swp-calendar-container {
|
|
display: grid;
|
|
grid-template-columns: var(--time-axis-width) 1fr;
|
|
grid-template-rows: auto 1fr;
|
|
overflow: hidden;
|
|
height: 100%;
|
|
}
|
|
|
|
/* Time axis */
|
|
swp-time-axis {
|
|
grid-column: 1;
|
|
grid-row: 1 / 3;
|
|
display: grid;
|
|
grid-template-rows: auto 1fr;
|
|
border-right: 1px solid var(--color-border);
|
|
background: var(--color-surface);
|
|
overflow: hidden;
|
|
user-select: none;
|
|
}
|
|
|
|
swp-header-spacer {
|
|
border-bottom: 1px solid var(--color-border);
|
|
}
|
|
|
|
swp-header-drawer {
|
|
display: grid;
|
|
grid-template-columns: repeat(var(--grid-columns), minmax(var(--day-column-min-width), 1fr));
|
|
min-width: calc(var(--grid-columns) * var(--day-column-min-width));
|
|
grid-auto-rows: 28px;
|
|
gap: 2px 0;
|
|
min-height: 0;
|
|
overflow: hidden;
|
|
background: var(--color-background-alt);
|
|
border-bottom: 1px solid var(--color-border);
|
|
}
|
|
|
|
swp-time-axis-content {
|
|
display: flex;
|
|
flex-direction: column;
|
|
position: relative;
|
|
}
|
|
|
|
swp-hour-marker {
|
|
height: var(--hour-height);
|
|
padding: 4px 8px;
|
|
font-size: 11px;
|
|
color: var(--color-text-secondary);
|
|
text-align: right;
|
|
position: relative;
|
|
|
|
&::after {
|
|
content: '';
|
|
position: absolute;
|
|
top: -1px;
|
|
right: 0;
|
|
width: 5px;
|
|
height: 1px;
|
|
background: var(--color-hour-line);
|
|
}
|
|
|
|
&:first-child::after {
|
|
display: none;
|
|
}
|
|
}
|
|
|
|
/* Grid container */
|
|
swp-grid-container {
|
|
grid-column: 2;
|
|
grid-row: 1 / 3;
|
|
display: grid;
|
|
grid-template-rows: subgrid;
|
|
overflow: hidden;
|
|
}
|
|
|
|
/* Viewport/Track for slide animation */
|
|
swp-header-viewport {
|
|
overflow: hidden;
|
|
}
|
|
|
|
swp-content-viewport {
|
|
overflow: hidden;
|
|
min-height: 0;
|
|
}
|
|
|
|
swp-header-track {
|
|
display: flex;
|
|
|
|
> swp-calendar-header { flex: 0 0 100%; }
|
|
}
|
|
|
|
swp-content-track {
|
|
display: flex;
|
|
height: 100%;
|
|
|
|
> swp-scrollable-content {
|
|
flex: 0 0 100%;
|
|
height: 100%;
|
|
}
|
|
}
|
|
|
|
/* Header */
|
|
swp-calendar-header {
|
|
display: grid;
|
|
grid-template-columns: repeat(var(--grid-columns), minmax(var(--day-column-min-width), 1fr));
|
|
min-width: calc(var(--grid-columns) * var(--day-column-min-width));
|
|
grid-auto-rows: auto;
|
|
background: var(--color-surface);
|
|
overflow-y: scroll;
|
|
overflow-x: hidden;
|
|
|
|
&::-webkit-scrollbar { background: transparent; }
|
|
&::-webkit-scrollbar-thumb { background: transparent; }
|
|
|
|
&[data-levels="date"] > swp-day-header { grid-row: 1; }
|
|
|
|
&[data-levels="resource date"] {
|
|
> swp-resource-header { grid-row: 1; }
|
|
> swp-day-header { grid-row: 2; }
|
|
}
|
|
|
|
&[data-levels="team resource date"] {
|
|
> swp-team-header { grid-row: 1; }
|
|
> swp-resource-header { grid-row: 2; }
|
|
> swp-day-header { grid-row: 3; }
|
|
}
|
|
}
|
|
|
|
swp-day-header,
|
|
swp-resource-header,
|
|
swp-team-header {
|
|
padding: 8px;
|
|
text-align: center;
|
|
border-right: 1px solid var(--color-border);
|
|
border-bottom: 1px solid var(--color-border);
|
|
user-select: none;
|
|
}
|
|
|
|
swp-team-header {
|
|
background: var(--color-team-bg);
|
|
color: var(--color-team-text);
|
|
font-weight: 500;
|
|
grid-column: span var(--team-cols, 1);
|
|
}
|
|
|
|
swp-resource-header {
|
|
background: var(--color-background-alt);
|
|
font-size: 13px;
|
|
}
|
|
|
|
swp-day-header {
|
|
swp-day-name {
|
|
display: block;
|
|
font-size: 11px;
|
|
color: var(--color-text-secondary);
|
|
text-transform: uppercase;
|
|
}
|
|
|
|
swp-day-date {
|
|
display: block;
|
|
font-size: 24px;
|
|
font-weight: 300;
|
|
}
|
|
}
|
|
|
|
/* Scrollable content */
|
|
swp-scrollable-content {
|
|
display: block;
|
|
overflow: auto;
|
|
}
|
|
|
|
swp-time-grid {
|
|
display: block;
|
|
position: relative;
|
|
min-height: calc((var(--day-end-hour) - var(--day-start-hour)) * var(--hour-height));
|
|
min-width: calc(var(--grid-columns) * var(--day-column-min-width));
|
|
|
|
/* Timelinjer */
|
|
&::after {
|
|
content: '';
|
|
position: absolute;
|
|
inset: 0;
|
|
z-index: 2;
|
|
background-image: repeating-linear-gradient(
|
|
to bottom,
|
|
transparent,
|
|
transparent calc(var(--hour-height) - 1px),
|
|
var(--color-hour-line) calc(var(--hour-height) - 1px),
|
|
var(--color-hour-line) var(--hour-height)
|
|
);
|
|
pointer-events: none;
|
|
}
|
|
}
|
|
|
|
/* Kvarterlinjer - 3 linjer per time (15, 30, 45 min) */
|
|
swp-grid-lines {
|
|
display: block;
|
|
position: absolute;
|
|
inset: 0;
|
|
z-index: 1;
|
|
background-image: repeating-linear-gradient(
|
|
to bottom,
|
|
transparent 0,
|
|
transparent calc(var(--hour-height) / 4 - 1px),
|
|
var(--color-grid-line-light) calc(var(--hour-height) / 4 - 1px),
|
|
var(--color-grid-line-light) calc(var(--hour-height) / 4),
|
|
transparent calc(var(--hour-height) / 4),
|
|
transparent calc(var(--hour-height) / 2 - 1px),
|
|
var(--color-grid-line-light) calc(var(--hour-height) / 2 - 1px),
|
|
var(--color-grid-line-light) calc(var(--hour-height) / 2),
|
|
transparent calc(var(--hour-height) / 2),
|
|
transparent calc(var(--hour-height) * 3 / 4 - 1px),
|
|
var(--color-grid-line-light) calc(var(--hour-height) * 3 / 4 - 1px),
|
|
var(--color-grid-line-light) calc(var(--hour-height) * 3 / 4),
|
|
transparent calc(var(--hour-height) * 3 / 4),
|
|
transparent var(--hour-height)
|
|
);
|
|
}
|
|
|
|
swp-day-columns {
|
|
position: absolute;
|
|
inset: 0;
|
|
display: grid;
|
|
grid-template-columns: repeat(var(--grid-columns), minmax(var(--day-column-min-width), 1fr));
|
|
min-width: calc(var(--grid-columns) * var(--day-column-min-width));
|
|
}
|
|
|
|
swp-day-column {
|
|
position: relative;
|
|
border-right: 1px solid var(--color-border);
|
|
}
|
|
|
|
swp-events-layer {
|
|
position: absolute;
|
|
inset: 0;
|
|
z-index: 10;
|
|
}
|
|
|
|
/* Unavailable time zones (outside working hours) */
|
|
swp-unavailable-layer {
|
|
position: absolute;
|
|
inset: 0;
|
|
z-index: 5;
|
|
pointer-events: none;
|
|
}
|
|
|
|
swp-unavailable-zone {
|
|
position: absolute;
|
|
left: 0;
|
|
right: 0;
|
|
background: var(--color-unavailable, rgba(0, 0, 0, 0.05));
|
|
pointer-events: none;
|
|
}
|