@operato/event-view 1.0.0-beta.4 → 1.0.0-beta.40
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +416 -0
- package/demo/index.html +1 -2
- package/dist/src/biz-event.d.ts +1 -0
- package/dist/src/biz-event.js.map +1 -1
- package/dist/src/calendar-monthly.js +2 -3
- package/dist/src/calendar-monthly.js.map +1 -1
- package/dist/src/calendar-weekly-styles.d.ts +1 -0
- package/dist/src/calendar-weekly-styles.js +94 -0
- package/dist/src/calendar-weekly-styles.js.map +1 -0
- package/dist/src/calendar-weekly.d.ts +24 -0
- package/dist/src/calendar-weekly.js +129 -0
- package/dist/src/calendar-weekly.js.map +1 -0
- package/dist/src/event-view.d.ts +2 -0
- package/dist/src/event-view.js +19 -9
- package/dist/src/event-view.js.map +1 -1
- package/dist/src/sample-event-provider.d.ts +15 -1
- package/dist/src/sample-event-provider.js +58 -1
- package/dist/src/sample-event-provider.js.map +1 -1
- package/dist/stories/index.stories.d.ts +6 -15
- package/dist/stories/index.stories.js +13 -26
- package/dist/stories/index.stories.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +8 -7
- package/src/biz-event.ts +1 -2
- package/src/calendar-weekly-styles.ts +94 -0
- package/src/calendar-weekly.ts +138 -0
- package/src/event-view.ts +9 -4
- package/src/sample-event-provider.ts +60 -1
- package/stories/index.stories.ts +26 -47
- package/themes/calendar-theme.css +21 -0
- package/tsconfig.json +2 -1
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import { css } from 'lit'
|
|
2
|
+
|
|
3
|
+
export const CalendarWeeklyStyles = css`
|
|
4
|
+
:host {
|
|
5
|
+
display: flex;
|
|
6
|
+
flex-direction: column;
|
|
7
|
+
color: var(--calendar-weekly-text-color, #585858);
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
[head] {
|
|
11
|
+
display: flex;
|
|
12
|
+
align-items: center;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
[head-week] {
|
|
16
|
+
display: flex;
|
|
17
|
+
align-items: left;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
[this-week] {
|
|
21
|
+
font-size: x-large;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
[nav] {
|
|
25
|
+
margin-left: auto;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
ol {
|
|
29
|
+
flex: 1;
|
|
30
|
+
|
|
31
|
+
display: grid;
|
|
32
|
+
grid-template-columns: repeat(7, 1fr);
|
|
33
|
+
grid-template-rows: max-content;
|
|
34
|
+
|
|
35
|
+
padding: 0;
|
|
36
|
+
margin: var(--calendar-weekly-ol-margin, 9px 0);
|
|
37
|
+
border-top: var(--calendar-weekly-ol-top-border, 3px solid #999);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
li {
|
|
41
|
+
position: relative;
|
|
42
|
+
|
|
43
|
+
list-style: none;
|
|
44
|
+
border: var(--calendar-weekly-border, 1px solid rgba(0, 0, 0, 0.1));
|
|
45
|
+
border-width: var(--calendar-weekly-border-width, 0 1px 1px 0px);
|
|
46
|
+
opacity: var(--calendar-weekly-opacity);
|
|
47
|
+
}
|
|
48
|
+
li:nth-child(7n + 1) {
|
|
49
|
+
border-left-width: 1px;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
li[day-of-week] {
|
|
53
|
+
opacity: 1;
|
|
54
|
+
background-color: var(--calendar-current-week-background-color, #fff);
|
|
55
|
+
padding: var(--calendar-weekly-label-padding);
|
|
56
|
+
color: rgba(var(--secondary-color-rgb), 0.8);
|
|
57
|
+
text-align: center;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
li[current-week] {
|
|
61
|
+
background-color: var(--calendar-current-monthly-background-color, #fff);
|
|
62
|
+
opacity: 1;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
span[date-label] {
|
|
66
|
+
display: block;
|
|
67
|
+
margin: var(--calendar-weekly-date-label-margin);
|
|
68
|
+
text-align: var(--calendar-weekly-label-align, center);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
li[today] > span[date-label] {
|
|
72
|
+
display: inline-block;
|
|
73
|
+
background-color: var(--calendar-weekly-date-label-background-color, #cc3300);
|
|
74
|
+
padding: var(--calendar-weekly-date-label-padding);
|
|
75
|
+
border-radius: var(--calendar-weekly-date-label-border-radius, 50%);
|
|
76
|
+
color: var(--calendar-weekly-date-label-color, #fff);
|
|
77
|
+
min-width: 16px;
|
|
78
|
+
text-align: center;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
[date] div {
|
|
82
|
+
display: block;
|
|
83
|
+
font-size: small;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
[event] {
|
|
87
|
+
display: block;
|
|
88
|
+
background-color: var(--calendar-weekly-background-color);
|
|
89
|
+
border: var(--calendar-weekly-event-border);
|
|
90
|
+
border-width: var(--calendar-weekly-event-border-width);
|
|
91
|
+
margin: var(--calendar-weekly-event-margin, 0 0 4px 0);
|
|
92
|
+
padding: var(--calendar-weekly-event-padding, 2px 4px 2px 4px);
|
|
93
|
+
}
|
|
94
|
+
`
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
import dayjs, { Dayjs } from 'dayjs/esm/index'
|
|
2
|
+
import weekday from 'dayjs/esm/plugin/weekday'
|
|
3
|
+
import weekOfYear from 'dayjs/esm/plugin/weekOfYear'
|
|
4
|
+
import { html, LitElement, PropertyValues } from 'lit'
|
|
5
|
+
import { customElement, property } from 'lit/decorators.js'
|
|
6
|
+
|
|
7
|
+
import { BizEvent } from './biz-event'
|
|
8
|
+
import { CalendarWeeklyStyles } from './calendar-weekly-styles'
|
|
9
|
+
import { EventProvider } from './event-provider'
|
|
10
|
+
|
|
11
|
+
dayjs.extend(weekday)
|
|
12
|
+
dayjs.extend(weekOfYear)
|
|
13
|
+
|
|
14
|
+
const WEEKDAYS = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat']
|
|
15
|
+
|
|
16
|
+
function isToday(date: Date) {
|
|
17
|
+
const today = new Date()
|
|
18
|
+
return (
|
|
19
|
+
date.getDate() == today.getDate() &&
|
|
20
|
+
date.getMonth() == today.getMonth() &&
|
|
21
|
+
date.getFullYear() == today.getFullYear()
|
|
22
|
+
)
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
type CALENDAR = {
|
|
26
|
+
label: string
|
|
27
|
+
date: Date
|
|
28
|
+
thisWeek: boolean
|
|
29
|
+
today?: boolean
|
|
30
|
+
}[]
|
|
31
|
+
|
|
32
|
+
@customElement('calendar-weekly')
|
|
33
|
+
export class CalendarWeekly extends LitElement {
|
|
34
|
+
static styles = [CalendarWeeklyStyles]
|
|
35
|
+
|
|
36
|
+
@property({ type: Number }) year: number = dayjs().year()
|
|
37
|
+
@property({ type: Number }) month: number = dayjs().month()
|
|
38
|
+
@property({ type: Number }) week: number = dayjs().week()
|
|
39
|
+
@property({ type: Array }) eventProvider?: EventProvider
|
|
40
|
+
|
|
41
|
+
render() {
|
|
42
|
+
const calendar = this.createDaysForCurrentWeek(this.year, this.week)
|
|
43
|
+
|
|
44
|
+
return html`
|
|
45
|
+
<div head>
|
|
46
|
+
<div this-week><b>${dayjs(new Date(this.year, this.month)).format('MMMM')}</b> ${this.year}</div>
|
|
47
|
+
|
|
48
|
+
<div nav>
|
|
49
|
+
<mwc-button
|
|
50
|
+
outlined
|
|
51
|
+
@click=${() => {
|
|
52
|
+
const dayJs = this.getLastDateOfWeek(this.year, this.week)
|
|
53
|
+
const prevWeek = dayJs.subtract(1, 'week')
|
|
54
|
+
this.moveTo(prevWeek.year(), prevWeek.month(), prevWeek.week())
|
|
55
|
+
}}
|
|
56
|
+
><</mwc-button
|
|
57
|
+
>
|
|
58
|
+
<mwc-button
|
|
59
|
+
@click=${() => {
|
|
60
|
+
this.moveTo(dayjs().year(), dayjs().month(), dayjs().week())
|
|
61
|
+
}}
|
|
62
|
+
>Today</mwc-button
|
|
63
|
+
>
|
|
64
|
+
<mwc-button
|
|
65
|
+
@click=${() => {
|
|
66
|
+
const dayJs = this.getLastDateOfWeek(this.year, this.week)
|
|
67
|
+
const nextWeek = dayJs.add(1, 'week')
|
|
68
|
+
this.moveTo(nextWeek.year(), nextWeek.month(), nextWeek.week())
|
|
69
|
+
}}
|
|
70
|
+
>></mwc-button
|
|
71
|
+
>
|
|
72
|
+
</div>
|
|
73
|
+
</div>
|
|
74
|
+
<div head-week>
|
|
75
|
+
<div this-week><b>Week ${this.week}</b></div>
|
|
76
|
+
</div>
|
|
77
|
+
|
|
78
|
+
<ol>
|
|
79
|
+
${calendar.map((date, index) => {
|
|
80
|
+
return html`
|
|
81
|
+
<li ?today=${date.today} day-of-week><span date-label>${date.label}(${WEEKDAYS[index]})</span></li>
|
|
82
|
+
`
|
|
83
|
+
})}
|
|
84
|
+
${calendar.map(date => {
|
|
85
|
+
return html`<li day-task>
|
|
86
|
+
<div>
|
|
87
|
+
${this.findEvents(date.date).map(
|
|
88
|
+
event =>
|
|
89
|
+
html`<span
|
|
90
|
+
@click=${() => event.clickEvent(event.title, event.due)}
|
|
91
|
+
event
|
|
92
|
+
.style="border-color: ${event.color};"
|
|
93
|
+
>${event.title}</span
|
|
94
|
+
>`
|
|
95
|
+
)}
|
|
96
|
+
</div>
|
|
97
|
+
</li>`
|
|
98
|
+
})}
|
|
99
|
+
</ol>
|
|
100
|
+
`
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
updated(changes: PropertyValues<this>) {}
|
|
104
|
+
|
|
105
|
+
findEvents(date: Date): BizEvent[] {
|
|
106
|
+
return this.eventProvider?.fetchEventsForDate(date, {}) || []
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
moveTo(year: number, month: number, week: number) {
|
|
110
|
+
this.year = year
|
|
111
|
+
this.month = month
|
|
112
|
+
this.week = week
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
getLastDateOfWeek(year: number, week: number): Dayjs {
|
|
116
|
+
const firstWeekLastDay = dayjs(new Date(year, 0, 1)).endOf('w')
|
|
117
|
+
week -= 1 // one-based week, so need the minus-one
|
|
118
|
+
return firstWeekLastDay.add(week, 'w')
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
createDaysForCurrentWeek(year: number, week: number): CALENDAR {
|
|
122
|
+
const lastDayjs = this.getLastDateOfWeek(year, week)
|
|
123
|
+
const weekDays = 7
|
|
124
|
+
|
|
125
|
+
return [...Array(weekDays)]
|
|
126
|
+
.map((day, index) => {
|
|
127
|
+
const date = new Date(lastDayjs.year(), lastDayjs.month(), lastDayjs.date() - index)
|
|
128
|
+
const label = dayjs(date).format('MM-DD')
|
|
129
|
+
return {
|
|
130
|
+
date,
|
|
131
|
+
label,
|
|
132
|
+
thisWeek: true,
|
|
133
|
+
today: isToday(date)
|
|
134
|
+
}
|
|
135
|
+
})
|
|
136
|
+
.reverse()
|
|
137
|
+
}
|
|
138
|
+
}
|
package/src/event-view.ts
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import './calendar-monthly'
|
|
2
|
+
import './calendar-weekly'
|
|
2
3
|
|
|
3
|
-
import {
|
|
4
|
+
import { css, html, LitElement } from 'lit'
|
|
4
5
|
import { customElement, property } from 'lit/decorators.js'
|
|
5
6
|
|
|
6
|
-
import {
|
|
7
|
+
import { SampleMonthlyEventProvider, SampleWeeklyEventProvider } from './sample-event-provider'
|
|
7
8
|
|
|
8
9
|
@customElement('event-view')
|
|
9
10
|
export class EventView extends LitElement {
|
|
@@ -13,7 +14,7 @@ export class EventView extends LitElement {
|
|
|
13
14
|
flex-direction: column;
|
|
14
15
|
}
|
|
15
16
|
|
|
16
|
-
calendar-
|
|
17
|
+
calendar-weekly {
|
|
17
18
|
flex: 1;
|
|
18
19
|
|
|
19
20
|
padding: 0;
|
|
@@ -21,7 +22,11 @@ export class EventView extends LitElement {
|
|
|
21
22
|
}
|
|
22
23
|
`
|
|
23
24
|
|
|
25
|
+
@property({ type: String }) format: string = 'monthly'
|
|
26
|
+
|
|
24
27
|
render() {
|
|
25
|
-
return
|
|
28
|
+
return this.format == 'weekly'
|
|
29
|
+
? html` <calendar-weekly .eventProvider=${new SampleWeeklyEventProvider()}></calendar-weekly> `
|
|
30
|
+
: html` <calendar-monthly .eventProvider=${new SampleMonthlyEventProvider()}></calendar-monthly> `
|
|
26
31
|
}
|
|
27
32
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { EventProvider } from './event-provider'
|
|
2
2
|
|
|
3
|
-
export class
|
|
3
|
+
export class SampleMonthlyEventProvider implements EventProvider {
|
|
4
4
|
fetchEventsForDate(date: Date, options: any) {
|
|
5
5
|
return [
|
|
6
6
|
{
|
|
@@ -55,3 +55,62 @@ export class SampleEventProvider implements EventProvider {
|
|
|
55
55
|
return []
|
|
56
56
|
}
|
|
57
57
|
}
|
|
58
|
+
|
|
59
|
+
export class SampleWeeklyEventProvider implements EventProvider {
|
|
60
|
+
fetchEventsForDate(date: Date, options: any) {
|
|
61
|
+
return [
|
|
62
|
+
{
|
|
63
|
+
due: '2021-08-21',
|
|
64
|
+
title: 'HAHAHA',
|
|
65
|
+
color: 'yellow',
|
|
66
|
+
clickEvent: function (title: string, due: string) {
|
|
67
|
+
console.log('clicked...', title, due)
|
|
68
|
+
}
|
|
69
|
+
},
|
|
70
|
+
{
|
|
71
|
+
due: '2021-08-21',
|
|
72
|
+
title: 'HOHOHO',
|
|
73
|
+
color: 'lime'
|
|
74
|
+
},
|
|
75
|
+
{
|
|
76
|
+
due: '2021-08-21',
|
|
77
|
+
title: 'HIHIHI',
|
|
78
|
+
color: 'yellow'
|
|
79
|
+
},
|
|
80
|
+
{
|
|
81
|
+
due: '2021-08-21',
|
|
82
|
+
title: 'HEHEHE',
|
|
83
|
+
color: 'white'
|
|
84
|
+
},
|
|
85
|
+
{
|
|
86
|
+
due: '2021-08-21',
|
|
87
|
+
title: 'KEKEKE',
|
|
88
|
+
color: 'yellow'
|
|
89
|
+
},
|
|
90
|
+
{
|
|
91
|
+
due: '2021-08-21',
|
|
92
|
+
title: 'MEMEME',
|
|
93
|
+
color: 'orange'
|
|
94
|
+
},
|
|
95
|
+
{
|
|
96
|
+
due: '2021-08-21',
|
|
97
|
+
title: 'MOMOMO',
|
|
98
|
+
color: 'lime'
|
|
99
|
+
},
|
|
100
|
+
{
|
|
101
|
+
due: '2021-08-21',
|
|
102
|
+
title: 'QUOQUO',
|
|
103
|
+
color: 'navy'
|
|
104
|
+
},
|
|
105
|
+
{
|
|
106
|
+
due: '2021-08-21',
|
|
107
|
+
title: 'ZZXXCC',
|
|
108
|
+
color: 'gray'
|
|
109
|
+
}
|
|
110
|
+
]
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
fetchEventsForDuration(from: Date, to: Date, options: any) {
|
|
114
|
+
return []
|
|
115
|
+
}
|
|
116
|
+
}
|
package/stories/index.stories.ts
CHANGED
|
@@ -1,60 +1,39 @@
|
|
|
1
|
-
import
|
|
2
|
-
|
|
1
|
+
import '../src/event-view.js'
|
|
2
|
+
|
|
3
|
+
import { html, TemplateResult } from 'lit'
|
|
3
4
|
|
|
4
5
|
export default {
|
|
5
6
|
title: 'EventView',
|
|
6
7
|
component: 'event-view',
|
|
7
8
|
argTypes: {
|
|
8
|
-
|
|
9
|
-
counter: { control: 'number' },
|
|
10
|
-
textColor: { control: 'color' },
|
|
9
|
+
format: { control: 'select', options: ['monthly', 'weekly'], description: 'set event view format' }
|
|
11
10
|
}
|
|
12
|
-
}
|
|
11
|
+
}
|
|
13
12
|
|
|
14
13
|
interface Story<T> {
|
|
15
|
-
(args: T): TemplateResult
|
|
16
|
-
args?: Partial<T
|
|
17
|
-
argTypes?: Record<string, unknown
|
|
14
|
+
(args: T): TemplateResult
|
|
15
|
+
args?: Partial<T>
|
|
16
|
+
argTypes?: Record<string, unknown>
|
|
18
17
|
}
|
|
19
18
|
|
|
20
19
|
interface ArgTypes {
|
|
21
|
-
|
|
22
|
-
counter?: number;
|
|
23
|
-
textColor?: string;
|
|
24
|
-
slot?: TemplateResult;
|
|
20
|
+
format?: string
|
|
25
21
|
}
|
|
26
22
|
|
|
27
|
-
const Template: Story<ArgTypes> = ({
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
export const CustomTitle = Template.bind({});
|
|
45
|
-
CustomTitle.args = {
|
|
46
|
-
title: 'My title',
|
|
47
|
-
};
|
|
48
|
-
|
|
49
|
-
export const CustomCounter = Template.bind({});
|
|
50
|
-
CustomCounter.args = {
|
|
51
|
-
counter: 123456,
|
|
52
|
-
};
|
|
53
|
-
|
|
54
|
-
export const SlottedContent = Template.bind({});
|
|
55
|
-
SlottedContent.args = {
|
|
56
|
-
slot: html`<p>Slotted content</p>`,
|
|
57
|
-
};
|
|
58
|
-
SlottedContent.argTypes = {
|
|
59
|
-
slot: { table: { disable: true } },
|
|
60
|
-
};
|
|
23
|
+
const Template: Story<ArgTypes> = ({ format = 'monthly' }: ArgTypes) =>
|
|
24
|
+
html`
|
|
25
|
+
<link rel="stylesheet" href="/themes/app-theme.css" />
|
|
26
|
+
<link rel="stylesheet" href="/themes/calendar-theme.css" />
|
|
27
|
+
|
|
28
|
+
<event-view format=${format}> </event-view>
|
|
29
|
+
`
|
|
30
|
+
|
|
31
|
+
export const Regular = Template.bind({})
|
|
32
|
+
Regular.args = {
|
|
33
|
+
format: 'monthly'
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export const WeeklyEventView = Template.bind({})
|
|
37
|
+
WeeklyEventView.args = {
|
|
38
|
+
format: 'weekly'
|
|
39
|
+
}
|
|
@@ -25,6 +25,27 @@ body {
|
|
|
25
25
|
--calendar-monthly-event-padding: 2px var(--padding-default);
|
|
26
26
|
--calendar-monthly-event-border: 3px solid #ccc;
|
|
27
27
|
--calendar-monthly-event-border-width: 0 0 0 3px;
|
|
28
|
+
|
|
29
|
+
/* weekly layout */
|
|
30
|
+
--calendar-weekly-ol-margin: var(--margin-default) 0;
|
|
31
|
+
--calendar-weekly-ol-top-border: 2px solid rgba(var(--secondary-color-rgb), 0.7);
|
|
32
|
+
--calendar-current-week-background-color: var(--theme-white-color);
|
|
33
|
+
--calendar-weekly-label-align: center;
|
|
34
|
+
--calendar-weekly-label-padding: var(--padding-narrow) 0;
|
|
35
|
+
--calendar-weekly-label-color: rgba(var(--secondary-color-rgb), 0.8);
|
|
36
|
+
--calendar-weekly-opacity: 0.5;
|
|
37
|
+
--calendar-weekly-date-label-background-color: var(--status-danger-color);
|
|
38
|
+
--calendar-weekly-date-label-margin: var(--margin-narrow);
|
|
39
|
+
--calendar-weekly-date-label-padding: 5px var(--padding-narrow);
|
|
40
|
+
--calendar-weekly-date-label-color: var(--theme-white-color);
|
|
41
|
+
|
|
42
|
+
--calendar-weekly-background-color: #f4f4f4;
|
|
43
|
+
--calendar-weekly-event-border-radius: var(--border-radius);
|
|
44
|
+
--calendar-weekly-event-margin: var(--padding-narrow) 0 0 0;
|
|
45
|
+
--calendar-weekly-event-padding: 2px var(--padding-default);
|
|
46
|
+
--calendar-weekly-event-border: 3px solid #ccc;
|
|
47
|
+
--calendar-weekly-event-border-width: 0 0 0 3px;
|
|
48
|
+
|
|
28
49
|
}
|
|
29
50
|
|
|
30
51
|
@media only screen and (max-width: 460px) {
|