@screenly/edge-apps 0.0.1 → 0.0.3

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.
Files changed (143) hide show
  1. package/dist/assets/fonts/Inter-Medium.woff2 +0 -0
  2. package/dist/assets/fonts/Inter-Regular.woff2 +0 -0
  3. package/dist/assets/fonts/Inter-SemiBold.woff2 +0 -0
  4. package/dist/assets/images/icons/chancesleet.svg +4 -0
  5. package/dist/assets/images/icons/clear-night.svg +5 -0
  6. package/dist/assets/images/icons/clear.svg +11 -0
  7. package/dist/assets/images/icons/cloudy.svg +4 -0
  8. package/dist/assets/images/icons/drizzle.svg +5 -0
  9. package/dist/assets/images/icons/fewdrops.svg +4 -0
  10. package/dist/assets/images/icons/fog.svg +6 -0
  11. package/dist/assets/images/icons/haze.svg +6 -0
  12. package/dist/assets/images/icons/mostly-cloudy-night.svg +7 -0
  13. package/dist/assets/images/icons/mostly-cloudy.svg +13 -0
  14. package/dist/assets/images/icons/partially-cloudy-night.svg +6 -0
  15. package/dist/assets/images/icons/partially-cloudy.svg +12 -0
  16. package/dist/assets/images/icons/partlysunny.svg +6 -0
  17. package/dist/assets/images/icons/rain-night.svg +8 -0
  18. package/dist/assets/images/icons/rainy.svg +6 -0
  19. package/dist/assets/images/icons/sleet-night.svg +14 -0
  20. package/dist/assets/images/icons/sleet.svg +4 -0
  21. package/dist/assets/images/icons/snow.svg +19 -0
  22. package/dist/assets/images/icons/thunderstorm-night.svg +9 -0
  23. package/dist/assets/images/icons/thunderstorm.svg +7 -0
  24. package/dist/assets/images/icons/windy.svg +6 -0
  25. package/dist/assets/images/screenly.svg +10 -0
  26. package/dist/components/app-header/app-header.d.ts +43 -0
  27. package/dist/components/app-header/app-header.d.ts.map +1 -0
  28. package/dist/components/app-header/app-header.js +244 -0
  29. package/dist/components/auto-scaler/auto-scaler.d.ts +65 -0
  30. package/dist/components/auto-scaler/auto-scaler.d.ts.map +1 -0
  31. package/dist/components/auto-scaler/auto-scaler.js +304 -0
  32. package/dist/components/brand-logo/brand-logo.d.ts +42 -0
  33. package/dist/components/brand-logo/brand-logo.d.ts.map +1 -0
  34. package/dist/components/brand-logo/brand-logo.js +209 -0
  35. package/dist/components/calendar-views/calendar-view-utils.d.ts +5 -0
  36. package/dist/components/calendar-views/calendar-view-utils.d.ts.map +1 -0
  37. package/dist/components/calendar-views/calendar-view-utils.js +73 -0
  38. package/dist/components/calendar-views/calendar-window-utils.d.ts +9 -0
  39. package/dist/components/calendar-views/calendar-window-utils.d.ts.map +1 -0
  40. package/dist/components/calendar-views/calendar-window-utils.js +57 -0
  41. package/dist/components/calendar-views/daily-calendar-view/daily-calendar-view-styles.d.ts +2 -0
  42. package/dist/components/calendar-views/daily-calendar-view/daily-calendar-view-styles.d.ts.map +1 -0
  43. package/dist/components/calendar-views/daily-calendar-view/daily-calendar-view-styles.js +175 -0
  44. package/dist/components/calendar-views/daily-calendar-view/daily-calendar-view.d.ts +21 -0
  45. package/dist/components/calendar-views/daily-calendar-view/daily-calendar-view.d.ts.map +1 -0
  46. package/dist/components/calendar-views/daily-calendar-view/daily-calendar-view.js +130 -0
  47. package/dist/components/calendar-views/daily-calendar-view/index.d.ts +2 -0
  48. package/dist/components/calendar-views/daily-calendar-view/index.d.ts.map +1 -0
  49. package/dist/components/calendar-views/daily-calendar-view/index.js +1 -0
  50. package/dist/components/calendar-views/event-layout.d.ts +18 -0
  51. package/dist/components/calendar-views/event-layout.d.ts.map +1 -0
  52. package/dist/components/calendar-views/event-layout.js +139 -0
  53. package/dist/components/calendar-views/schedule-calendar-view/index.d.ts +2 -0
  54. package/dist/components/calendar-views/schedule-calendar-view/index.d.ts.map +1 -0
  55. package/dist/components/calendar-views/schedule-calendar-view/index.js +1 -0
  56. package/dist/components/calendar-views/schedule-calendar-view/schedule-calendar-view-styles.d.ts +2 -0
  57. package/dist/components/calendar-views/schedule-calendar-view/schedule-calendar-view-styles.d.ts.map +1 -0
  58. package/dist/components/calendar-views/schedule-calendar-view/schedule-calendar-view-styles.js +118 -0
  59. package/dist/components/calendar-views/schedule-calendar-view/schedule-calendar-view.d.ts +23 -0
  60. package/dist/components/calendar-views/schedule-calendar-view/schedule-calendar-view.d.ts.map +1 -0
  61. package/dist/components/calendar-views/schedule-calendar-view/schedule-calendar-view.js +167 -0
  62. package/dist/components/calendar-views/weekly-calendar-view/index.d.ts +3 -0
  63. package/dist/components/calendar-views/weekly-calendar-view/index.d.ts.map +1 -0
  64. package/dist/components/calendar-views/weekly-calendar-view/index.js +1 -0
  65. package/dist/components/calendar-views/weekly-calendar-view/weekly-calendar-view-styles.d.ts +2 -0
  66. package/dist/components/calendar-views/weekly-calendar-view/weekly-calendar-view-styles.d.ts.map +1 -0
  67. package/dist/components/calendar-views/weekly-calendar-view/weekly-calendar-view-styles.js +234 -0
  68. package/dist/components/calendar-views/weekly-calendar-view/weekly-calendar-view-utils.d.ts +16 -0
  69. package/dist/components/calendar-views/weekly-calendar-view/weekly-calendar-view-utils.d.ts.map +1 -0
  70. package/dist/components/calendar-views/weekly-calendar-view/weekly-calendar-view-utils.js +83 -0
  71. package/dist/components/calendar-views/weekly-calendar-view/weekly-calendar-view.d.ts +26 -0
  72. package/dist/components/calendar-views/weekly-calendar-view/weekly-calendar-view.d.ts.map +1 -0
  73. package/dist/components/calendar-views/weekly-calendar-view/weekly-calendar-view.js +220 -0
  74. package/dist/components/dev-tools/dev-tools.d.ts +48 -0
  75. package/dist/components/dev-tools/dev-tools.d.ts.map +1 -0
  76. package/dist/components/dev-tools/dev-tools.js +186 -0
  77. package/dist/components/index.d.ts +14 -0
  78. package/dist/components/index.d.ts.map +1 -0
  79. package/dist/components/index.js +13 -0
  80. package/dist/components/register.d.ts +12 -0
  81. package/dist/components/register.d.ts.map +1 -0
  82. package/dist/components/register.js +11 -0
  83. package/dist/core/index.d.ts +30 -0
  84. package/dist/core/index.d.ts.map +1 -0
  85. package/dist/core/index.js +77 -0
  86. package/dist/index.d.ts +5 -0
  87. package/dist/index.d.ts.map +1 -0
  88. package/dist/index.js +8 -0
  89. package/dist/test/index.d.ts +3 -0
  90. package/dist/test/index.d.ts.map +1 -0
  91. package/dist/test/index.js +2 -0
  92. package/dist/test/mock.d.ts +23 -0
  93. package/dist/test/mock.d.ts.map +1 -0
  94. package/dist/test/mock.js +49 -0
  95. package/dist/test/screenshots.d.ts +120 -0
  96. package/dist/test/screenshots.d.ts.map +1 -0
  97. package/dist/test/screenshots.js +127 -0
  98. package/dist/test/setup.d.ts +2 -0
  99. package/dist/test/setup.d.ts.map +1 -0
  100. package/dist/test/setup.js +13 -0
  101. package/dist/types/index.d.ts +138 -0
  102. package/dist/types/index.d.ts.map +1 -0
  103. package/dist/types/index.js +15 -0
  104. package/dist/utils/calendar.d.ts +28 -0
  105. package/dist/utils/calendar.d.ts.map +1 -0
  106. package/dist/utils/calendar.js +77 -0
  107. package/dist/utils/error-handling.d.ts +6 -0
  108. package/dist/utils/error-handling.d.ts.map +1 -0
  109. package/dist/utils/error-handling.js +16 -0
  110. package/dist/utils/html.d.ts +7 -0
  111. package/dist/utils/html.d.ts.map +1 -0
  112. package/dist/utils/html.js +13 -0
  113. package/dist/utils/index.d.ts +13 -0
  114. package/dist/utils/index.d.ts.map +1 -0
  115. package/dist/utils/index.js +12 -0
  116. package/dist/utils/locale.d.ts +68 -0
  117. package/dist/utils/locale.d.ts.map +1 -0
  118. package/dist/utils/locale.js +318 -0
  119. package/dist/utils/metadata.d.ts +39 -0
  120. package/dist/utils/metadata.d.ts.map +1 -0
  121. package/dist/utils/metadata.js +66 -0
  122. package/dist/utils/oauth.d.ts +16 -0
  123. package/dist/utils/oauth.d.ts.map +1 -0
  124. package/dist/utils/oauth.js +42 -0
  125. package/dist/utils/screen.d.ts +26 -0
  126. package/dist/utils/screen.d.ts.map +1 -0
  127. package/dist/utils/screen.js +44 -0
  128. package/dist/utils/settings.d.ts +38 -0
  129. package/dist/utils/settings.d.ts.map +1 -0
  130. package/dist/utils/settings.js +89 -0
  131. package/dist/utils/template.d.ts +2 -0
  132. package/dist/utils/template.d.ts.map +1 -0
  133. package/dist/utils/template.js +6 -0
  134. package/dist/utils/theme.d.ts +47 -0
  135. package/dist/utils/theme.d.ts.map +1 -0
  136. package/dist/utils/theme.js +183 -0
  137. package/dist/utils/utm.d.ts +23 -0
  138. package/dist/utils/utm.d.ts.map +1 -0
  139. package/dist/utils/utm.js +30 -0
  140. package/dist/utils/weather.d.ts +84 -0
  141. package/dist/utils/weather.d.ts.map +1 -0
  142. package/dist/utils/weather.js +272 -0
  143. package/package.json +8 -7
