Skip to content
Snippets Groups Projects
Verified Commit c3011c73 authored by Volker Schukai's avatar Volker Schukai :alien:
Browse files

fix: optimize calendar view #296

 Conflicts:
	source/components/form/stylesheet/context-help.mjs
	source/components/time/stylesheet/month-calendar.mjs
	source/components/time/timeline/stylesheet/segment.mjs
parent 0f0ae687
No related branches found
No related tags found
No related merge requests found
Showing
with 1106 additions and 787 deletions
...@@ -43,6 +43,11 @@ ...@@ -43,6 +43,11 @@
"startDate": "2025-03-01", "startDate": "2025-03-01",
"endDate": "2025-03-01", "endDate": "2025-03-01",
"color": "#a32408" "color": "#a32408"
}, {
"id": "42",
"startDate": "2025-03-01",
"endDate": "2025-03-01",
"color": "#a32408"
}, },
{ {
......
File moved
{ {
"name": "@schukai/monster", "name": "@schukai/monster",
"version": "3.112.0", "version": "3.112.1",
"lockfileVersion": 3, "lockfileVersion": 3,
"requires": true, "requires": true,
"packages": { "packages": {
"": { "": {
"name": "@schukai/monster", "name": "@schukai/monster",
"version": "3.112.0", "version": "3.112.1",
"license": "AGPL 3.0", "license": "AGPL 3.0",
"dependencies": { "dependencies": {
"@floating-ui/dom": "^1.6.13", "@floating-ui/dom": "^1.6.13",
......
...@@ -13,7 +13,7 @@ ...@@ -13,7 +13,7 @@
import {addAttributeToken} from "../../../dom/attributes.mjs"; import {addAttributeToken} from "../../../dom/attributes.mjs";
import {ATTRIBUTE_ERRORMESSAGE} from "../../../dom/constants.mjs"; import {ATTRIBUTE_ERRORMESSAGE} from "../../../dom/constants.mjs";
export { ContextHelpStyleSheet }; export {ContextHelpStyleSheet}
/** /**
* @private * @private
...@@ -22,17 +22,10 @@ export { ContextHelpStyleSheet }; ...@@ -22,17 +22,10 @@ export { ContextHelpStyleSheet };
const ContextHelpStyleSheet = new CSSStyleSheet(); const ContextHelpStyleSheet = new CSSStyleSheet();
try { try {
ContextHelpStyleSheet.insertRule( ContextHelpStyleSheet.insertRule(`
`
@layer contexthelp { @layer contexthelp {
[data-monster-role=control]{box-sizing:border-box;outline:none;width:100%}[data-monster-role=control].flex{align-items:center;display:flex;flex-direction:row}:host{box-sizing:border-box;display:block}div[data-monster-role=popper]{align-content:center;background:var(--monster-bg-color-primary-1);border-color:var(--monster-bg-color-primary-4);border-radius:var(--monster-border-radius);border-style:var(--monster-border-style);border-width:var(--monster-border-width);box-shadow:var(--monster-box-shadow-1);box-sizing:border-box;color:var(--monster-color-primary-1);display:none;justify-content:space-between;left:0;padding:1.1em;position:absolute;top:0;width:-moz-max-content;width:max-content;z-index:var(--monster-z-index-modal)}div[data-monster-role=popper] div[data-monster-role=arrow]{background:var(--monster-bg-color-primary-1);height:calc(max(var(--monster-popper-witharrrow-distance), -1 * var(--monster-popper-witharrrow-distance))*2);pointer-events:none;position:absolute;width:calc(max(var(--monster-popper-witharrrow-distance), -1 * var(--monster-popper-witharrrow-distance))*2);z-index:-1}[data-monster-role=control]{line-height:1em;margin:0;padding:0;position:relative}[data-monster-role=control] [data-monster-role=button]{display:inline-block;position:relative}:is([data-monster-role=control] [data-monster-role=button]) svg{cursor:pointer}:is([data-monster-role=control] [data-monster-role=button]) svg.hidden{cursor:default;visibility:hidden}[data-monster-role=popper]{z-index:1000}:host{display:inline-block;margin:0 .2em;padding:0;position:relative;vertical-align:bottom} [data-monster-role=control]{box-sizing:border-box;outline:none;width:100%}[data-monster-role=control].flex{align-items:center;display:flex;flex-direction:row}:host{box-sizing:border-box;display:block}div[data-monster-role=popper]{align-content:center;background:var(--monster-bg-color-primary-1);border-color:var(--monster-bg-color-primary-4);border-radius:var(--monster-border-radius);border-style:var(--monster-border-style);border-width:var(--monster-border-width);box-shadow:var(--monster-box-shadow-1);box-sizing:border-box;color:var(--monster-color-primary-1);display:none;justify-content:space-between;left:0;padding:1.1em;position:absolute;top:0;width:-moz-max-content;width:max-content;z-index:var(--monster-z-index-modal)}div[data-monster-role=popper] div[data-monster-role=arrow]{background:var(--monster-bg-color-primary-1);height:calc(max(var(--monster-popper-witharrrow-distance), -1 * var(--monster-popper-witharrrow-distance))*2);pointer-events:none;position:absolute;width:calc(max(var(--monster-popper-witharrrow-distance), -1 * var(--monster-popper-witharrrow-distance))*2);z-index:-1}[data-monster-role=control]{line-height:1em;margin:0;padding:0;position:relative}[data-monster-role=control] [data-monster-role=button]{display:inline-block;position:relative}:is([data-monster-role=control] [data-monster-role=button]) svg{cursor:pointer}:is([data-monster-role=control] [data-monster-role=button]) svg.hidden{cursor:default;visibility:hidden}[data-monster-role=popper]{z-index:var(--monster-z-index-tooltip-overlay)}:host{display:inline-block;margin:0 .2em;padding:0;position:relative;vertical-align:bottom}
}`, }`, 0);
0,
);
} catch (e) { } catch (e) {
addAttributeToken( addAttributeToken(document.getRootNode().querySelector('html'), ATTRIBUTE_ERRORMESSAGE, e + "");
document.getRootNode().querySelector("html"),
ATTRIBUTE_ERRORMESSAGE,
e + "",
);
} }
This diff is collapsed.
...@@ -541,7 +541,7 @@ function findScrollableParent(element) { ...@@ -541,7 +541,7 @@ function findScrollableParent(element) {
while (parent) { while (parent) {
// Check the scroll properties of the element // Check the scroll properties of the element
const overflowY = window.getComputedStyle(parent).overflowY; const overflowY = window.getComputedStyle(parent).overflowY;
if (overflowY === 'scroll' || overflowY === 'auto') { if (overflowY === "scroll" || overflowY === "auto") {
return parent; return parent;
} }
parent = getNextParent(parent); // Move to the next parent element parent = getNextParent(parent); // Move to the next parent element
...@@ -549,7 +549,6 @@ function findScrollableParent(element) { ...@@ -549,7 +549,6 @@ function findScrollableParent(element) {
return window; // Fallback if no scrollable element is found return window; // Fallback if no scrollable element is found
} }
/** /**
* @private * @private
* @return {void} * @return {void}
......
...@@ -42,6 +42,7 @@ import {Datasource} from "../datatable/datasource.mjs"; ...@@ -42,6 +42,7 @@ import {Datasource} from "../datatable/datasource.mjs";
import { Observer } from "../../types/observer.mjs"; import { Observer } from "../../types/observer.mjs";
import { positionPopper } from "../form/util/floating-ui.mjs"; import { positionPopper } from "../form/util/floating-ui.mjs";
import { Segment as AppointmentSegment } from "./timeline/segment.mjs"; import { Segment as AppointmentSegment } from "./timeline/segment.mjs";
import { Appointment as AppointmentAppointment } from "./timeline/appointment.mjs";
export { MonthCalendar }; export { MonthCalendar };
...@@ -109,7 +110,20 @@ class MonthCalendar extends CustomElement { ...@@ -109,7 +110,20 @@ class MonthCalendar extends CustomElement {
* The individual configuration values can be found in the table. * The individual configuration values can be found in the table.
* *
* @property {Object} templates Template definitions * @property {Object} templates Template definitions
* @property {string} templates.main Main template
* @property {Object} labels Labels for the control
* @property {Object} classes Classes for the control
* @property {boolean} disabled Disables the control
* @property {Object} features Features for the control
* @property {boolean} features.showWeekend Show the weekend
* @property {boolean} features.monthOneLine Show the month in one line
* @property {Object} actions Actions for the control
* @property {Object} locale Locale for the control
* @property {string} locale.weekdayFormat Weekday format
* @property {string} startDate Start date
* @property {string} endDate End date
* @property {Object} datasource Datasource
* @property {string} datasource.selector Datasource selector
*/ */
get defaults() { get defaults() {
const startDate = new Date(); const startDate = new Date();
...@@ -201,7 +215,6 @@ function getTranslations() { ...@@ -201,7 +215,6 @@ function getTranslations() {
} }
} }
/** /**
* Calculates how many days of an appointment are distributed across calendar rows (weeks). * Calculates how many days of an appointment are distributed across calendar rows (weeks).
* Uses the start date of the calendar grid (e.g., from generateCalendarData()) as a reference. * Uses the start date of the calendar grid (e.g., from generateCalendarData()) as a reference.
...@@ -369,6 +382,19 @@ function initDataSource() { ...@@ -369,6 +382,19 @@ function initDataSource() {
}, 10); }, 10);
} }
/**
* Places and organizes appointments within a calendar grid according to their start and end dates,
* ensuring proper alignment and rendering within the calendar day containers.
*
* Appointments are evaluated to determine their appropriate positions, lengths, and styles based on calendar
* configuration and available rendering space.
*
* Errors are logged for invalid appointment data or when
* rendering issues are encountered.
*
* @private
* @return {void} No return value; the method operates on the DOM and internal state of the calendar element to render appointments visually.
*/
function placeAppointments() { function placeAppointments() {
const self = this; const self = this;
...@@ -389,6 +415,7 @@ function placeAppointments() { ...@@ -389,6 +415,7 @@ function placeAppointments() {
calenderStartDate, calenderStartDate,
calenderEndDate, calenderEndDate,
); );
calendarDays.forEach((day) => { calendarDays.forEach((day) => {
const k = const k =
day.date.getFullYear() + day.date.getFullYear() +
...@@ -406,17 +433,6 @@ function placeAppointments() { ...@@ -406,17 +433,6 @@ function placeAppointments() {
} }
const startDate = appointment?.startDate; const startDate = appointment?.startDate;
let container = self.shadowRoot.querySelector(
`[data-monster-day="${startDate}"] > [data-monster-role="appointment-container"]`,
);
if (!container) {
addErrorAttribute(
this,
"Invalid, missing or out of range date in appointment" + startDate,
);
return;
}
// calc length of appointment // calc length of appointment
const start = new Date(startDate); const start = new Date(startDate);
...@@ -489,10 +505,21 @@ function placeAppointments() { ...@@ -489,10 +505,21 @@ function placeAppointments() {
const sortedSegments = assignLinesToSegments(segments); const sortedSegments = assignLinesToSegments(segments);
const h = calcHeaderAndFooterHeight.call(this); const h = calcHeaderAndFooterHeight.call(this);
const marginAppointmentContainer = h.maxFooterHeight + h.maxHeaderHeight; const marginAppointmentContainer = h.maxFooterHeight + h.maxHeaderHeight;
const popper = self.shadowRoot.querySelectorAll(
"monster-appointment-segment",
);
if (popper) {
for (const p of popper) {
p.remove();
}
}
const daysWithMoreAppointments = new Set();
const moreAppointments = new Map();
for (let i = 0; i < sortedSegments.length; i++) { for (let i = 0; i < sortedSegments.length; i++) {
const segment = sortedSegments[i]; const segment = sortedSegments[i];
...@@ -500,16 +527,34 @@ function placeAppointments() { ...@@ -500,16 +527,34 @@ function placeAppointments() {
`[data-monster-day="${segment.start}"]`, `[data-monster-day="${segment.start}"]`,
); );
if (!container) {
continue;
}
let containerHeight = container?.getBoundingClientRect()?.height || 0; let containerHeight = container?.getBoundingClientRect()?.height || 0;
if (containerHeight === 0) { if (containerHeight === 0) {
addErrorAttribute(this, "Unable to retrieve container height"); addErrorAttribute(this, "Unable to retrieve container height");
continue; continue;
} }
let availableHeight = containerHeight - maxLineHeight - marginAppointmentContainer; let availableHeight =
containerHeight - maxLineHeight - marginAppointmentContainer;
let linesThatCanBeShown = Math.floor(availableHeight / maxLineHeight); let linesThatCanBeShown = Math.floor(availableHeight / maxLineHeight);
if (segment.line > linesThatCanBeShown) { if (segment.line > linesThatCanBeShown) {
daysWithMoreAppointments.add(segment.start);
const calendarDays = this.getOption("calendarDays");
const currentDay = calendarDays.find((day) => day.day === segment.start);
if (currentDay) {
if (!moreAppointments.has(currentDay.index)) {
moreAppointments.set(currentDay.index, []);
}
moreAppointments.get(currentDay.index).push(segment);
}
continue; continue;
} }
...@@ -550,24 +595,74 @@ function placeAppointments() { ...@@ -550,24 +595,74 @@ function placeAppointments() {
container.appendChild(appointmentSegment); container.appendChild(appointmentSegment);
} }
// mark days with more appointments, show a hint / link
for (const day of daysWithMoreAppointments) {
for (const cell of this.getOption("calendarDays")) {
if (cell.day === day) {
this.setOption(
"calendarDays." + cell.index + ".classes.more-appointments",
"visible",
);
}
}
} }
// get popper
for (const [index, appointments] of moreAppointments) {
const moreAppointmentsContainer = this.shadowRoot.querySelector(
`[data-monster-role=day-cell][data-monster-index="${index}"] > [data-monster-role="appointment-popper"] `,
);
if (!moreAppointmentsContainer) {
continue;
}
moreAppointmentsContainer.innerHTML = "";
for (const appointment of appointments) {
const appointmentSegment = document.createElement("monster-appointment");
appointmentSegment.style.backgroundColor = appointment.appointment.color;
appointmentSegment.style.position = "relative";
appointmentSegment.style.top = "unset";
// search a color that is readable on the background color
const rgb = appointmentSegment.style.backgroundColor.match(/\d+/g);
const brightness = Math.round(
(parseInt(rgb[0]) * 299 +
parseInt(rgb[1]) * 587 +
parseInt(rgb[2]) * 114) /
1000,
);
if (brightness > 125) {
appointmentSegment.style.color = "#000000";
} else {
appointmentSegment.style.color = "#ffffff";
}
appointmentSegment.style.width = "100%";
appointmentSegment.style.height = maxLineHeight + "px";
appointmentSegment.setOption("labels.text", appointment.label);
moreAppointmentsContainer.appendChild(appointmentSegment);
}
}
}
/** /**
* @private * @private
* @returns {{maxHeaderHeight: number, maxFooterHeight: number}} * @returns {{maxHeaderHeight: number, maxFooterHeight: number}}
*/ */
function calcHeaderAndFooterHeight() { function calcHeaderAndFooterHeight() {
let maxHeaderHeight = 0; let maxHeaderHeight = 0;
let maxFooterHeight = 0; let maxFooterHeight = 0;
const days = this.getOption("calendarDays"); const days = this.getOption("calendarDays");
for (const day of days) { for (const day of days) {
const current = day.date; const current = day.date;
const dayKey = const dayKey =
current.getFullYear() + current.getFullYear() +
"-" + "-" +
...@@ -586,7 +681,6 @@ function calcHeaderAndFooterHeight() { ...@@ -586,7 +681,6 @@ function calcHeaderAndFooterHeight() {
const header = cell.querySelector("[data-monster-role='day-header']"); const header = cell.querySelector("[data-monster-role='day-header']");
if (header instanceof HTMLDivElement) { if (header instanceof HTMLDivElement) {
maxHeaderHeight = Math.max( maxHeaderHeight = Math.max(
maxHeaderHeight, maxHeaderHeight,
header.getBoundingClientRect().height + header.getBoundingClientRect().height +
...@@ -598,7 +692,6 @@ function calcHeaderAndFooterHeight() { ...@@ -598,7 +692,6 @@ function calcHeaderAndFooterHeight() {
parseFloat(getComputedStyle(header.parentElement).paddingBottom) + parseFloat(getComputedStyle(header.parentElement).paddingBottom) +
parseFloat(getComputedStyle(header.parentElement).marginTop), parseFloat(getComputedStyle(header.parentElement).marginTop),
); );
} }
const footer = cell.querySelector("[data-monster-role='day-footer']"); const footer = cell.querySelector("[data-monster-role='day-footer']");
...@@ -690,12 +783,16 @@ function generateCalendarData() { ...@@ -690,12 +783,16 @@ function generateCalendarData() {
label: label, label: label,
index: i, index: i,
day: dayKey, day: dayKey,
classes: {
classes: "more-appointments": "hidden",
cell:
"day-cell " + "day-cell " +
(current.getMonth() === month ? "current-month" : "other-month") + (current.getMonth() === month ? "current-month" : "other-month") +
(current.getDay() === 0 || current.getDay() === 6 ? " weekend" : "") + (current.getDay() === 0 || current.getDay() === 6 ? " weekend" : "") +
(current.toDateString() === new Date().toDateString() ? " today" : ""), (current.toDateString() === new Date().toDateString()
? " today"
: ""),
},
appointments: [], appointments: [],
}); });
} }
...@@ -771,7 +868,6 @@ function getAppointmentsPerDay(appointments, start, end) { ...@@ -771,7 +868,6 @@ function getAppointmentsPerDay(appointments, start, end) {
/** /**
* @private * @private
* @return {initEventHandler} * @return {initEventHandler}
* @fires monster-calendar-clicked
*/ */
function initEventHandler() { function initEventHandler() {
const self = this; const self = this;
...@@ -787,13 +883,11 @@ function initEventHandler() { ...@@ -787,13 +883,11 @@ function initEventHandler() {
.querySelectorAll("[data-monster-role='day-cell']") .querySelectorAll("[data-monster-role='day-cell']")
.forEach((element) => { .forEach((element) => {
element.addEventListener("click", (event) => { element.addEventListener("click", (event) => {
console.log(event.relatedTarget, "event1");
console.log(event.composedPath(), "event");
const hoveredElement = this.shadowRoot.elementFromPoint( const hoveredElement = this.shadowRoot.elementFromPoint(
event.clientX, event.clientX,
event.clientY, event.clientY,
); );
if (hoveredElement instanceof AppointmentSegment) { if (hoveredElement instanceof AppointmentSegment) {
return; return;
} }
...@@ -801,14 +895,15 @@ function initEventHandler() { ...@@ -801,14 +895,15 @@ function initEventHandler() {
const element = findTargetElementFromEvent( const element = findTargetElementFromEvent(
event, event,
"data-monster-role", "data-monster-role",
"day-cell", "more-appointments",
); );
if (!element) { if (!element) {
return; return;
} }
const popper = element.querySelector( // parent is footer, and parent of footer is cell
const popper = element.parentElement.parentElement.querySelector(
'[data-monster-role="appointment-popper"]', '[data-monster-role="appointment-popper"]',
); );
...@@ -816,13 +911,14 @@ function initEventHandler() { ...@@ -816,13 +911,14 @@ function initEventHandler() {
return; return;
} }
positionPopper(element, popper, { //const appointments = getAppointmentsPerDay() || [];
const container = element.parentElement.parentElement;
positionPopper(container, popper, {
placement: "bottom", placement: "bottom",
}); });
//const appointments = getAppointmentsPerDay() || []; popper.style.width = container.getBoundingClientRect().width + "px";
popper.style.width = element.getBoundingClientRect().width + "px";
popper.style.zIndex = 1000; popper.style.zIndex = 1000;
popper.style.display = "block"; popper.style.display = "block";
...@@ -894,20 +990,20 @@ function getTemplate() { ...@@ -894,20 +990,20 @@ function getTemplate() {
return ` return `
<template id="cell"> <template id="cell">
<div data-monster-role="day-cell" <div data-monster-role="day-cell"
data-monster-attributes="class path:cell.classes, data-monster-attributes="class path:cell.classes.cell,
data-monster-day path:cell.day, data-monster-day path:cell.day,
data-monster-index path:cell.index"> data-monster-index path:cell.index">
<div class="header" data-monster-role="day-header"> <div class="header" data-monster-role="day-header">
<div data-monster-replace="path:cell.label"></div> <div data-monster-replace="path:cell.label"></div>
</div> </div>
<div data-monster-role="appointment-container"
data-monster-attributes="data-monster-calendar-index path:cell.index"></div>
<div class="footer" data-monster-role="day-footer"> <div class="footer" data-monster-role="day-footer">
<div data-monster-replace="path:labels.more" <div data-monster-replace="path:labels.more"
data-monster-attributes="data-monster-day-more path:cell.day"></div> data-monster-attributes="class path:cell.classes.more-appointments"
data-monster-role="more-appointments"></div>
</div> </div>
<div data-monster-role="appointment-popper" <div data-monster-role="appointment-popper"
class="popper" data-monster-replace="path:cell.appointments"></div> class="popper"></div>
</div> </div>
</template> </template>
......
...@@ -50,14 +50,12 @@ div.popper { ...@@ -50,14 +50,12 @@ div.popper {
z-index: var(--monster-z-index-dropdown); z-index: var(--monster-z-index-dropdown);
background-color: var(--monster-bg-color-primary-1); background-color: var(--monster-bg-color-primary-1);
color: var(--monster-color-primary-1); color: var(--monster-color-primary-1);
border-radius: var(--monster-theme-control-border-radius); border: none;
border-width: var(--monster-theme-control-border-width);
border-color: var(--monster-theme-control-border-color);
border-style: var(--monster-theme-control-border-style);
box-shadow: var(--monster-box-shadow-1); box-shadow: var(--monster-box-shadow-1);
padding: 0.5em; padding: 0;
display: none; display: none;
box-sizing: border-box; box-sizing: border-box;
outline: 1px solid var(--monster-color-primary-1);
} }
div.day-cell { div.day-cell {
...@@ -77,7 +75,14 @@ div.day-cell { ...@@ -77,7 +75,14 @@ div.day-cell {
div.footer { div.footer {
font-size: xx-small; font-size: xx-small;
}
[data-monster-role="more-appointments"] {
cursor: pointer;
}
.hidden {
display: none;
} }
div.current-month { div.current-month {
...@@ -95,7 +100,6 @@ div.today { ...@@ -95,7 +100,6 @@ div.today {
color : var(--monster-color-primary-4); color : var(--monster-color-primary-4);
} }
[data-monster-role=appointment-container] { [data-monster-role=appointment-container] {
position: absolute; position: absolute;
box-sizing: border-box; box-sizing: border-box;
......
This diff is collapsed.
/**
* Copyright © schukai GmbH and all contributing authors, {{copyRightYear}}. All rights reserved.
* Node module: @schukai/monster
*
* This source code is licensed under the GNU Affero General Public License version 3 (AGPLv3).
* The full text of the license can be found at: https://www.gnu.org/licenses/agpl-3.0.en.html
*
* For those who do not wish to adhere to the AGPLv3, a commercial license is available.
* Acquiring a commercial license allows you to use this software without complying with the AGPLv3 terms.
* For more information about purchasing a commercial license, please contact schukai GmbH.
*/
import { instanceSymbol } from "../../../constants.mjs";
import { ATTRIBUTE_ROLE } from "../../../dom/constants.mjs";
import { CustomElement } from "../../../dom/customelement.mjs";
import {
assembleMethodSymbol,
registerCustomElement,
} from "../../../dom/customelement.mjs";
import { AppointmentStyleSheet } from "./stylesheet/appointment.mjs";
export { Appointment };
/**
* @private
* @type {symbol}
*/
const controlElementSymbol = Symbol("calendarElement");
/**
* Am appointment is a part of the calendar that represents a single appointment.
*
* @fragments /fragments/components/time/timeline/appointment
*
* @example /examples/components/time/timeline/appointment-simple
*
* @since 3.113.0
* @copyright schukai GmbH
* @summary An appointment is a part of the calendar that represents a single appointment.
*/
class Appointment extends CustomElement {
/**
* This method is called by the `instanceof` operator.
* @returns {symbol}
*/
static get [instanceSymbol]() {
return Symbol.for(
"@schukai/monster/components/time/appointment/segment@@instance",
);
}
/**
*
* @return {Components.Time.Calendar
*/
[assembleMethodSymbol]() {
super[assembleMethodSymbol]();
initControlReferences.call(this);
initEventHandler.call(this);
return this;
}
/**
* To set the options via the HTML Tag, the attribute `data-monster-options` must be used.
* @see {@link https://monsterjs.org/en/doc/#configurate-a-monster-control}
*
* The individual configuration values can be found in the table.
*
* @property {Object} templates Template definitions
* @property {string} templates.main Main template
* @property {Object} labels Label definitions
* @property {Object} actions Callbacks
* @property {string} actions.click="throw Error" Callback when clicked
* @property {Object} features Features
* @property {Object} classes CSS classes
* @property {boolean} disabled=false Disabled state
*/
get defaults() {
return Object.assign({}, super.defaults, {
templates: {
main: getTemplate(),
},
labels: {
text: "Appointment",
},
classes: {},
disabled: false,
features: {},
actions: {},
startDate: "",
calendarDays: [],
calendarWeekdays: [],
});
}
/**
* @return {string}
*/
static getTag() {
return "monster-appointment";
}
/**
* @return {CSSStyleSheet[]}
*/
static getCSSStyleSheet() {
return [AppointmentStyleSheet];
}
}
/**
* @private
* @return {initEventHandler}
*/
function initEventHandler() {
const self = this;
return this;
}
/**
* @private
* @return {void}
*/
function initControlReferences() {
this[controlElementSymbol] = this.shadowRoot.querySelector(
`[${ATTRIBUTE_ROLE}="control"]`,
);
}
/**
* @private
* @return {string}
*/
function getTemplate() {
// language=HTML
return `
<div data-monster-role="control" part="control">
<div data-monster-role="appointment" data-monster-replace="path:labels.text" part="appointment"></div>
</div>
`;
}
registerCustomElement(Appointment);
...@@ -38,18 +38,18 @@ export { Segment }; ...@@ -38,18 +38,18 @@ export { Segment };
* @private * @private
* @type {symbol} * @type {symbol}
*/ */
export const calendarElementSymbol = Symbol("calendarElement"); const controlElementSymbol = Symbol("calendarElement");
/** /**
* A Calendar * A Calendar segment is a part of the calendar that represents a single appointment.
* *
* @fragments /fragments/components/time/calendar/ * @fragments /fragments/components/time/timeline/segment
* *
* @example /examples/components/time/calendar-simple * @example /examples/components/time/timeline/segment-simple
* *
* @since 3.112.0 * @since 3.112.0
* @copyright schukai GmbH * @copyright schukai GmbH
* @summary A beautiful Calendar that can make your life easier and also looks good. * @summary A calendar segment is a part of the calendar that represents a single appointment.
*/ */
class Segment extends CustomElement { class Segment extends CustomElement {
/** /**
...@@ -103,10 +103,6 @@ class Segment extends CustomElement { ...@@ -103,10 +103,6 @@ class Segment extends CustomElement {
features: {}, features: {},
actions: {}, actions: {},
// locale : {
// weekdayFormat: 'short',
// },
startDate: "", startDate: "",
calendarDays: [], calendarDays: [],
calendarWeekdays: [], calendarWeekdays: [],
...@@ -144,7 +140,7 @@ function initEventHandler() { ...@@ -144,7 +140,7 @@ function initEventHandler() {
* @return {void} * @return {void}
*/ */
function initControlReferences() { function initControlReferences() {
this[calendarElementSymbol] = this.shadowRoot.querySelector( this[controlElementSymbol] = this.shadowRoot.querySelector(
`[${ATTRIBUTE_ROLE}="control"]`, `[${ATTRIBUTE_ROLE}="control"]`,
); );
} }
......
@import "../../../style/property.pcss";
@import "../../../style/control.pcss";
@import "../../../style/accessibility.pcss";
@import "../../../style/button.pcss";
@import "../../../style/border.pcss";
@import "../../../style/typography.pcss";
@import "../../../style/theme.pcss";
@import "../../../style/color.pcss";
:host {
display: flex;
height: 0.5rem;
position: initial;
}
[data-monster-role="control"] {
display: flex;
position: relative;
flex-grow: 1;
border: none;
outline: none;
overflow: hidden;
padding: 0 2px;
}
...@@ -23,4 +23,5 @@ ...@@ -23,4 +23,5 @@
border: none; border: none;
outline: none; outline: none;
overflow: hidden; overflow: hidden;
padding: 0 2px;
} }
This diff is collapsed.
...@@ -30,6 +30,7 @@ export * from "./components/layout/slider.mjs"; ...@@ -30,6 +30,7 @@ export * from "./components/layout/slider.mjs";
export * from "./components/content/viewer.mjs"; export * from "./components/content/viewer.mjs";
export * from "./components/content/copy.mjs"; export * from "./components/content/copy.mjs";
export * from "./components/content/camera.mjs"; export * from "./components/content/camera.mjs";
export * from "./components/time/timeline/appointment.mjs";
export * from "./components/time/timeline/segment.mjs"; export * from "./components/time/timeline/segment.mjs";
export * from "./components/time/month-calendar.mjs"; export * from "./components/time/month-calendar.mjs";
export * from "./components/form/message-state-button.mjs"; export * from "./components/form/message-state-button.mjs";
......
...@@ -156,7 +156,7 @@ function getMonsterVersion() { ...@@ -156,7 +156,7 @@ function getMonsterVersion() {
} }
/** don't touch, replaced by make with package.json version */ /** don't touch, replaced by make with package.json version */
monsterVersion = new Version("3.112.0"); monsterVersion = new Version("3.112.1");
return monsterVersion; return monsterVersion;
} }
...@@ -7,7 +7,7 @@ describe('Monster', function () { ...@@ -7,7 +7,7 @@ describe('Monster', function () {
let monsterVersion let monsterVersion
/** don´t touch, replaced by make with package.json version */ /** don´t touch, replaced by make with package.json version */
monsterVersion = new Version("3.112.0") monsterVersion = new Version("3.112.1")
let m = getMonsterVersion(); let m = getMonsterVersion();
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment