Skip to content

Commit ad54df5

Browse files
committed
Add Calendar popup modal option (ngocjohn#51)
This pull request includes several refactorings and a new feature. The refactorings improve the default chart layout size, font size calculation for moon-phase-name, and the calendar popup grid item font size. The config for legend and legend alignment has also been removed. Additionally, a new feature has been added to include a Calendar popup modal option.
1 parent 56c6117 commit ad54df5

24 files changed

+274
-93
lines changed

src/components/moon-base-data.ts

+13-1
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ export class LunarBaseData extends LitElement {
5656
.moon-phase-name {
5757
font-size: 1.5rem;
5858
padding-block: 1rem;
59+
white-space: nowrap;
5960
}
6061
`,
6162
mainStyles,
@@ -122,7 +123,18 @@ export class LunarBaseData extends LitElement {
122123

123124
private _renderPhaseName(): TemplateResult {
124125
if (!this.moon.config.hide_header) return html``;
125-
return html` <div class="moon-phase-name">${this.moon.phaseName}</div> `;
126+
return html` <div class="moon-phase-name" style=${this._computeFontSize()}>${this.moon.phaseName}</div> `;
127+
}
128+
129+
private _computeFontSize() {
130+
const parentEl = this.shadowRoot?.querySelector('.moon-phase-name') as HTMLElement;
131+
if (!parentEl) return;
132+
const parentWidth = parentEl.clientWidth;
133+
const scrollWidth = parentEl.scrollWidth;
134+
const fontSize = parseFloat(window.getComputedStyle(parentEl).fontSize);
135+
const ratio = parentWidth / scrollWidth;
136+
const newFontSize = fontSize * ratio;
137+
return `font-size: ${newFontSize}px`;
126138
}
127139

128140
private _chunkObject = (obj: MoonData, size: number): MoonDataItem => {

src/components/moon-calendar-popup.ts

+29-12
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ export class LunarCalendarPopup extends LitElement {
2525
styles,
2626
css`
2727
#lunar-calendar {
28-
max-width: 500px;
28+
/* max-width: 500px; */
2929
margin: 0 auto;
3030
backdrop-filter: blur(10px);
3131
background: var(--ha-card-background-color, var(--secondary-background-color));
@@ -47,8 +47,9 @@ export class LunarCalendarPopup extends LitElement {
4747
justify-content: space-between;
4848
align-items: center;
4949
font-weight: 600;
50-
font-size: 1.3rem;
50+
font-size: initial;
5151
}
52+
5253
.calendar-header__month {
5354
display: flex;
5455
align-items: center;
@@ -75,11 +76,6 @@ export class LunarCalendarPopup extends LitElement {
7576
cursor: default;
7677
/* gap: 2px 4px; */
7778
}
78-
@media screen and (max-width: 800px) {
79-
#calendar-grid {
80-
grid-template-rows: auto;
81-
}
82-
}
8379
.day-of-week {
8480
text-align: center;
8581
font-weight: 500;
@@ -128,6 +124,19 @@ export class LunarCalendarPopup extends LitElement {
128124
color: var(--accent-color);
129125
}
130126
}
127+
@media screen and (max-width: 800px) {
128+
#calendar-grid {
129+
grid-template-rows: auto;
130+
}
131+
.calendar-header {
132+
font-size: 1rem;
133+
font-weight: 400;
134+
}
135+
.calendar-day > .day-symbol {
136+
font-size: 1rem;
137+
padding: 0;
138+
}
139+
}
131140
`,
132141
];
133142
}
@@ -145,10 +154,7 @@ export class LunarCalendarPopup extends LitElement {
145154
<div id="lunar-calendar" class=${backgroundClass}>
146155
<div class="calendar-header">
147156
${renderNavButton(ICON.CLOSE, () => {
148-
this.card._calendarPopup = false;
149-
if (this.card._calendarInfo) {
150-
this.card._calendarInfo = false;
151-
}
157+
this._handleClose();
152158
this.viewDate = DateTime.local().startOf('month');
153159
})}
154160
<div class="calendar-header__year">
@@ -203,6 +209,17 @@ export class LunarCalendarPopup extends LitElement {
203209
`;
204210
}
205211

