@operato/event-view 1.0.0-beta.4 → 1.0.0-beta.42

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.
@@ -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 { LitElement, css, html } from 'lit'
4
+ import { css, html, LitElement } from 'lit'
4
5
  import { customElement, property } from 'lit/decorators.js'
5
6
 
6
- import { SampleEventProvider } from './sample-event-provider'
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-monthly {
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 html` <calendar-monthly .eventProvider=${new SampleEventProvider()}></calendar-monthly> `
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 SampleEventProvider implements EventProvider {
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
+ }
@@ -1,60 +1,39 @@
1
- import { html, TemplateResult } from 'lit';
2
- import '../src/event-view.js';
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
- title: { control: 'text' },
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
- title?: string;
22
- counter?: number;
23
- textColor?: string;
24
- slot?: TemplateResult;
20
+ format?: string
25
21
  }
26
22
 
27
- const Template: Story<ArgTypes> = ({
28
- title = 'Hello world',
29
- counter = 5,
30
- textColor,
31
- slot,
32
- }: ArgTypes) => html`
33
- <event-view
34
- style="--event-view-text-color: ${textColor || 'black'}"
35
- .title=${title}
36
- .counter=${counter}
37
- >
38
- ${slot}
39
- </event-view>
40
- `;
41
-
42
- export const Regular = Template.bind({});
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) {
package/tsconfig.json CHANGED
@@ -1,8 +1,9 @@
1
1
  {
2
2
  "compilerOptions": {
3
- "target": "es2018",
3
+ "target": "esnext",
4
4
  "module": "esnext",
5
5
  "moduleResolution": "node",
6
+ "resolveJsonModule": true,
6
7
  "noEmitOnError": true,
7
8
  "lib": ["es2017", "dom"],
8
9
  "strict": true,