@meetelise/chat 1.30.0 → 1.30.2

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 (228) hide show
  1. package/dist/src/MyPubnub.d.ts +116 -0
  2. package/dist/src/WebComponent/FeeCalculator/components/addon-item/addon-item-styles.d.ts +2 -0
  3. package/dist/src/WebComponent/FeeCalculator/components/addon-item/addon-item.d.ts +22 -0
  4. package/dist/src/WebComponent/FeeCalculator/components/addon-item/index.d.ts +1 -0
  5. package/dist/src/WebComponent/FeeCalculator/components/fee-calculator-layout/fee-calculator-layout-styles.d.ts +2 -0
  6. package/dist/src/WebComponent/FeeCalculator/components/fee-calculator-layout/fee-calculator-layout.d.ts +34 -0
  7. package/dist/src/WebComponent/FeeCalculator/components/fee-card/fee-card-styles.d.ts +2 -0
  8. package/dist/src/WebComponent/FeeCalculator/components/fee-card/fee-card.d.ts +21 -0
  9. package/dist/src/WebComponent/FeeCalculator/components/fee-item/fee-item-styles.d.ts +2 -0
  10. package/dist/src/WebComponent/FeeCalculator/components/fee-item/fee-item.d.ts +13 -0
  11. package/dist/src/WebComponent/FeeCalculator/components/floor-plan-selector/floor-plan-selector-styles.d.ts +2 -0
  12. package/dist/src/WebComponent/FeeCalculator/components/floor-plan-selector/floor-plan-selector.d.ts +33 -0
  13. package/dist/src/WebComponent/FeeCalculator/components/floorplan-image-card/floorplan-image-card-styles.d.ts +2 -0
  14. package/dist/src/WebComponent/FeeCalculator/components/floorplan-image-card/floorplan-image-card.d.ts +18 -0
  15. package/dist/src/WebComponent/FeeCalculator/components/index.d.ts +5 -0
  16. package/dist/src/WebComponent/FeeCalculator/components/promo-card/promo-card-styles.d.ts +2 -0
  17. package/dist/src/WebComponent/FeeCalculator/components/promo-card/promo-card.d.ts +13 -0
  18. package/dist/src/WebComponent/FeeCalculator/constants.d.ts +2 -0
  19. package/dist/src/WebComponent/FeeCalculator/fee-calculator-styles.d.ts +1 -0
  20. package/dist/src/WebComponent/FeeCalculator/fee-calculator.d.ts +59 -0
  21. package/dist/src/WebComponent/FeeCalculator/index.d.ts +2 -0
  22. package/dist/src/WebComponent/FeeCalculator/model/building-fee.d.ts +80 -0
  23. package/dist/src/WebComponent/FeeCalculator/model/transaction-category.d.ts +23 -0
  24. package/dist/src/WebComponent/LeadSourceClient.d.ts +46 -0
  25. package/dist/src/WebComponent/OfficeHours.d.ts +21 -0
  26. package/dist/src/WebComponent/Scheduler/date-picker.d.ts +28 -0
  27. package/dist/src/WebComponent/Scheduler/time-picker.d.ts +14 -0
  28. package/dist/src/WebComponent/Scheduler/tour-scheduler.d.ts +100 -0
  29. package/dist/src/WebComponent/Scheduler/tour-type-option.d.ts +13 -0
  30. package/dist/src/WebComponent/Scheduler/tourSchedulerStyles.d.ts +1 -0
  31. package/dist/src/WebComponent/actions/InputStyles.d.ts +1 -0
  32. package/dist/src/WebComponent/actions/action-confirm-button.d.ts +13 -0
  33. package/dist/src/WebComponent/actions/call-us-window.d.ts +37 -0
  34. package/dist/src/WebComponent/actions/collapse-expand-button.d.ts +8 -0
  35. package/dist/src/WebComponent/actions/details-window.d.ts +14 -0
  36. package/dist/src/WebComponent/actions/email-us-window.d.ts +46 -0
  37. package/dist/src/WebComponent/actions/formatPhoneNumber.d.ts +17 -0
  38. package/dist/src/WebComponent/actions/minimize-expand-button.d.ts +8 -0
  39. package/dist/src/WebComponent/chat-additional-actions.d.ts +28 -0
  40. package/dist/src/WebComponent/health-chat.d.ts +47 -0
  41. package/dist/src/WebComponent/healthchat-styles.d.ts +1 -0
  42. package/dist/src/WebComponent/icons/ApplyOutlineIcon.d.ts +2 -0
  43. package/dist/src/WebComponent/icons/BookTourOutlineIcon.d.ts +2 -0
  44. package/dist/src/WebComponent/icons/CalculatorOutlineIcon.d.ts +2 -0
  45. package/dist/src/WebComponent/icons/ChatOutlineIcon.d.ts +2 -0
  46. package/dist/src/WebComponent/icons/ChevronLeftIcon.d.ts +2 -0
  47. package/dist/src/WebComponent/icons/ChevronRightIcon.d.ts +2 -0
  48. package/dist/src/WebComponent/icons/ContactResidentIcon.d.ts +2 -0
  49. package/dist/src/WebComponent/icons/DollarOutlineIcon.d.ts +3 -0
  50. package/dist/src/WebComponent/icons/EmailOutlineIcon.d.ts +2 -0
  51. package/dist/src/WebComponent/icons/HeyThereEmojiIcon.d.ts +2 -0
  52. package/dist/src/WebComponent/icons/PhoneOutlineIcon.d.ts +2 -0
  53. package/dist/src/WebComponent/icons/SendMessageIcon.d.ts +3 -0
  54. package/dist/src/WebComponent/icons/TourSelfGuidedIcon.d.ts +2 -0
  55. package/dist/src/WebComponent/icons/TourVirtuallyIcon.d.ts +2 -0
  56. package/dist/src/WebComponent/icons/TourWithAgentIcon.d.ts +2 -0
  57. package/dist/src/WebComponent/icons/XOutlineIcon.d.ts +2 -0
  58. package/dist/src/WebComponent/index.d.ts +2 -0
  59. package/dist/src/WebComponent/launcher/Launcher.d.ts +98 -0
  60. package/dist/src/WebComponent/launcher/launcherStyles.d.ts +1 -0
  61. package/dist/src/WebComponent/launcher/mobile-launcher.d.ts +27 -0
  62. package/dist/src/WebComponent/launcher/typeEmojiStyles.d.ts +1 -0
  63. package/dist/src/WebComponent/launcher/typeMiniStyles.d.ts +1 -0
  64. package/dist/src/WebComponent/launcher/typeMobileStyles.d.ts +1 -0
  65. package/dist/src/WebComponent/leasing-chat-styles.d.ts +1 -0
  66. package/dist/src/WebComponent/me-chat.d.ts +91 -0
  67. package/dist/src/WebComponent/me-select.d.ts +24 -0
  68. package/dist/src/WebComponent/mega-loader.d.ts +7 -0
  69. package/dist/src/WebComponent/mini-loader.d.ts +5 -0
  70. package/dist/src/WebComponent/pubnub-chat-styles.d.ts +1 -0
  71. package/dist/src/WebComponent/pubnub-chat.d.ts +49 -0
  72. package/dist/src/WebComponent/pubnub-media.d.ts +14 -0
  73. package/dist/src/WebComponent/pubnub-message-styles.d.ts +1 -0
  74. package/dist/src/WebComponent/pubnub-message.d.ts +39 -0
  75. package/dist/src/WebComponent/simple-launcher/simple-launcher-styles.d.ts +1 -0
  76. package/dist/src/WebComponent/simple-launcher/simple-launcher.d.ts +12 -0
  77. package/dist/src/WebComponent/utilities-chat.d.ts +47 -0
  78. package/dist/src/WebComponent/utilities-styles.d.ts +1 -0
  79. package/dist/src/WebComponent/utils.d.ts +31 -0
  80. package/dist/src/analytics.d.ts +64 -0
  81. package/dist/src/disclaimers.d.ts +8 -0
  82. package/dist/src/fetchBuildingABTestType.d.ts +8 -0
  83. package/dist/src/fetchBuildingInfo.d.ts +57 -0
  84. package/dist/src/fetchBuildingWebchatView.d.ts +123 -0
  85. package/dist/src/fetchFeatureFlag.d.ts +14 -0
  86. package/dist/src/fetchLeadSources.d.ts +4 -0
  87. package/dist/src/fetchPhoneNumberFromSource.d.ts +6 -0
  88. package/dist/src/getAvailabilities.d.ts +45 -0
  89. package/dist/src/getBuildingPhoneNumber.d.ts +1 -0
  90. package/dist/src/getShouldAllowScheduling.d.ts +1 -0
  91. package/dist/src/getShouldShowWebchat.d.ts +3 -0
  92. package/dist/src/getTimezoneString.d.ts +1 -0
  93. package/dist/src/globals.d.ts +1 -0
  94. package/dist/src/gtm.d.ts +6 -0
  95. package/dist/src/handleChatId.d.ts +11 -0
  96. package/dist/src/insertDNIIntoWebsite.d.ts +5 -0
  97. package/dist/src/insertLeadSourceIntoSchedulerLinks.d.ts +4 -0
  98. package/dist/src/main/MEChat.d.ts +74 -0
  99. package/dist/src/main/utils.d.ts +2 -0
  100. package/dist/src/postLeadSources.d.ts +3 -0
  101. package/dist/src/rentgrata.d.ts +4 -0
  102. package/dist/src/replaceSelectButtonsWithNewLink.d.ts +5 -0
  103. package/dist/src/services/fees/calculateQuote.d.ts +53 -0
  104. package/dist/src/services/fees/fetchBuildingFees.d.ts +24 -0
  105. package/dist/src/services/fees/fetchBuildingFloorplans.d.ts +21 -0
  106. package/dist/src/services/fees/utils.d.ts +1 -0
  107. package/dist/src/svgIcons.d.ts +5 -0
  108. package/dist/src/themes.d.ts +5 -0
  109. package/dist/src/types/rest-sdk.types.d.ts +11 -0
  110. package/dist/src/types/webchat-no-show-reason.d.ts +1 -0
  111. package/dist/src/utils.d.ts +13 -0
  112. package/package.json +1 -1
  113. package/public/dist/index.js +2 -3
  114. package/src/MyPubnub.ts +792 -0
  115. package/src/WebComponent/FeeCalculator/components/addon-item/addon-item-styles.ts +79 -0
  116. package/src/WebComponent/FeeCalculator/components/addon-item/addon-item.ts +121 -0
  117. package/src/WebComponent/FeeCalculator/components/addon-item/index.ts +1 -0
  118. package/src/WebComponent/FeeCalculator/components/fee-calculator-layout/fee-calculator-layout-styles.ts +126 -0
  119. package/src/WebComponent/FeeCalculator/components/fee-calculator-layout/fee-calculator-layout.ts +205 -0
  120. package/src/WebComponent/FeeCalculator/components/fee-card/fee-card-styles.ts +65 -0
  121. package/src/WebComponent/FeeCalculator/components/fee-card/fee-card.ts +91 -0
  122. package/src/WebComponent/FeeCalculator/components/fee-item/fee-item-styles.ts +44 -0
  123. package/src/WebComponent/FeeCalculator/components/fee-item/fee-item.ts +38 -0
  124. package/src/WebComponent/FeeCalculator/components/floor-plan-selector/floor-plan-selector-styles.ts +144 -0
  125. package/src/WebComponent/FeeCalculator/components/floor-plan-selector/floor-plan-selector.ts +241 -0
  126. package/src/WebComponent/FeeCalculator/components/floorplan-image-card/floorplan-image-card-styles.ts +74 -0
  127. package/src/WebComponent/FeeCalculator/components/floorplan-image-card/floorplan-image-card.ts +72 -0
  128. package/src/WebComponent/FeeCalculator/components/index.ts +5 -0
  129. package/src/WebComponent/FeeCalculator/components/promo-card/promo-card-styles.ts +39 -0
  130. package/src/WebComponent/FeeCalculator/components/promo-card/promo-card.ts +39 -0
  131. package/src/WebComponent/FeeCalculator/constants.ts +3 -0
  132. package/src/WebComponent/FeeCalculator/fee-calculator-styles.ts +334 -0
  133. package/src/WebComponent/FeeCalculator/fee-calculator.ts +369 -0
  134. package/src/WebComponent/FeeCalculator/index.ts +4 -0
  135. package/src/WebComponent/FeeCalculator/model/building-fee.ts +124 -0
  136. package/src/WebComponent/FeeCalculator/model/transaction-category.ts +23 -0
  137. package/src/WebComponent/LeadSourceClient.ts +332 -0
  138. package/src/WebComponent/MEChat.css +5 -0
  139. package/src/WebComponent/OfficeHours.ts +73 -0
  140. package/src/WebComponent/Scheduler/date-picker.ts +405 -0
  141. package/src/WebComponent/Scheduler/time-picker.ts +190 -0
  142. package/src/WebComponent/Scheduler/tour-scheduler.ts +1373 -0
  143. package/src/WebComponent/Scheduler/tour-type-option.ts +112 -0
  144. package/src/WebComponent/Scheduler/tourSchedulerStyles.ts +418 -0
  145. package/src/WebComponent/actions/InputStyles.ts +57 -0
  146. package/src/WebComponent/actions/action-confirm-button.ts +125 -0
  147. package/src/WebComponent/actions/call-us-window.ts +445 -0
  148. package/src/WebComponent/actions/collapse-expand-button.ts +65 -0
  149. package/src/WebComponent/actions/details-window.ts +150 -0
  150. package/src/WebComponent/actions/email-us-window.ts +555 -0
  151. package/src/WebComponent/actions/formatPhoneNumber.ts +72 -0
  152. package/src/WebComponent/actions/minimize-expand-button.ts +93 -0
  153. package/src/WebComponent/chat-additional-actions.ts +135 -0
  154. package/src/WebComponent/health-chat.ts +270 -0
  155. package/src/WebComponent/healthchat-styles.ts +119 -0
  156. package/src/WebComponent/icons/ApplyOutlineIcon.ts +22 -0
  157. package/src/WebComponent/icons/BookTourOutlineIcon.ts +13 -0
  158. package/src/WebComponent/icons/CalculatorOutlineIcon.ts +22 -0
  159. package/src/WebComponent/icons/ChatOutlineIcon.ts +10 -0
  160. package/src/WebComponent/icons/ChevronLeftIcon.ts +7 -0
  161. package/src/WebComponent/icons/ChevronRightIcon.ts +7 -0
  162. package/src/WebComponent/icons/ContactResidentIcon.ts +9 -0
  163. package/src/WebComponent/icons/DollarOutlineIcon.ts +18 -0
  164. package/src/WebComponent/icons/EmailOutlineIcon.ts +7 -0
  165. package/src/WebComponent/icons/HeyThereEmojiIcon.ts +12 -0
  166. package/src/WebComponent/icons/PhoneOutlineIcon.ts +7 -0
  167. package/src/WebComponent/icons/SendMessageIcon.ts +17 -0
  168. package/src/WebComponent/icons/TourSelfGuidedIcon.ts +17 -0
  169. package/src/WebComponent/icons/TourVirtuallyIcon.ts +17 -0
  170. package/src/WebComponent/icons/TourWithAgentIcon.ts +17 -0
  171. package/src/WebComponent/icons/XOutlineIcon.ts +8 -0
  172. package/src/WebComponent/index.ts +2 -0
  173. package/src/WebComponent/launcher/Launcher.ts +1282 -0
  174. package/src/WebComponent/launcher/launcherStyles.ts +500 -0
  175. package/src/WebComponent/launcher/mobile-launcher.ts +162 -0
  176. package/src/WebComponent/launcher/typeEmojiStyles.ts +161 -0
  177. package/src/WebComponent/launcher/typeMiniStyles.ts +60 -0
  178. package/src/WebComponent/launcher/typeMobileStyles.ts +50 -0
  179. package/src/WebComponent/leasing-chat-styles.ts +114 -0
  180. package/src/WebComponent/me-chat.ts +1262 -0
  181. package/src/WebComponent/me-select.ts +322 -0
  182. package/src/WebComponent/mega-loader.ts +36 -0
  183. package/src/WebComponent/mini-loader.ts +28 -0
  184. package/src/WebComponent/pubnub-chat-styles.ts +204 -0
  185. package/src/WebComponent/pubnub-chat.ts +928 -0
  186. package/src/WebComponent/pubnub-media.ts +208 -0
  187. package/src/WebComponent/pubnub-message-styles.ts +54 -0
  188. package/src/WebComponent/pubnub-message.ts +431 -0
  189. package/src/WebComponent/simple-launcher/simple-launcher-styles.ts +34 -0
  190. package/src/WebComponent/simple-launcher/simple-launcher.ts +100 -0
  191. package/src/WebComponent/utilities-chat.ts +270 -0
  192. package/src/WebComponent/utilities-styles.ts +110 -0
  193. package/src/WebComponent/utils.ts +82 -0
  194. package/src/analytics.ts +217 -0
  195. package/src/assetUrls.ts +6 -0
  196. package/src/disclaimers.ts +58 -0
  197. package/src/fetchBuildingABTestType.ts +21 -0
  198. package/src/fetchBuildingInfo.ts +87 -0
  199. package/src/fetchBuildingWebchatView.ts +156 -0
  200. package/src/fetchFeatureFlag.ts +250 -0
  201. package/src/fetchLeadSources.ts +98 -0
  202. package/src/fetchPhoneNumberFromSource.ts +31 -0
  203. package/src/fetchWebchatPreferences.ts +54 -0
  204. package/src/getAvailabilities.ts +179 -0
  205. package/src/getBuildingPhoneNumber.ts +26 -0
  206. package/src/getShouldAllowScheduling.ts +16 -0
  207. package/src/getShouldShowWebchat.ts +114 -0
  208. package/src/getTimezoneString.ts +39 -0
  209. package/src/globals.ts +1 -0
  210. package/src/gtm.ts +17 -0
  211. package/src/handleChatId.ts +101 -0
  212. package/src/insertDNIIntoWebsite.ts +146 -0
  213. package/src/insertLeadSourceIntoSchedulerLinks.ts +71 -0
  214. package/src/main/MEChat.test.ts +110 -0
  215. package/src/main/MEChat.ts +404 -0
  216. package/src/main/utils.ts +70 -0
  217. package/src/postLeadSources.ts +44 -0
  218. package/src/rentgrata.ts +74 -0
  219. package/src/replaceSelectButtonsWithNewLink.ts +69 -0
  220. package/src/services/fees/calculateQuote.ts +136 -0
  221. package/src/services/fees/fetchBuildingFees.ts +63 -0
  222. package/src/services/fees/fetchBuildingFloorplans.ts +74 -0
  223. package/src/services/fees/utils.ts +4 -0
  224. package/src/svgIcons.ts +14 -0
  225. package/src/themes.ts +65 -0
  226. package/src/types/rest-sdk.types.ts +13 -0
  227. package/src/types/webchat-no-show-reason.ts +6 -0
  228. package/src/utils.ts +121 -0
