diff --git a/components/calendar/package.json b/components/calendar/package.json
index cc4b545ecc..f5c1aadaa7 100644
--- a/components/calendar/package.json
+++ b/components/calendar/package.json
@@ -29,6 +29,7 @@
"dependencies": {
"@vonage/vvd-core": "2.9.0",
"lit-element": "^2.4.0",
+ "lit-html": "^1.3.0",
"tslib": "^2.0.3"
},
"devDependencies": {
diff --git a/components/calendar/src/_vwc-calendar-variables.scss b/components/calendar/src/_vwc-calendar-variables.scss
new file mode 100644
index 0000000000..54115a3525
--- /dev/null
+++ b/components/calendar/src/_vwc-calendar-variables.scss
@@ -0,0 +1,15 @@
+// snap fraction within an hour
+$fraction: 4;
+// number of columns according to days of week
+$total-columns: 7;
+// the rows according to hours a day
+$total-rows: 24;
+
+
+// event variables
+$color: --vvd-calendar-event--primary-color;
+$day: --vvd-calendar-event--day;
+$start: --vvd-calendar-event--start;
+$duration: --vvd-calendar-event--duration;
+$indent: --vvd-calendar-event--indent;
+$overlap-count: --vvd-calendar-event--overlap-count;
diff --git a/components/calendar/src/vwc-calendar-event.scss b/components/calendar/src/vwc-calendar-event.scss
index 5a77e791c0..a60bbe8a5c 100644
--- a/components/calendar/src/vwc-calendar-event.scss
+++ b/components/calendar/src/vwc-calendar-event.scss
@@ -1,22 +1,37 @@
-$indent: --vvd-calendar-event-indent;
-$overlap-count: --vvd-calendar-event-overlap-count;
-$event-color: --vvd-calendar-event-event-color;
-$event-day: --vvd-calendar-event-event-day;
-$event-row: --vvd-calendar-event-event-row;
+@use '@vonage/vvd-typography/scss/typography';
+@use '@vonage/vvd-design-tokens/build/scss/semantic-variables/scheme-variables';
+@use 'vwc-calendar-variables' as calendar-variables;
:host {
display: contents;
}
section {
- #{$indent}: calc(var(#{$overlap-count}, 0) * 8px);
- z-index: var(#{$overlap-count});
- margin: 1px 1px 1px calc(1px + var(#{$indent}));
- background-color: var(#{$event-color});
- border-radius: 3.64752px;
- grid-column: var(#{$event-day});
- grid-row: var(#{$event-row});
+ #{calendar-variables.$indent}: calc(var(#{calendar-variables.$overlap-count}, 0) * 8px);
+ z-index: var(#{calendar-variables.$overlap-count});
+ overflow: hidden;
+ padding: 16px;
+ margin: 1px 1px 1px calc(1px + var(#{calendar-variables.$indent}));
+ background-color: var(#{calendar-variables.$color}, var(#{scheme-variables.$vvd-color-neutral-40}));
+ border-radius: 6px;
+ color: var(#{scheme-variables.$vvd-color-on-primary});
+ contain: strict;
+ grid-column: var(#{calendar-variables.$day});
+ grid-row: var(#{calendar-variables.$start}) / span var(#{calendar-variables.$duration});
&:focus {
z-index: 2000;
}
}
+
+h2 {
+ @include typography.typography-cat-shorthand('body-2-bold');
+ margin: 0 0 4px;
+ > strong {
+ font: inherit;
+ }
+}
+
+p {
+ @include typography.typography-cat-shorthand('caption');
+ margin: 0;
+}
diff --git a/components/calendar/src/vwc-calendar-event.ts b/components/calendar/src/vwc-calendar-event.ts
index 2fa8ddf027..1efe1d7411 100644
--- a/components/calendar/src/vwc-calendar-event.ts
+++ b/components/calendar/src/vwc-calendar-event.ts
@@ -1,8 +1,9 @@
import '@vonage/vvd-core';
import {
- customElement, html, LitElement, property, TemplateResult, unsafeCSS
+ customElement, html, LitElement, property, TemplateResult
} from 'lit-element';
import { style } from './vwc-calendar-event.css';
+import { styleMap } from 'lit-html/directives/style-map';
declare global {
interface HTMLElementTagNameMap {
@@ -23,31 +24,74 @@ export class VWCCalendarEvent extends LitElement {
static styles = [style];
/**
- * @prop the label of the event
+ * @prop the heading of the event
* @public
* */
- @property({ type: String, reflect: true })
- label?: string;
+ @property({ type: String, reflect: false })
+ heading?: string;
+
+ /**
+ * @prop the description of the event
+ * @public
+ * */
+ @property({ type: String, reflect: false })
+ description?: string;
/**
* @prop day - day of the week (starts from 0)
* @public
* */
- @property({ type: Number, reflect: true })
- day?: 0 | 1 | 2 | 3 | 4 | 5 | 6;
+ @property({ type: Number, reflect: false })
+ day: 1 | 2 | 3 | 4 | 5 | 6 | 7 = 1;
+
+ /**
+ * @prop color - color of event card
+ * @public
+ * */
+ @property({ type: String, reflect: false })
+ color?: string;
+
+ /**
+ * @prop sets card display precendence and indentation
+ * @public
+ * */
+ @property({ type: String, reflect: false, attribute: 'overlap-count' })
+ overlapCount?: string;
+
+ /**
+ * @prop start - time of day event starts
+ * @public
+ * */
+ @property({ type: Number, reflect: false })
+ start = 0; // TODO should be converted to allowed range
+
+ /**
+ * @prop duration - event's time duration in hours
+ * @public
+ * */
+ @property({ type: Number, reflect: false })
+ duration = 1; // TODO should be converted to allowed range
/**
* the html markup
* @internal
* */
protected render(): TemplateResult {
+ const styles = {
+ ...this.color && { '--vvd-calendar-event--primary-color': this.color },
+ ...this.overlapCount && { '--vvd-calendar-event--overlap-count': this.overlapCount },
+ '--vvd-calendar-event--start': (this.start + 1).toString(),
+ '--vvd-calendar-event--duration': (this.duration).toString(),
+ '--vvd-calendar-event--day': this.day.toString()
+ };
return html`
-
+ ${this.heading}
+ ${this.description}
`;
}
diff --git a/components/calendar/src/vwc-calendar.scss b/components/calendar/src/vwc-calendar.scss
index bdbbf38184..947f19fc29 100644
--- a/components/calendar/src/vwc-calendar.scss
+++ b/components/calendar/src/vwc-calendar.scss
@@ -1,3 +1,4 @@
+@use 'vwc-calendar-variables' as calendar-variables;
@use '@vonage/vvd-design-tokens/build/scss/semantic-variables/scheme-variables';
@use '@vonage/vvd-typography/scss/typography';
@@ -7,13 +8,6 @@ ol {
list-style: none;
}
-// snap fraction within an hour
-$fraction: 4;
-// the rows according to hours a day
-$total-rows: 24;
-// number of columns according to days of week
-$total-columns: 7;
-
.container {
display: grid;
width: max(100%, 500px);
@@ -27,7 +21,7 @@ $total-columns: 7;
.time {
display: grid;
grid-area: time;
- grid-template-rows: repeat($total-rows, 1fr);
+ grid-template-rows: repeat(calendar-variables.$total-rows, 1fr);
margin-inline-end: 15px;
> li {
display: flex;
@@ -46,7 +40,7 @@ $total-columns: 7;
.headline {
display: grid;
grid-area: headline;
- grid-template-columns: repeat($total-columns, 1fr);
+ grid-template-columns: repeat(calendar-variables.$total-columns, 1fr);
> li > time {
@include typography.typography-cat-shorthand('caption');
text-transform: uppercase;
@@ -54,24 +48,22 @@ $total-columns: 7;
}
.calendar {
- $sum: $total-rows * $total-columns;
- $next: 1;
display: grid;
overflow: hidden;
- background-color: var(#{scheme-variables.$vvd-color-neutral-20});
- border-radius: 3.64752px;
+ background-color: var(#{scheme-variables.$vvd-color-neutral-20}, rgb(128, 128, 128));
+ border-radius: 6px;
box-shadow: 0 0 3.64752px rgba(0, 0, 0, 0.15);
counter-reset: listing;
gap: 1px;
grid-area: calendar;
grid-auto-flow: column;
- grid-template: repeat($total-rows * $fraction, 1fr) / repeat(
- $total-columns,
+ grid-template: repeat(calendar-variables.$total-rows * calendar-variables.$fraction, 1fr) / repeat(
+ calendar-variables.$total-columns,
1fr
);
> [role="listitem"i] {
height: 35px;
- background-color: var(#{scheme-variables.$vvd-color-base});
+ background-color: var(#{scheme-variables.$vvd-color-base}, rgb(255, 255, 255));
grid-column: var(--column);
grid-row: var(--row);
&::before {
@@ -83,19 +75,23 @@ $total-columns: 7;
}
}
- @for $i from 1 through $total-rows {
- $current-row: $i * $fraction - $fraction + 1;
- [role="listitem"i]:nth-child(#{$total-rows}n + #{$i}) {
- --row: #{$current-row} / span #{$fraction};
+ @for $i from 1 through calendar-variables.$total-rows {
+ $current-row: $i * calendar-variables.$fraction - calendar-variables.$fraction + 1;
+ [role="listitem"i]:nth-child(#{calendar-variables.$total-rows}n + #{$i}) {
+ --row: #{$current-row} / span #{calendar-variables.$fraction};
}
}
- @for $i from 1 through $total-columns {
- $sum: $sum - $total-rows + 1;
- [role="listitem"i]:nth-child(1n + #{$next}):nth-last-child(1n + #{$sum}) {
+
+ @for $i from 1 through calendar-variables.$total-columns {
+ /* extra 2 for the sibling events wrapper and the self containment */
+ $total-cells: calendar-variables.$total-columns * calendar-variables.$total-rows + 2;
+
+ $from: $i * calendar-variables.$total-rows - calendar-variables.$total-rows + 1;
+ $less: $total-cells - $i * calendar-variables.$total-rows;
+
+ [role="listitem"i]:nth-child(1n + #{$from}):nth-last-child(1n + #{$less}) {
--column: #{$i};
}
- /* stylelint-disable-next-line order/order */
- $next: $next + $total-rows;
}
}
diff --git a/components/calendar/src/vwc-calendar.ts b/components/calendar/src/vwc-calendar.ts
index f192e6042f..0eb9ad92cf 100644
--- a/components/calendar/src/vwc-calendar.ts
+++ b/components/calendar/src/vwc-calendar.ts
@@ -51,7 +51,7 @@ export class VWCCalendar extends LitElement {
datetime?: Date;
#daysLength = 7;
- #hoursOfDay = (Array.from({ length: 23 }) as Date[])
+ #hours = (Array.from({ length: 23 }) as Date[])
.fill(new Date(new Date().setHours(0, 0, 0)))
.map((d, i) => new Date(d.setHours(++i)))
@@ -102,7 +102,7 @@ export class VWCCalendar extends LitElement {
protected renderTimeCells(): TemplateResult[] {
const templates = [];
- for (let i = 0; i < (this.#hoursOfDay.length + 1) * this.#daysLength; i++) {
+ for (let i = 0; i < (this.#hours.length + 1) * this.#daysLength; i++) {
templates.push(html`
`);
}
return templates;
@@ -133,7 +133,7 @@ export class VWCCalendar extends LitElement {
- ${this.#hoursOfDay.map(h => html`-
+ ${this.#hours.map(h => html`
-
diff --git a/components/calendar/stories/calendar.stories.js b/components/calendar/stories/calendar.stories.js
index 59a9c5e162..4237c5b467 100644
--- a/components/calendar/stories/calendar.stories.js
+++ b/components/calendar/stories/calendar.stories.js
@@ -11,11 +11,13 @@ export default {
};
const Template = args => html`
-
-
-
-
-
+
+
+
+
+
+
+
`;
export const Basic = Template.bind({});
diff --git a/components/calendar/test/calendar.test.js b/components/calendar/test/calendar.test.js
index 9991c96547..5c30788e1b 100644
--- a/components/calendar/test/calendar.test.js
+++ b/components/calendar/test/calendar.test.js
@@ -28,6 +28,21 @@ describe('calendar', () => {
expect(actualElement.shadowRoot.innerHTML).to.equalSnapshot();
});
+ it('should set cells in correct day column', async () => {
+ const [actualElement] = addElement(
+ textToDomToParent(`<${COMPONENT_NAME}>Button Text${COMPONENT_NAME}>`)
+ );
+ await waitNextTask();
+
+ const { shadowRoot } = actualElement;
+ const cells = shadowRoot.querySelectorAll('.calendar > [role="listitem"i]');
+
+ const isCorrectColumns = Array.from(cells).every((cell, i) => getComputedStyle(cell)
+ .getPropertyValue('--column') == ~~(i / 24) + 1);
+
+ expect(isCorrectColumns).to.equal(true);
+ });
+
describe('API', () => {
it('should reflect weekdays as set by property', async () => {
const [actualElement] = addElement(