@@ -0,0 +1,57 @@
1
+ import dayjs from 'dayjs';
2
+ import utc from 'dayjs/plugin/utc';
3
+ import timezone from 'dayjs/plugin/timezone';
4
+ dayjs.extend(utc);
5
+ dayjs.extend(timezone);
6
+ // Once the current hour is past noon, lock the window to 1 PM so the view
7
+ // always shows 13:00–01:00 for the rest of the afternoon and evening.
8
+ // Before 1 PM the window simply starts at the current hour.
9
+ export function getWindowStartHour(currentHour) {
10
+ return currentHour > 12 ? 13 : currentHour;
11
+ }
12
+ export function generateTimeSlots(startHour, now, locale, timezone) {
13
+ const slots = [];
14
+ for (let i = 0; i < 12; i++) {
15
+ const hour = (startHour + i) % 24;
16
+ const baseDate = dayjs(now)
17
+ .tz(timezone)
18
+ .hour(hour)
19
+ .minute(0)
20
+ .second(0)
21
+ .millisecond(0)
22
+ .toDate();
23
+ let timeString;
24
+ try {
25
+ timeString = baseDate.toLocaleTimeString(locale, {
26
+ hour: 'numeric',
27
+ minute: '2-digit',
28
+ timeZone: timezone,
29
+ });
30
+ }
31
+ catch {
32
+ const formattedHour = hour === 0 ? 12 : hour % 12 || 12;
33
+ const ampm = hour < 12 ? 'AM' : 'PM';
34
+ timeString = `${formattedHour}:00 ${ampm}`;
35
+ }
36
+ slots.push({ time: timeString, hour });
37
+ }
38
+ return slots;
39
+ }
40
+ export function filterEventsForWindow(events, dayDateStr, windowStartHour, timezone) {
41
+ const windowStart = dayjs
42
+ .tz(`${dayDateStr}T00:00:00`, timezone)
43
+ .add(windowStartHour, 'hour');
44
+ const windowEnd = windowStart.add(12, 'hour');
45
+ const windowStartMs = windowStart.valueOf();
46
+ const windowEndMs = windowEnd.valueOf();
47
+ return events.filter((event) => {
48
+ if (event.isAllDay)
49
+ return false;
50
+ const eventStart = dayjs(event.startTime).tz(timezone);
51
+ if (eventStart.format('YYYY-MM-DD') !== dayDateStr)
52
+ return false;
53
+ const eventStartMs = eventStart.valueOf();
54
+ const eventEndMs = dayjs(event.endTime).tz(timezone).valueOf();
55
+ return eventStartMs < windowEndMs && eventEndMs > windowStartMs;
56
+ });
57
+ }
@@ -0,0 +1,2 @@
1
+ export declare const COMPONENT_CSS = ":host {\n display: flex;\n flex-direction: column;\n width: 100%;\n height: 100%;\n background: transparent;\n font-family: 'Inter', system-ui, sans-serif;\n overflow: hidden;\n}\n\n*,\n*::before,\n*::after {\n box-sizing: border-box;\n}\n\n.daily-calendar-container {\n display: flex;\n flex-direction: column;\n width: 100%;\n height: 100%;\n padding: 1rem 1.25rem 1rem 1rem;\n}\n\n.today-title {\n font-size: 2.8125rem;\n font-weight: 400;\n font-style: normal;\n color: var(--theme-color-primary, #0f3a97);\n letter-spacing: -0.1125rem;\n margin: 2rem 0 2.875rem 0;\n line-height: normal;\n text-align: center;\n flex-shrink: 0;\n}\n\n.day-grid {\n display: flex;\n flex: 1;\n min-height: 0;\n background: #fff;\n border-radius: 0.75rem;\n overflow: hidden;\n padding-top: 1.25rem;\n}\n\n.time-gutter {\n display: flex;\n flex-direction: column;\n flex-shrink: 0;\n width: 6.5rem;\n}\n\n.time-label {\n flex: 1;\n display: flex;\n align-items: flex-start;\n justify-content: flex-end;\n padding-right: 1rem;\n font-size: 0.98rem;\n color: #6b7280;\n white-space: nowrap;\n transform: translateY(-0.5em);\n}\n\n.day-body {\n flex: 1;\n position: relative;\n display: flex;\n flex-direction: column;\n overflow: visible;\n border-left: 0.0625rem solid #f3f4f6;\n}\n\n.hour-row {\n flex: 1;\n border-bottom: 0.0625rem solid #f3f4f6;\n position: relative;\n min-height: 0;\n}\n\n.hour-row:last-child {\n border-bottom: none;\n}\n\n.events-area {\n position: absolute;\n top: 0;\n left: 0.653rem;\n bottom: 0;\n right: 1.25rem;\n}\n\n.event-wrapper {\n position: absolute;\n z-index: 2;\n outline: 0.125rem solid white;\n border-radius: 0 0.653rem 0.653rem 0;\n}\n\n.event-item {\n height: 100%;\n background: #ededed;\n border-left: 0.327rem solid var(--theme-color-primary, #0f3a97);\n border-radius: 0 0.653rem 0.653rem 0;\n padding: 0.5rem 0.98rem;\n overflow: hidden;\n display: flex;\n flex-direction: column;\n align-items: flex-start;\n justify-content: flex-start;\n gap: 0.327rem;\n}\n\n.event-item.event-compact {\n justify-content: center;\n padding-top: 0;\n padding-bottom: 0;\n}\n\n.event-inline-time {\n color: var(--theme-color-primary, #0f3a97);\n}\n\n.event-item.clipped-top {\n border-top-left-radius: 0;\n border-top-right-radius: 0;\n}\n\n.event-item.clipped-bottom {\n border-bottom-left-radius: 0;\n border-bottom-right-radius: 0;\n}\n\n.event-title {\n font-size: 0.875rem;\n font-weight: 500;\n color: #111827;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n line-height: normal;\n}\n\n.event-time {\n font-size: 0.75rem;\n font-weight: 400;\n color: var(--theme-color-primary, #0f3a97);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n line-height: normal;\n}\n\n.current-time-indicator {\n position: absolute;\n left: 0;\n right: 0;\n height: 0.125rem;\n background: #ea4335;\n z-index: 10;\n pointer-events: none;\n}\n\n.current-time-indicator::before {\n content: '';\n position: absolute;\n left: -0.25rem;\n top: 50%;\n transform: translateY(-50%);\n width: 0.5rem;\n height: 0.5rem;\n border-radius: 50%;\n background: #ea4335;\n}";
2
+ //# sourceMappingURL=daily-calendar-view-styles.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"daily-calendar-view-styles.d.ts","sourceRoot":"","sources":["../../../../src/components/calendar-views/daily-calendar-view/daily-calendar-view-styles.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,aAAa,ypGA8KxB,CAAA"}
@@ -0,0 +1,175 @@
1
+ export const COMPONENT_CSS = `:host {
2
+ display: flex;
3
+ flex-direction: column;
4
+ width: 100%;
5
+ height: 100%;
6
+ background: transparent;
7
+ font-family: 'Inter', system-ui, sans-serif;
8
+ overflow: hidden;
9
+ }
10
+
11
+ *,
12
+ *::before,
13
+ *::after {
14
+ box-sizing: border-box;
15
+ }
16
+
17
+ .daily-calendar-container {
18
+ display: flex;
19
+ flex-direction: column;
20
+ width: 100%;
21
+ height: 100%;
22
+ padding: 1rem 1.25rem 1rem 1rem;
23
+ }
24
+
25
+ .today-title {
26
+ font-size: 2.8125rem;
27
+ font-weight: 400;
28
+ font-style: normal;
29
+ color: var(--theme-color-primary, #0f3a97);
30
+ letter-spacing: -0.1125rem;
31
+ margin: 2rem 0 2.875rem 0;
32
+ line-height: normal;
33
+ text-align: center;
34
+ flex-shrink: 0;
35
+ }
36
+
37
+ .day-grid {
38
+ display: flex;
39
+ flex: 1;
40
+ min-height: 0;
41
+ background: #fff;
42
+ border-radius: 0.75rem;
43
+ overflow: hidden;
44
+ padding-top: 1.25rem;
45
+ }
46
+
47
+ .time-gutter {
48
+ display: flex;
49
+ flex-direction: column;
50
+ flex-shrink: 0;
51
+ width: 6.5rem;
52
+ }
53
+
54
+ .time-label {
55
+ flex: 1;
56
+ display: flex;
57
+ align-items: flex-start;
58
+ justify-content: flex-end;
59
+ padding-right: 1rem;
60
+ font-size: 0.98rem;
61
+ color: #6b7280;
62
+ white-space: nowrap;
63
+ transform: translateY(-0.5em);
64
+ }
65
+
66
+ .day-body {
67
+ flex: 1;
68
+ position: relative;
69
+ display: flex;
70
+ flex-direction: column;
71
+ overflow: visible;
72
+ border-left: 0.0625rem solid #f3f4f6;
73
+ }
74
+
75
+ .hour-row {
76
+ flex: 1;
77
+ border-bottom: 0.0625rem solid #f3f4f6;
78
+ position: relative;
79
+ min-height: 0;
80
+ }
81
+
82
+ .hour-row:last-child {
83
+ border-bottom: none;
84
+ }
85
+
86
+ .events-area {
87
+ position: absolute;
88
+ top: 0;
89
+ left: 0.653rem;
90
+ bottom: 0;
91
+ right: 1.25rem;
92
+ }
93
+
94
+ .event-wrapper {
95
+ position: absolute;
96
+ z-index: 2;
97
+ outline: 0.125rem solid white;
98
+ border-radius: 0 0.653rem 0.653rem 0;
99
+ }
100
+
101
+ .event-item {
102
+ height: 100%;
103
+ background: #ededed;
104
+ border-left: 0.327rem solid var(--theme-color-primary, #0f3a97);
105
+ border-radius: 0 0.653rem 0.653rem 0;
106
+ padding: 0.5rem 0.98rem;
107
+ overflow: hidden;
108
+ display: flex;
109
+ flex-direction: column;
110
+ align-items: flex-start;
111
+ justify-content: flex-start;
112
+ gap: 0.327rem;
113
+ }
114
+
115
+ .event-item.event-compact {
116
+ justify-content: center;
117
+ padding-top: 0;
118
+ padding-bottom: 0;
119
+ }
120
+
121
+ .event-inline-time {
122
+ color: var(--theme-color-primary, #0f3a97);
123
+ }
124
+
125
+ .event-item.clipped-top {
126
+ border-top-left-radius: 0;
127
+ border-top-right-radius: 0;
128
+ }
129
+
130
+ .event-item.clipped-bottom {
131
+ border-bottom-left-radius: 0;
132
+ border-bottom-right-radius: 0;
133
+ }
134
+
135
+ .event-title {
136
+ font-size: 0.875rem;
137
+ font-weight: 500;
138
+ color: #111827;
139
+ white-space: nowrap;
140
+ overflow: hidden;
141
+ text-overflow: ellipsis;
142
+ line-height: normal;
143
+ }
144
+
145
+ .event-time {
146
+ font-size: 0.75rem;
147
+ font-weight: 400;
148
+ color: var(--theme-color-primary, #0f3a97);
149
+ white-space: nowrap;
150
+ overflow: hidden;
151
+ text-overflow: ellipsis;
152
+ line-height: normal;
153
+ }
154
+
155
+ .current-time-indicator {
156
+ position: absolute;
157
+ left: 0;
158
+ right: 0;
159
+ height: 0.125rem;
160
+ background: #ea4335;
161
+ z-index: 10;
162
+ pointer-events: none;
163
+ }
164
+
165
+ .current-time-indicator::before {
166
+ content: '';
167
+ position: absolute;
168
+ left: -0.25rem;
169
+ top: 50%;
170
+ transform: translateY(-50%);
171
+ width: 0.5rem;
172
+ height: 0.5rem;
173
+ border-radius: 50%;
174
+ background: #ea4335;
175
+ }`;
@@ -0,0 +1,21 @@
1
+ import { type CalendarEvent } from '../event-layout.js';
2
+ export type { CalendarEvent };
3
+ export declare class DailyCalendarView extends HTMLElement {
4
+ private _events;
5
+ private _now;
6
+ private _timezone;
7
+ private _locale;
8
+ private _initialized;
9
+ static get observedAttributes(): string[];
10
+ constructor();
11
+ connectedCallback(): void;
12
+ attributeChangedCallback(name: string, _oldVal: string, newVal: string): void;
13
+ get events(): CalendarEvent[];
14
+ set events(value: CalendarEvent[]);
15
+ get now(): Date;
16
+ set now(value: Date);
17
+ private _getEventLayouts;
18
+ private _buildDayBody;
19
+ private _render;
20
+ }
21
+ //# sourceMappingURL=daily-calendar-view.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"daily-calendar-view.d.ts","sourceRoot":"","sources":["../../../../src/components/calendar-views/daily-calendar-view/daily-calendar-view.ts"],"names":[],"mappings":"AAGA,OAAO,EACL,KAAK,aAAa,EAKnB,MAAM,oBAAoB,CAAA;AAY3B,YAAY,EAAE,aAAa,EAAE,CAAA;AAE7B,qBAAa,iBAAkB,SAAQ,WAAW;IAChD,OAAO,CAAC,OAAO,CAAsB;IACrC,OAAO,CAAC,IAAI,CAAmB;IAC/B,OAAO,CAAC,SAAS,CAAgB;IACjC,OAAO,CAAC,OAAO,CAAe;IAC9B,OAAO,CAAC,YAAY,CAAiB;IAErC,MAAM,KAAK,kBAAkB,aAE5B;;IAOD,iBAAiB;IAKjB,wBAAwB,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;IAMtE,IAAI,MAAM,IAAI,aAAa,EAAE,CAE5B;IAED,IAAI,MAAM,CAAC,KAAK,EAAE,aAAa,EAAE,EAGhC;IAED,IAAI,GAAG,IAAI,IAAI,CAEd;IAED,IAAI,GAAG,CAAC,KAAK,EAAE,IAAI,EAGlB;IAED,OAAO,CAAC,gBAAgB;IAmBxB,OAAO,CAAC,aAAa;IA4CrB,OAAO,CAAC,OAAO;CAoDhB"}
@@ -0,0 +1,130 @@
1
+ import dayjs from 'dayjs';
2
+ import utc from 'dayjs/plugin/utc';
3
+ import timezone from 'dayjs/plugin/timezone';
4
+ import { findEventClusters, calculateClusterLayouts, getEventKey, } from '../event-layout.js';
5
+ import { COMPONENT_CSS } from './daily-calendar-view-styles.js';
6
+ import { generateTimeSlots, getWindowStartHour, filterEventsForWindow, } from '../calendar-window-utils.js';
7
+ import { buildTimeGutter, buildEventElement } from '../calendar-view-utils.js';
8
+ dayjs.extend(utc);
9
+ dayjs.extend(timezone);
10
+ export class DailyCalendarView extends HTMLElement {
11
+ _events = [];
12
+ _now = new Date();
13
+ _timezone = 'UTC';
14
+ _locale = 'en';
15
+ _initialized = false;
16
+ static get observedAttributes() {
17
+ return ['timezone', 'locale'];
18
+ }
19
+ constructor() {
20
+ super();
21
+ this.attachShadow({ mode: 'open' });
22
+ }
23
+ connectedCallback() {
24
+ this._initialized = true;
25
+ this._render();
26
+ }
27
+ attributeChangedCallback(name, _oldVal, newVal) {
28
+ if (name === 'timezone')
29
+ this._timezone = newVal || 'UTC';
30
+ if (name === 'locale')
31
+ this._locale = newVal || 'en';
32
+ if (this._initialized)
33
+ this._render();
34
+ }
35
+ get events() {
36
+ return this._events;
37
+ }
38
+ set events(value) {
39
+ this._events = value || [];
40
+ if (this._initialized)
41
+ this._render();
42
+ }
43
+ get now() {
44
+ return this._now;
45
+ }
46
+ set now(value) {
47
+ this._now = value;
48
+ if (this._initialized)
49
+ this._render();
50
+ }
51
+ _getEventLayouts(todayEvents) {
52
+ const timezone = this._timezone;
53
+ const layoutMap = new Map();
54
+ if (todayEvents.length === 0)
55
+ return layoutMap;
56
+ const clusters = findEventClusters(todayEvents, timezone);
57
+ for (const cluster of clusters) {
58
+ const clusterLayouts = calculateClusterLayouts(cluster, timezone);
59
+ for (const [event, layout] of clusterLayouts) {
60
+ layoutMap.set(getEventKey(event), layout);
61
+ }
62
+ }
63
+ return layoutMap;
64
+ }
65
+ _buildDayBody(todayEvents, windowStartHour, timeIndicatorPercent, eventLayouts) {
66
+ const timezone = this._timezone;
67
+ const locale = this._locale;
68
+ const dayBody = document.createElement('div');
69
+ dayBody.className = 'day-body';
70
+ for (let rowIdx = 0; rowIdx < 12; rowIdx++) {
71
+ const hourRow = document.createElement('div');
72
+ hourRow.className = 'hour-row';
73
+ dayBody.appendChild(hourRow);
74
+ }
75
+ const eventsArea = document.createElement('div');
76
+ eventsArea.className = 'events-area';
77
+ for (const event of todayEvents) {
78
+ const layout = eventLayouts.get(getEventKey(event)) ?? {
79
+ event,
80
+ column: 0,
81
+ columnSpan: 1,
82
+ totalColumns: 1,
83
+ };
84
+ eventsArea.appendChild(buildEventElement(event, windowStartHour, layout, locale, timezone));
85
+ }
86
+ dayBody.appendChild(eventsArea);
87
+ if (timeIndicatorPercent >= 0 && timeIndicatorPercent <= 100) {
88
+ const indicator = document.createElement('div');
89
+ indicator.className = 'current-time-indicator';
90
+ indicator.style.setProperty('top', `${timeIndicatorPercent}%`);
91
+ dayBody.appendChild(indicator);
92
+ }
93
+ return dayBody;
94
+ }
95
+ _render() {
96
+ const shadow = this.shadowRoot;
97
+ const timezone = this._timezone;
98
+ const locale = this._locale;
99
+ const now = this._now;
100
+ const currentTime = dayjs(now).tz(timezone);
101
+ const currentHour = currentTime.hour();
102
+ const currentMinute = currentTime.minute();
103
+ const windowStartHour = getWindowStartHour(currentHour);
104
+ const timeSlots = generateTimeSlots(windowStartHour, now, locale, timezone);
105
+ const todayStr = currentTime.format('YYYY-MM-DD');
106
+ const todayEvents = filterEventsForWindow(this._events, todayStr, windowStartHour, timezone);
107
+ const eventLayouts = this._getEventLayouts(todayEvents);
108
+ const currentSlotIndex = timeSlots.findIndex((slot) => slot.hour === currentHour);
109
+ const timeIndicatorPercent = currentSlotIndex >= 0
110
+ ? ((currentSlotIndex + currentMinute / 60) / 12) * 100
111
+ : -1;
112
+ shadow.innerHTML = `<style>${COMPONENT_CSS}</style>`;
113
+ const container = document.createElement('div');
114
+ container.className = 'daily-calendar-container';
115
+ const title = document.createElement('p');
116
+ title.className = 'today-title';
117
+ title.textContent = 'Today';
118
+ container.appendChild(title);
119
+ const dayGrid = document.createElement('div');
120
+ dayGrid.className = 'day-grid';
121
+ dayGrid.appendChild(buildTimeGutter(timeSlots));
122
+ dayGrid.appendChild(this._buildDayBody(todayEvents, windowStartHour, timeIndicatorPercent, eventLayouts));
123
+ container.appendChild(dayGrid);
124
+ shadow.appendChild(container);
125
+ }
126
+ }
127
+ if (typeof window !== 'undefined' &&
128
+ !customElements.get('daily-calendar-view')) {
129
+ customElements.define('daily-calendar-view', DailyCalendarView);
130
+ }
@@ -0,0 +1,2 @@
1
+ export { DailyCalendarView } from './daily-calendar-view.js';
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/components/calendar-views/daily-calendar-view/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAA"}
@@ -0,0 +1 @@
1
+ export { DailyCalendarView } from './daily-calendar-view.js';
@@ -0,0 +1,18 @@
1
+ export interface CalendarEvent {
2
+ id?: string;
3
+ title: string;
4
+ startTime: string;
5
+ endTime: string;
6
+ isAllDay: boolean;
7
+ backgroundColor?: string;
8
+ }
9
+ export interface EventLayout {
10
+ event: CalendarEvent;
11
+ column: number;
12
+ columnSpan: number;
13
+ totalColumns: number;
14
+ }
15
+ export declare const findEventClusters: (allEvents: CalendarEvent[], timezone: string) => CalendarEvent[][];
16
+ export declare const calculateClusterLayouts: (cluster: CalendarEvent[], timezone: string) => Map<CalendarEvent, EventLayout>;
17
+ export declare const getEventKey: (event: CalendarEvent) => string;
18
+ //# sourceMappingURL=event-layout.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"event-layout.d.ts","sourceRoot":"","sources":["../../../src/components/calendar-views/event-layout.ts"],"names":[],"mappings":"AAWA,MAAM,WAAW,aAAa;IAC5B,EAAE,CAAC,EAAE,MAAM,CAAA;IACX,KAAK,EAAE,MAAM,CAAA;IACb,SAAS,EAAE,MAAM,CAAA;IACjB,OAAO,EAAE,MAAM,CAAA;IACf,QAAQ,EAAE,OAAO,CAAA;IACjB,eAAe,CAAC,EAAE,MAAM,CAAA;CACzB;AAED,MAAM,WAAW,WAAW;IAC1B,KAAK,EAAE,aAAa,CAAA;IACpB,MAAM,EAAE,MAAM,CAAA;IACd,UAAU,EAAE,MAAM,CAAA;IAClB,YAAY,EAAE,MAAM,CAAA;CACrB;AAcD,eAAO,MAAM,iBAAiB,GAC5B,WAAW,aAAa,EAAE,EAC1B,UAAU,MAAM,KACf,aAAa,EAAE,EAmEjB,CAAA;AA2ED,eAAO,MAAM,uBAAuB,GAClC,SAAS,aAAa,EAAE,EACxB,UAAU,MAAM,KACf,GAAG,CAAC,aAAa,EAAE,WAAW,CAkBhC,CAAA;AAED,eAAO,MAAM,WAAW,GAAI,OAAO,aAAa,KAAG,MAGa,CAAA"}
@@ -0,0 +1,139 @@
1
+ import dayjs from 'dayjs';
2
+ import utc from 'dayjs/plugin/utc';
3
+ import timezone from 'dayjs/plugin/timezone';
4
+ import isSameOrBefore from 'dayjs/plugin/isSameOrBefore';
5
+ import isSameOrAfter from 'dayjs/plugin/isSameOrAfter';
6
+ dayjs.extend(utc);
7
+ dayjs.extend(timezone);
8
+ dayjs.extend(isSameOrBefore);
9
+ dayjs.extend(isSameOrAfter);
10
+ const eventsOverlap = (a, b, timezone) => {
11
+ const aStart = dayjs(a.startTime).tz(timezone);
12
+ const aEnd = dayjs(a.endTime).tz(timezone);
13
+ const bStart = dayjs(b.startTime).tz(timezone);
14
+ const bEnd = dayjs(b.endTime).tz(timezone);
15
+ return aStart.isBefore(bEnd) && bStart.isBefore(aEnd);
16
+ };
17
+ export const findEventClusters = (allEvents, timezone) => {
18
+ if (allEvents.length === 0)
19
+ return [];
20
+ const sortedEvents = [...allEvents].sort((a, b) => dayjs(a.startTime).tz(timezone).diff(dayjs(b.startTime).tz(timezone)));
21
+ const adjacencyList = new Map();
22
+ for (let i = 0; i < sortedEvents.length; i++) {
23
+ const eventI = sortedEvents[i];
24
+ adjacencyList.set(eventI, new Set());
25
+ const eventAEnd = dayjs(eventI.endTime).tz(timezone);
26
+ for (let j = i + 1; j < sortedEvents.length; j++) {
27
+ const eventJ = sortedEvents[j];
28
+ const eventBStart = dayjs(eventJ.startTime).tz(timezone);
29
+ if (eventBStart.isSameOrAfter(eventAEnd))
30
+ break;
31
+ if (eventsOverlap(eventI, eventJ, timezone)) {
32
+ adjacencyList.get(eventI).add(eventJ);
33
+ if (!adjacencyList.has(eventJ)) {
34
+ adjacencyList.set(eventJ, new Set());
35
+ }
36
+ adjacencyList.get(eventJ).add(eventI);
37
+ }
38
+ }
39
+ }
40
+ const visited = new Set();
41
+ const clusters = [];
42
+ for (const event of sortedEvents) {
43
+ if (visited.has(event))
44
+ continue;
45
+ const cluster = [];
46
+ const queue = [event];
47
+ let queueIndex = 0;
48
+ while (queueIndex < queue.length) {
49
+ const current = queue[queueIndex++];
50
+ if (visited.has(current))
51
+ continue;
52
+ visited.add(current);
53
+ cluster.push(current);
54
+ const neighbors = adjacencyList.get(current) || new Set();
55
+ for (const neighbor of neighbors) {
56
+ if (!visited.has(neighbor)) {
57
+ queue.push(neighbor);
58
+ }
59
+ }
60
+ }
61
+ cluster.sort((a, b) => {
62
+ const startDiff = dayjs(a.startTime)
63
+ .tz(timezone)
64
+ .diff(dayjs(b.startTime).tz(timezone));
65
+ if (startDiff !== 0)
66
+ return startDiff;
67
+ const aDuration = dayjs(a.endTime).diff(dayjs(a.startTime));
68
+ const bDuration = dayjs(b.endTime).diff(dayjs(b.startTime));
69
+ return bDuration - aDuration;
70
+ });
71
+ clusters.push(cluster);
72
+ }
73
+ return clusters;
74
+ };
75
+ const assignColumns = (cluster, timezone) => {
76
+ const columns = [];
77
+ const assignments = new Map();
78
+ for (const event of cluster) {
79
+ const eventStart = dayjs(event.startTime).tz(timezone);
80
+ let assignedColumn = -1;
81
+ for (let col = 0; col < columns.length; col++) {
82
+ if (columns[col]?.isSameOrBefore(eventStart)) {
83
+ assignedColumn = col;
84
+ break;
85
+ }
86
+ }
87
+ if (assignedColumn === -1) {
88
+ assignedColumn = columns.length;
89
+ columns.push(dayjs(0));
90
+ }
91
+ columns[assignedColumn] = dayjs(event.endTime).tz(timezone);
92
+ assignments.set(event, assignedColumn);
93
+ }
94
+ return { assignments, totalColumns: columns.length };
95
+ };
96
+ const groupByColumn = (cluster, assignments, totalColumns) => {
97
+ const eventsByColumn = new Map();
98
+ for (let col = 0; col < totalColumns; col++) {
99
+ eventsByColumn.set(col, []);
100
+ }
101
+ for (const event of cluster) {
102
+ const eventColumn = assignments.get(event);
103
+ if (eventColumn !== undefined) {
104
+ eventsByColumn.get(eventColumn).push(event);
105
+ }
106
+ }
107
+ return eventsByColumn;
108
+ };
109
+ const calculateColumnSpan = (event, eventColumn, totalColumns, eventsByColumn, timezone) => {
110
+ const eventStart = dayjs(event.startTime).tz(timezone);
111
+ const eventEnd = dayjs(event.endTime).tz(timezone);
112
+ let columnSpan = 1;
113
+ for (let col = eventColumn + 1; col < totalColumns; col++) {
114
+ const eventsInCol = eventsByColumn.get(col) || [];
115
+ const columnBlocked = eventsInCol.some((other) => {
116
+ const otherStart = dayjs(other.startTime).tz(timezone);
117
+ const otherEnd = dayjs(other.endTime).tz(timezone);
118
+ return eventStart.isBefore(otherEnd) && otherStart.isBefore(eventEnd);
119
+ });
120
+ if (columnBlocked)
121
+ break;
122
+ columnSpan++;
123
+ }
124
+ return columnSpan;
125
+ };
126
+ export const calculateClusterLayouts = (cluster, timezone) => {
127
+ const { assignments, totalColumns } = assignColumns(cluster, timezone);
128
+ const eventsByColumn = groupByColumn(cluster, assignments, totalColumns);
129
+ const layouts = new Map();
130
+ for (const event of cluster) {
131
+ const eventColumn = assignments.get(event);
132
+ const columnSpan = calculateColumnSpan(event, eventColumn, totalColumns, eventsByColumn, timezone);
133
+ layouts.set(event, { event, column: eventColumn, columnSpan, totalColumns });
134
+ }
135
+ return layouts;
136
+ };
137
+ export const getEventKey = (event) => event.id
138
+ ? event.id
139
+ : `${event.startTime}|${event.endTime}|${event.title || ''}`;
@@ -0,0 +1,2 @@
1
+ export { ScheduleCalendarView } from './schedule-calendar-view.js';
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/components/calendar-views/schedule-calendar-view/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,MAAM,6BAA6B,CAAA"}
@@ -0,0 +1 @@
1
+ export { ScheduleCalendarView } from './schedule-calendar-view.js';
@@ -0,0 +1,2 @@
1
+ export declare const COMPONENT_CSS = ":host {\n display: flex;\n flex-direction: column;\n width: 100%;\n height: 100%;\n background: transparent;\n font-family: 'Inter', system-ui, sans-serif;\n overflow: hidden;\n}\n\n*,\n*::before,\n*::after {\n box-sizing: border-box;\n}\n\n.schedule-container {\n display: flex;\n flex-direction: column;\n width: 100%;\n height: 100%;\n padding: 1rem 1.25rem 1rem 1rem;\n gap: 1.5rem;\n overflow: hidden;\n}\n\n.schedule-title {\n font-size: 2.8125rem;\n font-weight: 400;\n color: var(--theme-color-primary, #0f3a97);\n letter-spacing: -0.1125rem;\n margin: 2rem 0 0 0;\n line-height: normal;\n text-align: center;\n flex-shrink: 0;\n}\n\n.schedule-body {\n display: flex;\n flex: 1;\n min-height: 0;\n background: #fff;\n border-radius: 0.75rem;\n overflow: hidden;\n padding: 1.5rem;\n gap: 2rem;\n}\n\n.day-section {\n display: flex;\n flex-direction: column;\n flex: 1;\n min-width: 0;\n gap: 0.75rem;\n overflow: hidden;\n}\n\n.day-section + .day-section {\n border-left: 0.0625rem solid #f3f4f6;\n padding-left: 2rem;\n}\n\n.day-heading {\n font-size: 0.98rem;\n font-weight: 500;\n color: #6b7280;\n text-transform: uppercase;\n letter-spacing: 0.05em;\n line-height: 1.333;\n flex-shrink: 0;\n}\n\n.events-list {\n display: flex;\n flex-direction: column;\n gap: 0.5rem;\n overflow: hidden;\n flex: 1;\n min-height: 0;\n}\n\n.event-item {\n display: flex;\n flex-direction: column;\n background: #ededed;\n border-left: 0.327rem solid var(--theme-color-primary, #0f3a97);\n border-radius: 0 0.5rem 0.5rem 0;\n padding: 0.5rem 0.75rem;\n gap: 0.2rem;\n flex-shrink: 0;\n}\n\n.event-title {\n font-size: 0.9rem;\n font-weight: 500;\n color: #111827;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n line-height: normal;\n}\n\n.event-time {\n font-size: 0.8rem;\n font-weight: 400;\n color: var(--theme-color-primary, #0f3a97);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n line-height: normal;\n}\n\n.no-events {\n font-size: 0.9rem;\n color: #9ca3af;\n text-align: center;\n padding: 1.5rem 0;\n}";
2
+ //# sourceMappingURL=schedule-calendar-view-styles.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schedule-calendar-view-styles.d.ts","sourceRoot":"","sources":["../../../../src/components/calendar-views/schedule-calendar-view/schedule-calendar-view-styles.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,aAAa,0lEAqHxB,CAAA"}