@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.
- package/dist/assets/fonts/Inter-Medium.woff2 +0 -0
- package/dist/assets/fonts/Inter-Regular.woff2 +0 -0
- package/dist/assets/fonts/Inter-SemiBold.woff2 +0 -0
- package/dist/assets/images/icons/chancesleet.svg +4 -0
- package/dist/assets/images/icons/clear-night.svg +5 -0
- package/dist/assets/images/icons/clear.svg +11 -0
- package/dist/assets/images/icons/cloudy.svg +4 -0
- package/dist/assets/images/icons/drizzle.svg +5 -0
- package/dist/assets/images/icons/fewdrops.svg +4 -0
- package/dist/assets/images/icons/fog.svg +6 -0
- package/dist/assets/images/icons/haze.svg +6 -0
- package/dist/assets/images/icons/mostly-cloudy-night.svg +7 -0
- package/dist/assets/images/icons/mostly-cloudy.svg +13 -0
- package/dist/assets/images/icons/partially-cloudy-night.svg +6 -0
- package/dist/assets/images/icons/partially-cloudy.svg +12 -0
- package/dist/assets/images/icons/partlysunny.svg +6 -0
- package/dist/assets/images/icons/rain-night.svg +8 -0
- package/dist/assets/images/icons/rainy.svg +6 -0
- package/dist/assets/images/icons/sleet-night.svg +14 -0
- package/dist/assets/images/icons/sleet.svg +4 -0
- package/dist/assets/images/icons/snow.svg +19 -0
- package/dist/assets/images/icons/thunderstorm-night.svg +9 -0
- package/dist/assets/images/icons/thunderstorm.svg +7 -0
- package/dist/assets/images/icons/windy.svg +6 -0
- package/dist/assets/images/screenly.svg +10 -0
- package/dist/components/app-header/app-header.d.ts +43 -0
- package/dist/components/app-header/app-header.d.ts.map +1 -0
- package/dist/components/app-header/app-header.js +244 -0
- package/dist/components/auto-scaler/auto-scaler.d.ts +65 -0
- package/dist/components/auto-scaler/auto-scaler.d.ts.map +1 -0
- package/dist/components/auto-scaler/auto-scaler.js +304 -0
- package/dist/components/brand-logo/brand-logo.d.ts +42 -0
- package/dist/components/brand-logo/brand-logo.d.ts.map +1 -0
- package/dist/components/brand-logo/brand-logo.js +209 -0
- package/dist/components/calendar-views/calendar-view-utils.d.ts +5 -0
- package/dist/components/calendar-views/calendar-view-utils.d.ts.map +1 -0
- package/dist/components/calendar-views/calendar-view-utils.js +73 -0
- package/dist/components/calendar-views/calendar-window-utils.d.ts +9 -0
- package/dist/components/calendar-views/calendar-window-utils.d.ts.map +1 -0
- package/dist/components/calendar-views/calendar-window-utils.js +57 -0
- package/dist/components/calendar-views/daily-calendar-view/daily-calendar-view-styles.d.ts +2 -0
- package/dist/components/calendar-views/daily-calendar-view/daily-calendar-view-styles.d.ts.map +1 -0
- package/dist/components/calendar-views/daily-calendar-view/daily-calendar-view-styles.js +175 -0
- package/dist/components/calendar-views/daily-calendar-view/daily-calendar-view.d.ts +21 -0
- package/dist/components/calendar-views/daily-calendar-view/daily-calendar-view.d.ts.map +1 -0
- package/dist/components/calendar-views/daily-calendar-view/daily-calendar-view.js +130 -0
- package/dist/components/calendar-views/daily-calendar-view/index.d.ts +2 -0
- package/dist/components/calendar-views/daily-calendar-view/index.d.ts.map +1 -0
- package/dist/components/calendar-views/daily-calendar-view/index.js +1 -0
- package/dist/components/calendar-views/event-layout.d.ts +18 -0
- package/dist/components/calendar-views/event-layout.d.ts.map +1 -0
- package/dist/components/calendar-views/event-layout.js +139 -0
- package/dist/components/calendar-views/schedule-calendar-view/index.d.ts +2 -0
- package/dist/components/calendar-views/schedule-calendar-view/index.d.ts.map +1 -0
- package/dist/components/calendar-views/schedule-calendar-view/index.js +1 -0
- package/dist/components/calendar-views/schedule-calendar-view/schedule-calendar-view-styles.d.ts +2 -0
- package/dist/components/calendar-views/schedule-calendar-view/schedule-calendar-view-styles.d.ts.map +1 -0
- package/dist/components/calendar-views/schedule-calendar-view/schedule-calendar-view-styles.js +118 -0
- package/dist/components/calendar-views/schedule-calendar-view/schedule-calendar-view.d.ts +23 -0
- package/dist/components/calendar-views/schedule-calendar-view/schedule-calendar-view.d.ts.map +1 -0
- package/dist/components/calendar-views/schedule-calendar-view/schedule-calendar-view.js +167 -0
- package/dist/components/calendar-views/weekly-calendar-view/index.d.ts +3 -0
- package/dist/components/calendar-views/weekly-calendar-view/index.d.ts.map +1 -0
- package/dist/components/calendar-views/weekly-calendar-view/index.js +1 -0
- package/dist/components/calendar-views/weekly-calendar-view/weekly-calendar-view-styles.d.ts +2 -0
- package/dist/components/calendar-views/weekly-calendar-view/weekly-calendar-view-styles.d.ts.map +1 -0
- package/dist/components/calendar-views/weekly-calendar-view/weekly-calendar-view-styles.js +234 -0
- package/dist/components/calendar-views/weekly-calendar-view/weekly-calendar-view-utils.d.ts +16 -0
- package/dist/components/calendar-views/weekly-calendar-view/weekly-calendar-view-utils.d.ts.map +1 -0
- package/dist/components/calendar-views/weekly-calendar-view/weekly-calendar-view-utils.js +83 -0
- package/dist/components/calendar-views/weekly-calendar-view/weekly-calendar-view.d.ts +26 -0
- package/dist/components/calendar-views/weekly-calendar-view/weekly-calendar-view.d.ts.map +1 -0
- package/dist/components/calendar-views/weekly-calendar-view/weekly-calendar-view.js +220 -0
- package/dist/components/dev-tools/dev-tools.d.ts +48 -0
- package/dist/components/dev-tools/dev-tools.d.ts.map +1 -0
- package/dist/components/dev-tools/dev-tools.js +186 -0
- package/dist/components/index.d.ts +14 -0
- package/dist/components/index.d.ts.map +1 -0
- package/dist/components/index.js +13 -0
- package/dist/components/register.d.ts +12 -0
- package/dist/components/register.d.ts.map +1 -0
- package/dist/components/register.js +11 -0
- package/dist/core/index.d.ts +30 -0
- package/dist/core/index.d.ts.map +1 -0
- package/dist/core/index.js +77 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +8 -0
- package/dist/test/index.d.ts +3 -0
- package/dist/test/index.d.ts.map +1 -0
- package/dist/test/index.js +2 -0
- package/dist/test/mock.d.ts +23 -0
- package/dist/test/mock.d.ts.map +1 -0
- package/dist/test/mock.js +49 -0
- package/dist/test/screenshots.d.ts +120 -0
- package/dist/test/screenshots.d.ts.map +1 -0
- package/dist/test/screenshots.js +127 -0
- package/dist/test/setup.d.ts +2 -0
- package/dist/test/setup.d.ts.map +1 -0
- package/dist/test/setup.js +13 -0
- package/dist/types/index.d.ts +138 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +15 -0
- package/dist/utils/calendar.d.ts +28 -0
- package/dist/utils/calendar.d.ts.map +1 -0
- package/dist/utils/calendar.js +77 -0
- package/dist/utils/error-handling.d.ts +6 -0
- package/dist/utils/error-handling.d.ts.map +1 -0
- package/dist/utils/error-handling.js +16 -0
- package/dist/utils/html.d.ts +7 -0
- package/dist/utils/html.d.ts.map +1 -0
- package/dist/utils/html.js +13 -0
- package/dist/utils/index.d.ts +13 -0
- package/dist/utils/index.d.ts.map +1 -0
- package/dist/utils/index.js +12 -0
- package/dist/utils/locale.d.ts +68 -0
- package/dist/utils/locale.d.ts.map +1 -0
- package/dist/utils/locale.js +318 -0
- package/dist/utils/metadata.d.ts +39 -0
- package/dist/utils/metadata.d.ts.map +1 -0
- package/dist/utils/metadata.js +66 -0
- package/dist/utils/oauth.d.ts +16 -0
- package/dist/utils/oauth.d.ts.map +1 -0
- package/dist/utils/oauth.js +42 -0
- package/dist/utils/screen.d.ts +26 -0
- package/dist/utils/screen.d.ts.map +1 -0
- package/dist/utils/screen.js +44 -0
- package/dist/utils/settings.d.ts +38 -0
- package/dist/utils/settings.d.ts.map +1 -0
- package/dist/utils/settings.js +89 -0
- package/dist/utils/template.d.ts +2 -0
- package/dist/utils/template.d.ts.map +1 -0
- package/dist/utils/template.js +6 -0
- package/dist/utils/theme.d.ts +47 -0
- package/dist/utils/theme.d.ts.map +1 -0
- package/dist/utils/theme.js +183 -0
- package/dist/utils/utm.d.ts +23 -0
- package/dist/utils/utm.d.ts.map +1 -0
- package/dist/utils/utm.js +30 -0
- package/dist/utils/weather.d.ts +84 -0
- package/dist/utils/weather.d.ts.map +1 -0
- package/dist/utils/weather.js +272 -0
- package/package.json +8 -7
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { type CalendarEvent } from '../event-layout.js';
|
|
2
|
+
export type { CalendarEvent };
|
|
3
|
+
export declare class WeeklyCalendarView extends HTMLElement {
|
|
4
|
+
private _events;
|
|
5
|
+
private _now;
|
|
6
|
+
private _timezone;
|
|
7
|
+
private _locale;
|
|
8
|
+
private _initialized;
|
|
9
|
+
private _lastWindowStartHour;
|
|
10
|
+
static get observedAttributes(): string[];
|
|
11
|
+
constructor();
|
|
12
|
+
connectedCallback(): void;
|
|
13
|
+
attributeChangedCallback(name: string, _oldVal: string, newVal: string): void;
|
|
14
|
+
get events(): CalendarEvent[];
|
|
15
|
+
set events(value: CalendarEvent[]);
|
|
16
|
+
get now(): Date;
|
|
17
|
+
set now(value: Date);
|
|
18
|
+
private _getWeekStart;
|
|
19
|
+
private _getEventLayouts;
|
|
20
|
+
private _buildDayHeader;
|
|
21
|
+
private _buildDayEventsArea;
|
|
22
|
+
private _buildDayColumn;
|
|
23
|
+
private _updateTimeIndicator;
|
|
24
|
+
private _render;
|
|
25
|
+
}
|
|
26
|
+
//# sourceMappingURL=weekly-calendar-view.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"weekly-calendar-view.d.ts","sourceRoot":"","sources":["../../../../src/components/calendar-views/weekly-calendar-view/weekly-calendar-view.ts"],"names":[],"mappings":"AAGA,OAAO,EACL,KAAK,aAAa,EAKnB,MAAM,oBAAoB,CAAA;AAc3B,YAAY,EAAE,aAAa,EAAE,CAAA;AAE7B,qBAAa,kBAAmB,SAAQ,WAAW;IACjD,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;IACrC,OAAO,CAAC,oBAAoB,CAAa;IAEzC,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,EAWlB;IAED,OAAO,CAAC,aAAa;IAOrB,OAAO,CAAC,gBAAgB;IAyCxB,OAAO,CAAC,eAAe;IAuBvB,OAAO,CAAC,mBAAmB;IAiC3B,OAAO,CAAC,eAAe;IAyCvB,OAAO,CAAC,oBAAoB;IAyB5B,OAAO,CAAC,OAAO;CAuDhB"}
|
|
@@ -0,0 +1,220 @@
|
|
|
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 './weekly-calendar-view-styles.js';
|
|
6
|
+
import { getLocalizedDayNames } from '../../../utils/index.js';
|
|
7
|
+
import { generateTimeSlots, getWindowStartHour, filterEventsForWindow, } from '../calendar-window-utils.js';
|
|
8
|
+
import { setAttribute } from './weekly-calendar-view-utils.js';
|
|
9
|
+
import { buildTimeGutter, buildEventElement } from '../calendar-view-utils.js';
|
|
10
|
+
dayjs.extend(utc);
|
|
11
|
+
dayjs.extend(timezone);
|
|
12
|
+
export class WeeklyCalendarView extends HTMLElement {
|
|
13
|
+
_events = [];
|
|
14
|
+
_now = new Date();
|
|
15
|
+
_timezone = 'UTC';
|
|
16
|
+
_locale = 'en';
|
|
17
|
+
_initialized = false;
|
|
18
|
+
_lastWindowStartHour = -1;
|
|
19
|
+
static get observedAttributes() {
|
|
20
|
+
return ['timezone', 'locale'];
|
|
21
|
+
}
|
|
22
|
+
constructor() {
|
|
23
|
+
super();
|
|
24
|
+
this.attachShadow({ mode: 'open' });
|
|
25
|
+
}
|
|
26
|
+
connectedCallback() {
|
|
27
|
+
this._initialized = true;
|
|
28
|
+
this._render();
|
|
29
|
+
}
|
|
30
|
+
attributeChangedCallback(name, _oldVal, newVal) {
|
|
31
|
+
if (name === 'timezone')
|
|
32
|
+
this._timezone = newVal || 'UTC';
|
|
33
|
+
if (name === 'locale')
|
|
34
|
+
this._locale = newVal || 'en';
|
|
35
|
+
if (this._initialized)
|
|
36
|
+
this._render();
|
|
37
|
+
}
|
|
38
|
+
get events() {
|
|
39
|
+
return this._events;
|
|
40
|
+
}
|
|
41
|
+
set events(value) {
|
|
42
|
+
this._events = value || [];
|
|
43
|
+
if (this._initialized)
|
|
44
|
+
this._render();
|
|
45
|
+
}
|
|
46
|
+
get now() {
|
|
47
|
+
return this._now;
|
|
48
|
+
}
|
|
49
|
+
set now(value) {
|
|
50
|
+
this._now = value;
|
|
51
|
+
if (!this._initialized)
|
|
52
|
+
return;
|
|
53
|
+
const newWindowStartHour = getWindowStartHour(dayjs(value).tz(this._timezone).hour());
|
|
54
|
+
if (newWindowStartHour !== this._lastWindowStartHour) {
|
|
55
|
+
this._render();
|
|
56
|
+
}
|
|
57
|
+
else {
|
|
58
|
+
this._updateTimeIndicator();
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
_getWeekStart() {
|
|
62
|
+
const timezone = this._timezone;
|
|
63
|
+
const now = dayjs(this._now).tz(timezone);
|
|
64
|
+
const weekStart = now.startOf('week');
|
|
65
|
+
return weekStart.toDate();
|
|
66
|
+
}
|
|
67
|
+
_getEventLayouts() {
|
|
68
|
+
const timezone = this._timezone;
|
|
69
|
+
const weekStartDate = dayjs(this._getWeekStart()).tz(timezone);
|
|
70
|
+
const layoutMap = new Map();
|
|
71
|
+
const eventsByDay = new Map();
|
|
72
|
+
const weekEvents = this._events.filter((event) => {
|
|
73
|
+
const eventStart = dayjs(event.startTime).tz(timezone);
|
|
74
|
+
return (!eventStart.isBefore(weekStartDate) &&
|
|
75
|
+
eventStart.isBefore(weekStartDate.add(7, 'day')));
|
|
76
|
+
});
|
|
77
|
+
weekEvents.forEach((event) => {
|
|
78
|
+
const eventStart = dayjs(event.startTime).tz(timezone);
|
|
79
|
+
const dayDiff = eventStart.diff(weekStartDate, 'day');
|
|
80
|
+
const dayIndex = ((dayDiff % 7) + 7) % 7;
|
|
81
|
+
if (!eventsByDay.has(dayIndex)) {
|
|
82
|
+
eventsByDay.set(dayIndex, []);
|
|
83
|
+
}
|
|
84
|
+
eventsByDay.get(dayIndex).push(event);
|
|
85
|
+
});
|
|
86
|
+
for (let dayIndex = 0; dayIndex < 7; dayIndex++) {
|
|
87
|
+
const dayEvents = eventsByDay.get(dayIndex) || [];
|
|
88
|
+
if (dayEvents.length === 0)
|
|
89
|
+
continue;
|
|
90
|
+
const clusters = findEventClusters(dayEvents, timezone);
|
|
91
|
+
for (const cluster of clusters) {
|
|
92
|
+
const clusterLayouts = calculateClusterLayouts(cluster, timezone);
|
|
93
|
+
for (const [event, layout] of clusterLayouts) {
|
|
94
|
+
layoutMap.set(getEventKey(event), layout);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
return layoutMap;
|
|
99
|
+
}
|
|
100
|
+
_buildDayHeader(dayDayjs, isToday) {
|
|
101
|
+
const locale = this._locale;
|
|
102
|
+
const dayHeader = document.createElement('div');
|
|
103
|
+
dayHeader.className = isToday ? 'day-header today' : 'day-header';
|
|
104
|
+
const dayName = document.createElement('span');
|
|
105
|
+
dayName.className = 'day-name';
|
|
106
|
+
dayName.textContent =
|
|
107
|
+
getLocalizedDayNames(locale).short[dayDayjs.day()] || '';
|
|
108
|
+
dayHeader.appendChild(dayName);
|
|
109
|
+
const dayDateNum = document.createElement('span');
|
|
110
|
+
dayDateNum.className = 'day-date';
|
|
111
|
+
dayDateNum.textContent = String(dayDayjs.date());
|
|
112
|
+
dayHeader.appendChild(dayDateNum);
|
|
113
|
+
return dayHeader;
|
|
114
|
+
}
|
|
115
|
+
_buildDayEventsArea(dayDateStr, windowStartHour, eventLayouts) {
|
|
116
|
+
const timezone = this._timezone;
|
|
117
|
+
const locale = this._locale;
|
|
118
|
+
const eventsArea = document.createElement('div');
|
|
119
|
+
eventsArea.className = 'events-area';
|
|
120
|
+
const dayEvents = filterEventsForWindow(this._events, dayDateStr, windowStartHour, timezone);
|
|
121
|
+
for (const event of dayEvents) {
|
|
122
|
+
const layout = eventLayouts.get(getEventKey(event)) ?? {
|
|
123
|
+
event,
|
|
124
|
+
column: 0,
|
|
125
|
+
columnSpan: 1,
|
|
126
|
+
totalColumns: 1,
|
|
127
|
+
};
|
|
128
|
+
eventsArea.appendChild(buildEventElement(event, windowStartHour, layout, locale, timezone));
|
|
129
|
+
}
|
|
130
|
+
return eventsArea;
|
|
131
|
+
}
|
|
132
|
+
_buildDayColumn(dayIdx, weekStart, windowStartHour, todayStr, timeIndicatorPercent, eventLayouts) {
|
|
133
|
+
const timezone = this._timezone;
|
|
134
|
+
const dayDayjs = dayjs(weekStart).tz(timezone).add(dayIdx, 'day');
|
|
135
|
+
const dayDateStr = dayDayjs.format('YYYY-MM-DD');
|
|
136
|
+
const isToday = dayDateStr === todayStr;
|
|
137
|
+
const dayCol = document.createElement('div');
|
|
138
|
+
dayCol.className = 'day-column';
|
|
139
|
+
setAttribute(dayCol, 'data-day-index', String(dayIdx));
|
|
140
|
+
dayCol.appendChild(this._buildDayHeader(dayDayjs, isToday));
|
|
141
|
+
const dayBody = document.createElement('div');
|
|
142
|
+
dayBody.className = 'day-body';
|
|
143
|
+
for (let rowIdx = 0; rowIdx < 12; rowIdx++) {
|
|
144
|
+
const hourRow = document.createElement('div');
|
|
145
|
+
hourRow.className = 'hour-row';
|
|
146
|
+
dayBody.appendChild(hourRow);
|
|
147
|
+
}
|
|
148
|
+
dayBody.appendChild(this._buildDayEventsArea(dayDateStr, windowStartHour, eventLayouts));
|
|
149
|
+
if (isToday && timeIndicatorPercent >= 0 && timeIndicatorPercent <= 100) {
|
|
150
|
+
const indicator = document.createElement('div');
|
|
151
|
+
indicator.className = 'current-time-indicator';
|
|
152
|
+
indicator.style.setProperty('top', `${timeIndicatorPercent}%`);
|
|
153
|
+
dayBody.appendChild(indicator);
|
|
154
|
+
}
|
|
155
|
+
dayCol.appendChild(dayBody);
|
|
156
|
+
return dayCol;
|
|
157
|
+
}
|
|
158
|
+
_updateTimeIndicator() {
|
|
159
|
+
const shadow = this.shadowRoot;
|
|
160
|
+
const timezone = this._timezone;
|
|
161
|
+
const currentTime = dayjs(this._now).tz(timezone);
|
|
162
|
+
const currentHour = currentTime.hour();
|
|
163
|
+
const currentMinute = currentTime.minute();
|
|
164
|
+
const windowStartHour = this._lastWindowStartHour;
|
|
165
|
+
const slotIndex = currentHour - windowStartHour;
|
|
166
|
+
const timeIndicatorPercent = slotIndex >= 0 && slotIndex < 12
|
|
167
|
+
? ((slotIndex + currentMinute / 60) / 12) * 100
|
|
168
|
+
: -1;
|
|
169
|
+
const indicator = shadow.querySelector('.current-time-indicator');
|
|
170
|
+
if (indicator) {
|
|
171
|
+
if (timeIndicatorPercent >= 0 && timeIndicatorPercent <= 100) {
|
|
172
|
+
indicator.style.setProperty('top', `${timeIndicatorPercent}%`);
|
|
173
|
+
}
|
|
174
|
+
else {
|
|
175
|
+
indicator.remove();
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
_render() {
|
|
180
|
+
const shadow = this.shadowRoot;
|
|
181
|
+
const timezone = this._timezone;
|
|
182
|
+
const locale = this._locale;
|
|
183
|
+
const now = this._now;
|
|
184
|
+
const currentTime = dayjs(now).tz(timezone);
|
|
185
|
+
const currentHour = currentTime.hour();
|
|
186
|
+
const currentMinute = currentTime.minute();
|
|
187
|
+
const windowStartHour = getWindowStartHour(currentHour);
|
|
188
|
+
this._lastWindowStartHour = windowStartHour;
|
|
189
|
+
const timeSlots = generateTimeSlots(windowStartHour, now, locale, timezone);
|
|
190
|
+
const weekStart = this._getWeekStart();
|
|
191
|
+
const eventLayouts = this._getEventLayouts();
|
|
192
|
+
const todayStr = currentTime.format('YYYY-MM-DD');
|
|
193
|
+
const currentSlotIndex = timeSlots.findIndex((slot) => slot.hour === currentHour);
|
|
194
|
+
const timeIndicatorPercent = currentSlotIndex >= 0
|
|
195
|
+
? ((currentSlotIndex + currentMinute / 60) / 12) * 100
|
|
196
|
+
: -1;
|
|
197
|
+
shadow.innerHTML = `<style>${COMPONENT_CSS}</style>`;
|
|
198
|
+
const container = document.createElement('div');
|
|
199
|
+
container.className = 'weekly-calendar-container';
|
|
200
|
+
const title = document.createElement('p');
|
|
201
|
+
title.className = 'this-week-title';
|
|
202
|
+
title.textContent = 'This week';
|
|
203
|
+
container.appendChild(title);
|
|
204
|
+
const weekGrid = document.createElement('div');
|
|
205
|
+
weekGrid.className = 'week-grid';
|
|
206
|
+
weekGrid.appendChild(buildTimeGutter(timeSlots));
|
|
207
|
+
const daysGrid = document.createElement('div');
|
|
208
|
+
daysGrid.className = 'days-grid';
|
|
209
|
+
for (let dayIdx = 0; dayIdx < 7; dayIdx++) {
|
|
210
|
+
daysGrid.appendChild(this._buildDayColumn(dayIdx, weekStart, windowStartHour, todayStr, timeIndicatorPercent, eventLayouts));
|
|
211
|
+
}
|
|
212
|
+
weekGrid.appendChild(daysGrid);
|
|
213
|
+
container.appendChild(weekGrid);
|
|
214
|
+
shadow.appendChild(container);
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
if (typeof window !== 'undefined' &&
|
|
218
|
+
!customElements.get('weekly-calendar-view')) {
|
|
219
|
+
customElements.define('weekly-calendar-view', WeeklyCalendarView);
|
|
220
|
+
}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* <edge-app-devtools>
|
|
3
|
+
*
|
|
4
|
+
* Development overlay showing viewport, reference resolution, and scale.
|
|
5
|
+
* Intended to be used alongside <auto-scaler>. Listens for the
|
|
6
|
+
* `scalechange` event dispatched by the scaler.
|
|
7
|
+
*
|
|
8
|
+
* Usage:
|
|
9
|
+
* ```html
|
|
10
|
+
* <auto-scaler reference-width="1920" reference-height="1080">
|
|
11
|
+
* <!-- app content -->
|
|
12
|
+
* </auto-scaler>
|
|
13
|
+
* <edge-app-devtools reference-width="1920" reference-height="1080"></edge-app-devtools>
|
|
14
|
+
* ```
|
|
15
|
+
*/
|
|
16
|
+
export declare class EdgeAppDevToolsElement extends HTMLElement {
|
|
17
|
+
private infoPanel;
|
|
18
|
+
private isVisible;
|
|
19
|
+
private scale;
|
|
20
|
+
private boundOnResize;
|
|
21
|
+
private boundOnKeyDown;
|
|
22
|
+
private boundOnScaleChange;
|
|
23
|
+
static get observedAttributes(): string[];
|
|
24
|
+
constructor();
|
|
25
|
+
connectedCallback(): void;
|
|
26
|
+
disconnectedCallback(): void;
|
|
27
|
+
attributeChangedCallback(_name: string, _oldValue: string | null, _newValue: string | null): void;
|
|
28
|
+
private isDevelopmentMode;
|
|
29
|
+
private upgradeProperty;
|
|
30
|
+
private get referenceWidth();
|
|
31
|
+
private get referenceHeight();
|
|
32
|
+
private updateInfo;
|
|
33
|
+
/**
|
|
34
|
+
* Toggle visibility of dev tools.
|
|
35
|
+
* Does not dispatch events in response to host setting properties,
|
|
36
|
+
* in line with best practices.
|
|
37
|
+
*/
|
|
38
|
+
toggle(): void;
|
|
39
|
+
show(): void;
|
|
40
|
+
hide(): void;
|
|
41
|
+
/**
|
|
42
|
+
* Imperative API for AutoScaler or host code to update the scale.
|
|
43
|
+
* Prefer listening to `scalechange` events on <auto-scaler>,
|
|
44
|
+
* but this method is provided for compatibility.
|
|
45
|
+
*/
|
|
46
|
+
updateScale(scale: number): void;
|
|
47
|
+
}
|
|
48
|
+
//# sourceMappingURL=dev-tools.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dev-tools.d.ts","sourceRoot":"","sources":["../../../src/components/dev-tools/dev-tools.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AACH,qBAAa,sBAAuB,SAAQ,WAAW;IACrD,OAAO,CAAC,SAAS,CAAiB;IAClC,OAAO,CAAC,SAAS,CAAQ;IACzB,OAAO,CAAC,KAAK,CAAI;IAEjB,OAAO,CAAC,aAAa,CAA0B;IAC/C,OAAO,CAAC,cAAc,CAIrB;IACD,OAAO,CAAC,kBAAkB,CAKzB;IAED,MAAM,KAAK,kBAAkB,aAE5B;;IA4DD,iBAAiB;IAyBjB,oBAAoB;IASpB,wBAAwB,CACtB,KAAK,EAAE,MAAM,EACb,SAAS,EAAE,MAAM,GAAG,IAAI,EACxB,SAAS,EAAE,MAAM,GAAG,IAAI;IAM1B,OAAO,CAAC,iBAAiB;IAUzB,OAAO,CAAC,eAAe;IAUvB,OAAO,KAAK,cAAc,GAIzB;IAED,OAAO,KAAK,eAAe,GAI1B;IAED,OAAO,CAAC,UAAU;IAkBlB;;;;OAIG;IACI,MAAM;IAKN,IAAI;IAKJ,IAAI;IAKX;;;;OAIG;IACI,WAAW,CAAC,KAAK,EAAE,MAAM;CAIjC"}
|
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* <edge-app-devtools>
|
|
3
|
+
*
|
|
4
|
+
* Development overlay showing viewport, reference resolution, and scale.
|
|
5
|
+
* Intended to be used alongside <auto-scaler>. Listens for the
|
|
6
|
+
* `scalechange` event dispatched by the scaler.
|
|
7
|
+
*
|
|
8
|
+
* Usage:
|
|
9
|
+
* ```html
|
|
10
|
+
* <auto-scaler reference-width="1920" reference-height="1080">
|
|
11
|
+
* <!-- app content -->
|
|
12
|
+
* </auto-scaler>
|
|
13
|
+
* <edge-app-devtools reference-width="1920" reference-height="1080"></edge-app-devtools>
|
|
14
|
+
* ```
|
|
15
|
+
*/
|
|
16
|
+
export class EdgeAppDevToolsElement extends HTMLElement {
|
|
17
|
+
infoPanel;
|
|
18
|
+
isVisible = false;
|
|
19
|
+
scale = 1;
|
|
20
|
+
boundOnResize = () => this.updateInfo();
|
|
21
|
+
boundOnKeyDown = (event) => {
|
|
22
|
+
if (event.key === 'd' || event.key === 'D') {
|
|
23
|
+
this.toggle();
|
|
24
|
+
}
|
|
25
|
+
};
|
|
26
|
+
boundOnScaleChange = (event) => {
|
|
27
|
+
const detail = event.detail;
|
|
28
|
+
if (detail && typeof detail.scale === 'number') {
|
|
29
|
+
this.updateScale(detail.scale);
|
|
30
|
+
}
|
|
31
|
+
};
|
|
32
|
+
static get observedAttributes() {
|
|
33
|
+
return ['reference-width', 'reference-height'];
|
|
34
|
+
}
|
|
35
|
+
constructor() {
|
|
36
|
+
super();
|
|
37
|
+
const shadow = this.attachShadow({ mode: 'open' });
|
|
38
|
+
const style = document.createElement('style');
|
|
39
|
+
style.textContent = `
|
|
40
|
+
:host {
|
|
41
|
+
position: fixed;
|
|
42
|
+
top: 0;
|
|
43
|
+
left: 0;
|
|
44
|
+
width: 100vw;
|
|
45
|
+
height: 100vh;
|
|
46
|
+
pointer-events: none;
|
|
47
|
+
z-index: 9999;
|
|
48
|
+
display: none;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
:host([hidden]) {
|
|
52
|
+
display: none;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
.info-panel {
|
|
56
|
+
position: fixed;
|
|
57
|
+
top: 10px;
|
|
58
|
+
right: 10px;
|
|
59
|
+
background: rgba(0, 0, 0, 0.8);
|
|
60
|
+
color: #00ff00;
|
|
61
|
+
padding: 12px 16px;
|
|
62
|
+
border-radius: 4px;
|
|
63
|
+
font-family: 'Courier New', monospace;
|
|
64
|
+
font-size: 12px;
|
|
65
|
+
line-height: 1.6;
|
|
66
|
+
pointer-events: auto;
|
|
67
|
+
user-select: none;
|
|
68
|
+
min-width: 200px;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
.info-panel__title {
|
|
72
|
+
font-weight: bold;
|
|
73
|
+
margin-bottom: 8px;
|
|
74
|
+
border-bottom: 1px solid #00ff00;
|
|
75
|
+
padding-bottom: 4px;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
.info-panel__hint {
|
|
79
|
+
margin-top: 8px;
|
|
80
|
+
font-size: 10px;
|
|
81
|
+
color: #888;
|
|
82
|
+
}
|
|
83
|
+
`;
|
|
84
|
+
this.infoPanel = document.createElement('div');
|
|
85
|
+
this.infoPanel.className = 'info-panel';
|
|
86
|
+
shadow.append(style, this.infoPanel);
|
|
87
|
+
}
|
|
88
|
+
connectedCallback() {
|
|
89
|
+
this.upgradeProperty('referenceWidth');
|
|
90
|
+
this.upgradeProperty('referenceHeight');
|
|
91
|
+
if (!this.isDevelopmentMode()) {
|
|
92
|
+
// In production we keep the element present but hidden
|
|
93
|
+
this.hide();
|
|
94
|
+
return;
|
|
95
|
+
}
|
|
96
|
+
window.addEventListener('resize', this.boundOnResize);
|
|
97
|
+
window.addEventListener('keydown', this.boundOnKeyDown);
|
|
98
|
+
// Listen for scalechange events from <auto-scaler> elements
|
|
99
|
+
// Events bubble up to document level, so we can listen there
|
|
100
|
+
// This works whether auto-scaler is a parent or sibling
|
|
101
|
+
document.addEventListener('scalechange', this.boundOnScaleChange);
|
|
102
|
+
this.show();
|
|
103
|
+
this.updateInfo();
|
|
104
|
+
}
|
|
105
|
+
disconnectedCallback() {
|
|
106
|
+
window.removeEventListener('resize', this.boundOnResize);
|
|
107
|
+
window.removeEventListener('keydown', this.boundOnKeyDown);
|
|
108
|
+
document.removeEventListener('scalechange', this.boundOnScaleChange);
|
|
109
|
+
}
|
|
110
|
+
attributeChangedCallback(_name, _oldValue, _newValue) {
|
|
111
|
+
if (!this.isConnected)
|
|
112
|
+
return;
|
|
113
|
+
this.updateInfo();
|
|
114
|
+
}
|
|
115
|
+
isDevelopmentMode() {
|
|
116
|
+
const meta = import.meta;
|
|
117
|
+
return (meta.env?.DEV ||
|
|
118
|
+
window.location.hostname === 'localhost' ||
|
|
119
|
+
window.location.hostname === '127.0.0.1' ||
|
|
120
|
+
window.location.search.includes('dev=true'));
|
|
121
|
+
}
|
|
122
|
+
upgradeProperty(prop) {
|
|
123
|
+
if (Object.prototype.hasOwnProperty.call(this, prop)) {
|
|
124
|
+
const element = this;
|
|
125
|
+
const value = element[prop];
|
|
126
|
+
delete element[prop];
|
|
127
|
+
element[prop] = value;
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
get referenceWidth() {
|
|
131
|
+
const attr = this.getAttribute('reference-width');
|
|
132
|
+
const value = attr ? Number(attr) : 1920;
|
|
133
|
+
return Number.isFinite(value) ? value : 1920;
|
|
134
|
+
}
|
|
135
|
+
get referenceHeight() {
|
|
136
|
+
const attr = this.getAttribute('reference-height');
|
|
137
|
+
const value = attr ? Number(attr) : 1080;
|
|
138
|
+
return Number.isFinite(value) ? value : 1080;
|
|
139
|
+
}
|
|
140
|
+
updateInfo() {
|
|
141
|
+
if (!this.infoPanel)
|
|
142
|
+
return;
|
|
143
|
+
const viewportWidth = window.innerWidth;
|
|
144
|
+
const viewportHeight = window.innerHeight;
|
|
145
|
+
const refWidth = this.referenceWidth;
|
|
146
|
+
const refHeight = this.referenceHeight;
|
|
147
|
+
this.infoPanel.innerHTML = `
|
|
148
|
+
<div class="info-panel__title">Edge App Dev Tools</div>
|
|
149
|
+
<div><strong>Viewport:</strong> ${viewportWidth} × ${viewportHeight}px</div>
|
|
150
|
+
<div><strong>Reference:</strong> ${refWidth} × ${refHeight}px</div>
|
|
151
|
+
<div><strong>Scale:</strong> ${this.scale.toFixed(3)}</div>
|
|
152
|
+
<div><strong>Orientation:</strong> ${viewportWidth >= viewportHeight ? 'Landscape' : 'Portrait'}</div>
|
|
153
|
+
<div class="info-panel__hint">Press 'D' to toggle</div>
|
|
154
|
+
`;
|
|
155
|
+
}
|
|
156
|
+
/**
|
|
157
|
+
* Toggle visibility of dev tools.
|
|
158
|
+
* Does not dispatch events in response to host setting properties,
|
|
159
|
+
* in line with best practices.
|
|
160
|
+
*/
|
|
161
|
+
toggle() {
|
|
162
|
+
this.isVisible = !this.isVisible;
|
|
163
|
+
this.style.display = this.isVisible ? 'block' : 'none';
|
|
164
|
+
}
|
|
165
|
+
show() {
|
|
166
|
+
this.isVisible = true;
|
|
167
|
+
this.style.display = 'block';
|
|
168
|
+
}
|
|
169
|
+
hide() {
|
|
170
|
+
this.isVisible = false;
|
|
171
|
+
this.style.display = 'none';
|
|
172
|
+
}
|
|
173
|
+
/**
|
|
174
|
+
* Imperative API for AutoScaler or host code to update the scale.
|
|
175
|
+
* Prefer listening to `scalechange` events on <auto-scaler>,
|
|
176
|
+
* but this method is provided for compatibility.
|
|
177
|
+
*/
|
|
178
|
+
updateScale(scale) {
|
|
179
|
+
this.scale = scale;
|
|
180
|
+
this.updateInfo();
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
// Register the custom element
|
|
184
|
+
if (typeof window !== 'undefined' && !customElements.get('edge-app-devtools')) {
|
|
185
|
+
customElements.define('edge-app-devtools', EdgeAppDevToolsElement);
|
|
186
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Web Components for Edge Apps
|
|
3
|
+
* Reusable UI components that can be used across multiple apps
|
|
4
|
+
*/
|
|
5
|
+
export { AppHeader } from './app-header/app-header.js';
|
|
6
|
+
export { AutoScalerElement } from './auto-scaler/auto-scaler.js';
|
|
7
|
+
export { BrandLogo } from './brand-logo/brand-logo.js';
|
|
8
|
+
export { EdgeAppDevToolsElement } from './dev-tools/dev-tools.js';
|
|
9
|
+
export { WeeklyCalendarView } from './calendar-views/weekly-calendar-view/index.js';
|
|
10
|
+
export { DailyCalendarView } from './calendar-views/daily-calendar-view/index.js';
|
|
11
|
+
export { ScheduleCalendarView } from './calendar-views/schedule-calendar-view/index.js';
|
|
12
|
+
export type { CalendarEvent } from './calendar-views/weekly-calendar-view/index.js';
|
|
13
|
+
import './register.js';
|
|
14
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/components/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,4BAA4B,CAAA;AACtD,OAAO,EAAE,iBAAiB,EAAE,MAAM,8BAA8B,CAAA;AAChE,OAAO,EAAE,SAAS,EAAE,MAAM,4BAA4B,CAAA;AACtD,OAAO,EAAE,sBAAsB,EAAE,MAAM,0BAA0B,CAAA;AACjE,OAAO,EAAE,kBAAkB,EAAE,MAAM,gDAAgD,CAAA;AACnF,OAAO,EAAE,iBAAiB,EAAE,MAAM,+CAA+C,CAAA;AACjF,OAAO,EAAE,oBAAoB,EAAE,MAAM,kDAAkD,CAAA;AACvF,YAAY,EAAE,aAAa,EAAE,MAAM,gDAAgD,CAAA;AAGnF,OAAO,eAAe,CAAA"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Web Components for Edge Apps
|
|
3
|
+
* Reusable UI components that can be used across multiple apps
|
|
4
|
+
*/
|
|
5
|
+
export { AppHeader } from './app-header/app-header.js';
|
|
6
|
+
export { AutoScalerElement } from './auto-scaler/auto-scaler.js';
|
|
7
|
+
export { BrandLogo } from './brand-logo/brand-logo.js';
|
|
8
|
+
export { EdgeAppDevToolsElement } from './dev-tools/dev-tools.js';
|
|
9
|
+
export { WeeklyCalendarView } from './calendar-views/weekly-calendar-view/index.js';
|
|
10
|
+
export { DailyCalendarView } from './calendar-views/daily-calendar-view/index.js';
|
|
11
|
+
export { ScheduleCalendarView } from './calendar-views/schedule-calendar-view/index.js';
|
|
12
|
+
// Side-effect: Register all components when this module is imported
|
|
13
|
+
import './register.js';
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Side-effect import file to register all web components
|
|
3
|
+
* Import this file to ensure all components are registered as custom elements
|
|
4
|
+
*/
|
|
5
|
+
import './brand-logo/brand-logo.js';
|
|
6
|
+
import './app-header/app-header.js';
|
|
7
|
+
import './auto-scaler/auto-scaler.js';
|
|
8
|
+
import './dev-tools/dev-tools.js';
|
|
9
|
+
import './calendar-views/weekly-calendar-view/weekly-calendar-view.js';
|
|
10
|
+
import './calendar-views/daily-calendar-view/daily-calendar-view.js';
|
|
11
|
+
import './calendar-views/schedule-calendar-view/schedule-calendar-view.js';
|
|
12
|
+
//# sourceMappingURL=register.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"register.d.ts","sourceRoot":"","sources":["../../src/components/register.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,4BAA4B,CAAA;AACnC,OAAO,4BAA4B,CAAA;AACnC,OAAO,8BAA8B,CAAA;AACrC,OAAO,0BAA0B,CAAA;AACjC,OAAO,+DAA+D,CAAA;AACtE,OAAO,6DAA6D,CAAA;AACpE,OAAO,mEAAmE,CAAA"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Side-effect import file to register all web components
|
|
3
|
+
* Import this file to ensure all components are registered as custom elements
|
|
4
|
+
*/
|
|
5
|
+
import './brand-logo/brand-logo.js';
|
|
6
|
+
import './app-header/app-header.js';
|
|
7
|
+
import './auto-scaler/auto-scaler.js';
|
|
8
|
+
import './dev-tools/dev-tools.js';
|
|
9
|
+
import './calendar-views/weekly-calendar-view/weekly-calendar-view.js';
|
|
10
|
+
import './calendar-views/daily-calendar-view/daily-calendar-view.js';
|
|
11
|
+
import './calendar-views/schedule-calendar-view/schedule-calendar-view.js';
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import type { AutoScalerElement } from '../components/auto-scaler/auto-scaler.js';
|
|
2
|
+
import type { EdgeAppDevToolsElement } from '../components/dev-tools/dev-tools.js';
|
|
3
|
+
import '../components/register.js';
|
|
4
|
+
/**
|
|
5
|
+
* Initialize an edge app with auto-scaling
|
|
6
|
+
* Convenience function for quick setup using web components
|
|
7
|
+
*
|
|
8
|
+
* @example
|
|
9
|
+
* ```typescript
|
|
10
|
+
* const { scaler, devTools } = initEdgeApp('app', {
|
|
11
|
+
* referenceWidth: 1920,
|
|
12
|
+
* referenceHeight: 1080,
|
|
13
|
+
* enableDevTools: true,
|
|
14
|
+
* })
|
|
15
|
+
* ```
|
|
16
|
+
*/
|
|
17
|
+
export declare function initEdgeApp(containerId: string, options: {
|
|
18
|
+
referenceWidth: number;
|
|
19
|
+
referenceHeight: number;
|
|
20
|
+
orientation?: 'landscape' | 'portrait' | 'auto';
|
|
21
|
+
centerContent?: boolean;
|
|
22
|
+
padding?: string;
|
|
23
|
+
debounceMs?: number;
|
|
24
|
+
enableDevTools?: boolean;
|
|
25
|
+
safeZone?: unknown;
|
|
26
|
+
}): {
|
|
27
|
+
scaler: AutoScalerElement;
|
|
28
|
+
devTools?: EdgeAppDevToolsElement;
|
|
29
|
+
};
|
|
30
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/core/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,0CAA0C,CAAA;AACjF,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,sCAAsC,CAAA;AAGlF,OAAO,2BAA2B,CAAA;AAElC;;;;;;;;;;;;GAYG;AACH,wBAAgB,WAAW,CACzB,WAAW,EAAE,MAAM,EACnB,OAAO,EAAE;IACP,cAAc,EAAE,MAAM,CAAA;IACtB,eAAe,EAAE,MAAM,CAAA;IACvB,WAAW,CAAC,EAAE,WAAW,GAAG,UAAU,GAAG,MAAM,CAAA;IAC/C,aAAa,CAAC,EAAE,OAAO,CAAA;IACvB,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,cAAc,CAAC,EAAE,OAAO,CAAA;IACxB,QAAQ,CAAC,EAAE,OAAO,CAAA;CACnB,GACA;IAAE,MAAM,EAAE,iBAAiB,CAAC;IAAC,QAAQ,CAAC,EAAE,sBAAsB,CAAA;CAAE,CA+ElE"}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
// Side-effect: Ensure components are registered when initEdgeApp is used
|
|
2
|
+
import '../components/register.js';
|
|
3
|
+
/**
|
|
4
|
+
* Initialize an edge app with auto-scaling
|
|
5
|
+
* Convenience function for quick setup using web components
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* ```typescript
|
|
9
|
+
* const { scaler, devTools } = initEdgeApp('app', {
|
|
10
|
+
* referenceWidth: 1920,
|
|
11
|
+
* referenceHeight: 1080,
|
|
12
|
+
* enableDevTools: true,
|
|
13
|
+
* })
|
|
14
|
+
* ```
|
|
15
|
+
*/
|
|
16
|
+
export function initEdgeApp(containerId, options) {
|
|
17
|
+
const container = document.getElementById(containerId);
|
|
18
|
+
if (!container) {
|
|
19
|
+
throw new Error(`Container element with id "${containerId}" not found`);
|
|
20
|
+
}
|
|
21
|
+
// Ensure components are registered (they auto-register when imported)
|
|
22
|
+
// Components are registered via side-effect imports in components/register.ts
|
|
23
|
+
// This is handled when user imports '@screenly/edge-apps/components'
|
|
24
|
+
// Create <auto-scaler> element
|
|
25
|
+
const scalerEl = document.createElement('auto-scaler');
|
|
26
|
+
scalerEl.setAttribute('reference-width', String(options.referenceWidth));
|
|
27
|
+
scalerEl.setAttribute('reference-height', String(options.referenceHeight));
|
|
28
|
+
if (options.orientation) {
|
|
29
|
+
scalerEl.setAttribute('orientation', options.orientation);
|
|
30
|
+
}
|
|
31
|
+
if (options.centerContent !== undefined) {
|
|
32
|
+
if (options.centerContent) {
|
|
33
|
+
scalerEl.setAttribute('center-content', '');
|
|
34
|
+
}
|
|
35
|
+
else {
|
|
36
|
+
scalerEl.removeAttribute('center-content');
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
if (options.padding) {
|
|
40
|
+
scalerEl.setAttribute('padding', options.padding);
|
|
41
|
+
}
|
|
42
|
+
if (options.debounceMs) {
|
|
43
|
+
scalerEl.setAttribute('debounce-ms', String(options.debounceMs));
|
|
44
|
+
}
|
|
45
|
+
// Move container content into scaler element
|
|
46
|
+
// Store original children
|
|
47
|
+
const children = Array.from(container.childNodes);
|
|
48
|
+
// Move children into scaler first
|
|
49
|
+
children.forEach((child) => {
|
|
50
|
+
scalerEl.appendChild(child);
|
|
51
|
+
});
|
|
52
|
+
// Replace container children with scaler
|
|
53
|
+
container.replaceChildren(scalerEl);
|
|
54
|
+
// Create dev tools if enabled
|
|
55
|
+
let devToolsEl;
|
|
56
|
+
if (options.enableDevTools) {
|
|
57
|
+
devToolsEl = document.createElement('edge-app-devtools');
|
|
58
|
+
devToolsEl.setAttribute('reference-width', String(options.referenceWidth));
|
|
59
|
+
devToolsEl.setAttribute('reference-height', String(options.referenceHeight));
|
|
60
|
+
// Listen for scalechange events from scaler
|
|
61
|
+
scalerEl.addEventListener('scalechange', ((event) => {
|
|
62
|
+
if (devToolsEl && event.detail?.scale) {
|
|
63
|
+
devToolsEl.updateScale(event.detail.scale);
|
|
64
|
+
}
|
|
65
|
+
}));
|
|
66
|
+
// Append to body (dev tools should be at root level)
|
|
67
|
+
document.body.appendChild(devToolsEl);
|
|
68
|
+
// Update dev tools with initial scale after scaler is connected
|
|
69
|
+
// Use a small delay to ensure scaler has calculated initial scale
|
|
70
|
+
setTimeout(() => {
|
|
71
|
+
if (devToolsEl && scalerEl.scale) {
|
|
72
|
+
devToolsEl.updateScale(scalerEl.scale);
|
|
73
|
+
}
|
|
74
|
+
}, 0);
|
|
75
|
+
}
|
|
76
|
+
return { scaler: scalerEl, devTools: devToolsEl };
|
|
77
|
+
}
|