@glatam/calendar-ui 1.0.2 → 1.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 (37) hide show
  1. package/dist/components/calendar-modal.d.ts +24 -0
  2. package/dist/components/calendar-modal.d.ts.map +1 -0
  3. package/dist/glatam-calendar-mini.d.ts +38 -0
  4. package/dist/glatam-calendar-mini.d.ts.map +1 -0
  5. package/dist/glatam-calendar.cjs +836 -0
  6. package/dist/glatam-calendar.d.ts +58 -0
  7. package/dist/glatam-calendar.d.ts.map +1 -0
  8. package/dist/glatam-calendar.js +1541 -0
  9. package/{src/index.ts → dist/index.d.ts} +1 -0
  10. package/dist/index.d.ts.map +1 -0
  11. package/dist/styles/calendar-modal.css.d.ts +2 -0
  12. package/dist/styles/calendar-modal.css.d.ts.map +1 -0
  13. package/dist/styles/calendar.css.d.ts +2 -0
  14. package/dist/styles/calendar.css.d.ts.map +1 -0
  15. package/dist/styles/variables.css.d.ts +2 -0
  16. package/dist/styles/variables.css.d.ts.map +1 -0
  17. package/dist/utils/timezone-utils.d.ts +16 -0
  18. package/dist/utils/timezone-utils.d.ts.map +1 -0
  19. package/dist/views/day-view.d.ts +27 -0
  20. package/dist/views/day-view.d.ts.map +1 -0
  21. package/dist/views/month-view.d.ts +23 -0
  22. package/dist/views/month-view.d.ts.map +1 -0
  23. package/dist/views/week-view.d.ts +28 -0
  24. package/dist/views/week-view.d.ts.map +1 -0
  25. package/package.json +6 -2
  26. package/src/components/calendar-modal.ts +0 -163
  27. package/src/glatam-calendar-mini.ts +0 -147
  28. package/src/glatam-calendar.ts +0 -194
  29. package/src/styles/calendar-modal.css.ts +0 -158
  30. package/src/styles/calendar.css.ts +0 -259
  31. package/src/styles/variables.css.ts +0 -91
  32. package/src/utils/timezone-utils.ts +0 -87
  33. package/src/views/day-view.ts +0 -130
  34. package/src/views/month-view.ts +0 -117
  35. package/src/views/week-view.ts +0 -158
  36. package/tsconfig.json +0 -8
  37. package/vite.config.ts +0 -35
@@ -7,3 +7,4 @@ export * from './components/calendar-modal.js';
7
7
  export * from './styles/variables.css.js';
8
8
  export * from './styles/calendar.css.js';
9
9
  export { formatISODate, parseISODate, isTimeBlocked } from '@glatam/calendar-core';