@@ -0,0 +1,405 @@
1
+ import { isSameMonth } from "date-fns";
2
+ import format from "date-fns/format";
3
+ import getDate from "date-fns/getDate";
4
+ import getMonth from "date-fns/getMonth";
5
+ import getYear from "date-fns/getYear";
6
+ import { LitElement, html, TemplateResult, css } from "lit";
7
+ import { customElement, property, state } from "lit/decorators.js";
8
+ import { classMap } from "lit/directives/class-map.js";
9
+ import {
10
+ dayNames,
11
+ getDaysInMonth,
12
+ getDaysInPreviousMonth,
13
+ getMonthEndDay,
14
+ getMonthStartDay,
15
+ Month,
16
+ monthNames,
17
+ } from "../utils";
18
+
19
+ @customElement("date-picker")
20
+ export class DatePicker extends LitElement {
21
+ /**
22
+ * Optional attribute to set the date picker's default month.
23
+ * The attribute will not be updated if the user changes the month shown.
24
+ */
25
+ @property({ attribute: "month", type: String })
26
+ defaultMonth?: Month;
27
+
28
+ /**
29
+ * Optional attribute to set the date picker's default year.
30
+ * The attribute will not be updated if the user changes the year shown.
31
+ */
32
+ @property({ attribute: "year", type: Number })
33
+ defaultYear?: number;
34
+
35
+ @property({ attribute: false })
36
+ availabilities?: {
37
+ [day: string]: Date[];
38
+ };
39
+
40
+ private _selectedDate?: Date = undefined;
41
+ set selectedDate(date: Date | undefined) {
42
+ const old = this._selectedDate;
43
+ this._selectedDate = date;
44
+ this.requestUpdate("selectedDate", old);
45
+ this.dispatchEvent(
46
+ new Event("change", {
47
+ composed: true,
48
+ bubbles: true,
49
+ })
50
+ );
51
+ }
52
+
53
+ @property({ attribute: false })
54
+ get selectedDate(): undefined | Date {
55
+ return this._selectedDate;
56
+ }
57
+
58
+ now = new Date();
59
+
60
+ private _monthShown =
61
+ this.defaultMonth && monthNames.indexOf(this.defaultMonth) !== -1
62
+ ? monthNames.indexOf(this.defaultMonth)
63
+ : this.now.getMonth();
64
+
65
+ // Make it easy to increment/decrement `this.monthShown` at year boundaries
66
+ // TODO: `willUpdate` is better: see https://lit.dev/docs/components/properties/ and https://lit.dev/docs/components/lifecycle/#willupdate
67
+ set monthShown(month: number) {
68
+ const oldMonthShown = this._monthShown;
69
+ if (month === 12) {
70
+ this._monthShown = 0;
71
+ this.yearShown++;
72
+ } else if (month === -1) {
73
+ this._monthShown = 11;
74
+ this.yearShown--;
75
+ } else {
76
+ this._monthShown = month;
77
+ }
78
+ this.requestUpdate("monthShown", oldMonthShown);
79
+ }
80
+
81
+ /** 0-indexed month, e.g. `0` for January */
82
+ @state()
83
+ get monthShown(): number {
84
+ return this._monthShown;
85
+ }
86
+
87
+ @state()
88
+ yearShown = this.defaultYear ?? this.now.getFullYear();
89
+
90
+ static styles = css`
91
+ :host {
92
+ box-sizing: border-box;
93
+ font-family: "Helvetica Neue", Arial;
94
+ color: #202020;
95
+ font-style: normal;
96
+ }
97
+
98
+ #calendar {
99
+ box-sizing: border-box;
100
+ display: flex;
101
+ flex-direction: column;
102
+ user-select: none;
103
+ min-width: 206px;
104
+ width: 206px;
105
+ background: #e7e7e7;
106
+ border: 1px solid #ffffff;
107
+ border-radius: 10px;
108
+ padding: 15px 12px 15px;
109
+ }
110
+
111
+ #header {
112
+ display: flex;
113
+ align-items: center;
114
+ justify-content: space-between;
115
+ margin-bottom: 13px;
116
+ }
117
+
118
+ h1 {
119
+ font-weight: 600;
120
+ font-size: 12px;
121
+ margin: 0;
122
+ margin-left: 0.7em;
123
+ }
124
+
125
+ #arrows {
126
+ width: 40.46px;
127
+ display: flex;
128
+ justify-content: space-between;
129
+ align-items: center;
130
+ }
131
+
132
+ #rows {
133
+ display: flex;
134
+ flex-direction: column;
135
+ gap: 10px;
136
+ }
137
+
138
+ .row {
139
+ display: flex;
140
+ justify-content: space-between;
141
+ align-items: center;
142
+ width: 100%;
143
+ }
144
+
145
+ .dayNumber,
146
+ .dayInitial {
147
+ position: relative;
148
+ font-size: 12px;
149
+ text-align: center;
150
+ flex: 1 1 0px;
151
+ border: none;
152
+ background: none;
153
+ width: 24px;
154
+ }
155
+
156
+ .dayInitial {
157
+ font-weight: 400;
158
+ }
159
+
160
+ .dayNumber {
161
+ position: relative;
162
+ font-size: 12px;
163
+ text-align: center;
164
+ flex: 1 1 0px;
165
+ border: none;
166
+ background: none;
167
+ width: 24px;
168
+ -webkit-appearance: none;
169
+ appearance: none;
170
+ margin: 0;
171
+ padding: 0;
172
+ border-radius: 0;
173
+ }
174
+
175
+ .dayNumber.selected::after,
176
+ .dayNumber:not(.selected):hover::after {
177
+ content: "";
178
+ height: 23px;
179
+ aspect-ratio: 1;
180
+ border-radius: 50%;
181
+ background-color: #202020;
182
+ position: absolute;
183
+ top: 50%;
184
+ left: 50%;
185
+ transform: translate(-50%, -50%);
186
+ z-index: -1;
187
+ }
188
+ .dayNumber.today:not(.selected)::after {
189
+ content: "";
190
+ height: 23px;
191
+ aspect-ratio: 1;
192
+ border: 1px solid #202020;
193
+ border-radius: 50%;
194
+ position: absolute;
195
+ top: 50%;
196
+ left: 50%;
197
+ transform: translate(-50%, -50%);
198
+ z-index: 1;
199
+ }
200
+ .dayNumber:not(.selected):hover::after {
201
+ background-color: lightgray;
202
+ z-index: -1;
203
+ }
204
+ .dayNumber.selected::after {
205
+ background-color: #202020;
206
+ }
207
+ .dayNumber.selected,
208
+ .dayNumber:not(.selected):not(.differentMonth):hover {
209
+ z-index: 1;
210
+ }
211
+ .dayNumber.selected {
212
+ color: white;
213
+ }
214
+ .dayNumber:is(.differentMonth, .past, .noAvailabilities) {
215
+ opacity: 30%;
216
+ }
217
+ `;
218
+
219
+ render(): TemplateResult {
220
+ const daysInMonth = getDaysInMonth(this.yearShown, this.monthShown);
221
+ const monthStartDay =
222
+ dayNames[getMonthStartDay(this.yearShown, this.monthShown)];
223
+ const daysInPreviousMonth = getDaysInPreviousMonth(
224
+ this.yearShown,
225
+ this.monthShown
226
+ );
227
+ const monthEndDay =
228
+ dayNames[getMonthEndDay(this.yearShown, this.monthShown)];
229
+ const extraDaysAtBeginningOfMonth = [];
230
+ if (monthStartDay !== "Sunday") {
231
+ const numberOfExtraDaysAtBeginningOfMonth =
232
+ dayNames.indexOf(monthStartDay);
233
+ for (let i = numberOfExtraDaysAtBeginningOfMonth; i > 0; i--) {
234
+ extraDaysAtBeginningOfMonth.push(daysInPreviousMonth + 1 - i);
235
+ }
236
+ }
237
+
238
+ const daysOfMonth = new Array(daysInMonth).fill(null).map((_, i) => i + 1);
239
+
240
+ const extraDaysAtEndOfMonth = [];
241
+ if (monthEndDay !== "Saturday") {
242
+ const numberOfExtraDaysAtEndOfMonth = [...dayNames]
243
+ .reverse()
244
+ .indexOf(monthEndDay);
245
+ for (let i = 1; i <= numberOfExtraDaysAtEndOfMonth; i++) {
246
+ extraDaysAtEndOfMonth.push(i);
247
+ }
248
+ }
249
+
250
+ const dayNums = [
251
+ ...extraDaysAtBeginningOfMonth,
252
+ ...daysOfMonth,
253
+ ...extraDaysAtEndOfMonth,
254
+ ];
255
+
256
+ const dayElements = dayNums.map((dayNumber, index) => {
257
+ const isPast =
258
+ this.yearShown < this.now.getFullYear() ||
259
+ (this.yearShown === this.now.getFullYear() &&
260
+ this.monthShown < this.now.getMonth()) ||
261
+ (this.yearShown === this.now.getFullYear() &&
262
+ this.monthShown === this.now.getMonth() &&
263
+ dayNumber < this.now.getDate());
264
+ const isDifferentMonth =
265
+ index < extraDaysAtBeginningOfMonth.length ||
266
+ index >= extraDaysAtBeginningOfMonth.length + daysOfMonth.length;
267
+ const isToday =
268
+ !isDifferentMonth &&
269
+ this.now.getMonth() === this.monthShown &&
270
+ this.now.getDate() === dayNumber;
271
+ const isSelected =
272
+ !!this.selectedDate &&
273
+ !isDifferentMonth &&
274
+ this.monthShown === getMonth(this.selectedDate) &&
275
+ this.yearShown === getYear(this.selectedDate) &&
276
+ dayNumber === getDate(this.selectedDate);
277
+ const dateString = format(
278
+ new Date(this.yearShown, this.monthShown, dayNumber),
279
+ "y-MM-dd"
280
+ );
281
+ const hasNoAvailabilities =
282
+ !this.availabilities?.[dateString] ||
283
+ this.availabilities?.[dateString]?.length === 0;
284
+ return html`<button
285
+ ?disabled=${isPast || hasNoAvailabilities || isDifferentMonth}
286
+ class="dayNumber ${classMap({
287
+ past: isPast,
288
+ differentMonth: isDifferentMonth,
289
+ today: isToday,
290
+ selected: isSelected,
291
+ noAvailabilities: hasNoAvailabilities,
292
+ })}"
293
+ >
294
+ ${dayNumber}
295
+ </button>`;
296
+ });
297
+ const rows = chunk(7, dayElements);
298
+
299
+ return html`
300
+ <div id="calendar">
301
+ <div id="header">
302
+ <h1>${monthNames[this.monthShown]} ${this.yearShown}</h1>
303
+ <div
304
+ id="arrows"
305
+ @click="${(e: MouseEvent) => {
306
+ if (
307
+ (e.target as HTMLElement)?.closest("#back") &&
308
+ !isSameMonth(
309
+ this.now,
310
+ new Date(this.yearShown, this.monthShown, 1)
311
+ )
312
+ ) {
313
+ this.monthShown--;
314
+ }
315
+ if ((e.target as HTMLElement)?.closest("#forward")) {
316
+ this.monthShown++;
317
+ }
318
+ }}"
319
+ @keydown="${(e: KeyboardEvent) => {
320
+ if (![" ", "Enter"].includes(e.key)) {
321
+ return;
322
+ }
323
+ if (
324
+ (e.target as HTMLElement)?.closest("#back") &&
325
+ !isSameMonth(
326
+ this.now,
327
+ new Date(this.yearShown, this.monthShown, 1)
328
+ )
329
+ ) {
330
+ e.preventDefault();
331
+ e.stopPropagation();
332
+ this.monthShown--;
333
+ } else if ((e.target as HTMLElement)?.closest("#forward")) {
334
+ e.preventDefault();
335
+ e.stopPropagation();
336
+ this.monthShown++;
337
+ }
338
+ }}"
339
+ >
340
+ <svg
341
+ id="back"
342
+ tabindex="0"
343
+ width="9"
344
+ height="16"
345
+ viewBox="0 0 9 16"
346
+ fill="none"
347
+ xmlns="http://www.w3.org/2000/svg"
348
+ >
349
+ <path
350
+ d="M8.67727 2.34317L7.26305 0.928955L0.192017 8.00001L7.26308 15.0711L8.6773 13.6569L3.02044 8L8.67727 2.34317Z"
351
+ fill="#83818E"
352
+ />
353
+ </svg>
354
+ <svg
355
+ id="forward"
356
+ tabindex="0"
357
+ width="9"
358
+ height="16"
359
+ viewBox="0 0 9 16"
360
+ fill="none"
361
+ xmlns="http://www.w3.org/2000/svg"
362
+ >
363
+ <path
364
+ d="M0.157227 2.34315L1.57144 0.928932L8.64251 8L1.57144 15.0711L0.157227 13.6569L5.81408 8L0.157227 2.34315Z"
365
+ fill="#83818E"
366
+ />
367
+ </svg>
368
+ </div>
369
+ </div>
370
+
371
+ <div
372
+ id="rows"
373
+ @click="${(e: MouseEvent) => {
374
+ const target = e.target as HTMLElement | undefined;
375
+ if (target?.closest("button.dayNumber:not(.differentMonth)"))
376
+ this.selectedDate = new Date(
377
+ this.yearShown,
378
+ this.monthShown,
379
+ parseInt(target.innerText)
380
+ );
381
+ }}"
382
+ >
383
+ <div class="row">
384
+ <span class="dayInitial">S</span>
385
+ <span class="dayInitial">M</span>
386
+ <span class="dayInitial">T</span>
387
+ <span class="dayInitial">W</span>
388
+ <span class="dayInitial">T</span>
389
+ <span class="dayInitial">F</span>
390
+ <span class="dayInitial">S</span>
391
+ </div>
392
+ ${rows.map((row) => html`<div class="row">${row}</div>`)}
393
+ </div>
394
+ </div>
395
+ `;
396
+ }
397
+ }
398
+
399
+ const chunk = <T>(chunkLength: number, array: T[]) => {
400
+ const chunks = [];
401
+ for (let i = 0; i < array.length; i += chunkLength) {
402
+ chunks.push(array.slice(i, i + chunkLength));
403
+ }
404
+ return chunks;
405
+ };
@@ -0,0 +1,190 @@
1
+ import { LitElement, html, TemplateResult, css } from "lit";
2
+ import { customElement, property, state } from "lit/decorators.js";
3
+ import { classMap } from "lit/directives/class-map.js";
4
+ import { DateWithTimeZoneOffset } from "../../getAvailabilities";
5
+ import { getTimezoneAbbreviation } from "../../getTimezoneString";
6
+
7
+ export type TimePickerOption = {
8
+ displayTime: string;
9
+ dateWithTimeZoneOffset: DateWithTimeZoneOffset;
10
+ };
11
+
12
+ const getDateWithTimezoneOffset = (
13
+ options: TimePickerOption[],
14
+ displayTime: string
15
+ ) => {
16
+ return options.reduce(function (map: Record<string, TimePickerOption>, obj) {
17
+ map[obj.displayTime] = obj;
18
+ return map;
19
+ }, {})[displayTime];
20
+ };
21
+
22
+ @customElement("time-picker")
23
+ export class TimePicker extends LitElement {
24
+ @property({ attribute: false })
25
+ options: TimePickerOption[] = [];
26
+
27
+ @property({ type: Boolean })
28
+ selectedDateExists = false;
29
+
30
+ @state()
31
+ private selected?: TimePickerOption;
32
+
33
+ @property({ attribute: false })
34
+ get selectedTime(): undefined | TimePickerOption {
35
+ return this.selected;
36
+ }
37
+
38
+ static styles = css`
39
+ * {
40
+ box-sizing: border-box;
41
+ }
42
+
43
+ :host {
44
+ color: #202020;
45
+ font-family: "Helvetica Neue", Arial;
46
+ }
47
+
48
+ .timezone-display-text {
49
+ font-size: 12px;
50
+ color: #767676;
51
+ }
52
+ .select-tour-type-instructions {
53
+ color: #e60000;
54
+ }
55
+
56
+ #optionContainer {
57
+ display: flex;
58
+ flex-wrap: wrap;
59
+ max-width: 200px;
60
+ max-height: 320px;
61
+ overflow-y: auto;
62
+ gap: 8px;
63
+ }
64
+
65
+ .option {
66
+ position: relative;
67
+ display: inline-flex;
68
+ justify-content: center;
69
+ align-items: center;
70
+ height: 40px;
71
+ width: 80px;
72
+ padding: 11px 11px 11px 14px;
73
+ background: #e7e7e7;
74
+ border: 1px solid #ffffff;
75
+ border-radius: 10px;
76
+ font-style: normal;
77
+ font-size: 14px;
78
+ user-select: none;
79
+ }
80
+
81
+ .option.selected {
82
+ color: white;
83
+ background: #202020;
84
+ box-shadow: inset 0px 0px 0px 3px rgb(131 129 142);
85
+ border-radius: 10px;
86
+ }
87
+
88
+ #noAvailabilityText {
89
+ font-size: 12px;
90
+ margin-left: 20px;
91
+ line-height: 18px;
92
+ max-width: 170px;
93
+ }
94
+
95
+ #noAvailabilityText.horizontal {
96
+ margin-left: 0;
97
+ }
98
+
99
+ @media screen and (max-width: 1200px) {
100
+ #optionContainer {
101
+ display: flex;
102
+ flex-wrap: wrap;
103
+ justify-content: center;
104
+ align-items: center;
105
+ max-width: none;
106
+ max-height: 120px;
107
+ overflow-x: auto;
108
+ gap: 8px;
109
+
110
+ width: 100%;
111
+ }
112
+ }
113
+ `;
114
+
115
+ render(): TemplateResult {
116
+ if (this.options.length === 1 && !this.selected) {
117
+ this.selected = getDateWithTimezoneOffset(
118
+ this.options,
119
+ this.options[0].displayTime
120
+ );
121
+ this.dispatchEvent(
122
+ new Event("change", { bubbles: true, composed: true })
123
+ );
124
+ }
125
+ return this.options?.length
126
+ ? html`
127
+ <div>
128
+ <div
129
+ id="optionContainer"
130
+ @click="${(e: MouseEvent) => {
131
+ const target = e.target as HTMLElement | undefined;
132
+
133
+ if (target?.closest(".option:not(.selected)"))
134
+ this.selected = getDateWithTimezoneOffset(
135
+ this.options,
136
+ target.innerText
137
+ );
138
+ this.dispatchEvent(
139
+ new Event("change", { bubbles: true, composed: true })
140
+ );
141
+ }}"
142
+ @keydown="${(e: KeyboardEvent) => {
143
+ const target = e.target as HTMLElement | undefined;
144
+ if (
145
+ [" ", "Enter"].includes(e.key) &&
146
+ target?.closest(".option")
147
+ ) {
148
+ e.preventDefault();
149
+ this.selected =
150
+ target.innerText !== this.selected?.displayTime
151
+ ? getDateWithTimezoneOffset(
152
+ this.options,
153
+ target.innerText
154
+ )
155
+ : undefined;
156
+ this.dispatchEvent(
157
+ new Event("change", { bubbles: true, composed: true })
158
+ );
159
+ }
160
+ }}"
161
+ >
162
+ ${this.options.map(
163
+ (option) =>
164
+ html`<div
165
+ class="option ${classMap({
166
+ selected:
167
+ this.selected?.displayTime === option.displayTime,
168
+ })}"
169
+ tabindex="0"
170
+ >
171
+ <span>${option.displayTime}</span>
172
+ </div>`
173
+ )}
174
+ </div>
175
+ <p class="timezone-display-text">
176
+ *All times displayed are your browser's time zone
177
+ (${getTimezoneAbbreviation()}). Your email confirmation will
178
+ reflect the converted local time for the community.
179
+ </p>
180
+ </div>
181
+ `
182
+ : html` <div id="noAvailabilityText">
183
+ ${this.selectedDateExists
184
+ ? html`<p>No available appointments for this day</p>`
185
+ : html`<p class="select-tour-type-instructions">
186
+ Please select a tour type to see available dates/times!
187
+ </p>`}
188
+ </div>`;
189
+ }
190
+ }