Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(vwc-calendar): cells wrong grid columns #862

Merged
merged 5 commits into from
May 27, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions components/calendar/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -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": {
Expand Down
15 changes: 15 additions & 0 deletions components/calendar/src/_vwc-calendar-variables.scss
Original file line number Diff line number Diff line change
@@ -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;
39 changes: 27 additions & 12 deletions components/calendar/src/vwc-calendar-event.scss
Original file line number Diff line number Diff line change
@@ -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;
}
60 changes: 52 additions & 8 deletions components/calendar/src/vwc-calendar-event.ts
Original file line number Diff line number Diff line change
@@ -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 {
Expand All @@ -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`
<section
role="button"
tabindex="0"
style="--vvd-calendar-event-event-day: ${unsafeCSS(this.day)}"
style="${styleMap(styles)}"
>
<label>${this.label}</label>
<h2><strong>${this.heading}</strong></h2>
<p>${this.description}</p>
</section>
`;
}
Expand Down
46 changes: 21 additions & 25 deletions components/calendar/src/vwc-calendar.scss
Original file line number Diff line number Diff line change
@@ -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';

Expand All @@ -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);
Expand All @@ -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;
Expand All @@ -46,32 +40,30 @@ $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;
}
}

.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 {
Expand All @@ -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;
}
}

Expand Down
6 changes: 3 additions & 3 deletions components/calendar/src/vwc-calendar.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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)))

Expand Down Expand Up @@ -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`<div role="listitem" tabindex="0"></div>`);
}
return templates;
Expand Down Expand Up @@ -133,7 +133,7 @@ export class VWCCalendar extends LitElement {
<ol class="time">
<!-- TODO: align to convention of generation from first hour in day and a length of hours. -->
<!-- TODO: get styled hour and datetime value -->
${this.#hoursOfDay.map(h => html`<li>
${this.#hours.map(h => html`<li>
<time datetime="${this.formatDate(h, { hour: 'numeric', minute: 'numeric', hour12: false })}">
${this.formatDate(h, { hour: 'numeric', hour12: true })}
</time>
Expand Down
12 changes: 7 additions & 5 deletions components/calendar/stories/calendar.stories.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,13 @@ export default {
};

const Template = args => html`<vwc-calendar ...=${spread(args)}>
<vwc-calendar-event day="2" style="--vvd-calendar-event-event-color: #4cc3d2; --vvd-calendar-event-event-row: 9 / span 24; --vvd-calendar-event-overlap-count: 2"></vwc-calendar-event>
<vwc-calendar-event day="2" style="--vvd-calendar-event-event-color: #d6219c; --vvd-calendar-event-event-row: 5 / span 16"></vwc-calendar-event>
<vwc-calendar-event day="2" style="--vvd-calendar-event-event-color: #b779ff; --vvd-calendar-event-event-row: 13 / span 10; --vvd-calendar-event-overlap-count: 1"></vwc-calendar-event>
<vwc-calendar-event day="4" style="--vvd-calendar-event-event-color: #d6219c; --vvd-calendar-event-event-row: 13 / span 32"></vwc-calendar-event>
<vwc-calendar-event day="6" style="--vvd-calendar-event-event-color: #b779ff; --vvd-calendar-event-event-row: 15 / span 8" label="my event"></vwc-calendar-event>
<vwc-calendar-event day="1" start="23" duration="9" heading="Summer time" description="All Day"></vwc-calendar-event>
<vwc-calendar-event day="1" start="0" duration="12" color="rgb(43, 158, 250)" heading="Summer time" description="All Day"></vwc-calendar-event>
<vwc-calendar-event day="3" start="4" duration="17" color="rgb(214, 33, 156)" heading="Summer time" description="All Day"></vwc-calendar-event>
<vwc-calendar-event day="7" start="12" duration="24" color="rgb(183, 126, 249)" heading="Summer time" description="All Day"></vwc-calendar-event>
<vwc-calendar-event day="7" start="69" duration="27" color="rgb(50, 175, 76)" heading="Summer time" description="All Day"></vwc-calendar-event>
<vwc-calendar-event day="4" start="24" duration="12" color="rgb(50, 175, 76)" heading="Summer time" description="All Day" overlap-count="2"></vwc-calendar-event>
<vwc-calendar-event day="4" start="26" duration="27" color="rgb(43, 158, 250)" heading="Summer time" description="All Day"></vwc-calendar-event>
</vwc-calendar>`;

export const Basic = Template.bind({});
Expand Down
15 changes: 15 additions & 0 deletions components/calendar/test/calendar.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand Down