@sula-tech/webcomponents 0.20.1 → 0.22.0

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 (154) hide show
  1. package/dist/cjs/index.cjs.js +7 -3
  2. package/dist/cjs/index.cjs.js.map +1 -1
  3. package/dist/cjs/loader.cjs.js +1 -1
  4. package/dist/cjs/{sula-avatar_31.cjs.entry.js → sula-avatar_32.cjs.entry.js} +453 -84
  5. package/dist/cjs/sula-avatar_32.cjs.entry.js.map +1 -0
  6. package/dist/cjs/{sula-menu.model-BDxbWyPG.js → sula-calendar.model-BI5cNrUo.js} +8 -2
  7. package/dist/cjs/sula-calendar.model-BI5cNrUo.js.map +1 -0
  8. package/dist/cjs/sula-toast-stack.cjs.entry.js +4 -4
  9. package/dist/cjs/sula-toast.cjs.entry.js +2 -2
  10. package/dist/cjs/webcomponents.cjs.js +1 -1
  11. package/dist/collection/collection-manifest.json +1 -0
  12. package/dist/collection/components/sula-calendar/model/sula-calendar.model.js +6 -0
  13. package/dist/collection/components/sula-calendar/model/sula-calendar.model.js.map +1 -0
  14. package/dist/collection/components/sula-calendar/sula-calendar.css +1 -0
  15. package/dist/collection/components/sula-calendar/sula-calendar.js +792 -0
  16. package/dist/collection/components/sula-calendar/sula-calendar.js.map +1 -0
  17. package/dist/collection/components/sula-calendar/sula-calendar.stories.js +309 -0
  18. package/dist/collection/components/sula-calendar/sula-calendar.stories.js.map +1 -0
  19. package/dist/collection/components/sula-checkbox/sula-checkbox.js +3 -3
  20. package/dist/collection/components/sula-chip/model/sula-chip.model.js +5 -0
  21. package/dist/collection/components/sula-chip/model/sula-chip.model.js.map +1 -1
  22. package/dist/collection/components/sula-chip/sula-chip.css +1 -1
  23. package/dist/collection/components/sula-chip/sula-chip.js +40 -5
  24. package/dist/collection/components/sula-chip/sula-chip.js.map +1 -1
  25. package/dist/collection/components/sula-chip/sula-chip.stories.js +14 -1
  26. package/dist/collection/components/sula-chip/sula-chip.stories.js.map +1 -1
  27. package/dist/collection/components/sula-dropdown/sula-dropdown.js +3 -3
  28. package/dist/collection/components/sula-icon/sula-icon.css +1 -1
  29. package/dist/collection/components/sula-icon/sula-icon.js +1 -1
  30. package/dist/collection/components/sula-icon-picker/sula-icon-picker.js +2 -2
  31. package/dist/collection/components/sula-loader/sula-loader.js +1 -1
  32. package/dist/collection/components/sula-menu/sula-menu.js +8 -8
  33. package/dist/collection/components/sula-menu-select-list/sula-menu-select-list.css +1 -1
  34. package/dist/collection/components/sula-menu-select-list/sula-menu-select-list.js +1 -1
  35. package/dist/collection/components/sula-progress-bar/sula-progress-bar.js +2 -2
  36. package/dist/collection/components/sula-radio-button/sula-radio-button.js +2 -2
  37. package/dist/collection/components/sula-search-bar/sula-search-bar.js +2 -2
  38. package/dist/collection/components/sula-segmented-control/sula-segmented-control.js +1 -1
  39. package/dist/collection/components/sula-switch/sula-switch.js +4 -4
  40. package/dist/collection/components/sula-table/sula-table.js +3 -3
  41. package/dist/collection/components/sula-table-body/sula-table-body.js +1 -1
  42. package/dist/collection/components/sula-table-cell/sula-table-cell.js +2 -2
  43. package/dist/collection/components/sula-table-head-cell/sula-table-head-cell.js +2 -2
  44. package/dist/collection/components/sula-table-header/sula-table-header.js +1 -1
  45. package/dist/collection/components/sula-table-row/sula-table-row.js +1 -1
  46. package/dist/collection/components/sula-tag/sula-tag.js +3 -3
  47. package/dist/collection/components/sula-textarea/sula-textarea.js +6 -6
  48. package/dist/collection/components/sula-textfield/sula-textfield.css +1 -1
  49. package/dist/collection/components/sula-textfield/sula-textfield.js +27 -3
  50. package/dist/collection/components/sula-textfield/sula-textfield.js.map +1 -1
  51. package/dist/collection/components/sula-textfield/sula-textfield.stories.js +9 -0
  52. package/dist/collection/components/sula-textfield/sula-textfield.stories.js.map +1 -1
  53. package/dist/collection/components/sula-tiles/sula-tiles.js +1 -1
  54. package/dist/collection/components/sula-timeline-list/sula-timeline-list.js +1 -1
  55. package/dist/collection/components/sula-toast/sula-toast.js +2 -2
  56. package/dist/collection/components/sula-toast-stack/sula-toast-stack.js +4 -4
  57. package/dist/collection/components/sula-toggle/sula-toggle.js +1 -1
  58. package/dist/collection/components/sula-tooltip/sula-tooltip.js +1 -1
  59. package/dist/collection/index.js +1 -0
  60. package/dist/collection/index.js.map +1 -1
  61. package/dist/components/index.js +1 -0
  62. package/dist/components/index.js.map +1 -1
  63. package/dist/components/{p-b7t6bSNa.js → p-CXm0qTFO.js} +4 -4
  64. package/dist/components/{p-b7t6bSNa.js.map → p-CXm0qTFO.js.map} +1 -1
  65. package/dist/components/p-Cp_4qTxj.js +10 -0
  66. package/dist/components/p-Cp_4qTxj.js.map +1 -0
  67. package/dist/components/{p-DmQoJS86.js → p-D5G0T47I.js} +5 -5
  68. package/dist/components/{p-DmQoJS86.js.map → p-D5G0T47I.js.map} +1 -1
  69. package/dist/components/p-DGAtNvje.js +555 -0
  70. package/dist/components/p-DGAtNvje.js.map +1 -0
  71. package/dist/components/{p-CJ2i2jVV.js → p-DwyYG9oc.js} +5 -5
  72. package/dist/components/{p-CJ2i2jVV.js.map → p-DwyYG9oc.js.map} +1 -1
  73. package/dist/components/{p-DmCNhtp_.js → p-MPkJUrNl.js} +3 -3
  74. package/dist/components/{p-DmCNhtp_.js.map → p-MPkJUrNl.js.map} +1 -1
  75. package/dist/components/{p-DGfvh6dZ.js → p-fAOl4EhI.js} +5 -5
  76. package/dist/components/{p-DGfvh6dZ.js.map → p-fAOl4EhI.js.map} +1 -1
  77. package/dist/components/{p-DqRqPukj.js → p-jplrktAF.js} +4 -4
  78. package/dist/components/{p-DqRqPukj.js.map → p-jplrktAF.js.map} +1 -1
  79. package/dist/components/{p-D0ZAC0yK.js → p-t7f_qmad.js} +7 -7
  80. package/dist/components/{p-D0ZAC0yK.js.map → p-t7f_qmad.js.map} +1 -1
  81. package/dist/components/sula-avatar.js +1 -1
  82. package/dist/components/sula-badge.js +1 -1
  83. package/dist/components/sula-breadcrumb.js +1 -1
  84. package/dist/components/sula-button.js +1 -1
  85. package/dist/components/sula-calendar.d.ts +11 -0
  86. package/dist/components/sula-calendar.js +411 -0
  87. package/dist/components/sula-calendar.js.map +1 -0
  88. package/dist/components/sula-checkbox.js +4 -4
  89. package/dist/components/sula-chip.js +22 -7
  90. package/dist/components/sula-chip.js.map +1 -1
  91. package/dist/components/sula-dropdown.js +1 -1
  92. package/dist/components/sula-icon-picker.js +6 -6
  93. package/dist/components/sula-icon.js +1 -1
  94. package/dist/components/sula-loader.js +1 -1
  95. package/dist/components/sula-menu-select-list.js +1 -1
  96. package/dist/components/sula-menu.js +9 -9
  97. package/dist/components/sula-modal.js +3 -3
  98. package/dist/components/sula-progress-bar.js +3 -3
  99. package/dist/components/sula-radio-button.js +2 -2
  100. package/dist/components/sula-search-bar.js +1 -1
  101. package/dist/components/sula-segmented-control.js +2 -2
  102. package/dist/components/sula-switch.js +4 -4
  103. package/dist/components/sula-table-body.js +1 -1
  104. package/dist/components/sula-table-cell.js +2 -2
  105. package/dist/components/sula-table-head-cell.js +2 -2
  106. package/dist/components/sula-table-header.js +1 -1
  107. package/dist/components/sula-table-row.js +1 -1
  108. package/dist/components/sula-table.js +3 -3
  109. package/dist/components/sula-tag.js +4 -4
  110. package/dist/components/sula-textarea.js +6 -6
  111. package/dist/components/sula-textfield.js +1 -545
  112. package/dist/components/sula-textfield.js.map +1 -1
  113. package/dist/components/sula-tiles.js +2 -2
  114. package/dist/components/sula-timeline-list.js +2 -2
  115. package/dist/components/sula-toast-stack.js +6 -6
  116. package/dist/components/sula-toast.js +1 -1
  117. package/dist/components/sula-toggle.js +2 -2
  118. package/dist/components/sula-tooltip.js +2 -2
  119. package/dist/esm/index.js +1 -1
  120. package/dist/esm/loader.js +1 -1
  121. package/dist/esm/{sula-avatar_31.entry.js → sula-avatar_32.entry.js} +447 -79
  122. package/dist/esm/sula-avatar_32.entry.js.map +1 -0
  123. package/dist/esm/{sula-menu.model-Cs9RR1ZV.js → sula-calendar.model-BbsLJDfp.js} +9 -3
  124. package/dist/esm/sula-calendar.model-BbsLJDfp.js.map +1 -0
  125. package/dist/esm/sula-toast-stack.entry.js +4 -4
  126. package/dist/esm/sula-toast.entry.js +2 -2
  127. package/dist/esm/webcomponents.js +1 -1
  128. package/dist/types/components/sula-calendar/model/sula-calendar.model.d.ts +28 -0
  129. package/dist/types/components/sula-calendar/sula-calendar.d.ts +134 -0
  130. package/dist/types/components/sula-calendar/sula-calendar.stories.d.ts +169 -0
  131. package/dist/types/components/sula-chip/model/sula-chip.model.d.ts +4 -0
  132. package/dist/types/components/sula-chip/sula-chip.d.ts +5 -1
  133. package/dist/types/components/sula-chip/sula-chip.stories.d.ts +12 -1
  134. package/dist/types/components/sula-textfield/sula-textfield.d.ts +4 -0
  135. package/dist/types/components/sula-textfield/sula-textfield.stories.d.ts +8 -0
  136. package/dist/types/components.d.ts +221 -2
  137. package/dist/types/index.d.ts +2 -0
  138. package/dist/webcomponents/index.esm.js +1 -1
  139. package/dist/webcomponents/{p-f4ef50ea.entry.js → p-22b10b91.entry.js} +840 -355
  140. package/dist/webcomponents/p-22b10b91.entry.js.map +1 -0
  141. package/dist/webcomponents/{p-Cs9RR1ZV.js → p-BbsLJDfp.js} +11 -4
  142. package/dist/webcomponents/p-BbsLJDfp.js.map +1 -0
  143. package/dist/webcomponents/{p-170854a5.entry.js → p-c552c435.entry.js} +16 -16
  144. package/dist/webcomponents/{p-c58125e1.entry.js → p-df271629.entry.js} +6 -6
  145. package/dist/webcomponents/webcomponents.esm.js +48 -23
  146. package/package.json +1 -1
  147. package/dist/cjs/sula-avatar_31.cjs.entry.js.map +0 -1
  148. package/dist/cjs/sula-menu.model-BDxbWyPG.js.map +0 -1
  149. package/dist/esm/sula-avatar_31.entry.js.map +0 -1
  150. package/dist/esm/sula-menu.model-Cs9RR1ZV.js.map +0 -1
  151. package/dist/webcomponents/p-Cs9RR1ZV.js.map +0 -1
  152. package/dist/webcomponents/p-f4ef50ea.entry.js.map +0 -1
  153. /package/dist/webcomponents/{p-170854a5.entry.js.map → p-c552c435.entry.js.map} +0 -0
  154. /package/dist/webcomponents/{p-c58125e1.entry.js.map → p-df271629.entry.js.map} +0 -0