10
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,sBAAsB,CAAC;AACrC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,uBAAuB,CAAC;AACtC,cAAc,sBAAsB,CAAC;AACrC,cAAc,qBAAqB,CAAC;AACpC,cAAc,gCAAgC,CAAC;AAC/C,cAAc,2BAA2B,CAAC;AAC1C,cAAc,0BAA0B,CAAC;AACzC,OAAO,EAAE,aAAa,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC"}
@@ -0,0 +1,2 @@
1
+ export declare const modalStyles: import('lit').CSSResult;
2
+ //# sourceMappingURL=calendar-modal.css.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"calendar-modal.css.d.ts","sourceRoot":"","sources":["../../src/styles/calendar-modal.css.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,WAAW,yBA2JvB,CAAC"}
@@ -0,0 +1,2 @@
1
+ export declare const calendarStyles: import('lit').CSSResult;
2
+ //# sourceMappingURL=calendar.css.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"calendar.css.d.ts","sourceRoot":"","sources":["../../src/styles/calendar.css.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,cAAc,yBAgQ1B,CAAC"}
@@ -0,0 +1,2 @@
1
+ export declare const variablesStyles: import('lit').CSSResult;
2
+ //# sourceMappingURL=variables.css.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"variables.css.d.ts","sourceRoot":"","sources":["../../src/styles/variables.css.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,eAAe,yBAwF3B,CAAC"}
@@ -0,0 +1,16 @@
1
+ import { TimeSlot } from '@glatam/calendar-core';
2
+
3
+ /**
4
+ * Calculates the difference in minutes between two timezones on a specific date.
5
+ * 'local' represents the user's local timezone.
6
+ */
7
+ export declare function getTimezoneOffsetDiff(date: Date, fromTz: string, toTz: string): number;
8
+ /**
9
+ * Shifts a single TimeSlot's times by a given offset in minutes and returns the shifted slot and optional day offset.
10
+ */
11
+ export declare function shiftSlot(slot: TimeSlot, offsetMinutes: number): {
12
+ start: string;
13
+ end: string;
14
+ dayShift: number;
15
+ };
16
+ //# sourceMappingURL=timezone-utils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"timezone-utils.d.ts","sourceRoot":"","sources":["../../src/utils/timezone-utils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AAEjD;;;GAGG;AACH,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAqCtF;AAED;;GAEG;AACH,wBAAgB,SAAS,CAAC,IAAI,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,GAAG;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,CAsCjH"}
@@ -0,0 +1,27 @@
1
+ import { LitElement } from 'lit';
2
+ import { CalendarDay, TimeSlot } from '@glatam/calendar-core';
3
+
4
+ export declare class GlatamCalendarDayView extends LitElement {
5
+ static styles: import('lit').CSSResult;
6
+ day: CalendarDay | null;
7
+ slots: TimeSlot[];
8
+ locale: string;
9
+ selectedRange: {
10
+ dateString: string;
11
+ start: string;
12
+ end: string;
13
+ } | null;
14
+ role: string;
15
+ private isDragging;
16
+ private dragStartSlotIndex;
17
+ private dragEndSlotIndex;
18
+ connectedCallback(): void;
19
+ disconnectedCallback(): void;
20
+ private handleMouseDown;
21
+ private handleMouseEnter;
22
+ private handleMouseUp;
23
+ private isSlotSelected;
24
+ private isSlotDragSelecting;
25
+ render(): import('lit-html').TemplateResult<1>;
26
+ }
27
+ //# sourceMappingURL=day-view.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"day-view.d.ts","sourceRoot":"","sources":["../../src/views/day-view.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAa,MAAM,KAAK,CAAC;AAG5C,OAAO,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AAE9D,qBACa,qBAAsB,SAAQ,UAAU;IACnD,MAAM,CAAC,MAAM,0BA6BX;IAE0B,GAAG,EAAE,WAAW,GAAG,IAAI,CAAQ;IAChC,KAAK,EAAE,QAAQ,EAAE,CAAM;IACtB,MAAM,SAAQ;IACd,aAAa,EAAE;QAAE,UAAU,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAQ;IAChF,IAAI,SAAc;IAErC,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,kBAAkB,CAAuB;IACjD,OAAO,CAAC,gBAAgB,CAAuB;IAExD,iBAAiB;IACjB,oBAAoB;IAEpB,OAAO,CAAC,eAAe;IAYvB,OAAO,CAAC,gBAAgB;IAIxB,OAAO,CAAC,aAAa,CAenB;IAEF,OAAO,CAAC,cAAc;IAKtB,OAAO,CAAC,mBAAmB;IAM3B,MAAM;CAkCP"}
@@ -0,0 +1,23 @@
1
+ import { LitElement } from 'lit';
2
+ import { CalendarDay } from '@glatam/calendar-core';
3
+
4
+ export declare class GlatamCalendarMonthView extends LitElement {
5
+ static styles: import('lit').CSSResult;
6
+ days: CalendarDay[];
7
+ locale: string;
8
+ startOfWeekDay: number;
9
+ selectedDates: string[];
10
+ role: string;
11
+ size: string;
12
+ minDate: string;
13
+ maxDate: string;
14
+ showNeighboringMonth: boolean;
15
+ tileClassName: ((data: {
16
+ date: Date;
17
+ dateString: string;
18
+ }) => string) | null;
19
+ private getWeekdayNames;
20
+ private handleDayClick;
21
+ render(): import('lit-html').TemplateResult<1>;
22
+ }
23
+ //# sourceMappingURL=month-view.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"month-view.d.ts","sourceRoot":"","sources":["../../src/views/month-view.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAa,MAAM,KAAK,CAAC;AAG5C,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAEpD,qBACa,uBAAwB,SAAQ,UAAU;IACrD,MAAM,CAAC,MAAM,0BAgCX;IAEyB,IAAI,EAAE,WAAW,EAAE,CAAM;IACxB,MAAM,SAAQ;IACd,cAAc,SAAK;IACpB,aAAa,EAAE,MAAM,EAAE,CAAM;IAC5B,IAAI,SAAc;IACH,IAAI,SAAY;IAC/B,OAAO,SAAM;IACb,OAAO,SAAM;IACZ,oBAAoB,UAAQ;IACzB,aAAa,EAAE,CAAC,CAAC,IAAI,EAAE;QAAE,IAAI,EAAE,IAAI,CAAC;QAAC,UAAU,EAAE,MAAM,CAAA;KAAE,KAAK,MAAM,CAAC,GAAG,IAAI,CAAQ;IAEpH,OAAO,CAAC,eAAe;IAWvB,OAAO,CAAC,cAAc;IAStB,MAAM;CA4CP"}
@@ -0,0 +1,28 @@
1
+ import { LitElement } from 'lit';
2
+ import { CalendarDay, TimeSlot } from '@glatam/calendar-core';
3
+
4
+ export declare class GlatamCalendarWeekView extends LitElement {
5
+ static styles: import('lit').CSSResult;
6
+ days: CalendarDay[];
7
+ slots: TimeSlot[];
8
+ locale: string;
9
+ selectedRange: {
10
+ dateString: string;
11
+ start: string;
12
+ end: string;
13
+ } | null;
14
+ role: string;
15
+ private isDragging;
16
+ private dragDayIndex;
17
+ private dragStartSlotIndex;
18
+ private dragEndSlotIndex;
19
+ connectedCallback(): void;
20
+ disconnectedCallback(): void;
21
+ private handleMouseDown;
22
+ private handleMouseEnter;
23
+ private handleMouseUp;
24
+ private isSlotSelected;
25
+ private isSlotDragSelecting;
26
+ render(): import('lit-html').TemplateResult<1>;
27
+ }
28
+ //# sourceMappingURL=week-view.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"week-view.d.ts","sourceRoot":"","sources":["../../src/views/week-view.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAa,MAAM,KAAK,CAAC;AAG5C,OAAO,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AAE9D,qBACa,sBAAuB,SAAQ,UAAU;IACpD,MAAM,CAAC,MAAM,0BAoDX;IAEyB,IAAI,EAAE,WAAW,EAAE,CAAM;IACzB,KAAK,EAAE,QAAQ,EAAE,CAAM;IACtB,MAAM,SAAQ;IACd,aAAa,EAAE;QAAE,UAAU,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAQ;IAChF,IAAI,SAAc;IAErC,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,YAAY,CAAuB;IAC3C,OAAO,CAAC,kBAAkB,CAAuB;IACjD,OAAO,CAAC,gBAAgB,CAAuB;IAExD,iBAAiB;IACjB,oBAAoB;IAEpB,OAAO,CAAC,eAAe;IAYvB,OAAO,CAAC,gBAAgB;IAIxB,OAAO,CAAC,aAAa,CAenB;IAEF,OAAO,CAAC,cAAc;IAKtB,OAAO,CAAC,mBAAmB;IAM3B,MAAM;CAsCP"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@glatam/calendar-ui",
3
- "version": "1.0.2",
3
+ "version": "1.0.3",
4
4
  "description": "Componente web UI para el calendario @glatam/calendar",
