@tui-cruises/mein-schiff-web-react-component-library 2.0.0-rc.1

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 (556) hide show
  1. package/CHANGELOG.md +7 -0
  2. package/LICENSE +14 -0
  3. package/README.md +26 -0
  4. package/custom.d.ts +14 -0
  5. package/icons/icons/360.tsx +20 -0
  6. package/icons/icons/add-circle.tsx +26 -0
  7. package/icons/icons/airplane.tsx +20 -0
  8. package/icons/icons/anchor.tsx +20 -0
  9. package/icons/icons/angle-tool.tsx +26 -0
  10. package/icons/icons/arrow-down.tsx +20 -0
  11. package/icons/icons/arrow-left.tsx +20 -0
  12. package/icons/icons/arrow-right.tsx +20 -0
  13. package/icons/icons/at.tsx +20 -0
  14. package/icons/icons/baggage.tsx +20 -0
  15. package/icons/icons/balcony.tsx +20 -0
  16. package/icons/icons/bathroom.tsx +32 -0
  17. package/icons/icons/beach.tsx +20 -0
  18. package/icons/icons/bed.tsx +26 -0
  19. package/icons/icons/bell.tsx +20 -0
  20. package/icons/icons/bording.tsx +20 -0
  21. package/icons/icons/cabins.tsx +20 -0
  22. package/icons/icons/calendar.tsx +32 -0
  23. package/icons/icons/cancel.tsx +20 -0
  24. package/icons/icons/cash.tsx +44 -0
  25. package/icons/icons/check-circle.tsx +18 -0
  26. package/icons/icons/check.tsx +20 -0
  27. package/icons/icons/circle.tsx +20 -0
  28. package/icons/icons/clear.tsx +24 -0
  29. package/icons/icons/clock-rotate-right.tsx +20 -0
  30. package/icons/icons/clock.tsx +26 -0
  31. package/icons/icons/cloud-sunny.tsx +43 -0
  32. package/icons/icons/cloud.tsx +20 -0
  33. package/icons/icons/compass.tsx +26 -0
  34. package/icons/icons/delete-circle.tsx +26 -0
  35. package/icons/icons/departure.tsx +20 -0
  36. package/icons/icons/details.tsx +20 -0
  37. package/icons/icons/diamond.tsx +20 -0
  38. package/icons/icons/edit-pencil.tsx +20 -0
  39. package/icons/icons/excellence.tsx +20 -0
  40. package/icons/icons/expand.tsx +20 -0
  41. package/icons/icons/eye-closed.tsx +20 -0
  42. package/icons/icons/eye-empty.tsx +26 -0
  43. package/icons/icons/eye-off.tsx +32 -0
  44. package/icons/icons/eye.tsx +26 -0
  45. package/icons/icons/fallback.tsx +26 -0
  46. package/icons/icons/filter.tsx +20 -0
  47. package/icons/icons/flag.tsx +20 -0
  48. package/icons/icons/fog.tsx +22 -0
  49. package/icons/icons/glases.tsx +28 -0
  50. package/icons/icons/group.tsx +32 -0
  51. package/icons/icons/heart-filled.tsx +20 -0
  52. package/icons/icons/heart.tsx +20 -0
  53. package/icons/icons/help-circle.tsx +24 -0
  54. package/icons/icons/home.tsx +22 -0
  55. package/icons/icons/humidity.tsx +30 -0
  56. package/icons/icons/impressions.tsx +20 -0
  57. package/icons/icons/inclusive-services.tsx +20 -0
  58. package/icons/icons/index.ts +141 -0
  59. package/icons/icons/info-empty.tsx +26 -0
  60. package/icons/icons/language.tsx +20 -0
  61. package/icons/icons/lifebuoy.tsx +30 -0
  62. package/icons/icons/loading.tsx +18 -0
  63. package/icons/icons/location.tsx +24 -0
  64. package/icons/icons/log-in.tsx +26 -0
  65. package/icons/icons/log-out.tsx +26 -0
  66. package/icons/icons/mail-open.tsx +20 -0
  67. package/icons/icons/map.tsx +20 -0
  68. package/icons/icons/maps-arrow-diagonal.tsx +20 -0
  69. package/icons/icons/media-image-list.tsx +32 -0
  70. package/icons/icons/menu.tsx +21 -0
  71. package/icons/icons/metropolis.tsx +20 -0
  72. package/icons/icons/minus.tsx +20 -0
  73. package/icons/icons/more-horiz.tsx +35 -0
  74. package/icons/icons/more-vert.tsx +35 -0
  75. package/icons/icons/mostly-cloudy-night.tsx +24 -0
  76. package/icons/icons/ms-ship.tsx +20 -0
  77. package/icons/icons/music.tsx +20 -0
  78. package/icons/icons/nav-arrow-down.tsx +20 -0
  79. package/icons/icons/nav-arrow-left.tsx +20 -0
  80. package/icons/icons/nav-arrow-right.tsx +20 -0
  81. package/icons/icons/nav-arrow-up.tsx +20 -0
  82. package/icons/icons/no-wifi.tsx +18 -0
  83. package/icons/icons/old-trips.tsx +20 -0
  84. package/icons/icons/percentage.tsx +20 -0
  85. package/icons/icons/phone.tsx +20 -0
  86. package/icons/icons/pin.tsx +20 -0
  87. package/icons/icons/play.tsx +20 -0
  88. package/icons/icons/plus-circle.tsx +20 -0
  89. package/icons/icons/plus.tsx +20 -0
  90. package/icons/icons/point.tsx +15 -0
  91. package/icons/icons/rain.tsx +22 -0
  92. package/icons/icons/receipt.tsx +20 -0
  93. package/icons/icons/refresh-double.tsx +32 -0
  94. package/icons/icons/search.tsx +26 -0
  95. package/icons/icons/security-pass.tsx +26 -0
  96. package/icons/icons/settings.tsx +20 -0
  97. package/icons/icons/share-ios.tsx +26 -0
  98. package/icons/icons/ship-account.tsx +20 -0
  99. package/icons/icons/ship-info.tsx +20 -0
  100. package/icons/icons/ship-position.tsx +27 -0
  101. package/icons/icons/shooting-stars.tsx +28 -0
  102. package/icons/icons/sleet.tsx +22 -0
  103. package/icons/icons/snow-flake.tsx +20 -0
  104. package/icons/icons/snow.tsx +22 -0
  105. package/icons/icons/sofa.tsx +32 -0
  106. package/icons/icons/star-dashed.tsx +20 -0
  107. package/icons/icons/star-filled.tsx +25 -0
  108. package/icons/icons/star-half-dashed.tsx +26 -0
  109. package/icons/icons/star.tsx +20 -0
  110. package/icons/icons/substract.tsx +26 -0
  111. package/icons/icons/sun-light.tsx +42 -0
  112. package/icons/icons/temperature-high.tsx +26 -0
  113. package/icons/icons/thunderstorm.tsx +26 -0
  114. package/icons/icons/tornado.tsx +18 -0
  115. package/icons/icons/trash.tsx +20 -0
  116. package/icons/icons/travel-assistant.tsx +24 -0
  117. package/icons/icons/tropical-storm.tsx +71 -0
  118. package/icons/icons/upcoming-trips.tsx +27 -0
  119. package/icons/icons/user.tsx +26 -0
  120. package/icons/icons/warning-circle.tsx +26 -0
  121. package/icons/icons/warning-hexagon.tsx +26 -0
  122. package/icons/icons/weather.tsx +20 -0
  123. package/icons/icons/wifi.tsx +20 -0
  124. package/icons/icons/wind.tsx +22 -0
  125. package/icons/icons/windrose.tsx +42 -0
  126. package/icons/icons/windsock.tsx +20 -0
  127. package/icons/pictograms/24h-meals.tsx +25 -0
  128. package/icons/pictograms/ad-template.tsx +23 -0
  129. package/icons/pictograms/add.tsx +25 -0
  130. package/icons/pictograms/adventure-club-only.tsx +25 -0
  131. package/icons/pictograms/allergy.tsx +30 -0
  132. package/icons/pictograms/anchor.tsx +23 -0
  133. package/icons/pictograms/arrival.tsx +23 -0
  134. package/icons/pictograms/baby-awake.tsx +20 -0
  135. package/icons/pictograms/baby-monitor.tsx +20 -0
  136. package/icons/pictograms/baby-sleep.tsx +20 -0
  137. package/icons/pictograms/baggage-information.tsx +23 -0
  138. package/icons/pictograms/baggage.tsx +23 -0
  139. package/icons/pictograms/bedroom-check.tsx +23 -0
  140. package/icons/pictograms/bedroom.tsx +23 -0
  141. package/icons/pictograms/beverages.tsx +28 -0
  142. package/icons/pictograms/billboard.tsx +23 -0
  143. package/icons/pictograms/blog.tsx +23 -0
  144. package/icons/pictograms/brochure.tsx +23 -0
  145. package/icons/pictograms/calendar-check.tsx +18 -0
  146. package/icons/pictograms/calendar-default.tsx +18 -0
  147. package/icons/pictograms/calendar-disabled.tsx +18 -0
  148. package/icons/pictograms/calendar-focus.tsx +25 -0
  149. package/icons/pictograms/champagne-glasses.tsx +25 -0
  150. package/icons/pictograms/check.tsx +25 -0
  151. package/icons/pictograms/checklist-check.tsx +18 -0
  152. package/icons/pictograms/checklist.tsx +21 -0
  153. package/icons/pictograms/checkmark.tsx +23 -0
  154. package/icons/pictograms/chef-hat.tsx +30 -0
  155. package/icons/pictograms/chevron-down.tsx +25 -0
  156. package/icons/pictograms/chevron-up.tsx +25 -0
  157. package/icons/pictograms/circles.tsx +25 -0
  158. package/icons/pictograms/cleaning-trolley.tsx +30 -0
  159. package/icons/pictograms/clock-0-30.tsx +23 -0
  160. package/icons/pictograms/clock-0.tsx +23 -0
  161. package/icons/pictograms/clock-1-30.tsx +23 -0
  162. package/icons/pictograms/clock-1.tsx +23 -0
  163. package/icons/pictograms/clock-10-30.tsx +23 -0
  164. package/icons/pictograms/clock-10.tsx +23 -0
  165. package/icons/pictograms/clock-11-30.tsx +23 -0
  166. package/icons/pictograms/clock-11.tsx +23 -0
  167. package/icons/pictograms/clock-2-30.tsx +23 -0
  168. package/icons/pictograms/clock-2.tsx +23 -0
  169. package/icons/pictograms/clock-3-30.tsx +23 -0
  170. package/icons/pictograms/clock-3.tsx +23 -0
  171. package/icons/pictograms/clock-4-30.tsx +23 -0
  172. package/icons/pictograms/clock-4.tsx +23 -0
  173. package/icons/pictograms/clock-5-30.tsx +23 -0
  174. package/icons/pictograms/clock-5.tsx +23 -0
  175. package/icons/pictograms/clock-6-30.tsx +23 -0
  176. package/icons/pictograms/clock-6.tsx +23 -0
  177. package/icons/pictograms/clock-7-30.tsx +23 -0
  178. package/icons/pictograms/clock-7.tsx +23 -0
  179. package/icons/pictograms/clock-8-30.tsx +23 -0
  180. package/icons/pictograms/clock-8.tsx +23 -0
  181. package/icons/pictograms/clock-9-30.tsx +23 -0
  182. package/icons/pictograms/clock-9.tsx +23 -0
  183. package/icons/pictograms/clock-default.tsx +23 -0
  184. package/icons/pictograms/close.tsx +25 -0
  185. package/icons/pictograms/clothing.tsx +23 -0
  186. package/icons/pictograms/cloud.tsx +23 -0
  187. package/icons/pictograms/cocktails.tsx +23 -0
  188. package/icons/pictograms/coffee-machine.tsx +23 -0
  189. package/icons/pictograms/compass.tsx +23 -0
  190. package/icons/pictograms/couple.tsx +25 -0
  191. package/icons/pictograms/crew-love.tsx +28 -0
  192. package/icons/pictograms/crown.tsx +23 -0
  193. package/icons/pictograms/dart.tsx +23 -0
  194. package/icons/pictograms/decoration.tsx +23 -0
  195. package/icons/pictograms/departure-check.tsx +25 -0
  196. package/icons/pictograms/departure-germany.tsx +20 -0
  197. package/icons/pictograms/departure-time.tsx +35 -0
  198. package/icons/pictograms/departure.tsx +23 -0
  199. package/icons/pictograms/diamond.tsx +23 -0
  200. package/icons/pictograms/discount-card.tsx +35 -0
  201. package/icons/pictograms/discount.tsx +30 -0
  202. package/icons/pictograms/documents.tsx +23 -0
  203. package/icons/pictograms/download-document.tsx +23 -0
  204. package/icons/pictograms/download.tsx +23 -0
  205. package/icons/pictograms/dripping-dew.tsx +23 -0
  206. package/icons/pictograms/dumbbell.tsx +25 -0
  207. package/icons/pictograms/early-bird.tsx +23 -0
  208. package/icons/pictograms/edit.tsx +23 -0
  209. package/icons/pictograms/energy-saving.tsx +23 -0
  210. package/icons/pictograms/enjoyer-club-only.tsx +18 -0
  211. package/icons/pictograms/environment.tsx +30 -0
  212. package/icons/pictograms/environmental-officer.tsx +30 -0
  213. package/icons/pictograms/explorer-club-only.tsx +18 -0
  214. package/icons/pictograms/family.tsx +25 -0
  215. package/icons/pictograms/fb-community.tsx +25 -0
  216. package/icons/pictograms/finance.tsx +25 -0
  217. package/icons/pictograms/fog.tsx +25 -0
  218. package/icons/pictograms/food-certificate.tsx +30 -0
  219. package/icons/pictograms/gastronomy.tsx +25 -0
  220. package/icons/pictograms/gift.tsx +23 -0
  221. package/icons/pictograms/globetrotter-club-only.tsx +18 -0
  222. package/icons/pictograms/hairdresser.tsx +20 -0
  223. package/icons/pictograms/handbag.tsx +30 -0
  224. package/icons/pictograms/hands-holding-heart.tsx +30 -0
  225. package/icons/pictograms/heart-beat.tsx +29 -0
  226. package/icons/pictograms/heart.tsx +23 -0
  227. package/icons/pictograms/home.tsx +23 -0
  228. package/icons/pictograms/hospital-cross.tsx +23 -0
  229. package/icons/pictograms/hot-dish.tsx +23 -0
  230. package/icons/pictograms/hot-drink.tsx +25 -0
  231. package/icons/pictograms/human-heart.tsx +30 -0
  232. package/icons/pictograms/human-holding-heart.tsx +30 -0
  233. package/icons/pictograms/human-open-arms.tsx +23 -0
  234. package/icons/pictograms/human-profile.tsx +23 -0
  235. package/icons/pictograms/human-swimming.tsx +25 -0
  236. package/icons/pictograms/ice-cream.tsx +23 -0
  237. package/icons/pictograms/important.tsx +23 -0
  238. package/icons/pictograms/index.ts +285 -0
  239. package/icons/pictograms/information.tsx +30 -0
  240. package/icons/pictograms/internet.tsx +23 -0
  241. package/icons/pictograms/jogging.tsx +21 -0
  242. package/icons/pictograms/kid-playing.tsx +23 -0
  243. package/icons/pictograms/life-jacket.tsx +21 -0
  244. package/icons/pictograms/lifebuoy.tsx +20 -0
  245. package/icons/pictograms/lightbulb.tsx +23 -0
  246. package/icons/pictograms/lightning.tsx +23 -0
  247. package/icons/pictograms/location-mark.tsx +30 -0
  248. package/icons/pictograms/log-in.tsx +23 -0
  249. package/icons/pictograms/long-term-trips.tsx +20 -0
  250. package/icons/pictograms/lotte-chatbot.tsx +28 -0
  251. package/icons/pictograms/lotte-mail.tsx +28 -0
  252. package/icons/pictograms/mail-at.tsx +23 -0
  253. package/icons/pictograms/mail-information.tsx +23 -0
  254. package/icons/pictograms/mailbox.tsx +23 -0
  255. package/icons/pictograms/many-sea-days.tsx +20 -0
  256. package/icons/pictograms/medal.tsx +23 -0
  257. package/icons/pictograms/microphone.tsx +23 -0
  258. package/icons/pictograms/ms-1.tsx +23 -0
  259. package/icons/pictograms/ms-2.tsx +30 -0
  260. package/icons/pictograms/ms-3.tsx +30 -0
  261. package/icons/pictograms/ms-4.tsx +30 -0
  262. package/icons/pictograms/ms-5.tsx +30 -0
  263. package/icons/pictograms/ms-6.tsx +30 -0
  264. package/icons/pictograms/ms-7-new-eng.tsx +37 -0
  265. package/icons/pictograms/ms-7-new.tsx +30 -0
  266. package/icons/pictograms/ms-7.tsx +30 -0
  267. package/icons/pictograms/ms-default.tsx +30 -0
  268. package/icons/pictograms/ms-flow-new-eng.tsx +37 -0
  269. package/icons/pictograms/ms-flow-new.tsx +49 -0
  270. package/icons/pictograms/ms-flow.tsx +41 -0
  271. package/icons/pictograms/ms-relax-new-eng.tsx +37 -0
  272. package/icons/pictograms/ms-relax-new.tsx +36 -0
  273. package/icons/pictograms/ms-ship.tsx +23 -0
  274. package/icons/pictograms/music-book.tsx +23 -0
  275. package/icons/pictograms/my-account.tsx +22 -0
  276. package/icons/pictograms/my-trips.tsx +29 -0
  277. package/icons/pictograms/navigation-arrow.tsx +23 -0
  278. package/icons/pictograms/no-wifi.tsx +21 -0
  279. package/icons/pictograms/not-available.tsx +23 -0
  280. package/icons/pictograms/offer.tsx +23 -0
  281. package/icons/pictograms/offline.tsx +25 -0
  282. package/icons/pictograms/onboard-announcement.tsx +20 -0
  283. package/icons/pictograms/package-newspaper.tsx +27 -0
  284. package/icons/pictograms/paper-news.tsx +23 -0
  285. package/icons/pictograms/paper-plane.tsx +28 -0
  286. package/icons/pictograms/payment-check.tsx +32 -0
  287. package/icons/pictograms/payment.tsx +28 -0
  288. package/icons/pictograms/people-check.tsx +25 -0
  289. package/icons/pictograms/people.tsx +25 -0
  290. package/icons/pictograms/permanent-make-up.tsx +20 -0
  291. package/icons/pictograms/person-single.tsx +23 -0
  292. package/icons/pictograms/phone.tsx +20 -0
  293. package/icons/pictograms/play-button.tsx +20 -0
  294. package/icons/pictograms/presentation.tsx +23 -0
  295. package/icons/pictograms/price-tag.tsx +21 -0
  296. package/icons/pictograms/printer.tsx +23 -0
  297. package/icons/pictograms/rain.tsx +23 -0
  298. package/icons/pictograms/receipt.tsx +25 -0
  299. package/icons/pictograms/remove.tsx +25 -0
  300. package/icons/pictograms/safety.tsx +23 -0
  301. package/icons/pictograms/screen.tsx +23 -0
  302. package/icons/pictograms/search.tsx +23 -0
  303. package/icons/pictograms/service.tsx +23 -0
  304. package/icons/pictograms/sewage.tsx +30 -0
  305. package/icons/pictograms/ship-outstanding.tsx +23 -0
  306. package/icons/pictograms/ship-transfer.tsx +23 -0
  307. package/icons/pictograms/shooting-stars.tsx +23 -0
  308. package/icons/pictograms/shore-excursions-old.tsx +23 -0
  309. package/icons/pictograms/shore-excursions.tsx +32 -0
  310. package/icons/pictograms/short-notice-departures.tsx +20 -0
  311. package/icons/pictograms/short-trips.tsx +21 -0
  312. package/icons/pictograms/size.tsx +23 -0
  313. package/icons/pictograms/smartphone.tsx +23 -0
  314. package/icons/pictograms/smiley.tsx +23 -0
  315. package/icons/pictograms/social-media.tsx +37 -0
  316. package/icons/pictograms/spa-balcony-cabin.tsx +43 -0
  317. package/icons/pictograms/speech-bubble-faq.tsx +23 -0
  318. package/icons/pictograms/speech-bubble-hello.tsx +23 -0
  319. package/icons/pictograms/speech-bubble-ok.tsx +30 -0
  320. package/icons/pictograms/speedboat.tsx +23 -0
  321. package/icons/pictograms/star-cancel.tsx +23 -0
  322. package/icons/pictograms/star-check.tsx +23 -0
  323. package/icons/pictograms/star-plus.tsx +23 -0
  324. package/icons/pictograms/star.tsx +23 -0
  325. package/icons/pictograms/sun-cloud.tsx +23 -0
  326. package/icons/pictograms/sun-lounger.tsx +23 -0
  327. package/icons/pictograms/sun.tsx +23 -0
  328. package/icons/pictograms/theater-mask.tsx +35 -0
  329. package/icons/pictograms/thermometer.tsx +23 -0
  330. package/icons/pictograms/tickets.tsx +21 -0
  331. package/icons/pictograms/towels.tsx +23 -0
  332. package/icons/pictograms/transportation.tsx +30 -0
  333. package/icons/pictograms/travel-protection-check.tsx +23 -0
  334. package/icons/pictograms/travel-protection.tsx +23 -0
  335. package/icons/pictograms/video.tsx +23 -0
  336. package/icons/pictograms/waste-management.tsx +30 -0
  337. package/icons/pictograms/webinar.tsx +23 -0
  338. package/icons/pictograms/wheel-of-fortune.tsx +23 -0
  339. package/icons/pictograms/wifi.tsx +20 -0
  340. package/icons/pictograms/wind.tsx +25 -0
  341. package/index.tsx +73 -0
  342. package/package.json +119 -0
  343. package/public/favicon-16x16.png +0 -0
  344. package/public/favicon-32x32.png +0 -0
  345. package/public/videos/placeholder.mp4 +0 -0
  346. package/src/assets/fonts/mein-schiff-sans-pro/MeinSchiffSansPro_It.ttf +0 -0
  347. package/src/assets/fonts/mein-schiff-sans-pro/MeinSchiffSansPro_It.woff +0 -0
  348. package/src/assets/fonts/mein-schiff-sans-pro/MeinSchiffSansPro_It.woff2 +0 -0
  349. package/src/assets/fonts/mein-schiff-sans-pro/MeinSchiffSansPro_Rg.ttf +0 -0
  350. package/src/assets/fonts/mein-schiff-sans-pro/MeinSchiffSansPro_Rg.woff +0 -0
  351. package/src/assets/fonts/mein-schiff-sans-pro/MeinSchiffSansPro_Rg.woff2 +0 -0
  352. package/src/assets/fonts/mein-schiff-sans-pro/MeinSchiffSansPro_SBd.ttf +0 -0
  353. package/src/assets/fonts/mein-schiff-sans-pro/MeinSchiffSansPro_SBd.woff +0 -0
  354. package/src/assets/fonts/mein-schiff-sans-pro/MeinSchiffSansPro_SBd.woff2 +0 -0
  355. package/src/assets/fonts/mein-schiff-sans-pro/MeinSchiffSansPro_SBdIt.ttf +0 -0
  356. package/src/assets/fonts/mein-schiff-sans-pro/MeinSchiffSansPro_SBdIt.woff +0 -0
  357. package/src/assets/fonts/mein-schiff-sans-pro/MeinSchiffSansPro_SBdIt.woff2 +0 -0
  358. package/src/assets/fonts/source-sans-pro/source-sans-pro-v21-latin-200.eot +0 -0
  359. package/src/assets/fonts/source-sans-pro/source-sans-pro-v21-latin-200.svg +338 -0
  360. package/src/assets/fonts/source-sans-pro/source-sans-pro-v21-latin-200.ttf +0 -0
  361. package/src/assets/fonts/source-sans-pro/source-sans-pro-v21-latin-200.woff +0 -0
  362. package/src/assets/fonts/source-sans-pro/source-sans-pro-v21-latin-200.woff2 +0 -0
  363. package/src/assets/fonts/source-sans-pro/source-sans-pro-v21-latin-200italic.eot +0 -0
  364. package/src/assets/fonts/source-sans-pro/source-sans-pro-v21-latin-200italic.svg +345 -0
  365. package/src/assets/fonts/source-sans-pro/source-sans-pro-v21-latin-200italic.ttf +0 -0
  366. package/src/assets/fonts/source-sans-pro/source-sans-pro-v21-latin-200italic.woff +0 -0
  367. package/src/assets/fonts/source-sans-pro/source-sans-pro-v21-latin-200italic.woff2 +0 -0
  368. package/src/assets/fonts/source-sans-pro/source-sans-pro-v21-latin-300.eot +0 -0
  369. package/src/assets/fonts/source-sans-pro/source-sans-pro-v21-latin-300.svg +338 -0
  370. package/src/assets/fonts/source-sans-pro/source-sans-pro-v21-latin-300.ttf +0 -0
  371. package/src/assets/fonts/source-sans-pro/source-sans-pro-v21-latin-300.woff +0 -0
  372. package/src/assets/fonts/source-sans-pro/source-sans-pro-v21-latin-300.woff2 +0 -0
  373. package/src/assets/fonts/source-sans-pro/source-sans-pro-v21-latin-300italic.eot +0 -0
  374. package/src/assets/fonts/source-sans-pro/source-sans-pro-v21-latin-300italic.svg +346 -0
  375. package/src/assets/fonts/source-sans-pro/source-sans-pro-v21-latin-300italic.ttf +0 -0
  376. package/src/assets/fonts/source-sans-pro/source-sans-pro-v21-latin-300italic.woff +0 -0
  377. package/src/assets/fonts/source-sans-pro/source-sans-pro-v21-latin-300italic.woff2 +0 -0
  378. package/src/assets/fonts/source-sans-pro/source-sans-pro-v21-latin-600.eot +0 -0
  379. package/src/assets/fonts/source-sans-pro/source-sans-pro-v21-latin-600.svg +337 -0
  380. package/src/assets/fonts/source-sans-pro/source-sans-pro-v21-latin-600.ttf +0 -0
  381. package/src/assets/fonts/source-sans-pro/source-sans-pro-v21-latin-600.woff +0 -0
  382. package/src/assets/fonts/source-sans-pro/source-sans-pro-v21-latin-600.woff2 +0 -0
  383. package/src/assets/fonts/source-sans-pro/source-sans-pro-v21-latin-600italic.eot +0 -0
  384. package/src/assets/fonts/source-sans-pro/source-sans-pro-v21-latin-600italic.svg +342 -0
  385. package/src/assets/fonts/source-sans-pro/source-sans-pro-v21-latin-600italic.ttf +0 -0
  386. package/src/assets/fonts/source-sans-pro/source-sans-pro-v21-latin-600italic.woff +0 -0
  387. package/src/assets/fonts/source-sans-pro/source-sans-pro-v21-latin-600italic.woff2 +0 -0
  388. package/src/assets/fonts/source-sans-pro/source-sans-pro-v21-latin-700.eot +0 -0
  389. package/src/assets/fonts/source-sans-pro/source-sans-pro-v21-latin-700.svg +337 -0
  390. package/src/assets/fonts/source-sans-pro/source-sans-pro-v21-latin-700.ttf +0 -0
  391. package/src/assets/fonts/source-sans-pro/source-sans-pro-v21-latin-700.woff +0 -0
  392. package/src/assets/fonts/source-sans-pro/source-sans-pro-v21-latin-700.woff2 +0 -0
  393. package/src/assets/fonts/source-sans-pro/source-sans-pro-v21-latin-700italic.eot +0 -0
  394. package/src/assets/fonts/source-sans-pro/source-sans-pro-v21-latin-700italic.svg +339 -0
  395. package/src/assets/fonts/source-sans-pro/source-sans-pro-v21-latin-700italic.ttf +0 -0
  396. package/src/assets/fonts/source-sans-pro/source-sans-pro-v21-latin-700italic.woff +0 -0
  397. package/src/assets/fonts/source-sans-pro/source-sans-pro-v21-latin-700italic.woff2 +0 -0
  398. package/src/assets/fonts/source-sans-pro/source-sans-pro-v21-latin-900.eot +0 -0
  399. package/src/assets/fonts/source-sans-pro/source-sans-pro-v21-latin-900.svg +337 -0
  400. package/src/assets/fonts/source-sans-pro/source-sans-pro-v21-latin-900.ttf +0 -0
  401. package/src/assets/fonts/source-sans-pro/source-sans-pro-v21-latin-900.woff +0 -0
  402. package/src/assets/fonts/source-sans-pro/source-sans-pro-v21-latin-900.woff2 +0 -0
  403. package/src/assets/fonts/source-sans-pro/source-sans-pro-v21-latin-900italic.eot +0 -0
  404. package/src/assets/fonts/source-sans-pro/source-sans-pro-v21-latin-900italic.svg +340 -0
  405. package/src/assets/fonts/source-sans-pro/source-sans-pro-v21-latin-900italic.ttf +0 -0
  406. package/src/assets/fonts/source-sans-pro/source-sans-pro-v21-latin-900italic.woff +0 -0
  407. package/src/assets/fonts/source-sans-pro/source-sans-pro-v21-latin-900italic.woff2 +0 -0
  408. package/src/assets/fonts/source-sans-pro/source-sans-pro-v21-latin-italic.eot +0 -0
  409. package/src/assets/fonts/source-sans-pro/source-sans-pro-v21-latin-italic.svg +343 -0
  410. package/src/assets/fonts/source-sans-pro/source-sans-pro-v21-latin-italic.ttf +0 -0
  411. package/src/assets/fonts/source-sans-pro/source-sans-pro-v21-latin-italic.woff +0 -0
  412. package/src/assets/fonts/source-sans-pro/source-sans-pro-v21-latin-italic.woff2 +0 -0
  413. package/src/assets/fonts/source-sans-pro/source-sans-pro-v21-latin-regular.eot +0 -0
  414. package/src/assets/fonts/source-sans-pro/source-sans-pro-v21-latin-regular.svg +337 -0
  415. package/src/assets/fonts/source-sans-pro/source-sans-pro-v21-latin-regular.ttf +0 -0
  416. package/src/assets/fonts/source-sans-pro/source-sans-pro-v21-latin-regular.woff +0 -0
  417. package/src/assets/fonts/source-sans-pro/source-sans-pro-v21-latin-regular.woff2 +0 -0
  418. package/src/assets/images/placeholder-blueish.jpg +0 -0
  419. package/src/assets/images/placeholder-sepia.jpg +0 -0
  420. package/src/assets/images/placeholder.jpg +0 -0
  421. package/src/components/core/Accordion/Accordion.tsx +228 -0
  422. package/src/components/core/Accordion/AccordionItem.tsx +72 -0
  423. package/src/components/core/Accordion/AccordionTab.tsx +39 -0
  424. package/src/components/core/Accordion/index.ts +3 -0
  425. package/src/components/core/Accordion/utils.tsx +13 -0
  426. package/src/components/core/Alert/Alert.tsx +131 -0
  427. package/src/components/core/Alert/index.ts +1 -0
  428. package/src/components/core/AlertDialog/AlertDialog.tsx +288 -0
  429. package/src/components/core/AlertDialog/index.ts +1 -0
  430. package/src/components/core/Badge/Badge.tsx +70 -0
  431. package/src/components/core/Badge/index.ts +1 -0
  432. package/src/components/core/BirthdateField/BirthdateField.tsx +269 -0
  433. package/src/components/core/BirthdateField/index.ts +1 -0
  434. package/src/components/core/Button/Button.tsx +178 -0
  435. package/src/components/core/Button/index.ts +1 -0
  436. package/src/components/core/ButtonGroup/ButtonGroup.tsx +71 -0
  437. package/src/components/core/ButtonGroup/index.ts +1 -0
  438. package/src/components/core/Calendar/Calendar.tsx +303 -0
  439. package/src/components/core/Calendar/index.ts +1 -0
  440. package/src/components/core/Checkbox/Checkbox.tsx +107 -0
  441. package/src/components/core/Checkbox/index.ts +1 -0
  442. package/src/components/core/CheckboxField/CheckboxField.tsx +156 -0
  443. package/src/components/core/CheckboxField/CheckboxFieldError.tsx +14 -0
  444. package/src/components/core/CheckboxField/CheckboxFieldLabel.tsx +25 -0
  445. package/src/components/core/CheckboxField/CheckboxFieldNote.tsx +16 -0
  446. package/src/components/core/CheckboxField/index.ts +1 -0
  447. package/src/components/core/Countdown/Countdown.tsx +67 -0
  448. package/src/components/core/Countdown/index.ts +1 -0
  449. package/src/components/core/DataTable/DataTable.tsx +98 -0
  450. package/src/components/core/DataTable/index.ts +1 -0
  451. package/src/components/core/Dialog/Dialog.tsx +443 -0
  452. package/src/components/core/Dialog/index.ts +1 -0
  453. package/src/components/core/Divider/Divider.tsx +37 -0
  454. package/src/components/core/Divider/index.ts +1 -0
  455. package/src/components/core/FavoriteButton/FavoriteButton.tsx +294 -0
  456. package/src/components/core/FavoriteButton/index.ts +1 -0
  457. package/src/components/core/Fieldset/Fieldset.tsx +42 -0
  458. package/src/components/core/Fieldset/index.ts +1 -0
  459. package/src/components/core/FormLabel/FormLabel.tsx +88 -0
  460. package/src/components/core/FormLabel/index.ts +1 -0
  461. package/src/components/core/Icon/Icon.tsx +106 -0
  462. package/src/components/core/Icon/index.ts +1 -0
  463. package/src/components/core/IconButton/IconButton.tsx +169 -0
  464. package/src/components/core/IconButton/index.ts +1 -0
  465. package/src/components/core/InputField/InputField.tsx +128 -0
  466. package/src/components/core/InputField/InputFieldError.tsx +17 -0
  467. package/src/components/core/InputField/InputFieldInput.tsx +67 -0
  468. package/src/components/core/InputField/InputFieldLabel.tsx +29 -0
  469. package/src/components/core/InputField/InputFieldNote.tsx +16 -0
  470. package/src/components/core/InputField/index.ts +1 -0
  471. package/src/components/core/LoadingSpinner/LoadingSpinner.tsx +50 -0
  472. package/src/components/core/LoadingSpinner/index.ts +1 -0
  473. package/src/components/core/Pagination/Pagination.tsx +191 -0
  474. package/src/components/core/Pagination/index.ts +1 -0
  475. package/src/components/core/PasswordField/PasswordField.tsx +187 -0
  476. package/src/components/core/PasswordField/PasswordFieldRequirementsList.tsx +78 -0
  477. package/src/components/core/PasswordField/index.ts +1 -0
  478. package/src/components/core/PhoneNumberInput/PhoneNumberInput.tsx +201 -0
  479. package/src/components/core/PhoneNumberInput/countries.json +242 -0
  480. package/src/components/core/PhoneNumberInput/index.ts +1 -0
  481. package/src/components/core/Pictogram/Pictogram.tsx +67 -0
  482. package/src/components/core/Pictogram/index.ts +1 -0
  483. package/src/components/core/Popover/Popover.tsx +61 -0
  484. package/src/components/core/Popover/index.ts +1 -0
  485. package/src/components/core/Portlist/Portlist.tsx +28 -0
  486. package/src/components/core/Portlist/index.ts +1 -0
  487. package/src/components/core/PriceInput/PriceInput.tsx +100 -0
  488. package/src/components/core/PriceInput/index.ts +1 -0
  489. package/src/components/core/QuantityItem/QuantityItem.tsx +37 -0
  490. package/src/components/core/QuantityItem/index.ts +1 -0
  491. package/src/components/core/Radio/Radio.tsx +64 -0
  492. package/src/components/core/Radio/index.ts +1 -0
  493. package/src/components/core/RadioField/RadioField.tsx +66 -0
  494. package/src/components/core/RadioField/index.ts +1 -0
  495. package/src/components/core/RadixRadio/RadixRadio.tsx +56 -0
  496. package/src/components/core/RadixRadio/index.ts +1 -0
  497. package/src/components/core/RadixSelect/RadixSelect.tsx +172 -0
  498. package/src/components/core/RadixSelect/index.ts +1 -0
  499. package/src/components/core/RangeSlider/RangeSlider.tsx +59 -0
  500. package/src/components/core/RangeSlider/index.ts +1 -0
  501. package/src/components/core/Section/Section.tsx +62 -0
  502. package/src/components/core/Section/index.ts +1 -0
  503. package/src/components/core/SegmentedControl/SegmentedControl.tsx +65 -0
  504. package/src/components/core/SegmentedControl/index.ts +1 -0
  505. package/src/components/core/Select/Select.tsx +171 -0
  506. package/src/components/core/Select/index.ts +1 -0
  507. package/src/components/core/SelectField/SelectField.tsx +67 -0
  508. package/src/components/core/SelectField/index.ts +1 -0
  509. package/src/components/core/Skeleton/Skeleton.tsx +23 -0
  510. package/src/components/core/Skeleton/SkeletonTextLines.tsx +37 -0
  511. package/src/components/core/Skeleton/index.ts +2 -0
  512. package/src/components/core/Stepper/Stepper.tsx +116 -0
  513. package/src/components/core/Stepper/index.ts +1 -0
  514. package/src/components/core/SwitchToggle/SwitchToggle.tsx +46 -0
  515. package/src/components/core/SwitchToggle/index.ts +1 -0
  516. package/src/components/core/Tabs/Tabs.tsx +130 -0
  517. package/src/components/core/Tabs/index.ts +1 -0
  518. package/src/components/core/Tag/Tag.tsx +61 -0
  519. package/src/components/core/Tag/index.ts +1 -0
  520. package/src/components/core/TextButton/TextButton.tsx +108 -0
  521. package/src/components/core/TextButton/index.ts +1 -0
  522. package/src/components/core/Toast/Toast.tsx +65 -0
  523. package/src/components/core/Toast/index.ts +1 -0
  524. package/src/components/core/Tooltip/Tooltip.tsx +110 -0
  525. package/src/components/core/Tooltip/index.ts +1 -0
  526. package/src/components/shared/NextFontMeinSchiffSansPro/NextFontMeinSchiffSansPro.tsx +160 -0
  527. package/src/components/shared/NextFontMeinSchiffSansPro/index.ts +1 -0
  528. package/src/components/shared/UniversalCarousel/CarouselContext.ts +61 -0
  529. package/src/components/shared/UniversalCarousel/CarouselDefaultPagination.tsx +92 -0
  530. package/src/components/shared/UniversalCarousel/CarouselInterface.tsx +152 -0
  531. package/src/components/shared/UniversalCarousel/CarouselStage.tsx +235 -0
  532. package/src/components/shared/UniversalCarousel/UniversalCarousel.tsx +125 -0
  533. package/src/components/shared/UniversalCarousel/helpers.ts +206 -0
  534. package/src/components/shared/UniversalCarousel/index.ts +4 -0
  535. package/src/helpers/children.ts +27 -0
  536. package/src/helpers/cookies.ts +22 -0
  537. package/src/helpers/dateFormat.ts +245 -0
  538. package/src/helpers/dateToYearMonthDay.ts +17 -0
  539. package/src/helpers/elementVisibility.ts +53 -0
  540. package/src/helpers/i18n.ts +197 -0
  541. package/src/helpers/price.ts +26 -0
  542. package/src/helpers/responsive-property.ts +118 -0
  543. package/src/helpers/screen.ts +14 -0
  544. package/src/helpers/sleep.ts +5 -0
  545. package/src/helpers/slot.tsx +68 -0
  546. package/src/helpers/ssr.ts +5 -0
  547. package/src/helpers/store.ts +75 -0
  548. package/src/helpers/types.ts +18 -0
  549. package/src/helpers/utils.ts +3 -0
  550. package/src/hooks/use-active-screen-names.ts +100 -0
  551. package/src/hooks/use-intersection-observer.ts +190 -0
  552. package/src/hooks/use-screen-name-at-least.ts +32 -0
  553. package/src/hooks/use-screen-name.ts +34 -0
  554. package/src/hooks/use-store.ts +45 -0
  555. package/src/hooks/use-toasts.ts +111 -0
  556. package/src/stores/toasts-store.ts +11 -0