212+
private _handleClose(): void {
213+
if (this.card.config.calendar_modal) {
214+
this.card._dialogOpen = false;
215+
} else {
216+
this.card._calendarPopup = false;
217+
if (this.card._calendarInfo) {
218+
this.card._calendarInfo = false;
219+
}
220+
}
221+
}
222+
206223
private _setEventListeners(): void {
207224
const grid = this.shadowRoot?.getElementById('calendar-grid');
208225
if (grid) {
@@ -232,7 +249,7 @@ export class LunarCalendarPopup extends LitElement {
232249
this.card.selectedDate = date;
233250
setTimeout(() => {
234251
this.viewDate = DateTime.local().startOf('month');
235-
this.card._calendarPopup = false;
252+
this._handleClose();
236253
}, 300);
237254
}
238255

src/components/moon-horizon-chart.ts

+39-25
Original file line numberDiff line numberDiff line change
@@ -46,12 +46,31 @@ export class LunarHorizonChart extends LitElement {
4646
this.setupChart();
4747
}
4848

49-
protected shouldUpdate(_changedProperties: PropertyValues): boolean {
49+
protected updated(_changedProperties: PropertyValues): void {
5050
if (_changedProperties.has('cardWidth')) {
51-
this._chart?.resize();
51+
if (this._chart) {
52+
this._chart.resize(this.cardWidth, this.cardHeight);
53+
}
5254
}
53-
return true;
5455
}
56+
57+
// protected shouldUpdate(_changedProperties: PropertyValues): boolean {
58+
// if (_changedProperties.has('moon')) {
59+
// if (this._chart) {
60+
// this._chart.data = this.chartData;
61+
// this._chart.update('none');
62+
// }
63+
// }
64+
// return true;
65+
// }
66+
67+
get cardHeight(): number {
68+
let height = this.cardWidth * 0.5 - 96;
69+
height = this.card.config.hide_header ? height + 48 : height;
70+
71+
return height;
72+
}
73+
5574
static get styles(): CSSResultGroup {
5675
return [
5776
styles,
@@ -198,15 +217,6 @@ export class LunarHorizonChart extends LitElement {
198217
},
199218
},
200219

201-
onResize: () => {
202-
const width = this.cardWidth;
203-
const height = this.cardWidth / 2;
204-
if (this._chart) {
205-
this._chart.canvas.width = width;
206-
this._chart.canvas.height = height;
207-
this._chart.update();
208-
}
209-
},
210220
// Hover on point
211221
onHover: (_event, elements) => {
212222
if (elements.length > 0) {
@@ -236,10 +246,17 @@ export class LunarHorizonChart extends LitElement {
236246
}
237247

238248
protected render(): TemplateResult {
249+
const dataContainer = this.renderDataContainer();
239250
return html`
240251
<div class="moon-horizon">
241-
<canvas id="moonPositionChart" width="${this.cardWidth}"></canvas>
252+
<canvas id="moonPositionChart" width="${this.cardWidth}" height="${this.cardHeight}"></canvas>
242253
</div>
254+
${dataContainer}
255+
`;
256+
}
257+
258+
private renderDataContainer(): TemplateResult {
259+
return html`
243260
<div class="moon-data-header">
244261
${this.renderHeaderTime()}
245262
<ha-icon-button
@@ -397,8 +414,8 @@ export class LunarHorizonChart extends LitElement {
397414
// Scales
398415
const scales = {} as ScaleOptions;
399416
scales['y'] = {
400-
suggestedMax: sugestedYMax + 30,
401-
suggestedMin: sugestedYMin > -60 ? -60 : sugestedYMin,
417+
suggestedMin: sugestedYMin,
418+
suggestedMax: sugestedYMax,
402419
ticks: {
403420
...ticksOptions,
404421
display: graphConfig?.y_ticks || false,
@@ -432,18 +449,15 @@ export class LunarHorizonChart extends LitElement {
432449
const plugins: ChartOptions['plugins'] = {};
433450

434451
plugins['legend'] = {
435-
display: graphConfig?.show_legend ?? true,
452+
display: false,
436453
align: graphConfig?.legend_align || 'center',
437454
position: graphConfig?.legend_position || 'bottom',
438455
labels: {
439456
usePointStyle: false,
440457
boxWidth: 0,
441458
boxHeight: 0,
442-
padding: 10,
459+
padding: 4,
443460
color: secondaryTextColor,
444-
font: {
445-
size: 14,
446-
},
447461
},
448462
};
449463

@@ -703,7 +717,7 @@ export class LunarHorizonChart extends LitElement {
703717

704718
const yPosition = y.getPixelForValue(0);
705719

706-
const lineOffset = isUp ? Math.round((yPosition - top) / 3) : Math.round((bottom - yPosition) / 2);
720+
const lineOffset = isUp ? Math.round((yPosition - top) / 4) : Math.round((bottom - yPosition) / 2);
707721
const maxTextWidth = getMaxValueText(ctx, isUp ? 'Rise' : 'Set', formatedTime, direction);
708722

709723
let textAlign: CanvasTextAlign = 'start';
@@ -754,16 +768,16 @@ export class LunarHorizonChart extends LitElement {
754768
id: 'expandChartArea',
755769
beforeDraw: (chart: Chart) => {
756770
chart.chartArea.left = 0;
757-
chart.chartArea.right = chart.width;
771+
chart.chartArea.right = this.cardWidth;
758772
chart.chartArea.top = 0;
759-
chart.chartArea.bottom = chart.height;
773+
chart.chartArea.bottom = this.cardHeight;
760774
},
761775

762776
afterUpdate: (chart: Chart) => {
763777
chart.chartArea.left = 0;
764-
chart.chartArea.right = chart.width;
778+
chart.chartArea.right = this.cardWidth;
765779
chart.chartArea.top = 0;
766-
chart.chartArea.bottom = chart.height;
780+
chart.chartArea.bottom = this.cardHeight;
767781
},
768782
};
769783
};

src/components/moon-horizon-dynamic.ts

+6-6
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,7 @@ export class LunarHorizonDynamic extends LitElement {
2424
@property({ attribute: false }) public hass!: HomeAssistant;
2525
@property({ attribute: false }) moon!: Moon;
2626
@property({ attribute: false }) card!: LunarPhaseCard;
27-
28-
@state() private cardWidth: number = 500;
27+
@property({ type: Number }) public cardWidth!: number;
2928

3029
@state() public fillColors!: FILL_COLORS;
3130

@@ -49,6 +48,7 @@ export class LunarHorizonDynamic extends LitElement {
4948
}
5049

5150
protected updated(_changedProperties: PropertyValues): void {
51+
if (!this.card.config || !this.moon) return;
5252
if (_changedProperties.has('cardWidth')) {
5353
if (this.dynamicChart) {
5454
this.dynamicChart.resize(this.cardWidth, this.cardHeight);
@@ -59,7 +59,6 @@ export class LunarHorizonDynamic extends LitElement {
5959
get cardHeight(): number {
6060
let height = this.cardWidth * 0.5;
6161
height = this.card.config.hide_header ? height : height - 48;
62-
console.log('height dynamic', height);
6362
return height;
6463
}
6564

@@ -95,6 +94,7 @@ export class LunarHorizonDynamic extends LitElement {
9594
box-sizing: border-box;
9695
border-radius: 24px;
9796
will-change: backdrop-filter;
97+
margin: -2px;
9898
}
9999
100100
#dynamic-chart {
@@ -348,7 +348,7 @@ export class LunarHorizonDynamic extends LitElement {
348348
const index = timeLabels.indexOf(closestTime);
349349
return {
350350
id: 'nowLine',
351-
beforeDatasetsDraw: (chart: Chart) => {
351+
beforeDatasetDraw: (chart: Chart) => {
352352
const now = this._date;
353353
const closestTime = timeLabels.reduce((a, b) =>
354354
Math.abs(b - now.getTime()) < Math.abs(a - now.getTime()) ? b : a
@@ -383,7 +383,7 @@ export class LunarHorizonDynamic extends LitElement {
383383
ctx.restore();
384384
},
385385

386-
afterDatasetsDraw: (chart: Chart) => {
386+
afterDatasetDraw: (chart: Chart) => {
387387
const dataSet = chart.getDatasetMeta(0);
388388
const {
389389
ctx,
@@ -609,7 +609,7 @@ export class LunarHorizonDynamic extends LitElement {
609609
private _expandChartArea = (): Plugin => {
610610
return {
611611
id: 'expandChartArea',
612-
beforeRender: (chart: Chart) => {
612+
afterRender: (chart: Chart) => {
613613
chart.chartArea.right = this.cardWidth;
614614
chart.chartArea.bottom = this.cardHeight;
615615
},

src/components/moon-star-field.ts

+16-3
Original file line numberDiff line numberDiff line change
@@ -3,16 +3,23 @@ import { customElement, property, state } from 'lit/decorators.js';
33

44
import { LunarPhaseCard } from '../lunar-phase-card';
55

6-
@customElement('moon-star-field')
6+
@customElement('lunar-star-field')
77
export class LunarStarField extends LitElement {
88
@property({ attribute: false }) _card!: LunarPhaseCard;
9-
@state() public count: number = 30;
9+
@state() private count: number = 30;
1010

1111
protected firstUpdated(_changedProperties: PropertyValues): void {
1212
super.firstUpdated(_changedProperties);
1313
this._createStarfield();
1414
}
1515

16+
protected updated(_changedProperties: PropertyValues): void {
17+
super.updated(_changedProperties);
18+
if (_changedProperties.has('_card')) {
19+
this._createStarfield();
20+
}
21+
}
22+
1623
static get styles(): CSSResultGroup {
1724
return [
1825
css`
@@ -69,11 +76,17 @@ export class LunarStarField extends LitElement {
6976
const y = Math.random() * starfield.offsetHeight;
7077

7178
// Random blink delay
72-
const delay = 20 + Math.random() * 5;
79+
const delay = 3 + Math.random() * 3;
7380
star.style.left = `${x}px`;
7481
star.style.top = `${y}px`;
7582
star.style.animationDelay = `${delay}s`;
7683
starfield.appendChild(star);
7784
}
7885
}
7986
}
87+
88+
declare global {
89+
interface HTMLElementTagNameMap {
90+
'lunar-star-field': LunarStarField;
91+
}
92+
}

0 commit comments

Comments
 (0)