@@ -0,0 +1,792 @@
1
+ import { Host, h } from "@stencil/core";
2
+ import { SulaTextfieldStatus } from "../sula-textfield/model/sula-textfield.model";
3
+ import { SulaCalendarStatus } from "./model/sula-calendar.model";
4
+ const DATE_PATTERN = /^(\d{2})\/(\d{2})\/(\d{4})$/;
5
+ const DAYS_IN_WEEK = 7;
6
+ const FALLBACK_LOCALE = 'pt-BR';
7
+ export class SulaCalendar {
8
+ constructor() {
9
+ /**
10
+ * Selected date in the `DD/MM/YYYY` format. In range mode the format is `DD/MM/YYYY - DD/MM/YYYY`
11
+ */
12
+ this.value = '';
13
+ /**
14
+ * The calendar is disabled
15
+ */
16
+ this.disabled = false;
17
+ /**
18
+ * The calendar field status
19
+ */
20
+ this.status = SulaCalendarStatus.Default;
21
+ /**
22
+ * Locale used to format month and weekday names
23
+ */
24
+ this.locale = 'pt-BR';
25
+ /**
26
+ * Enables selecting a date range (start and end dates) instead of a single date
27
+ */
28
+ this.range = false;
29
+ /**
30
+ * Allows typing the date directly in the field. When false, the date can only be picked in the calendar
31
+ */
32
+ this.allowTyping = true;
33
+ /**
34
+ * Renders only the calendar panel, without the input field
35
+ */
36
+ this.inline = false;
37
+ /**
38
+ * Renders a smaller chip-like trigger showing only the selected date (`DD/MM/YY`), instead of the input field
39
+ */
40
+ this.compact = false;
41
+ /**
42
+ * First day of the week, where 0 is Sunday and 6 is Saturday
43
+ */
44
+ this.firstDayOfWeek = 0;
45
+ /**
46
+ * Closes the calendar panel after a date is selected
47
+ */
48
+ this.closeOnSelect = true;
49
+ this.showCalendar = false;
50
+ this.openUpward = false;
51
+ this.hoverDate = null;
52
+ this.handleFieldClick = () => {
53
+ this.open();
54
+ };
55
+ this.handleCompactClick = (event) => {
56
+ event.stopPropagation();
57
+ if (this.showCalendar) {
58
+ this.close();
59
+ }
60
+ else {
61
+ this.open();
62
+ }
63
+ };
64
+ this.handleFieldKeydown = (event) => {
65
+ if (event.key === 'ArrowDown') {
66
+ event.preventDefault();
67
+ this.open();
68
+ }
69
+ };
70
+ this.handleInputChanged = (event) => {
71
+ var _a;
72
+ event.stopPropagation();
73
+ const typedValue = (_a = event.detail) !== null && _a !== void 0 ? _a : '';
74
+ this.value = typedValue;
75
+ if (this.range) {
76
+ const { start, end } = this.getRange();
77
+ if (start && end && start.getTime() <= end.getTime()) {
78
+ this.rangeSelected.emit({ start: this.formatDate(start), end: this.formatDate(end) });
79
+ }
80
+ return;
81
+ }
82
+ this.valueChanged.emit(typedValue);
83
+ };
84
+ this.handlePreviousMonth = (event) => {
85
+ event.stopPropagation();
86
+ this.changeMonth(-1);
87
+ };
88
+ this.handleNextMonth = (event) => {
89
+ event.stopPropagation();
90
+ this.changeMonth(1);
91
+ };
92
+ this.handleSelectDay = (event, day) => {
93
+ event.stopPropagation();
94
+ if (day.isDisabled || this.disabled)
95
+ return;
96
+ if (this.range) {
97
+ this.selectRangeDay(day.date);
98
+ return;
99
+ }
100
+ const formatted = this.formatDate(day.date);
101
+ this.value = formatted;
102
+ this.dateSelected.emit(formatted);
103
+ this.valueChanged.emit(formatted);
104
+ if (this.closeOnSelect && !this.inline) {
105
+ this.close();
106
+ }
107
+ };
108
+ this.handleGridLeave = () => {
109
+ this.hoverDate = null;
110
+ };
111
+ }
112
+ handleValueChange() {
113
+ this.hoverDate = null;
114
+ // keeps the view on the current month while an incomplete date is being typed
115
+ if (this.selectedDate) {
116
+ this.syncViewWithValue();
117
+ }
118
+ }
119
+ handleDocumentClick(event) {
120
+ if (!this.showCalendar || !this.node)
121
+ return;
122
+ if (!event.composedPath().includes(this.node)) {
123
+ this.close();
124
+ }
125
+ }
126
+ handleDocumentKeydown(event) {
127
+ if (this.showCalendar && event.key === 'Escape') {
128
+ this.close();
129
+ }
130
+ }
131
+ componentWillLoad() {
132
+ this.syncViewWithValue();
133
+ }
134
+ componentDidRender() {
135
+ if (this.showCalendar) {
136
+ this.calculatePanelPosition();
137
+ }
138
+ }
139
+ get selectedDate() {
140
+ return this.getRange().start;
141
+ }
142
+ getRange() {
143
+ var _a;
144
+ if (!this.range) {
145
+ return { start: this.parseDate(this.value), end: null };
146
+ }
147
+ const [startText, endText] = ((_a = this.value) !== null && _a !== void 0 ? _a : '').split('-');
148
+ return { start: this.parseDate(startText), end: this.parseDate(endText) };
149
+ }
150
+ syncViewWithValue() {
151
+ var _a;
152
+ const reference = (_a = this.selectedDate) !== null && _a !== void 0 ? _a : new Date();
153
+ this.viewMonth = reference.getMonth();
154
+ this.viewYear = reference.getFullYear();
155
+ }
156
+ parseDate(value) {
157
+ const match = DATE_PATTERN.exec((value !== null && value !== void 0 ? value : '').trim());
158
+ if (!match)
159
+ return null;
160
+ const day = Number(match[1]);
161
+ const month = Number(match[2]);
162
+ const year = Number(match[3]);
163
+ const date = new Date(year, month - 1, day, 0, 0, 0, 0);
164
+ const isValid = date.getDate() === day && date.getMonth() === month - 1 && date.getFullYear() === year;
165
+ return isValid ? date : null;
166
+ }
167
+ formatDate(date) {
168
+ const day = `${date.getDate()}`.padStart(2, '0');
169
+ const month = `${date.getMonth() + 1}`.padStart(2, '0');
170
+ return `${day}/${month}/${date.getFullYear()}`;
171
+ }
172
+ capitalize(text) {
173
+ return text.charAt(0).toUpperCase() + text.slice(1);
174
+ }
175
+ isSameDay(first, second) {
176
+ return first.getDate() === second.getDate() && first.getMonth() === second.getMonth() && first.getFullYear() === second.getFullYear();
177
+ }
178
+ isOutOfRange(date, min, max) {
179
+ return (!!min && date.getTime() < min.getTime()) || (!!max && date.getTime() > max.getTime());
180
+ }
181
+ get weekStart() {
182
+ const value = Math.trunc(Number(this.firstDayOfWeek));
183
+ return Number.isFinite(value) ? ((value % DAYS_IN_WEEK) + DAYS_IN_WEEK) % DAYS_IN_WEEK : 0;
184
+ }
185
+ // an invalid `locale` would make Intl throw and break the whole render
186
+ createFormatter(options) {
187
+ try {
188
+ return new Intl.DateTimeFormat(this.locale, options);
189
+ }
190
+ catch (_a) {
191
+ return new Intl.DateTimeFormat(FALLBACK_LOCALE, options);
192
+ }
193
+ }
194
+ getMonthLabel() {
195
+ const date = new Date(this.viewYear, this.viewMonth, 1);
196
+ const month = this.createFormatter({ month: 'short' }).format(date).replace(/\./g, '');
197
+ return `${this.capitalize(month)} ${this.viewYear}`;
198
+ }
199
+ getWeekdays() {
200
+ const shortFormatter = this.createFormatter({ weekday: 'short' });
201
+ const longFormatter = this.createFormatter({ weekday: 'long' });
202
+ return Array.from({ length: DAYS_IN_WEEK }, (_, index) => {
203
+ // 2024-01-07 is a Sunday, used as a stable reference to build the weekday sequence
204
+ const date = new Date(2024, 0, 7 + ((index + this.weekStart) % DAYS_IN_WEEK));
205
+ return {
206
+ short: this.capitalize(shortFormatter.format(date).replace(/\./g, '')),
207
+ long: this.capitalize(longFormatter.format(date)),
208
+ };
209
+ });
210
+ }
211
+ getWeeks() {
212
+ const today = new Date();
213
+ const { start, end } = this.getRange();
214
+ const previewEnd = this.range && !!start && !end ? this.hoverDate : null;
215
+ const rangeEnd = end !== null && end !== void 0 ? end : previewEnd;
216
+ const hasRange = this.range && !!start && !!rangeEnd;
217
+ const from = hasRange && start.getTime() > rangeEnd.getTime() ? rangeEnd : start;
218
+ const to = hasRange && start.getTime() > rangeEnd.getTime() ? start : rangeEnd;
219
+ const firstOfMonth = new Date(this.viewYear, this.viewMonth, 1);
220
+ const min = this.parseDate(this.minDate);
221
+ const max = this.parseDate(this.maxDate);
222
+ const offset = (firstOfMonth.getDay() - this.weekStart + DAYS_IN_WEEK) % DAYS_IN_WEEK;
223
+ const daysInMonth = new Date(this.viewYear, this.viewMonth + 1, 0).getDate();
224
+ const totalCells = Math.ceil((offset + daysInMonth) / DAYS_IN_WEEK) * DAYS_IN_WEEK;
225
+ const weeks = [];
226
+ for (let cell = 0; cell < totalCells; cell++) {
227
+ const date = new Date(this.viewYear, this.viewMonth, cell - offset + 1);
228
+ const day = {
229
+ date,
230
+ day: date.getDate(),
231
+ isCurrentMonth: date.getMonth() === this.viewMonth && date.getFullYear() === this.viewYear,
232
+ isSelected: (!!start && this.isSameDay(date, start)) || (this.range && !!end && this.isSameDay(date, end)),
233
+ isRangeStart: hasRange && this.isSameDay(date, from),
234
+ isRangeEnd: hasRange && this.isSameDay(date, to),
235
+ isInRange: hasRange && date.getTime() > from.getTime() && date.getTime() < to.getTime(),
236
+ isRangePreview: !!previewEnd && this.isSameDay(date, previewEnd) && !this.isSameDay(date, start),
237
+ isToday: this.isSameDay(date, today),
238
+ isDisabled: this.isOutOfRange(date, min, max),
239
+ };
240
+ if (cell % DAYS_IN_WEEK === 0)
241
+ weeks.push([]);
242
+ weeks[weeks.length - 1].push(day);
243
+ }
244
+ return weeks;
245
+ }
246
+ calculatePanelPosition() {
247
+ var _a, _b;
248
+ if (!this.node || this.inline)
249
+ return;
250
+ const rect = this.node.getBoundingClientRect();
251
+ const panelHeight = (_b = (_a = this.panelNode) === null || _a === void 0 ? void 0 : _a.offsetHeight) !== null && _b !== void 0 ? _b : 0;
252
+ const spaceBelow = window.innerHeight - rect.bottom;
253
+ const spaceAbove = rect.top;
254
+ this.openUpward = spaceBelow < panelHeight && spaceAbove > spaceBelow;
255
+ }
256
+ open() {
257
+ if (this.disabled || this.showCalendar)
258
+ return;
259
+ this.showCalendar = true;
260
+ this.calendarOpened.emit();
261
+ }
262
+ close() {
263
+ if (!this.showCalendar)
264
+ return;
265
+ this.showCalendar = false;
266
+ this.hoverDate = null;
267
+ this.calendarClosed.emit();
268
+ }
269
+ getCompactLabel() {
270
+ const { start, end } = this.getRange();
271
+ const short = (date) => this.formatDate(date).replace(/\/\d{2}(\d{2})$/, '/$1');
272
+ if (!start)
273
+ return this.placeholder || this.label || '';
274
+ return this.range && end ? `${short(start)} - ${short(end)}` : short(start);
275
+ }
276
+ changeMonth(step) {
277
+ const date = new Date(this.viewYear, this.viewMonth + step, 1);
278
+ this.viewMonth = date.getMonth();
279
+ this.viewYear = date.getFullYear();
280
+ this.monthChanged.emit({ month: this.viewMonth, year: this.viewYear });
281
+ }
282
+ selectRangeDay(date) {
283
+ const { start, end } = this.getRange();
284
+ // first click, or a click after a complete range, starts a new range
285
+ if (!start || end) {
286
+ this.value = this.formatDate(date);
287
+ return;
288
+ }
289
+ const [from, to] = date.getTime() < start.getTime() ? [date, start] : [start, date];
290
+ const range = { start: this.formatDate(from), end: this.formatDate(to) };
291
+ this.value = `${range.start} - ${range.end}`;
292
+ this.rangeSelected.emit(range);
293
+ if (this.closeOnSelect && !this.inline) {
294
+ this.close();
295
+ }
296
+ }
297
+ handleDayHover(day) {
298
+ if (!this.range || day.isDisabled)
299
+ return;
300
+ this.hoverDate = day.date;
301
+ }
302
+ getTextfieldStatus() {
303
+ return this.status === SulaCalendarStatus.Error ? SulaTextfieldStatus.Error : SulaTextfieldStatus.Default;
304
+ }
305
+ renderHeader() {
306
+ return (h("div", { class: "flex h-28 w-full flex-row items-center justify-between gap-12 px-4" }, h("button", { type: "button", class: "flex h-28 w-28 items-center justify-center rounded-xs hover:bg-states-empty-bg-hover", "aria-label": "M\u00EAs anterior", onClick: this.handlePreviousMonth }, h("sula-icon", { icon: "ph ph-caret-left", customClass: "text-base text-text-secondary" })), h("span", { class: "text-label-medium-regular text-text-primary", "aria-live": "polite" }, this.getMonthLabel()), h("button", { type: "button", class: "flex h-28 w-28 items-center justify-center rounded-xs hover:bg-states-empty-bg-hover", "aria-label": "Pr\u00F3ximo m\u00EAs", onClick: this.handleNextMonth }, h("sula-icon", { icon: "ph ph-caret-right", customClass: "text-base text-text-secondary" }))));
307
+ }
308
+ renderDay(day) {
309
+ return (h("div", { role: "gridcell", "aria-selected": day.isSelected ? 'true' : 'false', "aria-disabled": day.isDisabled ? 'true' : null, "aria-current": day.isToday ? 'date' : null, class: "relative flex w-full items-center justify-center", onMouseEnter: () => this.handleDayHover(day) }, (day.isInRange || day.isRangeStart !== day.isRangeEnd) && (h("span", { "data-range-background": true, "aria-hidden": "true", class: {
310
+ 'absolute inset-y-0 bg-surface-on-body-brand': true,
311
+ 'inset-x-0': day.isInRange,
312
+ 'right-0 w-1/2': day.isRangeStart && !day.isRangeEnd,
313
+ 'left-0 w-1/2': day.isRangeEnd && !day.isRangeStart,
314
+ } })), h("button", { type: "button", disabled: day.isDisabled, "aria-label": this.formatDate(day.date), onClick: (event) => this.handleSelectDay(event, day), class: {
315
+ 'relative flex h-36 w-36 items-center justify-center rounded-xxl text-label-small-regular transition-colors': true,
316
+ 'bg-brand-primary text-neutral-neutral-1': day.isSelected,
317
+ 'border border-brand-primary text-text-primary': day.isRangePreview && !day.isSelected,
318
+ 'text-text-primary hover:bg-states-empty-bg-hover': !day.isSelected && day.isCurrentMonth && !day.isDisabled,
319
+ 'text-text-secondary opacity-50 hover:bg-states-empty-bg-hover': !day.isSelected && !day.isCurrentMonth && !day.isDisabled,
320
+ 'cursor-not-allowed text-text-disabled line-through': day.isDisabled,
321
+ } }, day.day)));
322
+ }
323
+ renderPanel() {
324
+ return (h("div", { ref: node => (this.panelNode = node), role: this.inline ? 'group' : 'dialog', "aria-label": "Calend\u00E1rio", class: {
325
+ 'calendar-panel flex flex-col items-center rounded-lg border border-line-general bg-surface-body p-24': true,
326
+ 'w-full': !this.compact || this.inline,
327
+ 'absolute left-0 z-50': !this.inline,
328
+ 'calendar-panel--compact': this.compact && !this.inline,
329
+ 'bottom-full mb-8': !this.inline && this.openUpward,
330
+ 'top-full mt-8': !this.inline && !this.openUpward,
331
+ } }, h("div", { class: "flex w-full flex-col items-center gap-24" }, this.renderHeader(), h("div", { class: "flex w-full flex-col", role: "grid" }, h("div", { class: "grid grid-cols-7", role: "row" }, this.getWeekdays().map(weekday => (h("div", { role: "columnheader", title: weekday.long, class: "flex h-22 w-full items-center justify-center text-label-small-regular text-text-secondary" }, weekday.short)))), h("div", { role: "rowgroup", class: "grid gap-y-8 pt-8", onMouseLeave: this.handleGridLeave }, this.getWeeks().map(week => (h("div", { class: "grid grid-cols-7", role: "row" }, week.map(day => this.renderDay(day))))))))));
332
+ }
333
+ render() {
334
+ return (h(Host, { key: '03f17f7e0e68a7229d3aca0eff13974e32653d87', ref: node => (this.node = node) }, h("div", { key: '1a480da01747dedffbfe78831404433cbbd75b18', class: { 'relative': true, 'w-full': !this.compact || this.inline, 'inline-block': this.compact && !this.inline } }, !this.inline && this.compact && (h("button", { key: '8f2bf98089507e52f21add599c865e460adefc24', type: "button", disabled: this.disabled, "aria-haspopup": "dialog", "aria-expanded": this.showCalendar ? 'true' : 'false', "aria-label": this.label, onClick: this.handleCompactClick, class: {
335
+ 'flex h-40 items-center justify-center gap-8 rounded-xxl bg-surface-on-body px-16 py-2 text-label-medium-bold text-text-primary': true,
336
+ 'cursor-not-allowed opacity-50': this.disabled,
337
+ } }, h("sula-icon", { key: 'c27d9bca935147017996159a75b163c5f082cd96', icon: "ph ph-calendar-dots", customClass: "text-2xl text-text-secondary" }), h("span", { key: '239d70e9d79003484221a43efafdb503cff36fb2', class: "whitespace-nowrap" }, this.getCompactLabel()), h("sula-icon", { key: '13940e9f9c38e8a2be2bccdbf2b701f6db2b7cae', icon: this.showCalendar ? 'ph ph-caret-up' : 'ph ph-caret-down', customClass: "text-base text-text-primary" }))), !this.inline && !this.compact && (h("div", { key: '2cde57cb84d986160f4e6e5209f3e0537bfe4d1d', onClick: this.handleFieldClick, onKeyDown: this.handleFieldKeydown }, h("sula-textfield", { key: '1aea48c63cd5fb65c833b6673690d9672d8b2e5b', label: this.label, value: this.value, placeholder: this.placeholder, disabled: this.disabled, helpText: this.helpText, status: this.getTextfieldStatus(), icon: "ph ph-calendar-blank", maskPattern: this.range ? '99/99/9999 - 99/99/9999' : '99/99/9999', readOnly: !this.allowTyping, onValueChanged: this.handleInputChanged }))), (this.inline || this.showCalendar) && this.renderPanel())));
338
+ }
339
+ static get is() { return "sula-calendar"; }
340
+ static get encapsulation() { return "shadow"; }
341
+ static get originalStyleUrls() {
342
+ return {
343
+ "$": ["sula-calendar.scss"]
344
+ };
345
+ }
346
+ static get styleUrls() {
347
+ return {
348
+ "$": ["sula-calendar.css"]
349
+ };
350
+ }
351
+ static get properties() {
352
+ return {
353
+ "label": {
354
+ "type": "string",
355
+ "attribute": "label",
356
+ "mutable": false,
357
+ "complexType": {
358
+ "original": "string",
359
+ "resolved": "string",
360
+ "references": {}
361
+ },
362
+ "required": false,
363
+ "optional": false,
364
+ "docs": {
365
+ "tags": [],
366
+ "text": "The calendar field label"
367
+ },
368
+ "getter": false,
369
+ "setter": false,
370
+ "reflect": false
371
+ },
372
+ "value": {
373
+ "type": "string",
374
+ "attribute": "value",
375
+ "mutable": true,
376
+ "complexType": {
377
+ "original": "string",
378
+ "resolved": "string",
379
+ "references": {}
380
+ },
381
+ "required": false,
382
+ "optional": false,
383
+ "docs": {
384
+ "tags": [],
385
+ "text": "Selected date in the `DD/MM/YYYY` format. In range mode the format is `DD/MM/YYYY - DD/MM/YYYY`"
386
+ },
387
+ "getter": false,
388
+ "setter": false,
389
+ "reflect": false,
390
+ "defaultValue": "''"
391
+ },
392
+ "placeholder": {
393
+ "type": "string",
394
+ "attribute": "placeholder",
395
+ "mutable": false,
396
+ "complexType": {
397
+ "original": "string",
398
+ "resolved": "string",
399
+ "references": {}
400
+ },
401
+ "required": false,
402
+ "optional": true,
403
+ "docs": {
404
+ "tags": [],
405
+ "text": "The calendar field placeholder"
406
+ },
407
+ "getter": false,
408
+ "setter": false,
409
+ "reflect": false
410
+ },
411
+ "disabled": {
412
+ "type": "boolean",
413
+ "attribute": "disabled",
414
+ "mutable": false,
415
+ "complexType": {
416
+ "original": "boolean",
417
+ "resolved": "boolean",
418
+ "references": {}
419
+ },
420
+ "required": false,
421
+ "optional": false,
422
+ "docs": {
423
+ "tags": [],
424
+ "text": "The calendar is disabled"
425
+ },
426
+ "getter": false,
427
+ "setter": false,
428
+ "reflect": false,
429
+ "defaultValue": "false"
430
+ },
431
+ "helpText": {
432
+ "type": "string",
433
+ "attribute": "help-text",
434
+ "mutable": false,
435
+ "complexType": {
436
+ "original": "string",
437
+ "resolved": "string",
438
+ "references": {}
439
+ },
440
+ "required": false,
441
+ "optional": true,
442
+ "docs": {
443
+ "tags": [],
444
+ "text": "The help text displayed below the field"
445
+ },
446
+ "getter": false,
447
+ "setter": false,
448
+ "reflect": false
449
+ },
450
+ "status": {
451
+ "type": "string",
452
+ "attribute": "status",
453
+ "mutable": false,
454
+ "complexType": {
455
+ "original": "SulaCalendarStatus",
456
+ "resolved": "SulaCalendarStatus.Default | SulaCalendarStatus.Error",
457
+ "references": {
458
+ "SulaCalendarStatus": {
459
+ "location": "import",
460
+ "path": "./model/sula-calendar.model",
461
+ "id": "src/components/sula-calendar/model/sula-calendar.model.ts::SulaCalendarStatus"
462
+ }
463
+ }
464
+ },
465
+ "required": false,
466
+ "optional": false,
467
+ "docs": {
468
+ "tags": [],
469
+ "text": "The calendar field status"
470
+ },
471
+ "getter": false,
472
+ "setter": false,
473
+ "reflect": false,
474
+ "defaultValue": "SulaCalendarStatus.Default"
475
+ },
476
+ "locale": {
477
+ "type": "string",
478
+ "attribute": "locale",
479
+ "mutable": false,
480
+ "complexType": {
481
+ "original": "string",
482
+ "resolved": "string",
483
+ "references": {}
484
+ },
485
+ "required": false,
486
+ "optional": false,
487
+ "docs": {
488
+ "tags": [],
489
+ "text": "Locale used to format month and weekday names"
490
+ },
491
+ "getter": false,
492
+ "setter": false,
493
+ "reflect": false,
494
+ "defaultValue": "'pt-BR'"
495
+ },
496
+ "minDate": {
497
+ "type": "string",
498
+ "attribute": "min-date",
499
+ "mutable": false,
500
+ "complexType": {
501
+ "original": "string",
502
+ "resolved": "string",
503
+ "references": {}
504
+ },
505
+ "required": false,
506
+ "optional": true,
507
+ "docs": {
508
+ "tags": [],
509
+ "text": "Earliest selectable date in the `DD/MM/YYYY` format"
510
+ },
511
+ "getter": false,
512
+ "setter": false,
513
+ "reflect": false
514
+ },
515
+ "maxDate": {
516
+ "type": "string",
517
+ "attribute": "max-date",
518
+ "mutable": false,
519
+ "complexType": {
520
+ "original": "string",
521
+ "resolved": "string",
522
+ "references": {}
523
+ },
524
+ "required": false,
525
+ "optional": true,
526
+ "docs": {
527
+ "tags": [],
528
+ "text": "Latest selectable date in the `DD/MM/YYYY` format"
529
+ },
530
+ "getter": false,
531
+ "setter": false,
532
+ "reflect": false
533
+ },
534
+ "range": {
535
+ "type": "boolean",
536
+ "attribute": "range",
537
+ "mutable": false,
538
+ "complexType": {
539
+ "original": "boolean",
540
+ "resolved": "boolean",
541
+ "references": {}
542
+ },
543
+ "required": false,
544
+ "optional": false,
545
+ "docs": {
546
+ "tags": [],
547
+ "text": "Enables selecting a date range (start and end dates) instead of a single date"
548
+ },
549
+ "getter": false,
550
+ "setter": false,
551
+ "reflect": false,
552
+ "defaultValue": "false"
553
+ },
554
+ "allowTyping": {
555
+ "type": "boolean",
556
+ "attribute": "allow-typing",
557
+ "mutable": false,
558
+ "complexType": {
559
+ "original": "boolean",
560
+ "resolved": "boolean",
561
+ "references": {}
562
+ },
563
+ "required": false,
564
+ "optional": false,
565
+ "docs": {
566
+ "tags": [],
567
+ "text": "Allows typing the date directly in the field. When false, the date can only be picked in the calendar"
568
+ },
569
+ "getter": false,
570
+ "setter": false,
571
+ "reflect": false,
572
+ "defaultValue": "true"
573
+ },
574
+ "inline": {
575
+ "type": "boolean",
576
+ "attribute": "inline",
577
+ "mutable": false,
578
+ "complexType": {
579
+ "original": "boolean",
580
+ "resolved": "boolean",
581
+ "references": {}
582
+ },
583
+ "required": false,
584
+ "optional": false,
585
+ "docs": {
586
+ "tags": [],
587
+ "text": "Renders only the calendar panel, without the input field"
588
+ },
589
+ "getter": false,
590
+ "setter": false,
591
+ "reflect": false,
592
+ "defaultValue": "false"
593
+ },
594
+ "compact": {
595
+ "type": "boolean",
596
+ "attribute": "compact",
597
+ "mutable": false,
598
+ "complexType": {
599
+ "original": "boolean",
600
+ "resolved": "boolean",
601
+ "references": {}
602
+ },
603
+ "required": false,
604
+ "optional": false,
605
+ "docs": {
606
+ "tags": [],
607
+ "text": "Renders a smaller chip-like trigger showing only the selected date (`DD/MM/YY`), instead of the input field"
608
+ },
609
+ "getter": false,
610
+ "setter": false,
611
+ "reflect": false,
612
+ "defaultValue": "false"
613
+ },
614
+ "firstDayOfWeek": {
615
+ "type": "number",
616
+ "attribute": "first-day-of-week",
617
+ "mutable": false,
618
+ "complexType": {
619
+ "original": "number",
620
+ "resolved": "number",
621
+ "references": {}
622
+ },
623
+ "required": false,
624
+ "optional": false,
625
+ "docs": {
626
+ "tags": [],
627
+ "text": "First day of the week, where 0 is Sunday and 6 is Saturday"
628
+ },
629
+ "getter": false,
630
+ "setter": false,
631
+ "reflect": false,
632
+ "defaultValue": "0"
633
+ },
634
+ "closeOnSelect": {
635
+ "type": "boolean",
636
+ "attribute": "close-on-select",
637
+ "mutable": false,
638
+ "complexType": {
639
+ "original": "boolean",
640
+ "resolved": "boolean",
641
+ "references": {}
642
+ },
643
+ "required": false,
644
+ "optional": false,
645
+ "docs": {
646
+ "tags": [],
647
+ "text": "Closes the calendar panel after a date is selected"
648
+ },
649
+ "getter": false,
650
+ "setter": false,
651
+ "reflect": false,
652
+ "defaultValue": "true"
653
+ }
654
+ };
655
+ }
656
+ static get states() {
657
+ return {
658
+ "showCalendar": {},
659
+ "openUpward": {},
660
+ "viewMonth": {},
661
+ "viewYear": {},
662
+ "hoverDate": {}
663
+ };
664
+ }
665
+ static get events() {
666
+ return [{
667
+ "method": "dateSelected",
668
+ "name": "dateSelected",
669
+ "bubbles": true,
670
+ "cancelable": true,
671
+ "composed": true,
672
+ "docs": {
673
+ "tags": [],
674
+ "text": "Event emitted when a date is selected, with the date in the `DD/MM/YYYY` format"
675
+ },
676
+ "complexType": {
677
+ "original": "string",
678
+ "resolved": "string",
679
+ "references": {}
680
+ }
681
+ }, {
682
+ "method": "rangeSelected",
683
+ "name": "rangeSelected",
684
+ "bubbles": true,
685
+ "cancelable": true,
686
+ "composed": true,
687
+ "docs": {
688
+ "tags": [],
689
+ "text": "Event emitted in range mode when both the start and end dates are selected, either by picking or by typing. In range mode `valueChanged` is not emitted"
690
+ },
691
+ "complexType": {
692
+ "original": "SulaCalendarRange",
693
+ "resolved": "SulaCalendarRange",
694
+ "references": {
695
+ "SulaCalendarRange": {
696
+ "location": "import",
697
+ "path": "./model/sula-calendar.model",
698
+ "id": "src/components/sula-calendar/model/sula-calendar.model.ts::SulaCalendarRange"
699
+ }
700
+ }
701
+ }
702
+ }, {
703
+ "method": "valueChanged",
704
+ "name": "valueChanged",
705
+ "bubbles": true,
706
+ "cancelable": true,
707
+ "composed": true,
708
+ "docs": {
709
+ "tags": [],
710
+ "text": "Event emitted when the value changes, either by typing or by selecting a date. Not emitted in range mode, use `rangeSelected` instead"
711
+ },
712
+ "complexType": {
713
+ "original": "string",
714
+ "resolved": "string",
715
+ "references": {}
716
+ }
717
+ }, {
718
+ "method": "monthChanged",
719
+ "name": "monthChanged",
720
+ "bubbles": true,
721
+ "cancelable": true,
722
+ "composed": true,
723
+ "docs": {
724
+ "tags": [],
725
+ "text": "Event emitted when the displayed month changes"
726
+ },
727
+ "complexType": {
728
+ "original": "SulaCalendarMonthChange",
729
+ "resolved": "SulaCalendarMonthChange",
730
+ "references": {
731
+ "SulaCalendarMonthChange": {
732
+ "location": "import",
733
+ "path": "./model/sula-calendar.model",
734
+ "id": "src/components/sula-calendar/model/sula-calendar.model.ts::SulaCalendarMonthChange"
735
+ }
736
+ }
737
+ }
738
+ }, {
739
+ "method": "calendarOpened",
740
+ "name": "calendarOpened",
741
+ "bubbles": true,
742
+ "cancelable": true,
743
+ "composed": true,
744
+ "docs": {
745
+ "tags": [],
746
+ "text": "Event emitted when the calendar panel is opened"
747
+ },
748
+ "complexType": {
749
+ "original": "void",
750
+ "resolved": "void",
751
+ "references": {}
752
+ }
753
+ }, {
754
+ "method": "calendarClosed",
755
+ "name": "calendarClosed",
756
+ "bubbles": true,
757
+ "cancelable": true,
758
+ "composed": true,
759
+ "docs": {
760
+ "tags": [],
761
+ "text": "Event emitted when the calendar panel is closed"
762
+ },
763
+ "complexType": {
764
+ "original": "void",
765
+ "resolved": "void",
766
+ "references": {}
767
+ }
768
+ }];
769
+ }
770
+ static get watchers() {
771
+ return [{
772
+ "propName": "value",
773
+ "methodName": "handleValueChange"
774
+ }];
775
+ }
776
+ static get listeners() {
777
+ return [{
778
+ "name": "click",
779
+ "method": "handleDocumentClick",
780
+ "target": "document",
781
+ "capture": false,
782
+ "passive": false
783
+ }, {
784
+ "name": "keydown",
785
+ "method": "handleDocumentKeydown",
786
+ "target": "document",
787
+ "capture": false,
788
+ "passive": false
789
+ }];
790
+ }
791
+ }
792
+ //# sourceMappingURL=sula-calendar.js.map