@@ -0,0 +1,61 @@
1
+ import { createContext, Dispatch, SetStateAction } from 'react';
2
+ import { ScrollToIndex } from './CarouselInterface';
3
+
4
+ export type TCarouselContext = {
5
+ /**
6
+ * Indicates if the carousel is currently enabled.
7
+ */
8
+ enabled: boolean;
9
+
10
+ /**
11
+ * The indexes of the items that are currently fully visible.
12
+ */
13
+ visibleIndexes: number[];
14
+
15
+ /**
16
+ * The number of currently fully visible items.
17
+ */
18
+ visibleItems: number;
19
+
20
+ /**
21
+ * The index of the last item.
22
+ */
23
+ lastIndex: number;
24
+
25
+ /**
26
+ * The number of pixels the stage is scrolled.
27
+ */
28
+ stageScrollLeft: number;
29
+
30
+ /**
31
+ * The amount of pixels the stage would require to be rendered without a scrollbar -- its "width".
32
+ */
33
+ stageScrollWidth: number;
34
+
35
+ /**
36
+ * The current width of the stage -- its "width" as visible to the user.
37
+ */
38
+ stageWidth: number;
39
+
40
+ scrollToIndex: ScrollToIndex;
41
+
42
+ /**
43
+ * A setter for the context.
44
+ */
45
+ set: Dispatch<SetStateAction<TCarouselContext>>;
46
+ };
47
+
48
+ /**
49
+ * A context that provides information about the current state of the carousel, a helper function to scroll to a specific index and a setter for the context itself.
50
+ */
51
+ export const CarouselContext = createContext<TCarouselContext>({
52
+ enabled: false,
53
+ visibleIndexes: [0],
54
+ visibleItems: 0,
55
+ lastIndex: 0,
56
+ scrollToIndex: () => {},
57
+ stageScrollLeft: 0,
58
+ stageScrollWidth: 0,
59
+ stageWidth: 0,
60
+ set: () => {},
61
+ });
@@ -0,0 +1,92 @@
1
+ 'use client';
2
+
3
+ import type { FC, HTMLAttributes } from 'react';
4
+ import { twMerge } from '@tuic/tailwind-config';
5
+ import { CarouselInterface } from './CarouselInterface';
6
+ import { Pagination, PaginationProps } from '../../core/Pagination';
7
+
8
+ export type CarouselDefaultPaginationProps = Omit<
9
+ HTMLAttributes<HTMLElement>,
10
+ 'children'
11
+ > & {
12
+ i18n?: PaginationProps['i18n'];
13
+ className?: string;
14
+ };
15
+
16
+ /**
17
+ * Render the default carousel pagination in your carousel.
18
+ *
19
+ * > ⚠️ Important: This component is designed to function exclusively as a descendant of the `Carousel` component.
20
+ *
21
+ * ```tsx
22
+ * <UniversalCarousel>
23
+ * <CarouselStage>
24
+ * <Image src="..." className="aspect-4/3" />
25
+ * <Image src="..." className="aspect-4/3" />
26
+ * <Image src="..." className="aspect-4/3" />
27
+ * // Add as many items as needed ...
28
+ * </CarouselStage>
29
+ * <CarouselDefaultPagination />
30
+ * </UniversalCarousel>
31
+ * ```
32
+ */
33
+ export const CarouselDefaultPagination: FC<CarouselDefaultPaginationProps> = ({
34
+ ...attrs
35
+ }) => {
36
+ return (
37
+ <CarouselInterface>
38
+ {context => {
39
+ const {
40
+ visibleItems,
41
+ visibleIndexes,
42
+ lastIndex,
43
+ scrollToIndex,
44
+ stageWidth,
45
+ stageScrollWidth,
46
+ } = context;
47
+
48
+ if (stageScrollWidth <= stageWidth) {
49
+ return null; // No pagination needed if all items fit
50
+ }
51
+
52
+ const stepSize = visibleItems || 1; // Number of items per page
53
+ const totalPages = Math.ceil((lastIndex + 1) / stepSize); // Total number of pages
54
+ const firstVisibleIndex = Math.min(...visibleIndexes); // First currently visible item index
55
+ const lastVisibleIndex = Math.max(...visibleIndexes); // Last currently visible item index
56
+
57
+ // Calculate current page: Ensure correct page number on partial visibility
58
+ const currentPage = Math.ceil((lastVisibleIndex + 1) / stepSize);
59
+
60
+ // Boundaries for disabling prev/next buttons
61
+ const isPrevDisabled = firstVisibleIndex <= 0;
62
+ const isNextDisabled = lastVisibleIndex >= lastIndex;
63
+
64
+ const handlePrev = () => {
65
+ const targetIndex = Math.max(0, firstVisibleIndex - stepSize);
66
+ scrollToIndex(targetIndex, 'start');
67
+ };
68
+
69
+ const handleNext = () => {
70
+ const targetIndex = Math.min(
71
+ lastVisibleIndex + 1,
72
+ lastIndex - stepSize + 1,
73
+ );
74
+ scrollToIndex(targetIndex, 'start');
75
+ };
76
+
77
+ return (
78
+ <Pagination
79
+ {...attrs}
80
+ total={totalPages}
81
+ current={currentPage}
82
+ onPrevious={isPrevDisabled ? undefined : handlePrev}
83
+ onNext={isNextDisabled ? undefined : handleNext}
84
+ forcePreviousClickable={!isPrevDisabled}
85
+ forceNextClickable={!isNextDisabled}
86
+ className={twMerge('mt-8', attrs.className)}
87
+ />
88
+ );
89
+ }}
90
+ </CarouselInterface>
91
+ );
92
+ };
@@ -0,0 +1,152 @@
1
+ 'use client';
2
+
3
+ import type { FC, ReactNode } from 'react';
4
+ import { useCallback, useContext } from 'react';
5
+ import { CarouselContext } from './CarouselContext';
6
+
7
+ /**
8
+ * Scrolls the carousel to a specified index with customizable position and behavior.
9
+ *
10
+ * @param idx - The target index. Out of bounds values are wrapped around.
11
+ * @param position - The target item position: `'start'`, `'center'`, or `'end'`.
12
+ * @param scrollBehavior - The scroll behavior: `'auto'`, `'smooth'`, or `'instant'`.
13
+ */
14
+ export type ScrollToIndex = (
15
+ idx: number,
16
+ position: 'start' | 'center' | 'end',
17
+ scrollBehavior?: 'auto' | 'smooth' | 'instant',
18
+ ) => void;
19
+
20
+ export type CarouselInterfaceContext = {
21
+ /**
22
+ * Indicates if the carousel is currently
23
+ */
24
+ enabled: boolean;
25
+
26
+ /**
27
+ * An array of indexes of the currently fully visible items.
28
+ */
29
+ visibleIndexes: number[];
30
+
31
+ /**
32
+ * The number of currently fully visible items.
33
+ */
34
+ visibleItems: number;
35
+
36
+ /**
37
+ * The index of the last item.
38
+ * If you want to display the total number of items, you can use this value by adding 1.
39
+ */
40
+ lastIndex: number;
41
+
42
+ /**
43
+ * The number of pixels the stage is scrolled.
44
+ */
45
+ stageScrollLeft: number;
46
+
47
+ /**
48
+ * The amount of pixels the stage would require to be rendered without a scrollbar -- its "width".
49
+ */
50
+ stageScrollWidth: number;
51
+
52
+ /**
53
+ * The current width of the stage -- its "width" as visible to the user.
54
+ */
55
+ stageWidth: number;
56
+
57
+ scrollToIndex: ScrollToIndex;
58
+
59
+ /**
60
+ * A function that scrolls the carousel to the next item. The carousel loops to the first item, when invoked at the end of the carousel.
61
+ */
62
+ next: () => void;
63
+
64
+ /**
65
+ * A function that scrolls the carousel to the previous item. The carousel loops to the last item, when invoked at the start of the carousel.
66
+ */
67
+ prev: () => void;
68
+ };
69
+
70
+ type Props = {
71
+ children: (context: CarouselInterfaceContext) => ReactNode;
72
+ };
73
+
74
+ /**
75
+ * `CarouselInterface` acts as a comprehensive control and indicator system for the carousel, allowing for enhanced interaction and information display regarding the carousel's state.
76
+ *
77
+ * Utilize this component for various functionalities, including:
78
+ *
79
+ * - Showcasing the total number of items along with the position of the current item, for example, `Picture 1 of 5`.
80
+ * - Implementing navigational controls, such as previous and next buttons, for seamless navigation through carousel items.
81
+ * - Introducing visual indicators or "bullets" that represent the quantity of items and indicate the currently visible item.
82
+ * - Integrating sophisticated control logic using the `scrollToIndex` function, enabling direct navigation to any item within the carousel.
83
+ *
84
+ * > ⚠️ It's imperative to use this component as a direct descendant of the `Carousel` component to ensure proper functionality.
85
+ *
86
+ * Below is a practical example of how to integrate the `CarouselInterface` within the `Carousel` component:
87
+ *
88
+ * ```tsx
89
+ * <UniversalCarousel>
90
+ * <CarouselItems>
91
+ * ...
92
+ * </CarouselItems>
93
+ * <CarouselInterface>
94
+ * {(carouselContext) => {
95
+ * // Extracting properties from the carousel context
96
+ * const {visibleIndexes, lastIndex, prev, next} = carouselContext;
97
+ *
98
+ * // Constructing the carousel navigation interface
99
+ * return (
100
+ * <div>
101
+ * <button onClick={prev}>Previous</button>
102
+ *
103
+ * Picture {visibleIndexes[0] + 1} of {lastIndex + 1}
104
+ *
105
+ * <button onClick={next}>Next</button>
106
+ * </div>
107
+ * );
108
+ * }}
109
+ * </CarouselInterface>
110
+ * </UniversalCarousel>
111
+ * ```
112
+ *
113
+ * This code snippet illustrates a simple setup where users can navigate through items and view the current item's context within the carousel. Adjust the logic within `CarouselInterface` to suit specific use cases or UI requirements.
114
+ */
115
+ export const CarouselInterface: FC<Props> = ({ children }) => {
116
+ const {
117
+ enabled,
118
+ visibleIndexes,
119
+ visibleItems,
120
+ lastIndex,
121
+ scrollToIndex,
122
+ stageScrollLeft,
123
+ stageScrollWidth,
124
+ stageWidth,
125
+ } = useContext(CarouselContext);
126
+
127
+ const prev = useCallback(() => {
128
+ scrollToIndex(Math.min(...visibleIndexes) - 1, 'start');
129
+ }, [visibleIndexes, scrollToIndex]);
130
+
131
+ const next = useCallback(() => {
132
+ if (visibleIndexes.indexOf(lastIndex) > -1) {
133
+ scrollToIndex(0, 'start');
134
+ return;
135
+ }
136
+
137
+ scrollToIndex(Math.min(...visibleIndexes) + 1, 'start');
138
+ }, [visibleIndexes, lastIndex, scrollToIndex]);
139
+
140
+ return children({
141
+ enabled,
142
+ visibleIndexes,
143
+ visibleItems,
144
+ lastIndex,
145
+ scrollToIndex,
146
+ stageScrollLeft,
147
+ stageScrollWidth,
148
+ stageWidth,
149
+ prev,
150
+ next,
151
+ });
152
+ };
@@ -0,0 +1,235 @@
1
+ 'use client';
2
+
3
+ import {
4
+ FC,
5
+ HTMLAttributes,
6
+ MouseEventHandler,
7
+ ReactElement,
8
+ ReactNode,
9
+ useState,
10
+ } from 'react';
11
+ import { Children, useCallback, useContext, useEffect, useRef } from 'react';
12
+ import debounce from 'lodash/debounce';
13
+ import { twMerge } from '@tuic/tailwind-config';
14
+ import { CarouselContext } from './CarouselContext';
15
+ import {
16
+ combineEventHandlers,
17
+ createToIndexScroller,
18
+ getChildrenAsArrayOfElements,
19
+ getVisibleIndexes,
20
+ } from './helpers';
21
+ import { useMediaQuery } from '@tuic/lib/hooks/use-media-query';
22
+ import { useDraggableScroll } from '@tuic/lib/hooks/use-draggable-scroll';
23
+ import { useScreenName } from '../../../hooks/use-screen-name';
24
+ import { logger } from '@tuic/logger';
25
+
26
+ type Props = {
27
+ children: ReactNode;
28
+
29
+ /**
30
+ * Determines if carousel items can be dragged with a mouse. Defaults to false. On touch devices, dragging is enabled by default.
31
+ */
32
+ draggable?: boolean;
33
+
34
+ /**
35
+ * Props applied to each li element wrapping individual carousel items. Ideal for consistent styling or item spacing.
36
+ */
37
+ itemProps?: HTMLAttributes<HTMLLIElement>;
38
+ } & HTMLAttributes<HTMLUListElement>;
39
+
40
+ /**
41
+ * CarouselStage Component
42
+ *
43
+ * Encapsulates carousel items within a `ul` element, systematically wrapping each item in a `li`.
44
+ * Designed to be used exclusively within the `Carousel` component for smooth and customizable scrolling experiences.
45
+ *
46
+ * ### Example
47
+ * ```tsx
48
+ * <UniversalCarousel>
49
+ * <CarouselStage>
50
+ * <Image src="..." className="aspect-4/3" />
51
+ * <Image src="..." className="aspect-4/3" />
52
+ * <Image src="..." className="aspect-4/3" />
53
+ * </CarouselStage>
54
+ * </UniversalCarousel>
55
+ * ```
56
+ *
57
+ * ## Props
58
+ * - `draggable` (boolean): Enable or disable mouse dragging for the carousel. Defaults to `false`. On touch devices, dragging is always enabled.
59
+ * - `itemProps` (object): Props applied to each `li` element wrapping the carousel items, ideal for consistent styling or spacing.
60
+ *
61
+ * ### Adjusting Item Width
62
+ * Use the `carousel-item-w-*` utilities to set the width of carousel items.
63
+ * Items with width set as percentages (e.g., `w-1/3`, `w-[50%]`) automatically account for gaps specified by the `carousel-stage-gap` utility.
64
+ *
65
+ * ```tsx
66
+ * <CarouselStage itemProps={{ className: 'carousel-item-w-1/2' }} />
67
+ * // Sets each item's width to 50% of the carousel width.
68
+ *
69
+ * <CarouselStage itemProps={{ className: 'carousel-item-w-[80%]' }} />
70
+ * // Each item occupies 80% of the width, partially exposing the next item.
71
+ * ```
72
+ *
73
+ * ### Managing Spacing Between Items
74
+ *
75
+ * - **Single Visible Item**: Use `margin` utilities to add space between elements.
76
+ * ```tsx
77
+ * <CarouselStage itemProps={{ className: 'mr-2 last:mr-0' }} />
78
+ * ```
79
+ *
80
+ * - **Multiple Visible Items**: Use `carousel-stage-gap` utilities to add gaps. These gaps are automatically considered when using `carousel-item-w`.
81
+ * ```tsx
82
+ * <CarouselStage className="carousel-stage-gap-2" itemProps={{ className: 'carousel-item-w-1/3' }} />
83
+ * ```
84
+ */
85
+ export const CarouselStage: FC<Props> = ({
86
+ children,
87
+ draggable = true,
88
+ className: propClassName,
89
+ onScroll: propOnScroll,
90
+ onMouseDown: propOnMouseDown,
91
+ itemProps,
92
+ ...rest
93
+ }) => {
94
+ const { set: setContextValue, enabled } = useContext(CarouselContext);
95
+ const ref = useRef<HTMLUListElement>(null);
96
+ const screenName = useScreenName();
97
+
98
+ const [dragging, setDragging] = useState<boolean>(false);
99
+ const [preventClick, setPreventClick] = useState<boolean>(false);
100
+ const dragStartPosition = useRef<{ x: number; y: number }>({ x: 0, y: 0 });
101
+
102
+ // Create a debounced function that updates the current index.
103
+ const updateCurrentIndexDebounced = useRef(
104
+ debounce(() => {
105
+ setContextValue(prev => ({
106
+ ...prev,
107
+ visibleIndexes: getVisibleIndexes(ref),
108
+ stageScrollLeft: ref.current?.scrollLeft ?? 0,
109
+ stageScrollWidth: ref.current?.scrollWidth ?? 0,
110
+ stageWidth: ref.current?.offsetWidth ?? 0,
111
+ }));
112
+ }, 100),
113
+ );
114
+
115
+ // Set up the draggable scroll on desktop devices with a fine pointer (a mouse).
116
+ const hasFinePointer = useMediaQuery('pointer: fine');
117
+ const isDraggable = enabled && draggable && hasFinePointer;
118
+
119
+ const { onMouseDown: onMouseDownDraggable, onScroll: onScrollDraggable } =
120
+ useDraggableScroll(ref, {
121
+ direction: 'horizontal',
122
+ enabled: isDraggable,
123
+ onDragStart: ev => {
124
+ setPreventClick(false);
125
+ dragStartPosition.current = { x: ev.clientX, y: ev.clientY };
126
+ },
127
+ onDrag: (dx, dy) => {
128
+ const distanceMoved = Math.hypot(dx, dy); // Use dx and dy
129
+ if (distanceMoved > 5) {
130
+ setPreventClick(true); // Suppress clicks if drag movement exceeds 5px
131
+ }
132
+ },
133
+ onDragEnd: () => {
134
+ updateCurrentIndexDebounced.current();
135
+
136
+ // Conditionally set scroll-snap-type only if it's not already 'x mandatory'
137
+ ref.current?.style.setProperty('scroll-snap-type', 'x mandatory');
138
+
139
+ // Reset preventClick after a short delay
140
+ setTimeout(() => setPreventClick(false), 100);
141
+ },
142
+ });
143
+
144
+ // Get the children as an array of (react) elements.
145
+ let childrenAsArray: ReturnType<typeof getChildrenAsArrayOfElements> = [];
146
+ try {
147
+ childrenAsArray = getChildrenAsArrayOfElements(children);
148
+ } catch (error) {
149
+ if (process.env.NODE_ENV !== 'production') {
150
+ throw error;
151
+ }
152
+ logger.warn('[CarouselStage] Could not resolve react children', children);
153
+ }
154
+ const childrenCount = childrenAsArray.length;
155
+
156
+ // Merge the classNames of the wrapping list.
157
+ const containerClassName = twMerge(
158
+ enabled && 'snap-x snap-mandatory',
159
+ propClassName,
160
+ enabled && 'relative flex overflow-x-auto scrollbar-hidden',
161
+ );
162
+
163
+ // Merge the classNames of the list items.
164
+ const itemClassName = twMerge(
165
+ enabled && 'carousel-item-w-full',
166
+ enabled && !itemProps?.className?.includes('snap-') && 'snap-start',
167
+ itemProps?.className,
168
+ enabled && 'shrink-0',
169
+ dragging && 'pointer-events-none',
170
+ );
171
+
172
+ // Update the context value when the children change.
173
+ useEffect(() => {
174
+ const visibleIndexes = getVisibleIndexes(ref);
175
+ const scrollToIndex = createToIndexScroller(ref, childrenCount - 1);
176
+
177
+ setContextValue(prev => ({
178
+ ...prev,
179
+ lastIndex: childrenCount - 1,
180
+ visibleIndexes,
181
+ visibleItems: visibleIndexes.length,
182
+ scrollToIndex,
183
+ stageWidth: ref.current?.offsetWidth ?? 0,
184
+ stageScrollWidth: ref.current?.scrollWidth ?? 0,
185
+ }));
186
+
187
+ // Scroll to the first item on mount or children change
188
+ scrollToIndex(0, 'start', 'instant');
189
+ }, [enabled, childrenCount, setContextValue, screenName]);
190
+
191
+ // Combine the event handlers which are required for the draggable scroll.
192
+ const handleMouseDown = useCallback<MouseEventHandler<HTMLUListElement>>(
193
+ ev => {
194
+ combineEventHandlers([onMouseDownDraggable, propOnMouseDown])(ev);
195
+ },
196
+ [onMouseDownDraggable, propOnMouseDown],
197
+ );
198
+
199
+ const handleScroll = useCallback<MouseEventHandler<HTMLUListElement>>(
200
+ ev => {
201
+ combineEventHandlers([
202
+ onScrollDraggable,
203
+ updateCurrentIndexDebounced.current,
204
+ propOnScroll,
205
+ ])(ev);
206
+ },
207
+ [onScrollDraggable, propOnScroll],
208
+ );
209
+
210
+ return (
211
+ <ul
212
+ {...rest}
213
+ className={containerClassName}
214
+ ref={ref}
215
+ onMouseDown={handleMouseDown}
216
+ onScroll={handleScroll}
217
+ >
218
+ {Children.map<ReactNode, ReactElement>(childrenAsArray, (child, idx) => (
219
+ <li
220
+ {...itemProps}
221
+ key={child.key ?? idx}
222
+ className={itemClassName}
223
+ onClick={ev => {
224
+ if (preventClick) {
225
+ ev.preventDefault(); // Suppress the click if a drag occurred
226
+ return;
227
+ }
228
+ }}
229
+ >
230
+ {child}
231
+ </li>
232
+ ))}
233
+ </ul>
234
+ );
235
+ };
@@ -0,0 +1,125 @@
1
+ 'use client';
2
+
3
+ import { FC, ReactNode, useEffect, useRef } from 'react';
4
+ import { useState } from 'react';
5
+ import { CarouselContext, TCarouselContext } from './CarouselContext';
6
+ import {
7
+ getResponsiveValue,
8
+ ResponsiveValue,
9
+ } from '../../../helpers/responsive-property';
10
+ import { useScreenName } from '../../../hooks/use-screen-name';
11
+
12
+ type Props = {
13
+ enabled?: ResponsiveValue<boolean>;
14
+ children?: ReactNode;
15
+ initialIndex?: number;
16
+ };
17
+
18
+ /**
19
+ * The UniversalCarousel component provides a flexible and easily customizable UI element that's perfect for showcasing a collection of items that users can scroll through horizontally. The component is comprised of three main elements:
20
+ *
21
+ * 1. **`UniversalCarousel`**: The main component that creates the context for the carousel.
22
+ * 2. **`CarouselStage`**: A wrapper for the items within the carousel. It handles the layout and the scroll behavior of the carousel items.
23
+ * 3. **`CarouselInterface`**: An optional component that provides control mechanisms (like next and previous buttons) and indicators (like current position).
24
+ *
25
+ * Here's a basic example of how to use the `UniversalCarousel` component:
26
+ *
27
+ * ```tsx *
28
+ * <UniversalCarousel>
29
+ * <CarouselStage>
30
+ * <img src="..." alt="" />
31
+ * <img src="..." alt="" />
32
+ * <img src="..." alt="" />
33
+ * ...
34
+ * </CarouselStage>
35
+ * <CarouselInterface>
36
+ * {({ prev, next }) => (
37
+ * <>
38
+ * <button onClick={prev}>Previous</button>
39
+ * <button onClick={next}>Next</button>
40
+ * </>
41
+ * )}
42
+ * </CarouselInterface>
43
+ * </UniversalCarousel>
44
+ * ```
45
+ *
46
+ * ## Components
47
+ *
48
+ * ### UniversalCarousel
49
+ *
50
+ * The `UniversalCarousel` component sets up the context for the carousel and its items. It doesn't render any DOM elements by itself but provides the scaffolding necessary for the `CarouselStage` and `CarouselInterface`.
51
+ *
52
+ * #### Props
53
+ *
54
+ * - `children`: The elements to be displayed within the carousel. These are usually a combination of `CarouselStage`, `CarouselInterface` and other custom elements you need.
55
+ *
56
+ * ### CarouselStage
57
+ *
58
+ * `CarouselStage` is where the carousel items are housed. It is a `ul` element that renders each child as an `li`, ensuring proper semantics and accessibility.
59
+ *
60
+ * > 👉 Review the **Carousel Stage** documentation to learn more and view usage examples.
61
+ *
62
+ * ### CarouselInterface
63
+ *
64
+ * `CarouselInterface` is an optional component that exposes controls like "next" and "previous" buttons and indicators like the current position within the carousel.
65
+ *
66
+ * > 👉 Review the **Carousel Interface** documentation to learn more and view usage examples.
67
+ *
68
+ * ## Accessibility
69
+ *
70
+ * While the UniversalCarousel component has been designed with accessibility in mind, it's important to ensure that any custom controls or additional UI elements you add are also accessible. This includes proper use of ARIA attributes, ensuring keyboard navigation is possible, when feasable, and providing alternative text for images.
71
+ */
72
+ export const UniversalCarousel: FC<Props> = ({
73
+ enabled: enabledArg,
74
+ children,
75
+ initialIndex = 0,
76
+ }) => {
77
+ let screenName = useScreenName();
78
+ let enabled = getResponsiveValue(enabledArg, true, screenName);
79
+
80
+ const [contextValue, setContextValue] = useState<TCarouselContext>({
81
+ enabled,
82
+ visibleItems: 0,
83
+ visibleIndexes: [initialIndex],
84
+ lastIndex: 0,
85
+ stageScrollLeft: 0,
86
+ stageScrollWidth: 0,
87
+ stageWidth: 0,
88
+ scrollToIndex: (idx, position) => {},
89
+ set: () => {},
90
+ });
91
+
92
+ const isInitialized = useRef(false);
93
+
94
+ // Scroll to the initial index when the carousel is first rendered.
95
+ useEffect(() => {
96
+ if (
97
+ !isInitialized.current &&
98
+ contextValue.scrollToIndex &&
99
+ initialIndex > 0
100
+ ) {
101
+ const timer = setTimeout(() => {
102
+ contextValue.scrollToIndex(initialIndex, 'start', 'instant');
103
+ isInitialized.current = true;
104
+ }, 0);
105
+ return () => clearTimeout(timer);
106
+ }
107
+ }, [initialIndex, contextValue.scrollToIndex, contextValue]);
108
+
109
+ useEffect(() => {
110
+ if (contextValue.enabled === enabled) {
111
+ return;
112
+ }
113
+
114
+ setContextValue(prev => ({
115
+ ...prev,
116
+ enabled,
117
+ }));
118
+ }, [contextValue.enabled, enabled, setContextValue]);
119
+
120
+ return (
121
+ <CarouselContext.Provider value={{ ...contextValue, set: setContextValue }}>
122
+ {children}
123
+ </CarouselContext.Provider>
124
+ );
125
+ };