@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.
- package/CHANGELOG.md +7 -0
- package/LICENSE +14 -0
- package/README.md +26 -0
- package/custom.d.ts +14 -0
- package/icons/icons/360.tsx +20 -0
- package/icons/icons/add-circle.tsx +26 -0
- package/icons/icons/airplane.tsx +20 -0
- package/icons/icons/anchor.tsx +20 -0
- package/icons/icons/angle-tool.tsx +26 -0
- package/icons/icons/arrow-down.tsx +20 -0
- package/icons/icons/arrow-left.tsx +20 -0
- package/icons/icons/arrow-right.tsx +20 -0
- package/icons/icons/at.tsx +20 -0
- package/icons/icons/baggage.tsx +20 -0
- package/icons/icons/balcony.tsx +20 -0
- package/icons/icons/bathroom.tsx +32 -0
- package/icons/icons/beach.tsx +20 -0
- package/icons/icons/bed.tsx +26 -0
- package/icons/icons/bell.tsx +20 -0
- package/icons/icons/bording.tsx +20 -0
- package/icons/icons/cabins.tsx +20 -0
- package/icons/icons/calendar.tsx +32 -0
- package/icons/icons/cancel.tsx +20 -0
- package/icons/icons/cash.tsx +44 -0
- package/icons/icons/check-circle.tsx +18 -0
- package/icons/icons/check.tsx +20 -0
- package/icons/icons/circle.tsx +20 -0
- package/icons/icons/clear.tsx +24 -0
- package/icons/icons/clock-rotate-right.tsx +20 -0
- package/icons/icons/clock.tsx +26 -0
- package/icons/icons/cloud-sunny.tsx +43 -0
- package/icons/icons/cloud.tsx +20 -0
- package/icons/icons/compass.tsx +26 -0
- package/icons/icons/delete-circle.tsx +26 -0
- package/icons/icons/departure.tsx +20 -0
- package/icons/icons/details.tsx +20 -0
- package/icons/icons/diamond.tsx +20 -0
- package/icons/icons/edit-pencil.tsx +20 -0
- package/icons/icons/excellence.tsx +20 -0
- package/icons/icons/expand.tsx +20 -0
- package/icons/icons/eye-closed.tsx +20 -0
- package/icons/icons/eye-empty.tsx +26 -0
- package/icons/icons/eye-off.tsx +32 -0
- package/icons/icons/eye.tsx +26 -0
- package/icons/icons/fallback.tsx +26 -0
- package/icons/icons/filter.tsx +20 -0
- package/icons/icons/flag.tsx +20 -0
- package/icons/icons/fog.tsx +22 -0
- package/icons/icons/glases.tsx +28 -0
- package/icons/icons/group.tsx +32 -0
- package/icons/icons/heart-filled.tsx +20 -0
- package/icons/icons/heart.tsx +20 -0
- package/icons/icons/help-circle.tsx +24 -0
- package/icons/icons/home.tsx +22 -0
- package/icons/icons/humidity.tsx +30 -0
- package/icons/icons/impressions.tsx +20 -0
- package/icons/icons/inclusive-services.tsx +20 -0
- package/icons/icons/index.ts +141 -0
- package/icons/icons/info-empty.tsx +26 -0
- package/icons/icons/language.tsx +20 -0
- package/icons/icons/lifebuoy.tsx +30 -0
- package/icons/icons/loading.tsx +18 -0
- package/icons/icons/location.tsx +24 -0
- package/icons/icons/log-in.tsx +26 -0
- package/icons/icons/log-out.tsx +26 -0
- package/icons/icons/mail-open.tsx +20 -0
- package/icons/icons/map.tsx +20 -0
- package/icons/icons/maps-arrow-diagonal.tsx +20 -0
- package/icons/icons/media-image-list.tsx +32 -0
- package/icons/icons/menu.tsx +21 -0
- package/icons/icons/metropolis.tsx +20 -0
- package/icons/icons/minus.tsx +20 -0
- package/icons/icons/more-horiz.tsx +35 -0
- package/icons/icons/more-vert.tsx +35 -0
- package/icons/icons/mostly-cloudy-night.tsx +24 -0
- package/icons/icons/ms-ship.tsx +20 -0
- package/icons/icons/music.tsx +20 -0
- package/icons/icons/nav-arrow-down.tsx +20 -0
- package/icons/icons/nav-arrow-left.tsx +20 -0
- package/icons/icons/nav-arrow-right.tsx +20 -0
- package/icons/icons/nav-arrow-up.tsx +20 -0
- package/icons/icons/no-wifi.tsx +18 -0
- package/icons/icons/old-trips.tsx +20 -0
- package/icons/icons/percentage.tsx +20 -0
- package/icons/icons/phone.tsx +20 -0
- package/icons/icons/pin.tsx +20 -0
- package/icons/icons/play.tsx +20 -0
- package/icons/icons/plus-circle.tsx +20 -0
- package/icons/icons/plus.tsx +20 -0
- package/icons/icons/point.tsx +15 -0
- package/icons/icons/rain.tsx +22 -0
- package/icons/icons/receipt.tsx +20 -0
- package/icons/icons/refresh-double.tsx +32 -0
- package/icons/icons/search.tsx +26 -0
- package/icons/icons/security-pass.tsx +26 -0
- package/icons/icons/settings.tsx +20 -0
- package/icons/icons/share-ios.tsx +26 -0
- package/icons/icons/ship-account.tsx +20 -0
- package/icons/icons/ship-info.tsx +20 -0
- package/icons/icons/ship-position.tsx +27 -0
- package/icons/icons/shooting-stars.tsx +28 -0
- package/icons/icons/sleet.tsx +22 -0
- package/icons/icons/snow-flake.tsx +20 -0
- package/icons/icons/snow.tsx +22 -0
- package/icons/icons/sofa.tsx +32 -0
- package/icons/icons/star-dashed.tsx +20 -0
- package/icons/icons/star-filled.tsx +25 -0
- package/icons/icons/star-half-dashed.tsx +26 -0
- package/icons/icons/star.tsx +20 -0
- package/icons/icons/substract.tsx +26 -0
- package/icons/icons/sun-light.tsx +42 -0
- package/icons/icons/temperature-high.tsx +26 -0
- package/icons/icons/thunderstorm.tsx +26 -0
- package/icons/icons/tornado.tsx +18 -0
- package/icons/icons/trash.tsx +20 -0
- package/icons/icons/travel-assistant.tsx +24 -0
- package/icons/icons/tropical-storm.tsx +71 -0
- package/icons/icons/upcoming-trips.tsx +27 -0
- package/icons/icons/user.tsx +26 -0
- package/icons/icons/warning-circle.tsx +26 -0
- package/icons/icons/warning-hexagon.tsx +26 -0
- package/icons/icons/weather.tsx +20 -0
- package/icons/icons/wifi.tsx +20 -0
- package/icons/icons/wind.tsx +22 -0
- package/icons/icons/windrose.tsx +42 -0
- package/icons/icons/windsock.tsx +20 -0
- package/icons/pictograms/24h-meals.tsx +25 -0
- package/icons/pictograms/ad-template.tsx +23 -0
- package/icons/pictograms/add.tsx +25 -0
- package/icons/pictograms/adventure-club-only.tsx +25 -0
- package/icons/pictograms/allergy.tsx +30 -0
- package/icons/pictograms/anchor.tsx +23 -0
- package/icons/pictograms/arrival.tsx +23 -0
- package/icons/pictograms/baby-awake.tsx +20 -0
- package/icons/pictograms/baby-monitor.tsx +20 -0
- package/icons/pictograms/baby-sleep.tsx +20 -0
- package/icons/pictograms/baggage-information.tsx +23 -0
- package/icons/pictograms/baggage.tsx +23 -0
- package/icons/pictograms/bedroom-check.tsx +23 -0
- package/icons/pictograms/bedroom.tsx +23 -0
- package/icons/pictograms/beverages.tsx +28 -0
- package/icons/pictograms/billboard.tsx +23 -0
- package/icons/pictograms/blog.tsx +23 -0
- package/icons/pictograms/brochure.tsx +23 -0
- package/icons/pictograms/calendar-check.tsx +18 -0
- package/icons/pictograms/calendar-default.tsx +18 -0
- package/icons/pictograms/calendar-disabled.tsx +18 -0
- package/icons/pictograms/calendar-focus.tsx +25 -0
- package/icons/pictograms/champagne-glasses.tsx +25 -0
- package/icons/pictograms/check.tsx +25 -0
- package/icons/pictograms/checklist-check.tsx +18 -0
- package/icons/pictograms/checklist.tsx +21 -0
- package/icons/pictograms/checkmark.tsx +23 -0
- package/icons/pictograms/chef-hat.tsx +30 -0
- package/icons/pictograms/chevron-down.tsx +25 -0
- package/icons/pictograms/chevron-up.tsx +25 -0
- package/icons/pictograms/circles.tsx +25 -0
- package/icons/pictograms/cleaning-trolley.tsx +30 -0
- package/icons/pictograms/clock-0-30.tsx +23 -0
- package/icons/pictograms/clock-0.tsx +23 -0
- package/icons/pictograms/clock-1-30.tsx +23 -0
- package/icons/pictograms/clock-1.tsx +23 -0
- package/icons/pictograms/clock-10-30.tsx +23 -0
- package/icons/pictograms/clock-10.tsx +23 -0
- package/icons/pictograms/clock-11-30.tsx +23 -0
- package/icons/pictograms/clock-11.tsx +23 -0
- package/icons/pictograms/clock-2-30.tsx +23 -0
- package/icons/pictograms/clock-2.tsx +23 -0
- package/icons/pictograms/clock-3-30.tsx +23 -0
- package/icons/pictograms/clock-3.tsx +23 -0
- package/icons/pictograms/clock-4-30.tsx +23 -0
- package/icons/pictograms/clock-4.tsx +23 -0
- package/icons/pictograms/clock-5-30.tsx +23 -0
- package/icons/pictograms/clock-5.tsx +23 -0
- package/icons/pictograms/clock-6-30.tsx +23 -0
- package/icons/pictograms/clock-6.tsx +23 -0
- package/icons/pictograms/clock-7-30.tsx +23 -0
- package/icons/pictograms/clock-7.tsx +23 -0
- package/icons/pictograms/clock-8-30.tsx +23 -0
- package/icons/pictograms/clock-8.tsx +23 -0
- package/icons/pictograms/clock-9-30.tsx +23 -0
- package/icons/pictograms/clock-9.tsx +23 -0
- package/icons/pictograms/clock-default.tsx +23 -0
- package/icons/pictograms/close.tsx +25 -0
- package/icons/pictograms/clothing.tsx +23 -0
- package/icons/pictograms/cloud.tsx +23 -0
- package/icons/pictograms/cocktails.tsx +23 -0
- package/icons/pictograms/coffee-machine.tsx +23 -0
- package/icons/pictograms/compass.tsx +23 -0
- package/icons/pictograms/couple.tsx +25 -0
- package/icons/pictograms/crew-love.tsx +28 -0
- package/icons/pictograms/crown.tsx +23 -0
- package/icons/pictograms/dart.tsx +23 -0
- package/icons/pictograms/decoration.tsx +23 -0
- package/icons/pictograms/departure-check.tsx +25 -0
- package/icons/pictograms/departure-germany.tsx +20 -0
- package/icons/pictograms/departure-time.tsx +35 -0
- package/icons/pictograms/departure.tsx +23 -0
- package/icons/pictograms/diamond.tsx +23 -0
- package/icons/pictograms/discount-card.tsx +35 -0
- package/icons/pictograms/discount.tsx +30 -0
- package/icons/pictograms/documents.tsx +23 -0
- package/icons/pictograms/download-document.tsx +23 -0
- package/icons/pictograms/download.tsx +23 -0
- package/icons/pictograms/dripping-dew.tsx +23 -0
- package/icons/pictograms/dumbbell.tsx +25 -0
- package/icons/pictograms/early-bird.tsx +23 -0
- package/icons/pictograms/edit.tsx +23 -0
- package/icons/pictograms/energy-saving.tsx +23 -0
- package/icons/pictograms/enjoyer-club-only.tsx +18 -0
- package/icons/pictograms/environment.tsx +30 -0
- package/icons/pictograms/environmental-officer.tsx +30 -0
- package/icons/pictograms/explorer-club-only.tsx +18 -0
- package/icons/pictograms/family.tsx +25 -0
- package/icons/pictograms/fb-community.tsx +25 -0
- package/icons/pictograms/finance.tsx +25 -0
- package/icons/pictograms/fog.tsx +25 -0
- package/icons/pictograms/food-certificate.tsx +30 -0
- package/icons/pictograms/gastronomy.tsx +25 -0
- package/icons/pictograms/gift.tsx +23 -0
- package/icons/pictograms/globetrotter-club-only.tsx +18 -0
- package/icons/pictograms/hairdresser.tsx +20 -0
- package/icons/pictograms/handbag.tsx +30 -0
- package/icons/pictograms/hands-holding-heart.tsx +30 -0
- package/icons/pictograms/heart-beat.tsx +29 -0
- package/icons/pictograms/heart.tsx +23 -0
- package/icons/pictograms/home.tsx +23 -0
- package/icons/pictograms/hospital-cross.tsx +23 -0
- package/icons/pictograms/hot-dish.tsx +23 -0
- package/icons/pictograms/hot-drink.tsx +25 -0
- package/icons/pictograms/human-heart.tsx +30 -0
- package/icons/pictograms/human-holding-heart.tsx +30 -0
- package/icons/pictograms/human-open-arms.tsx +23 -0
- package/icons/pictograms/human-profile.tsx +23 -0
- package/icons/pictograms/human-swimming.tsx +25 -0
- package/icons/pictograms/ice-cream.tsx +23 -0
- package/icons/pictograms/important.tsx +23 -0
- package/icons/pictograms/index.ts +285 -0
- package/icons/pictograms/information.tsx +30 -0
- package/icons/pictograms/internet.tsx +23 -0
- package/icons/pictograms/jogging.tsx +21 -0
- package/icons/pictograms/kid-playing.tsx +23 -0
- package/icons/pictograms/life-jacket.tsx +21 -0
- package/icons/pictograms/lifebuoy.tsx +20 -0
- package/icons/pictograms/lightbulb.tsx +23 -0
- package/icons/pictograms/lightning.tsx +23 -0
- package/icons/pictograms/location-mark.tsx +30 -0
- package/icons/pictograms/log-in.tsx +23 -0
- package/icons/pictograms/long-term-trips.tsx +20 -0
- package/icons/pictograms/lotte-chatbot.tsx +28 -0
- package/icons/pictograms/lotte-mail.tsx +28 -0
- package/icons/pictograms/mail-at.tsx +23 -0
- package/icons/pictograms/mail-information.tsx +23 -0
- package/icons/pictograms/mailbox.tsx +23 -0
- package/icons/pictograms/many-sea-days.tsx +20 -0
- package/icons/pictograms/medal.tsx +23 -0
- package/icons/pictograms/microphone.tsx +23 -0
- package/icons/pictograms/ms-1.tsx +23 -0
- package/icons/pictograms/ms-2.tsx +30 -0
- package/icons/pictograms/ms-3.tsx +30 -0
- package/icons/pictograms/ms-4.tsx +30 -0
- package/icons/pictograms/ms-5.tsx +30 -0
- package/icons/pictograms/ms-6.tsx +30 -0
- package/icons/pictograms/ms-7-new-eng.tsx +37 -0
- package/icons/pictograms/ms-7-new.tsx +30 -0
- package/icons/pictograms/ms-7.tsx +30 -0
- package/icons/pictograms/ms-default.tsx +30 -0
- package/icons/pictograms/ms-flow-new-eng.tsx +37 -0
- package/icons/pictograms/ms-flow-new.tsx +49 -0
- package/icons/pictograms/ms-flow.tsx +41 -0
- package/icons/pictograms/ms-relax-new-eng.tsx +37 -0
- package/icons/pictograms/ms-relax-new.tsx +36 -0
- package/icons/pictograms/ms-ship.tsx +23 -0
- package/icons/pictograms/music-book.tsx +23 -0
- package/icons/pictograms/my-account.tsx +22 -0
- package/icons/pictograms/my-trips.tsx +29 -0
- package/icons/pictograms/navigation-arrow.tsx +23 -0
- package/icons/pictograms/no-wifi.tsx +21 -0
- package/icons/pictograms/not-available.tsx +23 -0
- package/icons/pictograms/offer.tsx +23 -0
- package/icons/pictograms/offline.tsx +25 -0
- package/icons/pictograms/onboard-announcement.tsx +20 -0
- package/icons/pictograms/package-newspaper.tsx +27 -0
- package/icons/pictograms/paper-news.tsx +23 -0
- package/icons/pictograms/paper-plane.tsx +28 -0
- package/icons/pictograms/payment-check.tsx +32 -0
- package/icons/pictograms/payment.tsx +28 -0
- package/icons/pictograms/people-check.tsx +25 -0
- package/icons/pictograms/people.tsx +25 -0
- package/icons/pictograms/permanent-make-up.tsx +20 -0
- package/icons/pictograms/person-single.tsx +23 -0
- package/icons/pictograms/phone.tsx +20 -0
- package/icons/pictograms/play-button.tsx +20 -0
- package/icons/pictograms/presentation.tsx +23 -0
- package/icons/pictograms/price-tag.tsx +21 -0
- package/icons/pictograms/printer.tsx +23 -0
- package/icons/pictograms/rain.tsx +23 -0
- package/icons/pictograms/receipt.tsx +25 -0
- package/icons/pictograms/remove.tsx +25 -0
- package/icons/pictograms/safety.tsx +23 -0
- package/icons/pictograms/screen.tsx +23 -0
- package/icons/pictograms/search.tsx +23 -0
- package/icons/pictograms/service.tsx +23 -0
- package/icons/pictograms/sewage.tsx +30 -0
- package/icons/pictograms/ship-outstanding.tsx +23 -0
- package/icons/pictograms/ship-transfer.tsx +23 -0
- package/icons/pictograms/shooting-stars.tsx +23 -0
- package/icons/pictograms/shore-excursions-old.tsx +23 -0
- package/icons/pictograms/shore-excursions.tsx +32 -0
- package/icons/pictograms/short-notice-departures.tsx +20 -0
- package/icons/pictograms/short-trips.tsx +21 -0
- package/icons/pictograms/size.tsx +23 -0
- package/icons/pictograms/smartphone.tsx +23 -0
- package/icons/pictograms/smiley.tsx +23 -0
- package/icons/pictograms/social-media.tsx +37 -0
- package/icons/pictograms/spa-balcony-cabin.tsx +43 -0
- package/icons/pictograms/speech-bubble-faq.tsx +23 -0
- package/icons/pictograms/speech-bubble-hello.tsx +23 -0
- package/icons/pictograms/speech-bubble-ok.tsx +30 -0
- package/icons/pictograms/speedboat.tsx +23 -0
- package/icons/pictograms/star-cancel.tsx +23 -0
- package/icons/pictograms/star-check.tsx +23 -0
- package/icons/pictograms/star-plus.tsx +23 -0
- package/icons/pictograms/star.tsx +23 -0
- package/icons/pictograms/sun-cloud.tsx +23 -0
- package/icons/pictograms/sun-lounger.tsx +23 -0
- package/icons/pictograms/sun.tsx +23 -0
- package/icons/pictograms/theater-mask.tsx +35 -0
- package/icons/pictograms/thermometer.tsx +23 -0
- package/icons/pictograms/tickets.tsx +21 -0
- package/icons/pictograms/towels.tsx +23 -0
- package/icons/pictograms/transportation.tsx +30 -0
- package/icons/pictograms/travel-protection-check.tsx +23 -0
- package/icons/pictograms/travel-protection.tsx +23 -0
- package/icons/pictograms/video.tsx +23 -0
- package/icons/pictograms/waste-management.tsx +30 -0
- package/icons/pictograms/webinar.tsx +23 -0
- package/icons/pictograms/wheel-of-fortune.tsx +23 -0
- package/icons/pictograms/wifi.tsx +20 -0
- package/icons/pictograms/wind.tsx +25 -0
- package/index.tsx +73 -0
- package/package.json +119 -0
- package/public/favicon-16x16.png +0 -0
- package/public/favicon-32x32.png +0 -0
- package/public/videos/placeholder.mp4 +0 -0
- package/src/assets/fonts/mein-schiff-sans-pro/MeinSchiffSansPro_It.ttf +0 -0
- package/src/assets/fonts/mein-schiff-sans-pro/MeinSchiffSansPro_It.woff +0 -0
- package/src/assets/fonts/mein-schiff-sans-pro/MeinSchiffSansPro_It.woff2 +0 -0
- package/src/assets/fonts/mein-schiff-sans-pro/MeinSchiffSansPro_Rg.ttf +0 -0
- package/src/assets/fonts/mein-schiff-sans-pro/MeinSchiffSansPro_Rg.woff +0 -0
- package/src/assets/fonts/mein-schiff-sans-pro/MeinSchiffSansPro_Rg.woff2 +0 -0
- package/src/assets/fonts/mein-schiff-sans-pro/MeinSchiffSansPro_SBd.ttf +0 -0
- package/src/assets/fonts/mein-schiff-sans-pro/MeinSchiffSansPro_SBd.woff +0 -0
- package/src/assets/fonts/mein-schiff-sans-pro/MeinSchiffSansPro_SBd.woff2 +0 -0
- package/src/assets/fonts/mein-schiff-sans-pro/MeinSchiffSansPro_SBdIt.ttf +0 -0
- package/src/assets/fonts/mein-schiff-sans-pro/MeinSchiffSansPro_SBdIt.woff +0 -0
- package/src/assets/fonts/mein-schiff-sans-pro/MeinSchiffSansPro_SBdIt.woff2 +0 -0
- package/src/assets/fonts/source-sans-pro/source-sans-pro-v21-latin-200.eot +0 -0
- package/src/assets/fonts/source-sans-pro/source-sans-pro-v21-latin-200.svg +338 -0
- package/src/assets/fonts/source-sans-pro/source-sans-pro-v21-latin-200.ttf +0 -0
- package/src/assets/fonts/source-sans-pro/source-sans-pro-v21-latin-200.woff +0 -0
- package/src/assets/fonts/source-sans-pro/source-sans-pro-v21-latin-200.woff2 +0 -0
- package/src/assets/fonts/source-sans-pro/source-sans-pro-v21-latin-200italic.eot +0 -0
- package/src/assets/fonts/source-sans-pro/source-sans-pro-v21-latin-200italic.svg +345 -0
- package/src/assets/fonts/source-sans-pro/source-sans-pro-v21-latin-200italic.ttf +0 -0
- package/src/assets/fonts/source-sans-pro/source-sans-pro-v21-latin-200italic.woff +0 -0
- package/src/assets/fonts/source-sans-pro/source-sans-pro-v21-latin-200italic.woff2 +0 -0
- package/src/assets/fonts/source-sans-pro/source-sans-pro-v21-latin-300.eot +0 -0
- package/src/assets/fonts/source-sans-pro/source-sans-pro-v21-latin-300.svg +338 -0
- package/src/assets/fonts/source-sans-pro/source-sans-pro-v21-latin-300.ttf +0 -0
- package/src/assets/fonts/source-sans-pro/source-sans-pro-v21-latin-300.woff +0 -0
- package/src/assets/fonts/source-sans-pro/source-sans-pro-v21-latin-300.woff2 +0 -0
- package/src/assets/fonts/source-sans-pro/source-sans-pro-v21-latin-300italic.eot +0 -0
- package/src/assets/fonts/source-sans-pro/source-sans-pro-v21-latin-300italic.svg +346 -0
- package/src/assets/fonts/source-sans-pro/source-sans-pro-v21-latin-300italic.ttf +0 -0
- package/src/assets/fonts/source-sans-pro/source-sans-pro-v21-latin-300italic.woff +0 -0
- package/src/assets/fonts/source-sans-pro/source-sans-pro-v21-latin-300italic.woff2 +0 -0
- package/src/assets/fonts/source-sans-pro/source-sans-pro-v21-latin-600.eot +0 -0
- package/src/assets/fonts/source-sans-pro/source-sans-pro-v21-latin-600.svg +337 -0
- package/src/assets/fonts/source-sans-pro/source-sans-pro-v21-latin-600.ttf +0 -0
- package/src/assets/fonts/source-sans-pro/source-sans-pro-v21-latin-600.woff +0 -0
- package/src/assets/fonts/source-sans-pro/source-sans-pro-v21-latin-600.woff2 +0 -0
- package/src/assets/fonts/source-sans-pro/source-sans-pro-v21-latin-600italic.eot +0 -0
- package/src/assets/fonts/source-sans-pro/source-sans-pro-v21-latin-600italic.svg +342 -0
- package/src/assets/fonts/source-sans-pro/source-sans-pro-v21-latin-600italic.ttf +0 -0
- package/src/assets/fonts/source-sans-pro/source-sans-pro-v21-latin-600italic.woff +0 -0
- package/src/assets/fonts/source-sans-pro/source-sans-pro-v21-latin-600italic.woff2 +0 -0
- package/src/assets/fonts/source-sans-pro/source-sans-pro-v21-latin-700.eot +0 -0
- package/src/assets/fonts/source-sans-pro/source-sans-pro-v21-latin-700.svg +337 -0
- package/src/assets/fonts/source-sans-pro/source-sans-pro-v21-latin-700.ttf +0 -0
- package/src/assets/fonts/source-sans-pro/source-sans-pro-v21-latin-700.woff +0 -0
- package/src/assets/fonts/source-sans-pro/source-sans-pro-v21-latin-700.woff2 +0 -0
- package/src/assets/fonts/source-sans-pro/source-sans-pro-v21-latin-700italic.eot +0 -0
- package/src/assets/fonts/source-sans-pro/source-sans-pro-v21-latin-700italic.svg +339 -0
- package/src/assets/fonts/source-sans-pro/source-sans-pro-v21-latin-700italic.ttf +0 -0
- package/src/assets/fonts/source-sans-pro/source-sans-pro-v21-latin-700italic.woff +0 -0
- package/src/assets/fonts/source-sans-pro/source-sans-pro-v21-latin-700italic.woff2 +0 -0
- package/src/assets/fonts/source-sans-pro/source-sans-pro-v21-latin-900.eot +0 -0
- package/src/assets/fonts/source-sans-pro/source-sans-pro-v21-latin-900.svg +337 -0
- package/src/assets/fonts/source-sans-pro/source-sans-pro-v21-latin-900.ttf +0 -0
- package/src/assets/fonts/source-sans-pro/source-sans-pro-v21-latin-900.woff +0 -0
- package/src/assets/fonts/source-sans-pro/source-sans-pro-v21-latin-900.woff2 +0 -0
- package/src/assets/fonts/source-sans-pro/source-sans-pro-v21-latin-900italic.eot +0 -0
- package/src/assets/fonts/source-sans-pro/source-sans-pro-v21-latin-900italic.svg +340 -0
- package/src/assets/fonts/source-sans-pro/source-sans-pro-v21-latin-900italic.ttf +0 -0
- package/src/assets/fonts/source-sans-pro/source-sans-pro-v21-latin-900italic.woff +0 -0
- package/src/assets/fonts/source-sans-pro/source-sans-pro-v21-latin-900italic.woff2 +0 -0
- package/src/assets/fonts/source-sans-pro/source-sans-pro-v21-latin-italic.eot +0 -0
- package/src/assets/fonts/source-sans-pro/source-sans-pro-v21-latin-italic.svg +343 -0
- package/src/assets/fonts/source-sans-pro/source-sans-pro-v21-latin-italic.ttf +0 -0
- package/src/assets/fonts/source-sans-pro/source-sans-pro-v21-latin-italic.woff +0 -0
- package/src/assets/fonts/source-sans-pro/source-sans-pro-v21-latin-italic.woff2 +0 -0
- package/src/assets/fonts/source-sans-pro/source-sans-pro-v21-latin-regular.eot +0 -0
- package/src/assets/fonts/source-sans-pro/source-sans-pro-v21-latin-regular.svg +337 -0
- package/src/assets/fonts/source-sans-pro/source-sans-pro-v21-latin-regular.ttf +0 -0
- package/src/assets/fonts/source-sans-pro/source-sans-pro-v21-latin-regular.woff +0 -0
- package/src/assets/fonts/source-sans-pro/source-sans-pro-v21-latin-regular.woff2 +0 -0
- package/src/assets/images/placeholder-blueish.jpg +0 -0
- package/src/assets/images/placeholder-sepia.jpg +0 -0
- package/src/assets/images/placeholder.jpg +0 -0
- package/src/components/core/Accordion/Accordion.tsx +228 -0
- package/src/components/core/Accordion/AccordionItem.tsx +72 -0
- package/src/components/core/Accordion/AccordionTab.tsx +39 -0
- package/src/components/core/Accordion/index.ts +3 -0
- package/src/components/core/Accordion/utils.tsx +13 -0
- package/src/components/core/Alert/Alert.tsx +131 -0
- package/src/components/core/Alert/index.ts +1 -0
- package/src/components/core/AlertDialog/AlertDialog.tsx +288 -0
- package/src/components/core/AlertDialog/index.ts +1 -0
- package/src/components/core/Badge/Badge.tsx +70 -0
- package/src/components/core/Badge/index.ts +1 -0
- package/src/components/core/BirthdateField/BirthdateField.tsx +269 -0
- package/src/components/core/BirthdateField/index.ts +1 -0
- package/src/components/core/Button/Button.tsx +178 -0
- package/src/components/core/Button/index.ts +1 -0
- package/src/components/core/ButtonGroup/ButtonGroup.tsx +71 -0
- package/src/components/core/ButtonGroup/index.ts +1 -0
- package/src/components/core/Calendar/Calendar.tsx +303 -0
- package/src/components/core/Calendar/index.ts +1 -0
- package/src/components/core/Checkbox/Checkbox.tsx +107 -0
- package/src/components/core/Checkbox/index.ts +1 -0
- package/src/components/core/CheckboxField/CheckboxField.tsx +156 -0
- package/src/components/core/CheckboxField/CheckboxFieldError.tsx +14 -0
- package/src/components/core/CheckboxField/CheckboxFieldLabel.tsx +25 -0
- package/src/components/core/CheckboxField/CheckboxFieldNote.tsx +16 -0
- package/src/components/core/CheckboxField/index.ts +1 -0
- package/src/components/core/Countdown/Countdown.tsx +67 -0
- package/src/components/core/Countdown/index.ts +1 -0
- package/src/components/core/DataTable/DataTable.tsx +98 -0
- package/src/components/core/DataTable/index.ts +1 -0
- package/src/components/core/Dialog/Dialog.tsx +443 -0
- package/src/components/core/Dialog/index.ts +1 -0
- package/src/components/core/Divider/Divider.tsx +37 -0
- package/src/components/core/Divider/index.ts +1 -0
- package/src/components/core/FavoriteButton/FavoriteButton.tsx +294 -0
- package/src/components/core/FavoriteButton/index.ts +1 -0
- package/src/components/core/Fieldset/Fieldset.tsx +42 -0
- package/src/components/core/Fieldset/index.ts +1 -0
- package/src/components/core/FormLabel/FormLabel.tsx +88 -0
- package/src/components/core/FormLabel/index.ts +1 -0
- package/src/components/core/Icon/Icon.tsx +106 -0
- package/src/components/core/Icon/index.ts +1 -0
- package/src/components/core/IconButton/IconButton.tsx +169 -0
- package/src/components/core/IconButton/index.ts +1 -0
- package/src/components/core/InputField/InputField.tsx +128 -0
- package/src/components/core/InputField/InputFieldError.tsx +17 -0
- package/src/components/core/InputField/InputFieldInput.tsx +67 -0
- package/src/components/core/InputField/InputFieldLabel.tsx +29 -0
- package/src/components/core/InputField/InputFieldNote.tsx +16 -0
- package/src/components/core/InputField/index.ts +1 -0
- package/src/components/core/LoadingSpinner/LoadingSpinner.tsx +50 -0
- package/src/components/core/LoadingSpinner/index.ts +1 -0
- package/src/components/core/Pagination/Pagination.tsx +191 -0
- package/src/components/core/Pagination/index.ts +1 -0
- package/src/components/core/PasswordField/PasswordField.tsx +187 -0
- package/src/components/core/PasswordField/PasswordFieldRequirementsList.tsx +78 -0
- package/src/components/core/PasswordField/index.ts +1 -0
- package/src/components/core/PhoneNumberInput/PhoneNumberInput.tsx +201 -0
- package/src/components/core/PhoneNumberInput/countries.json +242 -0
- package/src/components/core/PhoneNumberInput/index.ts +1 -0
- package/src/components/core/Pictogram/Pictogram.tsx +67 -0
- package/src/components/core/Pictogram/index.ts +1 -0
- package/src/components/core/Popover/Popover.tsx +61 -0
- package/src/components/core/Popover/index.ts +1 -0
- package/src/components/core/Portlist/Portlist.tsx +28 -0
- package/src/components/core/Portlist/index.ts +1 -0
- package/src/components/core/PriceInput/PriceInput.tsx +100 -0
- package/src/components/core/PriceInput/index.ts +1 -0
- package/src/components/core/QuantityItem/QuantityItem.tsx +37 -0
- package/src/components/core/QuantityItem/index.ts +1 -0
- package/src/components/core/Radio/Radio.tsx +64 -0
- package/src/components/core/Radio/index.ts +1 -0
- package/src/components/core/RadioField/RadioField.tsx +66 -0
- package/src/components/core/RadioField/index.ts +1 -0
- package/src/components/core/RadixRadio/RadixRadio.tsx +56 -0
- package/src/components/core/RadixRadio/index.ts +1 -0
- package/src/components/core/RadixSelect/RadixSelect.tsx +172 -0
- package/src/components/core/RadixSelect/index.ts +1 -0
- package/src/components/core/RangeSlider/RangeSlider.tsx +59 -0
- package/src/components/core/RangeSlider/index.ts +1 -0
- package/src/components/core/Section/Section.tsx +62 -0
- package/src/components/core/Section/index.ts +1 -0
- package/src/components/core/SegmentedControl/SegmentedControl.tsx +65 -0
- package/src/components/core/SegmentedControl/index.ts +1 -0
- package/src/components/core/Select/Select.tsx +171 -0
- package/src/components/core/Select/index.ts +1 -0
- package/src/components/core/SelectField/SelectField.tsx +67 -0
- package/src/components/core/SelectField/index.ts +1 -0
- package/src/components/core/Skeleton/Skeleton.tsx +23 -0
- package/src/components/core/Skeleton/SkeletonTextLines.tsx +37 -0
- package/src/components/core/Skeleton/index.ts +2 -0
- package/src/components/core/Stepper/Stepper.tsx +116 -0
- package/src/components/core/Stepper/index.ts +1 -0
- package/src/components/core/SwitchToggle/SwitchToggle.tsx +46 -0
- package/src/components/core/SwitchToggle/index.ts +1 -0
- package/src/components/core/Tabs/Tabs.tsx +130 -0
- package/src/components/core/Tabs/index.ts +1 -0
- package/src/components/core/Tag/Tag.tsx +61 -0
- package/src/components/core/Tag/index.ts +1 -0
- package/src/components/core/TextButton/TextButton.tsx +108 -0
- package/src/components/core/TextButton/index.ts +1 -0
- package/src/components/core/Toast/Toast.tsx +65 -0
- package/src/components/core/Toast/index.ts +1 -0
- package/src/components/core/Tooltip/Tooltip.tsx +110 -0
- package/src/components/core/Tooltip/index.ts +1 -0
- package/src/components/shared/NextFontMeinSchiffSansPro/NextFontMeinSchiffSansPro.tsx +160 -0
- package/src/components/shared/NextFontMeinSchiffSansPro/index.ts +1 -0
- package/src/components/shared/UniversalCarousel/CarouselContext.ts +61 -0
- package/src/components/shared/UniversalCarousel/CarouselDefaultPagination.tsx +92 -0
- package/src/components/shared/UniversalCarousel/CarouselInterface.tsx +152 -0
- package/src/components/shared/UniversalCarousel/CarouselStage.tsx +235 -0
- package/src/components/shared/UniversalCarousel/UniversalCarousel.tsx +125 -0
- package/src/components/shared/UniversalCarousel/helpers.ts +206 -0
- package/src/components/shared/UniversalCarousel/index.ts +4 -0
- package/src/helpers/children.ts +27 -0
- package/src/helpers/cookies.ts +22 -0
- package/src/helpers/dateFormat.ts +245 -0
- package/src/helpers/dateToYearMonthDay.ts +17 -0
- package/src/helpers/elementVisibility.ts +53 -0
- package/src/helpers/i18n.ts +197 -0
- package/src/helpers/price.ts +26 -0
- package/src/helpers/responsive-property.ts +118 -0
- package/src/helpers/screen.ts +14 -0
- package/src/helpers/sleep.ts +5 -0
- package/src/helpers/slot.tsx +68 -0
- package/src/helpers/ssr.ts +5 -0
- package/src/helpers/store.ts +75 -0
- package/src/helpers/types.ts +18 -0
- package/src/helpers/utils.ts +3 -0
- package/src/hooks/use-active-screen-names.ts +100 -0
- package/src/hooks/use-intersection-observer.ts +190 -0
- package/src/hooks/use-screen-name-at-least.ts +32 -0
- package/src/hooks/use-screen-name.ts +34 -0
- package/src/hooks/use-store.ts +45 -0
- package/src/hooks/use-toasts.ts +111 -0
- 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
|
+
};
|