5
5
  "type": "module",
6
6
  "author": "Santiago Hernández Saldarriaga",
@@ -14,6 +14,9 @@
14
14
  "import": "./dist/glatam-calendar.js"
15
15
  }
16
16
  },
17
+ "files": [
18
+ "dist"
19
+ ],
17
20
  "repository": {
18
21
  "type": "git",
19
22
  "url": "git+https://github.com/santiagoshs/glatam-calendar.git"
@@ -33,10 +36,11 @@
33
36
  ],
34
37
  "scripts": {
35
38
  "build": "vite build",
39
+ "prepublishOnly": "npm run build",
36
40
  "dev": "vite"
37
41
  },
38
42
  "dependencies": {
39
- "@glatam/calendar-core": "^1.0.2",
43
+ "@glatam/calendar-core": "^1.0.3",
40
44
  "lit": "^3.1.2"
41
45
  },
42
46
  "devDependencies": {
@@ -1,163 +0,0 @@
1
- import { LitElement, html } from 'lit';
2
- import { customElement, property, state } from 'lit/decorators.js';
3
- import { BlockingRule } from '@glatam/calendar-core';
4
- import { modalStyles } from '../styles/calendar-modal.css.js';
5
-
6
- @customElement('glatam-calendar-modal')
7
- export class GlatamCalendarModal extends LitElement {
8
- static styles = modalStyles;
9
-
10
- @property({ type: Boolean }) open = false;
11
- @property({ type: String }) dateString = '';
12
- @property({ type: String }) startTime = '';
13
- @property({ type: String }) endTime = '';
14
- @property({ type: Boolean }) isRange = false;
15
- @property({ type: Object }) existingRule: BlockingRule | null = null;
16
-
17
- @state() private description = '';
18
- @state() private blockAllDay = true;
19
- @state() private isRecurring = false;
20
- @state() private selectedDays: number[] = [];
21
-
22
- willUpdate(changedProperties: Map<string, any>) {
23
- if (changedProperties.has('open') && this.open) {
24
- if (this.existingRule) {
25
- this.description = 'Bloqueo';
26
- this.blockAllDay = !this.existingRule.slots || this.existingRule.slots.length === 0;
27
- this.isRecurring = this.existingRule.type === 'weekly';
28
- this.selectedDays = this.existingRule.daysOfWeek || [];
29
- } else {
30
- this.description = '';
31
- this.blockAllDay = !this.isRange;
32
- this.isRecurring = false;
33
- this.selectedDays = [new Date(this.dateString + 'T00:00:00').getDay()];
34
- }
35
- }
36
- }
37
-
38
- updated(changedProperties: Map<string, any>) {
39
- if (changedProperties.has('open')) {
40
- const dialog = this.shadowRoot?.getElementById('booking-dialog') as HTMLDialogElement;
41
- if (dialog) {
42
- if (this.open) {
43
- if (!dialog.open) dialog.showModal();
44
- } else {
45
- if (dialog.open) dialog.close();
46
- }
47
- }
48
- }
49
- }
50
-
51
- private handleDialogClose() {
52
- if (this.open) {
53
- this.dispatchEvent(new CustomEvent('close', { bubbles: true, composed: true }));
54
- }
55
- }
56
-
57
- private toggleDay(dayNum: number) {
58
- const idx = this.selectedDays.indexOf(dayNum);
59
- this.selectedDays = idx > -1 ? this.selectedDays.filter(d => d !== dayNum) : [...this.selectedDays, dayNum];
60
- }
61
-
62
- private handleSave() {
63
- const detail = {
64
- title: this.description || 'Bloqueo',
65
- blockAllDay: this.blockAllDay,
66
- isRecurring: this.isRecurring,
67
- selectedDays: this.selectedDays,
68
- dateString: this.dateString,
69
- startTime: this.startTime,
70
- endTime: this.endTime
71
- };
72
- this.dispatchEvent(new CustomEvent('save-rule', { detail, bubbles: true, composed: true }));
73
- }
74
-
75
- private handleDelete() {
76
- if (this.existingRule) {
77
- this.dispatchEvent(new CustomEvent('delete-rule', {
78
- detail: { id: this.existingRule.id },
79
- bubbles: true,
80
- composed: true
81
- }));
82
- }
83
- }
84
-
85
- render() {
86
- const weekLabels = ['D', 'L', 'M', 'M', 'J', 'V', 'S'];
87
- const formattedSelection = this.isRange
88
- ? `${this.dateString} (${this.startTime} - ${this.endTime})`
89
- : this.dateString;
90
-
91
- return html`
92
- <dialog id="booking-dialog" @close=${this.handleDialogClose}>
93
- <div class="modal-content">
94
- <h3>${this.existingRule ? 'Gestionar Bloqueo' : 'Crear Bloqueo'}</h3>
95
-
96
- <div style="font-size: 0.85rem; color: var(--glatam-text-secondary);">
97
- Selección: <strong>${formattedSelection}</strong>
98
- </div>
99
-
100
- <div class="form-group">
101
- <label>Descripción / Nota</label>
102
- <input
103
- type="text"
104
- .value=${this.description}
105
- @input=${(e: any) => this.description = e.target.value}
106
- placeholder="Ej. Reunión de equipo, Vacaciones"
107
- />
108
- </div>
109
-
110
- <div class="switch-row">
111
- <label>Bloquear todo el día</label>
112
- <label class="switch">
113
- <input
114
- type="checkbox"
115
- .checked=${this.blockAllDay}
116
- @change=${(e: any) => this.blockAllDay = e.target.checked}
117
- />
118
- <span class="slider"></span>
119
- </label>
120
- </div>
121
-
122
- <div class="switch-row">
123
- <label>Repetir semanalmente</label>
124
- <label class="switch">
125
- <input
126
- type="checkbox"
127
- .checked=${this.isRecurring}
128
- @change=${(e: any) => this.isRecurring = e.target.checked}
129
- />
130
- <span class="slider"></span>
131
- </label>
132
- </div>
133
-
134
- ${this.isRecurring
135
- ? html`
136
- <div class="form-group">
137
- <label>Repetir los días</label>
138
- <div class="days-grid">
139
- ${[1, 2, 3, 4, 5, 6, 0].map(day => html`
140
- <button
141
- class="day-btn ${this.selectedDays.includes(day) ? 'selected' : ''}"
142
- @click=${() => this.toggleDay(day)}
143
- >
144
- ${weekLabels[day]}
145
- </button>
146
- `)}
147
- </div>
148
- </div>
149
- `
150
- : ''}
151
-
152
- <div class="btn-actions">
153
- ${this.existingRule
154
- ? html`<button class="btn btn-danger" @click=${this.handleDelete}>Eliminar</button>`
155
- : ''}
156
- <button class="btn btn-cancel" @click=${() => this.dispatchEvent(new CustomEvent('close'))}>Cancelar</button>
157
- <button class="btn btn-save" @click=${this.handleSave}>Guardar</button>
158
- </div>
159
- </div>
160
- </dialog>
161
- `;
162
- }
163
- }
@@ -1,147 +0,0 @@
1
- import { LitElement, html, css } from 'lit';
2
- import { customElement, property, state } from 'lit/decorators.js';
3
- import {
4
- generateMonthDays,
5
- isTimeBlocked,
6
- BlockingRule,
7
- TimeSlot
8
- } from '@glatam/calendar-core';
9
- import { variablesStyles } from './styles/variables.css.js';
10
- import { calendarStyles } from './styles/calendar.css.js';
11
- import { getTimezoneOffsetDiff, shiftSlot } from './utils/timezone-utils.js';
12
-
13
- import './views/month-view.js';
14
-
15
- @customElement('glatam-calendar-mini')
16
- export class GlatamCalendarMini extends LitElement {
17
- static styles = [
18
- variablesStyles,
19
- calendarStyles,
20
- css`
21
- :host {
22
- display: inline-block;
23
- background: transparent;
24
- border: none;
25
- padding: 0;
26
- box-shadow: none;
27
- width: 100%;
28
- }
29
- `
30
- ];
31
-
32
- @property({ type: String }) role = 'buyer'; // Default to buyer for checkout
33
- @property({ type: String }) locale = 'es';
34
- @property({ type: Number }) startOfWeekDay = 0;
35
- @property({ type: Array }) rules: BlockingRule[] = [];
36
- @property({ type: Object }) selectedRange: { dateString: string; start: string; end: string } | null = null;
37
- @property({ type: String, reflect: true }) size = 'medium';
38
- @property({ type: String }) hostTimezone = 'America/Bogota'; @property({ type: String }) activeTimezone = 'local';
39
- @property({ type: String }) minDate = ''; @property({ type: String }) maxDate = '';
40
- @property({ type: Boolean }) showNeighboringMonth = true;
41
- @property({ attribute: false }) tileClassName: ((data: { date: Date; dateString: string }) => string) | null = null;
42
- @property({ type: Array }) slots: TimeSlot[] = [
43
- { start: '09:00', end: '10:00' }, { start: '10:00', end: '11:00' },
44
- { start: '11:00', end: '12:00' }, { start: '12:00', end: '13:00' },
45
- { start: '13:00', end: '14:00' }, { start: '14:00', end: '15:00' },
46
- { start: '15:00', end: '16:00' }, { start: '16:00', end: '17:00' },
47
- { start: '17:00', end: '18:00' },
48
- ];
49
-
50
- @state() private activeDate = new Date();
51
- @state() private dropdownOpen = false;
52
- @state() private dropdownSelectedDateString = '';
53
-
54
- private handleDropdownDaySelect(e: CustomEvent<{ dateString: string }>) {
55
- this.dropdownSelectedDateString = e.detail.dateString;
56
- }
57
-
58
- private selectDropdownSlot(slot: any) {
59
- const detail = {
60
- dateString: this.dropdownSelectedDateString,
61
- start: slot.displayStart,
62
- end: slot.displayEnd,
63
- hostStart: slot.start,
64
- hostEnd: slot.end
65
- };
66
- this.selectedRange = { dateString: this.dropdownSelectedDateString, start: slot.displayStart, end: slot.displayEnd };
67
- this.dispatchEvent(new CustomEvent('booking-selected', { detail, bubbles: true, composed: true }));
68
- this.dropdownOpen = false;
69
- this.dropdownSelectedDateString = '';
70
- }
71
-
72
- render() {
73
- const label = this.selectedRange
74
- ? `Reserva: ${this.selectedRange.dateString} (${this.selectedRange.start} - ${this.selectedRange.end})`
75
- : 'Seleccionar Fecha y Hora';
76
-
77
- const y = this.activeDate.getFullYear(), m = this.activeDate.getMonth();
78
- const dropdownDate = this.dropdownSelectedDateString ? new Date(this.dropdownSelectedDateString + 'T00:00:00') : null;
79
- const offset = dropdownDate && this.activeTimezone === 'local' ? getTimezoneOffsetDiff(dropdownDate, this.hostTimezone, 'local') : 0;
80
-
81
- const dropdownSlots = dropdownDate
82
- ? this.slots.map(slot => {
83
- const isBlocked = isTimeBlocked(dropdownDate, slot, this.rules);
84
- const shifted = shiftSlot(slot, offset);
85
- const suffix = shifted.dayShift > 0 ? ' (+1d)' : shifted.dayShift < 0 ? ' (-1d)' : '';
86
- return {
87
- ...slot,
88
- displayStart: shifted.start + suffix,
89
- displayEnd: shifted.end + suffix,
90
- isBlocked
91
- };
92
- })
93
- : [];
94
-
95
- return html`
96
- <div class="dropdown-container">
97
- <button class="btn btn-primary dropdown-toggle" @click=${() => this.dropdownOpen = !this.dropdownOpen}>
98
- <span>${label}</span> <span>${this.dropdownOpen ? '▲' : '▼'}</span>
99
- </button>
100
-
101
- ${this.dropdownOpen
102
- ? html`
103
- <div class="dropdown-card" style="--glatam-day-min-height: 38px;">
104
- ${!this.dropdownSelectedDateString
105
- ? html`
106
- <div style="font-weight:600; font-size:0.9rem; text-align:center; color: var(--glatam-text);">Selecciona un Día</div>
107
- <glatam-calendar-month-view
108
- .days=${generateMonthDays(y, m, this.rules, this.slots, this.startOfWeekDay)}
109
- .locale=${this.locale}
110
- .startOfWeekDay=${this.startOfWeekDay}
111
- .role=${this.role}
112
- size="small"
113
- .minDate=${this.minDate}
114
- .maxDate=${this.maxDate}
115
- .showNeighboringMonth=${this.showNeighboringMonth}
116
- .tileClassName=${this.tileClassName}
117
- @day-select=${this.handleDropdownDaySelect}
118
- ></glatam-calendar-month-view>
119
- `
120
- : html`
121
- <div style="display:flex; justify-content:space-between; align-items:center; border-bottom: 1px solid var(--glatam-border); padding-bottom:8px;">
122
- <button class="btn" style="height:28px; padding:0 8px; font-size:0.75rem;" @click=${() => this.dropdownSelectedDateString = ''}>&lt; Volver</button>
123
- <span style="font-size:0.8rem; font-weight:600; color: var(--glatam-text);">${this.dropdownSelectedDateString}</span>
124
- </div>
125
- <div class="slot-list">
126
- ${dropdownSlots.map(s => html`
127
- <button
128
- class="slot-btn ${s.isBlocked ? 'blocked' : ''}"
129
- ?disabled=${s.isBlocked}
130
- @click=${() => this.selectDropdownSlot(s)}
131
- >
132
- ${s.displayStart} - ${s.displayEnd} ${s.isBlocked ? '(Ocupado)' : ''}
133
- </button>
134
- `)}
135
- </div>
136
- `}
137
- </div>
138
- `
139
- : ''}
140
- </div>
141
- `;
142
- }
143
- }
144
-
145
- declare global {
146
- interface HTMLElementTagNameMap { 'glatam-calendar-mini': GlatamCalendarMini; }
147
- }